[Sie-announce] SIEコード [1796] getSubStringLengthメソッドの修正

Zurück zum Archiv-Index

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 {




Sie-announce メーリングリストの案内
Zurück zum Archiv-Index