svnno****@sourc*****
svnno****@sourc*****
2010年 3月 16日 (火) 20:24:24 JST
Revision: 1737 http://sourceforge.jp/projects/sie/svn/view?view=rev&revision=1737 Author: dhrname Date: 2010-03-16 20:24:24 +0900 (Tue, 16 Mar 2010) Log Message: ----------- path要素のd属性をいくつか修正 Modified Paths: -------------- branches/ufltima/dom/svg.js Modified: branches/ufltima/dom/svg.js =================================================================== --- branches/ufltima/dom/svg.js 2010-03-15 14:44:14 UTC (rev 1736) +++ branches/ufltima/dom/svg.js 2010-03-16 11:24:24 UTC (rev 1737) @@ -249,9 +249,10 @@ } } } - evt.initMutationEvent("DOMNodeInsertedIntoDocument", false, false, null, null, null, null, null); - tar.dispatchEvent(evt); //描画を開始するために、dispatchEventメソッドを使う - evt = name = tar = null; + var evtt = tar.ownerDocument.createEvent("MutationEvents"); + evtt.initMutationEvent("DOMNodeInsertedIntoDocument", false, false, null, null, null, null, null); + tar.dispatchEvent(evtt); //描画を開始するために、dispatchEventメソッドを使う + evtt = name = tar = null; }, false); return this; }; @@ -394,6 +395,7 @@ function SVGNumberList() { /*readonly unsigned long*/ this.numberOfItems = 0; + this._list = []; //リストの本体 return this; }; for (var prop in SVGStringList.prototype) { //prototypeのコピーで継承を行う @@ -1628,6 +1630,7 @@ }; function SVGPathSegList() { /*readonly unsigned long*/ this.numberOfItems = 0; + this._list = []; //リストの本体 return this; }; for (var prop in SVGStringList.prototype) { //prototypeのコピーで継承を行う @@ -1729,19 +1732,20 @@ tlist.appendItem(s); } } + D = null; /*以下の処理は、pathSegListからnormalizedPathSegListへの *変換をする処理。相対座標を絶対座標に変換して、M、L、Cコマンドに正規化していく */ - var cx = cy = 0; //現在セグメントの終了点の絶対座標を示す (相対座標を絶対座標に変換するときに使用) - var xn = yn = 0; //subpath の始点の絶対座標を示す (SコマンドやTコマンドなどで使用) - for (var i=0, tli=tlist.numberOfItems;i<tli;++i) { - var ti = tlist.getItem(i), ts = ti.pathSegType, dii = ti.pathSegTypeAsLetter; + var cx = 0, cy = 0; //現在セグメントの終了点の絶対座標を示す (相対座標を絶対座標に変換するときに使用) + var xn = 0, yn = 0; //subpath の始点の絶対座標を示す (SコマンドやTコマンドなどで使用) + 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) { } else if (ts === SVGPathSeg.PATHSEG_CLOSEPATH) { tnl.appendItem(ti); } else { + var rx = cx, ry = cy; //rx, ryは前のセグメントの終了点 if (ts % 2 === 1) { //相対座標ならば - var rx = cx, ry = cy; //rx, ryは前のセグメントの終了点 cx += ti.x; cy += ti.y; } else { @@ -1749,132 +1753,134 @@ cy = ti.y; } if (dii === "M") { - if (i !== 0) { + 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 = tlis.getItem(i-1); + var tg = tlist.getItem(j-1); if (tg.pathSegTypeAsLetter === "M") { - tnl.appendItem(tar.createSVGPathSegLinetoABS(cx, cy)); + tnl.appendItem(tar.createSVGPathSegLinetoAbs(cx, cy)); continue; } } tnl.appendItem(ti); } else if (dii === "m") { - if (i !== 0) { - var tg = tlist.getItem(i-1); + if (j !== 0) { + var tg = tlist.getItem(j-1); if (tg.pathSegTypeAsLetter === "m") { - tnl.appendItem(tar.createSVGPathSegLinetoABS(cx, cy)); + tnl.appendItem(tar.createSVGPathSegLinetoAbs(cx, cy)); continue; } } - tnl.appendItem(tar.createSVGPathSegMovetoABS(cx, cy)); + tnl.appendItem(tar.createSVGPathSegMovetoAbs(cx, cy)); } else if (dii === "L") { tnl.appendItem(ti); } else if (dii === "l") { - tnl.appendItem(tar.createSVGPathSegLinetoABS(cx, cy)); + tnl.appendItem(tar.createSVGPathSegLinetoAbs(cx, cy)); } else if (dii === "C") { 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)); + tnl.appendItem(tar.createSVGPathSegCurvetoCubicAbs(cx, cy, ti.x1+rx, ti.y1+ry, ti.x2+rx, ti.y2+ry)); } else if (dii === "Q") { //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)); + 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; - tnl.appendItem(tar.createSVGPathSegCurvetoCubicABS(cx, cy, (rx + 2*x1) / 3, (ry + 2*y1) / 3, (2*x1 + cx) / 3, (2*y1 + cy) / 3)); + 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") { - /*以下は、Arctoを複数のCuvetoに変換する処理 - *SVG 1.1 「F.6 Elliptical arc implementation notes」の章を参照 - *http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes - */ - var fS = ti.sweepFlag, psai = ti.angle; - if (ti.r1 === 0 || ti.r2 === 0) { - continue; - } - var r1 = Math.abs(ti.r1); - var r2 = Math.abs(ti.r2); - var ctx = (rx - cx) / 2, cty = (ry - cy) / 2; - var cpsi = Math.cos(psai * Math.PI / 180), spsi = Math.sin(psai * Math.PI / 180); - var rxd = cpsi*ctx + spsi*cty, ryd = -1*spsi*ctx + cpsi*cty; - var rxdd = rxd * rxd, rydd = ryd * ryd; - var r1x = r1 * r1, r2y = r2 * r2; - var lamda = rxdd/r1x + rydd/r2y; - var 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; + (function(ti, cx, cy, rx, ry, tar) { //変数を隠蔽するためのfunction + /*以下は、Arctoを複数のCuvetoに変換する処理 + *SVG 1.1 「F.6 Elliptical arc implementation notes」の章を参照 + *http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes + */ + var fS = ti.sweepFlag, psai = ti.angle; + if (ti.r1 === 0 || ti.r2 === 0) { + return; } - 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; - var tx = cpsi*txd - spsi*tyd + (rx+cx)/2, ty = spsi*txd + cpsi*tyd + (ry+cy)/2; - var rad = Math.atan2((ryd-tyd)/r2, (rxd-txd)/r1) - Math.atan2(0, 1); - var 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); - var 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; - var seg = Math.ceil(sse<0 ? -1*sse : sse); - var segr = dr / seg; - var t = 8/3 * Math.sin(segr/4) * Math.sin(segr/4) / Math.sin(segr/2); - var cpsir1 = cpsi * r1, cpsir2 = cpsi * r2; - var spsir1 = spsi * r1, spsir2 = spsi * r2; - var mc = Math.cos(s1); - var ms = Math.sin(s1); - var x2 = rx - t * (cpsir1*ms + spsir2*mc), y2 = ry - t * (spsir1*ms - cpsir2*mc); - for (var i = 0; i < seg; ++i) { - s1 += segr; - mc = Math.cos(s1); - ms = Math.sin(s1); - var x3 = cpsir1*mc - spsir2*ms + tx, y3 = spsir1*mc + cpsir2*ms + ty; - var 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; - } + var r1 = Math.abs(ti.r1); + var r2 = Math.abs(ti.r2); + var ctx = (rx - cx) / 2, cty = (ry - cy) / 2; + var cpsi = Math.cos(psai * Math.PI / 180), spsi = Math.sin(psai * Math.PI / 180); + var rxd = cpsi*ctx + spsi*cty, ryd = -1*spsi*ctx + cpsi*cty; + var rxdd = rxd * rxd, rydd = ryd * ryd; + var r1x = r1 * r1, r2y = r2 * r2; + var lamda = rxdd/r1x + rydd/r2y; + var 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; + var tx = cpsi*txd - spsi*tyd + (rx+cx)/2, ty = spsi*txd + cpsi*tyd + (ry+cy)/2; + var rad = Math.atan2((ryd-tyd)/r2, (rxd-txd)/r1) - Math.atan2(0, 1); + var 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); + var 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; + var seg = Math.ceil(sse<0 ? -1*sse : sse); + var segr = dr / seg; + var t = 8/3 * Math.sin(segr/4) * Math.sin(segr/4) / Math.sin(segr/2); + var cpsir1 = cpsi * r1, cpsir2 = cpsi * r2; + var spsir1 = spsi * r1, spsir2 = spsi * r2; + var mc = Math.cos(s1); + var ms = Math.sin(s1); + var 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; + var 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); } else if (dii === "S") { - if (i !== 0) { - var tg = tlist.getItem(i-1); + if (j !== 0) { + var tg = tlist.getItem(j-1); if (tg.pathSegTypeAsLetter === "C" || tg.pathSegTypeAsLetter === "c") { var x1 = 2*tg.x - tg.x2; var y1 = 2*tg.y - tg.y2; - tnl.appendItem(tar.createSVGPathSegCurvetoCubicABS(cx, cy, x1, y1, ti.x2, ti.y2)); + tnl.appendItem(tar.createSVGPathSegCurvetoCubicAbs(cx, cy, x1, y1, ti.x2, ti.y2)); } } } else if (dii === "s") { - if (i !== 0) { - var tg = tlist.getItem(i-1); + if (j !== 0) { + var tg = tlist.getItem(j-1); if (tg.pathSegTypeAsLetter === "C" || tg.pathSegTypeAsLetter === "c") { var x1 = 2*tg.x - tg.x2; var y1 = 2*tg.y - tg.y2; - tnl.appendItem(tar.createSVGPathSegCurvetoCubicABS(cx, cy, x1, y1, ti.x2+rx, ti.y2+ry)); + tnl.appendItem(tar.createSVGPathSegCurvetoCubicAbs(cx, cy, x1, y1, ti.x2+rx, ti.y2+ry)); } } } else if (dii === "T" || dii === "t") { - if (i !== 0) { - var tg = tlist.getItem(i-1); + if (j !== 0) { + var tg = tlist.getItem(j-1); if (tg.pathSegTypeAsLetter === "Q" || tg.pathSegTypeAsLetter === "q") { var x1 = 2*tg.x - tg.x1; var y1 = 2*tg.y - tg.y1; - tnl.appendItem(tar.createSVGPathSegCurvetoCubicABS(cx, cy, (rx + 2*x1) / 3, (ry + 2*y1) / 3, (2*x1 + cx) / 3, (2*y1 + cy) / 3)); + tnl.appendItem(tar.createSVGPathSegCurvetoCubicAbs(cx, cy, (rx + 2*x1) / 3, (ry + 2*y1) / 3, (2*x1 + cx) / 3, (2*y1 + cy) / 3)); } } } else if (dii === "H" || dii === "h") { - tnl.appendItem(tar.createSVGPathSegLinetoABS(cx, ry)); + tnl.appendItem(tar.createSVGPathSegLinetoAbs(cx, ry)); } else if (dii === "V" || dii === "v") { - tnl.appendItem(tar.createSVGPathSegLinetoABS(rx, cy)); + tnl.appendItem(tar.createSVGPathSegLinetoAbs(rx, cy)); } } } @@ -1900,25 +1906,19 @@ if (tps === "z" || tps === "Z") { dat += " x "; } else { - /*CTM(maなど)の行列と座標(x, y)の積を算出する。数学における表現は以下のとおり - *[ma mc me] [x] - *[mb md mf] * [y] - *[0 0 1 ] [1] - */ - var x = _parseInt(ma * ti.x + mc * ti.y + me, 10); //_parseIntはparseIntのエイリアスであり、値を丸めるのに使う - var y = _parseInt(mb * ti.x * md * ti.y + mf, 10); - x += " "; //文字列型に変換しておき、空白で区切りを付ける - y += " "; - dat += x; - dat += y; if (tps === "M") { - dat = "m" + dat; + dat += "m"; } else if (tps === "L") { - dat = "l" + dat; + dat += "l"; } else if (tps === "C") { - dat = "c" + dat; - x = _parseInt(ma * ti.x1 + mc * ti.y1 + me, 10); - y = _parseInt(mb * ti.x1 * md * ti.y1 + mf, 10); + dat += "c"; + /*CTM(maなど)の行列と座標(x, y)の積を算出する。数学における表現は以下のとおり + *[ma mc me] [x] + *[mb md mf] * [y] + *[0 0 1 ] [1] + */ + var x = _parseInt(ma * ti.x1 + mc * ti.y1 + me, 10); + var y = _parseInt(mb * ti.x1 * md * ti.y1 + mf, 10); x += " "; y += " "; dat += x; @@ -1930,6 +1930,12 @@ dat += x; dat += y; } + var x = _parseInt(ma * ti.x + mc * ti.y + me, 10); //_parseIntはparseIntのエイリアスであり、値を丸めるのに使う + var y = _parseInt(mb * ti.x * md * ti.y + mf, 10); + x += " "; //文字列型に変換しておき、空白で区切りを付ける + y += " "; + dat += x; + dat += y; } } var vi = tar.ownerDocument.documentElement.viewport; @@ -1953,10 +1959,11 @@ }; /*SVGPathSegClosePath*/ SVGPathElement.prototype.createSVGPathSegClosePath = function() { - return (new SVGPathSegClosePath()); + var _SVGPathSegClosePath = SVGPathSegClosePath; + return (new _SVGPathSegClosePath()); }; /*SVGPathSegMovetoAbs*/ SVGPathElement.prototype.createSVGPathSegMovetoAbs = function(/*float*/ x, /*float*/ y ) { - var s = new SVGPathSegMovetoAbs(); + var _SVGPathSegMovetoAbs = SVGPathSegMovetoAbs, s = new _SVGPathSegMovetoAbs(); s.x = x; s.y = y; return s; @@ -1980,7 +1987,7 @@ return s; }; /*SVGPathSegCurvetoCubicAbs*/ SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function(/*float*/ x, /*float*/ y, /*float*/ x1, /*float*/ y1, /*float*/ x2, /*float*/ y2 ) { - var s = new SVGPathSegCurvetoCubicAbs(); + var _SVGPathSegCurvetoCubicAbs = SVGPathSegCurvetoCubicAbs, s = new _SVGPathSegCurvetoCubicAbs(); s.x = x; s.y = y; s.x1 = x1;