The SVG classes in the com-hfg library are designed to let you construct or parse SVG content in a modular, object-oriented way.
//--------------------------------------------------------------------------
@Test
public void testDrawPolygon()
throws Exception
{
SVG svg = new SVG().setViewBox(new Rectangle(0, 0, 1200, 400));
// Border
svg.addRect(new Rectangle(1, 1, 1198, 398))
.setFill(null)
.setStroke(Color.BLUE)
.setStrokeWidth(2);
// Star
svg.addPolygon()
.setPoints("350,75 379,161 469,161 397,215 423,301 350,250 277,301 303,215 231,161 321,161")
.setFill(Color.RED)
.setStroke(Color.BLUE)
.setStrokeWidth(10);
// Hexagon
svg.addPolygon()
.setPoints("850,75 958,137.5 958,262.5 850,325 742,262.6 742,137.5")
.setFill(HTMLColor.LIME_GREEN)
.setStroke(Color.BLUE)
.setStrokeWidth(10);
SvgDoc doc = new SvgDoc(svg);
// Write out the SVG
doc.toIndentedSVG(System.out, 0, 3);
// Generate a PNG image via the Java2D support built into the SVG objects
BufferedImage bufferedImage = new BufferedImage(svg.getWidth(), svg.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = (Graphics2D) bufferedImage.getGraphics();
RenderingHints hints = new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
hints.add(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
g2.setRenderingHints(hints);
svg.draw(g2);
File pngFile = new File("polygon.png");
ImageIO.write(bufferedImage, "png", new FileOutputStream(pngFile));
}
would produce the following SVG:
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<svg height='399' viewBox='0 0 1200 400' width='1199' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns='http://www.w3.org/2000/svg'>
<rect fill='none' height='398' stroke='#0000ff' stroke-width='2' width='1198' x='1' y='1' />
<polygon fill='#ff0000' points='350,75 379,161 469,161 397,215 423,301 350,250 277,301 303,215 231,161 321,161' stroke='#0000ff' stroke-width='10' />
<polygon fill='#32cd32' points='850,75 958,137.5 958,262.5 850,325 742,262.6 742,137.5' stroke='#0000ff' stroke-width='10' />
</svg>
and this PNG image:
//--------------------------------------------------------------------------
@Test
public void testDrawArc2()
throws Exception
{
SVG svg = new SVG().setViewBox(new Rectangle(0, 0, 1200, 400));
// Border
svg.addRect(new Rectangle(1, 1, 1198, 398))
.setFill(null)
.setStroke(Color.BLUE)
.setStrokeWidth(1);
// Pie
svg.addPath("M300,200 h-150 a150,150 0 1,0 150,-150 z")
.setFill(Color.RED)
.setStroke(Color.BLUE)
.setStrokeWidth(5);
// Wedge
svg.addPath("M275,175 v-150 a150,150 0 0,0 -150,150 z")
.setFill(Color.YELLOW)
.setStroke(Color.BLUE)
.setStrokeWidth(5);
// Path
svg.addPath("M600,350 l 50,-25 a25,25 -30 0,1 50,-25 l 50,-25 a25,50 -30 0,1 50,-25 l 50,-25 a25,75 -30 0,1 50,-25 l 50,-25 a25,100 -30 0,1 50,-25 l 50,-25")
.setFill(null)
.setStroke(Color.RED)
.setStrokeWidth(5);
SvgDoc doc = new SvgDoc(svg);
// Write out the SVG
doc.toIndentedSVG(System.out, 0, 3);
// Generate a PNG image via the Java2D support built into the SVG objects
BufferedImage bufferedImage = new BufferedImage(svg.getWidth(), svg.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = (Graphics2D) bufferedImage.getGraphics();
RenderingHints hints = new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
hints.add(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
g2.setRenderingHints(hints);
svg.draw(g2);
File pngFile = new File("arc1.png");
ImageIO.write(bufferedImage, "png", new FileOutputStream(pngFile));
}
would produce the following SVG:
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<svg height='399' viewBox='0 0 1200 400' width='1199' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns='http://www.w3.org/2000/svg'>
<rect fill='none' height='398' stroke='#0000ff' stroke-width='1' width='1198' x='1' y='1' />
<path d='M300,200 h-150 a150,150 0 1,0 150,-150 z' fill='#ff0000' stroke='#0000ff' stroke-width='5' />
<path d='M275,175 v-150 a150,150 0 0,0 -150,150 z' fill='#ffff00' stroke='#0000ff' stroke-width='5' />
<path d='M600,350 l 50,-25 a25,25 -30 0,1 50,-25 l 50,-25 a25,50 -30 0,1 50,-25 l 50,-25 a25,75 -30 0,1 50,-25 l 50,-25 a25,100 -30 0,1 50,-25 l 50,-25' fill='none' stroke='#ff0000' stroke-width='5' />
</svg>
and this PNG image:
//--------------------------------------------------------------------------
@Test
public void testDrawArc2()
throws Exception
{
SVG svg = new SVG().setViewBox(new Rectangle(0, 0, 1200, 525));
SvgGroup g = svg.addGroup().setFontFamily("Verdana");
SvgDefs defs = g.addDefs();
SvgGroup baseEllipses = defs.addGroup().setId("baseEllipses").setFontSize(new Pixels(20));
baseEllipses.addEllipse().setCx(125).setCy(125).setRx(100).setRy(50).setFill(null).setStroke(HTMLColor.valueOf("#888888")).setStrokeWidth(2);
baseEllipses.addEllipse().setCx(225).setCy(75).setRx(100).setRy(50).setFill(null).setStroke(HTMLColor.valueOf("#888888")).setStrokeWidth(2);
baseEllipses.addText("Arc start").setX(35).setY(70);
baseEllipses.addText("Arc end").setX(225).setY(145);
// Border
g.addRect(new Rectangle(1, 1, 1198, 523)).setFill(null).setStroke(Color.BLUE).setStrokeWidth(1);
SvgGroup fontSizeGrp = g.addGroup().setFontSize("30");
SvgGroup legendGrp = fontSizeGrp.addGroup().setTransform("translate(0,0)");
legendGrp.addUse("#baseEllipses");
SvgGroup grp1 = fontSizeGrp.addGroup().setTransform("translate(400,0)");
grp1.addText("large-arc-flag=0").setX(50).setY(210);
grp1.addText("sweep-flag=0").setX(50).setY(250);
grp1.addUse("#baseEllipses");
grp1.addPath("M 125,75 a100,50 0 0,0 100,50").setFill(null).setStroke(Color.RED).setStrokeWidth(6);
SvgGroup grp2 = fontSizeGrp.addGroup().setTransform("translate(800,0)");
grp2.addText("large-arc-flag=0").setX(50).setY(210);
grp2.addText("sweep-flag=1").setX(50).setY(250);
grp2.addUse("#baseEllipses");
grp2.addPath("M 125,75 a100,50 0 0,1 100,50").setFill(null).setStroke(Color.RED).setStrokeWidth(6);
SvgGroup grp3 = fontSizeGrp.addGroup().setTransform("translate(400,250)");
grp3.addText("large-arc-flag=1").setX(50).setY(210);
grp3.addText("sweep-flag=0").setX(50).setY(250);
grp3.addUse("#baseEllipses");
grp3.addPath("M 125,75 a100,50 0 1,0 100,50").setFill(null).setStroke(Color.RED).setStrokeWidth(6);
SvgGroup grp4 = fontSizeGrp.addGroup().setTransform("translate(800,250)");
grp4.addText("large-arc-flag=1").setX(50).setY(210);
grp4.addText("sweep-flag=1").setX(50).setY(250);
grp4.addUse("#baseEllipses");
grp4.addPath("M 125,75 a100,50 0 1,1 100,50").setFill(null).setStroke(Color.RED).setStrokeWidth(6);
SvgDoc doc = new SvgDoc(svg);
// Write out the SVG
doc.toIndentedSVG(System.out, 0, 3);
// Generate a PNG image via the Java2D support built into the SVG objects
BufferedImage bufferedImage = new BufferedImage(svg.getWidth(), svg.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = (Graphics2D) bufferedImage.getGraphics();
RenderingHints hints = new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
hints.add(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
g2.setRenderingHints(hints);
svg.draw(g2);
File pngFile = new File("arc2.png");
ImageIO.write(bufferedImage, "png", new FileOutputStream(pngFile));
}
would produce the following SVG:
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<svg height='524' viewBox='0 0 1200 525' width='1199' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns='http://www.w3.org/2000/svg'>
<g style='font-family:Verdana'>
<defs>
<g font-size='20.0px' id='baseEllipses'>
<ellipse cx='125' cy='125' fill='none' rx='100' ry='50' stroke='#888888' stroke-width='2' />
<ellipse cx='225' cy='75' fill='none' rx='100' ry='50' stroke='#888888' stroke-width='2' />
<text x='35' y='70'>Arc start</text>
<text x='225' y='145'>Arc end</text>
</g>
</defs>
<rect fill='none' height='523' stroke='#0000ff' stroke-width='1' width='1198' x='1' y='1' />
<g font-size='30'>
<g transform='translate(0,0)'>
<use xlink:href='#baseEllipses' />
</g>
<g transform='translate(400,0)'>
<text x='50' y='210'>large-arc-flag=0</text>
<text x='50' y='250'>sweep-flag=0</text>
<use xlink:href='#baseEllipses' />
<path d='M 125,75 a100,50 0 0,0 100,50' stroke='#ff0000' stroke-width='6' />
</g>
<g transform='translate(800,0)'>
<text x='50' y='210'>large-arc-flag=0</text>
<text x='50' y='250'>sweep-flag=1</text>
<use xlink:href='#baseEllipses' />
<path d='M 125,75 a100,50 0 0,1 100,50' stroke='#ff0000' stroke-width='6' />
</g>
<g transform='translate(400,250)'>
<text x='50' y='210'>large-arc-flag=1</text>
<text x='50' y='250'>sweep-flag=0</text>
<use xlink:href='#baseEllipses' />
<path d='M 125,75 a100,50 0 1,0 100,50' stroke='#ff0000' stroke-width='6' />
</g>
<g transform='translate(800,250)'>
<text x='50' y='210'>large-arc-flag=1</text>
<text x='50' y='250'>sweep-flag=1</text>
<use xlink:href='#baseEllipses' />
<path d='M 125,75 a100,50 0 1,1 100,50' stroke='#ff0000' stroke-width='6' />
</g>
</g>
</g>
</svg>
and this PNG image:
//--------------------------------------------------------------------------
@Test
public void testGlow()
{
SVG svg = new SVG();
SvgDefs defs = svg.addDefs();
defs.addSubtag(createGlowFilter());
SvgGroup group = svg.addGroup()
.setFontFamily("Garamond")
.setFontWeight("normal")
.addStyle(CSS.textAlign(Align.CENTER));
group.addRect(new Rectangle(0, 0, 265, 75)).setFill(Color.black);
group.addText("Hello World!").setX(25).setY(50)
.setFilter("url(#glow)")
.setFill(Color.white).addStyle("font-size: 2.5em");
SvgDoc doc = new SvgDoc(svg);
doc.toIndentedSVG(new File("TestSvgFilters_testGlow.svg"), 0, 3);
}
//--------------------------------------------------------------------------
private SvgNode createGlowFilter()
{
SvgFilter filter = new SvgFilter().setId("glow").setHeight("150%").setY("-25%");
filter.addFeFlood().setFloodColor(HTMLColor.LIGHT_GREEN);
filter.addFeComposite().setIn2(FeInput.SourceAlpha).setOperator(CompositingOperatorType.in);
filter.addFeGaussianBlur().setStdDeviation(4);
SvgFeComponentTransfer componentTransfer = filter.addFeComponentTransfer();
componentTransfer.addFeFuncA().setType(ComponentTransferType.linear).setSlope(3).setIntercept(0);
SvgFeMerge merge = filter.addFeMerge();
merge.addFeMergeNode();
merge.addFeMergeNode().setIn(FeInput.SourceGraphic);
return filter;
}
would produce the following SVG:
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<svg height='75' width='265' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns='http://www.w3.org/2000/svg'>
<defs>
<filter height='150%' id='glow' y='-25%'>
<feFlood flood-color='#90ee90' />
<feComposite in2='SourceAlpha' operator='in' />
<feGaussianBlur stdDeviation='4' />
<feComponentTransfer>
<feFuncA intercept='0.0' slope='3.0' type='linear' />
</feComponentTransfer>
<feMerge>
<feMergeNode />
<feMergeNode in='SourceGraphic' />
</feMerge>
</filter>
</defs>
<g style='font-family:Garamond;font-weight:normal;text-align:center'>
<rect fill='#000000' height='75' width='265' x='0' y='0' />
<text fill='#ffffff' filter='url(#glow)' style='font-size: 2.5em' x='25' y='50'>Hello World!</text>
</g>
</svg>
which looks like this: