簡介
swf檔案的整體結構是 header + body的組成。檔案的開始是一個【檔案頭】
它的結構如下:
位元組
名稱 說明1 Signature
“F”表示非加密格式,”C”表示加密格式
1 Signature “W”無特殊意義1 Signature “S”無特殊意義
1 Version 版本號,它表示對應播放器版本
4 filelength 整個檔案長度,低位在前
N FrameSize
RECT結構體,表示螢幕大小,具體結構和長度根據數據變化,分析方法另外討論。
2 FrameRate 幀頻,默認為12,高位在前
2 FrameCount
幀數,表明檔案根下的幀數,低位在前
以上是swf 中,最簡單的一個tag,一個完整的swf檔案是由很多獨立的tag組成的。每一個tag都包括一個頭和一個數據體,頭有2種類型,短tag型和長tag型。
短tag型由2byte構成,前10個bit表示tag類型,後6個bit表示tag長度。
長tag型由6byte構成,前10個bit表示tag類型,後6個bit固定為全1,後4個byte代表tag長度。
tag的長度不同於檔案頭的長度FileLength,它是除去tag頭後的長度。
(另外)只有非加密的swf檔案可以直接用以上的方法解析,加密的檔案需要另外增加一步處理。具體方法由於牽涉到著作權問題,這裡我不加說明。
這份資料可能對flash設計意義不大,但如果有人用的著,我會繼續分析一下,如果有人也在做這方面的調查,歡迎和我一起討論。
第2節
前節說明了swf檔案 是由1個head和1個body構成的。
並且解析了header的結構,和一個tag的header部分的簡單說明。
下面餘下的就是swf檔案 的body了。
整個檔案body是由大量的tag組成的,通過分析tag的head部分,可以立刻知道這個tag的類型代碼和長度。
如果你無法識別這個tag的類型,也可以利用tag的長度,直接跳過這個tag。
這種方式保證了版本的兼容性,即使出現了新的tag,老版本的播放器還是能夠解析完整個swf檔案而不出現錯誤,大不了就是不能提供新的功能而已。
以下就是swf檔案結構的一個形象概念。
(檔案header)(檔案body)
|
(tag 1)(tag 2)(tag 3)(……)
|
(tag header)(tag body)
|
(tag 類型代碼)(tag 長度)
這樣大家是否對swf檔案的結構有了一個基本的認識?
下一節我會分析一下幾個swf必有的tag,包括
backgroundColor tag,showFrame tag和end tag
第3節
setBackgroundColor tag
這個tag是直接跟在檔案head後面的第一個tag,是檔案中必然存在的。
它的結構如下:
長度(bit) 名稱 說明
16 header tag頭,短tag型
類型碼為9
24 BackgroundColor
RGB類型,右3個位元組,分別表示紅、綠、藍
showFrame tag
這是檔案最後第2個tag,它是必然存在的。
結構如下:
長度(bit) 名稱 說明
16 header tag頭,短tag型
類型碼為1
end tag
結束tag,它的作用不用我說了,必然是檔案的最後一個tag。
長度(bit) 名稱 說明
16 header tag頭,短tag型
類型碼為0
下一節我將講的是character ID
和Depth的意義和textField的基本tag組成。
(另外)感謝AOL的補充和解釋。
第4節
一個textField就是一個文本框,文本框有3種,靜態的,動態的,和輸入型。作為tag的話,它只有2種,靜態的和動態的,輸入型不過是動態的一種特別形式。
這裡討論動態文本框的組成。
它由3個tag組成,2個定義tag和一個控制tag
分別是:
定義tag DefineFont2 DefineEditText (針對player 7.0
如有不同情況請檢查播放器版本)
控制tag PlaceObject2
DefineFont2 定義了一個字型信息,
DefineEditText引用了定義的字型,並定義了顯示的文字信息,而PlaceObject引用了定義的文字信息,並控制了文字的顯示。
他們之間的引用就是依靠character ID進行的。
character
ID就是一個從1開始的數字標示,如果中間出現缺漏,從缺漏開始的所有character
ID都被忽略,而重複的話,後出現的將覆蓋先出現的tag。
DefineFont2用一個character ID
來標示自己,DefineEditText和PlaceObject2也同樣如此。但並不是所有的tag都有character
ID。
另外,PlaceObject2雖然也有character
ID,但它並不是用來標示自己的,而是用來調用的。
而深度Depth在3個tag中只有PlaceObject2擁有。
這3個tag的關係就是這樣。這3個tag的結構我會在下節中說明。(抱歉,每次都說一點點!)
第5節
DefineFont2
這個tag的作用是定義一個字型,或者一組靜態輪廓字,用以給DefineEditText使用。
關於文字的幾乎所有信息,都可以在這個tag中進行設定,因此,這也是一個相當複雜的tag。
它的結構如下:
長度(bit) 名稱
說明
headerLength header
tag頭,類型碼為48
16 FontID character
ID,唯一的標示
1 FontFlagsHasLayout
根據字面解釋,判斷是否有變型的標記
1 FontFlagsShiftJIS
是否使用ShiftJIS編碼
1 FontFlagsSmallText
是否使用小字型顯示
1 FontFlagsANSI 是否使用ANSI編碼
1 FontFlagsWideOffsets
是否使用32位偏移量
1 FontFlagsWideCodes
是否使用16位文字編碼
1 FontFlagsItalic
文字是否是斜體
1 FontFlagsBold
文字是否是粗體
8 LanguageCode
語言編碼,有相應的編碼表對應
8 FontNameLen 檔案名稱長度
FontNameLen*8 FontName
檔案名稱稱(使用utf8編碼)
16 NumGlyphs 輪廓字個數
32/16 OffsetTable
根據FontFlagsWideOffsets,為32位,否則為16位
32/16 CodeTableOffset 同上
不定*NumGlyphs GlyphShapeTable
輪廓字信息,為shape結構(又是一個複雜結構)
16/8 CodeTable
根據FontFlagsWideCodes,為16位。編碼表,為固定值UCS-2
16/0 FontAscent
根據FontFlagsHasLayout,為16位,否則沒有該欄位
16/0 FontDescent
根據FontFlagsHasLayout,為16位,否則沒有該欄位
16/0 FontLeading
根據FontFlagsHasLayout,為16位,否則沒有該欄位
16/0*NumGlyphs FontAdvanceTable
根據FontFlagsHasLayout,為16位,否則沒有該欄位
RECT*NumGlyphs FontBoundsTable
根據FontFlagsHasLayout,為16位,否則沒有該欄位
16/0 KerningCount
根據FontFlagsHasLayout,為16位,否則沒有該欄位
KERNINGRECORD*KerningCount
FontKerningTable
根據FontFlagsHasLayout,為16位,否則沒有該欄位
如果你仔細看了上面的內容,我挺佩服你的。
其實如果單純分析動態文本的這個tag的信息,只需要分析到上面的fontName部分就足夠了,其他信息只對輪廓字,也就是靜態文字有效。
看到這個大家應該都明白了一點,動態文字在信息上,關鍵的只有一個字型名,而靜態文字卻包含了他的輪廓信息(包含在shape里)。
這就是動態文字和靜態文字最大的不同。