====== swfmill ======
* Homepage: [[http://swfmill.org/]]
* Subversion: [[http://svn.swfmill.org/swfmill/trunk/]] [[http://swfmill.org/trac/|via Trac]]
* Mailing List: [[http://osflash.org/mailman/listinfo/swfmill_osflash.org]]
* License: GNU GPL
===== Overview =====
=== What is it? ===
[[http://swfmill.org/|swfmill]] is a command line XML to SWF to XML processor using [[SWFML]],
an XML vocabulary closely modeled after the SWF format. It
i.e. it does not check if shapes you draw are closed, etc., so make
sure to thoroughly test SWFs you make with it.
Unlike the "simple" vocabulary, "basic" (like SWF) uses twips as a unit
instead of pixels. 20 twips are one pixel.
=== What can I do with the xslt processor? ===
If you don't like the "simple" vocabulary or have some special
requirements you can use it to transform your own XML vocabulary to
"basic" SWFML and output an SWF. Technically, "simple" is a built-in
default transform that does just that.
There are some SWF specific extensions to manage IDs and to import other SWFs.
=== For which platforms is it available? ===
You can [[http://swfmill.org/releases/|download]] windows and OS X and the sources for Linux.
64 bit processors are supported since version 0.2.3.
=== Where can I find more information? ===
Please follow the [[http://www.osflash.org/doku.php#relevant_links|links]] at the bottom of this page for some examples
and documentation, and visit the [[http://swfmill.org/|homepage]].
=== Is there a mailing list where I can get help? ===
Yes, you can [[http://osflash.org/mailman/listinfo/swfmill_osflash.org|subscribe]] and/or read the [[http://osflash.org/pipermail/swfmill_osflash.org/|archive]] (NEW!).
=== Anything else? ===
swfmill was written by [[http://0xdf.com/|Daniel Fischer]] and is published under the GPL.
===== Examples for the "simple" vocabulary =====
==== The most basic SWF ====
That's the most basic SWF you can make. It's 320 by 240 pixels, tries to run at 12 frames per second, and has a white background. Note the '''' tag, except of the '''' and '''' tags, all other tags belong into one. For simplicity's sake, most examples below will assume you know that, and won't include the header explicitly.
If you save this XML code into a file ''sample.swfml'' (it could also be ''sample.xml'' or in fact anything else), you can compile it into a binary SWF with the following commandline:
swfmill simple sample.swfml sample.swf
==== Importing Assets ====
=== Importing Images and SWFs ===
The '''' tag lets you import JPGs, PNGs (including alpha), SWFs and SVGs (somewhat experimental). They will be available as MovieClips. This example will import ''library/foo.jpg'' and give it the ID ''foo''. swfmill can also import TrueType fonts, but the syntax is different.
=== A simple Library ===
The '''' tag, like almost all others, lives in a '''' tag. You can determine in which frame assets are included into your SWF by using multiple frames and putting it into the one you want your assets to be available in. You don't have to import assets into the library, but then they won't be available to ActionScript. Sometimes you don't need an asset to be in the library, because you only want to use it as a part of another clip you define, or you place it onto the stage directly with the '''' tag.
Of course, you can have several '''' and '''' tags in one ''''. The example will import the same image as above, but this time into the library. The ID also serves as the linkage name if you import into the library.
=== Importing Fonts ===
swfmill can import most TTF fonts, with exception to fonts that use Bezier curves and bitmap fonts. It supports both DefineFont2 (>= Flash 7) and DefineFont3 (>= Flash 8).
Importing TTF fonts works almost like importing images or SWFs, but the '''' tag is used. Consider the following example:
Note : That the font tag must exist inside a library tag for the linkage id to work with TextFormats and dynamically created TextFields, or that it is Exported for runtime sharing.
== Font Rendering Engine ==
On the movie tag, if version="7" DefineFont2 is created. If version="8" or higher, DefineFont3 is created. Accordingly, changing the version attribute will also change the font rendering engine which flash uses.
== Font Name Conflicts ==
By default, swfmill pulls the font name from the TTF internal fields. This may create font name conflicts if you have different styles of the same font. To avoid this problem, include the name attribute. Without it, fonts such as Verdana Regular and Verdana Bold will both have the default name "Verdana": allowing you access to only 1 of those fonts in your text fields.
== Special Characters and the glyphs Attribute ==
glyphs == characters and swfmill allows you the option to include some or all of the characters provided by a TTF. We do this with the glyphs attribute.
If you do not include the glyphs attribute on the font tag, all available glyphs will be imported. This is a feature for users who want the most complete font they can get.
Other users may find this as a hindrance because they only need certain characters and want to keep the output SWF small. In this case, you can list the glyphs you would like included in the glyphs attribute. For example:
You may need to include special characters in your glyphs tag. You can do this by using XML entities or Unicode's Universal Character Set format. Note that XML only supports &, > <, ", and '. All other characters will need to be referenced in the Universal Character Set format. The following example includes the uppercase inverted exclamatory mark (ยก), the ampersand symbol (&), and the greater than symbol (>), and the uppercase A.
== id versus name ==
The font node has two differing attributes "id" and "name". id is used for the format attribute of textfields:
The name attribute is used in order to get an ActionScript reference to the embedded font. When using the TextField's embedFonts property, you'll be able to use the TextFormat.font property with this name.
This attribute is also a way to group different font by families and retrieve them from actionscript (Flash 8 only).
id and name attributes can be used together to serve different purposes.
=== Importing a Sound ===
We can import sounds with a similar method, where "id" is the linkage id, and we put the following tag inside of the tag:
and later in our actionscript (compiled prior via Mtasc, etc). we'd put:
var snd:Sound = new Sound();
snd.attachSound("myID");
snd.start();
Note: Requires pre-release 0.2.11.18 or later, and sound is not streamed.
Note: Works with 56, 64, 128, 192 and 256 kbps MP3s.
Note: joint stereo MP3s, WAV etc don't play at all.
=== Importing a Shared Library ===
You can use shared libraries, too. SWFs created with swfmill always are available for runtime sharing, to import another SWF as a library keep a local copy for testing purposes and import it like this:
==== Assigning a Class to a MovieClip ====
The ''class'' attribute of the '''' tag can be used to assign a class to your MovieClips. If you're doing this, keep in mind that [[MTASC]] does not compile "unused" classes into your SWF, and it has no way of knowing you need them for this. You can "force" it to include the class by assigning it to a variable or adding the class to the mtasc command line explicitly, but a simple ''import'' won't be enough. As usual when you do this, make sure that your class inherits from the intrinsic ''MovieClip'' class.
In order for swfmill to find the class it must have been compiled previously. That means you don't run swfmill first and compile your classes into it afterwards, but compile a ''classes.swf'' (although any other name would do) first with mtasc's ''-header'' setting and import it in your swfml:
==== Using components ====
As for version 0.2.9 you are able to use the new component tag. No need to use a library and a call tag. Here is a simple example. The combo is instantiated later by actionscript injected using [[mtasc]].
There are still 2 problems with components:
*SWF extracted from a SWC can be big because they contain data for the Flash IDE, classes and the visual elements that we need.
*If you add a couple of components from the same family, swfmill will not check if some classes already exist and you will end up with duplicates.
Here is a comparison with 3 components of the same family, an Alert window, a Label and a ProgressBar:
*Compiled with the Flash IDE: 12k
*Compiled with swfmill: 99k
==== Publishing to Flash 8 ====
To publish a Flash 8 SWF using Swfmill, specify the player version in the movie tag like this:
Also, if you are compiling AS2 code for use in your SWF with [[MTASC]], make sure you compile it with the -version 8 switch.
==== Flash 8 new features ====
Since swfmill version 0.2.11.3, some of the new tags introduced in flash 8 were introduced. Here is a list of them :
- File attributes to set security sandbox file access and metadata :
Choose between the arguments separated by |.
By default, useNetwork is set to 0 which means 'filesystem' (1 means 'network').
But make sure to add to the root tag the attribute local-access like so :
- Metadata that search engine could index :
- Flash 8 filters and blending modes.
Shared library published to flash 8 are now correctly handled.
==== Publishing AS3 compatible files ====
By default, swfmill publishes AS2 based AVM1 movies, which is not fully compatible with AVM2 that runs AS3. To publish AVM2 compatible SWF files for use in your AS3 projects, add the attribute as3="1" to your movie tag:
===== Advanced =====
==== Multi-state MovieClips ====
Sometimes you need movie clips which contain multiple states. Probably the most common example of this is a button. Buttons will normally have 4 states, Up, Over, Down, and Disabled. You can create a MovieClip that contains all the states for a button, and then have an ActionScript class manage the events and change which state is displayed depending on the state the button is in.
Here's an example of one way to create such a clip:
To change which state is displayed you can simply do a ''gotoAndStop(name)'' call on the button's movie clip.
There is one problem with the above solution. If your state images have transparencies then latter states could end up showing parts of the previous states. In theory you could set the depth values of the clips in all 4 frames to the same value, but this doesn't seem to work for more than 2 frames (at least as of 0.2.12.2).
To get around the transparency problem you could also define your movie clip as follows:
In this case you could simply have your code show/hide the child clips by name depending on which state you want displayed. It's a little more work in the code to change states (you have to both show the state you want and hide the others) but you don't have to worry about one state 'seeing through' to another.
==== Compositing frames with place ====
'Place' tag is used to insert clips to the SWF timeline. Clips themselves can contain frames and you use 'place' for them as well.
Along with the identifier and the optional coordinates, you must enter the depth for the clip. Depth starts from zero and up, where the highest number comes out top. Two clips cannot reside at the same depth, and when assigned, one will replace the other.
It's important to keep in mind that once a clip has been assigned to a depth, it will occupy that depth for the rest of the remaining timeline. Meaning that a clip placed at frame one will stay there for the rest of the movie. The only way to remove a clip is to assign another clip to its reserved depth, effectively overwriting it from the timeline.
When you're placing more than one clips to a frame, it is safest to do so in a separate clip. This way you can still overwrite the whole frame by simply placing a new clip in its place.
==== Dynamic Shared Font Loading ====
Swfmill can be used to create Shared Libraries for Dynamic Font Loading at runtime, a nice hack described by [[http://www.v-i-a.net/|Erixtekila]]. This is well documented, with examples, by Mike Barbero, [[http://www.deja-vue.net/blog/2006/05/26/as2-sharedfonts-datagrid-example-the-last-stand/|here]].
Essentially, you have to load an SWF (containing the font) which loads //itself// as a shared library. Here's an example, shamelessly ripped from Mike's page:
As you can see in the '''' tag for the dynamic library, the URL for the SWF must be ''http://localhost/test/charters.swf''. Relative paths work, too. So, when you need to load the font, you load the SWF you generated and it will load itself out of the browser cache.
The ''@name'' is set to the same value in all '''' tags on purpose, so you can use e.g., '''' in HTML TextFields. Of course it also works with just a single style, with only a selected subset of the glyphs, and so on.
==== Alternate Component Import Method ====
Earlier in this document a method for importing components was provided. This method allows you to add the components directly into the SWFs using only swfmill, but can potentially cause much larger output files. If you have access to the Flash IDE there is another simple method to add components.
Basically, you will use the Flash IDE to generate a blank SWF which contains the components you will want to use. Then, in your XML you add a clip to the library that imports this SWF. It appears that simply importing the clip has the effect of adding the components to the library, without even having to instantiate the clip.
For example, if you create an SWF using the Flash IDE which simply contains the ComboBox component and build it as ''Components.swf'' you can then do this in the XML:
then in your code wherever you wish to create the combo box you simply import the control's class at the top:
import mx.controls.ComboBox
and then instantiate it with the following (replacing ''_root'' with the movie clip you want to attach to and ''"myComboBox"'' with the name you wish to give it):
_root.createClassObject(ComboBox, "myComboBox" _root.getNextHighestDepth());
var cb:ComboBox = _root["myComboBox"];
==== SVG features and issues ====
SVG support works great for files produced by [[http://www.inkscape.org/|Inkscape]]. There are a couple of bugs supporting other svg files (e.g. [[http://swfmill.org/trac/ticket/12|#12]]). Currently you can only import single SVG file into SWF ([[http://swfmill.org/trac/ticket/14|#14]], seems to be fixed in trunk).
All groups (''svg:g'') in SVG are exported as movie clips (for Inkscape this affects layers as well as groups). These movie clips are named after either their ''inkscape:label'' attribute if that exists (first character '#' removed if present) or ''id'' attribute (''inkscape:label'' is better because it allows reusing name in different point of hierarchy. If group has ''transform'' attribute, all it's contents are created in yet another movie clip (usually called ''instance''//N//) with appropriate transformations applied.
If some element has ''swfClass'' attribute, then specified class is assigned to a movieclip corresponding to that element. All prerequisites described [[#Assigning a Class to a MovieClip|above]] must also be satisfied here.
A few more words about Inkscape. To set label you can right-click any object and choose //Object Properties//. To set class you can select object, pop up an //XML Editor// (e.g. using ''Ctrl+Shift+X'') and enter ''swfClass'' and appropriate value, then click //set//.
===== Relevant Links =====
* [[http://swfmill.org/|Swfmill homepage]]
* [[http://swfmill.org/doc/using-swfmill.html|Mark Winterhalder's guide to Swfmill]]
* [[http://aralbalkan.com/408|The Natural Entrypoint Method (Tutorial & Source Files) - Introducing A New Way to Create Flash Applications Using Swfmill and MTASC]]
* [[http://www.protozoo.com/?p=92|Swfmill GUI : ASAlter]]
* [[http://swfmill.org/doc/reference.html|'swfml basic' Reference]]
* [[http://aralbalkan.com/429|Publishing to Flash 8 with Swfmill and MTASC]]
* [[http://aralbalkan.com/373|Fame + Swfmill = Fully open source flash]] Post/tutorial on using Swfmill with [[FAME]].
* [[http://www.snafoo.org/swfmill/swfml_dtd.dtd|SWFMill DTD (Document Type Definition)]]