Skip to content

Commit c5f55eb

Browse files
committed
FOP-3286 Fix rounded borders
1 parent d5ea4d1 commit c5f55eb

2 files changed

Lines changed: 92 additions & 5 deletions

File tree

fop-core/src/main/java/org/apache/fop/render/intermediate/BorderPainter.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -317,11 +317,25 @@ protected void drawRoundedBorders(Rectangle borderRect,
317317
//Determine scale factor if any adjacent elliptic corners overlap
318318
double cornerCorrectionFactor = calculateCornerScaleCorrection(width, height, before, after, start,
319319
end);
320-
drawBorderSegment(start, before, end, 0, width, startx, starty, cornerCorrectionFactor);
321-
drawBorderSegment(before, end, after, 1, height, startx + width, starty, cornerCorrectionFactor);
322-
drawBorderSegment(end, after, start, 2, width, startx + width, starty + height,
323-
cornerCorrectionFactor);
324-
drawBorderSegment(after, start, before, 3, height, startx, starty + height, cornerCorrectionFactor);
320+
321+
if (hasRadius(before) || hasRadius(after) || hasRadius(start) || hasRadius(end)) {
322+
drawBorderSegment(before, end, after, 1, height, startx + width, starty, cornerCorrectionFactor);
323+
drawBorderSegment(after, start, before, 3, height, startx, starty + height, cornerCorrectionFactor);
324+
325+
drawBorderSegment(start, before, end, 0, width, startx, starty, cornerCorrectionFactor);
326+
drawBorderSegment(end, after, start, 2, width, startx + width, starty + height,
327+
cornerCorrectionFactor);
328+
} else {
329+
drawBorderSegment(start, before, end, 0, width, startx, starty, cornerCorrectionFactor);
330+
drawBorderSegment(before, end, after, 1, height, startx + width, starty, cornerCorrectionFactor);
331+
drawBorderSegment(end, after, start, 2, width, startx + width, starty + height,
332+
cornerCorrectionFactor);
333+
drawBorderSegment(after, start, before, 3, height, startx, starty + height, cornerCorrectionFactor);
334+
}
335+
}
336+
337+
private boolean hasRadius(BorderSegment segment) {
338+
return segment.getRadiusStart() != 0 || segment.getRadiusEnd() != 0;
325339
}
326340

327341
private void drawBorderSegment(BorderSegment start, BorderSegment before, BorderSegment end,

fop-core/src/test/java/org/apache/fop/render/intermediate/BorderPainterTestCase.java

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@
2222
import java.io.IOException;
2323

2424
import org.junit.Test;
25+
import org.mockito.InOrder;
2526
import static org.junit.Assert.assertEquals;
2627
import static org.mockito.Mockito.atLeastOnce;
2728
import static org.mockito.Mockito.doThrow;
29+
import static org.mockito.Mockito.inOrder;
2830
import static org.mockito.Mockito.mock;
2931
import static org.mockito.Mockito.never;
3032
import static org.mockito.Mockito.times;
@@ -35,6 +37,7 @@
3537
import org.apache.fop.traits.BorderProps;
3638
import org.apache.fop.traits.BorderProps.Mode;
3739

40+
3841
public class BorderPainterTestCase {
3942

4043
private static final BorderProps BORDER_PROPS = new BorderProps(Constants.EN_SOLID, 10, 50, 50,
@@ -73,6 +76,10 @@ private void test(BorderPainterTester<?> tester) throws IOException {
7376
tester.test();
7477
}
7578

79+
private void testOrientation(BorderPainterTester<?> tester) throws IOException {
80+
tester.testOrientation();
81+
}
82+
7683
@Test (expected = IFException.class)
7784
public void drawBordersThrowsIFException() throws Exception {
7885
GraphicsPainter graphicsPainter = mock(GraphicsPainter.class);
@@ -89,6 +96,12 @@ public void testDrawRectangularBorders() throws IOException {
8996
.beforeBorder().setWidth(0).tester());
9097
}
9198

99+
@Test
100+
public void testDrawRectangularBordersOrientation() throws IOException {
101+
testOrientation(new DrawRectangularBordersTester(0, 0, 1000, 1000)
102+
.setBorderWidth(10).beforeBorder().setWidth(10).tester());
103+
}
104+
92105
@Test
93106
public void testDrawRectangularBordersWithNullBorders() throws IOException, IFException {
94107
GraphicsPainter graphicsPainter = mock(GraphicsPainter.class);
@@ -112,6 +125,12 @@ public void drawRoundedBorders() throws Exception {
112125
test(new DrawRoundedBordersTester(0, 0, 60, 60).setBorderWidth(4).setCornerRadii(30));
113126
}
114127

128+
@Test
129+
public void drawRoundedBordersOrientation() throws Exception {
130+
testOrientation(new DrawRoundedBordersTester(0, 0, 100, 100).setBorderWidth(15)
131+
.setCornerRadii(10).beforeBorder().setWidth(5).tester());
132+
}
133+
115134
@Test
116135
public void testDrawRoundedBordersWithNullBorders() throws IOException, IFException {
117136
GraphicsPainter graphicsPainter = mock(GraphicsPainter.class);
@@ -244,8 +263,18 @@ public final void test() throws IOException {
244263
testMethod();
245264
}
246265

266+
public void testOrientation() throws IOException {
267+
before = beforeBuilder.build();
268+
after = afterBuilder.build();
269+
end = endBuilder.build();
270+
start = startBuilder.build();
271+
testMethodOrientation();
272+
}
273+
247274
protected abstract void testMethod() throws IOException;
248275

276+
protected abstract void testMethodOrientation() throws IOException;
277+
249278
protected static int numberOfNonZeroBorders(BorderProps first, BorderProps... borders) {
250279
int i = first.width == 0 ? 0 : 1;
251280
for (BorderProps borderProp : borders) {
@@ -339,6 +368,26 @@ public void testMethod() throws IOException {
339368
verifyDrawing();
340369
}
341370

371+
@Override
372+
protected void testMethodOrientation() throws IOException {
373+
sut.drawRoundedBorders(borderExtent, before, after, start, end);
374+
375+
InOrder inOrder = inOrder(graphicsPainter);
376+
377+
// orientation 0
378+
inOrder.verify(graphicsPainter, times(0)).rotateCoordinates(0);
379+
inOrder.verify(graphicsPainter).closePath();
380+
// orientation 1
381+
inOrder.verify(graphicsPainter).rotateCoordinates(Math.PI / 2d);
382+
inOrder.verify(graphicsPainter).closePath();
383+
// orientation 2
384+
inOrder.verify(graphicsPainter).rotateCoordinates(Math.PI * 2 / 2d);
385+
inOrder.verify(graphicsPainter).closePath();
386+
// orientation 3
387+
inOrder.verify(graphicsPainter).rotateCoordinates(Math.PI * 3 / 2d);
388+
inOrder.verify(graphicsPainter).closePath();
389+
}
390+
342391
private void verifyDrawing() throws IOException {
343392
final int rectX = borderExtent.x;
344393
final int rectY = borderExtent.y;
@@ -400,6 +449,25 @@ public void testMethod() throws IOException {
400449
verifyDrawing();
401450
}
402451

452+
public void testMethodOrientation() throws IOException {
453+
sut.drawRoundedBorders(borderExtent, before, after, start, end);
454+
455+
InOrder inOrder = inOrder(graphicsPainter);
456+
457+
// orientation 1
458+
inOrder.verify(graphicsPainter).rotateCoordinates(Math.PI / 2d);
459+
inOrder.verify(graphicsPainter).closePath();
460+
// orientation 3
461+
inOrder.verify(graphicsPainter).rotateCoordinates(Math.PI * 3 / 2d);
462+
inOrder.verify(graphicsPainter).closePath();
463+
// orientation 0
464+
inOrder.verify(graphicsPainter, times(0)).rotateCoordinates(0);
465+
inOrder.verify(graphicsPainter).closePath();
466+
// orientation 2
467+
inOrder.verify(graphicsPainter).rotateCoordinates(Math.PI * 2 / 2d);
468+
inOrder.verify(graphicsPainter).closePath();
469+
}
470+
403471
private void verifyDrawing() throws IOException {
404472
int numBorders = numberOfNonZeroBorders();
405473
final int rectWidth = borderExtent.width;
@@ -482,6 +550,11 @@ public void testMethod() throws IOException {
482550
verifyClipping();
483551
}
484552

553+
@Override
554+
protected void testMethodOrientation() throws IOException {
555+
//not needed
556+
}
557+
485558
private void verifyClipping() throws IOException {
486559
int xOrigin = borderExtent.x;
487560
int yOrigin = borderExtent.y;

0 commit comments

Comments
 (0)