PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/FlashDecompiler/src/org/libspark/swfassist/inprogress/swf/AnimationCollector.as

http://flash-decompiler.googlecode.com/
ActionScript | 530 lines | 409 code | 77 blank | 44 comment | 51 complexity | 37ed55bf1992d683324e6620c426f1a9 MD5 | raw file
  1. /*
  2. * Copyright(c) 2007 the Spark project.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  13. * either express or implied. See the License for the specific language
  14. * governing permissions and limitations under the License.
  15. */
  16. package org.libspark.swfassist.inprogress.swf
  17. {
  18. import org.libspark.swfassist.swf.tags.AbstractTagVisitor;
  19. import org.libspark.swfassist.swf.structures.SWF;
  20. import flash.display.Sprite;
  21. import org.libspark.swfassist.flash.display.ShapeDrawer;
  22. import org.libspark.swfassist.swf.tags.Tag;
  23. import org.libspark.swfassist.swf.tags.Tags;
  24. import flash.utils.Dictionary;
  25. import org.libspark.swfassist.swf.tags.ShowFrame;
  26. import org.libspark.swfassist.swf.tags.DefineSprite;
  27. import org.libspark.swfassist.swf.tags.DefineShape;
  28. import org.libspark.swfassist.swf.tags.DefineShape2;
  29. import org.libspark.swfassist.swf.tags.DefineShape3;
  30. import org.libspark.swfassist.swf.tags.DefineShape4;
  31. import org.libspark.swfassist.swf.tags.DefineFont;
  32. import org.libspark.swfassist.swf.tags.DefineFont2;
  33. import org.libspark.swfassist.swf.tags.DefineFont3;
  34. import org.libspark.swfassist.swf.tags.DefineText;
  35. import org.libspark.swfassist.swf.tags.DefineText2;
  36. import org.libspark.swfassist.swf.tags.PlaceObject;
  37. import org.libspark.swfassist.swf.tags.PlaceObject2;
  38. import org.libspark.swfassist.swf.tags.PlaceObject3;
  39. import org.libspark.swfassist.swf.tags.RemoveObject;
  40. import org.libspark.swfassist.swf.tags.RemoveObject2;
  41. import org.libspark.swfassist.flash.display.FlashGraphics;
  42. import org.libspark.swfassist.swf.structures.TextRecord;
  43. import org.libspark.swfassist.swf.structures.GlyphEntry;
  44. import org.libspark.swfassist.swf.tags.DefineFontAlignZones;
  45. import org.libspark.swfassist.swf.structures.ZoneRecord;
  46. import org.libspark.swfassist.swf.structures.ZoneData;
  47. public class AnimationCollector extends AbstractTagVisitor
  48. {
  49. private var _isMaster:Boolean = true;
  50. private var _timeline:Timeline = new Timeline();
  51. private var _dictionary:Dictionary = new Dictionary();
  52. private var _fontInfo:Dictionary = new Dictionary();
  53. private var _sprites:Array = [];
  54. public function draw(dest:Sprite, drawer:ShapeDrawer, frame:uint):void
  55. {
  56. var container:NamedContainer = new NamedContainer();
  57. dest.addChild(container);
  58. for (var i:uint = 1; i <= frame; ++i) {
  59. internalDraw(container, drawer, i);
  60. }
  61. }
  62. public function drawFrame(dest:Sprite, drawer:ShapeDrawer, frame:uint):void
  63. {
  64. var container:NamedContainer = dest.numChildren > 0 ? dest.getChildAt(0) as NamedContainer : null;
  65. if (!container) {
  66. container = new NamedContainer();
  67. dest.addChild(container);
  68. }
  69. internalDraw(container, drawer, frame);
  70. }
  71. private function internalDraw(dest:NamedContainer, drawer:ShapeDrawer, frameNumber:uint):void
  72. {
  73. if (_isMaster) {
  74. for each (var sprite:AnimationSprite in _sprites) {
  75. drawAnimationSprite(sprite, drawer);
  76. }
  77. }
  78. var frame:Frame = _timeline.getFrame(frameNumber);
  79. if (!frame) {
  80. return;
  81. }
  82. for each (var tag:Tag in frame.tags) {
  83. if (tag is PlaceObject2 || tag is PlaceObject3) {
  84. drawPlaceObject2(PlaceObject2(tag), dest, drawer);
  85. continue;
  86. }
  87. if (tag is RemoveObject2) {
  88. drawRemoveObject2(RemoveObject2(tag), dest);
  89. continue;
  90. }
  91. if (tag is RemoveObject) {
  92. drawRemoveObject(RemoveObject(tag), dest);
  93. continue;
  94. }
  95. }
  96. }
  97. private function drawPlaceObject2(tag:PlaceObject2, dest:NamedContainer, drawer:ShapeDrawer):void
  98. {
  99. var isNewCharacter:Boolean = false;
  100. var character:NamedSprite;
  101. if (tag.hasCharacter) {
  102. character = getCharacter(tag.characterId, drawer);
  103. if (tag.isMove) {
  104. var removed:NamedSprite = removeObject(dest, tag.depth);
  105. if (removed) {
  106. character.transform = removed.transform;
  107. }
  108. }
  109. isNewCharacter = true;
  110. }
  111. else {
  112. if (tag.isMove) {
  113. character = dest.getChildByDepth(tag.depth);
  114. }
  115. }
  116. if (character) {
  117. character.depth = tag.depth;
  118. if (isNewCharacter) {
  119. if (character is AnimationSprite) {
  120. drawAnimationSprite(AnimationSprite(character), drawer);
  121. _sprites.push(character);
  122. }
  123. dest.addChild(character);
  124. }
  125. if (tag.hasMatrix) {
  126. character.transform.matrix = tag.matrix.toNativeMatrix();
  127. character.transform = character.transform;
  128. }
  129. /*
  130. if (tag.hasColorTransform) {
  131. character.transform.colorTransform = tag.colorTransform.toNativeColorTransform();
  132. character.transform = character.transform;
  133. }
  134. */
  135. }
  136. }
  137. private function drawAnimationSprite(sprite:AnimationSprite, drawer:ShapeDrawer):void
  138. {
  139. if (sprite.numFrames == 1) {
  140. if (sprite.frameNumber != 0) {
  141. return;
  142. }
  143. sprite.frameNumber = 1;
  144. }
  145. else if (++sprite.frameNumber > sprite.numFrames) {
  146. sprite.frameNumber = 1;
  147. if (sprite.numChildren > 0) {
  148. removeAnimationSprites(Sprite(sprite.removeChildAt(0)));
  149. }
  150. }
  151. sprite.animation.drawFrame(sprite, drawer, sprite.frameNumber);
  152. }
  153. private function removeObject(container:NamedContainer, depth:uint):NamedSprite
  154. {
  155. var sprite:NamedSprite = container.removeChildByDepth(depth);
  156. if (sprite) {
  157. removeAnimationSprites(sprite);
  158. }
  159. return sprite;
  160. }
  161. private function removeAnimationSprites(sprite:Sprite):void
  162. {
  163. for (var i:uint = 0; i < sprite.numChildren; ++i) {
  164. removeAnimationSprites(Sprite(sprite.getChildAt(i)));
  165. }
  166. if (sprite is AnimationSprite) {
  167. removeAnimationSprite(AnimationSprite(sprite));
  168. }
  169. }
  170. private function removeAnimationSprite(sprite:AnimationSprite):void
  171. {
  172. var index:int = _sprites.indexOf(sprite);
  173. if (index >= 0) {
  174. _sprites.splice(index, 1);
  175. }
  176. }
  177. private function drawPlaceObject(tag:PlaceObject, dest:NamedContainer, drawer:ShapeDrawer):void
  178. {
  179. return;
  180. }
  181. private function drawRemoveObject2(tag:RemoveObject2, dest:NamedContainer):void
  182. {
  183. removeObject(dest, tag.depth);
  184. }
  185. private function drawRemoveObject(tag:RemoveObject, dest:NamedContainer):void
  186. {
  187. removeObject(dest, tag.depth);
  188. }
  189. private function getCharacter(id:uint, drawer:ShapeDrawer):NamedSprite
  190. {
  191. var tag:Object = _dictionary[id];
  192. if (tag) {
  193. if (tag is DefineShape) {
  194. return drawDefineShape(DefineShape(tag), drawer);
  195. }
  196. if (tag is DefineText) {
  197. return drawDefineText(DefineText(tag), drawer);
  198. }
  199. if (tag is Animation) {
  200. return new AnimationSprite(id, Animation(tag).collector, Animation(tag).tag.numFrames);
  201. }
  202. }
  203. return new NamedSprite(id);
  204. }
  205. private function drawDefineShape(tag:DefineShape, drawer:ShapeDrawer):NamedSprite
  206. {
  207. var sprite:NamedSprite = new NamedSprite(tag.shapeId);
  208. FlashGraphics(drawer.graphics).graphics = sprite.graphics;
  209. drawer.draw(tag.shapes);
  210. return sprite;
  211. }
  212. private function drawDefineText(tag:DefineText, drawer:ShapeDrawer):NamedSprite
  213. {
  214. var sprite:NamedSprite = new NamedSprite(tag.characterId);
  215. var text:Sprite = drawTextRecords(tag.textRecords, drawer);
  216. text.transform.matrix = tag.textMatrix.toNativeMatrix();
  217. text.transform = text.transform;
  218. sprite.addChild(text);
  219. return sprite;
  220. }
  221. private function drawTextRecords(records:Array, drawer:ShapeDrawer):Sprite
  222. {
  223. var sprite:Sprite = new Sprite();
  224. for each (var record:TextRecord in records) {
  225. drawTextRecord(record, sprite, drawer);
  226. }
  227. return sprite;
  228. }
  229. private function drawTextRecord(record:TextRecord, dest:Sprite, drawer:ShapeDrawer):void
  230. {
  231. if (record.hasFont) {
  232. var font:DefineFont = _dictionary[record.fontId];
  233. if (font) {
  234. /**
  235. var align:DefineFontAlignZones = _fontInfo[record.fontId];
  236. var zoneTable:Array = align ? align.zoneTable : null;
  237. /**/
  238. var glyphTable:Array = font.glyphShapeTable;
  239. var x:Number = record.hasXOffset ? record.xOffset / 20 : 0;
  240. var y:Number = record.hasYOffset ? record.yOffset / 20 : 0;
  241. for each (var entry:GlyphEntry in record.glyphEntries) {
  242. var index:uint = entry.glyphIndex;
  243. var glyphX:Number = x;
  244. var glyphY:Number = y;
  245. /**
  246. var glyphWidth:Number = 0;
  247. var glyphHeight:Number = 0;
  248. if (zoneTable) {
  249. var zone:ZoneRecord = zoneTable[index];
  250. if (zone.zoneMaskX) {
  251. glyphX += ZoneData(zone.zoneData[0]).alignmentCoordinate;
  252. glyphWidth = ZoneData(zone.zoneData[0]).range;
  253. }
  254. if (zone.zoneMaskY) {
  255. glyphY += ZoneData(zone.zoneData[1]).alignmentCoordinate;
  256. glyphHeight = ZoneData(zone.zoneData[1]).range;
  257. }
  258. trace(glyphX, glyphWidth, glyphY, glyphHeight);
  259. }
  260. /**/
  261. var glyph:Sprite = new Sprite();
  262. glyph.x = glyphX;
  263. glyph.y = glyphY;
  264. FlashGraphics(drawer.graphics).graphics = glyph.graphics;
  265. drawer.draw(glyphTable[index]);
  266. dest.addChild(glyph);
  267. /**
  268. x = glyphX + glyphWidth + entry.glyphAdvance / 20;
  269. /**/
  270. x += entry.glyphAdvance / 20;
  271. }
  272. }
  273. }
  274. }
  275. public override function visitDefineSprite(tag:DefineSprite):void
  276. {
  277. var collector:AnimationCollector = new AnimationCollector();
  278. collector._isMaster = false;
  279. collector._dictionary = _dictionary;
  280. collector._sprites = _sprites;
  281. tag.tags.visit(collector);
  282. var animation:Animation = new Animation();
  283. animation.tag = tag;
  284. animation.collector = collector;
  285. _dictionary[tag.spriteId] = animation;
  286. }
  287. public override function visitShowFrame(tag:ShowFrame):void
  288. {
  289. _timeline.newFrame();
  290. }
  291. public override function visitDefineShape(tag:DefineShape):void
  292. {
  293. _dictionary[tag.shapeId] = tag;
  294. }
  295. public override function visitDefineShape2(tag:DefineShape2):void
  296. {
  297. _dictionary[tag.shapeId] = tag;
  298. }
  299. public override function visitDefineShape3(tag:DefineShape3):void
  300. {
  301. _dictionary[tag.shapeId] = tag;
  302. }
  303. public override function visitDefineShape4(tag:DefineShape4):void
  304. {
  305. _dictionary[tag.shapeId] = tag;
  306. }
  307. public override function visitDefineFont(tag:DefineFont):void
  308. {
  309. _dictionary[tag.fontId] = tag;
  310. }
  311. public override function visitDefineFont2(tag:DefineFont2):void
  312. {
  313. _dictionary[tag.fontId] = tag;
  314. }
  315. public override function visitDefineFont3(tag:DefineFont3):void
  316. {
  317. _dictionary[tag.fontId] = tag;
  318. }
  319. public override function visitDefineFontAlignZones(tag:DefineFontAlignZones):void
  320. {
  321. _fontInfo[tag.fontId] = tag;
  322. }
  323. public override function visitDefineText(tag:DefineText):void
  324. {
  325. _dictionary[tag.characterId] = tag;
  326. }
  327. public override function visitDefineText2(tag:DefineText2):void
  328. {
  329. _dictionary[tag.characterId] = tag;
  330. }
  331. public override function visitPlaceObject(tag:PlaceObject):void
  332. {
  333. _timeline.currentFrame.addTag(tag);
  334. }
  335. public override function visitPlaceObject2(tag:PlaceObject2):void
  336. {
  337. _timeline.currentFrame.addTag(tag);
  338. }
  339. public override function visitPlaceObject3(tag:PlaceObject3):void
  340. {
  341. _timeline.currentFrame.addTag(tag);
  342. }
  343. public override function visitRemoveObject(tag:RemoveObject):void
  344. {
  345. _timeline.currentFrame.addTag(tag);
  346. }
  347. public override function visitRemoveObject2(tag:RemoveObject2):void
  348. {
  349. _timeline.currentFrame.addTag(tag);
  350. }
  351. }
  352. }
  353. import org.libspark.swfassist.swf.tags.Tag;
  354. import flash.display.Sprite;
  355. import flash.display.DisplayObject;
  356. import org.libspark.swfassist.inprogress.swf.AnimationCollector;
  357. import org.libspark.swfassist.swf.tags.DefineSprite;
  358. class Timeline
  359. {
  360. public function Timeline()
  361. {
  362. newFrame();
  363. }
  364. private var _frames:Array = [];
  365. private var _current:Frame;
  366. public function get currentFrame():Frame
  367. {
  368. return _current;
  369. }
  370. public function newFrame():void
  371. {
  372. _current = new Frame();
  373. _frames.push(_current);
  374. }
  375. public function getFrame(frame:uint):Frame
  376. {
  377. if (frame > _frames.length) {
  378. return null;
  379. }
  380. return _frames[frame - 1];
  381. }
  382. }
  383. class Frame
  384. {
  385. public var tags:Array = [];
  386. public function addTag(tag:Tag):void
  387. {
  388. tags.push(tag);
  389. }
  390. }
  391. class NamedSprite extends Sprite
  392. {
  393. public function NamedSprite(id:uint = 0)
  394. {
  395. this.id = id;
  396. }
  397. public var id:uint;
  398. public var depth:uint;
  399. }
  400. class NamedContainer extends Sprite
  401. {
  402. public override function addChild(child:DisplayObject):DisplayObject
  403. {
  404. if (child is NamedSprite) {
  405. var depth:uint = NamedSprite(child).depth;
  406. for (var i:uint = 0; i < numChildren; ++i) {
  407. var c:NamedSprite = getChildAt(i) as NamedSprite;
  408. if (c && c.depth < depth) {
  409. return addChildAt(child, getChildIndex(c) + 1);
  410. }
  411. }
  412. }
  413. return super.addChild(child);
  414. }
  415. public function getChildByDepth(depth:uint):NamedSprite
  416. {
  417. for (var i:uint = 0; i < numChildren; ++i) {
  418. var c:NamedSprite = getChildAt(i) as NamedSprite;
  419. if (c && c.depth == depth) {
  420. return c;
  421. }
  422. }
  423. return null;
  424. }
  425. public function removeChildByDepth(depth:uint):NamedSprite
  426. {
  427. for (var i:uint = 0; i < numChildren; ++i) {
  428. var c:NamedSprite = getChildAt(i) as NamedSprite;
  429. if (c && c.depth == depth) {
  430. removeChild(c);
  431. return c;
  432. }
  433. }
  434. return null;
  435. }
  436. }
  437. class Animation
  438. {
  439. public var tag:DefineSprite;
  440. public var collector:AnimationCollector;
  441. }
  442. class AnimationSprite extends NamedSprite
  443. {
  444. public function AnimationSprite(id:uint, animation:AnimationCollector, numFrames:uint)
  445. {
  446. super(id);
  447. this.animation = animation;
  448. this.numFrames = numFrames;
  449. }
  450. public var frameNumber:uint = 0;
  451. public var numFrames:uint = 0;
  452. public var animation:AnimationCollector;
  453. }