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

Quick Search    Search Deep

Source code: com/anotherbigidea/flash/movie/Frame.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.IOException;
37  import java.util.Enumeration;
38  import java.util.Vector;
39  
40  import com.anotherbigidea.flash.SWFConstants;
41  import com.anotherbigidea.flash.interfaces.SWFActions;
42  import com.anotherbigidea.flash.interfaces.SWFTagTypes;
43  import com.anotherbigidea.flash.sound.SoundStreamHead;
44  import com.anotherbigidea.flash.structs.AlphaTransform;
45  import com.anotherbigidea.flash.structs.SoundInfo;
46  
47  /**
48   * A Movie or Movie Clip frame
49   */
50  public class Frame
51  {
52      protected int frameNumber;
53      protected String label;
54      protected Vector placements = new Vector();
55      protected boolean stop;
56      protected TimeLine timeline;
57      protected Actions actions;
58      protected SoundStreamHead soundHeader;
59      protected byte[] soundData;
60      protected Sound soundToStart;
61      protected int    customTag = -1;
62      protected byte[] customTagData;
63      protected boolean mAnchor; //true for an anchor frame (Flash MX+)
64      
65      protected Frame( int number, TimeLine timeline )
66      {
67          frameNumber = number;
68          this.timeline = timeline;
69      }
70      
71      public SoundStreamHead getSoundHeader() { return soundHeader; }
72      public void setSoundHeader( SoundStreamHead header ) { soundHeader = header; }
73  
74      public byte[] getSoundData() { return soundData; }
75      public void   setSoundData( byte[] data ) { soundData = data; }
76      
77      public boolean isAnchor() { return mAnchor; }
78      public void setAnchor( boolean isAnchor ) { mAnchor = isAnchor; }
79      
80      /**
81       * Set a custom tag to be written at the start of the frame
82       */
83      public void setCustomTag( int tagId, byte[] tagData )
84      {
85          this.customTag     = tagId;
86          this.customTagData = tagData;
87      }
88      
89      /**
90       * @return number of frames required for the sound
91       */
92      public int startSound( Sound soundToStart, int framesPerSec )
93      {
94          this.soundToStart = soundToStart;
95          
96          int freq = soundToStart.getFrequency();
97          switch( freq )
98          {
99              case SWFConstants.SOUND_FREQ_5_5KHZ: freq = 5500; break;
100             case SWFConstants.SOUND_FREQ_11KHZ:  freq = 11000; break;
101             case SWFConstants.SOUND_FREQ_22KHZ:  freq = 22000; break;
102             case SWFConstants.SOUND_FREQ_44KHZ:  freq = 44000; break;
103             default: freq = 22000; break;
104         }
105         
106         int samples = soundToStart.getSampleCount();
107         int length = samples / freq;
108         return length * framesPerSec;
109     }
110     
111     /**
112      * Get the frame actions
113      */
114     public Actions getActions() { return actions; }
115     
116     /**
117      * Set the frame actions (or null them out)
118      */
119     public void setActions( Actions actions ) { this.actions = actions; }
120     
121     /** 
122      * Reset the frame actions (if any) and return the new empty Actions object
123      */
124     public Actions actions( int flashVersion ) 
125     { 
126         actions = new Actions( 0, flashVersion ); 
127         return actions;
128     }
129     
130     /**
131      * Get the frame number
132      */
133     public int getFrameNumber() { return frameNumber; }
134 
135     /**
136      * Get the placements in this frame
137      */
138     public Placement[] getPlacements()
139     {
140         Placement[] p= new Placement[ placements.size() ];
141         placements.copyInto( p );
142         return p;
143     }
144 
145     /**
146      * Get the frame label
147      * @return null if the frame has no label
148      */
149     public String getLabel() { return label; }
150 
151     /**
152      * Set the frame label - set to null to clear any label
153      */
154     public void setLabel( String label ) { this.label = label; }
155 
156     /**
157      * Set the stop flag - if true then the movie will stop at this frame.
158      * This can be set on the last frame to prevent the movie looping.
159      */
160     public void stop() { this.stop = true; }
161 
162 
163     /**
164      * Place a symbol at the given coordinates at the next available
165      * depth.
166      */
167     public Instance placeSymbol( Symbol symbol, int x, int y )
168     {
169         return placeSymbol( symbol, new Transform( x, y ), null, -1, -1 );
170     }
171 
172     /**
173      * Place a symbol at the next available depth with the given
174      * matrix transform and color transform.
175      * 
176      * @param matrix may be null to place the symbol at (0,0)
177      * @param cxform may be null if no color transform is required
178      */
179     public Instance placeSymbol( Symbol symbol, Transform matrix, AlphaTransform cxform )
180     {
181         return placeSymbol( symbol, matrix, cxform, -1, -1 );
182     }
183 
184     /**
185      * Place a symbol at the next available depth with the given properties.
186      * 
187      * @param matrix may be null to place the symbol at (0,0)
188      * @param cxform may be null if no color transform is required
189      * @param ratio  only for a MorphShape - the morph ratio from 0 to 65535,
190      *               should be -1 for a non-MorphShape
191      * @param clipDepth the top depth that will be clipped by the symbol, should
192      *               be -1 if this is not a clipping symbol
193      */
194     public Instance placeSymbol( Symbol symbol, Transform matrix, AlphaTransform cxform,
195                                  int ratio, int clipDepth )
196     {
197         int depth = timeline.getAvailableDepth();
198         Instance inst = new Instance( symbol, depth );
199         timeline.setAvailableDepth( depth+1 );
200         
201         if( matrix == null ) matrix = new Transform();
202         
203         Placement placement = new Placement( inst, matrix, cxform, null, 
204                                              ratio, clipDepth, frameNumber, false,
205                                              false, null );
206         
207         placements.add( placement );
208         return inst;
209     }
210     
211     /**
212      * Replace the symbol at the given depth with the new symbol
213      * 
214      * @param matrix may be null to place the symbol at (0,0)
215      * @param cxform may be null if no color transform is required
216      * @param ratio  only for a MorphShape - the morph ratio from 0 to 65535,
217      *               should be -1 for a non-MorphShape
218      * @param clipDepth the top depth that will be clipped by the symbol, should
219      *               be -1 if this is not a clipping symbol
220      */
221     public Instance replaceSymbol( Symbol symbol, int depth,
222                                    Transform matrix, AlphaTransform cxform,
223                                    int ratio, int clipDepth )
224     {
225         Instance inst = new Instance( symbol, depth );
226         
227         if( matrix == null ) matrix = new Transform();
228         
229         Placement placement = new Placement( inst, matrix, cxform, null, 
230                                              ratio, clipDepth, frameNumber,
231                                              false, true, null );
232         
233         placements.add( placement );
234         return inst;
235     }    
236     
237     /**
238      * Free up the given symbol so that it no longer takes up memory.
239      * All instances of the symbol must be removed first.
240      * This is useful with large images when they are no longer required.
241      */
242     public void undefineSymbol( Symbol symbol )
243     {
244         placements.add( new Placement( symbol ) );
245     }
246     
247     /**
248      * Place a Movie Clip at the next available depth with the given properties.
249      * 
250      * @param matrix may be null to place the symbol at (0,0)
251      * @param cxform may be null if no color transform is required
252      * @param name   the instance name of a MovieClip - should be null if this is
253      *               not a MovieClip
254      * @param clipAction an array of Actions (with clipAction conditions)
255      */
256     public Instance placeMovieClip( Symbol symbol, Transform matrix, 
257                                     AlphaTransform cxform, String name,
258                                     Actions[] clipActions )
259     {
260         int depth = timeline.getAvailableDepth();
261         Instance inst = new Instance( symbol, depth );
262         timeline.setAvailableDepth( depth+1 );
263         
264         if( matrix == null ) matrix = new Transform();
265         
266         Placement placement = new Placement( inst, matrix, cxform, name, 
267                                              -1, -1, frameNumber, false, false,
268                                              clipActions );
269         
270         placements.add( placement );
271         return inst;
272     }
273 
274     /**
275      * Replace the Symbol at the given depth with the new MovieClip
276      * 
277      * @param matrix may be null to place the symbol at (0,0)
278      * @param cxform may be null if no color transform is required
279      * @param name   the instance name of a MovieClip - should be null if this is
280      *               not a MovieClip
281      * @param clipAction an array of Actions (with clipAction conditions)
282      */
283     public Instance replaceMovieClip( Symbol symbol, int depth,
284                                       Transform matrix, 
285                                       AlphaTransform cxform, String name,
286                                       Actions[] clipActions )
287     {
288         Instance inst = new Instance( symbol, depth );
289         
290         if( matrix == null ) matrix = new Transform();
291         
292         Placement placement = new Placement( inst, matrix, cxform, name, 
293                                              -1, -1, frameNumber, false, true,
294                                              clipActions );
295         
296         placements.add( placement );
297         return inst;
298     }    
299     
300     /**
301      * Remove the symbol instance from the stage
302      */
303     public void remove( Instance instance )
304     {
305         placements.add( new Placement( instance, frameNumber ) );
306     }
307     
308     
309     /**
310      * Alter the symbol instance by moving it to the new coordinates.
311      * Only one alteration may be made to an Instance in any given frame.
312      */
313     public void alter( Instance instance, int x, int y )
314     {
315         alter( instance, new Transform( x, y ), null, -1 );
316     }
317 
318     /**
319      * Alter the symbol instance by applying the given transform and/or
320      * color transform.
321      * Only one alteration may be made to an Instance in any given frame.
322      * 
323      * @param matrix may be null if no positional change is to be made.
324      * @param cxform may be null if no color change is required.
325      */
326     public void alter( Instance instance, Transform matrix, AlphaTransform cxform )
327     {
328         alter( instance, matrix, cxform, -1 );
329     }
330     
331     /**
332      * Alter the symbol instance by applying the given properties.
333      * Only one alteration may be made to an Instance in any given frame.
334      * 
335      * @param matrix may be null if no positional change is to be made.
336      * @param cxform may be null if no color change is required.
337      * @param ratio  only for a MorphShape - the morph ratio from 0 to 65535,
338      *               should be -1 for a non-MorphShape
339      */
340     public void alter( Instance instance, Transform matrix, 
341                        AlphaTransform cxform, int ratio )
342     {
343         Placement placement = new Placement( instance, matrix, cxform, null, 
344                                              ratio, -1, frameNumber, true, false, null );
345         
346         placements.add( placement );
347     }
348     
349     protected void flushDefinitions( Movie movie, 
350                                      SWFTagTypes timelineWriter,
351                                      SWFTagTypes definitionWriter )
352         throws IOException 
353     {
354         for( Enumeration enum = placements.elements(); enum.hasMoreElements(); )
355         {
356             Placement placement = (Placement)enum.nextElement();
357             
358             placement.flushDefinitions( movie, timelineWriter, definitionWriter );
359         }
360     }
361     
362     /**
363      * Write the frame
364      */
365     protected void write( Movie movie, 
366                           SWFTagTypes movieTagWriter,
367                           SWFTagTypes timelineTagWriter )
368         throws IOException 
369     {
370         if( customTag >= 0 )
371         {
372             timelineTagWriter.tag( customTag, false, customTagData );
373         }
374         
375         if( actions != null )
376         {
377             SWFActions acts = timelineTagWriter.tagDoAction();
378             acts.start(0);
379             acts.blob( actions.bytes );
380             acts.done();
381         }
382         
383         if( stop )
384         {
385             SWFActions actions = timelineTagWriter.tagDoAction();
386             
387             actions.start(0);
388             actions.stop();
389             actions.end();
390             actions.done();
391         }
392 
393         if( soundHeader  != null ) soundHeader.write( timelineTagWriter );
394         if( soundData    != null ) timelineTagWriter.tagSoundStreamBlock( soundData );
395         if( soundToStart != null ) timelineTagWriter.tagStartSound( 
396                                        soundToStart.define( movie, movieTagWriter, timelineTagWriter ),
397                                        new SoundInfo( true, false, null, -1, -1, 0 ));
398         
399         for( Enumeration enum = placements.elements(); enum.hasMoreElements(); )
400         {
401             Placement placement = (Placement)enum.nextElement();
402             
403             placement.write( movie, movieTagWriter, timelineTagWriter );
404         }
405 
406         if( label != null ) timelineTagWriter.tagFrameLabel( label, mAnchor );
407         timelineTagWriter.tagShowFrame();
408     }    
409 }