📄 postscriptgraphics.java
字号:
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* PostscriptGraphics.java
* Copyright (C) 2003 Dale Fletcher
*
*/
package weka.gui.visualize;
import java.awt.image.renderable.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.font.*;
import java.io.*;
import java.util.*;
import java.awt.image.*;
import java.text.*;
/**
* The PostscriptGraphics class extends the Graphics2D class to
* produce an encapsulated postscript file rather than on-screen display.
* <p>
* Currently only a small (but useful) subset of Graphics methods have been
* implemented.
* To handle the ability to Clone a Graphics object, the graphics state of the
* eps is set from the graphics state of the local PostscriptGraphics before output.
* To use, create a PostscriptGraphics object, and pass it to the PaintComponent
* method of a JComponent.
* <p>
* If necessary additional font replacements can be inserted, since some fonts
* might be displayed incorrectly.
*
* @see #addPSFontReplacement(String, String)
* @see #m_PSFontReplacement
* @author Dale Fletcher (dale@cs.waikato.ac.nz)
* @author FracPete (fracpete at waikato dot ac dot nz)
* @version $Revision: 1.1 $
*/
public class PostscriptGraphics extends Graphics2D {
/**
* This inner class is used to maintain the graphics states of the PostScript
* file and graphics context.
*/
private class GraphicsState {
/** The current pen color */
protected Color m_currentColor;
/** The current Font */
protected Font m_currentFont;
/** The current Stroke (not yet used) */
protected Stroke m_currentStroke;
/** x,y Translation */
protected int m_xOffset;
protected int m_yOffset;
/** the scale factors */
protected double m_xScale;
protected double m_yScale;
/**
* Create a new GraphicsState with default values.
*/
GraphicsState(){
m_currentColor = Color.white;
m_currentFont = new Font ("Courier", Font.PLAIN, 11);
m_currentStroke = new BasicStroke();
m_xOffset = 0;
m_yOffset = 0;
m_xScale = 1.0;
m_yScale = 1.0;
}
/**
* Create a new cloned GraphicsState
*
* @param copy The GraphicsState to clone
*/
GraphicsState(GraphicsState copy){
m_currentColor = copy.m_currentColor;
m_currentFont = copy.m_currentFont;
m_currentStroke = copy.m_currentStroke;
m_xOffset = copy.m_xOffset;
m_yOffset = copy.m_yOffset;
m_xScale = copy.m_xScale;
m_yScale = copy.m_yScale;
}
/* Stroke Methods */
protected Stroke getStroke(){
return m_currentStroke;
}
protected void setStroke(Stroke s){
m_currentStroke = s;
}
/* Font Methods */
protected Font getFont(){
return m_currentFont;
}
protected void setFont(Font f){
m_currentFont = f;
}
/* Color Methods */
protected Color getColor(){
return m_currentColor;
}
protected void setColor(Color c){
m_currentColor = c;
}
/* Translation methods */
protected void setXOffset(int xo){
m_xOffset = xo;
}
protected void setYOffset(int yo){
m_yOffset = yo;
}
protected int getXOffset(){
return m_xOffset;
}
protected int getYOffset(){
return m_yOffset;
}
protected void setXScale(double x){
m_xScale = x;
}
protected void setYScale(double y){
m_yScale = y;
}
protected double getXScale(){
return m_xScale;
}
protected double getYScale(){
return m_yScale;
}
}
/** The bounding box of the output */
protected Rectangle m_extent;
/** The output file */
protected PrintStream m_printstream;
/** The current global PostScript graphics state for all cloned objects */
protected GraphicsState m_psGraphicsState;
/** The current local graphics state for this PostscriptGraphics object */
protected GraphicsState m_localGraphicsState;
/** whether to print some debug information */
protected final static boolean DEBUG = false;
/** the font replacement */
protected static Hashtable m_PSFontReplacement;
/** output if we're in debug mode */
static {
if (DEBUG)
System.err.println(PostscriptGraphics.class.getName() + ": DEBUG ON");
// get font replacements
m_PSFontReplacement = new Hashtable();
m_PSFontReplacement.put("SansSerif.plain", "Helvetica.plain"); // SansSerif.plain is displayed as Courier in GV???
m_PSFontReplacement.put("Dialog.plain", "Helvetica.plain"); // dialog is a Sans Serif font, but GV displays it as Courier???
m_PSFontReplacement.put("Microsoft Sans Serif", "Helvetica.plain"); // MS Sans Serif is a Sans Serif font (hence the name!), but GV displays it as Courier???
m_PSFontReplacement.put("MicrosoftSansSerif", "Helvetica.plain"); // MS Sans Serif is a Sans Serif font (hence the name!), but GV displays it as Courier???
}
/**
* Constructor
* Creates a new PostscriptGraphics object, given dimensions and
* output file.
*
* @param width The width of eps in points.
* @param height The height of eps in points.
* @param os File to send postscript to.
*/
public PostscriptGraphics(int width, int height, OutputStream os ){
m_extent = new Rectangle(0, 0, height, width);
m_printstream = new PrintStream(os);
m_localGraphicsState = new GraphicsState();
m_psGraphicsState = new GraphicsState();
Header();
}
/**
* Creates a new cloned PostscriptGraphics object.
*
* @param copy The PostscriptGraphics object to clone.
*/
PostscriptGraphics(PostscriptGraphics copy){
m_extent = new Rectangle(copy.m_extent);
m_printstream = copy.m_printstream;
m_localGraphicsState = new GraphicsState(copy.m_localGraphicsState); // create a local copy of the current state
m_psGraphicsState = copy.m_psGraphicsState; // link to global state of eps file
}
/**
* Finalizes output file.
*/
public void finished(){
m_printstream.flush();
}
/**
* Output postscript header to PrintStream, including helper macros.
*/
private void Header(){
m_printstream.println("%!PS-Adobe-3.0 EPSF-3.0");
m_printstream.println("%%BoundingBox: 0 0 " + xScale(m_extent.width) + " " + yScale(m_extent.height));
m_printstream.println("%%CreationDate: " + Calendar.getInstance().getTime());
m_printstream.println("/Oval { % x y w h filled");
m_printstream.println("gsave");
m_printstream.println("/filled exch def /h exch def /w exch def /y exch def /x exch def");
m_printstream.println("x w 2 div add y h 2 div sub translate");
m_printstream.println("1 h w div scale");
m_printstream.println("filled {0 0 moveto} if");
m_printstream.println("0 0 w 2 div 0 360 arc");
m_printstream.println("filled {closepath fill} {stroke} ifelse grestore} bind def");
m_printstream.println("/Rect { % x y w h filled");
m_printstream.println("/filled exch def /h exch def /w exch def /y exch def /x exch def");
m_printstream.println("newpath ");
m_printstream.println("x y moveto");
m_printstream.println("w 0 rlineto");
m_printstream.println("0 h neg rlineto");
m_printstream.println("w neg 0 rlineto");
m_printstream.println("closepath");
m_printstream.println("filled {fill} {stroke} ifelse} bind def");
m_printstream.println("%%BeginProlog\n%%EndProlog");
m_printstream.println("%%Page 1 1");
setFont(null); // set to default
setColor(null); // set to default
setStroke(null); // set to default
}
/**
* adds the PS font name to replace and its replacement in the replacement
* hashtable
*
* @param replace the PS font name to replace
* @param with the PS font name to replace the font with
*/
public static void addPSFontReplacement(String replace, String with) {
m_PSFontReplacement.put(replace, with);
}
/**
* Convert Java Y coordinate (0 = top) to PostScript (0 = bottom)
* Also apply current Translation
* @param y Java Y coordinate
* @return translated Y to postscript
*/
private int yTransform(int y){
return (m_extent.height - (m_localGraphicsState.getYOffset() + y));
}
/**
* Apply current X Translation
* @param x Java X coordinate
* @return translated X to postscript
*/
private int xTransform(int x){
return (m_localGraphicsState.getXOffset() + x);
}
/**
* scales the given number with the provided scale factor
*/
private int doScale(int number, double factor) {
return (int) StrictMath.round(number * factor);
}
/**
* scales the given x value with current x scale factor
*/
private int xScale(int x) {
return doScale(x, m_localGraphicsState.getXScale());
}
/**
* scales the given y value with current y scale factor
*/
private int yScale(int y) {
return doScale(y, m_localGraphicsState.getYScale());
}
/** Set the current eps graphics state to that of the local one
*/
private void setStateToLocal(){
setColor(this.getColor());
setFont(this.getFont());
setStroke(this.getStroke());
}
/**
* returns a two hexadecimal representation of i, if shorter than 2 chars
* then an additional "0" is put in front
*/
private String toHex(int i) {
String result;
result = Integer.toHexString(i);
if (result.length() < 2)
result = "0" + result;
return result;
}
/***** overridden Graphics methods *****/
/**
* Draw a filled rectangle with the background color.
*
* @param x starting x coord
* @param y starting y coord
* @param width rectangle width
* @param height rectangle height
*/
public void clearRect(int x, int y, int width, int height) {
setStateToLocal();
Color saveColor = getColor();
setColor(Color.white); // background color for page
m_printstream.println(xTransform(xScale(x)) + " " + yTransform(yScale(y)) + " " + xScale(width) + " " + yScale(height) + " true Rect");
setColor(saveColor);
}
/**
* Not implemented
*/
public void clipRect(int x, int y, int width, int height) {}
/**
* Not implemented
*/
public void copyArea(int x, int y, int width, int height, int dx, int dy) {}
/**
* Clone a PostscriptGraphics object
*/
public Graphics create() {
if (DEBUG)
m_printstream.println("%create");
PostscriptGraphics psg = new PostscriptGraphics(this);
return(psg);
}
/**
* Not implemented
*/
public void dispose(){}
/**
* Draw an outlined rectangle with 3D effect in current pen color.
* (Current implementation: draw simple outlined rectangle)
*
* @param x starting x coord
* @param y starting y coord
* @param width rectangle width
* @param height rectangle height
* @param raised True: appear raised, False: appear etched
*/
public void draw3DRect(int x, int y, int width, int height, boolean raised){
drawRect(x,y,width,height);
}
/**
* Not implemented
*/
public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle){}
/**
* simply calls drawString(String,int,int)
*
* @see #drawString(String,int,int)
*/
public void drawBytes(byte[] data, int offset, int length, int x, int y) {
drawString(new String(data, offset, length), x, y);
}
/**
* simply calls drawString(String,int,int)
*
* @see #drawString(String,int,int)
*/
public void drawChars(char[] data, int offset, int length, int x, int y) {
drawString(new String(data, offset, length), x, y);
}
/**
* calls drawImage(Image,int,int,int,int,Color,ImageObserver)
*
* @see #drawImage(Image,int,int,int,int,Color,ImageObserver)
*/
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);
}
/**
* calls drawImage(Image,int,int,Color,ImageObserver) with Color.WHITE as
* background color
*
* @see #drawImage(Image,int,int,Color,ImageObserver)
* @see Color#WHITE
*/
public boolean drawImage(Image img, int x, int y, ImageObserver observer){
return drawImage(img, x, y, Color.WHITE, observer);
}
/**
* PS see http://astronomy.swin.edu.au/~pbourke/geomformats/postscript/
* Java http://show.docjava.com:8086/book/cgij/doc/ip/graphics/SimpleImageFrame.java.html
*/
public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer){
try {
// get data from image
int[] pixels = new int[width * height];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -