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

Quick Search    Search Deep

Source code: com/anotherbigidea/flash/movie/Shape.java


1   /****************************************************************
2    * Copyright (c) 2001, David N. Main, All rights reserved.
3    * 
4    * Redistribution and use in source and binary forms, with or
5    * without modification, are permitted provided that the 
6    * following conditions are met:
7    *
8    * 1. Redistributions of source code must retain the above 
9    * copyright notice, this list of conditions and the following 
10   * disclaimer. 
11   * 
12   * 2. Redistributions in binary form must reproduce the above 
13   * copyright notice, this list of conditions and the following 
14   * disclaimer in the documentation and/or other materials 
15   * provided with the distribution.
16   * 
17   * 3. The name of the author may not be used to endorse or 
18   * promote products derived from this software without specific 
19   * prior written permission. 
20   * 
21   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY 
22   * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
23   * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
24   * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
25   * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
26   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
27   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
28   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
29   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
30   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
31   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
32   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33   ****************************************************************/
34  package com.anotherbigidea.flash.movie;
35  
36  import java.io.*;
37  import java.util.*;
38  import com.anotherbigidea.flash.interfaces.*;
39  import com.anotherbigidea.flash.writers.*;
40  import com.anotherbigidea.flash.readers.*;
41  import com.anotherbigidea.flash.structs.*;
42  import com.anotherbigidea.flash.SWFConstants;
43  
44  /**
45   * A Shape Symbol
46   */
47  public class Shape extends Symbol
48  {
49      public abstract static class Element {}
50      
51      public abstract static class Style extends Shape.Element 
52      {
53      }
54      
55      public abstract static class FillStyle extends Shape.Style
56      {
57      }
58      
59      public static class ColorFill extends Shape.FillStyle
60      {
61          protected Color color;
62          
63          /**
64           * @return may be Color or AlphaColor
65           */
66          public Color getColor() { return color; }
67          public void setColor( Color color ) { this.color = color; }
68          
69          public ColorFill( Color color )
70          {
71              this.color = color;
72          }
73      }
74      
75      public static class ImageFill extends Shape.FillStyle
76      {
77          protected Symbol image;
78          protected Transform matrix;
79          protected boolean clipped;
80          
81          public Symbol getImage()        { return image; }
82          public Transform getTransform() { return matrix; }
83          public boolean isClipped()      { return clipped; }
84          
85          public void setImage( Symbol image ) { this.image = image; }
86          public void setTransform( Transform matrix ) { this.matrix = matrix; }
87          public void setClipped( boolean isClipped ) { clipped = isClipped; }
88          
89          public ImageFill( Symbol image, Transform matrix, boolean isClipped )
90          {
91              this.image   = image;
92              this.matrix  = matrix;
93              this.clipped = isClipped;
94          }
95      }
96      
97      public static class GradientFill extends Shape.FillStyle
98      {
99          protected Color[] colors;
100         protected int[]   ratios;
101         protected Transform matrix;
102         protected boolean radial;
103         
104         public Color[]   getColors()    { return colors; }
105         public Transform getTransform() { return matrix; }
106         public int[]     getRatios()    { return ratios; }
107         public boolean   isRadial()     { return radial; }
108         
109         public void setColors( Color[] colors ) { this.colors = colors; }
110         public void setRatios( int[] ratios ) { this.ratios = ratios; }
111         public void setTransform( Transform matrix ) { this.matrix = matrix; }
112         public void setRadial( boolean isRadial ) { this.radial = isRadial; }
113         
114         public GradientFill( Color[] colors, int[] ratios, 
115                              Transform matrix, boolean isRadial )
116         {
117             this.colors = colors;
118             this.matrix = matrix;
119             this.radial = isRadial;
120             this.ratios = ratios;
121         }
122     }
123     
124     public static class LineStyle extends Shape.Style
125     {
126         protected double width;
127         protected Color  color;
128         
129         public double getWidth() { return width; }
130         public Color  getColor() { return color; }
131         
132         public void setWidth( double width ) { this.width = width; }
133         public void setColor( Color color ) { this.color = color; }
134         
135         public LineStyle( double width, Color color )
136         {
137             this.width = width;
138             this.color = color;
139         }
140     }
141     
142     public abstract static class SetStyle extends Shape.Element 
143     {
144         protected int index;
145         
146         public int getStyleIndex() { return index; }
147         public void setStyleIndex( int index ) { this.index = index; }
148         
149         protected SetStyle( int index )
150         {
151             this.index = index;
152         }
153     }
154     
155     public abstract static class SetFillStyle extends Shape.SetStyle 
156     {
157         protected SetFillStyle( int index )
158         {
159             super( index );
160         }
161     }
162     
163     public static class SetLeftFillStyle extends Shape.SetFillStyle 
164     {
165         public SetLeftFillStyle( int index )
166         {
167             super( index );
168         }
169     }
170     
171     public static class SetRightFillStyle extends Shape.SetFillStyle 
172     {
173         public SetRightFillStyle( int index )
174         {
175             super( index );
176         }
177     }
178     
179     public static class SetLineStyle extends Shape.SetStyle 
180     {
181         public SetLineStyle( int index )
182         {
183             super( index );
184         }
185     }
186     
187     public abstract static class Vector extends Shape.Element 
188     {
189         protected double x, y;
190         
191         public double getX() { return x; }
192         public double getY() { return y; }
193         
194         public void setX( double x ) { this.x = x; }
195         public void setY( double y ) { this.y = y; }
196         
197         protected Vector( double x, double y )
198         {
199             this.x = x;
200             this.y = y;
201         }
202     }
203     
204     public static class Move extends Shape.Vector 
205     {
206         public Move( double x, double y )
207         {
208             super( x, y );
209         }
210     }
211     
212     public static class Line extends Shape.Vector 
213     {
214         public Line( double x, double y )
215         {
216             super( x, y );
217         }
218     }
219 
220     public static class Curve extends Shape.Vector 
221     {
222         protected double cx, cy;
223         
224         public double getControlX() { return cx; }
225         public double getControlY() { return cy; }
226         
227         public void setControlX( double cx ) { this.cx = cx; }
228         public void setControlY( double cy ) { this.cy = cy; }
229         
230         public Curve( double x, double y, double controlX, double controlY )
231         {
232             super( x, y );
233             this.cx = controlX;
234             this.cy = controlY;
235         }        
236     }
237 
238     protected ArrayList elements = new ArrayList();
239     protected double minX, maxX, minY, maxY;  //bounding rectangle
240     protected boolean hasAlpha = false;
241     protected double maxLineWidth;
242     protected double currx, curry;
243     
244     public Shape() {}
245     
246     /**
247      * Get the bounding rectangle as a double[4] - (min-X,min-Y,max-X,max-Y)
248      */
249     public double[] getBoundingRectangle()
250     {
251         return new double[] { minX, minY, maxX, maxY };
252     }
253     
254     /**
255      * Set the bounding rectangle. This will be automatically calculated
256      * as the geometry vectors are defined and this rectangle will be enlarged
257      * if it does not contain all the vectors.
258      */
259     public void setBoundingRectangle( double minx, double minY, 
260                                       double maxX, double maxY )
261     {
262         this.minX = minX;
263         this.minY = minY;
264         this.maxX = maxX;
265         this.maxY = maxY;
266     }
267     
268     /**
269      * Access the list of shape elements
270      * Each object is a subclass of Shape.Element
271      */
272     public ArrayList getShapeElements()
273     {
274         return elements;
275     }
276     
277     /**
278      * Define a line style
279      * @param color if null then black is assumed
280      */
281     public void defineLineStyle( double width, Color color )
282     {
283         if( color == null ) color = new Color(0,0,0);
284         
285         LineStyle style = new LineStyle( width, color );
286 
287         if( maxLineWidth < width ) maxLineWidth = width;
288 
289         if( color instanceof AlphaColor ) hasAlpha = true;
290         
291         elements.add( style );
292     }
293     
294     /**
295      * Define a color fill
296      * @param color if null then white is assumed
297      */
298     public void defineFillStyle( Color color )
299     {
300         if( color == null ) color = new Color(255,255,255);
301         ColorFill fill = new ColorFill( color );
302         
303         if( color instanceof AlphaColor ) hasAlpha = true;
304         
305         elements.add( fill );
306     }
307     
308     /**
309      * Define an image fill
310      */
311     public void defineFillStyle( Symbol image, Transform matrix, boolean clipped )
312     {
313         ImageFill fill = new ImageFill(image,matrix,clipped);
314         
315         elements.add( fill );
316     }
317     
318     /**
319      * Define a gradient fill
320      */
321     public void defineFillStyle( Color[] colors, int[] ratios, 
322                                  Transform matrix, boolean radial )
323     {
324         GradientFill fill = new GradientFill( colors, ratios, matrix, radial );
325 
326         elements.add( fill );
327         
328         for( int i = 0; i < colors.length; i++ )
329         {
330             if( colors[i] == null ) continue;
331             if( colors[i] instanceof AlphaColor ) hasAlpha = true;
332         }        
333     }
334     
335     /**
336      * Set the left fill style
337      */
338     public void setLeftFillStyle( int index )
339     {
340         SetLeftFillStyle fill = new SetLeftFillStyle( index );
341         
342         elements.add( fill );
343     }
344 
345     /**
346      * Set the right fill style
347      */
348     public void setRightFillStyle( int index )
349     {
350         SetRightFillStyle fill = new SetRightFillStyle( index );
351         
352         elements.add( fill );
353     }
354 
355     /**
356      * Set the line style
357      */
358     public void setLineStyle( int index )
359     {
360         SetLineStyle style = new SetLineStyle( index );
361         
362         elements.add( style );
363     }
364     
365     /**
366      * Move the pen without drawing any line
367      */
368     public void move( double x, double y )
369     {
370         Move move = new Move( x, y );
371     
372         if( x < minX ) minX = x;
373         if( y < minY ) minY = y;
374         if( x > maxX ) maxX = x;
375         if( y > maxY ) maxY = y;
376         
377         elements.add( move );
378     }
379     
380     /**
381      * Draw a line in the current line style (if any)
382      */
383     public void line( double x, double y )
384     {
385         Line line = new Line( x, y );
386     
387         if( x < minX ) minX = x;
388         if( y < minY ) minY = y;
389         if( x > maxX ) maxX = x;
390         if( y > maxY ) maxY = y;
391         
392         elements.add( line );
393     }
394 
395     /**
396      * Draw a curve in the current line style (if any)
397      */
398     public void curve( double x, double y, double controlX, double controlY )
399     {
400         Curve curve = new Curve( x, y, controlX, controlY );
401         
402         if( x < minX ) minX = x;
403         if( y < minY ) minY = y;
404         if( x > maxX ) maxX = x;
405         if( y > maxY ) maxY = y;
406         
407         if( controlX < minX ) minX = controlX;
408         if( controlY < minY ) minY = controlY;
409         if( controlX > maxX ) maxX = controlX;
410         if( controlY > maxY ) maxY = controlY;
411         
412         elements.add( curve );
413     }
414     
415     protected int defineSymbol( Movie movie, 
416                                 SWFTagTypes timelineWriter,
417                                 SWFTagTypes definitionWriter )
418         throws IOException
419     {
420         currx = 0.0;
421         curry = 0.0;
422 
423         predefineImageFills( movie, timelineWriter, definitionWriter );
424         
425         int id = getNextId(movie);
426         
427         Rect outline = getRect();
428         
429         SWFShape shape = hasAlpha ? 
430                              definitionWriter.tagDefineShape3( id, outline ) :
431                              definitionWriter.tagDefineShape2( id, outline );
432 
433         writeShape( shape );
434         
435         return id;
436     }
437 
438     protected Rect getRect()
439     {
440         double adjust = maxLineWidth/2.0;
441         
442         Rect outline = new Rect( (int)(minX*SWFConstants.TWIPS - adjust*SWFConstants.TWIPS),
443                                  (int)(minY*SWFConstants.TWIPS - adjust*SWFConstants.TWIPS),
444                                  (int)(maxX*SWFConstants.TWIPS + adjust*SWFConstants.TWIPS),
445                                  (int)(maxY*SWFConstants.TWIPS + adjust*SWFConstants.TWIPS));
446         
447         return outline;
448     }
449     
450     protected void predefineImageFills( Movie movie, 
451                                         SWFTagTypes timelineWriter,
452                                         SWFTagTypes definitionWriter )
453         throws IOException 
454     {
455         //--Make sure any image fills are defined prior to the shape
456         for( Iterator it = elements.iterator(); it.hasNext(); )
457         {
458             Object el = it.next();
459             
460             if( el instanceof Shape.ImageFill )
461             {        
462                 Symbol image = ((Shape.ImageFill)el).getImage();
463                 
464                 if( image != null ) image.define( movie,
465                                                   timelineWriter, 
466                                                   definitionWriter );
467             }
468         }        
469     }
470     
471     protected void writeShape( SWFShape shape ) throws IOException
472     {
473         for( Iterator it = elements.iterator(); it.hasNext(); )
474         {
475             Object el = it.next();
476             
477             if( el instanceof Shape.ColorFill )
478             {
479                 Shape.ColorFill fill = (Shape.ColorFill)el;
480                 shape.defineFillStyle( fill.getColor() );
481             }
482             else if( el instanceof Shape.ImageFill )
483             {
484                 Shape.ImageFill fill = (Shape.ImageFill)el;
485 
486                 Symbol image = fill.getImage();
487                 int imgId = (image != null) ? image.getId() : 65535;
488                 
489                 shape.defineFillStyle( imgId, fill.getTransform(), fill.isClipped() );
490             }
491             else if( el instanceof Shape.GradientFill )
492             {
493                 Shape.GradientFill fill = (Shape.GradientFill)el;
494 
495                 shape.defineFillStyle( fill.getTransform(), 
496                                        fill.getRatios(),
497                                        fill.getColors(),
498                                        fill.isRadial() );
499             }
500             else if( el instanceof Shape.LineStyle )
501             {
502                 Shape.LineStyle style = (Shape.LineStyle)el;
503                 
504                 shape.defineLineStyle( (int)(style.getWidth() * SWFConstants.TWIPS),
505                                        style.getColor() );
506             }
507             else if( el instanceof Shape.SetLeftFillStyle )
508             {
509                 Shape.SetLeftFillStyle style = (Shape.SetLeftFillStyle)el;
510                 shape.setFillStyle0( style.getStyleIndex() );
511             }            
512             else if( el instanceof Shape.SetRightFillStyle )
513             {
514                 Shape.SetRightFillStyle style = (Shape.SetRightFillStyle)el;
515                 shape.setFillStyle1( style.getStyleIndex() );
516             }            
517             else if( el instanceof Shape.SetLineStyle )
518             {
519                 Shape.SetLineStyle style = (Shape.SetLineStyle)el;
520                 shape.setLineStyle( style.getStyleIndex() );
521             }            
522             else writeVector( shape, el );        
523         }
524         
525         shape.done();
526     }
527     
528     protected void writeVector( SWFVectors vecs, Object el ) throws IOException
529     {
530         if( el instanceof Shape.Move )
531         {
532             Shape.Move move = (Shape.Move)el;
533 
534             currx = move.getX()*SWFConstants.TWIPS;
535             curry = move.getY()*SWFConstants.TWIPS;
536 
537             int x = (int)currx;
538             int y = (int)curry;
539 
540             vecs.move( x, y );
541                 
542             //System.out.println( "M: " + x + " " + y );
543         }            
544         else if( el instanceof Shape.Line )
545         {
546             Shape.Line line = (Shape.Line)el;
547 
548             double xx = line.getX()*SWFConstants.TWIPS;
549             double yy = line.getY()*SWFConstants.TWIPS;
550                 
551             int dx = (int)(xx - currx);
552             int dy = (int)(yy - curry);
553                 
554             vecs.line( dx, dy );
555                 
556             //System.out.println( "currx=" + currx + " curry=" + curry + " xx=" + xx + " yy=" + yy + " (xx - currx)=" + (xx - currx) + "  (yy - curry)=" + (yy - curry) );
557             //System.out.println( "L: " + dx + " " + dy );
558 
559             currx = xx;
560             curry = yy;                
561         }            
562         else if( el instanceof Shape.Curve )
563         {
564             Shape.Curve curve = (Shape.Curve)el;
565 
566             double xx  = curve.getX()       *SWFConstants.TWIPS;
567             double yy  = curve.getY()       *SWFConstants.TWIPS;
568             double cxx = curve.getControlX()*SWFConstants.TWIPS;
569             double cyy = curve.getControlY()*SWFConstants.TWIPS;
570                 
571             int dx = (int)(xx - cxx);
572             int dy = (int)(yy - cyy);
573             int cx = (int)(cxx - currx);
574             int cy = (int)(cyy - curry);       
575                 
576             vecs.curve( cx, cy, dx, dy );
577                 
578             currx = xx;
579             curry = yy;                
580 
581             //System.out.println( "C: " + cx + " " + cy + " " + dx + " " + dy );
582         }            
583      }
584     
585     protected void writeGlyph( SWFVectors vecs ) throws IOException
586     {
587         currx = 0.0;
588         curry = 0.0;
589         
590         for( Iterator it = elements.iterator(); it.hasNext(); )
591         {
592             writeVector( vecs, it.next() );    
593         }        
594         
595         vecs.done();        
596    }
597 }