KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openlaszlo > iv > flash > api > shape > MorphShape


1 /*
2  * $Id: MorphShape.java,v 1.2 2002/03/14 20:27:38 awason Exp $
3  *
4  * ==========================================================================
5  *
6  * The JGenerator Software License, Version 1.0
7  *
8  * Copyright (c) 2000 Dmitry Skavish (skavish@usa.net). All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if
22  * any, must include the following acknowlegement:
23  * "This product includes software developed by Dmitry Skavish
24  * (skavish@usa.net, http://www.flashgap.com/)."
25  * Alternately, this acknowlegement may appear in the software itself,
26  * if and wherever such third-party acknowlegements normally appear.
27  *
28  * 4. The name "The JGenerator" must not be used to endorse or promote
29  * products derived from this software without prior written permission.
30  * For written permission, please contact skavish@usa.net.
31  *
32  * 5. Products derived from this software may not be called "The JGenerator"
33  * nor may "The JGenerator" appear in their names without prior written
34  * permission of Dmitry Skavish.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL DMITRY SKAVISH OR THE OTHER
40  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  *
49  */

50
51 package org.openlaszlo.iv.flash.api.shape;
52
53 import java.io.PrintStream JavaDoc;
54 import java.awt.geom.*;
55 import java.util.*;
56
57 import org.openlaszlo.iv.flash.parser.*;
58 import org.openlaszlo.iv.flash.util.*;
59 import org.openlaszlo.iv.flash.api.*;
60
61 /**
62  * MorphShape.
63  * <P>
64  * The DefineMorphShape tag defines the start and end states of a morph sequence.
65  * A morph object does not use previously defined shapes, it is considered a special
66  * type of shape with only one character ID. A morph object should be displayed with
67  * the PlaceObject2 tag, where the ratio field specifies how far the morph has progressed.
68  * <P>
69  * StartBounds defines the bounding-box of the shape at the start of the morph,
70  * and EndBounds defines the bounding-box at the end of the morph
71  * <P>
72  * MorphFillStyles contains an array interleaved fill styles for the start and end shapes.
73  * The fill style for the start shape is followed the corresponding fill style for the end shape.
74  * Similarly, MorphLineStyles contains an array of interleaved line styles.
75  * <P>
76  * The StartEdges array specifies the edges for the start shape, and the style change records for
77  * both shapes. Because the StyleChangeRecords must be the same for the start and end shapes,
78  * they are defined only in the StartEdges array. The EndEdges array specifies the edges for
79  * the end shape, and contains no style change records. The number of edges specified in StartEdges
80  * must equal the number of edges in EndEdges.
81  * <P>
82  * Note: Strictly speaking MoveTo records fall into the category of StyleChangeRecords,
83  * however they should be included in both the StartEdges and EndEdges arrays.
84  * <P>
85  * It is possible for an edge to change type over the course of a morph sequence.
86  * A straight edge can become a curved edge and vice versa. In this case, think of
87  * both edges as curved. A straight edge can be easily represented as a curve,
88  * by placing the off-curve (control) point at the mid-point of the straight edge,
89  * and the on-curve (anchor) point at the end of the straight edge.
90  * The calculation is as follows:
91  * <PRE><CODE>
92  * CurveControlDelta.x = StraightDelta.x / 2;
93  * CurveControlDelta.y = StraightDelta.y / 2;
94  * CurveAnchorDelta.x = StraightDelta.x / 2;
95  * CurveAnchorDelta.y = StraightDelta.y / 2;
96  * </CODE></PRE>
97  *
98  * @author Dmitry Skavish
99  * @see Shape
100  */

101 public final class MorphShape extends FlashDef {
102
103     private MorphShapeStyles shape_styles; // morph shape styles
104
private ShapeRecords records_start; // start records
105
private ShapeRecords records_end; // end records
106
private Rectangle2D bounds_start; // bounding box of start shape
107
private Rectangle2D bounds_end; // bounding box of end shape
108

109     /**
110      * Creates new empty morph shape
111      */

112     public MorphShape() {
113     }
114
115     /**
116      * Returns shape styles
117      *
118      * @return object representing array of shape styles
119      */

120     public MorphShapeStyles getShapeStyles() {
121         if( shape_styles == null ) {
122             shape_styles = new MorphShapeStyles();
123         }
124         return shape_styles;
125     }
126
127     /**
128      * Returns start shape records
129      *
130      * @return object representing array of shape records
131      */

132     public ShapeRecords getShapeRecordsStart() {
133         if( records_start == null ) {
134             records_start = new ShapeRecords();
135         }
136         return records_start;
137     }
138
139     /**
140      * Returns end shape records
141      *
142      * @return object representing array of shape records
143      */

144     public ShapeRecords getShapeRecordsEnd() {
145         if( records_end == null ) {
146             records_end = new ShapeRecords();
147         }
148         return records_end;
149     }
150
151     /**
152      * Adds specified fill style to the array of shape styles.
153      *
154      * @param fillStyle specified fill style
155      * @return index of added fill style in the array
156      */

157     public int addFillStyle( MorphFillStyle fillStyle ) {
158         return getShapeStyles().addFillStyle( fillStyle );
159     }
160
161     /**
162      * Adds specified line style to the array of shape styles
163      *
164      * @param lineStyle specified line style
165      * @return index of added line style in the array
166      */

167     public int addLineStyle( MorphLineStyle lineStyle ) {
168         return getShapeStyles().addLineStyle( lineStyle );
169     }
170
171     /**
172      * Sets specified fillstyle as current fillstyle0.
173      * <P>
174      * If the specified fillstyle is not in the shapestyle array
175      * then it's added, if it's already there it's reused.
176      *
177      * @param fillStyle specified fillstyle
178      * @return index of specified fillstyle in the shapestyle array
179      */

180     public int setFillStyle0( MorphFillStyle fillStyle ) {
181         int fs = getShapeStyles().getFillStyleIndex( fillStyle );
182         if( fs == -1 ) fs = addFillStyle( fillStyle );
183         setFillStyle0( fs );
184         return fs;
185     }
186
187     /**
188      * Sets specified fillstyle as current fillstyle1.
189      * <P>
190      * If the specified fillstyle is not in the shapestyle array
191      * then it's added, if it's already there it's reused.
192      *
193      * @param fillStyle specified fillstyle
194      * @return index of specified fillstyle in the shapestyle array
195      */

196     public int setFillStyle1( MorphFillStyle fillStyle ) {
197         int fs = getShapeStyles().getFillStyleIndex( fillStyle );
198         if( fs == -1 ) fs = addFillStyle( fillStyle );
199         setFillStyle1( fs );
200         return fs;
201     }
202
203     /**
204      * Sets specified linestyle as current linestyle.
205      * <P>
206      * If the specified linestyle is not in the shapestyle array
207      * then it's added, if it's already there it's reused.
208      *
209      * @param lineStyle specified linestyle
210      * @return index of specified linestyle in the shapestyle array
211      */

212     public int setLineStyle( MorphLineStyle lineStyle ) {
213         int ls = getShapeStyles().getLineStyleIndex( lineStyle );
214         if( ls == -1 ) ls = addLineStyle( lineStyle );
215         setLineStyle( ls );
216         return ls;
217     }
218
219     /**
220      * Sets current fillstyle0 by its index in shapestyle array.
221      *
222      * @param fillStyle index of fillstyle in shapestyle array to be set as current fillstyle0
223      */

224     public void setFillStyle0( int fillStyle ) {
225         StyleChangeRecord sc = getStyleChange();
226         sc.addFlags( StyleChangeRecord.FILLSTYLE0 );
227         sc.setFillStyle0( fillStyle );
228     }
229
230     /**
231      * Sets current fillstyle1 by its index in shapestyle array.
232      *
233      * @param fillStyle index of fillstyle in shapestyle array to be set as current fillstyle1
234      */

235     public void setFillStyle1( int fillStyle ) {
236         StyleChangeRecord sc = getStyleChange();
237         sc.addFlags( StyleChangeRecord.FILLSTYLE1 );
238         sc.setFillStyle1( fillStyle );
239     }
240
241     /**
242      * Sets current linestyle by its index in shapestyle array.
243      *
244      * @param lineStyle index of linestyle in shapestyle array to be set as current linestyle
245      */

246     public void setLineStyle( int lineStyle ) {
247         StyleChangeRecord sc = getStyleChange();
248         sc.addFlags( StyleChangeRecord.LINESTYLE );
249         sc.setLineStyle( lineStyle );
250     }
251
252     /**
253      * Returns index of current line style
254      *
255      * @return index of currently used line style
256      */

257     public int getLineStyleIndex() {
258         StyleChangeRecord sc = getStyleChange();
259         return sc.getLineStyle();
260     }
261
262     /**
263      * Returns current line style
264      *
265      * @return currently used line style
266      */

267     public MorphLineStyle getLineStyle() {
268         int idx = getLineStyleIndex();
269         return getShapeStyles().getLineStyle(idx);
270     }
271
272     /**
273      * Returns index of current fill style 0
274      *
275      * @return index of currently used fill style 0
276      */

277     public int getFillStyle0Index() {
278         StyleChangeRecord sc = getStyleChange();
279         return sc.getFillStyle0();
280     }
281
282     /**
283      * Returns current fill style 0
284      *
285      * @return currently used fill style 0
286      */

287     public MorphFillStyle getFillStyle0() {
288         int idx = getFillStyle0Index();
289         return getShapeStyles().getFillStyle(idx);
290     }
291
292     /**
293      * Returns index of current fill style 1
294      *
295      * @return index of currently used fill style 1
296      */

297     public int getFillStyle1Index() {
298         StyleChangeRecord sc = getStyleChange();
299         return sc.getFillStyle1();
300     }
301
302     /**
303      * Returns current fill style 1
304      *
305      * @return currently used fill style 1
306      */

307     public MorphFillStyle getFillStyle1() {
308         int idx = getFillStyle1Index();
309         return getShapeStyles().getFillStyle(idx);
310     }
311
312     public int getTag() {
313         return Tag.DEFINEMORPHSHAPE;
314     }
315
316     public void collectDeps( DepsCollector dc ) {
317         shape_styles.collectDeps(dc);
318     }
319
320     protected StyleChangeRecord getStyleChange() {
321         return getShapeRecordsStart().getStyleChange();
322     }
323
324     /**
325      * Parses Shape
326      *
327      * @param p Parser
328      * @return parsed shape
329      */

330     public static MorphShape parse( Parser p ) {
331
332         int tagCode = p.getTagCode();
333         MorphShape shape = new MorphShape();
334         shape.setID( p.getUWord() );
335         shape.bounds_start = p.getRect();
336         shape.bounds_end = p.getRect();
337
338         int offset = p.getUDWord();
339         int pos = p.getPos();
340
341         // parse first styles
342
shape.shape_styles = MorphShapeStyles.parse(p);
343
344         shape.records_start = ShapeRecords.parse(p);
345
346         p.setPos(pos+offset);
347
348         shape.records_end = ShapeRecords.parse(p);
349
350         return shape;
351     }
352
353     public void write( FlashOutput main ) {
354         FlashOutput fob = new FlashOutput(main,200);
355
356         fob.write(bounds_start);
357         fob.write(bounds_end);
358
359         fob.skip(4);
360         int pos = fob.getPos();
361
362         shape_styles.write(fob);
363
364         int nFillBits = shape_styles.calcNFillBits();
365         int nLineBits = shape_styles.calcNLineBits();
366         fob.writeByte( (nFillBits<<4) | nLineBits );
367         records_start.write(fob, nFillBits, nLineBits);
368         fob.writeBits(0, 6);
369         fob.flushBits();
370
371         int offset = fob.getPos()-pos;
372         fob.writeDWordAt(offset, pos-4);
373
374         fob.writeByte(0); // fill and line style bits
375
records_end.write(fob);
376
377         main.writeTag( getTag(), 2+fob.getSize() );
378         main.writeDefID( this );
379         main.writeFOB( fob );
380     }
381
382     public void printContent( PrintStream JavaDoc out, String JavaDoc indent ) {
383         out.println(indent+"MorphShape("+Tag.tagNames[getTag()]+"): id="+getID()+", name='"+getName()+"'");
384         out.println(indent+" start bounds="+bounds_start);
385         out.println(indent+" end bounds="+bounds_end);
386         shape_styles.printContent(out, " ");
387         records_start.printContent(out, " ");
388         records_end.printContent(out, " ");
389     }
390
391     public boolean isConstant() {
392         return true;
393     }
394
395     /**
396      * Returns MorphShape bounds
397      *
398      * @return shape bounds
399      */

400     public Rectangle2D getBounds() {
401         Rectangle2D dst = GeomHelper.newRectangle();
402         Rectangle2D.union( bounds_start, bounds_end, dst );
403         return dst;
404     }
405
406     /**
407      * Returns MorphShape start shape bounds
408      *
409      * @return shape bounds
410      */

411     public Rectangle2D getBoundsStart() {
412         return this.bounds_start;
413     }
414
415     /**
416      * Returns MorphShape end shape bounds
417      *
418      * @return shape bounds
419      */

420     public Rectangle2D getBoundsEnd() {
421         return this.bounds_end;
422     }
423
424     /**
425      * Sets bounding box for start shape.
426      *
427      * @param bounds new bounding box
428      */

429     public void setBoundsStart( Rectangle2D bounds ) {
430         this.bounds_start = bounds;
431     }
432
433     /**
434      * Sets bounding box for end shape.
435      *
436      * @param bounds new bounding box
437      */

438     public void setBoundsEnd( Rectangle2D bounds ) {
439         this.bounds_end = bounds;
440     }
441
442     /**
443      * Sets bounding box for start shape.
444      *
445      */

446     public void setBoundsStart( int x, int y, int width, int height ) {
447         setBoundsStart( GeomHelper.newRectangle(x,y,width,height) );
448     }
449
450     /**
451      * Sets bounding box for end shape.
452      *
453      */

454     public void setBoundsEnd( int x, int y, int width, int height ) {
455         setBoundsEnd( GeomHelper.newRectangle(x,y,width,height) );
456     }
457
458     protected FlashItem copyInto( FlashItem item, ScriptCopier copier ) {
459         super.copyInto( item, copier );
460         ((MorphShape)item).bounds_start = (Rectangle2D) bounds_start.clone();
461         ((MorphShape)item).bounds_end = (Rectangle2D) bounds_end.clone();
462         ((MorphShape)item).records_start = (ShapeRecords) records_start.getCopy(copier);
463         ((MorphShape)item).records_end = (ShapeRecords) records_end.getCopy(copier);
464         ((MorphShape)item).shape_styles = (MorphShapeStyles) shape_styles.getCopy(copier);
465         return item;
466     }
467
468     public FlashItem getCopy( ScriptCopier copier ) {
469         return copyInto( new MorphShape(), copier );
470     }
471
472     /* ----------------------------------------------------------------------------------- */
473     /* D R A W I N G */
474     /* ----------------------------------------------------------------------------------- */
475
476     /**
477      * Draws curve record.<p>
478      * All coordinates are in twixels.
479      *
480      * @param cx X control point
481      * @param cy Y control point
482      * @param ax X anchor point
483      * @param ay Y anchor point
484      */

485     public void drawCurveToStart( int cx, int cy, int ax, int ay ) {
486         getShapeRecordsStart().drawCurveTo(cx, cy, ax, ay);
487     }
488
489     public void drawCurveToEnd( int cx, int cy, int ax, int ay ) {
490         getShapeRecordsEnd().drawCurveTo(cx, cy, ax, ay);
491     }
492
493     /**
494      * Draws curve record.<p>
495      * All coordinates are in twixels.
496      *
497      * @param ax1 X anchor point 1
498      * @param ay1 Y anchor point 1
499      * @param cx X control point
500      * @param cy Y control point
501      * @param ax2 X anchor point 2
502      * @param ay2 Y anchor point 2
503      */

504     public void drawCurveStart( int ax1, int ay1, int cx, int cy, int ax2, int ay2 ) {
505         getShapeRecordsStart().drawCurve(ax1, ay1, cx, cy, ax2, ay2);
506     }
507
508     public void drawCurveEnd( int ax1, int ay1, int cx, int cy, int ax2, int ay2 ) {
509         getShapeRecordsEnd().drawCurve(ax1, ay1, cx, cy, ax2, ay2);
510     }
511
512     /**
513      * Draws curve record.<p>
514      * All coordinates are in twixels.
515      *
516      * @param anchor0 first anchor point
517      * @param control control point
518      * @param anchor1 second anchor point
519      */

520     public void drawCurveStart( Point2D anchor1, Point2D control, Point2D anchor2 ) {
521         getShapeRecordsStart().drawCurve(anchor1, control, anchor2);
522     }
523
524     public void drawCurveEnd( Point2D anchor1, Point2D control, Point2D anchor2 ) {
525         getShapeRecordsEnd().drawCurve(anchor1, control, anchor2);
526     }
527
528     /**
529      * Draws a straight line from current position to the specified one.<p>
530      * All coordinates are in twixels.
531      *
532      * @param x X of end of line
533      * @param y Y of end of line
534      */

535     public void drawLineToStart( int x, int y ) {
536         getShapeRecordsStart().drawLineTo(x, y);
537     }
538
539     public void drawLineToEnd( int x, int y ) {
540         getShapeRecordsEnd().drawLineTo(x, y);
541     }
542
543     /**
544      * Draws a straight line from current position to the specified one.<p>
545      * All coordinates are in twixels.
546      *
547      * @param p1 end of line
548      */

549     public void drawLineToStart( Point2D p1 ) {
550         getShapeRecordsStart().drawLineTo(p1);
551     }
552
553     public void drawLineToEnd( Point2D p1 ) {
554         getShapeRecordsEnd().drawLineTo(p1);
555     }
556
557     /**
558      * Draws a straight line specified by two points.
559      * <P>
560      * All coordinates are in twixels.
561      *
562      * @param x1 X of the beginning of the line
563      * @param y1 Y of the beginning of the line
564      * @param x2 X of the end of the line
565      * @param y2 Y of the end of the line
566      */

567     public void drawLineStart( int x1, int y1, int x2, int y2 ) {
568         getShapeRecordsStart().drawLine(x1, y1, x2, y2);
569     }
570
571     public void drawLineEnd( int x1, int y1, int x2, int y2 ) {
572         getShapeRecordsEnd().drawLine(x1, y1, x2, y2);
573     }
574
575     /**
576      * Draws a straight line specified by two points.
577      * <P>
578      * All coordinates are in twixels.
579      *
580      * @param p0 first point
581      * @param p1 second point
582      */

583     public void drawLineStart( Point2D p0, Point2D p1 ) {
584         getShapeRecordsStart().drawLine(p0, p1);
585     }
586
587     public void drawLineEnd( Point2D p0, Point2D p1 ) {
588         getShapeRecordsEnd().drawLine(p0, p1);
589     }
590
591     /**
592      * Draws a rectangle specified by its top-left corner and width and height
593      * <p>
594      * All coordinates are in twixels.
595      *
596      * @param x x coordinates of top-left corner of the rectangle
597      * @param y y coordinates of top-left corner of the rectangle
598      * @param width width of the rectangle
599      * @param height height of the rectangle
600      */

601     public void drawRectangleStart( int x, int y, int width, int height ) {
602         getShapeRecordsStart().drawRectangle(x, y, width, height);
603     }
604
605     public void drawRectangleEnd( int x, int y, int width, int height ) {
606         getShapeRecordsEnd().drawRectangle(x, y, width, height);
607     }
608
609     /**
610      * Draws a rectangle specified by {@link java.awt.geom.Rectangle2D}
611      * <p>
612      * All coordinates are in twixels.
613      *
614      * @param r specified rectangle
615      */

616     public void drawRectangleStart( Rectangle2D r ) {
617         getShapeRecordsStart().drawRectangle(r);
618     }
619
620     public void drawRectangleEnd( Rectangle2D r ) {
621         getShapeRecordsEnd().drawRectangle(r);
622     }
623
624     /**
625      * Moves pen to the specified position.<p>
626      * All coordinates are ABSOLUTE and are in twixels.
627      *
628      * @param x new current X
629      * @param y new current Y
630      */

631     public void movePenToStart( int x, int y ) {
632         getShapeRecordsStart().movePenTo(x, y);
633     }
634
635     public void movePenToEnd( int x, int y ) {
636         getShapeRecordsEnd().movePenTo(x, y);
637     }
638
639     /**
640      * Moves pen to the specified point.<p>
641      * All coordinates are ABSOLUTE and are in twixels!
642      *
643      * @param p new pen position
644      */

645     public void movePenToStart( Point2D p ) {
646         getShapeRecordsStart().movePenTo(p);
647     }
648
649     public void movePenToEnd( Point2D p ) {
650         getShapeRecordsEnd().movePenTo(p);
651     }
652
653     /**
654      * Draw AWT Shape
655      * <P>
656      * All shape coordinates are in twixels!
657      *
658      * @param shape AWT shape
659      */

660     public void drawAWTShapeStart( java.awt.Shape JavaDoc shape ) {
661         getShapeRecordsStart().drawAWTShape(shape);
662     }
663
664     public void drawAWTShapeEnd( java.awt.Shape JavaDoc shape ) {
665         getShapeRecordsEnd().drawAWTShape(shape);
666     }
667
668     /**
669      * Draw AWT Shape
670      * <P>
671      * All shape coordinates are in twixels!
672      *
673      * @param shape AWT shape
674      */

675     public void drawAWTShapeStart( java.awt.Shape JavaDoc shape, AffineTransform matrix ) {
676         getShapeRecordsStart().drawAWTShape(shape, matrix);
677     }
678
679     public void drawAWTShapeEnd( java.awt.Shape JavaDoc shape, AffineTransform matrix ) {
680         getShapeRecordsEnd().drawAWTShape(shape, matrix);
681     }
682
683     /**
684      * Draw AWT PathIterator
685      * <P>
686      * All coordinates are in twixels!
687      *
688      * @param pi AWT PathIterator
689      */

690     public void drawAWTPathIteratorStart( java.awt.geom.PathIterator JavaDoc pi ) {
691         getShapeRecordsStart().drawAWTPathIterator(pi);
692     }
693
694     public void drawAWTPathIteratorEnd( java.awt.geom.PathIterator JavaDoc pi ) {
695         getShapeRecordsEnd().drawAWTPathIterator(pi);
696     }
697
698 }
699
700
Popular Tags