svnno****@sourc*****
svnno****@sourc*****
2009年 10月 3日 (土) 19:20:39 JST
Revision: 1307 http://sourceforge.jp/projects/sie/svn/view?view=rev&revision=1307 Author: dhrname Date: 2009-10-03 19:20:39 +0900 (Sat, 03 Oct 2009) Log Message: ----------- getCTMメソッドの実装 Modified Paths: -------------- branches/DOM/org/w3c/dom/svg.js Modified: branches/DOM/org/w3c/dom/svg.js =================================================================== --- branches/DOM/org/w3c/dom/svg.js 2009-10-02 13:58:01 UTC (rev 1306) +++ branches/DOM/org/w3c/dom/svg.js 2009-10-03 10:20:39 UTC (rev 1307) @@ -873,87 +873,6 @@ return grad; } -//transform属性を処理 -function TransformList( /*element*/ ele) { - this.on = true; - try { - var ep = ele.parentNode; - var tf = ""; - if (ele.getAttribute("transform")) { - tf = ele.getAttribute("transform"); - } - while(ep.tagName == "group" || ep.tagName == "A") { //先祖要素のtransform属性を取得 - if (ep.getAttribute("transform")) { - tf = ep.getAttribute("transform") + tf; - ele.setAttribute("transform",tf); - } - ep = ep.parentNode; - } - this.tr = new Transform(); - var tft = ele.getAttribute("transform"); - if (tft) { - var coma = tft.match(/[A-Za-z]+(?=\s*\()/g); - var list = tft.match(/\([^\)]+\)/g); - this.tr.matrix = this.tr.getMatrix(list[0],coma[0]); - for (var i=1;i<coma.length;i++) { - this.tr.set(list[i],coma[i]); - } - list = null; - } else{ - this.on = false; - this.tr.matrix = new Matrix(1,0,0,1,0,0); - } - } catch(e) {stlog.add(e,816);} - return this; -} - -function Transform() { - this.matrix = new Matrix(1,0,0,1,0,0); - return this; -} -Transform.prototype.set = function transformset(list,c) { - var matri = this.getMatrix(list,c); - var mat = this.matrix; - this.matrix = mat.multiply(matri); -} -Transform.prototype.getMatrix = function transformgetMatrix(list,com) { - var a,b,c,d,e,f; - var deg = list.match(/[\-\d\.e]+/g); - var rad = parseFloat(deg[0]) / 180 * Math.PI; - for (var i=0,degli=deg.length;i<degli;i++) { - var et = deg[i].match(/([\-\d\.]+)e([\-\d\.]+)/); - if (et) { - deg[i] = parseFloat(RegExp.$1) * Math.pow(10,parseFloat(RegExp.$2)); - } - } - if (deg.length == 6) { - a = parseFloat(deg[0]); b = parseFloat(deg[1]); c = parseFloat(deg[2]); d = parseFloat(deg[3]); e = parseFloat(deg[4]); f = parseFloat(deg[5]); - } else if (deg.length == 3) { - var cx = parseFloat(deg[1]), cy = parseFloat(deg[2]); - a = Math.cos(rad); b = Math.sin(rad); c = -b; d = a; e = (1-a)*cx-c*cy; f = -b*cx+(1-d)*cy; - } else if (deg.length <= 2) { - switch (com) { - case "translate": - a = 1; b = 0; c = 0; d = 1; e = parseFloat(deg[0]); f = parseFloat(deg[1] || 0); - break; - case "scale": - a = parseFloat(deg[0]); b = 0; c = 0; d = parseFloat(deg[1] || deg[0]); e = 0; f = 0; - break; - case "rotate": - a = Math.cos(rad); b = Math.sin(rad); c = -b; d = a; e = 0; f = 0; - break; - case "skewX": - a = 1; b = 0; c = Math.tan(rad); d = 1; e = 0; f = 0; - break; - case "skewY": - a = 1; b = Math.tan(rad); c = 0; d = 1; e = 0; f = 0; - break; - } - } - var matri = new Matrix(a,b,c,d,e,f); - return matri; -} - //path要素のd属性で使われるA(rcTo)コマンドを処理 function STArc() { return this; @@ -1281,12 +1200,67 @@ s.height = this.tar.clientHeight; return s; }; + +//あらかじめ正規表現オブジェクトを生成しておく +NAIBU.comaR = /[A-Za-z]+(?=\s*\()/g; +NAIBU.listR = /\([^\)]+\)/g; +NAIBU.degR = /[\-\d\.e]+/g; + /*getCTMメソッド *CTMとは現在の利用座標系に対する変換行列 */ /*SVGMatrix*/ SVGElement.prototype.getCTM = function(){ - if (!this.transform._matrix) { //キャッシュがなければ、 - var n = this.transform.baseVal.consolidate(); + if (!this.transform._matrix) { //キャッシュがなければ、 + if (this.transform.animVal.numberOfItems === 0) { + try { + var tft = this.getNamedItemNS(null, "transform"); + /*以下はtrasnform属性の値を解析して、 + *TransformListオブジェクトに変換するもの + */ + if (tft) { + tft = tft.nodeValue; + var coma = tft.match(NAIBU.comaR); //コマンド文字にマッチ translate + var list = tft.match(NAIBU.listR); //カッコ内のリストにマッチ (10 20 30...) + var a,b,c,d,e,f,lis,deg,rad,degli, t; + for (var j=0,cli=coma.length;j<cli;j++) { + lis = list[j], com = coma[j]; + deg = lis.match(NAIBU.degR); + t = this.ownerDocument.documentElement.createSVGTransform(); + degli = deg.length; + if (degli === 6) { + a = parseFloat(deg[0]); b = parseFloat(deg[1]); c = parseFloat(deg[2]); d = parseFloat(deg[3]); e = parseFloat(deg[4]); f = parseFloat(deg[5]); + } else { + rad = parseFloat(deg[0]) / 180 * Math.PI; + if (degli === 3) { + var cx = parseFloat(deg[1]), cy = parseFloat(deg[2]); + a = Math.cos(rad); b = Math.sin(rad); c = -b; d = a; e = (1-a)*cx-c*cy; f = -b*cx+(1-d)*cy; + } else if (degli <= 2) { + switch (com) { + case "translate": + a = 1; b = 0; c = 0; d = 1; e = parseFloat(deg[0]); f = parseFloat(deg[1] || 0); + break; + case "scale": + a = parseFloat(deg[0]); b = 0; c = 0; d = parseFloat(deg[1] || deg[0]); e = 0; f = 0; + break; + case "rotate": + a = Math.cos(rad); b = Math.sin(rad); c = -b; d = a; e = 0; f = 0; + break; + case "skewX": + a = 1; b = 0; c = Math.tan(rad); d = 1; e = 0; f = 0; + break; + case "skewY": + a = 1; b = Math.tan(rad); c = 0; d = 1; e = 0; f = 0; + break; + } + } + } + lis = com = deg = rad = null; + } + list = coma = mat = null; + } + } catch(e) {stlog.add(e,816);} + } + var n = this.transform.animVal.consolidate(); n = n ? n.matrix : this.documentElement.createSVGMatrix(); this.transform._matrix = this.parentNode.getCTM().multiply(n); } @@ -2642,12 +2616,6 @@ SVGPathElement.prototype = new SVGElement(); SVGPathElement.prototype.read = function(){ this.d = this.getNamedItemNS(null, "d").nodeValue; - var tra = this.getNamedItemNS(null, "transform").nodeValue; - if (tra) { - var tta = this.transform.animVal; - var commands = tra.match(NAIBU.comR); - var degits = tra.match(NAIBU.degR); - } }; //あらかじめ正規表現オブジェクトを生成しておく NAIBU.comaR = /[A-Za-z]+(?=\s*\()/g; @@ -3442,10 +3410,10 @@ SVGColorProfileElement.constructor = SVGElement; SVGColorProfileElement.prototype = new SVGElement(); -function SVGMPathElement : +function SVGMPathElement() /* : SVGElement, SVGURIReference, - SVGExternalResourcesRequired { + SVGExternalResourcesRequired*/ { SVGElement.apply(this, arguments); }; SVGColorProfileElement.constructor = SVGElement;