Permalink
Browse files

Merge pull request #67 from igvteam/master

 Added support for winding rules to EPS, PDF, and SVG.
  • Loading branch information...
eseifert committed May 23, 2018
2 parents b2ba6a6 + 485723d commit 0c42974b4457bdafd5cfb1760259879a95ce70db
@@ -31,6 +31,7 @@
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
@@ -259,7 +260,12 @@ public void handle(Command<?> command) {
elements.add(getOutput(c.getValue(), c.getX(), c.getY()));
} else if (command instanceof FillShapeCommand) {
FillShapeCommand c = (FillShapeCommand) command;
elements.add(getOutput(c.getValue()) + " fill");
String fillMethod = " fill";
Shape shape = c.getValue();
if (shape instanceof Path2D && ((Path2D) shape).getWindingRule() == Path2D.WIND_EVEN_ODD) {
fillMethod = " eofill";
}
elements.add(getOutput(c.getValue()) + fillMethod);
} else if (command instanceof CreateCommand) {
elements.add("gsave");
} else if (command instanceof DisposeCommand) {
@@ -29,6 +29,7 @@
import java.awt.Stroke;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
@@ -505,9 +506,14 @@ private int getVersion(PDFObject object) {
}
} else if (command instanceof FillShapeCommand) {
FillShapeCommand c = (FillShapeCommand) command;
String fillMethod = " f";
Shape shape = c.getValue();
if (shape instanceof Path2D && ((Path2D) shape).getWindingRule() == Path2D.WIND_EVEN_ODD) {
fillMethod = " f*";
}
try (ByteArrayOutputStream ba = new ByteArrayOutputStream()) {
ba.write(getOutput(c.getValue()));
ba.write(serialize(" f"));
ba.write(serialize(fillMethod));
s = ba.toByteArray();
} catch (IOException e) {
throw new IllegalStateException(e);
@@ -31,6 +31,7 @@
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
@@ -283,8 +284,14 @@ public void handle(Command<?> command) {
addToGroup(e);
} else if (command instanceof FillShapeCommand) {
FillShapeCommand c = (FillShapeCommand) command;
Element e = getElement(c.getValue());
e.setAttribute("style", getStyle(true));
Shape shape = c.getValue();
Element e = getElement(shape);
if (shape instanceof Path2D) {
Path2D path = (Path2D) shape;
e.setAttribute("style", getStyle(true, path.getWindingRule() == Path2D.WIND_NON_ZERO));
} else {
e.setAttribute("style", getStyle(true));
}
addToGroup(e);
}
}
@@ -349,6 +356,10 @@ private boolean containsGroupCommand(List<Command<?>> commands) {
}
private String getStyle(boolean filled) {
return getStyle(filled, true);
}
private String getStyle(boolean filled, boolean fillRullNonZero) {
StringBuilder style = new StringBuilder();
Color color = getCurrentState().getColor();
@@ -360,6 +371,10 @@ private String getStyle(boolean filled) {
if (color.getAlpha() < 255) {
appendStyle(style, "fill-opacity", opacity);
}
if (!fillRullNonZero) {
// nonzero is the default; only need to set the style rule for non-default evenodd winding rule.
appendStyle(style, "fill-rule", "evenodd");
}
} else {
appendStyle(style, "fill", "none");
}
@@ -23,6 +23,7 @@
import static de.erichseifert.vectorgraphics2d.TestUtils.assertXMLEquals;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -76,14 +77,32 @@ public void drawShapeBlack() throws Exception {
assertXMLEquals(expected, result);
}
@Test
public void fillShapeBlack() throws Exception {
String result = process(
new FillShapeCommand(new Rectangle2D.Double(1, 2, 3, 4))
);
String expected =
HEADER + EOL +
" <rect height=\"4\" style=\"fill:rgb(255,255,255);stroke:none;\" width=\"3\" x=\"1\" y=\"2\"/>" + EOL +
FOOTER;
assertXMLEquals(expected, result);
}
@Test
public void fillShapeBlack() throws Exception {
public void fillShapeBlackEvenOdd() throws Exception {
// Example based on java.awt.LineBorder
Rectangle2D rectOuter = new Rectangle2D.Double(0, 0, 10, 10);
Rectangle2D rectInner = new Rectangle2D.Double(1, 1, 8, 8);
Path2D path = new Path2D.Double(Path2D.WIND_EVEN_ODD);
path.append(rectOuter, false);
path.append(rectInner, false);
String result = process(
new FillShapeCommand(new Rectangle2D.Double(1, 2, 3, 4))
new FillShapeCommand(path)
);
String expected =
HEADER + EOL +
" <rect height=\"4\" style=\"fill:rgb(255,255,255);stroke:none;\" width=\"3\" x=\"1\" y=\"2\"/>" + EOL +
" <path d=\"M0,0 L10.0,0 L10.0,10 L0.0,10 L0.0,0 Z M1,1 L9.0,1 L9.0,9 L1.0,9 L1.0,1 Z\" style=\"fill:rgb(255,255,255);fill-rule:evenodd;stroke:none;\"/>" + EOL +
FOOTER;
assertXMLEquals(expected, result);
}

0 comments on commit 0c42974

Please sign in to comment.