⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 psg.java

📁 java高级使用教程 全书一共分六章
💻 JAVA
📖 第 1 页 / 共 2 页
字号:

    /// Convert curves in the path to sequences of straight lines.
    public void flattenpath()
	{
	// This is actually a no-op, since we always represent curves
	// as sequences of straight lines.
	}

    /// Set the current path to the clipping path.
    // @exception Acme.PsgException "undefined result"
    public void clippath() throws PsgException
	{
	Dimension d = size();
	rectpath(
	    itransform_x( 0, 0 ), itransform_y( 0, 0 ),
	    idtransform_x( d.width, d.height ),
	    idtransform_y( d.width, d.height ) );
	}

    /// Return the bounding box of the current path.
    // The return is in the form of a four-element array - element 0 is
    // llx, 1 is lly, 2 is urx, and 3 is ury.
    // @exception Acme.PsgException "no current point"
    public double[] pathbbox() throws PsgException
	{
	if ( path.isEmpty() )
	    throw new PsgException( "no current point" );
	int llx, lly, urx, ury;
	llx = ury = Integer.MAX_VALUE;
	urx = lly = Integer.MIN_VALUE;
	Enumeration enum = path.elements();
	while ( enum.hasMoreElements() )
	    {
	    PsgPathItem pi = (PsgPathItem) enum.nextElement();
	    llx = Math.min( llx, pi.p.x );
	    lly = Math.max( lly, pi.p.y );
	    urx = Math.max( urx, pi.p.x );
	    ury = Math.min( ury, pi.p.y );
	    }
	double[] r = new double[4];
	r[0] = itransform_x( llx, lly );
	r[1] = itransform_y( llx, lly );
	r[2] = itransform_x( urx, ury );
	r[3] = itransform_y( urx, ury );
	return r;
	}

    /// Paint the whole graphics area with the background color.
    public void erasepage()
	{
	Dimension d = size();
	graphics.clearRect( 0, 0, d.width, d.height );
	}

    /// Fill current path with current color.
    public void fill()
	{
	int x, y;
	Polygon poly = null;
	graphics.setColor( current.color );
	Enumeration enum = path.elements();
	while ( enum.hasMoreElements() )
	    {
	    PsgPathItem pi = (PsgPathItem) enum.nextElement();
	    if ( ! pi.draw )
		{
		if ( poly != null )
		    graphics.fillPolygon( poly );
		poly = new Polygon();
		}
	    poly.addPoint( pi.p.x, pi.p.y );
	    x = pi.p.x;
	    y = pi.p.y;
	    }
	if ( poly != null )
	    graphics.fillPolygon( poly );
	newpath();
	}

    /// Draw lines along the current path.
    public void stroke()
	{
	int x = 0, y = 0;	// initial values don't ever get used
	graphics.setColor( current.color );
	Enumeration enum = path.elements();
	while ( enum.hasMoreElements() )
	    {
	    PsgPathItem pi = (PsgPathItem) enum.nextElement();
	    if ( pi.draw )
		if ( pi.linewidth < 1 )
		    graphics.drawLine( x, y, pi.p.x, pi.p.y );
		else
		    Acme.GuiUtils.drawThickLine(
			graphics, x, y, pi.p.x, pi.p.y, pi.linewidth );
	    x = pi.p.x;
	    y = pi.p.y;
	    }
	newpath();
	}

    /// Fill a rectangular path.
    public void rectfill( double x, double y, double width, double height )
	{
	gsave();
	rectpath( x, y, width, height );
	fill();
	grestore();
	}

    /// Stroke a rectangular path.
    public void rectstroke( double x, double y, double width, double height )
	{
	gsave();
	rectpath( x, y, width, height );
	stroke();
	grestore();
	}

    // Make a rectangular path.
    private void rectpath( double x, double y, double width, double height )
	{
	newpath();
	moveto( x, y );
	try
	    {
	    rlineto( width, 0 );
	    rlineto( 0, height );
	    rlineto( -width, 0 );
	    }
	catch ( Acme.PsgException e )
	    {
	    // Shouldn't happen.
	    throw new InternalError();
	    }
	closepath();
	}

    /// Set the current font to the specified name, style, and size.
    // Similar to a PostScript findfont scalefont setfont sequence.
    // @param name the name of the font - Dialog, Helvetica, TimesRoman, Courier
    // @param style some combination of Font.PLAIN, Font.BOLD, and Font.ITALIC
    // @param size how tall the font should be
    public void setfont( String name, int style, double size )
	{
	setfontName( name );
	setfontStyle( style );
	setfontSize( size );
	}

    /// Set the current font to the specified name.
    // @param name the name of the font - Dialog, Helvetica, TimesRoman, Courier
    public void setfontName( String name )
	{
	current.fontName = new String( name );
	current.font = null;
	}

    /// Set the current font to the specified style.
    // @param style some combination of Font.PLAIN, Font.BOLD, and Font.ITALIC
    public void setfontStyle( int style )
	{
	current.fontStyle = style;
	current.font = null;
	}

    /// Set the current font to the specified size.
    // @param size how tall the font should be
    public void setfontSize( double size )
	{
	current.fontSize = dtransform_y( 0.0, size );
	current.font = null;
	}

    /// Paint a string starting at the current point.
    // Doesn't do rotation yet.
    // @exception Acme.PsgException "no current point"
    public void show( String str ) throws PsgException
	{
	if ( current.point == null )
	    throw new PsgException( "no current point" );
	if ( current.font == null )
	    {
	    current.font = new Font(
		current.fontName, current.fontStyle, current.fontSize );
	    graphics.setFont( current.font );
	    }
	graphics.drawString( str,
	    transform_x( current.point.x, current.point.y ),
	    transform_y( current.point.x, current.point.y ) );
	}

    /// Return the x-width of a string.
    // Doesn't do rotation yet.
    // @exception Acme.PsgException "undefined result"
    public double stringwidth_x( String str ) throws PsgException
	{
	FontMetrics fm = graphics.getFontMetrics();
	return idtransform_x( fm.stringWidth( str ), 0 );
	}

    private Dimension size()
	{
	if ( component != null )
	    return component.size();
	    // return component.getSize();
	// Second choice - use the clipping area.
	Rectangle r = graphics.getClipBounds();
	return new Dimension( r.x + r.width, r.y + r.height );
	}

    private static double normAngle( double a )
	{
	int circles = (int) ( a / 360.0 );
	return a - circles * 360.0;
	}

    private static double toRadians( double a )
	{
	return a * Math.PI / 180.0;
	}

    /// Test program.
    public static void main( String[] args )
	{
	new MainFrame( new PsgTest(), args, 350, 350 );
	}

    }

class PsgState implements Cloneable
    {

    public int linewidth;
    public Color color;
    public DoublePoint point;
    public PsgMatrix matrix;

    public String fontName;
    public int fontStyle;
    public int fontSize;
    public Font font;

    // Create a new PsgState.
    public PsgState()
	{
	linewidth = 0;
	color = Color.black;
	point = null;
	matrix = new PsgMatrix();
	fontName = "Dialog";
	fontStyle = Font.PLAIN;
	fontSize = 12;
	font = null;
	}

    public Object clone()
	{
	try
	    {
	    PsgState n = (PsgState) super.clone();
	    n.color = new Color( color.getRGB() );
	    if ( point != null )
		n.point = (DoublePoint) point.clone();
	    n.matrix = (PsgMatrix) matrix.clone();
	    return n;
	    }
	catch ( CloneNotSupportedException e )
	    {
	    // Shouldn't happen.
	    throw new InternalError();
	    }
	}

    }

class PsgPathItem extends Acme.GenericCloneable
    {
    public Point p;
    public int linewidth;
    public boolean draw;

    public PsgPathItem( int x, int y, int linewidth, boolean draw )
	{
	this.p = new Point( x, y );
	this.linewidth = linewidth;
	this.draw = draw;
	}

    // You might think that since we contain a Point object that we need
    // to clone it.  However, we treat Points as immutable, never
    // modifying them once they are created, so it's perfectly safe
    // to just copy the reference and share the contents.
    }

class PsgMatrix extends Acme.GenericCloneable
    {
    public double xx, xy, yx, yy, tx, ty;

    public PsgMatrix()
	{
	// Initialize with the identity matrix.
	xx = 1.0;
	xy = 0.0;
	yx = 0.0;
	yy = 1.0;
	tx = 0.0;
	ty = 0.0;
	}
    
    public PsgMatrix multiply( PsgMatrix b )
	{
	PsgMatrix r = new PsgMatrix();
	r.xx = this.xx * b.xx + this.xy * b.yx;
	r.xy = this.xx * b.xy + this.xy * b.yy;
	r.yy = this.yx * b.xy + this.yy * b.yy;
	r.yx = this.yx * b.xx + this.yy * b.yx;
	r.tx = this.tx * b.xx + this.ty * b.yx + b.tx;
	r.ty = this.tx * b.xy + this.ty * b.yy + b.ty;
	return r;
	}
    
    public PsgMatrix invert() throws PsgException
	{
	PsgMatrix r = new PsgMatrix();
        double det = this.xx * this.yy - this.xy * this.yx;
	if ( det == 0.0 )
	  throw new PsgException( "undefined result" );
	r.xx = this.yy / det;
	r.xy = - this.xy / det;
	r.yx = - this.yx / det;
	r.yy = this.xx / det;
	r.tx = - ( this.tx * r.xx + this.ty * r.yx );
	r.ty = - ( this.tx * r.xy + this.ty * r.yy );
	return r;
	}
    }


// Test class.

class PsgTest extends Applet
    {

    // Called when the applet is first created.
    public void init()
        {
        setBackground( Color.white );
        }

    // Called when the applet should paint itself.
    public void paint( Graphics graphics )
	{
	try
	    {
	    Psg psg = new Psg( this );
	    psg.gsave();
		psg.translate( 50, 50 );
		psg.newpath();
		squarePath( psg, 50 );
		psg.stroke();
	    psg.grestore();
	    psg.gsave();
		psg.translate( 150, 50 );
		psg.rotate( 30 );
		psg.newpath();
		squarePath( psg, 50 );
		psg.stroke();
	    psg.grestore();
	    psg.gsave();
		psg.translate( 250, 50 );
		psg.rotate( 30 );
		psg.scale( 1.5, 1.5 );
		psg.newpath();
		squarePath( psg, 50 );
		psg.stroke();
	    psg.grestore();
	    psg.gsave();
		psg.translate( 50, 150 );
		psg.newpath();
		squarePath( psg, 50 );
		psg.fill();
	    psg.grestore();
	    psg.gsave();
		psg.translate( 150, 150 );
		psg.rotate( 30 );
		psg.newpath();
		squarePath( psg, 50 );
		psg.fill();
	    psg.grestore();
	    psg.gsave();
		psg.translate( 250, 150 );
		psg.rotate( 30 );
		psg.scale( 1.5, 1.5 );
		psg.newpath();
		squarePath( psg, 50 );
		psg.fill();
	    psg.grestore();
	    psg.gsave();
		psg.translate( 50, 250 );
		psg.newpath();
		psg.arc( 25, 25, 25, 0, 360 );
		psg.stroke();
	    psg.grestore();
	    psg.gsave();
		psg.translate( 150, 250 );
		psg.newpath();
		psg.arc( 25, 25, 25, 0, 360 );
		psg.fill();
	    psg.grestore();
	    psg.gsave();
		psg.translate( 250, 250 );
		psg.moveto( 0, 0 );
		psg.curveto( 0, 50, 50, 50, 50, 0 );
		psg.stroke();
	    psg.grestore();
	    }
	catch ( PsgException e )
	    {
	    System.err.println( e );
	    System.exit( 1 );
	    }
	}

    private void squarePath( Psg psg, int size ) throws PsgException
	{
	psg.moveto( 0, 0 );
	psg.rlineto( size, 0 );
	psg.rlineto( 0, size );
	psg.rlineto( -size, 0 );
	psg.closepath();
	}

    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -