From 0864f618dc60cfe3dde181a06ae82b12a0f32931 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Wed, 20 Aug 2008 20:47:34 +0000 Subject: [PATCH] Added support for painting leaders (implemented as drawLine in IFPainter). Removed unused "stroke" parameter in drawRect and renamed the method to fillRect. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign@687455 13f79535-47bb-0310-9956-ffa450edef68 --- .../render/intermediate/BorderPainter.java | 7 +- .../fop/render/intermediate/IFConstants.java | 1 + .../fop/render/intermediate/IFPainter.java | 21 +++- .../fop/render/intermediate/IFParser.java | 25 ++++- .../fop/render/intermediate/IFRenderer.java | 30 ++++- .../fop/render/intermediate/IFSerializer.java | 33 ++++-- .../fop/render/pdf/PDFBorderPainter.java | 62 ++++++++++ .../fop/render/pdf/PDFContentGenerator.java | 14 +++ .../org/apache/fop/render/pdf/PDFPainter.java | 26 +++-- .../apache/fop/render/pdf/PDFRenderer.java | 79 ++----------- .../org/apache/fop/traits/BorderProps.java | 41 +------ .../org/apache/fop/traits/BorderStyle.java | 106 ++++++++++++++++++ src/java/org/apache/fop/traits/RuleStyle.java | 98 ++++++++++++++++ src/java/org/apache/fop/traits/TraitEnum.java | 56 +++++++++ .../fop/render/svg/AbstractSVGPainter.java | 32 +++++- 15 files changed, 489 insertions(+), 142 deletions(-) create mode 100644 src/java/org/apache/fop/traits/BorderStyle.java create mode 100644 src/java/org/apache/fop/traits/RuleStyle.java create mode 100644 src/java/org/apache/fop/traits/TraitEnum.java diff --git a/src/java/org/apache/fop/render/intermediate/BorderPainter.java b/src/java/org/apache/fop/render/intermediate/BorderPainter.java index fdde321a9..e8874dc69 100644 --- a/src/java/org/apache/fop/render/intermediate/BorderPainter.java +++ b/src/java/org/apache/fop/render/intermediate/BorderPainter.java @@ -20,9 +20,11 @@ package org.apache.fop.render.intermediate; import java.awt.Color; +import java.awt.Point; import java.awt.Rectangle; import org.apache.fop.traits.BorderProps; +import org.apache.fop.traits.RuleStyle; /** * This is an abstract base class for handling border painting. @@ -198,7 +200,10 @@ public abstract class BorderPainter { protected abstract void drawBorderLine(int x1, int y1, int x2, int y2, - boolean horz, boolean startOrBefore, int style, Color col); + boolean horz, boolean startOrBefore, int style, Color color); + + public abstract void drawLine(Point start, Point end, + int width, Color color, RuleStyle style); protected abstract void moveTo(int x, int y); diff --git a/src/java/org/apache/fop/render/intermediate/IFConstants.java b/src/java/org/apache/fop/render/intermediate/IFConstants.java index f101ad363..e7f7e1a00 100644 --- a/src/java/org/apache/fop/render/intermediate/IFConstants.java +++ b/src/java/org/apache/fop/render/intermediate/IFConstants.java @@ -46,6 +46,7 @@ public interface IFConstants extends XMLConstants { String EL_IMAGE = "image"; String EL_CLIP_RECT = "clip-rect"; String EL_RECT = "rect"; + String EL_LINE = "line"; String EL_BORDER_RECT = "border-rect"; String EL_FONT = "font"; String EL_TEXT = "text"; diff --git a/src/java/org/apache/fop/render/intermediate/IFPainter.java b/src/java/org/apache/fop/render/intermediate/IFPainter.java index 4722a02ac..b354510f8 100644 --- a/src/java/org/apache/fop/render/intermediate/IFPainter.java +++ b/src/java/org/apache/fop/render/intermediate/IFPainter.java @@ -22,6 +22,7 @@ package org.apache.fop.render.intermediate; import java.awt.Color; import java.awt.Dimension; import java.awt.Paint; +import java.awt.Point; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.util.Map; @@ -33,6 +34,7 @@ import org.w3c.dom.Document; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fonts.FontInfo; import org.apache.fop.traits.BorderProps; +import org.apache.fop.traits.RuleStyle; /** * Interface used to paint whole documents layouted by Apache FOP. @@ -277,13 +279,12 @@ public interface IFPainter { //TODO clipRect() shall be considered temporary until verified with SVG and PCL /** - * Draws a rectangle. Either fill or stroke has to be specified. + * Fills a rectangular area. * @param rect the rectangle's coordinates and extent - * @param fill the fill paint (may be null) - * @param stroke the stroke color (may be null) + * @param fill the fill paint * @throws IFException if an error occurs while handling this event */ - void drawRect(Rectangle rect, Paint fill, Color stroke) throws IFException; + void fillRect(Rectangle rect, Paint fill) throws IFException; /** * Draws a border rectangle. The border segments are specified through {@code BorderProps} @@ -299,6 +300,18 @@ public interface IFPainter { BorderProps before, BorderProps after, BorderProps start, BorderProps end) throws IFException; + /** + * Draws a line. NOTE: Currently, only horizontal lines are implemented! + * @param start the start point of the line + * @param end the end point of the line + * @param width the line width + * @param color the line color + * @param style the line style (using the Constants.EN_* constants for the rule-style property) + * @throws IFException if an error occurs while handling this event + */ + void drawLine(Point start, Point end, int width, Color color, RuleStyle style) + throws IFException; + /** * Draws an image identified by a URI inside a given rectangle. This is the equivalent to * an fo:external-graphic in XSL-FO. diff --git a/src/java/org/apache/fop/render/intermediate/IFParser.java b/src/java/org/apache/fop/render/intermediate/IFParser.java index 50c061ff4..cc125a6f7 100644 --- a/src/java/org/apache/fop/render/intermediate/IFParser.java +++ b/src/java/org/apache/fop/render/intermediate/IFParser.java @@ -21,6 +21,7 @@ package org.apache.fop.render.intermediate; import java.awt.Color; import java.awt.Dimension; +import java.awt.Point; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.util.Map; @@ -50,6 +51,7 @@ import org.apache.fop.fo.ElementMapping; import org.apache.fop.fo.ElementMappingRegistry; import org.apache.fop.fo.expr.PropertyException; import org.apache.fop.traits.BorderProps; +import org.apache.fop.traits.RuleStyle; import org.apache.fop.util.ColorUtil; import org.apache.fop.util.ContentHandlerFactory; import org.apache.fop.util.ContentHandlerFactoryRegistry; @@ -138,6 +140,7 @@ public class IFParser implements IFConstants { elementHandlers.put(EL_TEXT, new TextHandler()); elementHandlers.put(EL_CLIP_RECT, new ClipRectHandler()); elementHandlers.put(EL_RECT, new RectHandler()); + elementHandlers.put(EL_LINE, new LineHandler()); elementHandlers.put(EL_BORDER_RECT, new BorderRectHandler()); elementHandlers.put(EL_IMAGE, new ImageHandler()); } @@ -467,13 +470,27 @@ public class IFParser implements IFConstants { } catch (PropertyException pe) { throw new IFException("Error parsing the fill attribute", pe); } - Color strokeColor; + painter.fillRect(new Rectangle(x, y, width, height), fillColor); + } + + } + + private class LineHandler extends AbstractElementHandler { + + public void startElement(Attributes attributes) throws IFException { + int x1 = Integer.parseInt(attributes.getValue("x1")); + int y1 = Integer.parseInt(attributes.getValue("y1")); + int x2 = Integer.parseInt(attributes.getValue("x2")); + int y2 = Integer.parseInt(attributes.getValue("y2")); + int width = Integer.parseInt(attributes.getValue("stroke-width")); + Color color; try { - strokeColor = getAttributeAsColor(attributes, "stroke"); + color = getAttributeAsColor(attributes, "color"); } catch (PropertyException pe) { - throw new IFException("Error parsing the stroke attribute", pe); + throw new IFException("Error parsing the fill attribute", pe); } - painter.drawRect(new Rectangle(x, y, width, height), fillColor, strokeColor); + RuleStyle style = RuleStyle.valueOf(attributes.getValue("style")); + painter.drawLine(new Point(x1, y1), new Point(x2, y2), width, color, style); } } diff --git a/src/java/org/apache/fop/render/intermediate/IFRenderer.java b/src/java/org/apache/fop/render/intermediate/IFRenderer.java index 0b74987b5..1ea3f9592 100644 --- a/src/java/org/apache/fop/render/intermediate/IFRenderer.java +++ b/src/java/org/apache/fop/render/intermediate/IFRenderer.java @@ -67,6 +67,7 @@ import org.apache.fop.area.inline.AbstractTextArea; import org.apache.fop.area.inline.ForeignObject; import org.apache.fop.area.inline.Image; import org.apache.fop.area.inline.InlineArea; +import org.apache.fop.area.inline.Leader; import org.apache.fop.area.inline.SpaceArea; import org.apache.fop.area.inline.TextArea; import org.apache.fop.area.inline.Viewport; @@ -87,6 +88,7 @@ import org.apache.fop.render.intermediate.extensions.GoToXYAction; import org.apache.fop.render.intermediate.extensions.NamedDestination; import org.apache.fop.render.pdf.PDFEventProducer; import org.apache.fop.traits.BorderProps; +import org.apache.fop.traits.RuleStyle; /** * This renderer implementation is an adapter to the {@code IFPainter} interface. It is used @@ -992,6 +994,30 @@ public class IFRenderer extends AbstractPathOrientedRenderer { } } + /** {@inheritDoc} */ + public void renderLeader(Leader area) { + renderInlineAreaBackAndBorders(area); + + int style = area.getRuleStyle(); + int ruleThickness = area.getRuleThickness(); + int startx = currentIPPosition + area.getBorderAndPaddingWidthStart(); + int starty = currentBPPosition + area.getOffset() + (ruleThickness / 2); + int endx = currentIPPosition + + area.getBorderAndPaddingWidthStart() + + area.getIPD(); + Color col = (Color)area.getTrait(Trait.COLOR); + + Point start = new Point(startx, starty); + Point end = new Point(endx, starty); + try { + painter.drawLine(start, end, ruleThickness, col, RuleStyle.valueOf(style)); + } catch (IFException ife) { + handleIFException(ife); + } + + super.renderLeader(area); + } + /** {@inheritDoc} */ protected void clip() { throw new IllegalStateException("Not used"); @@ -1048,9 +1074,9 @@ public class IFRenderer extends AbstractPathOrientedRenderer { /** {@inheritDoc} */ protected void fillRect(float x, float y, float width, float height) { try { - painter.drawRect( + painter.fillRect( toMillipointRectangle(x, y, width, height), - this.graphicContext.getPaint(), null); + this.graphicContext.getPaint()); } catch (IFException e) { handleIFException(e); } diff --git a/src/java/org/apache/fop/render/intermediate/IFSerializer.java b/src/java/org/apache/fop/render/intermediate/IFSerializer.java index 4eb7f0713..20db35c6a 100644 --- a/src/java/org/apache/fop/render/intermediate/IFSerializer.java +++ b/src/java/org/apache/fop/render/intermediate/IFSerializer.java @@ -22,6 +22,7 @@ package org.apache.fop.render.intermediate; import java.awt.Color; import java.awt.Dimension; import java.awt.Paint; +import java.awt.Point; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.util.Iterator; @@ -37,6 +38,7 @@ import org.apache.xmlgraphics.util.XMLizable; import org.apache.fop.render.RenderingContext; import org.apache.fop.traits.BorderProps; +import org.apache.fop.traits.RuleStyle; import org.apache.fop.util.ColorUtil; import org.apache.fop.util.DOM2SAX; import org.apache.fop.util.XMLUtil; @@ -364,8 +366,8 @@ public class IFSerializer extends AbstractXMLWritingIFPainter implements IFConst } /** {@inheritDoc} */ - public void drawRect(Rectangle rect, Paint fill, Color stroke) throws IFException { - if (fill == null && stroke == null) { + public void fillRect(Rectangle rect, Paint fill) throws IFException { + if (fill == null) { return; } try { @@ -374,15 +376,10 @@ public class IFSerializer extends AbstractXMLWritingIFPainter implements IFConst addAttribute(atts, "y", Integer.toString(rect.y)); addAttribute(atts, "width", Integer.toString(rect.width)); addAttribute(atts, "height", Integer.toString(rect.height)); - if (fill != null) { - addAttribute(atts, "fill", toString(fill)); - } - if (stroke != null) { - addAttribute(atts, "stroke", toString(stroke)); - } + addAttribute(atts, "fill", toString(fill)); element(EL_RECT, atts); } catch (SAXException e) { - throw new IFException("SAX error in drawRect()", e); + throw new IFException("SAX error in fillRect()", e); } } @@ -416,6 +413,24 @@ public class IFSerializer extends AbstractXMLWritingIFPainter implements IFConst } } + /** {@inheritDoc} */ + public void drawLine(Point start, Point end, int width, Color color, RuleStyle style) + throws IFException { + try { + AttributesImpl atts = new AttributesImpl(); + addAttribute(atts, "x1", Integer.toString(start.x)); + addAttribute(atts, "y1", Integer.toString(start.y)); + addAttribute(atts, "x2", Integer.toString(end.x)); + addAttribute(atts, "y2", Integer.toString(end.y)); + addAttribute(atts, "stroke-width", Integer.toString(width)); + addAttribute(atts, "color", Integer.toString(width)); + addAttribute(atts, "style", style.getName()); + element(EL_LINE, atts); + } catch (SAXException e) { + throw new IFException("SAX error in drawLine()", e); + } + } + /** {@inheritDoc} */ public void drawText(int x, int y, int[] dx, int[] dy, String text) throws IFException { try { diff --git a/src/java/org/apache/fop/render/pdf/PDFBorderPainter.java b/src/java/org/apache/fop/render/pdf/PDFBorderPainter.java index ab34e36c9..309307a51 100644 --- a/src/java/org/apache/fop/render/pdf/PDFBorderPainter.java +++ b/src/java/org/apache/fop/render/pdf/PDFBorderPainter.java @@ -20,6 +20,8 @@ package org.apache.fop.render.pdf; import java.awt.Color; +import java.awt.Point; +import java.awt.Rectangle; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -27,6 +29,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.fop.fo.Constants; import org.apache.fop.render.PrintRenderer; import org.apache.fop.render.intermediate.BorderPainter; +import org.apache.fop.traits.RuleStyle; /** * PDF-specific implementation of the {@code BorderPainter}. @@ -221,6 +224,65 @@ public class PDFBorderPainter extends BorderPainter { } } + /** {@inheritDoc} */ + public void drawLine(Point start, Point end, + int width, Color color, RuleStyle style) { + if (start.y != end.y) { + //TODO Support arbitrary lines if necessary + throw new UnsupportedOperationException( + "Can only deal with horizontal lines right now"); + } + + saveGraphicsState(); + int half = width / 2; + int starty = start.y - half; + Rectangle boundingRect = new Rectangle(start.x, start.y - half, end.x - start.x, width); + switch (style.getEnumValue()) { + case Constants.EN_SOLID: + case Constants.EN_DASHED: + case Constants.EN_DOUBLE: + drawBorderLine(start.x, start.y - half, end.x, end.y + half, + true, true, style.getEnumValue(), color); + break; + case Constants.EN_DOTTED: + generator.clipRect(boundingRect); + //This displaces the dots to the right by half a dot's width + //TODO There's room for improvement here + generator.add("1 0 0 1 " + format(half) + " 0 cm\n"); + drawBorderLine(start.x, start.y - half, end.x, end.y + half, + true, true, style.getEnumValue(), color); + break; + case Constants.EN_GROOVE: + case Constants.EN_RIDGE: + generator.setColor(PrintRenderer.lightenColor(color, 0.6f), true); + generator.add(format(start.x) + " " + format(starty) + " m\n"); + generator.add(format(end.x) + " " + format(starty) + " l\n"); + generator.add(format(end.x) + " " + format(starty + 2 * half) + " l\n"); + generator.add(format(start.x) + " " + format(starty + 2 * half) + " l\n"); + generator.add("h\n"); + generator.add("f\n"); + generator.setColor(color, true); + if (style == RuleStyle.GROOVE) { + generator.add(format(start.x) + " " + format(starty) + " m\n"); + generator.add(format(end.x) + " " + format(starty) + " l\n"); + generator.add(format(end.x) + " " + format(starty + half) + " l\n"); + generator.add(format(start.x + half) + " " + format(starty + half) + " l\n"); + generator.add(format(start.x) + " " + format(starty + 2 * half) + " l\n"); + } else { + generator.add(format(end.x) + " " + format(starty) + " m\n"); + generator.add(format(end.x) + " " + format(starty + 2 * half) + " l\n"); + generator.add(format(start.x) + " " + format(starty + 2 * half) + " l\n"); + generator.add(format(start.x) + " " + format(starty + half) + " l\n"); + generator.add(format(end.x - half) + " " + format(starty + half) + " l\n"); + } + generator.add("h\n"); + generator.add("f\n"); + break; + default: + throw new UnsupportedOperationException("rule style not supported"); + } + restoreGraphicsState(); + } static final String format(int coordinate) { return format(coordinate / 1000f); diff --git a/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java b/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java index da1bf728e..35dc0960a 100644 --- a/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java +++ b/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java @@ -20,6 +20,7 @@ package org.apache.fop.render.pdf; import java.awt.Color; +import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.io.IOException; import java.io.OutputStream; @@ -209,6 +210,19 @@ public class PDFContentGenerator { } } + /** + * Intersects the current clip region with the given rectangle. + * @param rect the clip rectangle + */ + public void clipRect(Rectangle rect) { + StringBuffer sb = new StringBuffer(); + sb.append(format(rect.x / 1000f)).append(' '); + sb.append(format(rect.y / 1000f)).append(' '); + sb.append(format(rect.width / 1000f)).append(' '); + sb.append(format(rect.height / 1000f)).append(" re W n\n"); + add(sb.toString()); + } + /** * Adds content to the stream. * @param content the PDF content diff --git a/src/java/org/apache/fop/render/pdf/PDFPainter.java b/src/java/org/apache/fop/render/pdf/PDFPainter.java index 0ddfd8324..e4418bb99 100644 --- a/src/java/org/apache/fop/render/pdf/PDFPainter.java +++ b/src/java/org/apache/fop/render/pdf/PDFPainter.java @@ -22,6 +22,7 @@ package org.apache.fop.render.pdf; import java.awt.Color; import java.awt.Dimension; import java.awt.Paint; +import java.awt.Point; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; @@ -65,6 +66,7 @@ import org.apache.fop.render.intermediate.extensions.BookmarkTree; import org.apache.fop.render.intermediate.extensions.GoToXYAction; import org.apache.fop.render.intermediate.extensions.NamedDestination; import org.apache.fop.traits.BorderProps; +import org.apache.fop.traits.RuleStyle; import org.apache.fop.util.CharUtilities; /** @@ -327,17 +329,12 @@ public class PDFPainter extends AbstractBinaryWritingIFPainter { /** {@inheritDoc} */ public void clipRect(Rectangle rect) throws IFException { generator.endTextObject(); - StringBuffer sb = new StringBuffer(); - sb.append(format(rect.x)).append(' '); - sb.append(format(rect.y)).append(' '); - sb.append(format(rect.width)).append(' '); - sb.append(format(rect.height)).append(" re W n\n"); - generator.add(sb.toString()); + generator.clipRect(rect); } /** {@inheritDoc} */ - public void drawRect(Rectangle rect, Paint fill, Color stroke) throws IFException { - if (fill == null && stroke == null) { + public void fillRect(Rectangle rect, Paint fill) throws IFException { + if (fill == null) { return; } generator.endTextObject(); @@ -349,9 +346,6 @@ public class PDFPainter extends AbstractBinaryWritingIFPainter { throw new UnsupportedOperationException("Non-Color paints NYI"); } } - if (stroke != null) { - throw new UnsupportedOperationException("stroke NYI"); - } StringBuffer sb = new StringBuffer(); sb.append(format(rect.x)).append(' '); sb.append(format(rect.y)).append(' '); @@ -360,9 +354,10 @@ public class PDFPainter extends AbstractBinaryWritingIFPainter { if (fill != null) { sb.append(" f"); } + /* Removed from method signature as it is currently not used if (stroke != null) { sb.append(" S"); - } + }*/ sb.append('\n'); generator.add(sb.toString()); } @@ -377,6 +372,13 @@ public class PDFPainter extends AbstractBinaryWritingIFPainter { } } + /** {@inheritDoc} */ + public void drawLine(Point start, Point end, int width, Color color, RuleStyle style) + throws IFException { + generator.endTextObject(); + this.borderPainter.drawLine(start, end, width, color, style); + } + private Typeface getTypeface(String fontName) { if (fontName == null) { throw new NullPointerException("fontName must not be null"); diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java index 325cc79fe..9567c5306 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java @@ -91,6 +91,7 @@ import org.apache.fop.pdf.PDFXObject; import org.apache.fop.render.AbstractPathOrientedRenderer; import org.apache.fop.render.Graphics2DAdapter; import org.apache.fop.render.RendererContext; +import org.apache.fop.traits.RuleStyle; import org.apache.fop.util.CharUtilities; /** @@ -167,6 +168,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer implements PDFConf /** The current content generator to produce PDF commands with */ protected PDFContentGenerator generator; + private PDFBorderPainter borderPainter; /** * the current annotation list to add annotations to @@ -189,6 +191,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer implements PDFConf /** Image handler registry */ private PDFImageHandlerRegistry imageHandlerRegistry = new PDFImageHandlerRegistry(); + /** * create the PDF renderer */ @@ -460,17 +463,8 @@ public class PDFRenderer extends AbstractPathOrientedRenderer implements PDFConf pageHeight = (int) h; this.generator = new PDFContentGenerator(this.pdfDoc, this.ostream, this.currentPage); - /* - currentStream = this.pdfDoc.getFactory() - .makeStream(PDFFilterList.CONTENT_FILTER, false); - this.textutil = new PDFTextUtil() { - protected void write(String code) { - currentStream.add(code); - } - }; + this.borderPainter = new PDFBorderPainter(this.generator); - currentState = new PDFState(); - */ // Transform the PDF's default coordinate system (0,0 at lower left) to the PDFRenderer's AffineTransform basicPageTransform = new AffineTransform(1, 0, 0, -1, 0, pageHeight / 1000f); @@ -1223,66 +1217,17 @@ public class PDFRenderer extends AbstractPathOrientedRenderer implements PDFConf public void renderLeader(Leader area) { renderInlineAreaBackAndBorders(area); - getState().push(); - saveGraphicsState(); int style = area.getRuleStyle(); - float startx = (currentIPPosition + area.getBorderAndPaddingWidthStart()) / 1000f; - float starty = (currentBPPosition + area.getOffset()) / 1000f; - float endx = (currentIPPosition + area.getBorderAndPaddingWidthStart() - + area.getIPD()) / 1000f; - float ruleThickness = area.getRuleThickness() / 1000f; + int ruleThickness = area.getRuleThickness(); + int startx = currentIPPosition + area.getBorderAndPaddingWidthStart(); + int starty = currentBPPosition + area.getOffset() + (ruleThickness / 2); + int endx = currentIPPosition + + area.getBorderAndPaddingWidthStart() + + area.getIPD(); Color col = (Color)area.getTrait(Trait.COLOR); - switch (style) { - case EN_SOLID: - case EN_DASHED: - case EN_DOUBLE: - drawBorderLine(startx, starty, endx, starty + ruleThickness, - true, true, style, col); - break; - case EN_DOTTED: - clipRect(startx, starty, endx - startx, ruleThickness); - //This displaces the dots to the right by half a dot's width - //TODO There's room for improvement here - generator.add("1 0 0 1 " + format(ruleThickness / 2) + " 0 cm\n"); - drawBorderLine(startx, starty, endx, starty + ruleThickness, - true, true, style, col); - break; - case EN_GROOVE: - case EN_RIDGE: - float half = area.getRuleThickness() / 2000f; - - generator.setColor(lightenColor(col, 0.6f), true); - generator.add(format(startx) + " " + format(starty) + " m\n"); - generator.add(format(endx) + " " + format(starty) + " l\n"); - generator.add(format(endx) + " " + format(starty + 2 * half) + " l\n"); - generator.add(format(startx) + " " + format(starty + 2 * half) + " l\n"); - generator.add("h\n"); - generator.add("f\n"); - generator.setColor(col, true); - if (style == EN_GROOVE) { - generator.add(format(startx) + " " + format(starty) + " m\n"); - generator.add(format(endx) + " " + format(starty) + " l\n"); - generator.add(format(endx) + " " + format(starty + half) + " l\n"); - generator.add(format(startx + half) + " " + format(starty + half) + " l\n"); - generator.add(format(startx) + " " + format(starty + 2 * half) + " l\n"); - } else { - generator.add(format(endx) + " " + format(starty) + " m\n"); - generator.add(format(endx) + " " + format(starty + 2 * half) + " l\n"); - generator.add(format(startx) + " " + format(starty + 2 * half) + " l\n"); - generator.add(format(startx) + " " + format(starty + half) + " l\n"); - generator.add(format(endx - half) + " " + format(starty + half) + " l\n"); - } - generator.add("h\n"); - generator.add("f\n"); - break; - default: - throw new UnsupportedOperationException("rule style not supported"); - } - - restoreGraphicsState(); - getState().pop(); - beginTextObject(); + borderPainter.drawLine(new Point(startx, starty), new Point(endx, starty), + ruleThickness, col, RuleStyle.valueOf(style)); super.renderLeader(area); } diff --git a/src/java/org/apache/fop/traits/BorderProps.java b/src/java/org/apache/fop/traits/BorderProps.java index 338743538..5bd4feec5 100644 --- a/src/java/org/apache/fop/traits/BorderProps.java +++ b/src/java/org/apache/fop/traits/BorderProps.java @@ -25,13 +25,12 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.fo.Constants; import org.apache.fop.fo.expr.PropertyException; import org.apache.fop.util.ColorUtil; /** * Border properties. - * Class to store border trait propties for the area tree. + * Class to store border trait properties for the area tree. */ public class BorderProps implements Serializable { @@ -89,45 +88,11 @@ public class BorderProps implements Serializable { } private String getStyleString() { - switch (style) { - case Constants.EN_NONE: return "none"; - case Constants.EN_HIDDEN: return "hidden"; - case Constants.EN_DOTTED: return "dotted"; - case Constants.EN_DASHED: return "dashed"; - case Constants.EN_SOLID: return "solid"; - case Constants.EN_DOUBLE: return "double"; - case Constants.EN_GROOVE: return "groove"; - case Constants.EN_RIDGE: return "ridge"; - case Constants.EN_INSET: return "inset"; - case Constants.EN_OUTSET: return "outset"; - default: throw new IllegalStateException("Illegal border style: " + style); - } + return BorderStyle.valueOf(style).getName(); } private static int getConstantForStyle(String style) { - if ("none".equalsIgnoreCase(style)) { - return Constants.EN_NONE; - } else if ("hidden".equalsIgnoreCase(style)) { - return Constants.EN_HIDDEN; - } else if ("dotted".equalsIgnoreCase(style)) { - return Constants.EN_DOTTED; - } else if ("dashed".equalsIgnoreCase(style)) { - return Constants.EN_DASHED; - } else if ("solid".equalsIgnoreCase(style)) { - return Constants.EN_SOLID; - } else if ("double".equalsIgnoreCase(style)) { - return Constants.EN_DOUBLE; - } else if ("groove".equalsIgnoreCase(style)) { - return Constants.EN_GROOVE; - } else if ("ridge".equalsIgnoreCase(style)) { - return Constants.EN_RIDGE; - } else if ("inset".equalsIgnoreCase(style)) { - return Constants.EN_INSET; - } else if ("outset".equalsIgnoreCase(style)) { - return Constants.EN_OUTSET; - } else { - throw new IllegalStateException("Illegal border style: " + style); - } + return BorderStyle.valueOf(style).getEnumValue(); } /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/traits/BorderStyle.java b/src/java/org/apache/fop/traits/BorderStyle.java new file mode 100644 index 000000000..2f274df22 --- /dev/null +++ b/src/java/org/apache/fop/traits/BorderStyle.java @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.traits; + +import java.io.ObjectStreamException; + +import org.apache.fop.fo.Constants; + +/** Enumeration class for border styles. */ +public final class BorderStyle extends TraitEnum { + + private static final long serialVersionUID = 1L; + + private static final String[] BORDER_STYLE_NAMES = new String[] + {"none", "hidden", "dotted", "dashed", + "solid", "double", "groove", "ridge", + "inset", "outset"}; + + private static final int[] BORDER_STYLE_VALUES = new int[] + {Constants.EN_NONE, Constants.EN_HIDDEN, Constants.EN_DOTTED, Constants.EN_DASHED, + Constants.EN_SOLID, Constants.EN_DOUBLE, Constants.EN_GROOVE, Constants.EN_RIDGE, + Constants.EN_INSET, Constants.EN_OUTSET}; + + /** border-style: none */ + public static final BorderStyle NONE = new BorderStyle(0); + /** border-style: hidden */ + public static final BorderStyle HIDDEN = new BorderStyle(1); + /** border-style: dotted */ + public static final BorderStyle DOTTED = new BorderStyle(2); + /** border-style: dashed */ + public static final BorderStyle DASHED = new BorderStyle(3); + /** border-style: solid */ + public static final BorderStyle SOLID = new BorderStyle(4); + /** border-style: double */ + public static final BorderStyle DOUBLE = new BorderStyle(5); + /** border-style: groove */ + public static final BorderStyle GROOVE = new BorderStyle(6); + /** border-style: ridge */ + public static final BorderStyle RIDGE = new BorderStyle(7); + /** border-style: inset */ + public static final BorderStyle INSET = new BorderStyle(8); + /** border-style: outset */ + public static final BorderStyle OUTSET = new BorderStyle(9); + + private static final BorderStyle[] STYLES = new BorderStyle[] { + NONE, HIDDEN, DOTTED, DASHED, SOLID, DOUBLE, GROOVE, RIDGE, INSET, OUTSET}; + + private BorderStyle(int index) { + super(BORDER_STYLE_NAMES[index], BORDER_STYLE_VALUES[index]); + } + + /** + * Returns the enumeration/singleton object based on its name. + * @param name the name of the enumeration value + * @return the enumeration object + */ + public static BorderStyle valueOf(String name) { + for (int i = 0; i < STYLES.length; i++) { + if (STYLES[i].getName().equalsIgnoreCase(name)) { + return STYLES[i]; + } + } + throw new IllegalArgumentException("Illegal border style: " + name); + } + + /** + * Returns the enumeration/singleton object based on its name. + * @param enumValue the enumeration value + * @return the enumeration object + */ + public static BorderStyle valueOf(int enumValue) { + for (int i = 0; i < STYLES.length; i++) { + if (STYLES[i].getEnumValue() == enumValue) { + return STYLES[i]; + } + } + throw new IllegalArgumentException("Illegal border style: " + enumValue); + } + + private Object readResolve() throws ObjectStreamException { + return valueOf(getName()); + } + + /** {@inheritDoc} */ + public String toString() { + return "BorderStyle:" + getName(); + } + +} diff --git a/src/java/org/apache/fop/traits/RuleStyle.java b/src/java/org/apache/fop/traits/RuleStyle.java new file mode 100644 index 000000000..19b57d76f --- /dev/null +++ b/src/java/org/apache/fop/traits/RuleStyle.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.traits; + +import java.io.ObjectStreamException; + +import org.apache.fop.fo.Constants; + +/** Enumeration class for rule styles. */ +public final class RuleStyle extends TraitEnum { + + private static final long serialVersionUID = 1L; + + private static final String[] RULE_STYLE_NAMES = new String[] + {"none", "dotted", "dashed", + "solid", "double", "groove", "ridge"}; + + private static final int[] RULE_STYLE_VALUES = new int[] + {Constants.EN_NONE, Constants.EN_DOTTED, Constants.EN_DASHED, + Constants.EN_SOLID, Constants.EN_DOUBLE, Constants.EN_GROOVE, Constants.EN_RIDGE}; + + /** rule-style: none */ + public static final RuleStyle NONE = new RuleStyle(0); + /** rule-style: dotted */ + public static final RuleStyle DOTTED = new RuleStyle(1); + /** rule-style: dashed */ + public static final RuleStyle DASHED = new RuleStyle(2); + /** rule-style: solid */ + public static final RuleStyle SOLID = new RuleStyle(3); + /** rule-style: double */ + public static final RuleStyle DOUBLE = new RuleStyle(4); + /** rule-style: groove */ + public static final RuleStyle GROOVE = new RuleStyle(5); + /** rule-style: ridge */ + public static final RuleStyle RIDGE = new RuleStyle(6); + + private static final RuleStyle[] STYLES = new RuleStyle[] { + NONE, DOTTED, DASHED, SOLID, DOUBLE, GROOVE, RIDGE}; + + private RuleStyle(int index) { + super(RULE_STYLE_NAMES[index], RULE_STYLE_VALUES[index]); + } + + /** + * Returns the enumeration/singleton object based on its name. + * @param name the name of the enumeration value + * @return the enumeration object + */ + public static RuleStyle valueOf(String name) { + for (int i = 0; i < STYLES.length; i++) { + if (STYLES[i].getName().equalsIgnoreCase(name)) { + return STYLES[i]; + } + } + throw new IllegalArgumentException("Illegal rule style: " + name); + } + + /** + * Returns the enumeration/singleton object based on its name. + * @param enumValue the enumeration value + * @return the enumeration object + */ + public static RuleStyle valueOf(int enumValue) { + for (int i = 0; i < STYLES.length; i++) { + if (STYLES[i].getEnumValue() == enumValue) { + return STYLES[i]; + } + } + throw new IllegalArgumentException("Illegal rule style: " + enumValue); + } + + private Object readResolve() throws ObjectStreamException { + return valueOf(getName()); + } + + /** {@inheritDoc} */ + public String toString() { + return "RuleStyle:" + getName(); + } + +} diff --git a/src/java/org/apache/fop/traits/TraitEnum.java b/src/java/org/apache/fop/traits/TraitEnum.java new file mode 100644 index 000000000..75c06dcc7 --- /dev/null +++ b/src/java/org/apache/fop/traits/TraitEnum.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.traits; + +import java.io.Serializable; + +/** Base class for enumeration classes representing traits. */ +public abstract class TraitEnum implements Serializable { + + private String name; + private int enumValue; + + /** + * Constructor to add a new named item. + * @param name Name of the item. + * @param enumValue the {@code Constants}.EN_* value + */ + protected TraitEnum(String name, int enumValue) { + this.name = name; + this.enumValue = enumValue; + } + + /** + * Returns the name of the enumeration. + * @return the name of the enumeration + */ + public String getName() { + return this.name; + } + + /** + * Returns the enumeration value (one of {@code Constants}.EN_*). + * @return the enumeration value + */ + public int getEnumValue() { + return this.enumValue; + } + +} diff --git a/src/sandbox/org/apache/fop/render/svg/AbstractSVGPainter.java b/src/sandbox/org/apache/fop/render/svg/AbstractSVGPainter.java index 80fcde0df..8f0be026e 100644 --- a/src/sandbox/org/apache/fop/render/svg/AbstractSVGPainter.java +++ b/src/sandbox/org/apache/fop/render/svg/AbstractSVGPainter.java @@ -22,6 +22,7 @@ package org.apache.fop.render.svg; import java.awt.Color; import java.awt.Dimension; import java.awt.Paint; +import java.awt.Point; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.io.FileNotFoundException; @@ -52,6 +53,7 @@ import org.apache.fop.render.intermediate.IFConstants; import org.apache.fop.render.intermediate.IFException; import org.apache.fop.render.intermediate.IFState; import org.apache.fop.traits.BorderProps; +import org.apache.fop.traits.RuleStyle; import org.apache.fop.util.ColorUtil; /** @@ -284,8 +286,8 @@ public abstract class AbstractSVGPainter extends AbstractXMLWritingIFPainter } /** {@inheritDoc} */ - public void drawRect(Rectangle rect, Paint fill, Color stroke) throws IFException { - if (fill == null && stroke == null) { + public void fillRect(Rectangle rect, Paint fill) throws IFException { + if (fill == null) { return; } try { @@ -298,12 +300,13 @@ public abstract class AbstractSVGPainter extends AbstractXMLWritingIFPainter if (fill != null) { atts.addAttribute("", "fill", "fill", CDATA, toString(fill)); } + /* disabled if (stroke != null) { - atts.addAttribute("", "stroke", "sroke", CDATA, toString(stroke)); - } + atts.addAttribute("", "stroke", "stroke", CDATA, toString(stroke)); + }*/ element("rect", atts); } catch (SAXException e) { - throw new IFException("SAX error in drawRect()", e); + throw new IFException("SAX error in fillRect()", e); } } @@ -313,6 +316,25 @@ public abstract class AbstractSVGPainter extends AbstractXMLWritingIFPainter // TODO Auto-generated method stub } + /** {@inheritDoc} */ + public void drawLine(Point start, Point end, int width, Color color, RuleStyle style) + throws IFException { + try { + establish(MODE_NORMAL); + AttributesImpl atts = new AttributesImpl(); + atts.addAttribute("", "x1", "x1", CDATA, Integer.toString(start.x)); + atts.addAttribute("", "y1", "y1", CDATA, Integer.toString(start.y)); + atts.addAttribute("", "x2", "x2", CDATA, Integer.toString(end.x)); + atts.addAttribute("", "y2", "y2", CDATA, Integer.toString(end.y)); + atts.addAttribute("", "stroke-width", "stroke-width", CDATA, toString(color)); + atts.addAttribute("", "fill", "fill", CDATA, toString(color)); + //TODO Handle style parameter + element("line", atts); + } catch (SAXException e) { + throw new IFException("SAX error in drawLine()", e); + } + } + /** {@inheritDoc} */ public void drawText(int x, int y, int[] dx, int[] dy, String text) throws IFException { try { -- 2.39.5