/*
* This code is part of Project Waterloo from King's College London
*
*
* Copyright King's College London 2013-
*
* @author Malcolm Lidierth, King's College London [Contact]
*
* Project Waterloo 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 3 of the License, or
* (at your option) any later version.
*
* Project Waterloo 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 program. If not, see .
*
*/
package kcl.waterloo.common.deploy;
import java.awt.Color;
import java.awt.Component;
import java.awt.Composite;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ImageObserver;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.RenderableImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.text.AttributedCharacterIterator;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.Map;
/**
* Abstract class for generating graphics scripts.
*
*
* AbstractDeployableGraphics2D is extended e.g. by PDEGraphics2D which provides
* a concrete implementation for generating Processing script output.
*
*
* Other subclasses may be added in the future to support other scripting
* languages.
*
*
*
* Revisions:
*
* 14.05.2013 Change class name to avoid conflicts with third-party
* packages.
*
* 27.05.2013 Do not clone parentGraphics in constructor
*
* 08.12.2013 Remove some left-over pde specific code
*
* @author Malcolm Lidierth, King's College London
* [Contact]
*/
public abstract class AbstractDeployableGraphics2D extends Graphics2D {
/**
* Graphics2D instance supplied to an AbstractDeployableGraphics2D subclass
* constructor.
*/
protected Graphics2D parentGraphics;
/**
* ArrayList of Formatters representing the code for each picture. The
* Formatter at element zero contains the code for the body of the main
* draw() method (including, therefore, calls to functions represented in
* later elements/pictures).
*/
protected ArrayList pictures = new ArrayList();
/**
* A constant delay to add to the display time for each picture when
* multiple pictures are created using the append method. This is useful,
* particularly with web viewing to start an animation only once the image
* is displayed.
*
* This also sets the interval between replays of the entire sequence.
*/
private int actionDelay = 5000;
/**
* ArrayList of Integers representing the delay from the start of painting
* to painting each picture in milliseconds. The actual delay will be the
* sum of this value and @code actionDelay}.
*/
protected ArrayList latency = new ArrayList();
/**
* If true, graphics will be drawn also to the parentGraphics instance.
*/
private boolean alsoPaintToSource = true;
/**
* Super-constructor that should be called from sub-class constructors.
*
* @param g the parent Graphics2D object for the component to be painted.
*/
protected AbstractDeployableGraphics2D(Graphics2D g) {
parentGraphics = g;//Do not clone 1.0.0c
latency.add(0, Integer.valueOf(0));
}
public boolean isAlsoPaintToSource() {
return alsoPaintToSource;
}
public void setAlsoPaintToSource(boolean alsoPaintToSource) {
this.alsoPaintToSource = alsoPaintToSource;
}
/**
* @return the actionDelay
*/
public int getActionDelay() {
return actionDelay;
}
/**
* @param actionDelay the actionDelay to set
*/
public void setActionDelay(int actionDelay) {
this.actionDelay = Math.max(actionDelay, 1);
}
public abstract void append(Component c, int elapsedTime);
public abstract void append(Component c);
protected long startTime = System.currentTimeMillis();
/**
* @return the code
*/
public String getCode() {
return pictures.get(0).toString();
}
public void write(File f) throws IOException {
FileOutputStream fout = null;
OutputStreamWriter out = null;
try {
fout = new FileOutputStream(f);
out = new OutputStreamWriter(fout, "UTF-8");
out.write(getCode());
} catch (IOException ex) {
throw (ex);
} finally {
if (out != null) {
out.close();
}
if (fout != null) {
fout.close();
}
}
}
/**
* Writes the generated code to
*
* @param f the file name
* @throws IOException
*/
public void write(String f) throws IOException {
write(new File(f));
}
/**
* Call this routine in the painting mechanism of an AWT/Swing hierarchy.
* How a concrete class responds is an implementation detail for the
* subclass. Typically, this will simply be used to add a comment to the
* generated code in a custom component e.g.
*
*
* public void paintComponent(Graphics g){
* if (g instanceof AbstractDeployableGraphics2D) {
* ((AbstractDeployableGraphics2D)g).setPaintObject(this);
* }
* }
*
* @param paintObject the paintObject to set
*/
public abstract void setPaintObject(Object paintObject);
/**
* Sets a string that will be added to the code output as a comment. Do not
* added comment markers - these should be added by any concrete
* implementations automatically and will be specific to the code language
* being used.
*
* @param comment the comment to set as a String
*/
public abstract void addComment(String comment);
/**
* Inserts user-specified code at the start of the generated code, but after
* any automatically generated declarations (which are therefore potentially
* available for use in that code).
*
* @param code fully formatted code string
*/
public abstract void prependCode(String code);
/**
* Inserts user-specified code into the coded output at the current
* location.
*
* @param code fully formatted code string
*/
public abstract void addCode(String code);
/**
* Adds user-specified code to the end of the generated code.
*
* @param code the code to append
*/
public abstract void appendCode(String code);
/**
* Implemented in some Graphics2D subclasses e.g. com.sun.java.Graphics2D.
* This is not part of the java.awt.Graphics2D API.
*
* @param img
* @param dx
* @param dy
* @param sx
* @param sy
* @param width
* @param height
* @param bgcolor
* @param observer
* @return true or false
*/
public abstract boolean copyImage(Image img, int dx, int dy, int sx, int sy,
int width, int height, Color bgcolor, ImageObserver observer);
/**
* AWT Graphics and Graphics2D classes generally implement draw3DRect
* through calls to other methods. Consequently there is no need to
* implement any code here explicitly as long as the
* concrete implementation of Graphics2D in parentGraphics works similarly,
* e.g. by a call to the Graphics2D methods.
*/
@Override
public final void draw3DRect(int x, int y, int width, int height, boolean raised) {
parentGraphics.draw3DRect(x, y, width, height, raised);
}
/**
* AWT Graphics and Graphics2D classes generally implement fill3DRect
* through calls to other methods. Consequently there is no need to
* implement any code here explicitly as long as the
* concrete implementation of Graphics2D in parentGraphics works similarly,
* e.g. by a call to the Graphics2D methods.
*/
@Override
public final void fill3DRect(int x, int y, int width, int height, boolean raised) {
parentGraphics.fill3DRect(x, y, width, height, raised);
}
@Override
public final void setTransform(AffineTransform Tx) {
parentGraphics.setTransform(Tx);
}
@Override
public AffineTransform getTransform() {
return parentGraphics.getTransform();
}
@Override
public Stroke getStroke() {
return parentGraphics.getStroke();
}
@Override
public void clip(Shape s) {
parentGraphics.clip(s);
}
@Override
public FontRenderContext getFontRenderContext() {
return parentGraphics.getFontRenderContext();
}
@Override
public Color getColor() {
return parentGraphics.getColor();
}
@Override
public void setColor(Color c) {
parentGraphics.setColor(c);
}
@Override
public void setPaintMode() {
parentGraphics.setPaintMode();
}
@Override
public final Font getFont() {
return parentGraphics.getFont();
}
@Override
public void setFont(Font font) {
parentGraphics.setFont(font);
}
@Override
public Rectangle getClipBounds() {
return parentGraphics.getClipBounds();
}
@Override
public void clipRect(int x, int y, int width, int height) {
parentGraphics.clipRect(x, y, width, height);
}
@Override
public void setClip(int x, int y, int width, int height) {
parentGraphics.setClip(x, y, width, height);
}
@Override
public Shape getClip() {
return parentGraphics.getClip();
}
@Override
public void setClip(Shape clip) {
parentGraphics.setClip(clip);
}
@Override
public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
return parentGraphics.hit(rect, s, onStroke);
}
@Override
public void setComposite(Composite comp) {
parentGraphics.setComposite(comp);
}
@Override
public void setPaint(Paint paint) {
parentGraphics.setPaint(paint);
}
@Override
public void setStroke(Stroke s) {
parentGraphics.setStroke(s);
}
@Override
public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) {
parentGraphics.setRenderingHint(hintKey, hintValue);
}
@Override
public Object getRenderingHint(RenderingHints.Key hintKey) {
return parentGraphics.getRenderingHint(hintKey);
}
@Override
public void setRenderingHints(Map, ?> hints) {
parentGraphics.setRenderingHints(hints);
}
@Override
public void addRenderingHints(Map, ?> hints) {
parentGraphics.addRenderingHints(hints);
}
@Override
public RenderingHints getRenderingHints() {
return parentGraphics.getRenderingHints();
}
@Override
public void setXORMode(Color c1) {
parentGraphics.setXORMode(c1);
}
@Override
public FontMetrics getFontMetrics(Font f) {
return parentGraphics.getFontMetrics(f);
}
@Override
public void copyArea(int x, int y, int width, int height, int dx, int dy) {
parentGraphics.copyArea(x, y, width, height, dx, dy);
}
@Override
public GraphicsConfiguration getDeviceConfiguration() {
return parentGraphics.getDeviceConfiguration();
}
@Override
public void translate(int x, int y) {
parentGraphics.translate(x, y);
}
@Override
public void translate(double tx, double ty) {
parentGraphics.translate(tx, ty);
}
@Override
public void rotate(double theta) {
parentGraphics.rotate(theta);
}
@Override
public void rotate(double theta, double x, double y) {
parentGraphics.rotate(theta, x, y);
}
@Override
public void scale(double sx, double sy) {
parentGraphics.scale(sx, sy);
}
@Override
public void shear(double shx, double shy) {
parentGraphics.shear(shx, shy);
}
@Override
public void transform(AffineTransform Tx) {
parentGraphics.transform(Tx);
}
@Override
public Paint getPaint() {
return parentGraphics.getPaint();
}
@Override
public Composite getComposite() {
return parentGraphics.getComposite();
}
@Override
public void setBackground(Color color) {
parentGraphics.setBackground(color);
}
@Override
public Color getBackground() {
return parentGraphics.getBackground();
}
/**
*
* @param s
*/
@Override
public void draw(Shape s) {
if (alsoPaintToSource) {
parentGraphics.draw(s);
}
}
@Override
public void drawString(String str, int x, int y) {
if (alsoPaintToSource) {
parentGraphics.drawString(str, x, y);
}
}
@Override
public void drawString(String str, float x, float y) {
if (alsoPaintToSource) {
parentGraphics.drawString(str, x, y);
}
}
@Override
public void drawString(AttributedCharacterIterator iterator, int x, int y) {
if (alsoPaintToSource) {
parentGraphics.drawString(iterator, x, y);
}
}
@Override
public void drawString(AttributedCharacterIterator iterator, float x, float y) {
if (alsoPaintToSource) {
parentGraphics.drawString(iterator, x, y);
}
}
@Override
public void drawGlyphVector(GlyphVector g, float x, float y) {
if (alsoPaintToSource) {
parentGraphics.drawGlyphVector(g, x, y);
}
}
@Override
public void fill(Shape s) {
if (alsoPaintToSource) {
parentGraphics.fill(s);
}
}
@Override
public void drawLine(int x1, int y1, int x2, int y2) {
if (alsoPaintToSource) {
parentGraphics.drawLine(x1, y1, x2, y2);
}
}
@Override
public void drawRect(int x, int y, int width, int height) {
if (alsoPaintToSource) {
parentGraphics.fillRect(x, y, width, height);
}
}
@Override
public void fillRect(int x, int y, int width, int height) {
if (alsoPaintToSource) {
parentGraphics.fillRect(x, y, width, height);
}
}
@Override
public void clearRect(int x, int y, int width, int height) {
if (alsoPaintToSource) {
parentGraphics.clearRect(x, y, width, height);
}
}
@Override
public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
if (alsoPaintToSource) {
parentGraphics.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
}
}
@Override
public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
if (alsoPaintToSource) {
parentGraphics.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
}
}
@Override
public void drawOval(int x, int y, int width, int height) {
if (alsoPaintToSource) {
parentGraphics.drawOval(x, y, width, height);
}
}
@Override
public void fillOval(int x, int y, int width, int height) {
if (alsoPaintToSource) {
parentGraphics.fillOval(x, y, width, height);
}
}
@Override
public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
if (alsoPaintToSource) {
parentGraphics.drawArc(x, y, width, height, startAngle, arcAngle);
}
}
@Override
public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
if (alsoPaintToSource) {
parentGraphics.fillArc(x, y, width, height, startAngle, arcAngle);
}
}
@Override
public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) {
if (alsoPaintToSource) {
parentGraphics.drawPolyline(xPoints, yPoints, nPoints);
}
}
@Override
public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) {
if (alsoPaintToSource) {
parentGraphics.drawPolyline(xPoints, yPoints, nPoints);
}
}
@Override
public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) {
if (alsoPaintToSource) {
parentGraphics.fillPolygon(xPoints, yPoints, nPoints);
}
}
@Override
public void drawBytes(byte[] data, int offset, int length, int x, int y) {
if (alsoPaintToSource) {
parentGraphics.drawBytes(data, offset, length, x, y);
}
}
@Override
public boolean drawImage(Image img, int x, int y, ImageObserver observer) {
return drawImage(img, x, y, img.getWidth(observer), img.getHeight(observer), observer);
}
@Override
public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) {
return parentGraphics.drawImage(img, x, y, width, height, null);
}
@Override
public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) {
return drawImage(img, x, y, img.getWidth(observer), img.getHeight(observer), bgcolor, observer);
}
@Override
public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer) {
return parentGraphics.drawImage(img, x, y, width, height, bgcolor, null);
}
@Override
public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) {
return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null, observer);
}
@Override
public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer) {
return parentGraphics.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bgcolor, null);
}
@Override
public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) {
return parentGraphics.drawImage(img, xform, null);
}
@Override
public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) {
parentGraphics.drawImage(img, op, x, y);
}
@Override
public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
parentGraphics.drawRenderedImage(img, xform);
}
@Override
public void drawRenderableImage(RenderableImage img, AffineTransform xform) {
parentGraphics.drawRenderableImage(img, xform);
}
@Override
public void dispose() {
parentGraphics.dispose();
}
/*
* This code is part of Project Waterloo from King's College London
*
*
* Copyright King's College London 2011-
*
* @author Malcolm Lidierth, King's College London [Contact]
*
* Project Waterloo 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 3 of the License, or
* (at your option) any later version.
*
* Project Waterloo 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 program. If not, see .
*
*
*
*/
protected static class GJPathSegmentInfo {
private int type = -1;
private double[] data = new double[6];
public GJPathSegmentInfo() {
type = PathIterator.SEG_CLOSE + PathIterator.SEG_CUBICTO;
}
public GJPathSegmentInfo(int t, double[] d) {
type = t;
setData(d);
}
/**
* @return the type
*/
public final int getType() {
return type;
}
/**
* @param t the type to set
*/
public final void setType(int t) {
this.type = t;
}
/**
* @return the data
*/
public final double[] getData() {
return data.clone();
}
/**
* @param d
*/
public final void setData(double[] d) {
data = d.clone();
}
}
}
Ads help maintain this website.