svnno****@sourc*****
svnno****@sourc*****
2011年 4月 1日 (金) 23:55:52 JST
Revision: 2547 http://sourceforge.jp/projects/sie/svn/view?view=rev&revision=2547 Author: dhrname Date: 2011-04-01 23:55:52 +0900 (Fri, 01 Apr 2011) Log Message: ----------- SVGPathElementのクロージャーをやめて、最適化 Modified Paths: -------------- branches/07x/074/org/w3c/dom/svg.js Modified: branches/07x/074/org/w3c/dom/svg.js =================================================================== --- branches/07x/074/org/w3c/dom/svg.js 2011-04-01 14:44:29 UTC (rev 2546) +++ branches/07x/074/org/w3c/dom/svg.js 2011-04-01 14:55:52 UTC (rev 2547) @@ -2535,382 +2535,385 @@ this.animatedNormalizedPathSegList = this.normalizedPathSegList; /*readonly SVGAnimatedNumber*/ this.pathLength = new SVGAnimatedNumber(); //以下は、d属性に変更があった場合の処理 - this.addEventListener("DOMAttrModified", function(evt){ - var tar = evt.target; - if (evt.attrName === "d" && evt.newValue !== ""){ - /* d属性の値が空の場合は、描画を行わないようにする - * - *SVG1.1 「8.3.9 The grammar for path data」の項目にある最後の文章を参照 - */ - var tnl = tar.normalizedPathSegList, - tlist = tar.pathSegList, - D = []; - if (tnl.numberOfItems > 0) { - tnl.clear(); - tlist.clear(); + this.addEventListener("DOMAttrModified", this._attrModi, false); + /*以下の処理は、このpath要素ノードがDOMツリーに追加されて初めて、 + *描画が開始されることを示す。つまり、appendChildで挿入されない限り、描画をしない。 + */ + this.addEventListener("DOMNodeInserted", this._nodeInsert, false); + return this; +}; +SVGPathElement.constructor = SVGElement; +SVGPathElement.prototype = new SVGElement(); +SVGPathElement.prototype._attrModi = function(evt){ + var tar = evt.target; + if (evt.attrName === "d" && evt.newValue !== ""){ + /* d属性の値が空の場合は、描画を行わないようにする + * + *SVG1.1 「8.3.9 The grammar for path data」の項目にある最後の文章を参照 + */ + var tnl = tar.normalizedPathSegList, + tlist = tar.pathSegList, + D = []; + if (tnl.numberOfItems > 0) { + tnl.clear(); + tlist.clear(); + } + /*d属性の値を正規表現を用いて、二次元配列Dに変換している。もし、d属性の値が"M 20 30 L20 40"ならば、 + *JSONにおける表現は以下のとおり + *D = [["M", 20, 30], ["L", 20 40]] + */ + var taco = tar._com, + sgs = taco.isSp, + dd = evt.newValue + .replace(taco.isRa, " -") + .replace(taco.isRb, " ") + .replace(taco.isRc, ",$1 ") + .replace(taco.isRd, ",$1 1") + .replace(taco.isRe, "") + .split(","), + dli=dd.length; + for (var i=0;i<dli;++i) { + D[i] = dd[i].match(sgs); + for (var j=1, dili=D[i].length;j<dili;++j) { + D[i][j] = +(D[i][j]); } - /*d属性の値を正規表現を用いて、二次元配列Dに変換している。もし、d属性の値が"M 20 30 L20 40"ならば、 - *JSONにおける表現は以下のとおり - *D = [["M", 20, 30], ["L", 20 40]] - */ - var taco = tar._com, - sgs = taco.isSp, - dd = evt.newValue - .replace(taco.isRa, " -") - .replace(taco.isRb, " ") - .replace(taco.isRc, ",$1 ") - .replace(taco.isRd, ",$1 1") - .replace(taco.isRe, "") - .split(","), - dli=dd.length; - for (var i=0;i<dli;++i) { - D[i] = dd[i].match(sgs); - for (var j=1, dili=D[i].length;j<dili;++j) { - D[i][j] = +(D[i][j]); + } + sgs = dd = null; + var isZ = taco._isZ, isM = taco._isM, isC = taco._isC, isL = taco._isL; + for (var i=0; i < dli; ++i) { + var di = D[i], s; + for (var j=1, dii=di[0], dili=di.length; j < dili; ++j) { + 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 (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 (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") { + s = tar.createSVGPathSegCurvetoCubicRel(di[j+4], di[j+5], di[j], di[j+1], di[j+2], di[j+3]); + j += 5; + } else if (dii === "Q") { + s = tar.createSVGPathSegCurvetoQuadraticAbs(di[j+2], di[j+3], di[j], di[j+1]); + j += 3; + } else if (dii === "q") { + s = tar.createSVGPathSegCurvetoQuadraticRel(di[j+2], di[j+3], di[j], di[j+1]); + j += 3; + } else if (dii === "A") { + s = tar.createSVGPathSegArcAbs(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 === "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 (isZ[dii]) { + s = tar.createSVGPathSegClosePath(); + } else if (dii === "S") { + s = tar.createSVGPathSegCurvetoCubicSmoothAbs(di[j+2], di[j+3], di[j], di[j+1]); + j += 3; + } else if (dii === "s") { + s = tar.createSVGPathSegCurvetoCubicSmoothRel(di[j+2], di[j+3], di[j], di[j+1]); + j += 3; + } else if (dii === "T") { + s = tar.createSVGPathSegCurvetoQuadraticSmoothAbs(di[j], di[j+1]); + ++j; + } else if (dii === "t") { + s = tar.createSVGPathSegCurvetoQuadraticSmoothRel(di[j], di[j+1]); + ++j; + } else if (dii === "H") { + s = tar.createSVGPathSegLinetoHorizontalAbs(di[j]); + } else if (dii === "h") { + s = tar.createSVGPathSegLinetoHorizontalRel(di[j]); + } else if (dii === "V") { + s = tar.createSVGPathSegLinetoVerticalAbs(di[j]); + } else if (dii === "v") { + s = tar.createSVGPathSegLinetoVerticalRel(di[j]); + } else { + s = new SVGPathSeg(); } + tlist.appendItem(s); } - sgs = dd = null; - var isZ = taco._isZ, isM = taco._isM, isC = taco._isC, isL = taco._isL; - for (var i=0; i < dli; ++i) { - var di = D[i], s; - for (var j=1, dii=di[0], dili=di.length; j < dili; ++j) { - 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 (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 (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") { - s = tar.createSVGPathSegCurvetoCubicRel(di[j+4], di[j+5], di[j], di[j+1], di[j+2], di[j+3]); - j += 5; - } else if (dii === "Q") { - s = tar.createSVGPathSegCurvetoQuadraticAbs(di[j+2], di[j+3], di[j], di[j+1]); - j += 3; - } else if (dii === "q") { - s = tar.createSVGPathSegCurvetoQuadraticRel(di[j+2], di[j+3], di[j], di[j+1]); - j += 3; - } else if (dii === "A") { - s = tar.createSVGPathSegArcAbs(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 === "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 (isZ[dii]) { - s = tar.createSVGPathSegClosePath(); - } else if (dii === "S") { - s = tar.createSVGPathSegCurvetoCubicSmoothAbs(di[j+2], di[j+3], di[j], di[j+1]); - j += 3; - } else if (dii === "s") { - s = tar.createSVGPathSegCurvetoCubicSmoothRel(di[j+2], di[j+3], di[j], di[j+1]); - j += 3; - } else if (dii === "T") { - s = tar.createSVGPathSegCurvetoQuadraticSmoothAbs(di[j], di[j+1]); - ++j; - } else if (dii === "t") { - s = tar.createSVGPathSegCurvetoQuadraticSmoothRel(di[j], di[j+1]); - ++j; - } else if (dii === "H") { - s = tar.createSVGPathSegLinetoHorizontalAbs(di[j]); - } else if (dii === "h") { - s = tar.createSVGPathSegLinetoHorizontalRel(di[j]); - } else if (dii === "V") { - s = tar.createSVGPathSegLinetoVerticalAbs(di[j]); - } else if (dii === "v") { - s = tar.createSVGPathSegLinetoVerticalRel(di[j]); - } else { - s = new SVGPathSeg(); - } - tlist.appendItem(s); + } + D = null; + /*以下の処理は、pathSegListからnormalizedPathSegListへの + *変換をする処理。相対座標を絶対座標に変換して、M、L、Cコマンドに正規化していく + */ + var cx = 0, cy = 0, //現在セグメントの終了点の絶対座標を示す (相対座標を絶対座標に変換するときに使用) + xn = 0, yn = 0, //T,tコマンドで仮想的な座標を算出するのに用いる。第一コントロール点 + startx = 0, starty = 0; //M,mコマンドにおける始点座標(Z,zコマンドで用いる) + for (var j=0, tli=tlist.numberOfItems;j<tli;++j) { + var ti = tlist.getItem(j), + ts = ti.pathSegType, + dii = ti.pathSegTypeAsLetter; + if (ts === /*SVGPathSeg.PATHSEG_UNKNOWN*/ 0) { + } else { + var rx = cx, ry = cy; //rx, ryは前のセグメントの終了点 + if (ts % 2 === 1) { //相対座標ならば + cx += ti.x; + cy += ti.y; + } else { + cx = ti.x; + cy = ti.y; } - } - D = null; - /*以下の処理は、pathSegListからnormalizedPathSegListへの - *変換をする処理。相対座標を絶対座標に変換して、M、L、Cコマンドに正規化していく - */ - var cx = 0, cy = 0, //現在セグメントの終了点の絶対座標を示す (相対座標を絶対座標に変換するときに使用) - xn = 0, yn = 0, //T,tコマンドで仮想的な座標を算出するのに用いる。第一コントロール点 - startx = 0, starty = 0; //M,mコマンドにおける始点座標(Z,zコマンドで用いる) - for (var j=0, tli=tlist.numberOfItems;j<tli;++j) { - var ti = tlist.getItem(j), - ts = ti.pathSegType, - dii = ti.pathSegTypeAsLetter; - if (ts === /*SVGPathSeg.PATHSEG_UNKNOWN*/ 0) { - } else { - var rx = cx, ry = cy; //rx, ryは前のセグメントの終了点 - if (ts % 2 === 1) { //相対座標ならば - cx += ti.x; - cy += ti.y; - } else { - cx = ti.x; - cy = ti.y; + if (isC[dii]) { + tnl.appendItem(ti); + } else if (isL[dii]) { + tnl.appendItem(ti); + } else if (isM[dii]) { + if (j !== 0) { + /*Mコマンドが続いた場合は、2番目以降はLコマンドと解釈する + *W3C SVG1.1の「8.3.2 The "moveto" commands」を参照 + *http://www.w3.org/TR/SVG11/paths.html#PathDataMovetoCommands + */ + var tg = tlist.getItem(j-1); + if (tg.pathSegTypeAsLetter === "M") { + tnl.appendItem(tar.createSVGPathSegLinetoAbs(cx, cy)); + continue; + } } - if (isC[dii]) { - tnl.appendItem(ti); - } else if (isL[dii]) { - tnl.appendItem(ti); - } else if (isM[dii]) { - if (j !== 0) { - /*Mコマンドが続いた場合は、2番目以降はLコマンドと解釈する - *W3C SVG1.1の「8.3.2 The "moveto" commands」を参照 - *http://www.w3.org/TR/SVG11/paths.html#PathDataMovetoCommands - */ - var tg = tlist.getItem(j-1); - if (tg.pathSegTypeAsLetter === "M") { - tnl.appendItem(tar.createSVGPathSegLinetoAbs(cx, cy)); - continue; - } + startx = cx; + starty = cy; + tnl.appendItem(ti); + } else if (dii === "m") { + if (j !== 0) { + var tg = tlist.getItem(j-1); + if (tg.pathSegTypeAsLetter === "m") { + tnl.appendItem(tar.createSVGPathSegLinetoAbs(cx, cy)); + continue; } - startx = cx; - starty = cy; - tnl.appendItem(ti); - } else if (dii === "m") { - if (j !== 0) { - var tg = tlist.getItem(j-1); - if (tg.pathSegTypeAsLetter === "m") { - tnl.appendItem(tar.createSVGPathSegLinetoAbs(cx, cy)); - continue; + } + startx = cx; + starty = cy; + tnl.appendItem(tar.createSVGPathSegMovetoAbs(cx, cy)); + } else if (dii === "l") { + tnl.appendItem(tar.createSVGPathSegLinetoAbs(cx, cy)); + } else if (dii === "c") { + tnl.appendItem(tar.createSVGPathSegCurvetoCubicAbs(cx, cy, ti.x1+rx, ti.y1+ry, ti.x2+rx, ti.y2+ry)); + } else if (isZ[dii]) { + cx = startx; + cy = starty; + tnl.appendItem(ti); + } else if (dii === "Q") { + xn = 2*cx - ti.x1; + yn = 2*cy - ti.y1; + //2次スプライン曲線は近似的な3次ベジェ曲線に変換している + tnl.appendItem(tar.createSVGPathSegCurvetoCubicAbs(cx, cy, (rx + 2*ti.x1) / 3, (ry + 2*ti.y1) / 3, (2*ti.x1 + cx) / 3, (2*ti.y1 + cy) / 3)); + } else if (dii === "q") { + var x1 = ti.x1 + rx, y1 = ti.y1 + ry; + xn = 2*cx - x1; + yn = 2*cy - y1; + tnl.appendItem(tar.createSVGPathSegCurvetoCubicAbs(cx, cy, (rx + 2*x1) / 3, (ry + 2*y1) / 3, (2*x1 + cx) / 3, (2*y1 + cy) / 3)); + x1 = y1 = null; + } else if (dii === "A" || dii === "a") { + (function(ti, cx, cy, rx, ry, tar, tnl) { //変数を隠蔽するためのfunction + /*以下は、Arctoを複数のCuvetoに変換する処理 + *SVG 1.1 「F.6 Elliptical arc implementation notes」の章を参照 + *http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes + */ + if (ti.r1 === 0 || ti.r2 === 0) { + return; + } + var fS = ti.sweepFlag, + psai = ti.angle, + r1 = _math.abs(ti.r1), + r2 = _math.abs(ti.r2), + ctx = (rx - cx) / 2, cty = (ry - cy) / 2, + cpsi = _math.cos(psai * _math.PI / 180), + spsi = _math.sin(psai * _math.PI / 180), + rxd = cpsi*ctx + spsi*cty, + ryd = -1*spsi*ctx + cpsi*cty, + rxdd = rxd * rxd, rydd = ryd * ryd, + r1x = r1 * r1, + r2y = r2 * r2, + lamda = rxdd/r1x + rydd/r2y, + sds; + if (lamda > 1) { + r1 = _math.sqrt(lamda) * r1; + r2 = _math.sqrt(lamda) * r2; + sds = 0; + } else{ + var seif = 1; + if (ti.largeArcFlag === fS) { + seif = -1; } + sds = seif * _math.sqrt((r1x*r2y - r1x*rydd - r2y*rxdd) / (r1x*rydd + r2y*rxdd)); } - startx = cx; - starty = cy; - tnl.appendItem(tar.createSVGPathSegMovetoAbs(cx, cy)); - } else if (dii === "l") { - tnl.appendItem(tar.createSVGPathSegLinetoAbs(cx, cy)); - } else if (dii === "c") { - tnl.appendItem(tar.createSVGPathSegCurvetoCubicAbs(cx, cy, ti.x1+rx, ti.y1+ry, ti.x2+rx, ti.y2+ry)); - } else if (isZ[dii]) { - cx = startx; - cy = starty; - tnl.appendItem(ti); - } else if (dii === "Q") { - xn = 2*cx - ti.x1; - yn = 2*cy - ti.y1; - //2次スプライン曲線は近似的な3次ベジェ曲線に変換している - tnl.appendItem(tar.createSVGPathSegCurvetoCubicAbs(cx, cy, (rx + 2*ti.x1) / 3, (ry + 2*ti.y1) / 3, (2*ti.x1 + cx) / 3, (2*ti.y1 + cy) / 3)); - } else if (dii === "q") { - var x1 = ti.x1 + rx, y1 = ti.y1 + ry; - xn = 2*cx - x1; - yn = 2*cy - y1; - tnl.appendItem(tar.createSVGPathSegCurvetoCubicAbs(cx, cy, (rx + 2*x1) / 3, (ry + 2*y1) / 3, (2*x1 + cx) / 3, (2*y1 + cy) / 3)); - x1 = y1 = null; - } else if (dii === "A" || dii === "a") { - (function(ti, cx, cy, rx, ry, tar, tnl) { //変数を隠蔽するためのfunction - /*以下は、Arctoを複数のCuvetoに変換する処理 - *SVG 1.1 「F.6 Elliptical arc implementation notes」の章を参照 - *http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes - */ - if (ti.r1 === 0 || ti.r2 === 0) { - return; - } - var fS = ti.sweepFlag, - psai = ti.angle, - r1 = _math.abs(ti.r1), - r2 = _math.abs(ti.r2), - ctx = (rx - cx) / 2, cty = (ry - cy) / 2, - cpsi = _math.cos(psai * _math.PI / 180), - spsi = _math.sin(psai * _math.PI / 180), - rxd = cpsi*ctx + spsi*cty, - ryd = -1*spsi*ctx + cpsi*cty, - rxdd = rxd * rxd, rydd = ryd * ryd, - r1x = r1 * r1, - r2y = r2 * r2, - lamda = rxdd/r1x + rydd/r2y, - sds; - if (lamda > 1) { - r1 = _math.sqrt(lamda) * r1; - r2 = _math.sqrt(lamda) * r2; - sds = 0; - } else{ - var seif = 1; - if (ti.largeArcFlag === fS) { - seif = -1; - } - sds = seif * _math.sqrt((r1x*r2y - r1x*rydd - r2y*rxdd) / (r1x*rydd + r2y*rxdd)); - } - var txd = sds*r1*ryd / r2, - tyd = -1 * sds*r2*rxd / r1, - tx = cpsi*txd - spsi*tyd + (rx+cx)/2, - ty = spsi*txd + cpsi*tyd + (ry+cy)/2, - rad = _math.atan2((ryd-tyd)/r2, (rxd-txd)/r1) - _math.atan2(0, 1), - s1 = (rad >= 0) ? rad : 2 * _math.PI + rad, - rad = _math.atan2((-ryd-tyd)/r2, (-rxd-txd)/r1) - _math.atan2((ryd-tyd)/r2, (rxd-txd)/r1), - dr = (rad >= 0) ? rad : 2 * _math.PI + rad; - if (!fS && dr > 0) { - dr -= 2*_math.PI; - } else if (fS && dr < 0) { - dr += 2*_math.PI; - } - var sse = dr * 2 / _math.PI, - seg = _math.ceil(sse<0 ? -1*sse : sse), - segr = dr / seg, - t = 8/3 * _math.sin(segr/4) * _math.sin(segr/4) / _math.sin(segr/2), - cpsir1 = cpsi * r1, cpsir2 = cpsi * r2, - spsir1 = spsi * r1, spsir2 = spsi * r2, - mc = _math.cos(s1), - ms = _math.sin(s1), - x2 = rx - t * (cpsir1*ms + spsir2*mc), - y2 = ry - t * (spsir1*ms - cpsir2*mc); - for (var n = 0; n < seg; ++n) { - s1 += segr; - mc = _math.cos(s1); - ms = _math.sin(s1); - var x3 = cpsir1*mc - spsir2*ms + tx, - y3 = spsir1*mc + cpsir2*ms + ty, - dx = -t * (cpsir1*ms + spsir2*mc), - dy = -t * (spsir1*ms - cpsir2*mc); - tnl.appendItem(tar.createSVGPathSegCurvetoCubicAbs(x3, y3, x2, y2, x3-dx, y3-dy)); - x2 = x3 + dx; - y2 = y3 + dy; - } - })(ti, cx, cy, rx, ry, tar, tnl); - } else if (dii === "S") { - if (j !== 0) { - var tg = tnl.getItem(tnl.numberOfItems-1); - if (tg.pathSegTypeAsLetter === "C") { - var x1 = 2*tg.x - tg.x2, - y1 = 2*tg.y - tg.y2; - } else { //前のコマンドがCでなければ、現在の座標を第1コントロール点に用いる - var x1 = rx, - y1 = ry; - } - } else { + var txd = sds*r1*ryd / r2, + tyd = -1 * sds*r2*rxd / r1, + tx = cpsi*txd - spsi*tyd + (rx+cx)/2, + ty = spsi*txd + cpsi*tyd + (ry+cy)/2, + rad = _math.atan2((ryd-tyd)/r2, (rxd-txd)/r1) - _math.atan2(0, 1), + s1 = (rad >= 0) ? rad : 2 * _math.PI + rad, + rad = _math.atan2((-ryd-tyd)/r2, (-rxd-txd)/r1) - _math.atan2((ryd-tyd)/r2, (rxd-txd)/r1), + dr = (rad >= 0) ? rad : 2 * _math.PI + rad; + if (!fS && dr > 0) { + dr -= 2*_math.PI; + } else if (fS && dr < 0) { + dr += 2*_math.PI; + } + var sse = dr * 2 / _math.PI, + seg = _math.ceil(sse<0 ? -1*sse : sse), + segr = dr / seg, + t = 8/3 * _math.sin(segr/4) * _math.sin(segr/4) / _math.sin(segr/2), + cpsir1 = cpsi * r1, cpsir2 = cpsi * r2, + spsir1 = spsi * r1, spsir2 = spsi * r2, + mc = _math.cos(s1), + ms = _math.sin(s1), + x2 = rx - t * (cpsir1*ms + spsir2*mc), + y2 = ry - t * (spsir1*ms - cpsir2*mc); + for (var n = 0; n < seg; ++n) { + s1 += segr; + mc = _math.cos(s1); + ms = _math.sin(s1); + var x3 = cpsir1*mc - spsir2*ms + tx, + y3 = spsir1*mc + cpsir2*ms + ty, + dx = -t * (cpsir1*ms + spsir2*mc), + dy = -t * (spsir1*ms - cpsir2*mc); + tnl.appendItem(tar.createSVGPathSegCurvetoCubicAbs(x3, y3, x2, y2, x3-dx, y3-dy)); + x2 = x3 + dx; + y2 = y3 + dy; + } + })(ti, cx, cy, rx, ry, tar, tnl); + } else if (dii === "S") { + if (j !== 0) { + var tg = tnl.getItem(tnl.numberOfItems-1); + if (tg.pathSegTypeAsLetter === "C") { + var x1 = 2*tg.x - tg.x2, + y1 = 2*tg.y - tg.y2; + } else { //前のコマンドがCでなければ、現在の座標を第1コントロール点に用いる var x1 = rx, y1 = ry; } - tnl.appendItem(tar.createSVGPathSegCurvetoCubicAbs(cx, cy, x1, y1, ti.x2, ti.y2)); - x1 = y1 = null; - } else if (dii === "s") { - if (j !== 0) { - var tg = tnl.getItem(tnl.numberOfItems-1); - if (tg.pathSegTypeAsLetter === "C") { - var x1 = 2*tg.x - tg.x2, - y1 = 2*tg.y - tg.y2; - } else { - var x1 = rx, - y1 = ry; - } + } else { + var x1 = rx, + y1 = ry; + } + tnl.appendItem(tar.createSVGPathSegCurvetoCubicAbs(cx, cy, x1, y1, ti.x2, ti.y2)); + x1 = y1 = null; + } else if (dii === "s") { + if (j !== 0) { + var tg = tnl.getItem(tnl.numberOfItems-1); + if (tg.pathSegTypeAsLetter === "C") { + var x1 = 2*tg.x - tg.x2, + y1 = 2*tg.y - tg.y2; } else { var x1 = rx, y1 = ry; } - tnl.appendItem(tar.createSVGPathSegCurvetoCubicAbs(cx, cy, x1, y1, ti.x2+rx, ti.y2+ry)); - x1 = y1 = null; - } else if (dii === "T" || dii === "t") { - if (j !== 0) { - var tg = tlist.getItem(j-1); - if ("QqTt".indexOf(tg.pathSegTypeAsLetter) > -1) { - } else { - xn = rx, yn = ry; - } - } else { + } else { + var x1 = rx, + y1 = ry; + } + tnl.appendItem(tar.createSVGPathSegCurvetoCubicAbs(cx, cy, x1, y1, ti.x2+rx, ti.y2+ry)); + x1 = y1 = null; + } else if (dii === "T" || dii === "t") { + if (j !== 0) { + var tg = tlist.getItem(j-1); + if ("QqTt".indexOf(tg.pathSegTypeAsLetter) > -1) { + } else { xn = rx, yn = ry; } - tnl.appendItem(tar.createSVGPathSegCurvetoCubicAbs(cx, cy, (rx + 2*xn) / 3, (ry + 2*yn) / 3, (2*xn + cx) / 3, (2*yn + cy) / 3)); - xn = 2*cx - xn; - yn = 2*cy - yn; - xx1 = yy1 = null; - } else if (dii === "H" || dii === "h") { - tnl.appendItem(tar.createSVGPathSegLinetoAbs(cx, ry)); - cy = ry; //勝手にti.yが0としているため - } else if (dii === "V" || dii === "v") { - tnl.appendItem(tar.createSVGPathSegLinetoAbs(rx, cy)); - cx = rx; + } else { + xn = rx, yn = ry; } + tnl.appendItem(tar.createSVGPathSegCurvetoCubicAbs(cx, cy, (rx + 2*xn) / 3, (ry + 2*yn) / 3, (2*xn + cx) / 3, (2*yn + cy) / 3)); + xn = 2*cx - xn; + yn = 2*cy - yn; + xx1 = yy1 = null; + } else if (dii === "H" || dii === "h") { + tnl.appendItem(tar.createSVGPathSegLinetoAbs(cx, ry)); + cy = ry; //勝手にti.yが0としているため + } else if (dii === "V" || dii === "v") { + tnl.appendItem(tar.createSVGPathSegLinetoAbs(rx, cy)); + cx = rx; } } } - evt = tar = taco = cx = cy = xn = yn = startx = starty = tnl = tlist = ti = dii = ts = isZ = isM = isL = isC = s = null; - }, false); - /*以下の処理は、このpath要素ノードがDOMツリーに追加されて初めて、 - *描画が開始されることを示す。つまり、appendChildで挿入されない限り、描画をしない。 + } + evt = tar = taco = cx = cy = xn = yn = startx = starty = tnl = tlist = ti = dii = ts = isZ = isM = isL = isC = s = null; +}; +SVGPathElement.prototype._nodeInsert = function(evt){ + var tar = evt.target; + if (evt.eventPhase === /*Event.BUBBLING_PHASE*/ 3) { + return; //強制終了させる + } + var tnext = tar.nextSibling, + tpar = tar.parentNode, + isLast = true; + if (tnext && tnext._tar && tpar._tar && (tnext._tar.parentNode === tpar._tar)) { + tpar._tar.insertBefore(tar._tar, tnext._tar); + } else if (tnext && !tnext._tar && tpar._tar) { + /*以下の処理は、_tarプロパティがない要素オブジェクトがあるため、それに対処するもの + *use要素や実体参照などは_tarプロパティがないことに注意 + */ + while (tnext) { + if (tnext._tar && (tnext._tar.parentNode === tpar._tar)) { + tpar._tar.insertBefore(tar._tar, tnext._tar); + isLast = false; + } + tnext = tnext.nextSibling; + } + if (isLast) { + tpar._tar.appendChild(tar._tar); + } + } else if (!tnext && tpar._tar) { + tpar._tar.appendChild(tar._tar); + } + tnext = tpar = isLast = null; + tar.addEventListener("DOMNodeInsertedIntoDocument", tar._nodeInsertInto, false); + evt = tar = null; +}; +SVGPathElement.prototype._nodeInsertInto = function(evt){ + /*以下の処理は、normalizedpathSegListとCTMに基づいて、 + *SVGのd属性をVMLに変換していく処理である。 */ - this.addEventListener("DOMNodeInserted", function(evt){ - var tar = evt.target; - if (evt.eventPhase === /*Event.BUBBLING_PHASE*/ 3) { - return; //強制終了させる - } - var tnext = tar.nextSibling, - tpar = tar.parentNode, - isLast = true; - if (tnext && tnext._tar && tpar._tar && (tnext._tar.parentNode === tpar._tar)) { - tpar._tar.insertBefore(tar._tar, tnext._tar); - } else if (tnext && !tnext._tar && tpar._tar) { - /*以下の処理は、_tarプロパティがない要素オブジェクトがあるため、それに対処するもの - *use要素や実体参照などは_tarプロパティがないことに注意 + var tar = evt.target, + matrix = tar.getScreenCTM(), + tlist = tar.normalizedPathSegList, + _parseInt = _pInt, + dat = [], + ma = matrix.a, mb = matrix.b, mc = matrix.c, md = matrix.d, me = matrix.e, mf = matrix.f, + cname = tar._com._nameCom, + isZ = tar._com._isZ, isC = tar._com._isC; + for (var i=0, tli=tlist.numberOfItems;i<tli;++i) { + var ti = tlist[i], + tps = ti.pathSegTypeAsLetter, + t = cname[tps]; + if (isC[tps]) { + /*CTM(mx)の行列と座標(x, y)の積を算出する。数学における表現は以下のとおり + *[ma mc me] [x] + *[mb md mf] * [y] + *[0 0 1 ] [1] */ - while (tnext) { - if (tnext._tar && (tnext._tar.parentNode === tpar._tar)) { - tpar._tar.insertBefore(tar._tar, tnext._tar); - isLast = false; - } - tnext = tnext.nextSibling; - } - if (isLast) { - tpar._tar.appendChild(tar._tar); - } - } else if (!tnext && tpar._tar) { - tpar._tar.appendChild(tar._tar); + t += ([_parseInt(ma*ti.x1 + mc*ti.y1 + me, 10), + _parseInt(mb*ti.x1 + md*ti.y1 + mf, 10), + _parseInt(ma*ti.x2 + mc*ti.y2 + me, 10), + _parseInt(mb*ti.x2 + md*ti.y2 + mf, 10), + _parseInt(ma*ti.x + mc*ti.y + me, 10), + _parseInt(mb*ti.x + md*ti.y + mf, 10)]).join(" "); + } else if (!isZ[tps]) { + t += _parseInt(ma*ti.x + mc*ti.y + me, 10)+ " " +_parseInt(mb*ti.x + md*ti.y + mf, 10); } - tnext = tpar = isLast = null; - tar.addEventListener("DOMNodeInsertedIntoDocument", function(evt){ - /*以下の処理は、normalizedpathSegListとCTMに基づいて、 - *SVGのd属性をVMLに変換していく処理である。 - */ - var tar = evt.target, - matrix = tar.getScreenCTM(), - tlist = tar.normalizedPathSegList, - _parseInt = _pInt, - dat = [], - ma = matrix.a, mb = matrix.b, mc = matrix.c, md = matrix.d, me = matrix.e, mf = matrix.f, - cname = tar._com._nameCom, - isZ = tar._com._isZ, isC = tar._com._isC; - for (var i=0, tli=tlist.numberOfItems;i<tli;++i) { - var ti = tlist[i], - tps = ti.pathSegTypeAsLetter, - t = cname[tps]; - if (isC[tps]) { - /*CTM(mx)の行列と座標(x, y)の積を算出する。数学における表現は以下のとおり - *[ma mc me] [x] - *[mb md mf] * [y] - *[0 0 1 ] [1] - */ - t += ([_parseInt(ma*ti.x1 + mc*ti.y1 + me, 10), - _parseInt(mb*ti.x1 + md*ti.y1 + mf, 10), - _parseInt(ma*ti.x2 + mc*ti.y2 + me, 10), - _parseInt(mb*ti.x2 + md*ti.y2 + mf, 10), - _parseInt(ma*ti.x + mc*ti.y + me, 10), - _parseInt(mb*ti.x + md*ti.y + mf, 10)]).join(" "); - } else if (!isZ[tps]) { - t += _parseInt(ma*ti.x + mc*ti.y + me, 10)+ " " +_parseInt(mb*ti.x + md*ti.y + mf, 10); - } - dat[i] = t; - } - var vi = tar.ownerDocument.documentElement, - w = vi.width.baseVal.value, - h = vi.height.baseVal.value, - tt = tar._tar; - dat[dat.length] = " e"; - tt.path = dat.join(" "); - tt.coordsize = w + " " + h; - NAIBU._setPaint(tar, matrix); - delete tar._cacheMatrix, tar._currentStyle; - evt = tar = dat = t = w = h = matrix = tlist = x = y = _parseInt = ma = mb = mc = md = me = mf = vi = isZ = isC = i = tli = tps = ti = cname = tt = null; - }, false); - evt = tar = null; - }, false); - return this; + dat[i] = t; + } + var vi = tar.ownerDocument.documentElement, + w = vi.width.baseVal.value, + h = vi.height.baseVal.value, + tt = tar._tar; + dat[dat.length] = " e"; + tt.path = dat.join(" "); + tt.coordsize = w + " " + h; + NAIBU._setPaint(tar, matrix); + delete tar._cacheMatrix, tar._currentStyle; + evt = tar = dat = t = w = h = matrix = tlist = x = y = _parseInt = ma = mb = mc = md = me = mf = vi = isZ = isC = i = tli = tps = ti = cname = tt = null; }; -SVGPathElement.constructor = SVGElement; -SVGPathElement.prototype = new SVGElement(); SVGPathElement.prototype._com = { _nameCom : { z : " x ",