<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">/* Copyright Andy C. Deck 1999 All rights reserved. */    
import java.awt.Polygon; 
import java.util.Hashtable;
import java.awt.Color;
import java.util.Random;
import java.awt.Rectangle;
import java.awt.Graphics;
import java.awt.Rectangle;

public abstract class Stroke
{
   public abstract Rectangle fill(Graphics g, Item d);
   public abstract void init(Item d);
   public abstract void finish(Item d);
   public abstract byte getTool();
   public abstract byte[] getIcon();
}


/*
//****************************************************
// CAPGUN

class capgun extends Stroke
{
	private int[][] st = new int[10][2];

	public void init(Item d){
          st[d.id][0] = d.x;
          st[d.id][1] = d.y;  
	} 
    public void finish(Item d){}
	public byte getTool(){ return Env.CAPGUN; }
	public byte[] getIcon(){ 
        final byte icon[] = { 10, 6,6, 8,10, 13,16, 23,24 };
        return icon; 
    } 


    public Rectangle fill(Graphics g, Item d)
    {
        int[] xpts= new int[4];
        int[] ypts= new int[4];
        int thick = (byte)(d.press&gt;&gt;1);
        int thick2 = thick&lt;&lt;1;
        g.fillOval((d.x - thick), (d.y - thick), thick2 , thick2);
        g.fillOval((st[d.id][0] - thick), (st[d.id][1] - thick), thick2, thick2);
        float f9= (float)(st[d.id][0] - d.x);
        float f10= (float)(st[d.id][1] - d.y);
        float f12;
        float f11= (float)thick * (float)Math.sqrt(( 1.0  /                                                             (double)( (float)1.0  + ((f9 * f9) / (f10 * f10)))));
        if ((f10 !=  (float)0.0 )) {
            f12= (-(f11 * f9)) / f10;
        }
        else {
            f12= (float)thick;
            f11=0;
        }
        xpts[0]= (int)((float)d.x - f11);
        xpts[1]= (int)((float)d.x + f11);
        xpts[2]= (int)((float)st[d.id][0] + f11);
        xpts[3]= (int)((float)st[d.id][0] - f11);
        ypts[0]= (int)((float)d.y - f12);  
	ypts[1]= (int)((float)d.y + f12);
        ypts[2]= (int)((float)st[d.id][1] + f12);
        ypts[3]= (int)((float)st[d.id][1] - f12);
        java.awt.Polygon p = new java.awt.Polygon(xpts,ypts,4);
	g.drawLine(xpts[0],ypts[0],xpts[3],ypts[3]);
	g.drawLine(xpts[2],ypts[2],xpts[1],ypts[1]);
		
        st[d.id][0] = d.x;
        st[d.id][1] = d.y;
        Rectangle r = new Rectangle(d.x - thick, d.y -thick, thick2, thick2);
        return r.union(p.getBoundingBox());   
     }
}       



//****************************************************
// CROSSHAIR 

class crosshair extends Stroke
{
private Rectangle rect = new Rectangle();
 private int[][] st = new int[10][2];

    public void init(Item d){
          st[d.id][0] = d.x;
          st[d.id][1] = d.y;
    }
    public void finish(Item d){}
    public byte getTool(){ return Env.CROSSHAIR; }
    public byte[] getIcon(){
        final byte icon[] = { 7, 9,4, 9,7, 8,12, 6,14, 6,18, 8,22, 15,24, 21,20, 24,20  };
        return icon;
    }

    public Rectangle fill(Graphics g, Item d){
        int wid = d.press&gt;&gt;1;
        for(int i=(-wid);i&lt;wid+1;i+=1){
               g.drawLine(d.x+i,d.y,st[d.id][0]+i,st[d.id][1]);
               g.drawLine(d.x,d.y+i,st[d.id][0],st[d.id][1]+i);
        }
        rect.reshape( Math.min(st[d.id][0],d.x)-d.press,Math.min(st[d.id][1],d.y)-d.press,
        Math.abs(st[d.id][0]-d.x)+d.press+d.press,Math.abs(st[d.id][1]-d.y)+d.press+d.press);
        st[d.id][0] = d.x;
        st[d.id][1] = d.y;
        return rect;
    }
}                 


//****************************************************
// HATCH

class hatch extends Stroke
{
 private Random r = new Random();

	private int[][] st = new int[10][2];

	public void init(Item d){
          st[d.id][0] = d.x;
          st[d.id][1] = d.y; 
	}
    public void finish(Item d){}
	public byte getTool(){ return Env.HATCH; }
	public byte[] getIcon(){ 
        final byte icon[] = { 10, 12,12, 18,18 , 12, 12, 18,18}; 
        return icon; 
    }


    public Rectangle fill(Graphics g, Item d)
    {
        java.awt.Polygon p = new java.awt.Polygon();
		int dx=0,dy=0,px=0,py=0;
		  px = Math.abs(st[d.id][0]-d.x) + 1;
          py = Math.abs(d.y-st[d.id][1]) + 1;
          for(int i=0;i&lt;d.press;i+=2){
                 dx += r.nextInt()%px;
                 dy += r.nextInt()%py; 
                 p.addPoint(d.x+dx,d.y+dy);
                 p.addPoint(st[d.id][0]+dx,st[d.id][1]+dy);
          }                          
		g.fillPolygon(p);
		st[d.id][0] = d.x;
        st[d.id][1] = d.y;  
	return p.getBoundingBox();
    }


}


//****************************************************
// RIBBON

class ribbon extends Stroke
{
 private int[][] st = new int[10][4];

  public void init(Item d){ 
        st[d.id][0] = d.x;
        st[d.id][1] = d.y;
        st[d.id][2] = d.x;
        st[d.id][3] = d.y;
  }
  public void finish(Item d){}
  public byte getTool(){ return Env.RIBBON; }
	public byte[] getIcon(){ 
         final byte icon[] = { 10, 5,6, 8,15, 15,22, 23,28};
         return icon; 
  }
     
    public Rectangle fill(Graphics g, Item d)
    {
         Polygon p = new Polygon();
                 double a = (double)(d.x - st[d.id][0]);
         double b = (double)(d.y - st[d.id][1]);
         double dbl = Math.sqrt(a*a+b*b);
         if(dbl==0) dbl = 1.0;
             p.addPoint(st[d.id][0],st[d.id][1]);
             p.addPoint(d.x,d.y);
             p.addPoint(st[d.id][2],st[d.id][3]);
             p.addPoint(st[d.id][2]=(int)(st[d.id][0]+d.press*((d.y-st[d.id][1])/dbl)),
                        st[d.id][3]=(int)(st[d.id][1]-d.press*((d.x-st[d.id][0])/dbl)));
             p.addPoint(d.x+st[d.id][2]-st[d.id][0], d.y+st[d.id][3]-st[d.id][1]);
             p.addPoint(d.x,d.y);              
	     g.drawPolygon(p);
                st[d.id][0] = d.x;
        st[d.id][1] = d.y;
                return p.getBoundingBox();
        }                   	
}       



//****************************************************
// SCALLOP

class scallop extends Stroke
{
	private int[][] st = new int[10][4];
	public void init(Item d){ 
        st[d.id][0] = d.x;
        st[d.id][1] = d.y;
        st[d.id][2] = d.x;
        st[d.id][3] = d.y;
	}
    public void finish(Item d){}
    public byte getTool(){ return Env.SCALLOP; }
    public byte[] getIcon(){ 
         final byte icon[]={2, 3,6, 19,4, 24,10, 22,17, 17,22, 9,25, 9,25};
         return icon; 
    }

     public Rectangle fill(Graphics g, Item d)
    {
        java.awt.Polygon p = new java.awt.Polygon();
            p.addPoint(d.x,d.y);
            p.addPoint(st[d.id][0],st[d.id][1]);
            p.addPoint(st[d.id][2],st[d.id][3]);
            if(d.press &gt; 100) g.fillPolygon(p);
	    else{
		for(int i = 0; i&lt; d.press; i++){
		int x = (i*st[d.id][0] + (d.press-i)*d.x)/d.press;
		int y = (i*st[d.id][1] + (d.press-i)*d.y)/d.press;
		g.drawLine(x,y,st[d.id][2],st[d.id][3]);
	        }
              g.drawPolygon(p);
	    }
            st[d.id][0] = d.x;
            st[d.id][1] = d.y;
            return p.getBoundingBox();
        }          
}       

/*
//****************************************************
// SNOW2

class snow extends Stroke
{
 Rectangle rect = new Rectangle();

	public void init(Item d){
		d.press = 0;
	}
    public void finish(Item d){}
	public byte getTool(){ return Env.SNOW; }
	public byte[] getIcon(){ 
           final byte icon[] = { 8, 5,5, 8,10, 12,14 ,16,16} ;
           return icon; 
    }

	Color c,nc;
        Random r = new Random();

    public Rectangle fill(Graphics g, Item d)
    {
int px=0,py=0,px2,py2;
           if(c != g.getColor())
           {
                c = g.getColor();
                nc = new Color(255-c.getRed(),255-c.getGreen(),255-c.getBlue());
           }
           g.setXORMode(nc);
           int hp = d.press==1?1:(byte)(d.press&gt;&gt;1);
           for(int i=1;i&lt;hp+1;i++)
           {
                px = d.x+r.nextInt()%hp;
                py = d.y+r.nextInt()%hp;
                px2 = px + 10;
                py2 = py + 10;
                g.drawLine(px,  py,px2,py2);
                g.drawLine(px+1,py,px2,py2);
                g.drawLine(px+2,py,px2,py2);
                g.drawLine(px+3,py,px2,py2);
                g.drawLine(px+4,py,px2,py2);
                g.drawLine(px+5,py,px2,py2);
                g.drawLine(px+6,py,px2,py2);
                g.drawLine(px+7,py,px2,py2);
                g.drawLine(px+8,py,px2,py2);
                g.drawLine(px+9,py,px2,py2);
           }
           g.setPaintMode();
           rect.reshape(d.x-d.press,d.y-d.press,d.press+d.press+10,d.press+d.press+10);
           return rect;           
    }
}       


//****************************************************
// SPINDLE2

class spindle extends Stroke
{
private Random r = new Random();
	private int[][] st = new int[10][2];   

	public void init(Item d){
		st[d.id][0] = d.x;
		st[d.id][1] = d.y;
    }
    public void finish(Item d){}
	public byte getTool(){ return Env.SPINDLE; }
	public byte[] getIcon(){ 
         final byte icon[] = {  10, 12,8, 7,17, 12,22, 21,28, 26,21, 26,11, 24,6};
         return icon; 
    }

    public Rectangle fill(Graphics g, Item d)
    {
        java.awt.Polygon p = new java.awt.Polygon();
		 int px=d.x; int py=d.y;
		 int hp = (d.press&lt;&lt;1)+1;
		 int jitx,jity;
		 int x=0, y=0;
		 int steps = (Math.abs(d.x-st[d.id][0]) + Math.abs(d.y-st[d.id][1]))/2;
                for(int i=0;i&lt;steps;i++){
		    if(d.press&gt;100){
			x = (i*d.x + (steps-i)*st[d.id][0])/steps;
                    	y = (i*d.y + (steps-i)*st[d.id][1])/steps;    
		    }else{
			x = ((steps-i)*d.x + i*st[d.id][0])/steps;
                    	y = ((steps-i)*d.y + i*st[d.id][1])/steps;    
		    }
		    if(Math.abs(px-x)&lt;hp){
	              jitx = ((st[d.id][0] - d.x)&gt;&gt;2); 
                      if(jitx&gt;4) jitx= 4;
		      else if(jitx&lt;-4) jitx=-4;
                      px += jitx;
		    }
		    else if(d.press&lt;100) px += r.nextInt()%d.press;
		    if(Math.abs(py-y)&lt;hp){
                       jity = ((st[d.id][1] - d.y)&gt;&gt;2);
                      if(jity&gt;4) jity= 4;
		      else if(jity&lt;-4) jity=-4;
		      py += jity;
		    }
		    else if(d.press&lt;100) py += r.nextInt()%d.press;
                    p.addPoint(x,y);
                    p.addPoint(px,py);
                }           
		 for(int i=0;i&lt;p.npoints;i+=2) g.drawLine(p.xpoints[i],p.ypoints[i],
                p.xpoints[i+1],p.ypoints[i+1]);  
		st[d.id][0] = d.x;
		st[d.id][1] = d.y;
		return p.getBoundingBox();
	}
}       


/*
//****************************************************
// THORNYNAIL

class thornynail extends Stroke
{
private Random r = new Random();
	
	private int[][] st = new int[10][2];
	public void init(Item d){
        st[d.id][0] = d.x;
        st[d.id][1] = d.y; 
	}
    public void finish(Item d){}
	public byte getTool(){ return Env.THORNYNAIL; }
	public byte[] getIcon(){ 
            final byte icon[] = { 9, 7,6, 12,10, 14,13, 20,20};
            return icon; 
    }

    public Rectangle fill(Graphics g, Item d)
    {
		int thick = d.press;
        java.awt.Polygon p = new java.awt.Polygon();
		thick = thick==0?1:thick;
            p.addPoint(d.x,d.y);
            p.addPoint(st[d.id][0],st[d.id][1]);
            p.addPoint(d.x+r.nextInt()%thick,d.y+r.nextInt()%thick);
            p.addPoint(d.x+r.nextInt()%thick,d.y+r.nextInt()%thick);
		g.fillPolygon(p);
		st[d.id][0] = d.x;
        st[d.id][1] = d.y;
		return p.getBoundingBox();
    }

}       


//****************************************************
// TINSEL2

class tinsel extends Stroke
{
private Random r = new Random();

	private int[][] st = new int[10][2];
	public void init(Item d){
        st[d.id][0] = d.x;
        st[d.id][1] = d.y; 
	}
    public void finish(Item d){}
	public byte getTool(){ return Env.TINSEL; }
	public byte[] getIcon(){ 
          final byte icon[] = { 9, 8,8, 11,12, 16,16, 20,17, 20,20}; 
          return icon; 
    }
     
    public Rectangle fill(Graphics g, Item d)
    {
                int thick = d.press;
        java.awt.Polygon p = new java.awt.Polygon();
           for(int i=0;i&lt;thick;i++){
                p.addPoint((r.nextInt()%thick)+d.x,(r.nextInt()%thick)+d.y);
                p.addPoint(d.x,d.y);
                p.addPoint(st[d.id][0],st[d.id][1]);
           }
        g.drawPolygon(p);
                st[d.id][0] = d.x;
        st[d.id][1] = d.y;
                return p.getBoundingBox();
	}
}       



//****************************************************
// VEIL2

class veil extends Stroke
{
 private Rectangle rect = new Rectangle();
	public void   init(Item d){ }
        public void   finish(Item d){}
	public byte   getTool(){ return Env.VEIL; }
	public byte[] getIcon(){ 
		final byte icon[] = { 7, 6,5, 8,9, 10,14, 13,20, 19,24 };
		return icon;     
    }

    public Rectangle fill(Graphics g, Item d)
    {
	   int thick = d.press;
	   int thick2 = d.press&gt;&gt;1;
	   int px = 0; 
	   int py = 0;
	   int dx = d.x%2==0? d.x-thick2:d.x-thick2+1;
           int dy = d.y%2==0? d.y-thick2:d.y-thick2+1;
           py = dy + thick;
           px = dx + thick;
           int i=0;
           while(true){
                 g.drawLine(dx+i,dy,dx,dy+i);
                             if(i&gt;=thick) break;
                 g.drawLine(px,py-i,px-i,py);
                 i+=2;
            }
            rect.reshape(dx,dy,thick,thick); 
			return rect;
    }
}
*/

//****************************************************
// BARCODE2

class barcode extends Stroke
{
    public void init(Item d){}
    public void finish(Item d){}
    public byte getTool(){ return Env.BARCODE; }
    public byte[] getIcon(){ 
		final byte icon[] = { 10,26,25 };
    	return icon; 
    }

    public Rectangle fill(Graphics g, Item d)
    {
		int dx,dy,py;
		  for(int i=0;i&lt;50;){
                py=(Env.r.nextInt()%2==0?35:45);
                for(dy=0;dy&lt;(dx=(Math.abs(Env.r.nextInt()%3)+1));dy++)
                    g.drawLine(d.x-25+i+dy,d.y-25,d.x-25+i+dy,d.y-25+py);
                if(py==35){
                    g.drawString((new Integer(i%10)).toString(),
                        d.x+i-25,d.y+23);
                }
                i+=(dx+6);
            }
            Env.rect.reshape(d.x-25,d.y-25,50,50);            
			return Env.rect;
    }
	   
}       

//****************************************************
// CAPGUN

class capgun extends Stroke
{
	private int[][] st = new int[10][2];

	public void init(Item d){
        st[d.id][0] = d.x;
        st[d.id][1] = d.y; 
	} 
    public void finish(Item d){}
	public byte getTool(){ return Env.CAPGUN; }
	public byte[] getIcon(){ 
        final byte icon[] = { 10, 6,6, 8,10, 13,16, 23,24 };
        return icon; 
    } 


     public Rectangle fill(Graphics g, Item d)
    {
        int[] xpts= new int[4];
        int[] ypts= new int[4];
        int thick = (byte)(d.press&gt;&gt;1);
        int thick2 = thick&lt;&lt;1;
        g.fillOval((d.x - thick), (d.y - thick), thick2 , thick2);
        g.fillOval((st[d.id][0] - thick), (st[d.id][1] - thick), thick2, thick2);
        float f9= (float)(st[d.id][0] - d.x);
        float f10= (float)(st[d.id][1] - d.y);
        float f12;
        float f11= (float)thick * (float)Math.sqrt(( 1.0  /                                                             (double)( (float)1.0  + ((f9 * f9) / (f10 * f10)))));
        if ((f10 !=  (float)0.0 )) {
            f12= (-(f11 * f9)) / f10;
        }
        else {
            f12= (float)thick;
            f11=0;
        }
        xpts[0]= (int)((float)d.x - f11);
        xpts[1]= (int)((float)d.x + f11);
        xpts[2]= (int)((float)st[d.id][0] + f11);
        xpts[3]= (int)((float)st[d.id][0] - f11);
        ypts[0]= (int)((float)d.y - f12);  
	    ypts[1]= (int)((float)d.y + f12);
        ypts[2]= (int)((float)st[d.id][1] + f12);
        ypts[3]= (int)((float)st[d.id][1] - f12);
        java.awt.Polygon p = new java.awt.Polygon(xpts,ypts,4);
	g.drawLine(xpts[0],ypts[0],xpts[3],ypts[3]);
	g.drawLine(xpts[2],ypts[2],xpts[1],ypts[1]);
		
        st[d.id][0] = d.x;
        st[d.id][1] = d.y;
        Rectangle r = new Rectangle(d.x - thick, d.y -thick, thick2, thick2);
        return r.union(p.getBoundingBox());   
     }
}       



//****************************************************
// CROSSHAIR 

class crosshair extends Stroke
{
private Rectangle rect = new Rectangle();
 private int[][] st = new int[10][2];

    public void init(Item d){
          st[d.id][0] = d.x;
          st[d.id][1] = d.y;
    }
    public void finish(Item d){}
    public byte getTool(){ return Env.CROSSHAIR; }
    public byte[] getIcon(){
        final byte icon[] = { 7, 9,4, 9,7, 8,12, 6,14, 6,18, 8,22, 15,24, 21,20, 24,20  };
        return icon;
    }

    public Rectangle fill(Graphics g, Item d){
        int wid = d.press&gt;&gt;1;
        for(int i=(-wid);i&lt;wid+1;i+=1){
               g.drawLine(d.x+i,d.y,st[d.id][0]+i,st[d.id][1]);
               g.drawLine(d.x,d.y+i,st[d.id][0],st[d.id][1]+i);
        }
        rect.reshape( Math.min(st[d.id][0],d.x)-d.press,Math.min(st[d.id][1],d.y)-d.press,
        Math.abs(st[d.id][0]-d.x)+d.press+d.press,Math.abs(st[d.id][1]-d.y)+d.press+d.press);
        st[d.id][0] = d.x;
        st[d.id][1] = d.y;
        return rect;
    }
}                 


//****************************************************
// GOOBER

class goober extends Stroke
{
    public void init(Item d){}
    public void finish(Item d){}
	public byte getTool(){ return Env.GOOBER; }
	public byte[] getIcon(){ 
        //final byte icon[] = { 20, 16,15, 28,14, 29,31, 18,30 };
        final byte icon[] = { 10, 13,24, 14,13, 20,9, 20,20, 12,22, 9,14, 13,5,  };
        return icon; 
    } 

Rectangle rect = new Rectangle();
Random r = new Random();

    public Rectangle fill(Graphics g, Item d)
    {
	int i,px=0,py=0;
	int thick = (byte)(d.press&gt;&gt;1);
	int thicksq = thick*thick;
		 for(i=0;i&lt;thick;i++) {
			px = r.nextInt()%thick;
               py = r.nextInt()%((int)Math.sqrt(thicksq-px*px))
                     + d.y;
               px += d.x;
			g.fillRect(px,py,2,2);
		}
	rect.reshape(d.x-i-2,d.y-i-2,i+i+4,i+i+4);
	return rect;
    }

/* Not in use with this version yet
 *
    Rectangle draw(Graphics g, Item d)
    {
        int i,px=0,py=0;
	int thick = (byte)(d.press&gt;&gt;1);
		 int thicksq = thick*thick;
		 for(i=0;i&lt;thick;i++) 
		 {
			px = Env.r.nextInt()%thick;
               py = Env.r.nextInt()%((int)Math.sqrt(thicksq-px*px))
                     + d.y;
               px += d.x;
			g.drawRect(px,py,2,2);
		 }
	Env.rect.reshape(d.x-i-2,d.y-i-2,i+i+4,i+i+4);
	return Env.rect;
    }
*/
}       



//****************************************************
// GRASS

class grass extends Stroke
{
    public void init(Item d){}
    public void   finish(Item d){}
    public byte    getTool(){ return Env.GRASS; }
    public String getName(){ return "Grass";   }
    public byte[] getIcon(){ 
       final byte icon[] = { 10, 21,21, 15,18, 9,9, 15,19, 19,8,  };
       return icon;      
    }

Random r = new Random();
Rectangle rect = new Rectangle();

    public Rectangle fill(Graphics g, Item d)
    {
		int thick = (byte)(d.press&gt;&gt;1);
		int px=0,py=0;
            for(int i=0;i&lt;thick;i+=2){
                py = r.nextInt()%thick;
				px = d.x-py;
				py = d.y-py;
                g.drawLine(px,py+i,px+i,py);
                g.drawLine(px+thick,py-i,px+i,py+thick);
            }
            rect.reshape(px-2*thick,py-2*thick,4*thick,4*thick);
		return rect;
    }

 /* This not used yet by this version
  * 
    Rectangle draw(Graphics g, Item d,connection con)
    {
		int px=0,py=0;
		int thick=(byte)(d.press&gt;&gt;1);
        for(int i=0;i&lt;thick;i+=2){
            py = Env.r.nextInt()%thick;
		    px = d.x-py;
			py = d.y-py;
            g.drawLine(px,py+i,px+i,py);
            g.drawLine(px+thick,py+i,px-i,py+thick);
        }
        Env.rect.reshape(px-2*thick,py-2*thick,4*thick,4*thick);
		return Env.rect;
    }
*/

  /* Older alternate style
    Rectangle fill(Graphics g, int x, int y, int ox, int oy, int px, int py, byte thick)
    {
        for(int i=0;i&lt;thick;i+=2){
           py = d.y-Env.r.nextInt()%thick;
		   px = d.x-Env.r.nextInt()%thick;
           g.drawLine(px,py+i,px+i,py);
           g.drawLine(px+thick,py+thick,px-i,py-i);
        }
        return new Rectangle(px,py,thick,thick);
    }*/

}


//****************************************************
// GUNKO

class gunko extends Stroke
{
	public void init(Item d){ 
	}
    public void finish(Item d){}
	public byte getTool(){ return Env.GUNKO; }
	public byte[] getIcon(){ 
        final byte icon[] = { 11, 15,15, 14,14 };
        return icon; 
    }

Random r = new Random();

    public Rectangle fill(Graphics g, Item d)
    {
        java.awt.Polygon p = new java.awt.Polygon();
	int thick = (d.press&lt;5?d.press+3:d.press);
        for(int i=0;i&lt;thick;i++)
                p.addPoint(r.nextInt()%thick+d.x, r.nextInt()%thick+d.y);
        g.fillPolygon(p);
	return p.getBoundingBox();
    }

/*  This not in use in this version yet
 *
    Rectangle draw(Graphics g, Item d)
    {
        java.awt.Polygon p = new java.awt.Polygon();
		int thick = (d.press&lt;5?d.press+3:d.press);
            for(int i=0;i&lt;thick;i++)
                     p.addPoint(r.nextInt()%thick+d.x, r.nextInt()%thick+d.y);
        g.drawPolygon(p);
		return p.getBoundingBox();
    }
*/
}       



//****************************************************
// HATCH

class hatch extends Stroke
{
 private Random r = new Random();

	private int[][] st = new int[10][2];

	public void init(Item d){
          st[d.id][0] = d.x;
          st[d.id][1] = d.y; 
	}
    public void finish(Item d){}
	public byte getTool(){ return Env.HATCH; }
	public byte[] getIcon(){ 
        final byte icon[] = { 10, 12,12, 18,18 , 12, 12, 18,18}; 
        return icon; 
    }


    public Rectangle fill(Graphics g, Item d)
    {
        java.awt.Polygon p = new java.awt.Polygon();
		int dx=0,dy=0,px=0,py=0;
		  px = Math.abs(st[d.id][0]-d.x) + 1;
          py = Math.abs(d.y-st[d.id][1]) + 1;
          for(int i=0;i&lt;d.press;i+=2){
                 dx += r.nextInt()%px;
                 dy += r.nextInt()%py; 
                 p.addPoint(d.x+dx,d.y+dy);
                 p.addPoint(st[d.id][0]+dx,st[d.id][1]+dy);
          }                          
		g.fillPolygon(p);
		st[d.id][0] = d.x;
        st[d.id][1] = d.y;  
	return p.getBoundingBox();
    }


}


//****************************************************
// LINE

class line extends Stroke
{
  private int[][] st = new int[Env.MAX_USERS][2];  
    public void init(Item d){
        st[d.id][0] = d.x;
        st[d.id][1] = d.y;    
    }
    public void finish(Item d){}
    public byte getTool(){ return Env.LINE; }
    public byte[] getIcon(){ 
            //byte icon[] = { 8, 8,8, 16,9, 26,13, 27,23, 16,31, 24,37, 37,38};
            byte icon[] = { 10, 6,7, 15,11, 22,20,  };
            return icon; 
    }

    public Rectangle fill(Graphics g, Item d)
    {
		int thick = d.press ;
        int[] xpts= new int[4];
        int[] ypts= new int[4];
        if (thick &lt; 2)
        {
            g.drawLine(d.x, d.y, st[d.id][0], st[d.id][1]);
            Env.rect.reshape(Math.min(d.x,st[d.id][0])-2,Math.min(d.y,st[d.id][1])-2,Math.abs(d.x-st[d.id][0])+6,Math.abs(d.y-st[d.id][1])+6);
			return Env.rect;
        }
		thick= (byte)(thick/2);
        g.fillOval((d.x - thick), (d.y - thick), (thick * 2), (thick * 2));
        g.fillOval((st[d.id][0] - thick), (st[d.id][1] - thick), (thick * 2), (thick * 2));
        float f9= (float)(st[d.id][0] - d.x);
        float f10= (float)(st[d.id][1] - d.y);
        float f12;
        float f11= (float)thick * (float)Math.sqrt(( 1.0  / (double)( (float)1.0  + ((f9 * f9) / (f10 *
f10)))));
        if ((f10 !=  (float)0.0 )) {
            f12= (-(f11 * f9)) / f10;
        }
        else {
            f12= (float)thick;
        }
        xpts[0]= Math.round(((float)d.x - f11));
        xpts[1]= Math.round(((float)d.x + f11));
        xpts[2]= Math.round(((float)st[d.id][0] + f11));
        xpts[3]= Math.round(((float)st[d.id][0]- f11));
        ypts[0]= Math.round(((float)d.y - f12));
        ypts[1]= Math.round(((float)d.y + f12));
        ypts[2]= Math.round(((float)st[d.id][1] + f12));
        ypts[3]= Math.round(((float)st[d.id][1] - f12));
        java.awt.Polygon p = new java.awt.Polygon(xpts,ypts,4);
        g.fillPolygon(p);
		st[d.id][0] = d.x;
        st[d.id][1] = d.y;      
		Rectangle r = new Rectangle(d.x - thick, d.y -thick, 2*thick, 2*thick);
		return r.union(p.getBoundingBox());
    }

/* Not used in this version yet
 *
    Rectangle draw(Graphics g, Item d,connection con)
    {
	int thick = d.press ;
        int[] xpts= new int[4];
        int[] ypts= new int[4];
        if (thick &lt;2)
        {
            g.drawLine(d.x, d.y, st[d.id][0], st[d.id][1]);
            Env.rect.reshape(Math.min(d.x,st[d.id][0])-2,Math.min(d.y,st[d.id][1])-2,
                                 Math.abs(d.x-st[d.id][0])+6,Math.abs(d.y-st[d.id][1])+6);
			return Env.rect;
        }
		thick = (byte)(thick/2);
        g.drawOval((d.x - thick), (d.y - thick), (thick * 2), (thick * 2));
        g.drawOval((st[d.id][0] - thick), (st[d.id][1] - thick), (thick * 2), (thick * 2));
        float f9= (float)(st[d.id][0] - d.x);
        float f10= (float)(st[d.id][1] - d.y);
		if(f10==0.0) return Env.rect;
        float f12;
        float f11= (float)thick * (float)Math.sqrt(( 1.0  / (double)( (float)1.0  + ((f9 * f9) / (f10 *
f10)))));
        if ((f10 !=  (float)0.0 )) {
            f12= (-(f11 * f9)) / f10;
        }
        else {
            f12= (float)thick;
        }
        xpts[0]= Math.round(((float)d.x - f11));
        xpts[1]= Math.round(((float)d.x + f11));
        xpts[2]= Math.round(((float)st[d.id][0] + f11));
        xpts[3]= Math.round(((float)st[d.id][0]- f11));
        ypts[0]= Math.round(((float)d.y - f12));
        ypts[1]= Math.round(((float)d.y + f12));
        ypts[2]= Math.round(((float)st[d.id][1] + f12));
        ypts[3]= Math.round(((float)st[d.id][1] - f12));
        java.awt.Polygon p = new java.awt.Polygon(xpts,ypts,4);
		st[d.id][0] = d.x;
        st[d.id][1] = d.y;      
        g.drawPolygon(p);
		Rectangle r = new Rectangle(d.x - thick, d.y -thick, 2*thick, 2*thick);
		if(con!=null) con.send(d);
		return r.union(p.getBoundingBox());
    }
*/
}       



//****************************************************
// NLEGS

class nlegs extends Stroke
{
   private int[][] st = new int[10][4];

    public void init(Item d){  
        st[d.id][0] = d.x;
        st[d.id][1] = d.y;
        st[d.id][2] = d.x;
        st[d.id][3] = d.y;
    }
    public void finish(Item d){}
	public byte getTool(){ return Env.NLEGS; }
	public byte[] getIcon(){ 
         final byte icon[] = { 8, 4,7, 6,15, 8,18, 14,25, 20,28};
         return icon; 
    }
	
    public Rectangle fill(Graphics g, Item d)
    {
        java.awt.Polygon p = new java.awt.Polygon();
	double a = (double)(d.x - st[d.id][0]);
        double b = (double)(d.y - st[d.id][1]);
        double dbl = Math.sqrt(a*a+b*b);
        if(dbl==0) dbl = 1.0; 
            p.addPoint(d.x,d.y);
            p.addPoint(st[d.id][0],st[d.id][1]);
            p.addPoint(st[d.id][2],st[d.id][3]);
	    p.addPoint(st[d.id][2]=(int)(st[d.id][0]+d.press*((d.y-st[d.id][1])/dbl)),
            st[d.id][3]=(int)(st[d.id][1]-d.press*((d.x-st[d.id][0])/dbl)));
            st[d.id][2]+=(d.x-st[d.id][0]);
            st[d.id][3]+=(d.y-st[d.id][1]);
            p.addPoint(st[d.id][2], st[d.id][3]);
            p.addPoint(d.x,d.y);
		 for(int i=0;i&lt;p.npoints;i+=2) g.drawLine(p.xpoints[i],p.ypoints[i],
                p.xpoints[i+1],p.ypoints[i+1]);  
		 st[d.id][0] = d.x;
         st[d.id][1] = d.y;
		return p.getBoundingBox();
    }

/* Not yet in use
 *
    Rectangle draw(Graphics g, Item d,connection con)
    {
        java.awt.Polygon p = new java.awt.Polygon();
		int x, y;
	
		d.press = (d.press&lt;2?(byte)1:(byte)(d.press&gt;&gt;1));
		double a = (double)(d.x - st[d.id][0]);
        double b = (double)(d.y - st[d.id][1]);
        double dbl = Math.sqrt(a*a+b*b);
        if(dbl==0) dbl = 1.0; 
		
            p.addPoint(d.x,d.y);
            p.addPoint(st[d.id][0],st[d.id][1]);
            p.addPoint(x=st[d.id][2],y=st[d.id][3]);
		    p.addPoint(st[d.id][2]=(int)(st[d.id][0]+d.press*((d.y-st[d.id][1])/dbl)),
            st[d.id][3]=(int)(st[d.id][1]-d.press*((d.x-st[d.id][0])/dbl)));
			p.addPoint((d.x-st[d.id][2])*2+d.x,(d.y-st[d.id][3])*2+d.y);
			p.addPoint((d.x-x)*2+d.x,(d.y-y)*2+d.y);
            st[d.id][2]+=(d.x-st[d.id][0]);
            st[d.id][3]+=(d.y-st[d.id][1]);
            p.addPoint(st[d.id][2], st[d.id][3]);
		 for(int i=0;i&lt;p.npoints-1;i+=2) g.drawLine(p.xpoints[i],p.ypoints[i],
                p.xpoints[i+1],p.ypoints[i+1]);  
		 st[d.id][0] = d.x;
         st[d.id][1] = d.y;
		if(con!=null) con.send(d);
		return p.getBoundingBox();
	}
*/
}       



//****************************************************
// PROP

class prop extends Stroke
{
    public void init(Item d){ }
    public void finish(Item d){}
	public byte getTool(){ return Env.PROP; }
 	public byte[] getIcon(){ 
	     final byte icon[] = { 15, 3,7, 17,6, 20,15, 7,20,};
        return icon; 
    }

Random r = new Random();
Rectangle rect = new Rectangle();

    public Rectangle fill(Graphics g, Item d)
    {
		int thick = d.press ;
		int dx,i;
		thick = thick==0? 1: thick;
		for(i=0;i&lt;256;i+=thick){
            dx = Math.abs(r.nextInt()%thick);
            g.fillArc(d.x-dx/2,d.y-dx/2,dx,dx,r.nextInt()%360,r.nextInt()%90);
        }
        rect.reshape(d.x-thick&gt;&gt;1,d.y-thick&gt;&gt;1,i+thick,i+thick); 
	return rect;
    }

/* Not yet in use
 *    Rectangle draw(Graphics g, Item d,connection con)
    {
		int dx,i;
		int thick = d.press ;
		thick = thick==0? 1: thick;
		//for(i=0;(i&lt;&lt;4)&lt;4096;i+=thick){
		for(i=0;i&lt;256;i+=thick){
            dx = Math.abs(r.nextInt()%thick);
            g.drawArc(d.x-dx/2,d.y-dx/2,dx,dx,r.nextInt()%360,r.nextInt()%90);
        }
        rect.reshape(d.x-thick&gt;&gt;1,d.y-thick&gt;&gt;1,i+thick,i+thick); 
		if(con!=null) con.send(d);
		return rect;
    }
*/
}



//****************************************************
// RIBBON

class ribbon extends Stroke
{
 private int[][] st = new int[10][4];

  public void init(Item d){ 
        st[d.id][0] = d.x;
        st[d.id][1] = d.y;
        st[d.id][2] = d.x;
        st[d.id][3] = d.y;
  }
  public void finish(Item d){}
  public byte getTool(){ return Env.RIBBON; }
	public byte[] getIcon(){ 
         final byte icon[] = { 10, 5,6, 8,15, 15,22, 23,28};
         return icon; 
  }
     
    public Rectangle fill(Graphics g, Item d)
    {
         Polygon p = new Polygon();
                 double a = (double)(d.x - st[d.id][0]);
         double b = (double)(d.y - st[d.id][1]);
         double dbl = Math.sqrt(a*a+b*b);
         if(dbl==0) dbl = 1.0;
                         p.addPoint(st[d.id][0],st[d.id][1]);
             p.addPoint(d.x,d.y);
             p.addPoint(st[d.id][2],st[d.id][3]);
             p.addPoint(st[d.id][2]=(int)(st[d.id][0]+d.press*((d.y-st[d.id][1])/dbl)),
                        st[d.id][3]=(int)(st[d.id][1]-d.press*((d.x-st[d.id][0])/dbl)));
             p.addPoint(d.x+st[d.id][2]-st[d.id][0], d.y+st[d.id][3]-st[d.id][1]);
             p.addPoint(d.x,d.y);              
	     g.drawPolygon(p);
                st[d.id][0] = d.x;
        st[d.id][1] = d.y;
                return p.getBoundingBox();
        }                   	
}       



//****************************************************
// SCALLOP

class scallop extends Stroke
{
	private int[][] st = new int[10][4];
	public void init(Item d){ 
        st[d.id][0] = d.x;
        st[d.id][1] = d.y;
        st[d.id][2] = d.x;
        st[d.id][3] = d.y;
	}
    public void finish(Item d){}
    public byte getTool(){ return Env.SCALLOP; }
    public byte[] getIcon(){ 
         final byte icon[]={2, 3,6, 19,4, 24,10, 22,17, 17,22, 9,25, 9,25};
         return icon; 
    }

     public Rectangle fill(Graphics g, Item d)
    {
        java.awt.Polygon p = new java.awt.Polygon();
            p.addPoint(d.x,d.y);
            p.addPoint(st[d.id][0],st[d.id][1]);
            p.addPoint(st[d.id][2],st[d.id][3]);
            if(d.press &gt; 100) g.fillPolygon(p);
	    else{
		for(int i = 0; i&lt; d.press; i++){
		int x = (i*st[d.id][0] + (d.press-i)*d.x)/d.press;
		int y = (i*st[d.id][1] + (d.press-i)*d.y)/d.press;
		g.drawLine(x,y,st[d.id][2],st[d.id][3]);
	        }
              g.drawPolygon(p);
	    }
            st[d.id][0] = d.x;
            st[d.id][1] = d.y;
            return p.getBoundingBox();
        }          
}       



//****************************************************
// SINE

class sine extends Stroke
{
    private int[][] st = new int[10][4];
    private boolean[] neg = new boolean[10];

    public void init(Item d){ 
	st[d.id][0] = d.x;
        st[d.id][1] = d.y;
        st[d.id][2] = d.x;
        st[d.id][3] = d.y;
    }
    public void finish(Item d){}
    public byte getTool(){ return Env.SINE; }
    public byte[] getIcon(){ 
      final byte icon[] = { 10, 25,26, 20,20, 13,12, 8,8,  };
      return icon; 
    }


    public Rectangle fill(Graphics g, Item d)
    {
		int thick = d.press;
		int xx, yy;
		int mpx=(d.x+st[d.id][0])&gt;&gt;1;
		int mpy=(d.y+st[d.id][1])&gt;&gt;1;
		double dx = d.x - st[d.id][0];	
		double dy = d.y - st[d.id][1];	
		double diameter = Math.sqrt(dx*dx+ dy*dy);
		double radius = diameter/2.0;
		 xx = (int)(mpx-radius);
		 yy = (int)(mpy-radius);
		 int st_angle = (int)(180.0*(Math.acos((double)(mpx-st[d.id][0])/radius))/Math.PI);
		 if((mpy-st[d.id][1])&gt;=0) st_angle=(360-st_angle);
		 g.drawArc(xx,yy,(int)diameter,(int)diameter,st_angle,neg[d.id]?180:-180);
		 g.drawArc(xx+1,yy+1,(int)diameter-2,(int)diameter-2,st_angle,neg[d.id]?180:-180);
		 g.drawArc(xx-1,yy-1,(int)diameter+2,(int)diameter+2,st_angle,neg[d.id]?180:-180);
		 neg[d.id] = !neg[d.id];
		st[d.id][0] = d.x;
		st[d.id][1] = d.y;
	return new Rectangle(Math.min(d.x,st[d.id][0]),Math.min(d.y,st[d.id][1]),d.press,d.press);
	}

/* Not yet in use
 *
    Rectangle draw(Graphics g, Item d)
    {
	int thick = d.press;
	int tx, ty;
        int xx, yy;
	int lox, loy;
	lox = st[d.id][0];
	loy = st[d.id][1];
        double steps = (int)d.press;
        double scale;
        double a = (double)(d.x - st[d.id][0]);
        double b = (double)(d.y - st[d.id][1]);
        double dbl = Math.sqrt(a*a+b*b);
	if(dbl==0) dbl = 1.0;
	double factorb = b/dbl;
	double factora = a/dbl;
        for(int i = 1; i&lt;= steps; i++){
				xx =(int)(( i*d.x + (steps-i)*st[d.id][0])/steps);
                yy =(int)(( i*d.y + (steps-i)*st[d.id][1])/steps);   
                scale = (double)(thick* Math.sin(Math.PI*2.0*(i)/steps));
                tx  =  (int)(xx +      scale*factorb);
                ty  =  (int)(yy -      scale*factora);
                g.drawLine(tx,ty,lox,loy);
                lox = tx;
                loy = ty;
        }                                          
	st[d.id][0] = d.x;
        st[d.id][1] = d.y; 
	 return new Rectangle(Math.min(d.x,st[d.id][0]),Math.min(d.y,st[d.id][1]),d.press,d.press);
    }
*/
}



//****************************************************
// SNOW

class snow extends Stroke
{
 Rectangle rect = new Rectangle();

	public void init(Item d){
		d.press = 0;
	}
    public void finish(Item d){}
	public byte getTool(){ return Env.SNOW; }
	public byte[] getIcon(){ 
           final byte icon[] = { 8, 5,5, 8,10, 12,14 ,16,16} ;
           return icon; 
    }

	Color c,nc;
        Random r = new Random();

    public Rectangle fill(Graphics g, Item d)
    {
int px=0,py=0,px2,py2;
           if(c != g.getColor())
           {
                c = g.getColor();
                nc = new Color(255-c.getRed(),255-c.getGreen(),255-c.getBlue());
           }
           g.setXORMode(nc);
           int hp = d.press==1?1:(byte)(d.press&gt;&gt;1);
           for(int i=1;i&lt;hp+1;i++)
           {
                px = d.x+r.nextInt()%hp;
                py = d.y+r.nextInt()%hp;
                px2 = px + 10;
                py2 = py + 10;
                g.drawLine(px,  py,px2,py2);
                g.drawLine(px+1,py,px2,py2);
                g.drawLine(px+2,py,px2,py2);
                g.drawLine(px+3,py,px2,py2);
                g.drawLine(px+4,py,px2,py2);
                g.drawLine(px+5,py,px2,py2);
                g.drawLine(px+6,py,px2,py2);
                g.drawLine(px+7,py,px2,py2);
                g.drawLine(px+8,py,px2,py2);
                g.drawLine(px+9,py,px2,py2);
           }
           g.setPaintMode();
           rect.reshape(d.x-d.press,d.y-d.press,d.press+d.press+10,d.press+d.press+10);
           return rect;           
    }


}       



//****************************************************
// SPINDLE

class spindle extends Stroke
{
private Random r = new Random();
	private int[][] st = new int[10][2];   

	public void init(Item d){
		st[d.id][0] = d.x;
		st[d.id][1] = d.y;
    }
    public void finish(Item d){}
	public byte getTool(){ return Env.SPINDLE; }
	public byte[] getIcon(){ 
         final byte icon[] = {  10, 12,8, 7,17, 12,22, 21,28, 26,21, 26,11, 24,6};
         return icon; 
    }

    public Rectangle fill(Graphics g, Item d)
    {
        java.awt.Polygon p = new java.awt.Polygon();
		 int px=d.x; int py=d.y;
		 int hp = (d.press&lt;&lt;1)+1;
		 int jitx,jity;
		 int x=0, y=0;
		 int steps = (Math.abs(d.x-st[d.id][0]) + Math.abs(d.y-st[d.id][1]))/2;
                for(int i=0;i&lt;steps;i++){
		    if(d.press&gt;100){
			x = (i*d.x + (steps-i)*st[d.id][0])/steps;
                    	y = (i*d.y + (steps-i)*st[d.id][1])/steps;    
		    }else{
			x = ((steps-i)*d.x + i*st[d.id][0])/steps;
                    	y = ((steps-i)*d.y + i*st[d.id][1])/steps;    
		    }
		    if(Math.abs(px-x)&lt;hp){
	              jitx = ((st[d.id][0] - d.x)&gt;&gt;2); 
                      if(jitx&gt;4) jitx= 4;
		      else if(jitx&lt;-4) jitx=-4;
                      px += jitx;
		    }
		    else if(d.press&lt;100) px += r.nextInt()%d.press;
		    if(Math.abs(py-y)&lt;hp){
                       jity = ((st[d.id][1] - d.y)&gt;&gt;2);
                      if(jity&gt;4) jity= 4;
		      else if(jity&lt;-4) jity=-4;
		      py += jity;
		    }
		    else if(d.press&lt;100) py += r.nextInt()%d.press;
                    p.addPoint(x,y);
                    p.addPoint(px,py);
                }           
		 for(int i=0;i&lt;p.npoints;i+=2) g.drawLine(p.xpoints[i],p.ypoints[i],
                p.xpoints[i+1],p.ypoints[i+1]);  
		st[d.id][0] = d.x;
		st[d.id][1] = d.y;
		return p.getBoundingBox();
	}
}       



//****************************************************
// SPLATTER

class splatter extends capgun
{
    private int[][] st = new int[10][2]; 

    public void init(Item d){
	  st[d.id][0] = d.x;
	  st[d.id][1] = d.y;
	  super.init(d);
    }
    public byte getTool(){ return Env.SPLAT; }
    public byte[] getIcon(){ 
         final byte icon[] = { 7, 6,8, 12,14, 16,20, 18,23 }; 
         return icon; 
    }


    public Rectangle fill(Graphics g, Item d)
    {
		splat(g,d);
		return super.fill(g,d);
    }

Random r = new Random();
	
    public void splat(Graphics g,Item d){
	    int dx = Math.abs(d.x-st[d.id][0]) + d.press;
		int dy = Math.abs(d.y-st[d.id][1]) + d.press;
		for(int i=0;i&lt;d.press;i++) g.drawRect(d.x+r.nextInt()%dx,d.y+r.nextInt()%dy,1,1);
		st[d.id][0] = d.x;
        st[d.id][1] = d.y;    
    }

/* Not yet in use
 *
    Rectangle draw(Graphics g, Item d)
    {
		splat(g,d);
		return super.draw(g,d);
    }
*/
}       


//****************************************************
// THORNYNAIL

class thornynail extends Stroke
{
private Random r = new Random();
	
	private int[][] st = new int[10][2];
	public void init(Item d){
        st[d.id][0] = d.x;
        st[d.id][1] = d.y; 
	}
    public void finish(Item d){}
	public byte getTool(){ return Env.THORNY; }
	public byte[] getIcon(){ 
            final byte icon[] = { 9, 7,6, 12,10, 14,13, 20,20};
            return icon; 
    }

    public Rectangle fill(Graphics g, Item d)
    {
		int thick = d.press;
        java.awt.Polygon p = new java.awt.Polygon();
		thick = thick==0?1:thick;
            p.addPoint(d.x,d.y);
            p.addPoint(st[d.id][0],st[d.id][1]);
            p.addPoint(d.x+r.nextInt()%thick,d.y+r.nextInt()%thick);
            p.addPoint(d.x+r.nextInt()%thick,d.y+r.nextInt()%thick);
		g.fillPolygon(p);
		st[d.id][0] = d.x;
        st[d.id][1] = d.y;
		return p.getBoundingBox();
    }

}       


//****************************************************
// TINSEL

class tinsel extends Stroke
{
private Random r = new Random();

	private int[][] st = new int[10][2];
	public void init(Item d){
        st[d.id][0] = d.x;
        st[d.id][1] = d.y; 
	}
    public void finish(Item d){}
	public byte getTool(){ return Env.TINSEL; }
	public byte[] getIcon(){ 
          final byte icon[] = { 9, 8,8, 11,12, 16,16, 20,17, 20,20}; 
          return icon; 
    }
     
    public Rectangle fill(Graphics g, Item d)
    {
                int thick = d.press;
        java.awt.Polygon p = new java.awt.Polygon();
           for(int i=0;i&lt;thick;i++){
                p.addPoint((r.nextInt()%thick)+d.x,(r.nextInt()%thick)+d.y);
                p.addPoint(d.x,d.y);
                p.addPoint(st[d.id][0],st[d.id][1]);
           }
        g.drawPolygon(p);
                st[d.id][0] = d.x;
        st[d.id][1] = d.y;
                return p.getBoundingBox();
	}
}       



//****************************************************
// VEIL

class veil extends Stroke
{
 private Rectangle rect = new Rectangle();
	public void   init(Item d){ }
        public void   finish(Item d){}
	public byte   getTool(){ return Env.VEIL; }
	public byte[] getIcon(){ 
		final byte icon[] = { 7, 6,5, 8,9, 10,14, 13,20, 19,24 };
		return icon;     
    }

    public Rectangle fill(Graphics g, Item d)
    {
	   int thick = d.press;
	   int thick2 = d.press&gt;&gt;1;
	   int px = 0; 
	   int py = 0;
	   int dx = d.x%2==0? d.x-thick2:d.x-thick2+1;
           int dy = d.y%2==0? d.y-thick2:d.y-thick2+1;
           py = dy + thick;
           px = dx + thick;
           int i=0;
           while(true){
                 g.drawLine(dx+i,dy,dx,dy+i);
                             if(i&gt;=thick) break;
                 g.drawLine(px,py-i,px-i,py);
                 i+=2;
            }
            rect.reshape(dx,dy,thick,thick); 
			return rect;
    }
}



//****************************************************
// WRAKE

class wrake extends Stroke
{
	private int[][] st = new int[Env.MAX_USERS][4]; 

	public void init(Item d){ 
        st[d.id][0] = d.x;
        st[d.id][1] = d.y; 
        //st[d.id][2] = d.x;
        //st[d.id][3] = d.y; 
	}
    public void finish(Item d){}
	public byte    getTool(){ return Env.WRAKE; }
	public byte[] getIcon(){ 
           final byte icon[] = {10, 11,5, 19,7, 23,13, 18,21, 11,23, 7,22,   };
	       return icon;      
    }	

    public Rectangle fill(Graphics g, Item d)
    {
        java.awt.Polygon p = new java.awt.Polygon();
		int dx,dy;
		d.press  = (d.press&lt;2?(byte)1:(byte)(d.press&gt;&gt;1));
		double a = (double)(d.x - st[d.id][0]);
        double b = (double)(d.y - st[d.id][1]);
        double dbl = Math.sqrt(a*a+b*b);
        if(dbl==0) dbl = 1.0;
			 dx = st[d.id][0]-st[d.id][2];
             dy = st[d.id][1]-st[d.id][3];
            p.addPoint(d.x,d.y);
            p.addPoint(st[d.id][0],st[d.id][1]);
			p.addPoint(st[d.id][2],st[d.id][3]);   
            p.addPoint(st[d.id][2]=(int)(st[d.id][0]+d.press*((d.y-st[d.id][1])/dbl)),
            st[d.id][3]=(int)(st[d.id][1]-d.press*((d.x-st[d.id][0])/dbl)));
			p.addPoint(st[d.id][0]+dx,st[d.id][1]+dy);
            p.addPoint(d.x+(d.x-st[d.id][2]),d.y+(d.y-st[d.id][3]));
		g.fillPolygon(p);
		st[d.id][0] = d.x;
        st[d.id][1] = d.y;
		return p.getBoundingBox();
    }

/* Not yet in use
 *
    Rectangle draw(Graphics g, Item d,connection con)
    {
        java.awt.Polygon p = new java.awt.Polygon();
		int dx,dy;
		d.press  = (d.press&lt;2?(byte)1:(byte)(d.press&gt;&gt;1));
		double a = (double)(d.x - st[d.id][0]);
        double b = (double)(d.y - st[d.id][1]);
        double dbl = Math.sqrt(a*a+b*b);
        if(dbl==0) dbl = 1.0;
			 dx = st[d.id][0]-st[d.id][2];
             dy = st[d.id][1]-st[d.id][3];
            p.addPoint(d.x,d.y);
            p.addPoint(st[d.id][0],st[d.id][1]);
            p.addPoint(st[d.id][2],st[d.id][3]);   
            p.addPoint(st[d.id][2]=(int)(st[d.id][0]+d.press*((d.y-st[d.id][1])/dbl)),
            st[d.id][3]=(int)(st[d.id][1]-d.press*((d.x-st[d.id][0])/dbl)));
			p.addPoint(st[d.id][0]+dx,st[d.id][1]+dy);
            p.addPoint(d.x+(d.x-st[d.id][2]),d.y+(d.y-st[d.id][3]));
		 for(int i=0;i&lt;p.npoints;i+=2) g.drawLine(p.xpoints[i],p.ypoints[i],
                p.xpoints[i+1],p.ypoints[i+1]);  
		st[d.id][0] = d.x;
        st[d.id][1] = d.y;
		return p.getBoundingBox();
	}
*/
}       
</pre></body></html>