Made to Order Software Corporation Logo

structure

SWF Any Filter (swf_any_filter)

SWF Structure Info
Tag Flash Version: 
8
SWF Structure: 
/* the filter type */
struct swf_filter_type {
	unsigned char	f_type;
};

struct swf_filter_glow {
	swf_filter_type	f_type;		/* 0, 2, 3, 4 or 7 */
	if(f_type == GradientGlow || f_type == GradientBevel) {
		unsigned char		f_count;
	}
	else {
		f_count = 1;
	}
	swf_rgba		f_rgba[f_count];
	if(f_type == Bevel) {
		swf_rgba		f_highlight_rgba[f_count];
	}
	if(f_type == GradientGlow || f_type == GradientBevel) {
		unsigned char		f_position[f_count];
	}
	signed long fixed	f_blur_horizontal;
	signed long fixed	f_blur_vertical;
	if(f_type != Glow) {
		signed long fixed	f_radian_angle;
		signed long fixed	f_distance;
	}
	signed short fixed	f_strength;
	unsigned		f_inner_shadow : 1;
	unsigned		f_knock_out : 1;
	unsigned		f_composite_source : 1;
	if(f_type == Bevel) {
		unsigned		f_on_top : 1;
	}
	else {
		unsigned		f_reserved : 1;
	}
	if(f_type == GradientGlow || f_type == GradientBevel) {
		unsigned		f_passes : 4;
	}
	else {
		unsigned		f_reserved : 4;
	}
};

struct swf_filter_blur {
	swf_filter_type		f_type;	/* 1 */
	unsigned long fixed	f_blur_horizontal;
	unsigned long fixed	f_blur_vertical;
	unsigned		f_passes : 5;
	unsigned		f_reserved : 3;
};

struct swf_filter_convolution {
	swf_filter_type	f_type;		/* 5 */
	unsigned char	f_columns;
	unsigned char	f_rows;
	long float	f_divisor;
	long float	f_bias;
	long float	f_weights[f_columns × f_rows];
	swf_rgba	f_default_color;
	unsigned	f_reserved : 6;
	unsigned	f_clamp : 1;
	unsigned	f_preserve_alpha : 1;
};

struct swf_filter_colormatrix {
	swf_filter_type	f_type;		/* 6 */
	long float	f_matrix[20];
};

struct swf_any_filter {
	swf_filter_type			f_fitler_type;
	swf_filter_blur			f_filter_blur;
	swf_filter_colormatrix		f_filter_colormatrix;
	swf_filter_convolution		f_filter_convolution;
	swf_filter_glow			f_filter_glow;
};

A filter defines how to transform the objects it is attached to. The first byte is the filter type. The data following depend on the type. Because each filter is much different, they are defined in separate structures. You can attach a filter to an object using an ActionScript or the PlaceObject3 tag.

The following describes the different filters available since version 8.

SWF Gradient (swf_gradient)

SWF Structure Info
Tag Flash Version: 
3
SWF Structure: 
struct swf_gradient {
	if(tag == DefineShape4) {
		unsigned		f_spread_mode : 2;
		unsigned		f_interpolation_mode : 2;
		unsigned		f_count : 4;
	}
	else {
		unsigned		f_pad : 4;
		unsigned		f_count : 4;
	}
	swf_gradient_record	f_gradient_record[f_count];
	/* f_type is defined in the swf_fill_style encompassing this gradient */
	if(f_type == 0x13) {
		signed short fixed	f_focal_point;
	}
};

This structure defines a gradient. This is a set of colors which are used to define an image with colors smoothly varying from one color to the next. The gradient can be radial (circular) or linear (rectangular).

The f_count field is limited depending on the tag used and the version of SWF as defined below:

SWF Text Entry (swf_text_entry)

SWF Structure Info
Tag Flash Version: 
1
SWF Structure: 
struct swf_text_entry {
	unsigned		f_glyph_index : f_glyph_bits;
	signed			f_advance : f_advance_bits;
};

The swf_text_entry structure defines a list of characters and the number of TWIPs to skip to go to the next character. Note that f_advance is a signed value. Thus you can write characters from right to left which is useful to write characters in languages such as Arabic in a native way. The number of bits used to define each field of this structure is defined in the DefineText or DefineText2 tags.

SWF Text Record (swf_text_record)

SWF Structure Info
Tag Flash Version: 
1
SWF Structure: 
struct swf_text_record_end {
	unsigned		f_end : 8;	/* all zeroes */
};

struct swf_text_record_setup {
	unsigned		f_type_setup : 1;	/* always one */
	unsigned		f_reserved : 3;
	unsigned		f_has_font : 1;
	unsigned		f_has_color : 1;
	unsigned		f_has_move_y : 1;
	unsigned		f_has_move_x : 1;
	if(f_has_font) {
		unsigned short		f_font_id_ref;
	}
	if(f_has_color) {
		if(tag == DefineText) {
			swf_rgb		f_color;
		}
		else {	/* if tag is DefineText2 */
			swf_rgba	f_color;
		}
	}
	if(f_has_move_x) {
		signed short		f_move_x;
	}
	if(f_has_move_y) {
		signed short		f_move_y;
	}
	if(f_has_font) {
		unsigned short		f_font_height;
	}
};

struct swf_text_record_glyphs {
	unsigned		f_type_glyph : 1;		/* always zero */
	unsigned		f_glyph_count : 7;		/* at least one */
	swf_text_entry		f_entry[f_glyph_count];
};

struct swf_text_record_string {
	unsigned		f_type_setup : 1;	/* always one */
	unsigned		f_reserved : 3;
	unsigned		f_has_font : 1;
	unsigned		f_has_color : 1;
	unsigned		f_has_move_y : 1;
	unsigned		f_has_move_x : 1;
	if(f_has_font) {
		unsigned short		f_font_id_ref;
	}
	if(f_has_color) {
		if(tag == DefineText) {
			swf_rgb		f_color;
		}
		else {	/* if tag is DefineText2 */
			swf_rgba	f_color;
		}
	}
	if(f_has_move_x) {
		signed short		f_move_x;
	}
	if(f_has_move_y) {
		signed short		f_move_y;
	}
	if(f_has_font) {
		unsigned short		f_font_height;
	}
	unsigned char		f_glyph_count;		/* at least one */
	swf_text_entry		f_entry[f_glyph_count];
};

union swf_text_record {
	unsigned		f_flags : 8;
	swf_text_record_end	f_end;
	if(version >= 7) {
		swf_text_record_string	f_string;
	}
	else {
		swf_text_record_setup	f_setup;
		swf_text_record_glyphs	f_glyphs;
	}
};

The swf_text_record structure is a union composed of a swf_text_record_setup definition followed by characters. Multiple records can follow each others. The list is ended with one byte set to 0.

WARNING: it seems that Macromedia didn't think about a file having two records of type glyph one after another (it makes their plugins crash); you will have to insert a setup record between each glyph record (the setup can be empty: i.e. add one byte equal to 0x80). The very first setup has to at least define the font.

NOTE: this has been corrected by Macromedia it now shows as one structure ...

SWF Fill Style (swf_fill_style)

SWF Structure Info
Tag Flash Version: 
1
SWF Structure: 
/* f_type = 0x00 - solid fill */
struct swf_fill_style_solid {
	unsigned char		f_type;
	if(f_tag == DefineMorphShape || f_tag == DefineMorphShape2) {
		swf_rgba	f_rgba;
		swf_rgba	f_rgba_morph;
	}
	else if(f_tag == DefineShape3) {
		swf_rgba	f_rgba;
	}
	else {
		swf_rgb		f_rgb;
	}
};

/* f_type = 0x10 - linear gradient fill,
	    0x12 - radial gradient fill
	    0x13 - focal gradient fill (V8.0) */
struct swf_fill_style_gradient {
	unsigned char		f_type;
	swf_matrix			f_gradient_matrix;
	if(f_tag == DefineMorphShape || f_tag == DefineMorphShape2) {
		swf_matrix	f_gradient_matrix_morph;
	}
	swf_gradient		f_gradient;
};

/* f_type = 0x40 - tilled bitmap fill with smoothed edges,
	    0x41 - clipped bitmap fill with smoothed edges,
	    0x42 - tilled bitmap fill with hard edges (V7.0)1,
	    0x43 - clipped bitmap fill with hard edges (V7.0)2 */
struct swf_fill_style_bitmap {
	unsigned char		f_type;
	unsigned short		f_bitmap_ref;
	swf_matrix		f_bitmap_matrix;
	if(f_tag == DefineMorphShape || f_tag == DefineMorphShape2) {
		swf_matrix	f_bitmap_matrix_morph;
	}
};

union swf_fill_style {
	unsigned char		f_type;
	swf_fill_style_solid	f_solid;
	swf_fill_style_gradient	f_gradient;
	swf_fill_style_bitmap	f_bitmap;
};
  • 1. See description for more info.
  • 2. See description for more info.

The fill style is defined in the first byte. The values are defined below. Depending on that value, the fill style structure changes as shown below. swf_fill_style is a union of all the other structures.

Notice that types 0x42 and 0x43 are only available since version 7 and type 0x13 is only available since version 8.

Note that these values were introduced in Flash 7 but it looks like only player 8 supported the distinction between hard edges and smooth edges on a per shape basis. That would explain why I could not see any difference between smooth and hard shapes when I tested this feature ...

SWF Styles (swf_styles)

SWF Structure Info
Tag Flash Version: 
1
SWF Structure: 
struct swf_styles {
	swf_fill_style_array	f_fill_styles;
	swf_line_style_array	f_line_styles;
	swf_styles_count	f_styles_count;
};

This structure is found in the shape with style and change style structures.

SWF Shape Record (swf_shape_record)

SWF Structure Info
Tag Flash Version: 
1
SWF Structure: 
/* if f_shape_record_type = 0 & f_end_of_shape = 0
then that's the end of the list of shape records */
struct swf_shape_record_end { unsigned f_shape_record_type : 1; unsigned f_end_of_shape : 5; };
/* f_shape_record_type = 0 & at least one of the following five bits is not zero
then change style, fill and position setup */
struct swf_shape_record_setup { unsigned f_shape_record_type : 1; if(f_tag == DefineShape) {1 unsigned f_shape_reserved : 1; /* always zero */ } else { unsigned f_shape_has_new_styles : 1; } unsigned f_shape_has_line_style : 1; unsigned f_shape_has_fill_style1 : 1; unsigned f_shape_has_fill_style0 : 1; unsigned f_shape_has_move_to : 1; if(f_shape_has_move_to) { unsigned f_shape_move_size : 5; signed twips f_shape_move_x : f_shape_move_size; signed twips f_shape_move_y : f_shape_move_size; } if(f_shape_has_fill_style0) { unsigned f_shape_fill_style0 : f_fill_bits_count; } if(f_shape_has_fill_style1) { unsigned f_shape_fill_style1 : f_fill_bits_count; } if(f_shape_has_line_style) { unsigned f_shape_line_style : f_line_bits_count; } if(f_shape_has_new_styles) { swf_styles f_styles; } }; /* f_shape_record_type = 1 -- edge record */ struct swf_shape_record_edge { unsigned f_shape_record_type : 1; unsigned f_shape_edge_type : 1; unsigned f_shape_coord_size : 4; f_shape_coord_real_size = f_shape_coord_size + 2; if(f_shape_edge_type == 0) { signed twips f_shape_control_delta_x : f_shape_coord_real_size; signed twips f_shape_control_delta_y : f_shape_coord_real_size; signed twips f_shape_anchor_delta_x : f_shape_coord_real_size; signed twips f_shape_anchor_delta_y : f_shape_coord_real_size; } else { unsigned f_shape_line_has_x_and_y : 1; if(f_shape_line_has_x_and_y == 1) { signed twips f_shape_delta_x : f_shape_coord_real_size; signed twips f_shape_delta_y : f_shape_coord_real_size; } else { unsigned f_shape_line_has_x_or_y : 1; if(f_shape_line_has_x_or_y == 0) { signed twips f_shape_delta_x : f_shape_coord_real_size; } else { signed twips f_shape_delta_y : f_shape_coord_real_size; } } } }; union swf_shape_record { swf_shape_record_end f_shape_end; swf_shape_record_setup f_shape_setup; swf_shape_record_edge f_shape_edge; };
  • 1. From my tests with the official Macromedia Flash plugin, it looks that there is always a bit at this position. It seems however that it cannot be set to 1 in v1.0 of the tag (i.e. when the DefineShape tag is used).

The shape records are typed. Depending on that type, the contents vary. The following defines one structure for each type. The shape record is a union of these structures.

It is important to note that the f_shape_move_x and f_shape_move_y are not deltas from the current point, but a position from the current shape origin. All the other positions are defined as deltas from the previous position, including the anchors which are deltas from the control point position!

PlaceObject2

Tag Info
Tag Number: 
26
Tag Type: 
Define
Tag Flash Version: 
3
Brief Description: 

Place, replace, remove an object in the current display list.

Tag Structure: 
struct swf_placeobject2 {	/* and swf_placeobject3 */
	swf_tag			f_tag;		/* 26 or 70 */
	/* NOTE: the following flags can be read as one or two bytes also */
	if(version >= 8) {
		unsigned	f_place_reserved : 5;
		unsigned	f_place_bitmap_caching : 1;
		unsigned	f_place_blend_mode : 1;
		unsigned	f_place_filters : 1;
	}
	if(version >= 5) {
		unsigned	f_place_has_actions : 1;
	}
	else {
		unsigned	f_place_reserved : 1;
	}
	unsigned		f_place_has_clipping_depth : 1;
	unsigned		f_place_has_name : 1;
	unsigned		f_place_has_morph_position : 1;
	unsigned		f_place_has_color_transform : 1;
	unsigned		f_place_has_matrix : 1;
	unsigned		f_place_has_id_ref : 1;
	unsigned		f_place_has_move : 1;
	unsigned short		f_depth;
	if(f_place_has_id_ref) {
		unsigned short		f_object_id_ref;
	}
	if(f_place_has_matrix) {
		swf_matrix		f_matrix;
	}
	if(f_place_has_color_transform) {
		swf_color_transform	f_color_transform;
	}
	if(f_place_has_morph_position) {
		unsigned short		f_morph_position;
	}
	if(f_place_has_name) {
		string			f_name;1
	}
	if(f_place_has_clipping_depth) {
		unsigned short		f_clipping_depth;
	}
	/* 3 next entries since v8.0 */
	if(f_place_filters) {
		unsigned char		f_filter_count;
		swf_any_filter		f_filter;
	}
	if(f_place_blend_mode) {
		unsigned char		f_blend_mode;
	}
	if(f_place_bitmap_caching) {
		/* WARNING: this is not defined in the Macromedia documentation
		 * it may be that it was part of the blend mode whenever the person
		 * who defined this byte was testing (I copied that from somewhere else!).
		 */
		unsigned char		f_bitmap_caching;
	}
	/* since v5.0 */
	if(f_place_has_actions) {
		unsigned short		f_reserved;
		if(version >= 6) {
			unsigned long	f_all_flags;
		}
		else {
			unsigned short	f_all_flags;
		}
		swf_event		f_event[<variable>];
		if(version >= 6) {
			unsigned long	f_end;	/* always zero */
		}
		else {
			unsigned short	f_end;	/* always zero */
		}
	}
};
  • 1. Assuming that this PlaceObject2 references a DefineSprite, this name becomes the name of this instance of the sprite. This feature enables you to place the same DefineSprite multiple times in your display list each time using a different name.

This tag will be used to specify where and how to place an object in the next frame. The PlaceObject is much different and is presented separately.

The f_depth field is used to indicate at which depth the character is inserted in the current frame. There can be only one object per depth value (thus a maximum of 65536 objects can appear on a single frame).

The f_place_has_move and f_place_has_id_ref flags are used to indicate what to do at the given depth. The following table presents what happens depending on the current value.

f_place_has_move ...

SoundStreamBlock

Tag Info
Tag Number: 
19
Tag Type: 
Define
Tag Flash Version: 
2
Brief Description: 

A block of sound data (i.e. audio samples.) The size of this block of data is defined in the previous SoundStreamHead tag. It is used to download sound samples on a per frame basis instead of all at once.

Tag Structure: 
struct swf_soundstreamblock {
	swf_long_tag		f_tag;		/* 19 */
	unsigned char		f_sound_data[variable size];
};

The SoundStreamBlock tag defines the data of a sound effect previously defined with a SoundStreamHead or a SoundStreamHead2 tag.

WARNING: This tag requires you to save the swf_tag structure in long format whatever the size of the data (i.e. f_tag_and_size & 0x3F == 0x3F always true even if the size is 62 or less.)

The data depends on the SoundStreamHead[2] definition and is variable in size. Please, see the DefineSound tag for more information about sound data.

DefineButtonSound

Tag Info
Tag Number: 
17
Tag Type: 
Define
Tag Flash Version: 
2
Brief Description: 

Defines how to play a sound effect for when an event occurs on the referenced button.

Tag Structure: 
enum {
	DEFINE_BUTTON_SOUND_CONDITION_POINTER_LEAVE = 0,
	DEFINE_BUTTON_SOUND_CONDITION_POINTER_ENTER = 1,
	DEFINE_BUTTON_SOUND_CONDITION_POINTER_PUSH = 2,
	DEFINE_BUTTON_SOUND_CONDITION_POINTER_RELEASE_INSIDE = 3,
	DEFINE_BUTTON_SOUND_CONDITION_MAX = 4
};

struct swf_definebuttonsound {
	swf_tag			f_tag;		/* 17 */
	unsigned short		f_button_id_ref;
	swf_sound_info		f_button_sound_condition[DEFINE_BUTTON_SOUND_CONDITION_MAX];
};

The DefineButtonSound can be used to emit a sound when an event occur on the specified button. It is likely better to use sprites that you display using actions than to use this tag. You will have access to more events and conditions, plus this tag always includes four sound effect references.

The f_button_id_ref is a reference to the button given sound effects.