Made to Order Software Corporation Logo

SWF

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 Fill Style Array (swf_fill_style_array)

SWF Structure Info
Tag Flash Version: 
1
SWF Structure: 
struct swf_fill_style_array {
	unsigned char		f_count;
	if(f_tag != DefineShape && f_count == 255) {
		unsigned short	f_real_count;
	}
	else {
		f_real_count = f_count;
	}
	swf_fill_style		f_fill_style[f_real_count];
};

The array of fill styles starts with a counter. When DefineShape is used, the counter can be any value from 0 (no style) to 255. When DefineShape2 or DefineShape3 are used, the value 255 is reserved so you can declare more than 255 styles.

SWF Styles Count (swf_styles_count)

SWF Structure Info
Tag Flash Version: 
1
SWF Structure: 
struct swf_styles {1
	unsigned char		f_fill_bits_count : 4;
	unsigned char		f_line_bits_count : 4;
};
  • 1. Since always aligned, you can read one byte and mask/shift bits quickly on this one.

Note that the line & fill bits are declared as "unsigned char" because they will always be aligned. The proper definition would probably be a bit field though.

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!

SWF Shape with Style (swf_shape_with_style)

SWF Structure Info
Tag Flash Version: 
1
SWF Structure: 
struct swf_shape {
	swf_styles_count	f_styles_count;
	swf_shape_record	f_shape_records[variable];
};

The array of shape records starts with a set of style definitions and is followed by shape records. The last record is marked by a null record.

SWF Morph Shape with Style (swf_morph_shape_with_style)

SWF Structure Info
Tag Flash Version: 
1
SWF Structure: 
struct swf_morph_shape_with_style {
	swf_styles		f_styles;
	swf_shape_record	f_shape_records[variable];
	char align;
	swf_styles_count	f_styles_count;
	swf_shape_record	f_shape_records_morph[variable];
};

The array of shape records starts with a set of styles definition and is followed by shape records. The list of shape records ends with a null record.

Note that f_shape_records_morph cannot include any reference to styles and lines, nor include new styles. It is likely that the f_styles_count will always be 0x11. Also, it is always byte aligned.

SWF Shape (swf_shape)

SWF Structure Info
Tag Flash Version: 
1
SWF Structure: 
struct swf_shape {
	swf_styles_count	f_styles_count;
	swf_shape_record	f_shape_records[variable];
};

Fonts uses this declaration. It does not include any style (fill or line) definitions. The drawing will use fill 0 when the inside of the shape should not be drawn and 1 when it is to be filled. The line style should not be defined.

SWF Kerning (swf_kerning)

SWF Structure Info
Tag Flash Version: 
1
SWF Structure: 
struct swf_kerning {
	if(f_font2_wide) {
		unsigned short		f_kerning_code1;
		unsigned short		f_kerning_code2;
	}
	else {
		unsigned char		f_kerning_code1;
		unsigned char		f_kerning_code2;
	}
	signed short		f_kerning_adjustment;
};

The following table defines the number of TWIPs to move left or right before to draw the 2nd character when the 1st one was drawn right before it. For instance, the letters AV may be drawn really close so the V is written over the A. To the contrary, WI may be seperated some more so the I doesn't get merged to the top of the W.

The computation to move the drawing pen is done as follow:

SWF ARGB (swf_argb)

SWF Structure Info
Tag Flash Version: 
1
SWF Structure: 
struct swf_argb {
	unsigned char		f_alpha;1
	unsigned char		f_red;
	unsigned char		f_green;
	unsigned char		f_blue;
};
  • 1. 0 represents a fully transparent color, 255 represents a solid color.

The color components can be set to any value from 0 (no intensity) to maximum intensity (255).1

It is important to note that even fully transparent pixels may not have their red, green, blue components set to 0. This is useful if you want to add a value to the alpha channel using one of the color transformation matrices. In that case, using all 0's would generate a black color.

  • 1. For some PNG images, the red, green and blue colors may need to be multiplied by their alpha channel value before saved. Use the following formula to compute the proper values:

       f_red = orginal red * f_alpha / 255

This format was added to be mostly compatible with the old PNG format (XRGB).