[Sie-announce] SIEコード [1068] 1, radialGradient要素の実装

アーカイブの一覧に戻る

svnno****@sourc***** svnno****@sourc*****
2009年 3月 12日 (木) 20:34:08 JST


Revision: 1068
          http://svn.sourceforge.jp/view?root=sie&view=rev&rev=1068
Author:   dhrname
Date:     2009-03-12 20:34:08 +0900 (Thu, 12 Mar 2009)

Log Message:
-----------
1, radialGradient要素の実装
2, transformToCTMの最適化

Modified Paths:
--------------
    branches/04x/sie.js

Property Changed:
----------------
    branches/04x/sie.js

Modified: branches/04x/sie.js
===================================================================
--- branches/04x/sie.js	2009-03-12 10:35:24 UTC (rev 1067)
+++ branches/04x/sie.js	2009-03-12 11:34:08 UTC (rev 1068)
@@ -232,7 +232,7 @@
   if (te !== void 0) {
   do {
   try{
-    if (name.indexOf(te.nodeName) === -1) {
+    if (name.indexOf(te.nodeName) === -1) { //タグ名が一致しないのであれば
       var ns = te.nextSibling; //次のノードをnsに収納
       var er = ele.removeChild(te);
       er = null;
@@ -997,7 +997,8 @@
     var isRadial = false;
     try {
     if (this._urlreg.test(this.fill)) { //fill属性の値がurl(#id)ならば、idを設定したグラデーション関連要素を呼び出す
-      isRadial = this.gradient(fillElement, RegExp.$1);
+      this.w = w; this.h = h; //radialGradientで必要
+      isRadial = this.gradient(fillElement, RegExp.$1, el.getAttribute("path"), el.currentStyle.width, el.currentStyle.height);
     } else {
       fillElement.setAttribute("color", this.color(this.fill));
       var fillOpacity = this.fillopacity * this.opacity; //opacityを掛け合わせる
@@ -1208,7 +1209,7 @@
   return color;
 }
 //linearGradient、radialGradient要素を処理
-NAIBU.PaintColor.prototype.gradient = function pcgradient( /*element*/ ele, /*string*/ id) {
+NAIBU.PaintColor.prototype.gradient = function pcgradient( /*element*/ ele, /*string*/ id, /*string*/ data) {
   var grad = document.getElementById(id);
   if (grad) {
   var grad2 = grad;
@@ -1255,13 +1256,54 @@
     ele.setAttribute("type", "gradientTitle");
     ele.setAttribute("focus", "100%");
     ele.setAttribute("focusposition", "0.5 0.5");
-  } catch(e) {stlog.add(e,1175);}
+    var cx = parseFloat((grad.getAttribute("cx") || "0.5").replace(/%/, ""));
+    var cy = parseFloat((grad.getAttribute("cy") || "0.5").replace(/%/, ""));
+    var r = rx = ry = parseFloat((grad.getAttribute("r") || "0.5").replace(/%/, ""));
+    var el = this.w, et = this.h, er = 0, eb = 0;
+    var units = grad.getAttribute("gradientUnits");
+    if (!units || units === "objectBoundingBox") {
+      //%の場合は小数点に変換(10% -> 0.1)
+      cx = cx > 1 ? cx/100 : cx; cy = cy > 1 ? cy/100 : cy; r = r > 1 ? r/100 : r;
+      //要素の境界領域を求める(四隅の座標を求める)
+      var degis = (this.tar.getAttribute("path")+"").match(/[0-9\-]+/g);
+      for (var i=0,degisli=degis.length;i<degisli;i+=2) {
+        var nx = parseInt(degis[i]), ny = parseInt(degis[i+1]);
+        el = el > nx ? nx : el;
+        et = et > ny ? ny : et;
+        er = er > nx ? er : nx;
+        eb = eb > ny ? eb : ny;
+      }
+      cx = cx*(er - el) + el; cy = cy*(eb - et) + et; rx = r*(er - el); ry = r*(eb - et)
+    }
+    el = cx - rx; et = cy - ry; er = cx + rx; eb = cy + ry;
+    var outline = document.getElementById("_NAIBU_outline");
+    var background = document.createElement("div"), gradient = document.createElement("div");
+    background.style.position = "absolute"; gradient.style.position = "absolute";
+    background.style.top = 0; background.style.left = 0; background.style.width = this.w; background.style.height = this.h;
+    outline.appendChild(background);
+    outline.appendChild(gradient);
+    background.style.filter = "progid:DXImageTransform.Microsoft.Compositor";
+    background.filters.item('DXImageTransform.Microsoft.Compositor').Function = 23;
+    var elout = ele.outerHTML;
+    var er2 = er - el / 2;
+    var ellipse = "ar " +el+ "," +et+ "," +er+ "," +eb+ " " +er2+ ",0 " +er2+ ",0 e";
+    var coord = 'coordsize="' +this.w+ ' ' +this.h+ '"';
+    background.innerHTML = '<v:shape style="position:relative;"' +coord+ 'path="' +data+ '" stroked="f" fillcolor="' +color[color.length-1]+ '" />';
+    gradient.innerHTML = '<v:shape style="position:relative; antialias:false;"' +coord+ 'path="' +ellipse+ '" stroked="f">' +elout+ '</v:shape>';
+    background.filters[0].apply();
+    background.innerHTML = '<v:shape style="position:relative; antialias:false;"' +coord+ 'path="' +ellipse+ '" stroked="f">' +elout+ '</v:shape>';
+    background.filters[0].play();
+    this.tar.parentNode.insertBefore(background, this.tar);
+    background.style.left = "-40"; //ずれを修正
+    this.tar.setAttribute("filled", "false");
+    return true;
+    } catch(e) {stlog.add(e,1175);}
   }
   } else {
-    return;
+    return false;
   }
   x1 = y1 = type = color = colors = opacity = null;
-  return;
+  return false;
 }
 
 //font属性、関連プロパティを処理する
@@ -1329,32 +1371,23 @@
  } catch(e){stlog.add(e,1185);}
 }
 
-
 //NAIBU.transformToCTM transform属性を処理。Matrix型に変換
 //あらかじめ正規表現オブジェクトを生成しておく
 NAIBU.comaR = /[A-Za-z]+(?=\s*\()/g;
 NAIBU.listR = /\([^\)]+\)/g;
 NAIBU.degR = /[\-\d\.e]+/g;
-NAIBU.etR = /([\-\d\.]+)e([\-\d\.]+)/;
 NAIBU.transformToCTM = function ( /*element*/ ele, /*Matrix*/ matrix) {
   try {
   var tft = ele.getAttribute("transform");
   if (tft) {
     var coma = tft.match(NAIBU.comaR); //コマンド文字にマッチ translate
     var list = tft.match(NAIBU.listR); //カッコ内のリストにマッチ (10 20 30...)
-    var degR = NAIBU.degR, etR = NAIBU.etR;
     for (var j=0;j<coma.length;j++) {
       var lis = list[j], com = coma[j];
       var a,b,c,d,e,f;
-      var deg = lis.match(degR);
+      var deg = lis.match(NAIBU.degR);
       var rad = parseFloat(deg[0]) / 180 * Math.PI;
       var degli = deg.length;
-      for (var i=0;i<degli;++i) {
-        var et = etR.test(deg[i]);
-        if (et) {
-          deg[i] = parseFloat(RegExp.$1) * Math.pow(10,parseFloat(RegExp.$2));
-        }
-      }
       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 if (degli === 3) {
@@ -1669,15 +1702,15 @@
 STLength.prototype._dR = /\D+$/; //RegExpオブジェクトをあらかじめ生成
 STLength.prototype._n = [1, 0.01, 1, 1, 1, 35.43307, 3.543307, 90, 1.25, 15]; //利用単位への変換値
 STLength.prototype._tani = { //単位に番号を振る
-    "pt": 9,
-    "pc": 10,
-    "mm": 7,
-    "cm": 6,
-    "in": 8,
-    "em": 3,
-    "ex": 4,
-    "px": 5,
-    "%":  2
+  "pt": 9,
+  "pc": 10,
+  "mm": 7,
+  "cm": 6,
+  "in": 8,
+  "em": 3,
+  "ex": 4,
+  "px": 5,
+  "%":  2
 }
 STLength.prototype.newValueSpecifiedUnits = function stlengthnvsu( /*number*/ ut, /*number*/ value) {
   this.unitType = ut;
@@ -1865,10 +1898,15 @@
   obst.width = regwv;
   obst.height = reghv;
   ob.setAttribute("coordsize",regwv  +" "+  reghv);
+  var oba = document.createElement("div");
+  oba.setAttribute("id","_NAIBU_outline");
+  obj.parentNode.appendChild(oba);
+  var nd = new Date();
   STdocument[dn] = new SVGtoVML(obc,obwidth,obheight,regw,regh);
   obj.parentNode.insertBefore(ob,obj);
   STdocument[dn].read();
   STdocument[dn].set();
+  alert((new Date).getTime() - nd.getTime())
   if (NAIBU.STObject !== void 0) {NAIBU.STObject.next();}
   data = dc = null;
 }


Property changes on: branches/04x/sie.js
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/04x/041/sie.js:891-923
/branches/04x/042/sie.js:927-967
/branches/04x/043/sie.js:969-1013
   + /branches/04x/041/sie.js:891-923
/branches/04x/042/sie.js:927-967
/branches/04x/043/sie.js:969-1013
/branches/04x/044/sie.js:1015-1067




Sie-announce メーリングリストの案内
アーカイブの一覧に戻る