svnno****@sourc*****
svnno****@sourc*****
2010年 4月 19日 (月) 23:31:18 JST
Revision: 1796 http://sourceforge.jp/projects/sie/svn/view?view=rev&revision=1796 Author: dhrname Date: 2010-04-19 23:31:17 +0900 (Mon, 19 Apr 2010) Log Message: ----------- getSubStringLengthメソッドの修正 Modified Paths: -------------- branches/ufltima/dom/svg.js Modified: branches/ufltima/dom/svg.js =================================================================== --- branches/ufltima/dom/svg.js 2010-04-17 14:39:30 UTC (rev 1795) +++ branches/ufltima/dom/svg.js 2010-04-19 14:31:17 UTC (rev 1796) @@ -2633,11 +2633,58 @@ /*float*/ SVGTextContentElement.prototype.getComputedTextLength = function() { this.getSubStringLength(0, this.getNumberOfChars()); }; +/*getSubStringLengthメソッド + *charnum番目の文字からnchars+charnum-1番目までの長さ + */ /*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]); + /*変数fontSizeはCTM処理後の、fontの実際の大きさを算出するための変数。 + *つまり、CTMの行列式の2乗を掛け合わせることにより、fontの大きさにCTMを組み入れる + */ + var fontSize = parseFloat(style.getPropertyValue("font-size")); + var matrix = this.getScreenCTM(); + fontSize = fontSize * Math.sqrt(Math.abs(matrix.determinant())); + //startとendはそのノードの始まりと終わりの文字のポジション番号。dは検索用の変数。 + var s = 0, start = end = 0, d = charnum, t = this.firstChild, f = /[fijlt.,:;1]/g; + while (t) { + if (t.nodeName === "#text") { + var n = t.length, echar = charnum + nchars - 1, data; + end = start + n - 1; + if (((charnum<start) && (echar<start)) || ((charnum>end) && (echar>end))) { + } else { + s += n * fontSize; + var cs = charnum - start, ee = end - echar; + if ((cs>0) && (end>charnum)) { + s -= cs * fontSize; + } + if ((ee>0) && (start<echar)) { + s -= ee * fontSize; + } + var ec = echar > end ? end : echar, cha = charnum < start ? start : charnum; + data = t.substringData(cha, ec); + if (isYokogaki) { + var kerning = data.match(f).length; + } else { + var kerinig = 0; + } + s -= kerning; + } + start = end + 1; + n = data = kerning = null; + } else if (t.localName === "tspan") { + var n = t.getNumberOfChars(), echar = charnum + nchars - 1, data; + end = start + n - 1; + if (((charnum<start) && (echar<start)) || ((charnum>end) && (echar>end))) { + } else { + var ec = echar > end ? end : echar, cha = charnum < start ? start : charnum; + s += t.getSubStringLength(cha, ec-cha); + } + start = end + 1; + } + t = t.nextSibling; + } + return s; } /*SVGPoint*/ SVGTextContentElement.prototype.getStartPositionOfChar = function (/*unsigned long*/ charnum ) { if (charnum > this.getNumberOfChars() || charnum < 0) { @@ -2686,53 +2733,7 @@ } else { 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; - /*変数fontSizeはCTM処理後の、fontの実際の大きさを算出するための変数。 - *つまり、CTMの行列式の2乗を掛け合わせることにより、fontの大きさにCTMを組み入れる - */ - var fontSize = parseFloat(style.getPropertyValue("font-size")); - 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 {