主题:[原创]swf文件的数据结构以及转为exe或从exe中剥离出swf的代码
swf文件的数据结构以及转为exe或从exe中剥离出swf的源代码
SWF文件是由一个文件头,以及一系列的标签组成的。标签类型有两种:定义型标签和控制型标签。定义型标签把所有物体定义成一个个角色,这些角色存在字典里面。控制型标签操作这些角色,并且控制影片的流程。
swf 的长度单位使用twips(缇),1像素=20缇,这样,分数的像素可以使用整数的缇表示。
swf 的字符串是以00结束的byte序列,采用utf-8编码。
下面介绍swf文件的数据结构。
一、文件头
文件头的结构见表1。
表1:SWF文件头
---------------------------------------------------------------------------
字段 字节数 说明
---------------------------------------------------------------------------
标识符 3 “FWS”或“CWS”的ascii码
版本号 1 版本,例如:1表示swf1,6表示swf6
文件长度 4 长整形,文件的字节数,低位在前
帧大小 RECT结构 SWF场景的大小,单位为twip(缇,1缇=1/20像素,与VB不同)
帧速度 2 以8.8表示的浮点数(也有文章说这是一个整形数),默认=000C
帧数 2 整形,影片总帧数,低位在前
---------------------------------------------------------------------------
说明:
1.文件头以标识符开始,不是“FWS”就是“CWS”。FWS表示该文件未压缩;CWS 表示文件从 RECT 字段开始(第 9 个字节开始)至文件结尾的所有内容,都是使用开放标准 ZLIB 压缩过的(CWS 是在 SWF6 以后才被使用的。对其解压缩可以使用 zlib1.dll 中提供的 uncompress)。本文的所有数据结构分析都是针对“FWS”的,因为“CWS”压缩过的数据看起来面目全非,没法进行分析。
2.文件长度字段,如果是 FWS,该字段表示包括文件头在内的整个文件的准确大小;如果是 CWS,该字段表示解压后文件的大小(不包括前 8 个字节),而不是实际文件的大小,。这样做的目的是让解压后的大小可见,可以使解压过程更加有效。
3.帧大小字段表示影片的宽度和高度.它是一个 RECT 结构,根据 4 个点的坐标可计算出宽高,其结构见表2。
4.帧速率表示理想的每秒播放帧数,如果 SWF 文件包含声音流数据,或者 CPU 速度慢,这个速率是不能保证的。这 2 个字节中,前字节表示小数,后字节表示整数,不过一般极少有小数位的帧速率,所以一般我们只计算整数就可以了,如:00 0C,表示每秒 12 帧。
表2:RECT是使用bit-pack的数据结构
---------------------------------------------------
字段 类型 说明
---------------------------------------------------
Nbits UB(5) 指定后面每个字段各占二进制的几位
Xmin SB(Nbits) x最小值,一般=0
Xmax SB(Nbits) x最大值,即影片宽度
Ymin SB(Nbits) y最小值,一般=0
Ymax SB(Nbits) y最大值,即影片高度
---------------------------------------------------
说明:
1.RECT字段是采用 swf 文件格式规范中定义的“位值”(bit_value)进行存储的,其特点是不管字节区分,按照最小位数(bits)将值连续存储,在末字节中空位补0。比如两个用 9 位表示的无符号值7、8 将占用 3 个字节,表示为二进制就是:00000011 10000010 00000000,将 3 个字节按位连在一起,前 9 位值为7,再 9 位值为8,在第 3 个字节的其他空位全部补0。
2.Nbits字段使用整个结构的前5位来指定后面4个字段各占二进制的几位。例如:
78 00 05 5F 00 00 0F A0 00
换成二进制:
01111000 00000000 00000101 01011111 00000000 00000000 00001111 10100000 00000000
先取前5位转换为10进制:01111=15,这就是说,后面的4个字段,各占用15位,共15×4+5=65位,需要9个字节,72-65=7,后面有7个空闲位。划分如下:
01111 000000000000000 010101011111000 000000000000000 001111101000000 0000000
然后我们可以算出
Xmin = (000000000000000)2=(0)10
Xmax = (010101011111000)2=(11000)10
Ymin = (000000000000000)2=(0)10
Ymax = (001111101000000)2=(8000)10
所以,影片的宽高是11000×8000缇,换算成像素是:550×400
关于影片宽、高的计算,笔者编写了一段代码,见文后的“附”。
二、标签
在文件头后面的是一些标签化的数据块。所有的标签都是用一种通用格式。所以任何程序在解析一个 SWF文件时,都可以跳过那些还不明确的标签。在每个标签中的数据可以指向这个标签中的偏移量,但绝不能指向另外一个标签的偏移量。这样,在用工具处理 SWF 文件的时候就任意可以删除、插入和修改,而 SWF 文件不会被破坏。这种方式保证了版本的兼容性,即使出现了新的标签类型,老版本的播放器还是能够解析完整个 swf 文件而不出现错误,大不了就是不能提供新的功能而已。
每个标签都由标签头和数据体两部分组成。标签头包括标签类型和标签长度。标签头格式有两种:短型和长型。短型由 2 字节构成,长型由 6 字节构成。短型标签头用于数据体不超过 62 字节的标签;长型标签头则用于数据体在 4G 之内的任何标签中。
标签头格式见表3和表4。
表3:标签头(短型)
----------------------
字段 占位 说明
----------------------
标签类型 10 高10位
标签长度 6 低6位
数据体 ≤62字节
----------------------
说明:
1.标签头是一个 2 字节的整形数(低位在前高位在后),例如标签头数据为44 11,那么:“44 11”→“11 44”=“00010001 01000100”,高10位是(0001000101)2=(69)10,低6位是(000100)2=(4)10。查询swf文件中的tag值和action值,可以知道标签类型码=69的是FileAttribute标签。低6位的值4表示标签长度为4个字节。
2.标签长度是指数据体的长度,不包括标签头的 2 字节。
表4:标签头(长型)
-----------------------------------------------
字段 占位 说明
-----------------------------------------------
标签类型 10 高10位,意义同短型标签头
6 低6位,数值固定为3F(二进制6个1)
标签长度 32
数据体 ≥63字节,<4GB字节
-----------------------------------------------
说明:
区分短型标签头和长型标签头的关键,就是看标签头的低6位是否全1。
三、标签类型
SWF有两种类型的标签:
1.定义型标签(definition tag):
这类标签定义 SWF影片的内容,如各种形状,文字,位图,声音等等。每个定义型标签都被分配了一个唯一的编号(标识号),以供其它标签引用,这叫做角色标识(character ID),编号的原则是从1开始顺序编号。flash播放器把这些角色放到一个存储空间里面,这个存储空间我们一般叫它字典。定义型标签是不会绘制任何图形的,也就是说不会产生任何动画。
2.控制型标签(control tag):
这类标签用来产生和操作字典中的角色实例的渲染,并且控制影片的流程。这类标签如有 character ID,并不是用来标识自己的,而是用来调用的。
3.字典
字典是已经定义好的所有角色的仓库,并且可以通过控制型标签来使用它。建立和使用字典的过程是以下这样的:
①一个定义型标签定义了一些内容,如形体,字体,位图或者声音。
②定义型标签给该内容赋上一个唯一的角色标识(CharacterID),这是一个从1开始的数字标识,如果中间出现缺漏,从缺漏开始的所有character ID都被忽略,而重复的话,后出现的将覆盖先出现的标签。
③依据角色标识把内容存到字典中。
④一个控制型标签根据角色标识从字典中找出相应的内容,然后给这个内容执行一些动作,比如显示一个形体,或者播放一个声音。每个控制型标签都只指定一个唯一的标识。相同的标识是不允许的。举个象征性的例子,第一个角色的标识是1,第二个角色的标识是2,依次类推。角色标识为0的是一个特殊的标识,被看作是空角色。控制型标签并不是唯一指向字典的标签。定义型标签也可以指向多个角色来定义一些更复杂的角色。例如,定义按钮(DefineButton)和定义精灵(DefineSprite)标签都是根据其它角色来定义它们的内容的。定义文字(DefineText)标签可以指向字体角色来为文字选择不同的字体。
四、标签的顺序
除了FileAttribute要放在最前(这是一些全局的东西),结束标签要放在最末,标签之间一般不需要顺序,但是要保证依存关系,比如标签B要引用标签A的标志,就不能在A的前面出现。Stream标签需要按照顺序。一个定义了角色的定义型标签必须在引用这个角色的控制型标签之前。
五、swf必有的几个标签介绍
1.SetBackgroundColor标签
该标签是 Flash7 及以前版本的 SWF 文件里紧跟在文件头后面的第一个标签:
------------------------------------------------
名称 占位 说明
------------------------------------------------
标签头 16 43 02,短型,类型码=9
背景色 24 RGB类型,3个字节分别表示红、绿、蓝
------------------------------------------------
说明:
标签头的2字节数据是16进制数据,类型码“=”号后面的是10进制数据,以下同。
2.FileAttributes标签
该标签是 Flash8 及以后版本的 SWF 文件里紧跟在文件头后面的第一个标签:
---------------------------------------------------------------------------------
名称 占位 说明
---------------------------------------------------------------------------------
标签头 16 44 11,短型,标签类型=69
Reserved 3 总是0
hasMetaData 1 =1表示含有MetaData标签,=0表示不含
Reserved 3 总是0
UseNetWork 1 =1表示在本地加载时有网络权限,=0表示在本地加载时只有本地权限。
Reserved 24 总是0
---------------------------------------------------------------------------------
3.ShowFrame标签
这是文件倒数第2个标签,它是必然存在的。结构如下:
------------------------------------
名称 占位 说明
------------------------------------
标签头 16 40 00,短型,类型码=1
------------------------------------
说明:
标签长度=0表示后面没有数据体。该标签在文件中会多次出现,它表示当前帧显示完毕。
4.end标签
结束标签,必然是文件的最后一个标签。
------------------------------------
名称 占位 说明
------------------------------------
标签头 16 00 00,短型,类型码=0
------------------------------------
六、其它重要标签介绍
以下有的标签在文件中会多次出现。
1.DefineFont2
这个标签的作用是定义一个字体,或者一组静态轮廓字,用以给DefineEdit Text使用。关于文字的几乎所有信息,都可以在这个标签中进行设置,它的结构如下:
------------------------------------------------------------------------------------------
占位 名称 备注
------------------------------------------------------------------------------------------
16 Header 标签头, 类型码=48
16 FontID 字符,唯一的标号
1 FontFlagsHasLayout 根据字面解释,判断是否有变型的标记
1 FontFlagsShiftJIS 是否使用ShiftJIS编码
1 FontFlagsSmallText 是否使用小字体显示
1 FontFlagsANSI 是否使用ANSI编码
1 FontFlagsWideOffsets 是否使用32位偏移量
1 FontFlagsWideCodes 是否使用16位文字编码
1 FontFlagsItalic 文字是否是斜体
1 FontFlagsBold 文字是否是粗体
8 LanguageCode 语言编码有相应编码表对应
8 FontNameLen 字体文件名长度
* FontName 字体文件名(utf-8编码)字段长度=FontNameLen×8
16 NumGlyphs 轮廓字个数
32/16 OffsetTable 根据FontFlagsWideOffsets
32/16 CodeTableOffset 同上
* GlyphShapeTable 轮廓字信息,为shape结构(又是一个复杂结构),字段长度=不定×NumGlyphs
16/8 CodeTable 根据FontFlagsWideCodes,编码表为固定值UCS-2
16/0 FontAscent 根据FontFlagsHasLayout,否则无该字段
16/0 FontDescent 根据FontFlagsHasLayout,否则无该字段
16/0 FontLeading 根据FontFlagsHasLayout,否则无该字段
* FontAdvanceTable 根据FontFlagsHasLayout,否则无该字段,如有,字段长度=16×NumGlyphs
* FontBoundsTable 根据FontFlagsHasLayout,否则无该字段,如有,字段长度=RECT×NumGlyphs
16/0 KerningCount 根据FontFlagsHasLayout,否则无该字段
*16/0 FontKerningTable 根据FontFlagsHasLayout,否则无该字段,如有,字段长度=KERNINGRECORD
×KerningCount
------------------------------------------------------------------------------------------
说明:
1.*标记说明该字段的占位是不确定的,看后面的备注说明。
2.占位是分数的,表示如果有这个字段,占位为分子值,否则为分母值。
3.如果单纯分析动态文本的这个标签的信息,只需要分析到上面的fontName部分就足够了,其他信息只对轮廓字,也就是静态文字有效。动态文字在信息上,关键的只有一个字体名,而静态文字却包含了他的轮廓信息(包含在shape里),这是动态文字和静态文字最大的不同。
2.DoAction标签
----------------------------------------------------------------------------
标签头 2 3F 03,长型,类型码=12
标签长度 4 02 00 00 00,表示后面的数据体占2个字节
数据体 2 07 00,07表示Action代码,查Action代码可以知道它表示ActionStop,
也就是写在第一帧的代码AS Code;00表示DoAction标签结束。
----------------------------------------------------------------------------
3.FrameLabel标签(帧标签)
----------------------------------------------------------------------------
标签头 2 FF 0A,长型,类型码=43
标签长度 4 06 00 00 00,表示后面的数据体占6个字节
数据体 6 73 74 61 72 74 00,字符串“start”,00是字符串结束标志。
----------------------------------------------------------------------------
七、播放器对SWF文件的处理
Flash播放器在一个显示帧标签到来之前会处理显示帧标签之前SWF文件的所有标签。在这个时候,播放列表被复制到屏幕上面,与此同时Flash播放器在处理下一帧之前是空闲的。第一帧所显示的内容,是在第一个显示帧标签之前的所有控制型标签操作产生的累积效果。第二帧所显示的内容,是从文件开始到第二个显示帧标签所有控制型标签操作产生的累积效果。以此类推。
八、由swf文件转换为的exe格式的文件
exe 格式的 swf 文件不过是一个 Flash 播放器程序后面跟着一个 swf 文件,两个文件合成一个文件,就这么简单! 由于它自带了播放器,所以比较方便,但缺点是文件体积大,每个这种文件内都含有一个播放器,有这个必要吗?
转换步骤:
1.以二进制方式读入你选定的 Flash 播放器,并原封不动地写入新文件。这个播放器以 Adobe Flash Player 为好,因为我试过,自己以 VB 编写的 Flash 播放器以及网上下载的其它 Flash 播放器,生成exe 文件后,都无法播放(播放器可以调出来,但它就是不做任何事情),估计 Adobe Flash Player 代码中已专门对这种文件进行了处理(我也曾在自己以 VB 编写的 Flash 播放器上做了多次试验,但是取不到 command 的命令行参数, command 是空的,如果能得到命令行参数,才会有解决办法)。播放器的版本不要太高,6.0 左右即可,因为版本越高,体积越大。
2.以二进制方式读入一个 swf 文件内容,并原封不动地写入新文件。
3.写入四个字节的文件标识符“56 34 12 FA”。
4.定写入 swf 文件长度。
SWF文件是由一个文件头,以及一系列的标签组成的。标签类型有两种:定义型标签和控制型标签。定义型标签把所有物体定义成一个个角色,这些角色存在字典里面。控制型标签操作这些角色,并且控制影片的流程。
swf 的长度单位使用twips(缇),1像素=20缇,这样,分数的像素可以使用整数的缇表示。
swf 的字符串是以00结束的byte序列,采用utf-8编码。
下面介绍swf文件的数据结构。
一、文件头
文件头的结构见表1。
表1:SWF文件头
---------------------------------------------------------------------------
字段 字节数 说明
---------------------------------------------------------------------------
标识符 3 “FWS”或“CWS”的ascii码
版本号 1 版本,例如:1表示swf1,6表示swf6
文件长度 4 长整形,文件的字节数,低位在前
帧大小 RECT结构 SWF场景的大小,单位为twip(缇,1缇=1/20像素,与VB不同)
帧速度 2 以8.8表示的浮点数(也有文章说这是一个整形数),默认=000C
帧数 2 整形,影片总帧数,低位在前
---------------------------------------------------------------------------
说明:
1.文件头以标识符开始,不是“FWS”就是“CWS”。FWS表示该文件未压缩;CWS 表示文件从 RECT 字段开始(第 9 个字节开始)至文件结尾的所有内容,都是使用开放标准 ZLIB 压缩过的(CWS 是在 SWF6 以后才被使用的。对其解压缩可以使用 zlib1.dll 中提供的 uncompress)。本文的所有数据结构分析都是针对“FWS”的,因为“CWS”压缩过的数据看起来面目全非,没法进行分析。
2.文件长度字段,如果是 FWS,该字段表示包括文件头在内的整个文件的准确大小;如果是 CWS,该字段表示解压后文件的大小(不包括前 8 个字节),而不是实际文件的大小,。这样做的目的是让解压后的大小可见,可以使解压过程更加有效。
3.帧大小字段表示影片的宽度和高度.它是一个 RECT 结构,根据 4 个点的坐标可计算出宽高,其结构见表2。
4.帧速率表示理想的每秒播放帧数,如果 SWF 文件包含声音流数据,或者 CPU 速度慢,这个速率是不能保证的。这 2 个字节中,前字节表示小数,后字节表示整数,不过一般极少有小数位的帧速率,所以一般我们只计算整数就可以了,如:00 0C,表示每秒 12 帧。
表2:RECT是使用bit-pack的数据结构
---------------------------------------------------
字段 类型 说明
---------------------------------------------------
Nbits UB(5) 指定后面每个字段各占二进制的几位
Xmin SB(Nbits) x最小值,一般=0
Xmax SB(Nbits) x最大值,即影片宽度
Ymin SB(Nbits) y最小值,一般=0
Ymax SB(Nbits) y最大值,即影片高度
---------------------------------------------------
说明:
1.RECT字段是采用 swf 文件格式规范中定义的“位值”(bit_value)进行存储的,其特点是不管字节区分,按照最小位数(bits)将值连续存储,在末字节中空位补0。比如两个用 9 位表示的无符号值7、8 将占用 3 个字节,表示为二进制就是:00000011 10000010 00000000,将 3 个字节按位连在一起,前 9 位值为7,再 9 位值为8,在第 3 个字节的其他空位全部补0。
2.Nbits字段使用整个结构的前5位来指定后面4个字段各占二进制的几位。例如:
78 00 05 5F 00 00 0F A0 00
换成二进制:
01111000 00000000 00000101 01011111 00000000 00000000 00001111 10100000 00000000
先取前5位转换为10进制:01111=15,这就是说,后面的4个字段,各占用15位,共15×4+5=65位,需要9个字节,72-65=7,后面有7个空闲位。划分如下:
01111 000000000000000 010101011111000 000000000000000 001111101000000 0000000
然后我们可以算出
Xmin = (000000000000000)2=(0)10
Xmax = (010101011111000)2=(11000)10
Ymin = (000000000000000)2=(0)10
Ymax = (001111101000000)2=(8000)10
所以,影片的宽高是11000×8000缇,换算成像素是:550×400
关于影片宽、高的计算,笔者编写了一段代码,见文后的“附”。
二、标签
在文件头后面的是一些标签化的数据块。所有的标签都是用一种通用格式。所以任何程序在解析一个 SWF文件时,都可以跳过那些还不明确的标签。在每个标签中的数据可以指向这个标签中的偏移量,但绝不能指向另外一个标签的偏移量。这样,在用工具处理 SWF 文件的时候就任意可以删除、插入和修改,而 SWF 文件不会被破坏。这种方式保证了版本的兼容性,即使出现了新的标签类型,老版本的播放器还是能够解析完整个 swf 文件而不出现错误,大不了就是不能提供新的功能而已。
每个标签都由标签头和数据体两部分组成。标签头包括标签类型和标签长度。标签头格式有两种:短型和长型。短型由 2 字节构成,长型由 6 字节构成。短型标签头用于数据体不超过 62 字节的标签;长型标签头则用于数据体在 4G 之内的任何标签中。
标签头格式见表3和表4。
表3:标签头(短型)
----------------------
字段 占位 说明
----------------------
标签类型 10 高10位
标签长度 6 低6位
数据体 ≤62字节
----------------------
说明:
1.标签头是一个 2 字节的整形数(低位在前高位在后),例如标签头数据为44 11,那么:“44 11”→“11 44”=“00010001 01000100”,高10位是(0001000101)2=(69)10,低6位是(000100)2=(4)10。查询swf文件中的tag值和action值,可以知道标签类型码=69的是FileAttribute标签。低6位的值4表示标签长度为4个字节。
2.标签长度是指数据体的长度,不包括标签头的 2 字节。
表4:标签头(长型)
-----------------------------------------------
字段 占位 说明
-----------------------------------------------
标签类型 10 高10位,意义同短型标签头
6 低6位,数值固定为3F(二进制6个1)
标签长度 32
数据体 ≥63字节,<4GB字节
-----------------------------------------------
说明:
区分短型标签头和长型标签头的关键,就是看标签头的低6位是否全1。
三、标签类型
SWF有两种类型的标签:
1.定义型标签(definition tag):
这类标签定义 SWF影片的内容,如各种形状,文字,位图,声音等等。每个定义型标签都被分配了一个唯一的编号(标识号),以供其它标签引用,这叫做角色标识(character ID),编号的原则是从1开始顺序编号。flash播放器把这些角色放到一个存储空间里面,这个存储空间我们一般叫它字典。定义型标签是不会绘制任何图形的,也就是说不会产生任何动画。
2.控制型标签(control tag):
这类标签用来产生和操作字典中的角色实例的渲染,并且控制影片的流程。这类标签如有 character ID,并不是用来标识自己的,而是用来调用的。
3.字典
字典是已经定义好的所有角色的仓库,并且可以通过控制型标签来使用它。建立和使用字典的过程是以下这样的:
①一个定义型标签定义了一些内容,如形体,字体,位图或者声音。
②定义型标签给该内容赋上一个唯一的角色标识(CharacterID),这是一个从1开始的数字标识,如果中间出现缺漏,从缺漏开始的所有character ID都被忽略,而重复的话,后出现的将覆盖先出现的标签。
③依据角色标识把内容存到字典中。
④一个控制型标签根据角色标识从字典中找出相应的内容,然后给这个内容执行一些动作,比如显示一个形体,或者播放一个声音。每个控制型标签都只指定一个唯一的标识。相同的标识是不允许的。举个象征性的例子,第一个角色的标识是1,第二个角色的标识是2,依次类推。角色标识为0的是一个特殊的标识,被看作是空角色。控制型标签并不是唯一指向字典的标签。定义型标签也可以指向多个角色来定义一些更复杂的角色。例如,定义按钮(DefineButton)和定义精灵(DefineSprite)标签都是根据其它角色来定义它们的内容的。定义文字(DefineText)标签可以指向字体角色来为文字选择不同的字体。
四、标签的顺序
除了FileAttribute要放在最前(这是一些全局的东西),结束标签要放在最末,标签之间一般不需要顺序,但是要保证依存关系,比如标签B要引用标签A的标志,就不能在A的前面出现。Stream标签需要按照顺序。一个定义了角色的定义型标签必须在引用这个角色的控制型标签之前。
五、swf必有的几个标签介绍
1.SetBackgroundColor标签
该标签是 Flash7 及以前版本的 SWF 文件里紧跟在文件头后面的第一个标签:
------------------------------------------------
名称 占位 说明
------------------------------------------------
标签头 16 43 02,短型,类型码=9
背景色 24 RGB类型,3个字节分别表示红、绿、蓝
------------------------------------------------
说明:
标签头的2字节数据是16进制数据,类型码“=”号后面的是10进制数据,以下同。
2.FileAttributes标签
该标签是 Flash8 及以后版本的 SWF 文件里紧跟在文件头后面的第一个标签:
---------------------------------------------------------------------------------
名称 占位 说明
---------------------------------------------------------------------------------
标签头 16 44 11,短型,标签类型=69
Reserved 3 总是0
hasMetaData 1 =1表示含有MetaData标签,=0表示不含
Reserved 3 总是0
UseNetWork 1 =1表示在本地加载时有网络权限,=0表示在本地加载时只有本地权限。
Reserved 24 总是0
---------------------------------------------------------------------------------
3.ShowFrame标签
这是文件倒数第2个标签,它是必然存在的。结构如下:
------------------------------------
名称 占位 说明
------------------------------------
标签头 16 40 00,短型,类型码=1
------------------------------------
说明:
标签长度=0表示后面没有数据体。该标签在文件中会多次出现,它表示当前帧显示完毕。
4.end标签
结束标签,必然是文件的最后一个标签。
------------------------------------
名称 占位 说明
------------------------------------
标签头 16 00 00,短型,类型码=0
------------------------------------
六、其它重要标签介绍
以下有的标签在文件中会多次出现。
1.DefineFont2
这个标签的作用是定义一个字体,或者一组静态轮廓字,用以给DefineEdit Text使用。关于文字的几乎所有信息,都可以在这个标签中进行设置,它的结构如下:
------------------------------------------------------------------------------------------
占位 名称 备注
------------------------------------------------------------------------------------------
16 Header 标签头, 类型码=48
16 FontID 字符,唯一的标号
1 FontFlagsHasLayout 根据字面解释,判断是否有变型的标记
1 FontFlagsShiftJIS 是否使用ShiftJIS编码
1 FontFlagsSmallText 是否使用小字体显示
1 FontFlagsANSI 是否使用ANSI编码
1 FontFlagsWideOffsets 是否使用32位偏移量
1 FontFlagsWideCodes 是否使用16位文字编码
1 FontFlagsItalic 文字是否是斜体
1 FontFlagsBold 文字是否是粗体
8 LanguageCode 语言编码有相应编码表对应
8 FontNameLen 字体文件名长度
* FontName 字体文件名(utf-8编码)字段长度=FontNameLen×8
16 NumGlyphs 轮廓字个数
32/16 OffsetTable 根据FontFlagsWideOffsets
32/16 CodeTableOffset 同上
* GlyphShapeTable 轮廓字信息,为shape结构(又是一个复杂结构),字段长度=不定×NumGlyphs
16/8 CodeTable 根据FontFlagsWideCodes,编码表为固定值UCS-2
16/0 FontAscent 根据FontFlagsHasLayout,否则无该字段
16/0 FontDescent 根据FontFlagsHasLayout,否则无该字段
16/0 FontLeading 根据FontFlagsHasLayout,否则无该字段
* FontAdvanceTable 根据FontFlagsHasLayout,否则无该字段,如有,字段长度=16×NumGlyphs
* FontBoundsTable 根据FontFlagsHasLayout,否则无该字段,如有,字段长度=RECT×NumGlyphs
16/0 KerningCount 根据FontFlagsHasLayout,否则无该字段
*16/0 FontKerningTable 根据FontFlagsHasLayout,否则无该字段,如有,字段长度=KERNINGRECORD
×KerningCount
------------------------------------------------------------------------------------------
说明:
1.*标记说明该字段的占位是不确定的,看后面的备注说明。
2.占位是分数的,表示如果有这个字段,占位为分子值,否则为分母值。
3.如果单纯分析动态文本的这个标签的信息,只需要分析到上面的fontName部分就足够了,其他信息只对轮廓字,也就是静态文字有效。动态文字在信息上,关键的只有一个字体名,而静态文字却包含了他的轮廓信息(包含在shape里),这是动态文字和静态文字最大的不同。
2.DoAction标签
----------------------------------------------------------------------------
标签头 2 3F 03,长型,类型码=12
标签长度 4 02 00 00 00,表示后面的数据体占2个字节
数据体 2 07 00,07表示Action代码,查Action代码可以知道它表示ActionStop,
也就是写在第一帧的代码AS Code;00表示DoAction标签结束。
----------------------------------------------------------------------------
3.FrameLabel标签(帧标签)
----------------------------------------------------------------------------
标签头 2 FF 0A,长型,类型码=43
标签长度 4 06 00 00 00,表示后面的数据体占6个字节
数据体 6 73 74 61 72 74 00,字符串“start”,00是字符串结束标志。
----------------------------------------------------------------------------
七、播放器对SWF文件的处理
Flash播放器在一个显示帧标签到来之前会处理显示帧标签之前SWF文件的所有标签。在这个时候,播放列表被复制到屏幕上面,与此同时Flash播放器在处理下一帧之前是空闲的。第一帧所显示的内容,是在第一个显示帧标签之前的所有控制型标签操作产生的累积效果。第二帧所显示的内容,是从文件开始到第二个显示帧标签所有控制型标签操作产生的累积效果。以此类推。
八、由swf文件转换为的exe格式的文件
exe 格式的 swf 文件不过是一个 Flash 播放器程序后面跟着一个 swf 文件,两个文件合成一个文件,就这么简单! 由于它自带了播放器,所以比较方便,但缺点是文件体积大,每个这种文件内都含有一个播放器,有这个必要吗?
转换步骤:
1.以二进制方式读入你选定的 Flash 播放器,并原封不动地写入新文件。这个播放器以 Adobe Flash Player 为好,因为我试过,自己以 VB 编写的 Flash 播放器以及网上下载的其它 Flash 播放器,生成exe 文件后,都无法播放(播放器可以调出来,但它就是不做任何事情),估计 Adobe Flash Player 代码中已专门对这种文件进行了处理(我也曾在自己以 VB 编写的 Flash 播放器上做了多次试验,但是取不到 command 的命令行参数, command 是空的,如果能得到命令行参数,才会有解决办法)。播放器的版本不要太高,6.0 左右即可,因为版本越高,体积越大。
2.以二进制方式读入一个 swf 文件内容,并原封不动地写入新文件。
3.写入四个字节的文件标识符“56 34 12 FA”。
4.定写入 swf 文件长度。