import java.awt.geom.AffineTransform;
import org.apache.fop.fo.Constants;
+import org.apache.fop.render.intermediate.BorderPainter;
import org.apache.fop.util.ColorUtil;
/**
}
break;
case Constants.EN_DASHED:
- int thick = lineDataInfo.getThickness() * 3;
if (borderPaintInfo.isHorizontal()) {
- lineDataInfo.setX2 ( lineDataInfo.getX1() + thick );
+ int dashWidth = (int) (BorderPainter.dashWidthCalculator(x2 - x1, thickness));
+ lineDataInfo.setX2 ( lineDataInfo.getX1() + dashWidth );
lineDataInfo.setY2 ( lineDataInfo.getY1() );
int ex2 = Math.round(x2);
- while (lineDataInfo.getX1() + thick < ex2) {
+ int spaceWidth = (int) (BorderPainter.DASHED_BORDER_SPACE_RATIO * dashWidth);
+ while (lineDataInfo.getX2() < ex2) {
dataStream.createLine(lineDataInfo);
- lineDataInfo.setX1 ( lineDataInfo.getX1() + 2 * thick );
- lineDataInfo.setX2 ( lineDataInfo.getX1() + thick );
+ lineDataInfo.setX1 ( lineDataInfo.getX2() + spaceWidth );
+ lineDataInfo.setX2 ( lineDataInfo.getX1() + dashWidth );
}
} else {
+ int dashWidth = (int) BorderPainter.dashWidthCalculator(y2 - y1, thickness);
lineDataInfo.setX2 ( lineDataInfo.getX1() );
- lineDataInfo.setY2 ( lineDataInfo.getY1() + thick );
+ lineDataInfo.setY2 ( lineDataInfo.getY1() + dashWidth );
int ey2 = Math.round(y2);
- while (lineDataInfo.getY1() + thick < ey2) {
+ int spaceWidth = (int) (BorderPainter.DASHED_BORDER_SPACE_RATIO * dashWidth);
+ while (lineDataInfo.getY2() < ey2) {
dataStream.createLine(lineDataInfo);
- lineDataInfo.setY1 ( lineDataInfo.getY1() + 2 * thick );
- lineDataInfo.setY2 ( lineDataInfo.getY1() + thick );
+ lineDataInfo.setY1 ( lineDataInfo.getY2() + spaceWidth );
+ lineDataInfo.setY2 ( lineDataInfo.getY1() + dashWidth );
}
}
break;
/** Convention index of bottom-left border corners */
protected static final int BOTTOM_LEFT = 3;
+ /** The ratio between a solid dash and the white-space in a dashed-border */
+ public static final float DASHED_BORDER_SPACE_RATIO = 0.5f;
+ /** The length of the dash as a factor of the border width i.e. 4 -> dashWidth = 4*borderWidth */
+ protected static final float DASHED_BORDER_LENGTH_FACTOR = 4.0f;
+
private final GraphicsPainter graphicsPainter;
public BorderPainter(GraphicsPainter graphicsPainter) {
return bp != null && bp.isCollapseOuter();
}
+ /**
+ * This method calculates the length of the "dash" in a dashed border. The dash satisfies the
+ * condition that corners start on a dash and end with a dash (rather than ending with a white space).
+ * @param borderLength The length of the border.
+ * @param borderWidth The width/thickness of the border.
+ * @param dashSpaceRatio The ratio between dashes and white-space.
+ * @return returns the length of the dash such that it fits the criteria above.
+ */
+ public static float dashWidthCalculator(float borderLength, float borderWidth) {
+ float dashWidth = DASHED_BORDER_LENGTH_FACTOR * borderWidth;
+ int period = (int) ((borderLength - dashWidth) / dashWidth / (1.0f + DASHED_BORDER_SPACE_RATIO));
+ period = period < 0 ? 0 : period;
+ return borderLength / (period * (1.0f + DASHED_BORDER_SPACE_RATIO) + 1.0f);
+ }
+
/** TODO merge with drawRectangularBorders?
* @param borderRect the border rectangle
* @param bpsBefore the border specification on the before side
import org.apache.fop.fo.Constants;
import org.apache.fop.render.intermediate.ArcToBezierCurveTransformer;
import org.apache.fop.render.intermediate.BezierCurvePainter;
+import org.apache.fop.render.intermediate.BorderPainter;
import org.apache.fop.render.intermediate.GraphicsPainter;
import org.apache.fop.traits.RuleStyle;
import org.apache.fop.util.ColorUtil;
case Constants.EN_DASHED:
generator.setColor(col);
if (horz) {
- float unit = Math.abs(2 * h);
- int rep = (int) (w / unit);
- if (rep % 2 == 0) {
- rep++;
- }
- unit = w / rep;
+ float dashedWidth = BorderPainter.dashWidthCalculator(w, h);
float ym = y1 + (h / 2);
- generator.setDashLine(unit)
+ generator.setDashLine(dashedWidth, dashedWidth * BorderPainter.DASHED_BORDER_SPACE_RATIO)
.setLineWidth(h)
.strokeLine(x1, ym, x2, ym);
} else {
- float unit = Math.abs(2 * w);
- int rep = (int) (h / unit);
- if (rep % 2 == 0) {
- rep++;
- }
- unit = h / rep;
+ float dashedWidth = BorderPainter.dashWidthCalculator(h, w);
float xm = x1 + (w / 2);
- generator.setDashLine(unit)
+ generator.setDashLine(dashedWidth, dashedWidth * BorderPainter.DASHED_BORDER_SPACE_RATIO)
.setLineWidth(w)
.strokeLine(xm, y1, xm, y2);
}
import org.apache.fop.fo.Constants;
import org.apache.fop.render.intermediate.ArcToBezierCurveTransformer;
import org.apache.fop.render.intermediate.BezierCurvePainter;
+import org.apache.fop.render.intermediate.BorderPainter;
import org.apache.fop.render.intermediate.GraphicsPainter;
import org.apache.fop.traits.RuleStyle;
import org.apache.fop.util.ColorUtil;
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");
+ float dashWidth = BorderPainter.dashWidthCalculator(w, h);
+ gen.useDash("[" + dashWidth + " " + BorderPainter.DASHED_BORDER_SPACE_RATIO
+ * dashWidth + "] 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");
+ float dashWidth = BorderPainter.dashWidthCalculator(h, w);
+ gen.useDash("[" + dashWidth + " " + BorderPainter.DASHED_BORDER_SPACE_RATIO
+ * dashWidth + "] 0");
gen.useLineCap(0);
gen.useLineWidth(w);
float xm = x1 + (w / 2);
documents. Example: the fix of marks layering will be such a case when it's done.
-->
<release version="FOP Trunk" date="TBD">
+ <action context="Code" dev="MH" type="add" fixes-bug="45822">
+ Changed the dashed borders to appear more like dashes and less like dots
+ </action>
<action context="Code" dev="PH" type="add" fixes-bug="54041">
Added support for Rounded Corners on block areas.
</action>
import org.junit.Test;
-import org.apache.fop.fo.Constants;
-import org.apache.fop.traits.BorderProps;
-import org.apache.fop.traits.BorderProps.Mode;
-
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
+import org.apache.fop.fo.Constants;
+import org.apache.fop.traits.BorderProps;
+import org.apache.fop.traits.BorderProps.Mode;
+
public class BorderPainterTestCase {
private static final BorderProps BORDER_PROPS = new BorderProps(Constants.EN_SOLID, 10, 50, 50,
--- /dev/null
+package org.apache.fop.render.pdf;
+
+import java.awt.Color;
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.fop.fo.Constants;
+import org.apache.fop.pdf.PDFDocument;
+
+public class PDFBorderPainterTestCase {
+
+ private PDFContentGenerator generator;
+ private ByteArrayOutputStream outStream;
+ private PDFGraphicsPainter borderPainter;
+
+ @Before
+ public void setUp() {
+ outStream = new ByteArrayOutputStream();
+ generator = new PDFContentGenerator(new PDFDocument("test"), outStream, null);
+ borderPainter = new PDFGraphicsPainter(generator);
+ }
+
+ /**
+ * This test will fail if either of the below statements isn't true:
+ * org.apache.fop.render.intermediate.BorderPainter.DASHED_BORDER_SPACE_RATIO = 0.5f:q
+ * org.apache.fop.render.intermediate.BorderPainter.DASHED_BORDER_LENGTH_FACTOR = 4.0f.
+ */
+ @Test
+ public void testDrawBorderLine() throws Exception {
+ borderPainter.drawBorderLine(0, 0, 40000, 1000, true, true,
+ Constants.EN_DASHED, Color.BLACK);
+ generator.flushPDFDoc();
+ OutputStream outStream = new ByteArrayOutputStream();
+ outStream = generator.getStream().getBufferOutputStream();
+ assertTrue(((ByteArrayOutputStream) outStream).toString().contains("[4 2] 0 d 1 w"));
+ }
+
+ public void tearDown() {
+ generator = null;
+ outStream= null;
+ }
+}
--- /dev/null
+package org.apache.fop.render.ps;
+
+import java.awt.Color;
+import java.io.ByteArrayOutputStream;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.xmlgraphics.ps.PSGenerator;
+
+import org.apache.fop.fo.Constants;
+
+public class PSBorderPainterTestCase {
+
+ private PSGenerator generator;
+ private ByteArrayOutputStream outStream;
+ private PSGraphicsPainter borderPainter;
+
+ @Before
+ public void setUp() {
+ outStream = new ByteArrayOutputStream();
+ generator = new PSGenerator(outStream);
+ borderPainter = new PSGraphicsPainter(generator);
+ }
+
+ /**
+ * This test will fail if either of the below statements isn't true:
+ * org.apache.fop.render.intermediate.BorderPainter.DASHED_BORDER_SPACE_RATIO = 0.5f:q
+ * org.apache.fop.render.intermediate.BorderPainter.DASHED_BORDER_LENGTH_FACTOR = 4.0f.
+ */
+ @Test
+ public void testDrawBorderLine() throws Exception {
+ borderPainter.drawBorderLine(0, 0, 40000, 1000, true, true,
+ Constants.EN_DASHED, Color.BLACK);
+ assertTrue(outStream.toString().contains("[4.0 2.0] 0 setdash"));
+ }
+
+ public void tearDown() {
+ generator = null;
+ outStream= null;
+ }
+}