From 34ecb4c0e098856c1249025865c05ea34b46b51e Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Fri, 19 Dec 2008 09:31:15 +0000 Subject: [PATCH] Borders and leaders/rules for the PostScript painter. BorderPainter methods throw IOException (needed for PostScript). Some Javadocs. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign@727986 13f79535-47bb-0310-9956-ffa450edef68 --- .../render/intermediate/BorderPainter.java | 74 +++- .../fop/render/java2d/Java2DPainter.java | 7 +- .../org/apache/fop/render/pdf/PDFPainter.java | 6 +- .../apache/fop/render/pdf/PDFRenderer.java | 1 + .../apache/fop/render/ps/PSBorderPainter.java | 324 ++++++++++++++++++ .../org/apache/fop/render/ps/PSPainter.java | 8 +- .../org/apache/fop/render/ps/PSRenderer.java | 222 +----------- 7 files changed, 422 insertions(+), 220 deletions(-) create mode 100644 src/java/org/apache/fop/render/ps/PSBorderPainter.java diff --git a/src/java/org/apache/fop/render/intermediate/BorderPainter.java b/src/java/org/apache/fop/render/intermediate/BorderPainter.java index e8874dc69..75f773291 100644 --- a/src/java/org/apache/fop/render/intermediate/BorderPainter.java +++ b/src/java/org/apache/fop/render/intermediate/BorderPainter.java @@ -22,6 +22,7 @@ package org.apache.fop.render.intermediate; import java.awt.Color; import java.awt.Point; import java.awt.Rectangle; +import java.io.IOException; import org.apache.fop.traits.BorderProps; import org.apache.fop.traits.RuleStyle; @@ -38,10 +39,11 @@ public abstract class BorderPainter { * @param bpsAfter the border specification on the after side * @param bpsStart the border specification on the start side * @param bpsEnd the border specification on the end side + * @throws IOException if an I/O error occurs while creating the borders */ public void drawBorders(Rectangle borderRect, BorderProps bpsBefore, BorderProps bpsAfter, - BorderProps bpsStart, BorderProps bpsEnd) { + BorderProps bpsStart, BorderProps bpsEnd) throws IOException { int startx = borderRect.x; int starty = borderRect.y; int width = borderRect.width; @@ -199,21 +201,75 @@ public abstract class BorderPainter { } + /** + * Draws a border line. + * @param x1 X coordinate of the upper left corner + * of the line's bounding rectangle (in millipoints) + * @param y1 start Y coordinate of the upper left corner + * of the line's bounding rectangle (in millipoints) + * @param x2 end X coordinate of the lower right corner + * of the line's bounding rectangle (in millipoints) + * @param y2 end y coordinate of the lower right corner + * of the line's bounding rectangle (in millipoints) + * @param horz true if it is a horizontal line + * @param startOrBefore true if the line is the start or end edge of a border box + * @param style the border style + * @param color the border color + * @throws IOException if an I/O error occurs + */ protected abstract void drawBorderLine(int x1, int y1, int x2, int y2, - boolean horz, boolean startOrBefore, int style, Color color); + boolean horz, boolean startOrBefore, int style, Color color) throws IOException; + /** + * Draws a line/rule. + * @param start start point (coordinates in millipoints) + * @param end end point (coordinates in millipoints) + * @param width width of the line + * @param color the line color + * @param style the rule style + * @throws IOException if an I/O error occurs + */ public abstract void drawLine(Point start, Point end, - int width, Color color, RuleStyle style); + int width, Color color, RuleStyle style) throws IOException; - protected abstract void moveTo(int x, int y); + /** + * Moves the cursor to the given coordinate. + * @param x the X coordinate (in millipoints) + * @param y the Y coordinate (in millipoints) + * @throws IOException if an I/O error occurs + */ + protected abstract void moveTo(int x, int y) throws IOException; - protected abstract void lineTo(int x, int y); + /** + * Draws a line from the current cursor position to the given coordinates. + * @param x the X coordinate (in millipoints) + * @param y the Y coordinate (in millipoints) + * @throws IOException if an I/O error occurs + */ + protected abstract void lineTo(int x, int y) throws IOException; - protected abstract void closePath(); + /** + * Closes the current path. + * @throws IOException if an I/O error occurs + */ + protected abstract void closePath() throws IOException; + + /** + * Reduces the current clipping region to the current path. + * @throws IOException if an I/O error occurs + */ + protected abstract void clip() throws IOException; - protected abstract void clip(); + /** + * Save the graphics state on the stack. + * @throws IOException if an I/O error occurs + */ + protected abstract void saveGraphicsState() throws IOException; - protected abstract void saveGraphicsState(); - protected abstract void restoreGraphicsState(); + /** + * Restore the last graphics state from the stack. + * @throws IOException if an I/O error occurs + */ + protected abstract void restoreGraphicsState() throws IOException; } diff --git a/src/java/org/apache/fop/render/java2d/Java2DPainter.java b/src/java/org/apache/fop/render/java2d/Java2DPainter.java index 9da39a319..34fbb3384 100644 --- a/src/java/org/apache/fop/render/java2d/Java2DPainter.java +++ b/src/java/org/apache/fop/render/java2d/Java2DPainter.java @@ -190,7 +190,12 @@ public class Java2DPainter extends AbstractIFPainter { public void drawBorderRect(Rectangle rect, BorderProps before, BorderProps after, BorderProps start, BorderProps end) throws IFException { if (before != null || after != null || start != null || end != null) { - this.borderPainter.drawBorders(rect, before, after, start, end); + try { + this.borderPainter.drawBorders(rect, before, after, start, end); + } catch (IOException e) { + //Won't happen with Java2D + throw new IllegalStateException("Unexpected I/O error"); + } } } diff --git a/src/java/org/apache/fop/render/pdf/PDFPainter.java b/src/java/org/apache/fop/render/pdf/PDFPainter.java index 8e29ded4c..339acbb24 100644 --- a/src/java/org/apache/fop/render/pdf/PDFPainter.java +++ b/src/java/org/apache/fop/render/pdf/PDFPainter.java @@ -227,7 +227,11 @@ public class PDFPainter extends AbstractIFPainter { BorderProps start, BorderProps end) throws IFException { if (before != null || after != null || start != null || end != null) { generator.endTextObject(); - this.borderPainter.drawBorders(rect, before, after, start, end); + try { + this.borderPainter.drawBorders(rect, before, after, start, end); + } catch (IOException ioe) { + throw new IFException("I/O error while drawing borders", ioe); + } } } diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java index e0e1bab69..c40c94fc4 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java @@ -482,6 +482,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer implements PDFConf this.pdfDoc.addObject(annots); } this.pdfDoc.addObject(currentPage); + this.borderPainter = null; this.generator.flushPDFDoc(); this.generator = null; } diff --git a/src/java/org/apache/fop/render/ps/PSBorderPainter.java b/src/java/org/apache/fop/render/ps/PSBorderPainter.java new file mode 100644 index 000000000..97f621507 --- /dev/null +++ b/src/java/org/apache/fop/render/ps/PSBorderPainter.java @@ -0,0 +1,324 @@ +/* + * 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.render.ps; + +import java.awt.Color; +import java.awt.Point; +import java.io.IOException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.xmlgraphics.ps.PSGenerator; + +import org.apache.fop.fo.Constants; +import org.apache.fop.render.intermediate.BorderPainter; +import org.apache.fop.traits.RuleStyle; +import org.apache.fop.util.ColorUtil; + +/** + * PostScript-specific implementation of the {@code BorderPainter}. + */ +public class PSBorderPainter extends BorderPainter { + + /** logging instance */ + private static Log log = LogFactory.getLog(PSBorderPainter.class); + + private PSGenerator generator; + + /** + * Creates a new border painter for PostScript. + * @param generator the PostScript generator + */ + public PSBorderPainter(PSGenerator generator) { + this.generator = generator; + } + + /** {@inheritDoc} */ + protected void drawBorderLine(int x1, int y1, int x2, int y2, boolean horz, + boolean startOrBefore, int style, Color col) throws IOException { + drawBorderLine(generator, toPoints(x1), toPoints(y1), toPoints(x2), toPoints(y2), + horz, startOrBefore, style, col); + } + + private static void drawLine(PSGenerator gen, + float startx, float starty, float endx, float endy) throws IOException { + gen.writeln(gen.formatDouble(startx) + " " + + gen.formatDouble(starty) + " M " + + gen.formatDouble(endx) + " " + + gen.formatDouble(endy) + " lineto stroke newpath"); + } + + /** {@inheritDoc} */ + public static void drawBorderLine(PSGenerator gen, + float x1, float y1, float x2, float y2, boolean horz, + boolean startOrBefore, int style, Color col) throws IOException { + float w = x2 - x1; + float h = y2 - y1; + if ((w < 0) || (h < 0)) { + log.error("Negative extent received. Border won't be painted."); + return; + } + switch (style) { + case Constants.EN_DASHED: + gen.useColor(col); + if (horz) { + float unit = Math.abs(2 * h); + int rep = (int)(w / unit); + if (rep % 2 == 0) { + rep++; + } + unit = w / rep; + gen.useDash("[" + unit + "] 0"); + gen.useLineCap(0); + gen.useLineWidth(h); + float ym = y1 + (h / 2); + drawLine(gen, x1, ym, x2, ym); + } else { + float unit = Math.abs(2 * w); + int rep = (int)(h / unit); + if (rep % 2 == 0) { + rep++; + } + unit = h / rep; + gen.useDash("[" + unit + "] 0"); + gen.useLineCap(0); + gen.useLineWidth(w); + float xm = x1 + (w / 2); + drawLine(gen, xm, y1, xm, y2); + } + break; + case Constants.EN_DOTTED: + gen.useColor(col); + gen.useLineCap(1); //Rounded! + if (horz) { + float unit = Math.abs(2 * h); + int rep = (int)(w / unit); + if (rep % 2 == 0) { + rep++; + } + unit = w / rep; + gen.useDash("[0 " + unit + "] 0"); + gen.useLineWidth(h); + float ym = y1 + (h / 2); + drawLine(gen, x1, ym, x2, ym); + } else { + float unit = Math.abs(2 * w); + int rep = (int)(h / unit); + if (rep % 2 == 0) { + rep++; + } + unit = h / rep; + gen.useDash("[0 " + unit + "] 0"); + gen.useLineWidth(w); + float xm = x1 + (w / 2); + drawLine(gen, xm, y1, xm, y2); + } + break; + case Constants.EN_DOUBLE: + gen.useColor(col); + gen.useDash(null); + if (horz) { + float h3 = h / 3; + gen.useLineWidth(h3); + float ym1 = y1 + (h3 / 2); + float ym2 = ym1 + h3 + h3; + drawLine(gen, x1, ym1, x2, ym1); + drawLine(gen, x1, ym2, x2, ym2); + } else { + float w3 = w / 3; + gen.useLineWidth(w3); + float xm1 = x1 + (w3 / 2); + float xm2 = xm1 + w3 + w3; + drawLine(gen, xm1, y1, xm1, y2); + drawLine(gen, xm2, y1, xm2, y2); + } + break; + case Constants.EN_GROOVE: + case Constants.EN_RIDGE: + float colFactor = (style == Constants.EN_GROOVE ? 0.4f : -0.4f); + gen.useDash(null); + if (horz) { + Color uppercol = ColorUtil.lightenColor(col, -colFactor); + Color lowercol = ColorUtil.lightenColor(col, colFactor); + float h3 = h / 3; + gen.useLineWidth(h3); + float ym1 = y1 + (h3 / 2); + gen.useColor(uppercol); + drawLine(gen, x1, ym1, x2, ym1); + gen.useColor(col); + drawLine(gen, x1, ym1 + h3, x2, ym1 + h3); + gen.useColor(lowercol); + drawLine(gen, x1, ym1 + h3 + h3, x2, ym1 + h3 + h3); + } else { + Color leftcol = ColorUtil.lightenColor(col, -colFactor); + Color rightcol = ColorUtil.lightenColor(col, colFactor); + float w3 = w / 3; + gen.useLineWidth(w3); + float xm1 = x1 + (w3 / 2); + gen.useColor(leftcol); + drawLine(gen, xm1, y1, xm1, y2); + gen.useColor(col); + drawLine(gen, xm1 + w3, y1, xm1 + w3, y2); + gen.useColor(rightcol); + drawLine(gen, xm1 + w3 + w3, y1, xm1 + w3 + w3, y2); + } + break; + case Constants.EN_INSET: + case Constants.EN_OUTSET: + colFactor = (style == Constants.EN_OUTSET ? 0.4f : -0.4f); + gen.useDash(null); + if (horz) { + Color c = ColorUtil.lightenColor(col, (startOrBefore ? 1 : -1) * colFactor); + gen.useLineWidth(h); + float ym1 = y1 + (h / 2); + gen.useColor(c); + drawLine(gen, x1, ym1, x2, ym1); + } else { + Color c = ColorUtil.lightenColor(col, (startOrBefore ? 1 : -1) * colFactor); + gen.useLineWidth(w); + float xm1 = x1 + (w / 2); + gen.useColor(c); + drawLine(gen, xm1, y1, xm1, y2); + } + break; + case Constants.EN_HIDDEN: + break; + default: + gen.useColor(col); + gen.useDash(null); + gen.useLineCap(0); + if (horz) { + gen.useLineWidth(h); + float ym = y1 + (h / 2); + drawLine(gen, x1, ym, x2, ym); + } else { + gen.useLineWidth(w); + float xm = x1 + (w / 2); + drawLine(gen, xm, y1, xm, y2); + } + } + } + + /** {@inheritDoc} */ + public void drawLine(Point start, Point end, + int width, Color color, RuleStyle style) throws IOException { + 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, starty, end.x, starty + width, + true, true, style.getEnumValue(), color); + break; + case Constants.EN_DOTTED: + clipRect(start.x, starty, end.x - start.x, width); + //This displaces the dots to the right by half a dot's width + //TODO There's room for improvement here + generator.concatMatrix(1, 0, 0, 1, toPoints(half), 0); + drawBorderLine(start.x, starty, end.x, starty + width, + true, true, style.getEnumValue(), color); + break; + case Constants.EN_GROOVE: + case Constants.EN_RIDGE: + generator.useColor(ColorUtil.lightenColor(color, 0.6f)); + moveTo(start.x, starty); + lineTo(end.x, starty); + lineTo(end.x, starty + 2 * half); + lineTo(start.x, starty + 2 * half); + closePath(); + generator.writeln(" fill newpath"); + generator.useColor(color); + if (style == RuleStyle.GROOVE) { + moveTo(start.x, starty); + lineTo(end.x, starty); + lineTo(end.x, starty + half); + lineTo(start.x + half, starty + half); + lineTo(start.x, starty + 2 * half); + } else { + moveTo(end.x, starty); + lineTo(end.x, starty + 2 * half); + lineTo(start.x, starty + 2 * half); + lineTo(start.x, starty + half); + lineTo(end.x - half, starty + half); + } + closePath(); + generator.writeln(" fill newpath"); + break; + default: + throw new UnsupportedOperationException("rule style not supported"); + } + + restoreGraphicsState(); + + } + + private static float toPoints(int mpt) { + return mpt / 1000f; + } + + /** {@inheritDoc} */ + protected void moveTo(int x, int y) throws IOException { + generator.writeln(generator.formatDouble(toPoints(x)) + " " + + generator.formatDouble(toPoints(y)) + " M"); + } + + /** {@inheritDoc} */ + protected void lineTo(int x, int y) throws IOException { + generator.writeln(generator.formatDouble(toPoints(x)) + " " + + generator.formatDouble(toPoints(y)) + " lineto"); + } + + /** {@inheritDoc} */ + protected void closePath() throws IOException { + generator.writeln("cp"); + } + + private void clipRect(int x, int y, int width, int height) throws IOException { + generator.defineRect(toPoints(x), toPoints(y), toPoints(width), toPoints(height)); + clip(); + } + + /** {@inheritDoc} */ + protected void clip() throws IOException { + generator.writeln("clip newpath"); + } + + /** {@inheritDoc} */ + protected void saveGraphicsState() throws IOException { + generator.saveGraphicsState(); + } + + /** {@inheritDoc} */ + protected void restoreGraphicsState() throws IOException { + generator.restoreGraphicsState(); + } + +} diff --git a/src/java/org/apache/fop/render/ps/PSPainter.java b/src/java/org/apache/fop/render/ps/PSPainter.java index 3c937addf..a55d20739 100644 --- a/src/java/org/apache/fop/render/ps/PSPainter.java +++ b/src/java/org/apache/fop/render/ps/PSPainter.java @@ -64,6 +64,7 @@ public class PSPainter extends AbstractIFPainter { private static Log log = LogFactory.getLog(PSPainter.class); private PSDocumentHandler documentHandler; + private PSBorderPainter borderPainter; private boolean inTextMode = false; @@ -74,6 +75,7 @@ public class PSPainter extends AbstractIFPainter { public PSPainter(PSDocumentHandler documentHandler) { super(); this.documentHandler = documentHandler; + this.borderPainter = new PSBorderPainter(documentHandler.gen); this.state = IFState.create(); } @@ -236,9 +238,8 @@ public class PSPainter extends AbstractIFPainter { BorderProps start, BorderProps end) throws IFException { if (before != null || after != null || start != null || end != null) { try { - //TODO Implement me endTextObject(); - //this.borderPainter.drawBorders(rect, before, after, start, end); + this.borderPainter.drawBorders(rect, before, after, start, end); } catch (IOException ioe) { throw new IFException("I/O error in drawBorderRect()", ioe); } @@ -249,9 +250,8 @@ public class PSPainter extends AbstractIFPainter { public void drawLine(Point start, Point end, int width, Color color, RuleStyle style) throws IFException { try { - //TODO Implement me endTextObject(); - //this.borderPainter.drawLine(start, end, width, color, style); + this.borderPainter.drawLine(start, end, width, color, style); } catch (IOException ioe) { throw new IFException("I/O error in drawLine()", ioe); } diff --git a/src/java/org/apache/fop/render/ps/PSRenderer.java b/src/java/org/apache/fop/render/ps/PSRenderer.java index 55f714f31..19fcd8af8 100644 --- a/src/java/org/apache/fop/render/ps/PSRenderer.java +++ b/src/java/org/apache/fop/render/ps/PSRenderer.java @@ -21,6 +21,7 @@ package org.apache.fop.render.ps; // Java import java.awt.Color; +import java.awt.Point; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; @@ -37,7 +38,6 @@ import java.util.Map; import javax.xml.transform.Source; -import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -80,7 +80,6 @@ import org.apache.fop.area.inline.TextArea; import org.apache.fop.area.inline.WordArea; import org.apache.fop.datatypes.URISpecification; import org.apache.fop.events.ResourceEventProducer; -import org.apache.fop.fo.Constants; import org.apache.fop.fo.extensions.ExtensionAttachment; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.LazyFont; @@ -98,8 +97,8 @@ import org.apache.fop.render.ps.extensions.PSCommentBefore; import org.apache.fop.render.ps.extensions.PSExtensionAttachment; import org.apache.fop.render.ps.extensions.PSSetPageDevice; import org.apache.fop.render.ps.extensions.PSSetupCode; +import org.apache.fop.traits.RuleStyle; import org.apache.fop.util.CharUtilities; -import org.apache.fop.util.ColorUtil; /** * Renderer that renders to PostScript. @@ -159,6 +158,7 @@ public class PSRenderer extends AbstractPathOrientedRenderer * normal rendering process. */ protected PSRenderingUtil psUtil; + private PSBorderPainter borderPainter; /** Is used to determine the document's bounding box */ private Rectangle2D documentBoundingBox; @@ -600,151 +600,7 @@ public class PSRenderer extends AbstractPathOrientedRenderer protected void drawBorderLine(float x1, float y1, float x2, float y2, boolean horz, boolean startOrBefore, int style, Color col) { try { - float w = x2 - x1; - float h = y2 - y1; - if ((w < 0) || (h < 0)) { - log.error("Negative extent received. Border won't be painted."); - return; - } - switch (style) { - case Constants.EN_DASHED: - useColor(col); - if (horz) { - float unit = Math.abs(2 * h); - int rep = (int)(w / unit); - if (rep % 2 == 0) { - rep++; - } - unit = w / rep; - gen.useDash("[" + unit + "] 0"); - gen.useLineCap(0); - gen.useLineWidth(h); - float ym = y1 + (h / 2); - drawLine(x1, ym, x2, ym); - } else { - float unit = Math.abs(2 * w); - int rep = (int)(h / unit); - if (rep % 2 == 0) { - rep++; - } - unit = h / rep; - gen.useDash("[" + unit + "] 0"); - gen.useLineCap(0); - gen.useLineWidth(w); - float xm = x1 + (w / 2); - drawLine(xm, y1, xm, y2); - } - break; - case Constants.EN_DOTTED: - useColor(col); - gen.useLineCap(1); //Rounded! - if (horz) { - float unit = Math.abs(2 * h); - int rep = (int)(w / unit); - if (rep % 2 == 0) { - rep++; - } - unit = w / rep; - gen.useDash("[0 " + unit + "] 0"); - gen.useLineWidth(h); - float ym = y1 + (h / 2); - drawLine(x1, ym, x2, ym); - } else { - float unit = Math.abs(2 * w); - int rep = (int)(h / unit); - if (rep % 2 == 0) { - rep++; - } - unit = h / rep; - gen.useDash("[0 " + unit + "] 0"); - gen.useLineWidth(w); - float xm = x1 + (w / 2); - drawLine(xm, y1, xm, y2); - } - break; - case Constants.EN_DOUBLE: - useColor(col); - gen.useDash(null); - if (horz) { - float h3 = h / 3; - gen.useLineWidth(h3); - float ym1 = y1 + (h3 / 2); - float ym2 = ym1 + h3 + h3; - drawLine(x1, ym1, x2, ym1); - drawLine(x1, ym2, x2, ym2); - } else { - float w3 = w / 3; - gen.useLineWidth(w3); - float xm1 = x1 + (w3 / 2); - float xm2 = xm1 + w3 + w3; - drawLine(xm1, y1, xm1, y2); - drawLine(xm2, y1, xm2, y2); - } - break; - case Constants.EN_GROOVE: - case Constants.EN_RIDGE: - float colFactor = (style == EN_GROOVE ? 0.4f : -0.4f); - gen.useDash(null); - if (horz) { - Color uppercol = ColorUtil.lightenColor(col, -colFactor); - Color lowercol = ColorUtil.lightenColor(col, colFactor); - float h3 = h / 3; - gen.useLineWidth(h3); - float ym1 = y1 + (h3 / 2); - gen.useColor(uppercol); - drawLine(x1, ym1, x2, ym1); - gen.useColor(col); - drawLine(x1, ym1 + h3, x2, ym1 + h3); - gen.useColor(lowercol); - drawLine(x1, ym1 + h3 + h3, x2, ym1 + h3 + h3); - } else { - Color leftcol = ColorUtil.lightenColor(col, -colFactor); - Color rightcol = ColorUtil.lightenColor(col, colFactor); - float w3 = w / 3; - gen.useLineWidth(w3); - float xm1 = x1 + (w3 / 2); - gen.useColor(leftcol); - drawLine(xm1, y1, xm1, y2); - gen.useColor(col); - drawLine(xm1 + w3, y1, xm1 + w3, y2); - gen.useColor(rightcol); - drawLine(xm1 + w3 + w3, y1, xm1 + w3 + w3, y2); - } - break; - case Constants.EN_INSET: - case Constants.EN_OUTSET: - colFactor = (style == EN_OUTSET ? 0.4f : -0.4f); - gen.useDash(null); - if (horz) { - Color c = ColorUtil.lightenColor(col, (startOrBefore ? 1 : -1) * colFactor); - gen.useLineWidth(h); - float ym1 = y1 + (h / 2); - gen.useColor(c); - drawLine(x1, ym1, x2, ym1); - } else { - Color c = ColorUtil.lightenColor(col, (startOrBefore ? 1 : -1) * colFactor); - gen.useLineWidth(w); - float xm1 = x1 + (w / 2); - gen.useColor(c); - drawLine(xm1, y1, xm1, y2); - } - break; - case Constants.EN_HIDDEN: - break; - default: - useColor(col); - gen.useDash(null); - gen.useLineCap(0); - if (horz) { - gen.useLineWidth(h); - float ym = y1 + (h / 2); - drawLine(x1, ym, x2, ym); - } else { - gen.useLineWidth(w); - float xm = x1 + (w / 2); - drawLine(xm, y1, xm, y2); - } - } + PSBorderPainter.drawBorderLine(gen, x1, y1, x2, y2, horz, startOrBefore, style, col); } catch (IOException ioe) { handleIOTrouble(ioe); } @@ -773,6 +629,7 @@ public class PSRenderer extends AbstractPathOrientedRenderer } }; this.gen.setPSLevel(getLanguageLevel()); + this.borderPainter = new PSBorderPainter(this.gen); this.currentPageNumber = 0; //Initial default page device dictionary settings @@ -852,6 +709,8 @@ public class PSRenderer extends AbstractPathOrientedRenderer if (pageDeviceDictionary != null) { pageDeviceDictionary.clear(); } + this.borderPainter = null; + this.gen = null; } /** @@ -1346,74 +1205,27 @@ public class PSRenderer extends AbstractPathOrientedRenderer super.renderInlineParent(ip); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void renderLeader(Leader area) { renderInlineAreaBackAndBorders(area); - endTextObject(); - 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); + endTextObject(); try { - 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 - gen.concatMatrix(1, 0, 0, 1, ruleThickness / 2, 0); - drawBorderLine(startx, starty, endx, starty + ruleThickness, - true, true, style, col); - break; - case EN_GROOVE: - case EN_RIDGE: - float half = area.getRuleThickness() / 2000f; - - gen.useColor(ColorUtil.lightenColor(col, 0.6f)); - moveTo(startx, starty); - lineTo(endx, starty); - lineTo(endx, starty + 2 * half); - lineTo(startx, starty + 2 * half); - closePath(); - gen.writeln(" fill newpath"); - gen.useColor(col); - if (style == EN_GROOVE) { - moveTo(startx, starty); - lineTo(endx, starty); - lineTo(endx, starty + half); - lineTo(startx + half, starty + half); - lineTo(startx, starty + 2 * half); - } else { - moveTo(endx, starty); - lineTo(endx, starty + 2 * half); - lineTo(startx, starty + 2 * half); - lineTo(startx, starty + half); - lineTo(endx - half, starty + half); - } - closePath(); - gen.writeln(" fill newpath"); - break; - default: - throw new UnsupportedOperationException("rule style not supported"); - } + borderPainter.drawLine(new Point(startx, starty), new Point(endx, starty), + ruleThickness, col, RuleStyle.valueOf(style)); } catch (IOException ioe) { handleIOTrouble(ioe); } - restoreGraphicsState(); super.renderLeader(area); } -- 2.39.5