[Sie-announce] SIEコード [1307] getCTMメソッドの実装

Back to archive index

svnno****@sourc***** svnno****@sourc*****
2009年 10月 3日 (土) 19:20:39 JST


Revision: 1307
          http://sourceforge.jp/projects/sie/svn/view?view=rev&revision=1307
Author:   dhrname
Date:     2009-10-03 19:20:39 +0900 (Sat, 03 Oct 2009)

Log Message:
-----------
getCTMメソッドの実装

Modified Paths:
--------------
    branches/DOM/org/w3c/dom/svg.js

Modified: branches/DOM/org/w3c/dom/svg.js
===================================================================
--- branches/DOM/org/w3c/dom/svg.js	2009-10-02 13:58:01 UTC (rev 1306)
+++ branches/DOM/org/w3c/dom/svg.js	2009-10-03 10:20:39 UTC (rev 1307)
@@ -873,87 +873,6 @@
   return grad;
 }
 
-//transform属性を処理
-function TransformList( /*element*/ ele) {
-  this.on = true;
-  try {
-  var ep = ele.parentNode;
-  var tf = "";
-  if (ele.getAttribute("transform")) {
-    tf = ele.getAttribute("transform");
-  }
-  while(ep.tagName == "group" || ep.tagName == "A") { //先祖要素のtransform属性を取得
-    if (ep.getAttribute("transform")) {
-      tf = ep.getAttribute("transform") + tf;
-      ele.setAttribute("transform",tf);
-    }
-    ep = ep.parentNode;
-  }
-  this.tr = new Transform();
-  var tft =   ele.getAttribute("transform");
-  if (tft) {
-    var coma = tft.match(/[A-Za-z]+(?=\s*\()/g);
-    var list = tft.match(/\([^\)]+\)/g);
-    this.tr.matrix = this.tr.getMatrix(list[0],coma[0]);
-    for (var i=1;i<coma.length;i++) {
-      this.tr.set(list[i],coma[i]);
-    }
-    list = null;
-  }  else{
-    this.on = false;
-    this.tr.matrix = new Matrix(1,0,0,1,0,0);
-  }
-  }  catch(e) {stlog.add(e,816);}
-  return this;
-}
-
-function Transform() {
-  this.matrix = new Matrix(1,0,0,1,0,0);
-  return this;
-}
-Transform.prototype.set = function transformset(list,c) {
-  var matri = this.getMatrix(list,c);
-  var mat = this.matrix;
-  this.matrix = mat.multiply(matri);
-}
-Transform.prototype.getMatrix = function transformgetMatrix(list,com) {
-  var a,b,c,d,e,f;
-  var deg = list.match(/[\-\d\.e]+/g);
-  var rad =   parseFloat(deg[0]) / 180 * Math.PI;
-  for (var i=0,degli=deg.length;i<degli;i++) {
-    var et = deg[i].match(/([\-\d\.]+)e([\-\d\.]+)/);
-    if (et) {
-      deg[i] = parseFloat(RegExp.$1) * Math.pow(10,parseFloat(RegExp.$2));
-    }
-  }
-  if (deg.length == 6) {
-    a = parseFloat(deg[0]); b = parseFloat(deg[1]); c = parseFloat(deg[2]); d = parseFloat(deg[3]); e = parseFloat(deg[4]); f = parseFloat(deg[5]);
-  } else if (deg.length == 3) {
-    var cx = parseFloat(deg[1]), cy = parseFloat(deg[2]);
-    a = Math.cos(rad); b = Math.sin(rad); c = -b; d = a; e = (1-a)*cx-c*cy; f = -b*cx+(1-d)*cy;
-  } else if (deg.length <= 2) {
-    switch (com) {
-      case "translate":
-        a = 1; b = 0; c = 0; d = 1; e = parseFloat(deg[0]); f = parseFloat(deg[1] || 0);
-      break;
-      case "scale":
-        a = parseFloat(deg[0]); b = 0; c = 0; d = parseFloat(deg[1] || deg[0]); e = 0; f = 0;
-      break;
-      case "rotate":
-        a = Math.cos(rad); b = Math.sin(rad); c = -b; d = a; e = 0; f = 0;
-      break;
-      case "skewX":
-        a = 1; b = 0; c = Math.tan(rad); d = 1; e = 0; f = 0;
-      break;
-      case "skewY":
-        a = 1; b = Math.tan(rad); c = 0; d = 1; e = 0; f = 0;
-      break;
-    }
-  }
-  var matri = new Matrix(a,b,c,d,e,f);
-  return matri;
-}
-
 //path要素のd属性で使われるA(rcTo)コマンドを処理
 function STArc() {
   return this;
@@ -1281,12 +1200,67 @@
   s.height = this.tar.clientHeight;
   return s;
 };
+
+//あらかじめ正規表現オブジェクトを生成しておく
+NAIBU.comaR = /[A-Za-z]+(?=\s*\()/g;
+NAIBU.listR = /\([^\)]+\)/g;
+NAIBU.degR = /[\-\d\.e]+/g;
+
 /*getCTMメソッド
  *CTMとは現在の利用座標系に対する変換行列
  */
 /*SVGMatrix*/ SVGElement.prototype.getCTM = function(){
-  if (!this.transform._matrix) {  //キャッシュがなければ、
-    var n = this.transform.baseVal.consolidate();
+  if (!this.transform._matrix) {           //キャッシュがなければ、
+    if (this.transform.animVal.numberOfItems === 0) {
+      try {
+      var tft = this.getNamedItemNS(null, "transform");
+      /*以下はtrasnform属性の値を解析して、
+       *TransformListオブジェクトに変換するもの
+       */
+      if (tft) {
+        tft = tft.nodeValue;
+        var coma = tft.match(NAIBU.comaR); //コマンド文字にマッチ translate
+        var list = tft.match(NAIBU.listR); //カッコ内のリストにマッチ (10 20 30...)
+        var a,b,c,d,e,f,lis,deg,rad,degli, t;
+        for (var j=0,cli=coma.length;j<cli;j++) {
+          lis = list[j], com = coma[j];
+          deg = lis.match(NAIBU.degR);
+          t = this.ownerDocument.documentElement.createSVGTransform();
+          degli = deg.length;
+          if (degli === 6) {
+            a = parseFloat(deg[0]); b = parseFloat(deg[1]); c = parseFloat(deg[2]); d = parseFloat(deg[3]); e = parseFloat(deg[4]); f = parseFloat(deg[5]);
+          } else {
+            rad = parseFloat(deg[0]) / 180 * Math.PI;
+            if (degli === 3) {
+              var cx = parseFloat(deg[1]), cy = parseFloat(deg[2]);
+              a = Math.cos(rad); b = Math.sin(rad); c = -b; d = a; e = (1-a)*cx-c*cy; f = -b*cx+(1-d)*cy;
+            } else if (degli <= 2) {
+              switch (com) {
+              case "translate":
+                a = 1; b = 0; c = 0; d = 1; e = parseFloat(deg[0]); f = parseFloat(deg[1] || 0);
+              break;
+              case "scale":
+                a = parseFloat(deg[0]); b = 0; c = 0; d = parseFloat(deg[1] || deg[0]); e = 0; f = 0;
+              break;
+              case "rotate":
+                a = Math.cos(rad); b = Math.sin(rad); c = -b; d = a; e = 0; f = 0;
+              break;
+              case "skewX":
+                a = 1; b = 0; c = Math.tan(rad); d = 1; e = 0; f = 0;
+              break;
+              case "skewY":
+                a = 1; b = Math.tan(rad); c = 0; d = 1; e = 0; f = 0;
+              break;
+              }
+            }
+          }
+          lis = com = deg = rad = null;
+        }
+        list = coma = mat = null;
+      }
+      }  catch(e) {stlog.add(e,816);}
+    }
+    var n = this.transform.animVal.consolidate();
     n = n ? n.matrix : this.documentElement.createSVGMatrix();
     this.transform._matrix = this.parentNode.getCTM().multiply(n);
   }
@@ -2642,12 +2616,6 @@
 SVGPathElement.prototype = new SVGElement();
 SVGPathElement.prototype.read = function(){
   this.d = this.getNamedItemNS(null, "d").nodeValue;
-  var tra = this.getNamedItemNS(null, "transform").nodeValue;
-  if (tra) {
-    var tta = this.transform.animVal;
-    var commands = tra.match(NAIBU.comR);
-    var degits = tra.match(NAIBU.degR);
-  }
 };
 //あらかじめ正規表現オブジェクトを生成しておく
 NAIBU.comaR = /[A-Za-z]+(?=\s*\()/g;
@@ -3442,10 +3410,10 @@
 SVGColorProfileElement.constructor = SVGElement;
 SVGColorProfileElement.prototype = new SVGElement();
 
-function SVGMPathElement : 
+function SVGMPathElement() /* : 
                 SVGElement,
                 SVGURIReference,
-                SVGExternalResourcesRequired {
+                SVGExternalResourcesRequired*/ {
   SVGElement.apply(this, arguments);
 };
 SVGColorProfileElement.constructor = SVGElement;




Sie-announce メーリングリストの案内
Back to archive index