Shapes

Shapes Contents

Shapes Contents.................................................................................................................................................. 1

Shapes......................................................................................................................................................................... 1

Shape Overview..................................................................................................................................................... 2

An Example Shape................................................................................................................................................. 3

Fill Styles............................................................................................................................................................... 4

Line Styles............................................................................................................................................................. 4

Shape structures..................................................................................................................................................... 5

Shape Records........................................................................................................................................................ 6

End Shape Record.................................................................................................................................................. 6

Style Change Record.............................................................................................................................................. 6

FillStyle0 and FillStyle1........................................................................................................................................ 7

Edge Records.......................................................................................................................................................... 8

Straight Edge Record.............................................................................................................................................. 8

Curved Edge Record............................................................................................................................................... 9

Converting between Quadratic and Cubic Bezier curves..................................................................................... 10

DefineShape......................................................................................................................................................... 10

DefineShape2....................................................................................................................................................... 10

DefineShape3....................................................................................................................................................... 11

SDK Examples....................................................................................................................................................... 11

 

Shapes

 

The 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 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.  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:

 

·         CharacterId — A 16-bit value that uniquely identifies this shape as a ‘character’ in the dictionary.  The CharacterId can be referred to in control tags such as PlaceObject.  Characters can be re-used and combined with other characters to make more complex shapes.

·         Bounding box — The rectangle that completely encloses the shape.

·         Fill style array — A list of all the fill styles used in a shape.

·         Line style array — A list of all the line styles used in a shape.

·         Shape-record array — A list of shape-records.  Shape-records can define straight or curved edges, style changes, or move the drawing position.

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

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 SWF:

 

·         First, the fill styles are defined with a FILLSTYLEARRAY.  The two unique fill styles are solid red and solid green.

·         This is followed by a LINESTYLEARRAY that includes the two unique line styles; 1-pixel black, and 2-pixel black .

·         This is followed by an array of SHAPERECORDs.

 

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:

 

·         The first shape-record selects the 2-pixel wide line style, and moves the drawing position to the top of the curved line by setting the MoveTo flag.

·         The next shape-record is a curved edge, which ends to the bottom of the line.  The path is not closed.

 

Now we define the red square:

 

·         The next shape-record selects the 1-pixel line style and the red fill style.  It also moves the drawing position to the top-left corner of the red rectangle.

·         The following four shape-records are straight edges.  The last edge must end at the top-left corner.  Flash requires that closed figures be joined explicitly.  That is, the first and last points must be co-incident.

 

Now we define the red circle:

 

·         The next shape-record does not change any style settings, but moves the drawing position to the top of the red circle.

·         The following eight shape-records are curved edges that define the circle.  Again, the path must finish where it started.

 

Now we define the green rounded-rectangle:

 

·         The next shape-record selects the 2-pixel wide line style, and the green fill.  It also moves the drawing position to the top-left of the rounded-rectangle.

·         The following twelve shape-records are a mixture of straight shape-records (the sides) interspersed with curved shape-records (the rounded corners).  The path finishes where it began.

Fill Styles

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:

(See class FFillStyleArray in the Flash File Format SDK)

 

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

 

The format of a fill style value within the file is described in the following table:

(See class FFillStyle in the Flash File Format SDK)

 

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

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:

(See class FLineStyleArray in the Flash File Format SDK)

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

 

 

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:

(See class FLineStyle in the Flash File Format SDK)

 

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

 

Notes:

 

1.        All lines in 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.        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.

 

(See class FShape in the Flash File Format SDK)

 

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

 

The SHAPEWITHSTYLE structure extends the SHAPE structure by including fill style and line style information.  SHAPEWITHSTYLE is used by the DefineShape tag.

 

(See class FShapeWStyle in the Flash File Format SDK)

 

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

 

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


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.

 

(See class FShapeRecEnd in the Flash File Format SDK)

 

ENDSHAPERECORD

Field

Type

Comment

TypeFlag

UB[1] = 0

Non-edge record flag

EndOfShape

UB[5] = 0

End of shape flag

 

Style Change Record

The style change record is also a non-edge record.  It can be used to:

 

·         Select a fill or line style for drawing

·         Move the current drawing position (without drawing)

·         Replace the current fill and line style arrays with a new set of styles

 

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.

 

(See class FShapeRecChange in the Flash File Format SDK)

 

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

 

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.

 

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.

 

 

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.

 

(See class FShapeRecEdgeStraight in the Flash File Format SDK)

 

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

 

Curved Edge Record

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.  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.

 

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 first anchor point is the current drawing position.

·         The control point is the current drawing position + ControlDelta.

·         The last anchor point is the current drawing position + ControlDelta + AnchorDelta.

 

The last anchor point becomes the current drawing position.

 

(See class FShapeRecEdgeCurved in the Flash File Format SDK)

 

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

 

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.

 

(See class FDTDefineShape in the Flash File Format SDK)

 

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

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. (SWF 2.0)

 

(See class FDTDefineShape2 in the Flash File Format SDK)

 

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

DefineShape3

Extends the capabilities of DefineShape2 by extending all of the RGB color fields to support RGBA with alpha transparency. (SWF 3.0)

 

(See class FDTDefineShape3 in the Flash File Format SDK)

 

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

 

SDK Examples

 

The SDK contains C++ examples that demonstrate how to create shapes in SWF.

 

The low-level examples are:

 

·         FExampleRectangle.cpp creates a rectangle from straight edge records.

·         FExampleCircle.cpp creates a circle from curved edge records.

·         FExampleOval.cpp creates an oval (or ellipse) from curved edge records.

 

The high-level examples are:

 

·         HFExampleRectangle.cpp creates three rectangles by specifying the origin and size of each rectangle.

·         HFExampleCircle.cpp creates two circles by specifying center and radius.

·         HFExampleOval.cpp creates an oval by specifying the bounding-box of the oval.