Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/xerox/VTM/glyphs/VClippedPath.java


1   /*   FILE: VClippedPath.java
2    *   DATE OF CREATION:   Wed Feb 05 10:50:50 2003
3    *   AUTHOR :            Emmanuel Pietriga (emmanuel@w3.org)
4    *   MODIF:              Thu Jul 10 16:25:40 2003 by Emmanuel Pietriga (emmanuel@w3.org, emmanuel@claribole.net)
5    *   Copyright (c) Emmanuel Pietriga, 2002. All Rights Reserved
6    *   Licensed under the GNU LGPL. For full terms see the file COPYING.
7    */ 
8   
9   package com.xerox.VTM.glyphs;
10  
11  import java.awt.Color;
12  import java.awt.Graphics2D;
13  import java.awt.Font;
14  import java.awt.Stroke;
15  import java.awt.geom.GeneralPath;
16  import java.awt.geom.PathIterator;
17  import java.awt.geom.AffineTransform;
18  import java.util.Vector;
19  import com.xerox.VTM.engine.*;
20  import com.xerox.VTM.svg.*;
21  
22  /**
23   * General path - similar to a VPath, but implements an experimental clipping algorithm that should enhance performances (quicker rendering) when only part of the path is actually seen (draw only curves/segments that are seen)
24   * @author Emmanuel Pietriga
25   **/
26  
27  public class VClippedPath extends VPath implements Cloneable {
28  
29      private ClippedPathSeg[] segs;
30      LongPoint firstPoint;
31      LongPoint lastPoint;
32  
33      private void addSeg(LongPoint p,short segType){
34    if (firstPoint==null){
35        firstPoint=p;
36    }
37    else if (segs==null){
38        segs=new ClippedPathSeg[1];
39        segs[0]=new ClippedPathSeg((firstPoint.x+p.x)/2,(firstPoint.y+p.y)/2,(p.x-firstPoint.x)/2,-(p.y-firstPoint.y)/2,segType,p.x,-p.y);
40        lastPoint=p;
41    }
42    else {
43        ClippedPathSeg[] tmpArray=new ClippedPathSeg[segs.length+1];
44        System.arraycopy(segs,0,tmpArray,0,segs.length);
45        segs=tmpArray;
46        segs[segs.length-1]=new ClippedPathSeg((lastPoint.x+p.x)/2,(lastPoint.y+p.y)/2,(p.x-lastPoint.x)/2,-(p.y-lastPoint.y)/2,segType,p.x,-p.y);
47        lastPoint=p;
48    }
49      }
50  
51      public VClippedPath(){
52    super();
53      }
54  
55      /**
56       *@param x coordinate in virtual space
57       *@param y coordinate in virtual space
58       *@param z altitude
59       *@param c fill color
60       */
61      public VClippedPath(long x,long y,float z,Color c){
62    super(x,y,z,c);
63      }
64  
65      /**
66       *@param z altitude
67       *@param c fill color
68       *@param svg valid <i>d</i> attribute of an SVG <i>path</i> element. m as first coords are taken into account, so any coord list beginning with one of these instructions will make the path begin elsewhere than at (x,y). Absolute commands (uppercase letters) as first coords have the side effect of assigning first point with these values instead of x,y (overriden)
69       */
70      public VClippedPath(float z,Color c,String svg){
71    super(z,c,svg);
72      }
73  
74      /**
75       * new path, begins at (vx,vy)
76       */
77      public void resetPath(){
78    super.resetPath();
79    firstPoint=null;
80    segs=null;
81      }
82  
83      /**
84       * add a new segment to the path, from current point to point (x,y)
85       *@param x coordinate in virtual space
86       *@param y coordinate in virtual space
87       *@param abs true if absolute coordinates, false if relative coordinates (w.r.t last point)
88       */
89      public void addSegment(long x,long y,boolean abs){
90    if (abs){lp.setLocation(x,y);}
91    else {lp.translate(x,y);}
92    path.lineTo(lp.x,-lp.y);
93     addSeg(new LongPoint(lp.x,lp.y),ClippedPathSeg.SEG_TYPE_SEG);
94    realHotSpot.setLocation((vx+lp.x)/2,(vy+lp.y)/2);
95    computeSize();
96      }
97  
98  
99      /**
100      * add a new quadratic curve to the path, from current point to point (x,y), with control point (x1,y1)
101      *@param x coordinate in virtual space
102      *@param y coordinate in virtual space
103      *@param x1 coordinate in virtual space
104      *@param y1 coordinate in virtual space
105      *@param abs true if absolute coordinates, false if relative coordinates (w.r.t last point)
106      */
107     public void addQdCurve(long x,long y,long x1,long y1,boolean abs){
108   if (abs){
109       path.quadTo(x1,-y1,x,-y);
110       addSeg(new LongPoint(x1,y1),ClippedPathSeg.SEG_TYPE_QD1);
111       addSeg(new LongPoint(x,y),ClippedPathSeg.SEG_TYPE_QD2);
112       lp.setLocation(x,y);
113   }
114   else {
115       path.quadTo(lp.x+x1,-(lp.y+y1),lp.x+x,-(lp.y+y));
116       addSeg(new LongPoint(lp.x+x1,lp.y+y1),ClippedPathSeg.SEG_TYPE_QD1);
117       addSeg(new LongPoint(lp.x+x,lp.y+y),ClippedPathSeg.SEG_TYPE_QD2);
118       lp.translate(x,y);
119   }
120   realHotSpot.setLocation((vx+lp.x)/2,(vy+lp.y)/2);
121   computeSize();
122     }
123 
124     /**
125      * add a new cubic curve to the path, from current point to point (x,y), with control points (x1,y1) and (x2,y2)
126      *@param x coordinate in virtual space
127      *@param y coordinate in virtual space
128      *@param x1 coordinate in virtual space
129      *@param y1 coordinate in virtual space
130      *@param x2 coordinate in virtual space
131      *@param y2 coordinate in virtual space
132      *@param abs true if absolute coordinates, false if relative coordinates (w.r.t last point)
133      */
134     public void addCbCurve(long x,long y,long x1,long y1,long x2,long y2,boolean abs){
135   if (abs){
136       path.curveTo(x1,-y1,x2,-y2,x,-y);
137       addSeg(new LongPoint(x1,y1),ClippedPathSeg.SEG_TYPE_CB1);
138       addSeg(new LongPoint(x2,y2),ClippedPathSeg.SEG_TYPE_CB2);
139       addSeg(new LongPoint(x,y),ClippedPathSeg.SEG_TYPE_CB3);
140       lp.setLocation(x,y);
141   }
142   else {
143       path.curveTo(lp.x+x1,-(lp.y+y1),lp.x+x2,-(lp.y+y2),lp.x+x,-(lp.y+y));
144       addSeg(new LongPoint(lp.x+x1,lp.y+y1),ClippedPathSeg.SEG_TYPE_CB1);
145       addSeg(new LongPoint(lp.x+x2,lp.y+y2),ClippedPathSeg.SEG_TYPE_CB2);
146       addSeg(new LongPoint(lp.x+x,lp.y+y),ClippedPathSeg.SEG_TYPE_CB3);
147       lp.translate(x,y);
148   }
149   realHotSpot.setLocation((vx+lp.x)/2,(vy+lp.y)/2);
150   computeSize();
151     }
152 
153     /**
154      * "jump" to point (x,y) without drawing anything
155      *@param x coordinate in virtual space
156      *@param y coordinate in virtual space
157      *@param abs true if absolute coordinates, false if relative coordinates (w.r.t last point)
158      */
159     public void jump(long x,long y, boolean abs){
160   if (abs){lp.setLocation(x,y);}
161   else {lp.translate(x,y);}
162   path.moveTo(lp.x,-lp.y);
163    addSeg(new LongPoint(lp.x,lp.y),ClippedPathSeg.SEG_TYPE_JMP);
164   if (getPathLength()==1){vx=lp.x;vy=lp.y;}
165   realHotSpot.setLocation((vx+lp.x)/2,(vy+lp.y)/2);
166   computeSize();
167     }
168 
169 
170     /**draw glyph 
171      *@param i camera index in the virtual space
172      */
173     public void draw(Graphics2D g,int vW,int vH,int i,Stroke stdS,AffineTransform stdT){
174   if (visibilityHasChanged()){constructVisiblePath();}
175   g.setColor(this.color);
176   if (true){//replace by something using projected size (so that we do not paint it if too small)
177        at=AffineTransform.getTranslateInstance(pc[i].cx,pc[i].cy);
178        at.concatenate(AffineTransform.getScaleInstance(coef,coef));
179       g.setTransform(at);
180       if (stroke!=null){
181     g.setStroke(stroke);
182     g.draw(path);
183     g.setStroke(stdS);
184       }
185       else {
186     g.draw(path);
187       }
188       g.setTransform(stdT);
189   }
190     }
191 
192     /**used to find out if it is necessary to project and draw the glyph in the current view - override default method in Glyph*/
193     public boolean drawMe(long w1,long h1,long w2,long h2,int i){//i should be the camera's index (used only by some glyph classes redefining this method from the one in Glyph)
194   boolean res=false;
195   if (forcedDrawing){return true;}
196   else {
197       if (((realHotSpot.x>=w2) && (realHotSpot.x<=w1) && (realHotSpot.y>=h2) && (realHotSpot.y<=h1)) || (((realHotSpot.x-drawingRadius)<=w1) && ((realHotSpot.x+drawingRadius)>=w2) && ((realHotSpot.y-drawingRadius)<=h1) && ((realHotSpot.y+drawingRadius)>=h2))){
198     try {
199         for (int j=0;j<segs.length;j++){
200       if (((segs[j].x>=w2) && (segs[j].x<=w1) && (segs[j].y>=h2) && (segs[j].y<=h1)) || (((segs[j].x-segs[j].w)<=w1) && ((segs[j].x+segs[j].w)>=w2) && ((segs[j].y-segs[j].h)<=h1) && ((segs[j].y+segs[j].h)>=h2))){
201           segs[j].setVisible(true);
202           res=true;
203       }
204       else {segs[j].setVisible(false);}
205         }
206 //         return false;
207     }
208     catch (NullPointerException ex){return false;}
209       }
210 //       else {
211 //     return false;
212 //       }
213   }
214   //printVis();
215   return res;
216     }
217 
218     void printVis(){
219   System.err.print("[");
220   for (int i=0;i<segs.length;i++){
221       System.err.print(segs[i].visible+",");
222   }
223   System.err.print("]");
224   System.err.println(visibilityHasChanged());
225     }
226 
227     private boolean visibilityHasChanged(){
228   for (int i=0;i<segs.length;i++){
229       if (segs[i].wasVisible!=segs[i].visible){return true;}
230   }
231   return false;
232     }
233 
234     void constructVisiblePath(){
235   path=new GeneralPath();
236   path.moveTo(firstPoint.x,-firstPoint.y);
237   for (int i=0;i<segs.length;){
238       if (segs[i].type==ClippedPathSeg.SEG_TYPE_CB1){
239     if (segs[i].visible || segs[i+1].visible || segs[i+2].visible){
240         path.curveTo(segs[i].java2Dx,segs[i].java2Dy,segs[i+1].java2Dx,segs[i+1].java2Dy,segs[i+2].java2Dx,segs[i+2].java2Dy);
241     }
242     i+=3;
243       }
244       else if (segs[i].type==ClippedPathSeg.SEG_TYPE_QD1){
245     if (segs[i].visible || segs[i+1].visible){
246         path.quadTo(segs[i].java2Dx,segs[i].java2Dy,segs[i+1].java2Dx,segs[i+1].java2Dy);
247     }
248     i+=2;
249       }
250       else if (segs[i].type==ClippedPathSeg.SEG_TYPE_SEG){
251     if (segs[i].visible){
252         path.lineTo(segs[i].java2Dx,segs[i].java2Dy);
253     }
254     i++;
255       }
256       else if (segs[i].type==ClippedPathSeg.SEG_TYPE_JMP){
257     if (segs[i].visible){
258         path.moveTo(segs[i].java2Dx,segs[i].java2Dy);
259     }
260     i++;
261       }
262       else if (segs[i].type==ClippedPathSeg.SEG_TYPE_CB2){i+=2;}
263       else if (segs[i].type==ClippedPathSeg.SEG_TYPE_QD2){i++;}
264       else if (segs[i].type==ClippedPathSeg.SEG_TYPE_CB3){i++;}
265   }  
266     }
267 
268     /**returns a clone of this object - not yet implemented for VClippedPath*/
269     public Object clone(){
270   VClippedPath res=new VClippedPath();
271   res.borderColor=this.borderColor;
272   res.selectedColor=this.selectedColor;
273   res.mouseInsideColor=this.mouseInsideColor;
274   res.bColor=this.bColor;
275   return res;
276     }
277     
278 }
279