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) {