svnno****@sourc*****
svnno****@sourc*****
2010年 4月 17日 (土) 23:07:14 JST
Revision: 1794
http://sourceforge.jp/projects/sie/svn/view?view=rev&revision=1794
Author: dhrname
Date: 2010-04-17 23:07:14 +0900 (Sat, 17 Apr 2010)
Log Message:
-----------
getEndPositionOfCharメソッドの実装
Modified Paths:
--------------
branches/ufltima/dom/svg.js
Modified: branches/ufltima/dom/svg.js
===================================================================
--- branches/ufltima/dom/svg.js 2010-04-14 14:17:44 UTC (rev 1793)
+++ branches/ufltima/dom/svg.js 2010-04-17 14:07:14 UTC (rev 1794)
@@ -356,7 +356,11 @@
return newItem;
},
/*DOMString*/ getItem : function(/*unsigned long*/ index ) {
- return (this._list[index]);
+ if (index >= this.numberOfItems || index < 0) {
+ throw (new DOMException(DOMException.INDEX_SIZE_ERR));
+ } else {
+ return (this._list[index]);
+ }
},
/*DOMString*/ insertItemBefore : function(/*DOMString*/ newItem, /*unsigned long*/ index ){
if (index >= this.numberOfItems) {
@@ -368,7 +372,7 @@
return newItem;
},
/*DOMString*/ replaceItem : function(/*DOMString*/ newItem, /*unsigned long*/ index ){
- if (index >= this.numberOfItems || this.numberOfItems < 0) {
+ if (index >= this.numberOfItems || index < 0) {
throw (new DOMException(DOMException.INDEX_SIZE_ERR));
} else {
this._list.splice(index, 1, newItem);
@@ -377,7 +381,7 @@
},
//raises( DOMException, SVGException );
/*DOMString*/ removeItem : function(/*unsigned long*/ index ){
- if (index >= this.numberOfItems || this.numberOfItems < 0) {
+ if (index >= this.numberOfItems || index < 0) {
throw (new DOMException(DOMException.INDEX_SIZE_ERR));
} else {
this._list.splice(index, 1);
@@ -2627,52 +2631,94 @@
return (this._tar.innerText.length);
};
/*float*/ SVGTextContentElement.prototype.getComputedTextLength = function() {
- var s = 0, t = this.firstChild, f = /[fijlt.,:;1]/g;
- //以下のメソッドに関しては、css.js(org.w3c.dom.css)をご覧下さい
- var style = this.ownerDocument.defaultView.getComputedStyle(this, null);
- var isYokogaki = (style.getPropertyValue("writing-mode")) === "lr-tb" true : false;
- var fontSize = parseFloat(style.getPropertyValue("font-size"));
- /*以下はCTM処理後の、fontの実際の大きさを算出するための処理。
- *つまり、CTMの行列式の2乗を掛け合わせることにより、CTMを組み入れる
- */
- fontSize = fontSize * Math.sqrt(Math.abs(this.getScreenCTM().determinant()));
- while (t) {
- if (t.nodeName === "#text") {
- var kerning = t.data.match(f).length; //カーニングの対象となる文字の数(SVGFontのときはhkernとvkern要素を考慮する)
- var n = t.length;
- n = n * fontSize - kerning;
- s += n;
- } else if (t.localName === "tspan") {
- s += t.getComputedTextLength();
- //dx(縦書きのときはdy)属性のずらしを考慮に入れて、長さを計算する
- var td = isYokogaki ? t.dx.baseVal : t.dy.baseVal;
- for (var i=0;i<td.numberOfItems;++i) {
- s += td.getItem(i);
- }
- }
- t = t.nextSibling;
- }
- return s;
+ this.getSubStringLength(0, this.getNumberOfChars());
};
/*float*/ SVGTextContentElement.prototype.getSubStringLength = function(/*unsigned long*/ charnum, /*unsigned long*/ nchars ) {
-
+ var style = this.ownerDocument.defaultView.getComputedStyle(this, null);
+ var isYokogaki = ((style.getPropertyValue("writing-mode")) === "lr-tb") ? true : false;
+ var t = isYokogaki ? "x" : "y";
+ return (this.getEndPositionOfChar(charnum+nchars)[t] - this.getStartPositionOfChar(charnum)[t]);
}
/*SVGPoint*/ SVGTextContentElement.prototype.getStartPositionOfChar = function (/*unsigned long*/ charnum ) {
if (charnum > this.getNumberOfChars() || charnum < 0) {
- return (new DOMException(DOMException.INDEX_SIZE_ERR));
+ throw (new DOMException(DOMException.INDEX_SIZE_ERR));
} else {
}
};
/*SVGPoint*/ SVGTextContentElement.prototype.getEndPositionOfChar = function(/*unsigned long*/ charnum ) {
if (charnum > this.getNumberOfChars() || charnum < 0) {
- return (new DOMException(DOMException.INDEX_SIZE_ERR));
+ throw (new DOMException(DOMException.INDEX_SIZE_ERR));
} else {
- //以下のメソッドに関しては、css.js(org.w3c.dom.css)をご覧下さい
- var fontSize = this.style.getPropertyCSSValue("font-size").getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
- fontSize = fontSize * Math.sqrt(Math.abs(ttm.determinant())); //現在の座標系で文字の大きさを変換する
- var s = this.ownerDocument.documentElement.createSVGPoint();
- s.x = (fontSize*(charnum+1));
- s.y = 0;
+ var s = this.ownerDocument.createSVGPoint(), d = charnum + 1, t = this.firstChild, f = /[fijlt.,:;1]/g;
+ var x = y = 0;
+ var style = this.ownerDocument.defaultView.getComputedStyle(this, null);
+ var isYokogaki = ((style.getPropertyValue("writing-mode")) === "lr-tb") ? true : false;
+ var fontSize = parseFloat(style.getPropertyValue("font-size"));
+ /*変数fontSizeはCTM処理後の、fontの実際の大きさを算出するための変数。
+ *つまり、CTMの行列式の2乗を掛け合わせることにより、fontの大きさにCTMを組み入れる
+ */
+ var matrix = this.getScreenCTM();
+ fontSize = fontSize * Math.sqrt(Math.abs(matrix.determinant()));
+ /*文字の終了位置における座標(x, y)を求める方法としては、
+ *まず、文字の長さ(h)を算出して、相対座標(x, y)を導き出す
+ */
+ var h = 0;
+ while (t) {
+ if (t.nodeName === "#text") {
+ var n = t.length, isBreak = false;
+ if (d > n) {
+ d -= n;
+ var data = t.data;
+ } else {
+ n = d;
+ var data = t.substringData(0, d);
+ isBreak = true;
+ }
+ if (isYokogaki) {
+ var kerning = data.match(f).length;
+ } else {
+ var kerinig = 0;
+ }
+ h = n * fontSize - kerning;
+ n = data = kerning = null;
+ if (isBreak) {
+ break;
+ }
+ } else if (t.localName === "tspan") {
+ if (t.getNumberOfChars() > d) {
+ h += t.getEndPositionOfChar(d);
+ }
+ //dx(縦書きのときはdy)属性のずらしを考慮に入れて、長さを計算する
+ if (isYokogaki) {
+ var tb = t.dx.baseVal;
+ } else {
+ var tb = t.dy.baseVal;
+ }
+ h += tb.getItem(0).value;
+ }
+ t = t.nextSibling;
+ }
+ if (isYokogaki) {
+ x = h;
+ } else {
+ y = h;
+ }
+ /*続けて、求めておいた相対座標(x, y)に、絶対座標を付け加えることによって、
+ *文字の位置の絶対座標を割り出すことができる。そのためにはx属性とy属性を計算に入れることが肝要
+ */
+ var txb = this.x.baseVal, tyb = this.y.baseVal;
+ if (txb.numberOfItems > charnum) {
+ x = txb.getItem(charnum).value;
+ } else {
+ x += txb.getItem(txb.numberOfItems-1).value;
+ }
+ if (tyb.numberOfItems > charnum) {
+ y = tyb.getItem(charnum).value;
+ } else {
+ y += tyb.getItem(tyb.numberOfItems-1).value;
+ }
+ s.x = x;
+ s.y = y;
return s;
}
};
@@ -2696,8 +2742,14 @@
/*readonly SVGAnimatedLengthList*/ this.dx = new SVGAnimatedLengthList();
/*readonly SVGAnimatedLengthList*/ this.dy = new SVGAnimatedLengthList();
/*readonly SVGAnimatedNumberList*/ this.rotate = new SVGAnimatedNumberList();
- this.x.baseVal.appendItem(this.ownerDocument.createSVGLength());
- this.y.baseVal.appendItem(this.ownerDocument.createSVGLength());
+ this.addEventListener("DOMAttrModified", function(evt){
+ var tar = evt.target;
+ if (evt.eventPhase === Event.BUBBLING_PHASE) {
+ return; //強制終了させる
+ }
+ tar.x.baseVal.appendItem(tar.ownerDocument.documentElement.createSVGLength());
+ tar.y.baseVal.appendItem(tar.ownerDocument.documentElement.createSVGLength());
+ }, false);
return this;
};
SVGTextPositioningElement.constructor = SVGTextContentElement;