PageRenderTime 68ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/svgweb/tests/non-licensed/perf/test7/src/org/svgweb/nodes/SVGSVGNode.as

https://github.com/dionjwa/Hydrax
ActionScript | 577 lines | 431 code | 73 blank | 73 comment | 136 complexity | 3743acbecb3d5eca4f80f4f4fb94f8dd MD5 | raw file
  1. /*
  2. Copyright (c) 2009 by contributors:
  3. * James Hight (http://labs.zavoo.com/)
  4. * Richard R. Masters
  5. * Google Inc. (Brad Neuberg -- http://codinginparadise.org)
  6. Licensed under the Apache License, Version 2.0 (the "License");
  7. you may not use this file except in compliance with the License.
  8. You may obtain a copy of the License at
  9. http://www.apache.org/licenses/LICENSE-2.0
  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, either express or implied.
  13. See the License for the specific language governing permissions and
  14. limitations under the License.
  15. */
  16. package org.svgweb.nodes
  17. {
  18. import org.svgweb.core.SVGNode;
  19. import org.svgweb.core.SVGViewer;
  20. import org.svgweb.events.SVGEvent;
  21. import flash.geom.Matrix;
  22. import flash.display.Sprite;
  23. import flash.events.Event;
  24. import flash.utils.getTimer;
  25. import flash.external.ExternalInterface;
  26. import org.svgweb.utils.ImageLoader;
  27. public class SVGSVGNode extends SVGNode
  28. {
  29. protected var parentSVGRoot:SVGSVGNode = null;
  30. private var _pendingRenderCount:int;
  31. protected var firedOnLoad:Boolean = false;
  32. protected var loadTime:int = -1; // milliseconds
  33. protected var scaleModeParam:String = 'svg_all';
  34. private var _idLookup:Object;
  35. private var _guidLookup:Object;
  36. protected var _referersById:Object;
  37. protected var _fonts:Object;
  38. protected var fontListeners:Array = new Array();
  39. public var title:String;
  40. public var viewer:SVGViewer;
  41. public var currentScale:Number = 1;
  42. public var currentTranslate:Object = {x: 0, y: 0};
  43. public var imageCache:Object = new Object();
  44. private var lastFrameTime:uint = getTimer();
  45. private var totalFrameTime:uint = 0;
  46. private var frameCount:uint = 0;
  47. /** If this file was loaded from a URL, such as samples/scimitar.svg,
  48. then objectURL points to the relative path from which it was
  49. fetched, such as 'samples/' */
  50. public var objectURL:String = '';
  51. /** Same as objectURL, but the relative path from the containing HTML
  52. page. */
  53. public var pageURL:String = '';
  54. public function SVGSVGNode(svgRoot:SVGSVGNode = null, xml:XML = null,
  55. original:SVGNode = null,
  56. viewer:SVGViewer = null, objectURL:String = '',
  57. pageURL:String = ''):void {
  58. this.viewer = viewer;
  59. this.objectURL = objectURL;
  60. this.pageURL = pageURL;
  61. if (svgRoot) {
  62. this.parentSVGRoot = svgRoot;
  63. }
  64. super(this, xml, original);
  65. }
  66. public override function set xml(value:XML):void {
  67. default xml namespace = svg;
  68. this._idLookup = new Object();
  69. this._guidLookup = new Object();
  70. this._referersById = new Object();
  71. this._fonts = new Object();
  72. super.xml = value;
  73. // If this is the top SVG element, then start the render tracking process.
  74. if (this.parentSVGRoot == null) {
  75. if (this.xml) {
  76. if (this.xml.@id) {
  77. this._idLookup[this.xml.@id] = this;
  78. }
  79. this._guidLookup[this.xml.@__guid] = this;
  80. }
  81. this._pendingRenderCount = 1;
  82. }
  83. }
  84. protected override function onAddedToStage(event:Event):void {
  85. super.onAddedToStage(event);
  86. topSprite.addEventListener(Event.ENTER_FRAME, updateAnimations);
  87. }
  88. protected override function onRemovedFromStage(event:Event):void {
  89. topSprite.removeEventListener(Event.ENTER_FRAME, updateAnimations);
  90. super.onRemovedFromStage(event);
  91. }
  92. public function getDocTime():Number {
  93. if (this.parentSVGRoot) {
  94. return this.parentSVGRoot.getDocTime();
  95. }
  96. else {
  97. return (getTimer() - this.loadTime) / 1000.0;
  98. }
  99. }
  100. protected function updateAnimations(event:Event):void {
  101. /* Frame Counter
  102. if (this.lastFrameTime > 0) {
  103. this.totalFrameTime += (getTimer() - this.lastFrameTime);
  104. this.frameCount++;
  105. if (this.frameCount % 10 == 0) {
  106. this.dbg("last frame time: " + (getTimer() - this.lastFrameTime) +
  107. "ms, avg time: " + (this.totalFrameTime/this.frameCount) +
  108. "ms avg rate: " + (1000.0/(this.totalFrameTime/this.frameCount)) + " frames/sec");
  109. this.totalFrameTime = 0;
  110. this.frameCount = 0;
  111. }
  112. }
  113. this.lastFrameTime=getTimer();
  114. */
  115. if (this.parentSVGRoot) {
  116. this.parentSVGRoot.updateAnimations(event);
  117. }
  118. else {
  119. // Nothing to do while the document is loading
  120. if (this.loadTime == -1) {
  121. return;
  122. }
  123. var svgEvent:SVGEvent = new SVGEvent(SVGEvent._SVGDocTimeUpdate);
  124. svgEvent.setDocTime( (getTimer() - this.loadTime) / 1000.0 );
  125. this.dispatchEvent(svgEvent);
  126. }
  127. }
  128. public function seekToDocTime(docTime:Number):void {
  129. if (this.parentSVGRoot) {
  130. this.parentSVGRoot.seekToDocTime(docTime);
  131. }
  132. else {
  133. this.loadTime = getTimer() - docTime*1000.0;
  134. var svgEvent:SVGEvent = new SVGEvent(SVGEvent._SVGDocTimeSeek);
  135. svgEvent.setDocTime(docTime);
  136. this.dispatchEvent(svgEvent);
  137. }
  138. }
  139. override public function getStyle(name:String, defaultValue:* = null, inherit:Boolean = false):* {
  140. var value:String = super.getStyle(name, null, false);
  141. if (value) {
  142. return value;
  143. }
  144. if ((name == 'opacity')
  145. || (name == 'fill-opacity')
  146. || (name == 'stroke-opacity')
  147. || (name == 'stroke-width')) {
  148. return '1';
  149. }
  150. if (name == 'fill') {
  151. return 'black';
  152. }
  153. if (name == 'stroke') {
  154. return 'none';
  155. }
  156. return defaultValue;
  157. }
  158. override public function getAttribute(name:String, defaultValue:* = null,
  159. inherit:Boolean = true,
  160. applyAnimations:Boolean = true,
  161. useStyle:Boolean = false):* {
  162. var value:String = this._getAttribute(name, defaultValue, inherit, applyAnimations, useStyle);
  163. if (value !== null) {
  164. return value;
  165. }
  166. if (ATTRIBUTES_NOT_INHERITED.indexOf(name) != -1) {
  167. if (defaultValue == null) {
  168. if (name == 'opacity') {
  169. return '1';
  170. }
  171. // default fall through
  172. }
  173. return defaultValue;
  174. }
  175. if (inherit && (this.svgParent != null)) {
  176. return this.svgParent.getAttribute(name, defaultValue, inherit, applyAnimations, useStyle);
  177. }
  178. if ((name == 'opacity')
  179. || (name == 'fill-opacity')
  180. || (name == 'stroke-opacity')
  181. || (name == 'stroke-width')) {
  182. return '1';
  183. }
  184. if (name == 'fill') {
  185. return 'black';
  186. }
  187. if (name == 'stroke') {
  188. return 'none';
  189. }
  190. if (name == 'visibility') {
  191. return 'visible';
  192. }
  193. return defaultValue;
  194. }
  195. override public function setAttribute(name:String, value:String):void {
  196. super.setAttribute(name, value);
  197. if (name == 'x' || name == 'y') {
  198. this.applyDefaultMask();
  199. }
  200. }
  201. override protected function loadAttribute(name:String, field:String = null,
  202. applyStyle:Boolean = false):void {
  203. // Issue 226: Topmost <svg> tag ignores x and y
  204. if (topSprite.parent is SVGViewer &&
  205. (name == 'x' || name == 'y') ) {
  206. return;
  207. } else {
  208. super.loadAttribute(name, field, applyStyle);
  209. }
  210. }
  211. // The following functions track the number of elements that have a redraw
  212. // pending. When the count reaches zero, the onLoad handler can be called.
  213. //
  214. // The overall count starts at one to account for the top SVG element. This is done
  215. // in the set xml handler above.
  216. // Other elements increment the count when they are added. This is done
  217. // by an override of addChild in SVGNode.
  218. // Every element decrements the count when rendering is complete. This is done
  219. // by drawNode in SVGNode.
  220. public function renderPending():void {
  221. if (this.parentSVGRoot) {
  222. this.parentSVGRoot.renderPending();
  223. }
  224. else {
  225. this._pendingRenderCount++;
  226. }
  227. }
  228. public function renderFinished():void {
  229. if (this.parentSVGRoot) {
  230. this.parentSVGRoot.renderFinished();
  231. }
  232. else {
  233. this._pendingRenderCount--;
  234. if (this._pendingRenderCount == 0) {
  235. if (!this.firedOnLoad) {
  236. this.handleOnLoad();
  237. this.firedOnLoad = true;
  238. }
  239. }
  240. if (this._pendingRenderCount < 0 && !this.firedOnLoad) {
  241. this.dbg("error: pendingRenderCount count negative: " + this._pendingRenderCount);
  242. }
  243. }
  244. }
  245. public function registerNode(node:SVGNode):void {
  246. if (this.parentSVGRoot) {
  247. this.parentSVGRoot.registerNode(node);
  248. } else {
  249. registerID(node);
  250. registerGUID(node);
  251. }
  252. }
  253. public function unregisterNode(node:SVGNode):void {
  254. if (this.parentSVGRoot) {
  255. this.parentSVGRoot.unregisterNode(node);
  256. } else {
  257. unregisterID(node);
  258. unregisterGUID(node);
  259. }
  260. }
  261. public function registerID(node:SVGNode):void {
  262. if (node.id) {
  263. _idLookup[node.id] = node;
  264. }
  265. }
  266. public function unregisterID(node:SVGNode):void {
  267. if (node.id) {
  268. delete _idLookup[node.id];
  269. }
  270. }
  271. public function registerGUID(node:SVGNode):void {
  272. _guidLookup[node.guid] = node;
  273. }
  274. public function unregisterGUID(node:SVGNode):void {
  275. delete _guidLookup[node.guid];
  276. }
  277. override protected function registerSelf():void {
  278. super.registerSelf();
  279. if (parentSVGRoot) {
  280. parentSVGRoot.registerNode(this);
  281. }
  282. }
  283. override protected function unregisterSelf():void {
  284. super.unregisterSelf();
  285. if (parentSVGRoot) {
  286. parentSVGRoot.unregisterNode(this);
  287. parentSVGRoot = null;
  288. }
  289. }
  290. /**
  291. *
  292. * If this object depends on another object, then we can
  293. * register our interest in being invalidated when the
  294. * dependency object is redrawn.
  295. *
  296. * The node references referenceId.
  297. * An array of nodes that reference the referenceId is created.
  298. *
  299. **/
  300. public function addReference(node:SVGNode, referencedId:String):void {
  301. if (this.parentSVGRoot) {
  302. this.parentSVGRoot.addReference(node, referencedId);
  303. }
  304. else {
  305. if (!this._referersById[referencedId]) {
  306. this._referersById[referencedId]= new Array();
  307. }
  308. if (this._referersById[referencedId].lastIndexOf(node) == -1) {
  309. this._referersById[referencedId].push(node);
  310. }
  311. }
  312. }
  313. public function deleteReference(node:SVGNode, referencedId:String):void {
  314. if (this.parentSVGRoot) {
  315. this.parentSVGRoot.deleteReference(node, referencedId);
  316. }
  317. else {
  318. if (this._referersById[referencedId]) {
  319. if (this._referersById[referencedId].lastIndexOf(node) != -1) {
  320. delete this._referersById[referencedId][this._referersById[referencedId].lastIndexOf(node)];
  321. }
  322. }
  323. }
  324. }
  325. public function invalidateReferers(id:String):void {
  326. if (this.parentSVGRoot) {
  327. this.parentSVGRoot.invalidateReferers(id);
  328. }
  329. else {
  330. //this.svgRoot.debug("Invalidating referers to " + id);
  331. if (this._referersById[id]) {
  332. var referers:Array = this._referersById[id];
  333. for (var refererIdx:String in referers) {
  334. referers[refererIdx].invalidateDisplay();
  335. }
  336. }
  337. }
  338. }
  339. public function getNode(name:String):SVGNode {
  340. if (this.parentSVGRoot) {
  341. return this.parentSVGRoot.getNode(name);
  342. } else if (_idLookup.hasOwnProperty(name)) {
  343. return _idLookup[name];
  344. }
  345. return null;
  346. }
  347. public function getNodeByGUID(guid:String):SVGNode {
  348. if (_guidLookup.hasOwnProperty(guid)) {
  349. return _guidLookup[guid];
  350. }
  351. return null;
  352. }
  353. /**
  354. *
  355. * Fonts
  356. *
  357. **/
  358. public function registerFont(font:SVGFontNode):void {
  359. if (this.parentSVGRoot) {
  360. this.parentSVGRoot.registerFont(font);
  361. }
  362. else {
  363. _fonts[font.getFontFaceName()] = font;
  364. }
  365. for each(var node:SVGNode in fontListeners) {
  366. node.onRegisterFont(font.getFontFaceName());
  367. }
  368. }
  369. public function unregisterFont(font:SVGFontNode):void {
  370. if (this.parentSVGRoot) {
  371. this.parentSVGRoot.unregisterFont(font);
  372. }
  373. else {
  374. delete _fonts[font.getFontFaceName()];
  375. }
  376. }
  377. public function getFont(fontFace:String):SVGFontNode {
  378. if (this.parentSVGRoot) {
  379. return this.parentSVGRoot.getFont(fontFace);
  380. }
  381. else {
  382. return _fonts[fontFace];
  383. }
  384. }
  385. public function registerFontListener(node:SVGNode):void {
  386. if (this.parentSVGRoot) {
  387. this.parentSVGRoot.registerFontListener(node);
  388. }
  389. else {
  390. fontListeners.push(node);
  391. }
  392. }
  393. public function unregisterFontListener(node:SVGNode):void {
  394. if (this.parentSVGRoot) {
  395. this.parentSVGRoot.unregisterFontListener(node);
  396. }
  397. else {
  398. if (fontListeners.lastIndexOf(node) != -1) {
  399. delete fontListeners[fontListeners.lastIndexOf(node)];
  400. }
  401. }
  402. }
  403. public function handleScript(script:String):void {
  404. if (this.parentSVGRoot) {
  405. this.parentSVGRoot.handleScript(script);
  406. }
  407. else if (topSprite.parent is SVGViewer) {
  408. SVGViewer(topSprite.parent).handleScript(script);
  409. }
  410. }
  411. public function loadImage(imageHref:String, imageNode:SVGImageNode):void {
  412. if (this.parentSVGRoot) {
  413. this.parentSVGRoot.loadImage(imageHref, imageNode);
  414. }
  415. else {
  416. if (!this.imageCache[imageHref]) {
  417. this.imageCache[imageHref] = new ImageLoader(imageHref);
  418. }
  419. this.imageCache[imageHref].addListener(imageNode);
  420. }
  421. }
  422. public function handleOnLoad():void {
  423. if (this.parentSVGRoot) {
  424. this.parentSVGRoot.handleOnLoad();
  425. }
  426. else {
  427. this.loadTime = getTimer();
  428. var svgEvent:SVGEvent = new SVGEvent(SVGEvent.SVGLoad);
  429. this.dispatchEvent(svgEvent);
  430. }
  431. }
  432. public function addActionListener(eventType:String, target:Sprite):void {
  433. if (this.parentSVGRoot) {
  434. this.parentSVGRoot.addActionListener(eventType, target);
  435. }
  436. else if (topSprite.parent is SVGViewer) {
  437. SVGViewer(topSprite.parent).addActionListener(eventType, target);
  438. }
  439. }
  440. public function removeActionListener(eventType:String, target:Sprite):void {
  441. if (this.parentSVGRoot) {
  442. this.parentSVGRoot.removeActionListener(eventType, target);
  443. }
  444. else if (topSprite.parent is SVGViewer) {
  445. SVGViewer(topSprite.parent).removeActionListener(eventType, target);
  446. }
  447. }
  448. public function zoomAndPan():void {
  449. var m:Matrix;
  450. // do we have a cached viewBox matrix that we've already applied?
  451. if (this._lastVBMatrix) {
  452. m = this._lastVBMatrix.clone();
  453. } else {
  454. m = new Matrix();
  455. }
  456. m.translate(this.currentTranslate.x, this.currentTranslate.y);
  457. m.scale(this.currentScale, this.currentScale);
  458. viewBoxSprite.transform.matrix = m;
  459. }
  460. public function debug(debugString:String):void {
  461. // UNCOMMENT!!!
  462. //ExternalInterface.call("debug", debugString);
  463. }
  464. public function error(message:String):void {
  465. if (this.parentSVGRoot) {
  466. this.parentSVGRoot.error(message);
  467. }
  468. else if (topSprite.parent is SVGViewer) {
  469. SVGViewer(topSprite.parent).error(message);
  470. }
  471. }
  472. /** Functions for profiling. */
  473. override public function start(subject:String, subjectStarted:String = null):void {
  474. if (this.parentSVGRoot) {
  475. this.parentSVGRoot.start(subject, subjectStarted);
  476. }
  477. else if (topSprite.parent is SVGViewer) {
  478. SVGViewer(topSprite.parent).start(subject, subjectStarted);
  479. }
  480. }
  481. /** Functions for profiling. */
  482. override public function end(subject:String, subjectStarted:String = null):void {
  483. if (this.parentSVGRoot) {
  484. this.parentSVGRoot.end(subject, subjectStarted);
  485. }
  486. else if (topSprite.parent is SVGViewer) {
  487. SVGViewer(topSprite.parent).end(subject, subjectStarted);
  488. }
  489. }
  490. /** Functions for profiling. */
  491. override public function increment(subject:String, amount:int):void {
  492. if (this.parentSVGRoot) {
  493. this.parentSVGRoot.increment(subject, amount);
  494. }
  495. else if (topSprite.parent is SVGViewer) {
  496. SVGViewer(topSprite.parent).increment(subject, amount);
  497. }
  498. }
  499. }
  500. }