com.hfg.graphics.SvgGraphics2D Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com_hfg Show documentation
Show all versions of com_hfg Show documentation
com.hfg xml, html, svg, and bioinformatics utility library
package com.hfg.graphics;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Paint;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.font.GlyphVector;
import java.awt.font.FontRenderContext;
import java.awt.geom.Point2D;
import java.awt.image.ImageObserver;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.RenderableImage;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.text.AttributedCharacterIterator;
import java.util.Map;
import java.util.Stack;
import com.hfg.css.CSS;
import com.hfg.exception.UnimplementedMethodException;
import com.hfg.xml.XMLTag;
import com.hfg.svg.*;
//------------------------------------------------------------------------------
/**
* Simple Graphics2D class which can be used to generate SVG. Not yet with full functionality.
*
* @author J. Alex Taylor, hairyfatguy.com
*
*/
//------------------------------------------------------------------------------
// com.hfg XML/HTML Coding Library
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
// [email protected]
//------------------------------------------------------------------------------
public class SvgGraphics2D extends Graphics2D
{
private Paint mCurrentPaint = sDefaultPaint;
private Color mCurrentBackground = Color.BLACK;
private Font mCurrentFont = new Font("sanserif", Font.PLAIN, 12);
private Stroke mCurrentStroke = sDefaultStroke;
private int mCurrentX;
private int mCurrentY;
private SVG mRootTag = new SVG();
private Stack mTagStack = new Stack<>();
private Stack mTransformStack = new Stack<>();
private static Paint sDefaultPaint = Color.BLACK;
private static Stroke sDefaultStroke = null; //new BasicStroke();
/**
* Used to create proper font metrics
*/
private static Graphics2D sG2D = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB).createGraphics();
private static FontRenderContext sFRC;
static
{
AffineTransform frcTransform = new AffineTransform();
frcTransform.scale(96f/72f, 1);
sFRC = new FontRenderContext(frcTransform, false, false);
}
//##########################################################################
// CONSTRUCTORS
//##########################################################################
//--------------------------------------------------------------------------
public SvgGraphics2D()
{
mTagStack.push(mRootTag);
mTransformStack.push(new AffineTransform());
}
//##########################################################################
// PUBLIC METHODS
//##########################################################################
//--------------------------------------------------------------------------
public SVG getRootTag()
{
return mRootTag;
}
//--------------------------------------------------------------------------
public void draw(Shape shape)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public boolean drawImage(Image image, AffineTransform affineTransform, ImageObserver imageObserver)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void drawImage(BufferedImage bufferedImage, BufferedImageOp bufferedImageOp, int i, int i1)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void drawRenderedImage(RenderedImage renderedImage, AffineTransform affineTransform)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void drawRenderableImage(RenderableImage renderableImage, AffineTransform affineTransform)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void drawString(String inString, int x, int y)
{
drawString(inString, (float)x, (float)y);
}
//--------------------------------------------------------------------------
public void drawString(String inString, float x, float y)
{
SvgText textTag = new SvgText(inString, getFont(), new Point2D.Float(x, y));
textTag.addStyle("font-family:" + getFont().getFamily());
textTag.addStyle(CSS.fontSize(getFont().getSize()));
if (mCurrentPaint instanceof Color) textTag.addStyle("fill:#" + ColorUtil.colorToHex(getColor()));
mTagStack.peek().addSubtag(textTag);
}
//--------------------------------------------------------------------------
public void drawString(AttributedCharacterIterator attributedCharacterIterator, int i, int i1)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void drawString(AttributedCharacterIterator attributedCharacterIterator, float v, float v1)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public boolean drawImage(Image image, int i, int i1, ImageObserver imageObserver)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public boolean drawImage(Image image, int i, int i1, int i2, int i3, ImageObserver imageObserver)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public boolean drawImage(Image image, int i, int i1, Color color, ImageObserver imageObserver)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public boolean drawImage(Image image, int i, int i1, int i2, int i3, Color color, ImageObserver imageObserver)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public boolean drawImage(Image image, int i, int i1, int i2, int i3, int i4, int i5, int i6, int i7, ImageObserver imageObserver)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public boolean drawImage(Image image, int i, int i1, int i2, int i3, int i4, int i5, int i6, int i7, Color color, ImageObserver imageObserver)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void dispose()
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void drawGlyphVector(GlyphVector glyphVector, float v, float v1)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void fill(Shape shape)
{
if (shape instanceof Rectangle)
{
fill((Rectangle) shape);
}
else
{
throw new UnimplementedMethodException();
}
}
//--------------------------------------------------------------------------
public boolean hit(Rectangle rectangle, Shape shape, boolean b)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public GraphicsConfiguration getDeviceConfiguration()
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void setComposite(Composite composite)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void setRenderingHint(RenderingHints.Key key, Object object)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public Object getRenderingHint(RenderingHints.Key key)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void setRenderingHints(Map, ?> map)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void addRenderingHints(Map, ?> map)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public RenderingHints getRenderingHints()
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public Graphics create()
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public Font getFont()
{
return mCurrentFont;
}
//--------------------------------------------------------------------------
public void setFont(Font inFont)
{
mCurrentFont = inFont;
}
//--------------------------------------------------------------------------
public FontMetrics getFontMetrics(Font inFont)
{
return sG2D.getFontMetrics(inFont);
}
//--------------------------------------------------------------------------
public Rectangle getClipBounds()
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void clipRect(int i, int i1, int i2, int i3)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void setClip(int i, int i1, int i2, int i3)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public Shape getClip()
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void setClip(Shape shape)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void copyArea(int i, int i1, int i2, int i3, int i4, int i5)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void drawLine(int x1, int y1, int x2, int y2)
{
if (! mCurrentStroke.equals(sDefaultStroke))
{
draw(mCurrentStroke.createStrokedShape(new Line2D.Float(x1, y1, x2, y2)));
}
else
{
SvgLine lineTag = new SvgLine(new Point(x1, y1), new Point(x2, y2));
if (! mCurrentPaint.equals(sDefaultPaint)) lineTag.addStyle(CSS.color(getColor()));
mTagStack.peek().addSubtag(lineTag);
}
}
//--------------------------------------------------------------------------
// A convenience method
public void fill(Rectangle inRect)
{
fillRect(inRect.x, inRect.y, inRect.width, inRect.height);
}
//--------------------------------------------------------------------------
public void fillRect(int x1, int y1, int inWidth, int inHeight)
{
Rectangle rect = new Rectangle(x1, y1, inWidth, inHeight);
if (null == mCurrentStroke
|| mCurrentStroke instanceof BasicStroke)
{
SvgRect rectTag = new SvgRect(rect);
if (mCurrentPaint instanceof Color) rectTag.addStyle("fill:#" + ColorUtil.colorToHex(getColor()));
float lineWidth = mCurrentStroke != null ? ((BasicStroke) mCurrentStroke).getLineWidth() : 0;
if (lineWidth > 0)
{
rectTag.addStyle("stroke-width:" + lineWidth + "px");
rectTag.addStyle("stroke:#" + ColorUtil.colorToHex(mCurrentBackground));
}
mTagStack.peek().addSubtag(rectTag);
}
else
{
draw(mCurrentStroke.createStrokedShape(rect));
}
}
//--------------------------------------------------------------------------
public void clearRect(int i, int i1, int i2, int i3)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void drawRoundRect(int i, int i1, int i2, int i3, int i4, int i5)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void fillRoundRect(int i, int i1, int i2, int i3, int i4, int i5)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void drawOval(int i, int i1, int i2, int i3)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void fillOval(int i, int i1, int i2, int i3)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void drawArc(int i, int i1, int i2, int i3, int i4, int i5)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void fillArc(int i, int i1, int i2, int i3, int i4, int i5)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void drawPolyline(int[] ints, int[] ints1, int i)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void drawPolygon(int[] ints, int[] ints1, int i)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void fillPolygon(int[] ints, int[] ints1, int i)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void translate(int x, int y)
{
SvgGroup group = new SvgGroup();
group.setTransform(String.format("translate(%d,%d)", x, y));
mTagStack.peek().addSubtag(group);
mTagStack.push(group);
AffineTransform transform = new AffineTransform(mTransformStack.peek());
transform.setToTranslation(x, y);
mTransformStack.push(transform);
}
//--------------------------------------------------------------------------
public void translate(double x, double y)
{
SvgGroup group = new SvgGroup();
group.setTransform(String.format("translate(%.1f,%.1f)", x, y));
mTagStack.peek().addSubtag(group);
mTagStack.push(group);
AffineTransform transform = new AffineTransform(mTransformStack.peek());
transform.setToTranslation(x, y);
mTransformStack.push(transform);
}
//--------------------------------------------------------------------------
public void rotate(double v)
{
SvgGroup group = new SvgGroup();
group.setTransform(String.format("rotate(%.1f)", v));
mTagStack.peek().addSubtag(group);
mTagStack.push(group);
AffineTransform transform = new AffineTransform(mTransformStack.peek());
transform.setToRotation(v);
mTransformStack.push(transform);
}
//--------------------------------------------------------------------------
public void rotate(double v, double v1, double v2)
{
SvgGroup group = new SvgGroup();
group.setTransform(String.format("rotate(%.1f, %.1f, %.1f)", v, v1, v2));
mTagStack.peek().addSubtag(group);
mTagStack.push(group);
AffineTransform transform = new AffineTransform(mTransformStack.peek());
transform.setToRotation(v, v1, v2);
mTransformStack.push(transform);
}
//--------------------------------------------------------------------------
public void scale(double v, double v1)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void shear(double v, double v1)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void transform(AffineTransform inAffineTransform)
{
AffineTransform transform = new AffineTransform(mTransformStack.peek());
transform.concatenate(inAffineTransform);
mTransformStack.push(transform);
}
//--------------------------------------------------------------------------
public void setTransform(AffineTransform inAffineTransform)
{
while (mTagStack.size() > 1 && ! inAffineTransform.equals(mTransformStack.peek()))
{
mTagStack.pop();
mTransformStack.pop();
}
if (! inAffineTransform.equals(mTransformStack.peek()))
{
mTransformStack.pop();
mTransformStack.push(new AffineTransform(inAffineTransform));
}
}
//--------------------------------------------------------------------------
public AffineTransform getTransform()
{
return new AffineTransform(mTransformStack.peek()); // Return a copy
}
//--------------------------------------------------------------------------
public void setPaint(Paint inPaint)
{
mCurrentPaint = inPaint;
}
//--------------------------------------------------------------------------
public Paint getPaint()
{
return mCurrentPaint;
}
//--------------------------------------------------------------------------
public Color getColor()
{
return (mCurrentPaint instanceof Color ? (Color) mCurrentPaint : null);
}
//--------------------------------------------------------------------------
public void setColor(Color inColor)
{
mCurrentPaint = inColor;
}
//--------------------------------------------------------------------------
/**
Sets the paint mode of this graphics context to overwrite the destination
with this graphics context's current color. This sets the logical pixel
operation function to the paint or overwrite mode. All subsequent rendering
operations will overwrite the destination with the current color.
*/
public void setPaintMode()
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
/**
Not implemented.
Sets the paint mode of this graphics context to alternate between this
graphics context's current color and the new specified color. This specifies
that logical pixel operations are performed in the XOR mode, which alternates
pixels between the current color and a specified XOR color.
When drawing operations are performed, pixels which are the current color are
changed to the specified color, and vice versa.
Pixels that are of colors other than those two colors are changed in an
unpredictable but reversible manner; if the same figure is drawn twice, then
all pixels are restored to their original values.
@param inColor the color to alternate with the current default color of the graphics context
*/
public void setXORMode(Color inColor)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public Composite getComposite()
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public void setBackground(Color inValue)
{
mCurrentBackground = inValue;
}
//--------------------------------------------------------------------------
public Color getBackground()
{
return mCurrentBackground;
}
//--------------------------------------------------------------------------
public void setStroke(Stroke inStroke)
{
mCurrentStroke = inStroke;
}
//--------------------------------------------------------------------------
public Stroke getStroke()
{
return mCurrentStroke;
}
//--------------------------------------------------------------------------
public void clip(Shape shape)
{
throw new UnimplementedMethodException();
}
//--------------------------------------------------------------------------
public FontRenderContext getFontRenderContext()
{
return sFRC;
}
}