Macromedia Flash File Format (SWF)

recompiled with RAW HTWL

Shapes


Introduction Basic Types Display List Control Tags
Shapes (Examples Shapes) Gradients Buttons
Sprites Fonts and Text Shape Morphing Bitmap
Sounds Actions ActionScripts Reference

Shapes Contents

Shapes
Shape Overview
An Example Shape
Fill Styles
Line Styles
Shape structures
Shape Records
End Shape Record
Style Change Record
FillStyle0 and FillStyle1
Edge Records
Straight Edge Records
Curved Edge Records
Converting between Quadratic and Cubic Bezier curves
DefineShape
DefineShape2
DefineShape3

Shapes

The Macromedia Flash (SWF) shape architecture is designed to be compact, flexible and rendered very quickly to the display. It is similar to most vector formats in that shapes are defined by a list of edges called a path. A path may be closed — where the start and end of the path meet to close the figure, or open — where the path forms an open-ended stroke. A path may contain a mixture of straight edges, curved edges, and ‘pen up and move’ commands. The latter allows multiple disconnected figures to be described by a single shape structure. (see MoveTo flag)

A fill style defines the appearance of an area enclosed by a path. Fill styles supported by Macromedia Flash (SWF) include a color, a gradient, or a bitmapped image.
A line style defines the appearance of the outline of a path. The line style may be a stroke of any thickness and color.

Most vector formats only allow one fill and line style per path. Macromedia Flash (SWF) extends this concept by allowing each edge to have its own line and fill style. This can have unpredictable results when fill styles change in the middle of a path.

Flash also supports two fill styles per edge, one for each side of the edge: FillStyle0 and FillStyle1. FillStyle0 should always be used first and then FillStyle1 if the shape is filled on both sides of the edge.

Shape Overview

A shape is comprised of the following elements: Note: Line and fill styles are defined once only, and may be used (and re-used) by any of the edges in the shape.
an
				example shape

An Example Shape

This example appears to be a collection of shapes, but it can be described with a single DefineShape tag.

The red circle, red square and green rounded-rectangle are closed paths. The curved line is an open path. The red square consists of all straight edges, the red circle consists of all curved edges, while the rounded rectangle has curved edges interspersed with straight edges.

There are two fill styles; solid green and solid red, and two line styles; 1-pixel black, and 2-pixel black. The red circle and red square share the same fill and line styles. The rounded rectangle and curved line share the same line style.

Here’s how to describe this example with Macromedia Flash (SWF): All shape records share a similar structure but can have varied meaning. A shape-record can define straight or curved edge, a style change, or it can move the current drawing position.

Now we define the curved line: Now we define the red square: Now we define the red circle: Now we define the green rounded-rectangle:

See other examples in the Examples Page.

Fill Styles

Macromedia Flash (SWF) supports three basic types of fills for a shape.

Solid fill — A simple RGBA color that fills a portion of a shape. An alpha value of 255 means a completely opaque fill. An alpha value of zero means a completely transparent fill. Any alpha between 0 and 255 will be partially transparent.
Gradient Fill — A gradient fill can be either a linear or a radial gradient. See Gradients for an in depth description of how gradients are defined.
Bitmap fill — Bitmap fills refer to a bitmap characterId. There are two styles: clipped and tiled. A clipped bitmap fill repeats the color on the edge of a bitmap if the fill extends beyond the edge of the bitmap. A tiled fill repeats the bitmap if the fill extends beyond the edge of the bitmap.

A fill style array enumerates a number of fill styles. The format of a fill style array is described in the following table:
     FillStyleArray     
     Field           Type           Comment     
     FillStyleCount           count = UI8           Count of fill styles     
     FillStyleCountExtended           If count = 0xFF count = UI16           Extended count of fill Styles.
Supported only for Shape2 and Shape3.
    
     FillStyles           FillStyle[count]           Array of fill styles     
    SwfJava v0.0: how to create a FillStyleArray    
    new FillStyleArray (    
        FillStyle[] fillStyles    
    );    


    XWF v0.0: how to declare a FillStyleArray element    
    <FillStyleArray>    
        <fillStyle ... />    
        <fillStyle ... />    
        ...    
    </FillStyleArray>    



The format of a fill style value within the file is described in the following table:
     FillStyle     
     Field           Type           Comment     
     FillStyleType           type = UI8
0x00 = solid fill
0x10 = linear gradient fill
0x12 = radial gradient fill
0x40 = tiled bitmap fill
0x41 = clipped bitmap fill
    
     Type of fill style     
     Color           If type = 0x00 RGBA (if Shape3);
RGB (if Shape1 or Shape2)
    
     Solid fill color with transparency information     
     GradientMatrix           If type = 0x10 or 0x12 MATRIX           Matrix for gradient fill     
     Gradient           If type = 0x10 or 0x12 GRADIENT           Gradient fill     
     BitmapID           If type = 0x40 or 0x41 UI16           ID of bitmap character for fill     
     BitmapMatrix           if type = 0x40 or 0x41 MATRIX           Matrix for bitmap fill     
    SwfJava v0.0: how to create a FillStyle    
    new SolidFillStyle (    
        RGB color    
    );    
        
    new SolidFillStyle (    
        RGBA color    
    );    
        
    {other types are not yet implemented}    


    XWF v0.0: how to declare a SolidFillStyle element    
    <SolidFillStyle color="#3366FF" />    
        
    <SolidFillStyle color="#3366FF/99" />    


Line Styles

A line style array enumerates a number of line styles. The format of a line style array is described in the following table:
     LineStyleArray     
     Field           Type           Comment     
     LineStyleCount           count = UI8           Count of line styles     
     LineStyleCountExtended           If count = 0xFF count = UI16           Extended count of line Styles.     
     LineStyles           LineStyle[count]           Array of line styles     
    SwfJava v0.0: how to create a LineStyleArray    
    new LineStyleArray (    
        LineStyle[] lineStyles    
    );    


    XWF v0.0: how to declare a LineStyleArray element    
    <LineStyleArray>    
        <lineStyle ... />    
        <lineStyle ... />    
        ...    
    </LineStyleArray>    



A line style represents a width and color of a line. The format of a line style value within the file is described in the following table:
     LineStyle     
     Field           Type           Comment     
     Width           UI16           Width of line in twips     
     Color           RGB (Shape1 or Shape2); RGBA (Shape3)           Color value including alpha channel information for Shape3s     
    SwfJava v0.0: how to create a LineStyle    
    new LineStyle (    
        int width, RGB color    
    );    
        
    new LineStyle (    
        int width, RGBA color    
    );    


    XWF v0.0: how to declare a LineStyle element    
    <LineStyle width="(int)" color="#3399FF" >    
        
    <LineStyle width="(int)" color="#3399FF/CC" >    

Notes:
  1. All lines in Macromedia Flash (SWF) have rounded joins and end-caps. Different join styles and end styles can be simulated with a very narrow shape that looks identical to the desired stroke.
  2. Macromedia Flash (SWF) has no native support for dashed or dotted line styles. A dashed line can be simulated by breaking up the path into a series of short lines.

Shape structures

The SHAPE structure defines a shape without a fill style or line style information. SHAPE is used by the DefineFont tag, to define character glyphs.
     Shape     
     Field           Type           Comment     
     NumFillBits           NfillBits = UB[4]           Number of fill index bits     
     NumLineBits           NlineBits = UB[4]           Number of line index bits     
     ShapeRecords           ShapeRecord[one or more]           Shape records - see below     
    SwfJava v0.0: how to create a Shape    
    new Shape (    
        ShapeContext shapeContext,    
        ShapeRecord [] shapeRecords    
    );    


    XWF v0.0: how to declare a Shape element    
    <Shape>    
        <edge ... />    
        <edge ... />    
        ...    
    </Shape>    
        
    an edge can be a StyleChange, a StraightEdge, or a CurvedEdge.    



The SHAPEWITHSTYLE structure extends the SHAPE structure by including fill style and line style information. SHAPEWITHSTYLE is used by the DefineShape tag.
     ShapeWithStyle     
     Field           Type           Comment     
     FillStyles           FillStyleArray           Array of fill styles     
     LineStyles           LineStyleArray           Array of line styles     
     NumFillBits           NfillBits = UB[4]           Number of fill index bits     
     NumLineBits           NlineBits = UB[4]           Number of line index bits     
     ShapeRecords           ShapeRecord[one or more]           Shape records - see below     
    SwfJava v0.0: how to create a ShapeWithStyle    
    new ShapeWithStyle (    
        FillStyleArray fillStyles,    
        LineStyleArray lineStyles,    
        ShapeRecord[] shapeRecords    
    );    


Note: The LINESTYLELARRAY and FILLSTYLEARRAY begin at index 1, not index 0.


Shape Tag
This diagram illustrates the SHAPEWITHSTYLE structure.

First, the Fill styles and Line styles are defined. These are defined once only and are referred to by array index.

The blue area represents the array of shape-records.

The first shape-record selects a fill from the fill style array, and moves the drawing position to the start of the shape. This is followed by a series of edge records that define the shape.

The next record changes the fill style, and the subsequent edge-records are filled using this new style.

This tag is a completely autonomous object. The style change records only refer to fill and line styles that have been defined in this tag.

Shape Records

There are four types of shape-record:
  1. End shape record.
  2. Style change record.
  3. Straight edge record.
  4. Curved edge record.
All shape-records begin with a TypeFlag. If the TypeFlag is zero, the shape-record is a non-edge record, and a further five bits of flag information follow.

End Shape Record

The end shape record simply indicates the end of the shape-record array. It is a non-edge record with all five flags equal to zero.
     EndShapeRecord     
     Field           Type           Comment     
     TypeFlag           UB[1] = 0           Non-edge record flag     
     EndOfShape           UB[5] = 0           End of shape flag     
    SwfJava v0.0: how to create a EndShapeRecord    
        
    new EndShapeRecord();    
        


    XWF v0.0: how to declare a EndShape element    
        
    no declaration is necessary for EndShape    
        


Style Change Record

The style change record is also a non-edge record. It can be used to: Because fill and line styles often change at the start of a new path, it is useful to perform more than one action in a single record. For example, say a DefineShape tag defines a red circle and a blue square. After the circle is closed, it is necessary to move the drawing position, and replace the red fill with the blue fill. The style change record can achieve this with a single shape-record.
     StyleChangeRecord     
     Field           Type           Comment     
     TypeFlag           UB[1] = 0           Non-edge record flag     
     StateNewStyles           NewStyles = UB[1]           New styles flag. Used by DefineShape2 and DefineShape3 only.     
     StateLineStyle           LineStyle = UB[1]           Line style change flag     
     StateFillStyle1           FillStyle1 = UB[1]           Fill style 1 change flag     
     StateFillStyle0           FillStyle0 = UB[1]           Fill style 0 change flag     
     StateMoveTo           MoveTo = UB[1]           Move to flag     
     MoveBits           If moveTo nMoveBits = UB[5]           Move bit count     
     MoveDeltaX           If moveTo SB[nMoveBits]           Delta X value     
     MoveDeltaY           If moveTo SB[nMoveBits]           Delta Y value     
     FillStyle0           If fillStyle0 UB[nFillBits]           Fill 0 Style     
     FillStyle1           If fillStyle1 UB[nFillBits]           Fill 1 Style     
     LineStyle           If lineStyle UB[nLineBits]           Line Style     
     FillStyles           If newStyles FillStyleArray           Array of new fill styles     
     LineStyles           If newStyles LineStyleArray           Array of new line styles     
     NumFillBits           If newStyles NfillBits = UB[4]           Number of fill index bits for new styles     
     NumLineBits           If newStyles NlineBits = UB[4]           Number of line index bits for new styles     
    SwfJava v0.0: how to create a StyleChangeRecord    
    new StyleChangeRecord(    
        boolean hasLineStyle, int lineStyle,    
        boolean hasFillStyle0, int fillStyle0,    
        boolean hasFillStyle1, int fillStyle1,    
        boolean hasMoveTo, int x, int y,    
        boolean hasNewStyles,    
            FillStyleArray newFillStyles,    
            LineStyleArray newLineStyles,    
            int newStylesNFillBits, int newStylesNLineBits    
    );    


    XWF v0.0: how to declare a StyleChange tag    
    <StyleChange    
        [lineStyle="(int)"]    
        [fillStyle0="(int)"] [fillStyle1="(int)"]    
    >    
        [<MoveTo x="(int)" y="(int)" />]    
        [<NewStyles>    
            ...    
        </NewStyles>]    
    </StyleChange>    



In the first shape record MoveDeltaX and MoveDeltaY are relative to the shape origin. In subsequent shape-records, MoveDeltaX and MoveDeltaY are relative to the current drawing position.

quoting openswf.org: “MoveX/Y are not deltas from the previous point, they are relative to shape origin.”

The style arrays begin at index 1, not index 0. FillStyle = 1 refers to the first style in the fill style array, FillStyle = 2 refers to the second style in the fill style array, and so on. A fill style index of zero means the path is not filled, and a line style index of zero means the path has no stroke. Initially the fill and line style indices are set to zero – no fill or stroke.

FillStyle0 and FillStyle1

Flash supports two fill styles per edge, one for each side of the edge: FillStyle0 and FillStyle1. For most shapes (those which don’t self-intersect or overlap) FillStyle0 should be used. For overlapping shapes the situation is more complex.

For example, if a shape consisted of two overlapping squares, and only FillStyle0 is defined, the Flash player will render a ‘hole’ where the paths overlap. This area can be filled using FillStyle1. In this situation, the rule is that for any directed vector, FillStyle0 is the color to the left of the vector, and FillStyle1 is the color to the right of the vector. (See diagram below)

Note: FillStyle0 and FillStyle1 should not be confused with FILLSTYLEARRAY indices. FillStyle0 and FillStyle1 are variables that contain indices into the FILLSTYLEARRAY.

FillStyles

See other examples in the Examples Page.

Edge Records

Edge-records have a TypeFlag of 1. There are two types of edge records; straight and curved. The StraightFlag determines the type.

Straight Edge Record

The straight-edge record stores the edge as an X-Y delta. The delta is added to the current drawing position, and this becomes the new drawing position. The edge is rendered between the old and new drawing positions.

Straight-edge records support three types of line:
  1. General lines.
  2. Horizontal lines.
  3. Vertical lines.
General lines store both X & Y deltas, the horizontal and vertical lines store only the X delta and Y delta respectively.
     StraightEdgeRecord     
     Field           Type           Comment     
     TypeFlag           UB[1] = 1           This is an edge record     
     StraightFlag           UB[1] = 1           Straight edge — always 1     
     NumBits           NBits = UB[4] + 2           Number of bits per value     
     GeneralLineFlag           LineFlag = UB[1]           General Line equals 1, Vert/Horz Line equals 0     
     DeltaX           If lineFlag = 1 SB[nBits]           X delta     
     DeltaY           If lineFlag = 1 SB[nBits]           Y delta     
     VertLineFlag           If lineFlag = 0 vertFlag = SB[1]           Vertical Line equals 1, Horizontal Line equals 0     
     DeltaX           If vertFlag = 0 SB[nBits]           X delta     
     DeltaY           If vertFlag = 1 SB[nBits]           Y delta     
    SwfJava v0.0: how to create a StraightEdgeRecord    
    new StraightEdgeRecord(    
        int dx, int dy    
    );    


    XWF v0.0: how to declare a StraightEdge tag    
    <StraightEdge dx="(int)" dy="(int)" />    


Curved Edge Record

Macromedia Flash (SWF) differs from most vector file formats by using Quadratic Bezier curves rather than Cubic Bezier curves. PostScript uses Cubic Beziers, as do most drawing applications, such as Illustrator, FreeHand and Corel Draw. Macromedia Flash (SWF) uses Quadratic Bezier curves because they can be stored more compactly, and can be rendered more efficiently.

Below is a diagram of a Quadratic Bezier curve and a Cubic Bezier curve.

Quadratic Bezier, Cubic Bezier

A Quadratic Bezier curve has 3 points. Two on-curve anchor points, and one off-curve control point.
A Cubic Bezier curve has 4 points. Two on-curve anchor points, and two off-curve control points.

The curved-edge record stores the edge as two X-Y deltas. The three points that define the Quadratic Bezier are calculated like this: The last anchor point becomes the current drawing position.
     CurvedEdgeRecord     
     Field           Type           Comment     
     TypeFlag           UB[1] = 1           This is an edge record     
     StraightFlag           UB[1] = 0           Curved edge — always 0     
     NumBits           NBits = UB[4] + 2           Number of bits per value     
     ControlDeltaX           SB[nBits]           X control point change     
     ControlDeltaY           SB[nBits]           Y control point change     
     AnchorDeltaX           SB[nBits]           X anchor point change     
     AnchorDeltaY           SB[nBits]           Y anchor point change     
    SwfJava v0.0: how to create a CurvedEdgeRecord    
    new CurvedEdgeRecord(    
        int cx, int cy,    
        int ax, int ay    
    );    


    XWF v0.0: how to declare a CurvedEdge tag    
    <CurvedEdge cx="(int)" cy="(int)" ax="(int)" ay="(int)" />    


Converting between Quadratic and Cubic Bezier curves

A Quadratic Bezier curve can be represented exactly by a Cubic Bezier curve, since you are going from a 2nd order curve to a 3rd order curve. The conversion is fairly straightforward.

For a discussion of how to convert Quadratic Bezier curves to Cubic Bezier curves see: http://www.icce.rug.nl/erikjan/bluefuzz/beziers/beziers/node2.html


A Cubic Bezier curve can be only be approximated with a Quadratic Bezier curve, since you are going from a 3rd order curve to a 2nd order curve. This involves recursive subdivision of the curve, until the cubic curve and the quadratic equivalent are matched within some arbitrary tolerance.

For a discussion of how to approximate Cubic Bezier curves with Quadratic Bezier curves see: http://www.research.microsoft.com/ hollasch/cgindex/curves/cbez-quadspline.html http://fonts.apple.com/TTRefMan/RM08/appendixE.html

DefineShape

The DefineShape tag defines a shape for later use by control tags such as PlaceObject. The ShapeId uniquely identifies this shape as ‘character’ in the Dictionary. The ShapeBounds field is the rectangle that completely encloses the shape. The SHAPEWITHSTYLE structure includes all the paths, fill styles and line styles that make up the shape.
     DefineShape     
     Field           Type           Comment     
     Header           RECORDHEADER           Tag ID = 2     
     ShapeID           UI16           ID for this character     
     ShapeBounds           RECT           Bounds of the shape     
     Shapes           ShapeWithStyle           Shape information     
    SwfJava v0.0: how to create a DefineShape    
    new DefineShape(    
        int shapeID,    
        Rect shapeBounds,    
        ShapeWithStyle styles    
    );    


    XWF v0.0: how to declare a DefineShape tag    
    <DefineShape id="(int)" >    
        [<FillStyleArray ... >]    
        [<LineStyleArray ... >]    
        <edge ... />    
        <edge ... />    
        ...    
    </DefineShape>    
        
    an edge can be a StyleChange, a StraightEdge, or a CurvedEdge.    


DefineShape2

Extends the capabilities of DefineShape with the ability to support more than 255 styles in the style list and multiple style lists in a single shape. (Macromedia Flash (SWF) 2)
     DefineShape2     
     Field           Type           Comment     
     Header           RECORDHEADER           Tag ID = 22     
     ShapeID           UI16           ID for this character     
     ShapeBounds           RECT           Bounds of the shape     
     Shapes           ShapeWithStyle           Shape information     
    SwfJava v0.0: how to create a DefineShape2    
    new DefineShape2(    
        int shapeID,    
        Rect shapeBounds,    
        ShapeWithStyle styles    
    );    
        


    XWF v0.0: how to declare a DefineShape2 tag    
    <DefineShape2 id="(int)" >    
        [<FillStyleArray ... >]    
        [<LineStyleArray ... >]    
        <edge ... />    
        <edge ... />    
        ...    
    </DefineShape2>    
        
    an edge can be a StyleChange, a StraightEdge, or a CurvedEdge.    


DefineShape3

Extends the capabilities of DefineShape2 by extending all of the RGB color fields to support RGBA with alpha transparency. (Macromedia Flash (SWF) 3)
     DefineShape3     
     Field           Type           Comment     
     Header           RECORDHEADER           Tag ID = 32     
     ShapeID           UI16           ID for this character     
     ShapeBounds           RECT           Bounds of the shape     
     Shapes           ShapeWithStyle           Shape information     
    SwfJava v0.0: how to create a DefineShape3    
    new DefineShape3(    
        int shapeID,    
        Rect shapeBounds,    
        ShapeWithStyle styles    
    );    


    XWF v0.0: how to declare a DefineShape3 tag    
    <DefineShape3 id="(int)" >    
        [<FillStyleArray ... >]    
        [<LineStyleArray ... >]    
        <edge ... />    
        <edge ... />    
        ...    
    </DefineShape3>    
        
    an edge can be a StyleChange, a StraightEdge, or a CurvedEdge.    


Introduction Basic Types Display List Control Tags
Shapes (Examples Shapes) Gradients Buttons
Sprites Fonts and Text Shape Morphing Bitmap
Sounds Actions ActionScripts Reference