SWFC Manual swfc is a tool for generating flash files. You can write small simple scripts and then have them compiled to SWF Flash Animations.
Calling swfc

swfc is command line based. You call it via $ swfc file.sc The filename of what is generated depends on the filename of the script (file.sc), the filename given inside the script, and the optional -o passed to swfc.

A simple swfc example

Let's create a simple SWF file, shall we? The following script creates a red box with a yellow border. On the right side you see the script used, on the left side the swf file that is generated.

.flash filename="box.swf" .box b1 100 100 color=yellow fill=red .put b1 pin=center scale=0% .frame 100 .change b1 pin=center scale=100% .frame 200 .change b1 pin=center scale=0% .end

The .box command creates the box. Every object that is created must also be explicitly put into the scene using .put to become visible.

Change, on the other hand, modifies an already existing object. It works gradually: In the example above, the change happens over 100 frames. If you want to change an object suddently from one frame to the next, you would use the .jump command.

Color transforms

You can define a number of parameters in the .put, .change and .jump tags. Among those are the color transform parameters red, green, blue and alpha. Furthermore, for convenience, there's also luminance, which sets red, green and blue in one go.

Each one of these consists of two parts: The multiplicator and the shift. The syntax is ±<multiplicator>±<shift> . So, for example, to make an object 50% brighter, you would use luminance=+128. Notice that all color components inside the transformed object in the range 128-255 will be mapped to 255 with this. To map 0 to 128, 255 to 255, but 128 to 192, you would use luminance=0.5+128.

You can also specify negative values for both <mutliplicator> and <shift>. This makes it e.g. possible to invert an object: luminance=-1+255.

The following example demonstrates a few of the possible transforms:

.flash filename="cxform.swf" version=5 fps=25 .jpeg s1 "photo.jpeg" quality=80% .put s1 x=50 y=50 scalex=110 scaley=110 .frame 50 .change s1 x=0 y=0 scalex=210 scaley=210 red=-1+255 green=-1+255 blue=-1+255 #invert .frame 100 .change s1 x=100 y=50 scalex=110 scaley=110 red=0 green=+0 blue=+0 #remove red .frame 150 .change s1 x=0 y=0 scalex=210 scaley=210 red=+0 green=2 blue=-1+255 #amplify green, invert blue .frame 200 .change s1 x=50 y=100 scalex=110 scaley=110 red=2-128 green=-2+255 blue=+0.7+40 #alien glow .frame 250 .change s1 x=0 y=0 scalex=210 scaley=210 red=8-1024 green=8-1024 blue=8-1024 #palette reduce .frame 300 .change s1 x=0 y=0 scalex=210 scaley=210 red=+0 green=+0 blue=+0 #back to normal .frame 350 .change s1 x=105 y=105 scalex=0 scaley=0 luminance=0 #fadeout .end A very useful fact is also that you can color transform the alpha component. So to fade any object into the background, you would simply transform it's alpha color: E.g. alpha=64 would make the object 75% transparent. This is used in an example further below.
swfc has font support. That means you can also insert texts into your animations. The easiest way to load a font is to do something like .font Arial filename="Arial.ttf" . You now have a font named Arial to play with. For example, for the obligatory hello world program: .flash filename="helloworld.swf" .font Arial filename="Arial.ttf" .text helloworld font=Arial text="Hello World!" .put helloworld .end The text argument expects UTF-8 strings. So if you want to pass any special characters (umlauts, digraphs etc.), they have to be UTF-8 encoded. Besides TrueType fonts, swfc also supports native SWF fonts. If you have a SWF with a font you would like to use, do a swfextract file.swf Then write down the font ID of the font, and do a swfextract -f <fontid> file.swf -o myfont.swf .

This will give you a file named myfont.swf which you can also use in the filename parameter of .font.

Furthermore, you can convert TTF and Type1 fonts into SWF using font2swf: font2swf Arial.ttf -o Arial.swf The nice advantage of this is that you can play Arial.swf in the flash player and see what the font looks like. (Also, loading a font in SWF format is slighly faster than from a TTF file, as with TTFs spline conversion has to take place).

So much for the basics. Now let's go to the more advanced functionality around fonts.

Apart from being able to define text in your swfc files, you can also define text outlines. Those are not real characters but rather abstract vector objects which you can use in other commands.

.flash filename="fontoutline.swf" .font Arial "Arial.swf" .textshape helloworld font=Arial size=200% text="Hello World" .filled filled_helloworld outline=helloworld fill=blue line=3 color=green .put filled_helloworld .end Here, .textshape helloworld defines an outline named "helloworld", which is then used to construct a filled outline named filled_helloworld. To make this a little more interesting, let's fill with a gradient instead of a plain color: .flash filename="fontgradient.swf" .font Arial "Arial.swf" .textshape helloworld font=Arial text="SHADE" .gradient whitefade: 0% black 50% #505050 100% yellow .end .filled filled_helloworld outline=helloworld fill=whitefade line=1 color=#2c2c2c .put filled_helloworld scale=200% .end While at it, you can also fill with an image: .flash filename="fontimage.swf" .font courier "Courier.swf" .jpeg beach "beach.jpg" .textshape text font=courier text="HOLIDAY" .filled filled_text outline=text fill=beach line=1 color=#2c2c2c .put filled_text scale=200% .end But let's get back to normal .text characters. The following demonstrates that you can treat objects defined with .text like normal shapes, i.e., scale them, move them, and use them for clipping: .flash filename="text5.swf" .font courier "Courier.swf" .text hithere text="HELLO" font=courier size=200% .jpeg scenery "scenery.jpg" .frame 1 .startclip hithere pin=center x=100 y=75 scale=50% #text clips... .put scenery scale=50% .end .frame 100 .change hithere rotate+=360 pin=center scale=100% .end

The last two examples look similar, but their underlying structure is different: The first is a shape object filled with image data (that is, a texture), while the second uses a normal text object to clip an rectangular image. (More about clipping in the next section)

Also, .text takes a color attribute (that's actually the poor man's version of the more advanced filling options that .textshape in conjunction with .filled offers), which is used here together with the alpha parameter of .change:

.flash filename="text6.swf" .font times "Times.swf" .text hello text="HELLO" font=times size=200% color=blue .text world text="WORLD" font=times size=200% color=red .frame 1 .put hello pin=center x=50 y=50 .put world pin=center x=50 y=50 alpha=25% .frame 200 .change hello rotate+=360 pin=center alpha=25% .change world rotate-=360 pin=center alpha=100% .end
Another example for clipping against text: .flash filename="textclip.swf" bbox=400x120 background=black version=6 .font times "Times.swf" .textshape helloworld text="HELLO WORLD" font=times size=300% .filled helloworld1 outline=helloworld fill=blue line=0 .filled helloworld2 outline=helloworld fill=green line=0 .frame 1 .put h3=helloworld1 y=100 .startclip h1=helloworld1 y=100 .put h2=helloworld2 y=100 .end .frame 1000 .change h1 x=-1000 .change h2 x=-500 .change h3 x=-1000 .end
A special type of text in SWF is the edittext, which can be modified by the viewer. It's content can also be queried and set from ActionScript (see below). You can generate this type of text with the .edittext command: .flash filename="edittext.swf" bbox=410x210 .font Arial "Arial.swf" .edittext myedittext font=Arial size=50% width=400 height=200 color=blue border multiline wordwrap text="Edit me!\nClick with your mouse on this text to edit it." .put myedittext x=3 y=3 .end
In the previous chapter, we learned how to create a text outline using .textshape. The other way to create outlines is to use the .outline command: .flash filename="house.swf" .outline house_outline: M 36.99 29.93 L 15.52 51.39 L 20.44 51.39 L 20.44 81.91 L 39.73 81.91 L 39.73 62.33 L 48.36 62.33 L 48.36 81.91 L 53.84 81.91 L 53.84 51.39 L 58.45 51.39 L 36.99 29.93 M 28.79 53.70 L 34.55 53.70 L 34.55 60.60 L 28.79 60.60 L 28.79 53.70 .end .filled house outline=house_outline fill=grey color=grey .put house .end The syntax of the paths inside the .outline command is the same as in svg. That means you can use the svg editor of your choice (e.g.: inkscape) to create these outlines. You then need to extract them out of the .xml/.svg file. They are inside the "d" attribute of the "path" tag: ... <path style="fill:#0000ff;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;" d="M 369.90625 299.31250 L 155.21875 513.96875 L 204.40625 513.96875 L 204.40625 819.15625 L 397.31250 819.15625 L 397.31250 623.37500 L 483.68750 623.37500 L 483.68750 819.15625 L 538.40625 819.15625 L 538.40625 513.96875 L 584.56250 513.96875 L 369.90625 299.31250 z M 287.90625 537.00000 L 345.50000 537.00000 L 345.50000 606.09375 L 287.90625 606.09375 L 287.90625 537.00000 z " id="rect908" /> ...
Outlines can be filled with gradients, bitmaps etc., just like seen previously with .textshape: .flash filename="gradients.swf" .outline star: M 521,640 C 502,678 370,546 328,554 C 270,566 152,731 93,722 C 51,716 147,549 127,512 C 98,460 -107,400 -117,341 C -124,299 63,339 93,308 C 133,265 127,50 180,23 C 218,3 238,195 276,213 C 330,238 532,166 575,208 C 605,238 429,316 424,358 C 416,417 547,587 521,640 .end .gradient rainbow: 0% blue 25% green 50% yellow 75% orange 100% red .end .gradient fire radial: 0% white 50% yellow 100% red .end .gradient horizon: 0% cyan 49% blue 50% green 100% peru .end .gradient transparent: 0% #ff000000 100% #ff0000ff .end .box scenery fill=horizon width=200 height=200 .box bar fill=transparent width=240 height=20 .filled star1 outline=star fill=rainbow line=1 .filled star2 outline=star fill=fire line=1 .put scenery rotate=90% .put star1 scale=10% x=-70 .put star2 scale=10% x=-180 y=110 .put bar x=-180 y=10 rotate=45 .end

The previous example demonstrated how to fill an outline with a gradient.

There are two types of gradients: radial and linear. radial gradients have a center point and a radius (and are immune to rotations), and linear gradients have a start point and a width (or height) and can be rotated.

gradients can be freely positioned inside the object you want to fill, by passing the x, y and width and height (or r) parameters to .gradient. .flash filename="gradients2.swf" .outline o: moveTo -50,-50 lineTo 0,-45 lineTo 50,-50 lineTo 45,0 lineTo 50,50 lineTo 0,45 lineTo -50,50 lineTo -45,0 lineTo -50,-50 .end .gradient horizon1 radial x=-50 y=-50 r=100: 0% cyan 49% blue 50% green 100% cyan .end .gradient horizon2 radial x=0 y=0 r=50: 0% cyan 49% blue 50% green 100% cyan .end .filled o1 outline=o fill=horizon1 line=0 .filled o2 outline=o fill=horizon2 line=0 .put o1 x=50 y=50 .put o2 x=150 y=50 .end If you want to use a given gradient several times with different x and y values, you can also first define the gradient itself, and then position it with .texture: .flash filename="gradients3.swf" # same outline as above, only in more terse notation .outline o: M -50,-50 L 0,-45 L 50,-50 L 45,0 L 50,50 L 0,45 L -50,50 L -45,0 L -50,-50 .end .gradient horizon radial: 0% cyan 50% blue 50% green 100% cyan .end .texture horizon1=horizon x=-50 y=-50 r=100 .filled o1 outline=o fill=horizon1 line=0 .put o1 x=50 y=50 .texture horizon2=horizon x=0 y=0 r=50 .filled o2 outline=o fill=horizon2 line=0 .put o2 x=150 y=50 .texture horizon3=horizon x=0 y=50 r=10 .filled o3 outline=o fill=horizon3 line=0 .put o3 x=50 y=150 .texture horizon4=horizon x=50 y=50 r=200 .filled o4 outline=o fill=horizon4 line=0 .put o4 x=150 y=150 .gradient bunt: 0% black 20% blue 40% magenta 60% orange 80% cyan 100% white .end .texture bunt1=bunt x=-50 y=-50 width=100 .filled oo1 outline=o fill=bunt1 line=0 .put oo1 x=50 y=250 .texture bunt2=bunt x=-50 y=-50 width=141 height=141 rotate=45 .filled oo2 outline=o fill=bunt2 line=0 .put oo2 x=150 y=250 .texture bunt3=bunt x=-50 y=50 width=141 height=141 rotate=-45 .filled oo3 outline=o fill=bunt3 line=0 .put oo3 x=50 y=350 .texture bunt4=bunt x=50 y=50 width=100 rotate=180 .filled oo4 outline=o fill=bunt4 line=0 .put oo4 x=150 y=350 .end
swfc has Actionscript support. For normal actionscript, which is executed once a given frame is reached, just open an .action block, and write the ActionScript into the block: .flash filename="action.swf" bbox=300x300 fps=50 .box mybox color=blue fill=green width=100 height=100 .put mybox .frame 1 .action: _root.angle += 0.05; mybox._x = 100*Math.cos(_root.angle)+100; mybox._y = 100*Math.sin(_root.angle)+100; .end .frame 2 .action: gotoFrame(0); Play(); .end .frame 3 .end For much more interesting ActionScript examples, see Laurent Lalanne's Flash Eyes or the source of Jean-Michel Sarlat's Mandelbrot explorer. or Sunder Iyer's swfc pages.

Actionscript comes in handy when dealing with SWF Buttons.

A button defines, in SWF context, an object sensitive to mouse movement, mouse buttons, and key presses.

The following is a trivial example: Four objects which change their shape once the cursor is over it. .flash filename="button1.swf" fps=50 .box box1 color=white fill=#336633 width=50 height=50 .box box2 color=white fill=#99cc99 width=100 height=100 .button mybutton1 .show box1 as=shape x=25 y=25 .show box2 as=hover x=12.5 y=12.5 .end .frame 1 .put b1=mybutton1 .put b2=mybutton1 x=100 red=+255 .put b3=mybutton1 y=100 green=+255 .put b4=mybutton1 x=100 y=100 blue=+255 .end

The .show command (which can only be used inside .button) has a syntax very similar to .put. For every shape a button uses, you can specify the position, color transform, scaling, rotation etc. just like with .put.

The only real difference between those two commands is the as parameter: with that you tell the button when to display that specific shape. There are four allowed parameters to as:

Blend modes were introduced in Flash 8. They allow to use different alrithmetrics when it comes to putting transparent (or semi transparent) shapes or images on top of each other. The diffent blend modes are: normal layer multiply screen lighten darken add substract difference invert alpha erase overlay hardlight For example, in order to set a "invert" blend mode: .flash filename="invert.swf" fps=50 bbox=511x127 .jpeg pic stripe.jpg .put pic .font arial Arial.ttf .text txt font=arial text="Test inverted blend mode... ABCDEFGHIJKLMNOPQRSTUVWXYZ" size=200% .put txt x=512 y=120 blend=invert .frame 700 .change txt x=-4096 .end The layer blend modes is especially useful, if you want to make sprite transparent. Compare the two stacks of rectangles in the next example. In the left one (set without layer), when the sprite is made transparent via alpha=50%, the rectangles also are transparent in respect to each other- i.e., you don't get a transparent image of a stack of rectangles, you get an image of a stack of transparent rectangles. On the right side, the stack is set with layer, and only the whole sprite get's transparent. .flash filename="layer.swf" fps=50 bbox=511x127 .jpeg background stripe.jpg .put background .box b1 fill=green width=100 height=100 .box b2 fill=cyan width=100 height=100 .box b3 fill=blue width=100 height=100 .sprite s1 .put b1 .put b2 x=25 y=25 .put b3 x=50 y=50 .end .sprite s2 .put b1 .put b2 x=25 y=25 .put b3 x=50 y=50 .end .put s1 alpha=50% .put s2 alpha=50% x=300 blend=layer .end

An especially nice new feature of Flash 8 are filters.

The current version of swfc supports the following filters:

dropshadow blur gradientglow bevel
The "dropshadow" filter dropsshadow can be used to add shadows below (or above) flash objects. Every shadow has a color, and a direction/distance parameter (angle,distance), which controls where the shadow will be placed. The shadow is calculated by blurring (radios blur the alpha layer of the corresponding object, strengthening it (multiplication with strength), filling it with color and then merging it with the background. If the optional knockout option is given, the original object is removed, only the shadow is visible. If the innershadow parameter is given, the shadow will be inside the object. .flash filename="shadow.swf" version=8 bbox=430x140 background=blue .font myfont "Times.ttf" .text mytext text="SHADOW" font=myfont size=140% color=yellow .dropshadow myshadow color=black blur=5 angle=45 distance=50 passes=2 strength=1 .put mytext filter=myshadow y=75 .end
The "bevel" filter

The bevel filter essentially applies two shadows at once, at opposite directions. It supports the same arguments as the dropshadow filter, and also the optional ontop argument, which, if given, moves the "shadows" above the image. (useful together with knockout).

The following example demonstrates another feature of the swfc filter implementation: filters can also be animated. .flash filename="bevel.swf" version=8 background=blue fps=12 .font arial "Arial.ttf" .text abc text="FILTERS" font=arial size=130% color=red .text beveltxt text="BEVEL" font=arial size=130% color=red .bevel bevel0 highlight=white shadow=black blur=9 angle=45 distance=4 passes=2 strength=2 knockout .bevel bevel1 highlight=white shadow=black blur=14 angle=45 distance=6 passes=2 strength=2 knockout .bevel bevel2 highlight=white shadow=black blur=7 angle=0 distance=6 passes=2 strength=1 innershadow knockout .bevel bevel3 highlight=white shadow=black blur=7 angle=360 distance=6 passes=2 strength=1 innershadow knockout .put beveltxt filter=bevel0 .put abc filter=bevel2 y=80 .frame 50 .change beveltxt filter=bevel1 .frame 100 .change beveltxt filter=bevel0 .change abc filter=bevel3 .end
The "blur" filter The blur filter is probably the most simple filter- it only takes a blur radius and a number of passes. It then performs a blur effect by smoothening an area of blurx times blury pixels. .flash filename="blur.swf" version=8 fps=50 bbox=200x200 .font arial "Arial.ttf" .blur myblur1 blur=100 passes=2 # blur=100 is an abbreviation for blurx=100 blury=100 .blur myblur2 blurx=0 blury=0 passes=2 .blur myblur3 blurx=0 blury=100 passes=2 .textshape abc text="BLUR" font=arial size=100% .filled fabc outline=abc line=2 color=blue fill=white .filled fabc2 outline=abc line=2 color=red fill=yellow .sprite mysprite .put fabc pin=center x=100 y=100 .put fabc2 pin=center x=100 y=100 .frame 200 .change fabc pin=center rotate=360 .change fabc2 pin=center rotate=-360 .end .put mysprite filter=myblur1 .frame 200 .change mysprite filter=myblur2 .frame 400 .change mysprite filter=myblur3 .end
The "gradientglow" filter gradientglow is like the shadow filter, only that the resulting shadow color is calculated from a gradient instead of a single color. .flash filename="filters.swf" version=8 .font times "Times.ttf" .text abc text="Gradientglow" font=times size=100% color=blue .gradient fire: 0% black/00 25% red/40 50% orange/80 75% yellow/c0 100% white/ff .end .gradientglow fireglow1 gradient=fire blur=20 innershadow angle=1 distance=20 .gradientglow fireglow2 gradient=fire blur=20 angle=0 distance=2 passes=1 knockout .gradientglow fireglow3 gradient=fire blur=20 angle=0 distance=2 passes=1 ontop .put abc1=abc filter=fireglow1 .put abc2=abc y=50 filter=fireglow2 .put abc3=abc y=100 filter=fireglow3 .end