[Sie-announce] SIEコード [2100] ハッシュ検索を使って、SVGPathElementの高速化を試みた

Back to archive index

svnno****@sourc***** svnno****@sourc*****
2010年 10月 27日 (水) 22:44:42 JST


Revision: 2100
          http://sourceforge.jp/projects/sie/svn/view?view=rev&revision=2100
Author:   dhrname
Date:     2010-10-27 22:44:42 +0900 (Wed, 27 Oct 2010)

Log Message:
-----------
ハッシュ検索を使って、SVGPathElementの高速化を試みた

Modified Paths:
--------------
    branches/06x/062/org/w3c/dom/svg.js

Modified: branches/06x/062/org/w3c/dom/svg.js
===================================================================
--- branches/06x/062/org/w3c/dom/svg.js	2010-10-26 14:31:08 UTC (rev 2099)
+++ branches/06x/062/org/w3c/dom/svg.js	2010-10-27 13:44:42 UTC (rev 2100)
@@ -55,6 +55,7 @@
  * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
  */
 
+
 //これを頭に付けたら、内部処理用
 var  NAIBU = {};
 //documentを速くするために
@@ -2279,7 +2280,6 @@
   this.animatedNormalizedPathSegList = this.normalizedPathSegList;
   /*readonly SVGAnimatedNumber*/ this.pathLength = new SVGAnimatedNumber();
   //以下は、d属性に変更があった場合の処理
-  var ra = /\-/g, rb = /,/g, rc = /([a-yA-Y])/g, rd = /([zZ])/g, re = /,/;
   this.addEventListener("DOMAttrModified", function(evt){
     var tar = evt.target;
     if (evt.attrName === "d" && evt.newValue !== ""){
@@ -2292,14 +2292,14 @@
        *JSONにおける表現は以下のとおり
        *D = [["M", 20, 30], ["L", 20 40]]
        */
+      var taco = tar._com, sgs = taco.isSp;
       var dd = evt.newValue
-      .replace(ra, " -")
-      .replace(rb, " ")
-      .replace(rc, ",$1 ")
-      .replace(rd, ",$1 1")
-      .replace(re, "")
+      .replace(taco.isRa, " -")
+      .replace(taco.isRb, " ")
+      .replace(taco.isRc, ",$1 ")
+      .replace(taco.isRd, ",$1 1")
+      .replace(taco.isRe, "")
       .split(",");
-      var sgs = /\S+/g;
       for (var i=0, dli=dd.length;i<dli;++i) {
         D[i] = dd[i].match(sgs);
         for (var j=1, dili=D[i].length;j<dili;++j) {
@@ -2307,22 +2307,23 @@
         }
       }
       sgs = dd = null;
+      var isZ = taco._isZ, isM = taco._isM, isC = taco._isC, isL = taco._isL;
       for (var i=0, Dli=D.length; i < Dli; ++i) {
         var di = D[i], s;
         for (var j=1, dii=di[0], dili=di.length; j < dili; ++j) {
-          if (dii === "M") {
+          if (isM[dii]) {
             s = tar.createSVGPathSegMovetoAbs(di[j], di[j+1]);
             ++j;
           } else if (dii === "m") {
             s = tar.createSVGPathSegMovetoRel(di[j], di[j+1]);
             ++j;
-          } else if (dii === "L") {
+          } else if (isL[dii]) {
             s = tar.createSVGPathSegLinetoAbs(di[j], di[j+1]);
             ++j;
           } else if (dii === "l") {
             s = tar.createSVGPathSegLinetoRel(di[j], di[j+1]);
             ++j;
-          } else if (dii === "C") {
+          } else if (isC[dii]) {
             s = tar.createSVGPathSegCurvetoCubicAbs(di[j+4], di[j+5], di[j], di[j+1], di[j+2], di[j+3]);
             j += 5;
           } else if (dii === "c") {
@@ -2340,7 +2341,7 @@
           } else if (dii === "a") {
             s = tar.createSVGPathSegArcRel(di[j+5], di[j+6], di[j], di[j+1], di[j+2], di[j+3], di[j+4]);
             j += 6;
-          } else if (dii === "Z" || dii === "z") {
+          } else if (isZ[dii]) {
             s = tar.createSVGPathSegClosePath();
           } else if (dii === "S") {
             s = tar.createSVGPathSegCurvetoCubicSmoothAbs(di[j+2], di[j+3], di[j], di[j+1]);
@@ -2387,7 +2388,7 @@
             cx = ti.x;
             cy = ti.y;
           }
-          if (dii === "M") {
+          if (isM[dii]) {
             if (j !== 0) {
               /*Mコマンドが続いた場合は、2番目以降はLコマンドと解釈する
                *W3C SVG1.1の「8.3.2 The "moveto" commands」を参照
@@ -2413,15 +2414,15 @@
             startx = cx;
             starty = cy;
             tnl.appendItem(tar.createSVGPathSegMovetoAbs(cx, cy));
-          } else if (dii === "L") {
+          } else if (isL[dii]) {
             tnl.appendItem(ti);
           } else if (dii === "l") {
             tnl.appendItem(tar.createSVGPathSegLinetoAbs(cx, cy));
-          } else if (dii === "C") {
+          } else if (isC[dii]) {
             tnl.appendItem(ti);
           } else if (dii === "c") {
             tnl.appendItem(tar.createSVGPathSegCurvetoCubicAbs(cx, cy, ti.x1+rx, ti.y1+ry, ti.x2+rx, ti.y2+ry));
-          } else if (dii === "z") {
+          } else if (isZ[dii]) {
             cx = startx;
             cy = starty;
             tnl.appendItem(ti);
@@ -2536,7 +2537,7 @@
         }
         ti = dii = ts = null;
       }
-      cx = cy = xn = yn = startx = starty = null;
+      taco = cx = cy = xn = yn = startx = starty = null;
     }
     evt = null;
   }, false);
@@ -2579,19 +2580,20 @@
        */
       var tar = evt.target, matrix = tar.getScreenCTM(), tlist = tar.normalizedPathSegList, _parseInt = parseInt;
       var dat = [], ma = matrix.a, mb = matrix.b, mc = matrix.c, md = matrix.d, me = matrix.e, mf = matrix.f;
+      var isZ = tar._com._isZ, isM = tar._com._isM, isL = tar._com._isL, isC = tar._com._isC;
       for (var i=0, tli=tlist.numberOfItems;i<tli;++i) {
         var ti = tlist.getItem(i), tps = ti.pathSegTypeAsLetter;
         /*IE6の高速化のために、以下では、x += "";のような文字連結ではなくて、
          *x[data.length] = "";という形をとった
          */
-        if (tps === "z" || tps === "Z") {
+        if (isZ[tps]) {
           dat[dat.length] = " x ";
         } else {
-          if (tps === "M") {
+          if (isM[tps]) {
             dat[dat.length] = "m";
-          } else if (tps === "L") {
+          } else if (isL[tps]) {
             dat[dat.length] = "l";
-          } else if (tps === "C") {
+          } else if (isC[tps]) {
             dat[dat.length] = "c";
             /*CTM(mx)の行列と座標(x, y)の積を算出する。数学における表現は以下のとおり
              *[ma mc me]   [x]
@@ -2623,6 +2625,27 @@
 };
 SVGPathElement.constructor = SVGElement;
 SVGPathElement.prototype = new SVGElement();
+SVGPathElement.prototype._com = {
+  _isZ : {
+    z : 1,
+    Z : 1
+  },
+  _isC : {
+    C : 1
+  },
+  _isL : {
+    L : 1
+  },
+  _isM : {
+    M : 1
+  },
+  isRa : /\-/g,
+  isRb : /,/g,
+  isRc : /([a-yA-Y])/g,
+  isRd : /([zZ])/g,
+  isRe : /,/,
+  isSp : /\S+/g
+};
   /*float*/         SVGPathElement.prototype.getTotalLength = function() {
     var s = 0, nl = this.normalizedPathSegList;
     for (var i=1,nln=nl.numberOfItems,ms=null;i<nln;++i) {




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