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 ",