Project

General

Profile

Defect #3414 » Redmine-0.8.5-sie.patch

sunday walker, 2009-10-26 13:33

View differences:

app/controllers/repositories_controller.rb (working copy)
249 249
      :scale_integers => true,
250 250
      :step_x_labels => 2,
251 251
      :show_data_values => false,
252
      :no_css => true,
252 253
      :graph_title => l(:label_commits_per_month),
253 254
      :show_graph_title => true
254 255
    )
......
292 293
      :scale_integers => true,
293 294
      :show_data_values => false,
294 295
      :rotate_y_labels => false,
296
      :no_css => true,
295 297
      :graph_title => l(:label_commits_per_author),
296 298
      :show_graph_title => true
297 299
    )
app/views/repositories/stats.rhtml (working copy)
1 1
<h2><%= l(:label_statistics) %></h2>
2 2

  
3 3
<p>
4
<%= tag("embed", :width => 800, :height => 300, :type => "image/svg+xml", :src => url_for(:controller => 'repositories', :action => 'graph', :id => @project, :graph => "commits_per_month")) %>
4
<%= content_tag("object", "", :width => 800, :height => 300, :type => "image/svg+xml", :data => url_for(:controller => 'repositories', :action => 'graph', :id => @project, :graph => "commits_per_month")) %>
5 5
</p>
6 6
<p>
7
<%= tag("embed", :width => 800, :height => 400, :type => "image/svg+xml", :src => url_for(:controller => 'repositories', :action => 'graph', :id => @project, :graph => "commits_per_author")) %>
7
<%= content_tag("object", "", :width => 800, :height => 400, :type => "image/svg+xml", :data => url_for(:controller => 'repositories', :action => 'graph', :id => @project, :graph => "commits_per_author")) %>
8 8
</p>
9 9

  
10 10
<p><%= link_to l(:button_back), :action => 'show', :id => @project %></p>
11 11

  
12 12
<% html_title(l(:label_repository), l(:label_statistics)) -%>
13

  
14

  
15
<% content_for :header_tags do %>
16
    <%= javascript_include_tag 'sie', :defer => "defer" %>
17
<% end %>
public/javascripts/sie.js (revision 0)
1
/*SIE-SVG without Plugin under LGPL2.1 & GPL2.0 & Mozilla Public Lisence
2
 *公式ページは http://sie.sourceforge.jp/
3
 *利用方法は <script defer="defer" type="text/javascript" src="sie.js"></script>
4
 */
5
/* ***** BEGIN LICENSE BLOCK *****
6
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
7
 *
8
 * The contents of this file are subject to the Mozilla Public License Version
9
 * 1.1 (the "License"); you may not use this file except in compliance with
10
 * the License. You may obtain a copy of the License at
11
 * http://www.mozilla.org/MPL/
12
 *
13
 * Software distributed under the License is distributed on an "AS IS" basis,
14
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
15
 * for the specific language governing rights and limitations under the
16
 * License.
17
 *
18
 * The Original Code is the Mozilla SVG Cairo Renderer project.
19
 *
20
 * The Initial Developer of the Original Code is IBM Corporation.
21
 * Portions created by the Initial Developer are Copyright (C) 2004
22
 * the Initial Developer. All Rights Reserved.
23
 *
24
 * Parts of this file contain code derived from the following files(s)
25
 * of the Mozilla SVG project (these parts are Copyright (C) by their
26
 * respective copyright-holders):
27
 *    layout/svg/renderer/src/libart/nsSVGLibartBPathBuilder.cpp
28
 *
29
 * Contributor(s):DHRNAME revulo
30
 *
31
 * Alternatively, the contents of this file may be used under the terms of
32
 * either of the GNU General Public License Version 2 or later (the "GPL"),
33
 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
34
 * in which case the provisions of the GPL or the LGPL are applicable instead
35
 * of those above. If you wish to allow use of your version of this file only
36
 * under the terms of either the GPL or the LGPL, and not to allow others to
37
 * use your version of this file under the terms of the MPL, indicate your
38
 * decision by deleting the provisions above and replace them with the notice
39
 * and other provisions required by the GPL or the LGPL. If you do not delete
40
 * the provisions above, a recipient may use your version of this file under
41
 * the terms of any one of the MPL, the GPL or the LGPL.
42
 *
43
 * ***** END LICENSE BLOCK ***** */
44

  
45
//これを頭に付けたら、内部処理用
46
var  NAIBU = {};
47
//documentを速くするために
48
/*@cc_on  _d=document;eval('var  document=_d')@*/
49
//bookmarkletから呼び出されたらtrue
50
var sieb_s;
51

  
52
//svgtovml load時に、最初に起動する関数
53
function svgtovml() {
54
  //IEだったらtrueを返す
55
  var isMSIE = /*@cc_on!@*/false;
56
  //引数にtrueがあれば、例外処理のログを作動させる
57
  stlog = new STLog(false);
58
  var ary = document.getElementsByTagName("script");
59
  //全script要素をチェックして、type属性がimage/svg+xmlならば、中身をSVGとして処理する
60
  for (var i=0; i < ary.length; i++) {
61
    var hoge = ary[i].type;
62
    if (ary[i].type === "image/svg+xml") {
63
      var ait = ary[i].text;
64
      if (sieb_s && ait.match(/&lt;svg/)) {
65
        //ソース内のタグを除去
66
        ait = ait.replace(/<.+?>/g, "");
67
        //エンティティを文字に戻す
68
        ait = ait.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&amp;/g, "&");
69
      }
70
      if (isMSIE) {
71
        setVMLNameSpace();
72
        var da = {};
73
        da.obj = []; da.obj[i] = ary[i]; da.num = i + 1; da.content = ait.replace(/\shref=/g, " target='_top' xlink:href="); da.success = true;
74
        ca(da);
75
      } else {
76
        var base = location.href.replace(/\/[^\/]+?$/,"/"); //URIの最後尾にあるファイル名は消す。例: /n/sie.js -> /n/
77
        ait = ait.replace(/\shref=(['"a-z]+?):\/\//g, " target='_top' xlink:href=$1://").replace(/\shref=(.)/g, " target='_top' xlink:href=$1"+base);
78
        var s = textToSVG(ait,ary[i].getAttribute("width"),ary[i].getAttribute("height"));
79
        ary[i].parentNode.insertBefore(s,ary[i]);
80
      }
81
    }
82
  }
83
  NAIBU.STObject = new Objectembeds();
84
  if (isMSIE) {
85
    setVMLNameSpace();
86
    var oba = document.createElement("div");
87
    oba.setAttribute("id","_NAIBU_outline");
88
    document.body.appendChild(oba);
89
    NAIBU.STObject.next();
90
    success = true;
91
  } else if (/a/[-1] === 'a'){ //Firefoxだったらtrueを返す
92
    NAIBU.STObject.ffnext();
93
  }
94
}
95
//他のページに移動する際に起動
96
function unsvgtovml() {
97
  NAIBU = stlog = STLog = null;
98
}
99

  
100
//vmlの名前空間をセット(必須)
101
function setVMLNameSpace() {
102
  if (!document.namespaces["v"]) {
103
    document.namespaces.add("v","urn:schemas-microsoft-com:vml");
104
    document.namespaces.add("o","urn:schemas-microsoft-com:office:office");
105
    var st = document.createStyleSheet();
106
    var vmlUrl = "behavior: url(#default#VML);display:inline-block;} "; //inline-blockはIEのバグ対策
107
    st.cssText = "v\\:rect{" +vmlUrl+ "v\\:image{" +vmlUrl+ "v\\:fill{" +vmlUrl+ "v\\:stroke{" +vmlUrl+ "o\\:opacity2{" +vmlUrl
108
      + "dn\\:defs{display:none}"
109
      + "v\\:group{text-indent:0px;position:relative;width:100%;height:100%;" +vmlUrl
110
      + "v\\:shape{width:100%;height:100%;" +vmlUrl;
111
  }
112
}
113

  
114
//windowに指定したイベントと関数を追加
115
NAIBU.addEvent = function(evt,lis){
116
  if (window.addEventListener) {
117
    window.addEventListener(evt, lis, false);
118
  } else if (window.attachEvent) {
119
    window.attachEvent('on'+evt, lis);
120
  } else {
121
    window['on'+evt] = lis;
122
  }
123
}
124
NAIBU.addEvent("load",svgtovml);
125
NAIBU.addEvent("unload",unsvgtovml);
126

  
127
//以下は例外処理のログをとるためのもの。開発者以外は削除すること
128
function STLog(jou) {
129
this.jo = jou;
130
if (this.jo) {
131
  this.p = document.createElement("div");
132
  this.p.innerHTML = "<h1>例外処理のログ</h1>";
133
  document.body.insertBefore(this.p,document.body.firstChild);
134
}
135
  return this;
136
}
137
STLog.prototype.add = function(e,code) {
138
if (this.jo) {
139
  this.p.innerHTML += "<p>"+code+":"+e.message+"</p>";
140
}
141
}
142

  
143
//SVGtoVML 本体。SVGDocumentの代わりを担う
144
//object要素の幅と高さがwとh(単位はpxに統一)。svg要素の幅と高さがswi.valueとshi.value。svg要素にwidth属性が指定されていない場合、swi.value=wである。
145
function SVGtoVML( /*element*/ obc, /*float*/ w, /*float*/ h, /*STLength*/ swi, /*STLength*/ shi) {
146
  this.rootElement = obc; this.w = w; this.h = h; this.swi = swi; this.shi = shi;
147
  return this;
148
}
149
SVGtoVML.prototype.read = function stvread(/*element*/ ob) {
150
  this.rootElement.style.visibility = "hidden";
151
  this.vi = new STViewSpec(this.rootElement);
152
  try{
153
  this.children = []; //子要素
154
  var sw = this.swi.value,  sh = this.shi.value;
155
  this.getObject("USE", STUseElement, "use", sw, sh); //use要素を先に処理
156
  var mat = this.vi.set(sw, sh, ob); //返り値はMatrix型
157
  this.chset(this.rootElement, mat, sw, sh);
158
  } catch(n) {stlog.add(n,109);}
159
}
160
SVGtoVML.prototype.getObject = function stvgetob( /*string*/ tag, /*object*/ st, /*string*/nodes, /*float*/w, h) {
161
  try {
162
  var li = this.rootElement.getElementsByTagName(tag);
163
  var la = [];
164
  for (var i=0,lli=li ? li.length : 0;i<lli;++i) {
165
    la[i] = new st(li[i], w, h);
166
  }
167
  this[nodes] = la;
168
  li = null;
169
  } catch(e) {stlog.add(e,129);}
170
}
171
SVGtoVML.prototype.set = function stvset(ob) {
172
  var w = this.w, h = this.h, c = this.children;
173
  var sw = this.swi.value, sh = this.shi.value;
174
  this.setObject(this.use,sw,sh);
175
  this.setObject(c,sw,sh);
176
  try {
177
  var backr = document.createElement("v:rect"); //背景の作成
178
  backr.style.position = "absolute";
179
  backr.style.width = w+ "px";
180
  backr.style.height = h+ "px";
181
  backr.style.zIndex = -1;
182
  backr.stroked = "false";
183
  backr.filled = "false";
184
  this.rootElement.appendChild(backr);
185
  var trstyle = this.rootElement.style;
186
  var tpstyle = ob.style;
187
  trstyle.visibility = "visible";
188
  //以下、画像を切り取り
189
  trstyle.overflow = "hidden";
190
  var backrs = backr.currentStyle;
191
  var viewWidth = w > sw ? sw : w, viewHeight = h > sh ? sh : h; //ウィンドウ枠の長さを決定する
192
  var bfl = parseFloat(backrs.left), bft = parseFloat(backrs.top);
193
  var bl = -this.vi._tx, bt = -this.vi._ty;
194
  if (bfl !== 0 && !isNaN(bfl)) { //内部の図形にずれが生じたとき(isNaNはIE8でautoがデフォルト値のため)
195
    bl = bfl;
196
    tpstyle.left = -bl+ "px";
197
  }
198
  if (bft !== 0 && !isNaN(bfl)) {
199
    bt = bft;
200
    tpstyle.top = -bt+ "px";
201
  }
202
  var backright = bl + viewWidth + 1;
203
  var backdown = bt + viewHeight + 1;
204
  trstyle.clip = "rect(" +bt+ "px " +backright+ "px " +backdown+ "px " +bl+ "px)";
205
  //以下、テキストの位置を修正
206
  var text = this.rootElement.getElementsByTagName("div");
207
  for (var i=0,textli=text.length;i<textli;++i) {
208
    var texti = text[i];
209
    if (texti.firstChild.nodeName !== "shape") { //radialGradient用のdiv要素でないならば
210
      var tis = texti.style;
211
      tis.left = parseFloat(tis.left) + bl + "px";
212
      tis.top = parseFloat(tis.top) + bt + "px";
213
      //以下はdiv要素がa要素のスタイルを継承しないので必要
214
      var tp = texti.parentNode;
215
      while (tp.nodeName === "group") { //group要素である限り、さかのぼる
216
        tp = tp.parentNode;
217
      }
218
      if (tp.nodeName === "A") { //先祖要素がa要素ならば
219
        tis.cursor = "hand";
220
      }
221
    }
222
  }
223
  } catch(e) {stlog.add(e,138);}
224
}
225
SVGtoVML.prototype.setObject = function stvsetob( /*SVGElement*/ arr, /*float*/ sw, /*float*/ sh) {
226
  try {
227
  for (var i=0,arri=arr.length;i<arri;++i) {
228
      arr[i].set(sw,sh);
229
  }
230
  } catch(e) {stlog.add(e,170);}
231
}
232

  
233
//chset childNodesで要素を作成していく
234
SVGtoVML.prototype.chset = function _s_chset( /*element*/ ele, /*Matrix*/ matrix, /*float*/w, /*float*/h){
235
  var nods = ele.childNodes, s = null;
236
  var name = "group|shape|defs|STOP|fill|stroke|DIV|SPAN|A|image|rect|USE", gname = "DIV|group"; //要素名に合致させる文字列
237
  var cmatrix = matrix; //子要素に継がせるCTM
238
  var te = nods[0];
239
  if (te !== void 0) {
240
  do {
241
  try{
242
    if (name.indexOf(te.nodeName) === -1) { //タグ名が一致しないのであれば
243
      var ns = te.nextSibling; //次のノードをnsに収納
244
      var er = ele.removeChild(te);
245
      er = null;
246
      te = ns;
247
    } else {
248
      if (te.nodeType === 1) { //要素ならば
249
        if (te.nodeName === "shape") {
250
          switch (te.getAttribute("tag")) {
251
            case "path":
252
              s = new STPath(te, matrix);
253
            break;
254
            case "rect":
255
              s = new STRectElement(te, matrix, w, h);
256
            break;
257
            case "circle":
258
              s = new STCircle(te, matrix, w, h);
259
            break;
260
            case "ellipse":
261
              s = new STEllipse(te, matrix, w, h);
262
            break;
263
            case "polyline":
264
              s = new STPolyline(te, matrix);
265
            break;
266
            case "polygon":
267
              s = new STPolygon(te, matrix);
268
            break;
269
            case "line":
270
              s = new STLine(te, matrix, w, h);
271
            break;
272
          }
273
        } else if (te.nodeName === "DIV") {
274
          s = new STText(te, matrix, w, h);
275
        } else if (te.nodeName === "group") {
276
          s = new STGroupElement(te, matrix, w, h);
277
        } else if (te.nodeName === "A") {
278
          s = new STAElement(te, matrix);
279
          cmatrix = s.transformable;
280
        } else if (te.nodeName === "image") {
281
          s = new STImage(te, matrix, w, h);
282
        }
283
        if (s) {
284
          this.children[this.children.length] = s;
285
          var s = null; //var宣言によって、再設定
286
        }
287
        if (gname.indexOf(te.nodeName) === -1) {
288
          this.chset(te, cmatrix, w, h);
289
        }
290
      }
291
      te = te.nextSibling;
292
    }
293
  } catch(e){stlog.add(e,3002);}
294
  } while (te);
295
  }
296
  nods = name = gname = matrix = cmatrix = w = h = null;
297
}
298

  
299
//object要素とembed要素の取得を総括して行う
300
function Objectembeds(){
301
  this.obj = document.getElementsByTagName("object") || {length:0};
302
  this.emd = document.getElementsByTagName("embed") || {length:0};
303
  this.onumber = this.enumber = 0;
304
  return this;
305
}
306
Objectembeds.prototype.next = function(){
307
  try{
308
  if (this.onumber < this.obj.length) { //object要素の読み込みをまず行う
309
    var n = this.onumber;
310
    this.onumber++;
311
    try {
312
      getURL(this.obj[n].getAttribute("data"),ca,this.obj,n+1); //data属性をロード
313
    } catch(e) {stlog.add(e,177);this.next();}
314
  } else if (this.enumber < this.emd.length) { //object要素が終われば、次にembed要素の読み込み
315
    var n = this.onumber+this.enumber;
316
    this.enumber++;
317
      try {
318
        getURL(this.emd[n].src,ca,this.emd,n+1);
319
      } catch(e) {stlog.add(e,185);this.next();}
320
  } else { //全要素の読み込みが終われば
321
  }
322
  } catch(e) {stlog.add(e,293);this.onumber++;this.next();}
323
}
324
//embed要素をobject要素に変える(Firefoxのみ)
325
Objectembeds.prototype.ffnext = function(){
326
  try{
327
    for (var i=0,teli=this.emd.length;i<teli;++i) {
328
      var s = document.createElement("object"), tei = this.emd[i];
329
      s.setAttribute("data", tei.getAttribute("src"));
330
      s.setAttribute("type", "image/svg+xml");
331
      s.setAttribute("width", tei.getAttribute("width")); s.setAttribute("height", tei.getAttribute("height"));
332
      var tep = tei.parentNode;
333
      tep.insertBefore(s,tei);
334
      tep.removeChild(tei);
335
	  teli--;
336
    }
337
  } catch(e) {stlog.add(e,294);}
338
}
339

  
340
//g要素の処理
341
function STGroupElement( /*element*/ g, /*Matrix*/ matrix, /*float*/w, h) {
342
  try{
343
  this.tar = g;
344
  this.transformable = NAIBU.transformToCTM(g,matrix); //g要素のtransform属性を前もって処理
345
  //以下、ツリーとして処理
346
  this.children = [];
347
  this.chset(g,this.transformable, w, h);
348
  w = h = null;
349
  } catch(e){stlog.add(e,3144);}
350
  return this;
351
}
352
STGroupElement.prototype.set = function (sw,sh) {
353
  try{
354
  stvsetob(this.children,sw,sh);
355
  this.children = this.transformable = null;
356
  } catch(e){stlog.addd(e,3145)}
357
};
358
STGroupElement.prototype.chset = SVGtoVML.prototype.chset;
359

  
360
//a要素の処理
361
function STAElement( /*element*/ a, /*Matrix*/ matrix) {
362
  this.xlink = new NAIBU.XLink(a);
363
  this.target = a.getAttribute("target");
364
  this.transformable = NAIBU.transformToCTM(a,matrix);
365
  return this;
366
}
367
STAElement.prototype.set = function aset() {
368
  try {
369
    var t = this.target;
370
    var st = "replace";
371
    if (t === "_blank") {
372
      st = "new";
373
    }
374
    this.xlink.tar.setAttribute("xlink:show",st);
375
    this.xlink.set();
376
    var txts = this.xlink.tar.style;
377
    txts.cursor = "hand";
378
    txts.left = "0px";
379
    txts.top = "0px";
380
    txts.textDecoration = "none";
381
  }  catch(e) {stlog.add(e,204);}
382
}
383

  
384
//text要素の処理
385
function STText( /*element*/ te, /*Matrix*/ matrix, /*float*/w, h) {
386
  this.tar = te;
387
  this.x = new STLength((te.getAttribute("x") || 0), w);
388
  this.y = new STLength((te.getAttribute("y") || 0), h);
389
  this.dx = te.getAttribute("dx") || null;
390
  this.dy = te.getAttribute("dy") || null;
391
  this.paint = new NAIBU.FontStyle(te);
392
  this.transformable = NAIBU.transformToCTM(te,matrix);
393
  try { //子要素のtspan要素を処理
394
    var li = this.tar.getElementsByTagName("SPAN");
395
    var l = [];
396
    for (var i=0,lli=li.length;i<lli;++i) {
397
      l[i] = new STTSpanElement(li[i],this.dx,this.dy,this.transformable, w, h);
398
    }
399
    this.tspan = l;
400
    li = w = h = null;
401
  } catch(e) {stlog.add(e,129264);}
402
  return this;
403
}
404
STText.prototype.set = function textset( /*float*/ w, /*float*/ h) {
405
  try {
406
  var ttm = this.transformable;
407
  var p = new Point(this.x.value,this.y.value);
408
  var ptm = p.matrixTransform(ttm);
409
  var tts = this.tar.style;
410
  tts.position = "absolute";
411
  var ttp = this.tar.parentNode;
412
  if (ttp.lastChild.nodeName !== "rect") {
413
    var backr = document.createElement("v:rect");
414
    var backrs = backr.style; //ずれを修正するためのもの
415
    backrs.width = "1px";
416
    backrs.height = "1px";
417
    backrs.left = "0px";
418
    backrs.top = "0px";
419
    backr.stroked = "false";
420
    backr.filled = "false";
421
    ttp.appendChild(backr);
422
  }
423
  tts.width = "0px";
424
  tts.height = "0px";
425
  this.paint.fset(w,h,ttm);
426
  } catch(e) {stlog.add(e,236);}
427
  try {
428
    //以下は、テキストの幅であるtextLengthを算出する
429
    var arr = this.tspan, textLength = 0, fontSize = this.paint.fontSize, atfontSize = 0, fij = /[fijlt.,:;1]/g; //fontSizeは親要素の文字サイズ。atfontSizeは各span要素のサイズ。
430
    for (var i=0,s={dx:0,dy:0},arri=arr.length;i<arri;++i) {
431
      var ari = arr[i];
432
      ari.paint.fset(w,h,ari.transformable);
433
      var atps = ari.tar.previousSibling;
434
      if (atps && atps !== void 0) {
435
        if (atps.nodeType === 3) { //tspan要素の前がText Nodeならば
436
          var ad = atps.data;
437
          var alm = fij.test(ad) ? ad.match(fij).length : 0; //iなどはカーニング調整をする
438
          textLength += (2 * ad.length - alm) * fontSize / 2;
439
        } else {
440
          var ai = atps.innerText;
441
          var alm = fij.test(ad) ? ai.match(fij).length : 0;
442
          textLength += (2 * ai.length - alm) * atfontSize / 2;
443
        }
444
      }
445
      atfontSize = ari.paint.fontSize;
446
      s = ari.set(w,h,s);
447
    }
448
    if (arr.length === 0) {  //tspan要素がなければ
449
      var tti = this.tar.innerText;
450
      var alm = fij.test(tti) ? tti.match(fij).length : 0;
451
      textLength = (2 * tti.length - alm) * fontSize / 2;
452
    }
453
    //以下はtext-anchorプロパティをサポートする。
454
    var tancx = 0, tancy = 0;
455
    if (tts.textAnchor === "middle") {  //中寄せならば
456
      tancx = tancy = textLength / 4;
457
    } else if (tts.textAnchor === "end") {
458
      tancx = tancy = textLength / 2;
459
    }
460
    if (this.paint.writingMode.indexOf("tb") === 0) { //縦書きならば、x座標に影響を与えない
461
      tancx = -fontSize * 0.04; //さらにディセンダの調整を行う
462
    } else {
463
      tancy = -fontSize * 0.04;
464
    }
465
    tts.left = ptm.x - tancx;
466
    tts.top = ptm.y - tancy;
467
    p = ptm = tancx = tancy = fij = w = h = null;
468
    this.textLength = textLength;
469
  } catch(e) {stlog.add(e,2831);}
470
  p = ptm = tancx = tancy = null;
471
  this.textLength = textLength;
472
}
473
//fontset フォントの大きさを幅と高さを使ってpx単位に変換
474
function fontset( /*float*/ f, /*float*/ w, /*float*/ h, /*Matrix*/ ttm) {
475
  try {
476
  var sw = new STLength(f, Math.sqrt((w*w + h*h) / 2));
477
  var swx = sw.value * Math.sqrt(Math.abs(ttm.determinant()));
478
  sw = null;
479
  } catch(e) {stlog.add(e,282);swx=f;}
480
  return swx;
481
}
482

  
483
//span要素の処理
484
function STTSpanElement( /*element*/ ele, /*string*/ dx, /*string*/ dy, /*Matrix*/ matrix, /*float*/w, h) {
485
  this.tar = ele;
486
  var x = ele.getAttribute("x"), y = ele.getAttribute("y"), spandx = ele.getAttribute("dx"), spandy = ele.getAttribute("dy");
487
  this.x = x ? new STLength(x, w) : null;
488
  this.y = y ? new STLength(y, h) : null;
489
  this.dx = (dx || spandx) ? new STLength(spandx || dx) : null; //自分の要素と親要素が両方ともdx属性を持たないならば、nullにしてずらさないようにする。
490
  this.dy = (dy || spandy) ? new STLength(spandy || dy) : null;
491
  this.paint = new NAIBU.FontStyle(ele);
492
  this.transformable = NAIBU.transformToCTM(ele, matrix);
493
  return this;
494
}
495
//ddはずれの値を持つオブジェクトをあらわす
496
STTSpanElement.prototype.set = function(w, h, dd) {
497
  try {
498
  var tts = this.tar.style;
499
  tts.position = "relative";
500
  tts.left = (this.dx ? this.dx.value : 0) + dd.dx+ "px";
501
  tts.top = (this.dy ? this.dy.value : 0) + dd.dy+ "px";
502
  var p, ptm;
503
  if (this.x && this.y) { //x属性とy属性が指定されていたならば(注:仕様と相違がある可能性?)。
504
    p = new Point(this.x.value, this.y.value);
505
    ptm = p.matrixTransform(this.transformable);
506
    tts.position = "absolute";
507
    tts.left = ptm.x+ "px";
508
    tts.top = ptm.y+ "px";
509
  }
510
  p = ptm = w = h = null;
511
  //ずれの値を返す
512
  return {dx : parseFloat(tts.left), dy : parseFloat(tts.top)}
513
  } catch(e) {stlog.add(e,304);}
514
}
515

  
516
//line要素の処理
517
function STLine( /*element*/ li, /*Matrix*/ matrix, /*float*/w, h) {
518
  this.tar = li;
519
  this.x1 = new STLength((li.getAttribute("x1") || 0), w);
520
  this.y1 = new STLength((li.getAttribute("y1") || 0), h);
521
  this.x2 = new STLength((li.getAttribute("x2") || 0), w);
522
  this.y2 = new STLength((li.getAttribute("y2") || 0), h);
523
  this.paint = new NAIBU.PaintColor(li);
524
  this.transformable = NAIBU.transformToCTM(li,matrix);
525
  return this;
526
}
527
STLine.prototype.set = function lineset(w,h) {
528
  try {
529
    var ttm = this.transformable;
530
    var list = ["m", this.x1.value, this.y1.value, "l", this.x2.value, this.y2.value];
531
    var pl = new PList(list);
532
    var plm = pl.matrixTransform(ttm);
533
    var dat = plm.list.join(" ");
534
    var ele = this.tar;
535
    ele.path = dat;
536
    ele.coordsize = w + " " + h;
537
    this.paint.set(w, h, ttm);
538
    list = pl = plm = dat = this.paint = ttm = this.transformable = w = h = null;
539
  } catch(e) {stlog.add(e,257);}
540
}
541

  
542
//path要素の処理
543
function STPath( /*element*/ ele, /*Matrix*/ matrix) {
544
  this.tar = ele;
545
  this.d = ele.getAttribute("d");
546
  this.paint = new NAIBU.PaintColor(ele);
547
  this.transformable = NAIBU.transformToCTM(ele,matrix);
548
  return this;
549
}
550
STPath.prototype.set = function ( /*float*/ w, /*float*/ h) {
551
  var dat = "";
552
  try {
553
    var dd = this.d
554
      .replace(/\s*([A-DF-Z])/gi, '],["$1" ') //convert to JSON array
555
      .replace(/^\],/, "[")
556
      .replace(/\s*$/, "]]")
557
      .replace(/[\s,]{2,}|\s/g, ",")
558
      .replace(/([\d.])-/g, "$1,-");
559
    var D = eval('('+dd+')'); //ここまでd属性のパーサ
560
    var ttm = this.transformable;
561
    var preCom;
562
    var x = 0, y = 0;   //現在の点の絶対座標
563
    var x0 = 0, y0 = 0; //subpath の始点の絶対座標
564
    var dx = 0, dy = 0;
565
    var tma = ttm.a, tmb = ttm.b, tmc = ttm.c, tmd = ttm.d, tme = ttm.e, tmf = ttm.f;
566
    for (var i = 0, Dli = D.length; i < Dli; ++i) {
567
      var F = D[i];
568
      var com = F[0].toLowerCase(); //F[0]の値はコマンド文字
569
      var rel = (com === F[0]);     //相対座標のコマンドならtrue
570
      if (com === "z") {
571
        F = ["x"];
572
        x = x0; y = y0;
573
      } else if (com === "a") { //ArcTo
574
        F[0] = "c";
575
        preCom = com;
576
        var relx = 0, rely = 0;
577
        if (rel) {
578
          relx = x; rely = y;
579
        }
580
        var ar = new STArc();
581
        ar.sset(x, y, F, relx, rely);
582
        x = F[F.length-2] + relx;
583
        y = F[F.length-1] + rely;
584
        var pl = new PList(ar.D);
585
        var plm = pl.matrixTransform(ttm);
586
        F = ["c"].concat(plm.list);
587
        if (F.length === 8) {
588
          F[7] = "";
589
        }
590
      } else {
591
        var rx = x, ry = y;
592
        if (rel) {
593
          rx = ry = 0;
594
        }
595
        switch (com) { //ここはif文ではなくて、switch文で処理する必要がある。
596
          case "h": F = ["l", F[F.length-1], ry];
597
          break;
598
          case "v": F = ["l", rx, F[F.length-1]];
599
          break;
600
          case "s": F[0] = "c"; if (preCom !== "c") {dx = dy = 0;} F = NAIBU.nst(6, F, rx + dx, ry + dy);
601
          break;
602
          case "t": F[0] = "q"; if (preCom !== "q") {dx = dy = 0;} F = NAIBU.nst(4, F, rx + dx, ry + dy);
603
          break;
604
          default:  F[0] = com; //"M", "L", "C", "Q" は小文字に変換
605
        }
606
        if (rel) {
607
          F = NAIBU.reltoabs(x, y, F); //絶対座標に変換
608
        }
609
        preCom = com = F[0];
610
        if (com === "c" || com === "q") {
611
          var Fli = F.length;
612
          dx = F[Fli-2] - F[Fli-4];
613
          dy = F[Fli-1] - F[Fli-3];
614
        }
615
        if (com === "q") {
616
          F = NAIBU.qtoc(x, y, F); //二次ベジェは三次ベジェに変換
617
        }
618
        if (com === "m") {
619
          x0 = F[1]; y0 = F[2]; //subpath の始点を記憶
620
        }
621
        var Fli = F.length;
622
        x = F[Fli-2];
623
        y = F[Fli-1];
624
        var _x, _y; //この変数は初期化されないために必要
625
        for (var j = 1; j < Fli; j += 2) { //CTMで座標変換
626
          _x = parseInt(tma * F[j] + tmc * F[j+1] + tme, 10);
627
          _y = parseInt(tmb * F[j] + tmd * F[j+1] + tmf, 10);
628
          F[j]   = _x;
629
          F[j+1] = _y;
630
        }
631
        if (com === "m" && Fli > 3) { //MoveToが複数の座標ならば、2番目以降の座標ペアをLineToとして処理
632
          F.splice(3, 0, "l");
633
        }
634
      }
635
      dat += F.join(" ");
636
      F = null;
637
    }
638
    D = dd = Fli = null; //解放
639
  } catch(e) {if(this.d == ""){/*d属性が空*/}else{stlog.add(e,355);}}
640
  try {
641
    var ele = this.tar;
642
    ele.path = dat + " e";
643
    ele.coordsize = w + " " + h;
644
    this.paint.set(w, h, ttm);
645
    dat = this.paint = ttm = this.transformable = this.d = preCom = x = y = x0 = y0 = dx = dy = tma = tmb = tmc = tmd = tme = tmf = w = h = null; //解放
646
  } catch(e) {stlog.add(e,372);}
647
};
648

  
649
//QからCに変換
650
NAIBU.qtoc = function (/*float*/ x, /*float*/ y, /*Array*/ F) {
651
  F[0] = "c";
652
  for (var i = 1; i < F.length; i += 6) {
653
    var x1 = F[i], y1 = F[i+1], x2 = F[i+2], y2 = F[i+3];
654
    F.splice(i, 2, (x + 2 * x1) / 3, (y + 2 * y1) / 3, (2 * x1 + x2) / 3, (2 * y1 + y2) / 3);
655
    x = x2; y = y2;
656
  }
657
  return F;
658
}
659

  
660
//前回の座標を反転させる。それを挿入
661
NAIBU.nst = function ( /*int*/ skip, /*Array*/ F, /*float*/ x1, /*float*/ y1) {
662
  F.splice(1, 0, x1, y1);
663
  for (var i = skip+1; i < F.length; i += skip) {
664
    x1 = 2 * F[i-2] - F[i-4];
665
    y1 = 2 * F[i-1] - F[i-3];
666
    F.splice(i, 0, x1, y1);
667
  }
668
  return F;
669
}
670

  
671
//相対座標を絶対座標に変換
672
NAIBU.reltoabs = function (/*float*/ x, /*float*/ y, /*Array*/ F) {
673
  var skip = 2;
674
  if (F[0] === "c") { 
675
    skip = 6;
676
  } else if (F[0] === "q") {
677
    skip = 4;
678
  }
679
  for (var i = 1, Fli = F.length; i < Fli; i += 2) {
680
    F[i] += x; F[i+1] += y;
681
    if ((i+1) % skip === 0) {
682
      x = F[i]; y = F[i+1];
683
    }
684
  }
685
  return F;
686
}
687

  
688
//polygon要素を処理
689
function STPolygon( /*element*/ ele, /*Matrix*/ matrix) {
690
  this.tar = ele;
691
  this.points = ele.attributes["points"].nodeValue;
692
  this.paint = new NAIBU.PaintColor(ele);
693
  this.transformable = NAIBU.transformToCTM(ele,matrix);
694
  return this;
695
}
696
STPolygon.prototype.set = function polygonset(w,h) {
697
  var dat;
698
  var ttm = this.transformable;
699
  try {
700
    var F = this.points.replace(/^\s+|\s+$/g, "").split(/[\s,]+/);
701
    var pl = new PList(F);
702
    var plm = pl.matrixTransform(ttm);
703
    plm.list.splice(2, 0, "l");
704
    dat = "m" + plm.list.join(" ") + "x e";
705
  } catch(e) {stlog.add(e,395);}
706
  try {
707
    var ele = this.tar;
708
    ele.path = dat;
709
    ele.coordsize = w + " " + h;
710
    this.paint.set(w, h, ttm);
711
  } catch(e) {stlog.add(e,406);}
712
}
713

  
714
//polyline要素を処理
715
function STPolyline( /*element*/ ele, /*Matrix*/ matrix) {
716
  this.tar = ele;
717
  this.points = ele.attributes["points"].nodeValue;
718
  this.paint = new NAIBU.PaintColor(ele);
719
  this.transformable = NAIBU.transformToCTM(ele,matrix);
720
  return this;
721
}
722
STPolyline.prototype.set = function polylineset(w,h) {
723
  var dat;
724
  var ttm = this.transformable;
725
  try {
726
    var F = this.points.replace(/^\s+|\s+$/g, "").split(/[\s,]+/);
727
    var pl = new PList(F);
728
    var plm = pl.matrixTransform(ttm);
729
    plm.list.splice(2, 0, "l");
730
    dat = "m" + plm.list.join(" ") + "e";
731
  } catch(e) {stlog.add(e,429);}
732
  try {
733
    var ele = this.tar;
734
    ele.path = dat;
735
    ele.coordsize = w + " " + h;
736
    this.paint.set(w, h, ttm);
737
  } catch(e) {stlog.add(e,440);}
738
}
739

  
740
//circle要素を処理
741
function STCircle( /*element*/ ele, /*Matrix*/ matrix, /*float*/w, h) {
742
  this.tar = ele;
743
  try {
744
    this.cx = new STLength((ele.getAttribute("cx") || 0), w);
745
    this.cy = new STLength((ele.getAttribute("cy") || 0), h);
746
    this.r = new STLength(ele.getAttribute("r"));
747
    this.paint = new NAIBU.PaintColor(ele);
748
    this.transformable = NAIBU.transformToCTM(ele,matrix);
749
    w = h = null;
750
  } catch(e) {stlog.add(e,450);}
751
  return this;
752
}
753
//ベジェ曲線で円を表現する
754
STCircle.prototype.set = function ovalset(w,h) {
755
  var cx = this.cx.value, cy = this.cy.value, rx = ry = this.r.value;
756
  var top = cy - ry, left = cx - rx, bottom = cy + ry, right = cx + rx;
757
  try {
758
  var ttm = this.transformable;
759
  var rrx = rx * 0.55228, rry = ry * 0.55228;
760
  var list = ["m", cx,top, "c", cx-rrx,top, left,cy-rry, left,cy, left,cy+rry, cx-rrx,bottom, cx,bottom, cx+rrx,bottom, right,cy+rry, right,cy, right,cy-rry, cx+rrx,top, cx,top, "x e"];
761
  var pl = new PList(list);
762
  var plm = pl.matrixTransform(ttm);
763
  var dat = plm.list.join(" ");
764
  } catch(e) {stlog.add(e,468);}
765
  try {
766
    var ele = this.tar;
767
    ele.path = dat;
768
    ele.coordsize = w + " " + h;
769
    this.paint.set(w, h, ttm);
770
    dat = list = pl = plm = this.paint = ttm = this.transformable = w = h = null; //解放
771
  } catch(e) {stlog.add(e,479);}
772
}
773

  
774
//ellipse要素を処理
775
function STEllipse( /*element*/ ele, /*Matrix*/ matrix, /*float*/w, h) {
776
  this.tar = ele;
777
  try {
778
    this.cx = new STLength((ele.getAttribute("cx") || 0), w);
779
    this.cy = new STLength((ele.getAttribute("cy") || 0), h);
780
    this.rx = new STLength(ele.getAttribute("rx"), w);
781
    this.ry = new STLength(ele.getAttribute("ry"), h);
782
    this.paint = new NAIBU.PaintColor(ele);
783
    this.transformable = NAIBU.transformToCTM(ele,matrix);
784
    w = h = null;
785
  } catch(e) {stlog.add(e,490);}
786
  return this;
787
}
788
STEllipse.prototype.set = function elliset(w,h) {
789
  var cx = this.cx.value, cy = this.cy.value, rx = this.rx.value, ry = this.ry.value;
790
  var top = cy - ry, left = cx - rx, bottom = cy + ry, right = cx + rx;
791
  try {
792
  var ttm = this.transformable;
793
  var rrx = rx * 0.55228, rry = ry * 0.55228;
794
  var list = ["m", cx,top, "c", cx-rrx,top, left,cy-rry, left,cy, left,cy+rry, cx-rrx,bottom, cx,bottom, cx+rrx,bottom, right,cy+rry, right,cy, right,cy-rry, cx+rrx,top, cx,top, "x e"];
795
  var pl = new PList(list);
796
  var plm = pl.matrixTransform(ttm);
797
  var dat = plm.list.join(" ");
798
  } catch(e) {stlog.add(e,508);}
799
  try {
800
    var ele = this.tar;
801
    ele.path = dat;
802
    ele.coordsize = w + " " + h;
803
    this.paint.set(w, h, ttm);
804
    dat = list = pl = plm = this.paint = ttm = this.transformable = w = h = null; //解放
805
  } catch(e) {stlog.add(e,519);}
806
}
807

  
808
//rect要素を処理
809
function STRectElement( /*element*/ rect, /*Matrix*/ matrix, /*float*/ w, h) {
810
  this.tar = rect;
811
  try {
812
    this.x = new STLength((rect.getAttribute("x") || 0), w);
813
    this.y = new STLength((rect.getAttribute("y") || 0), h);
814
    this.width = new STLength(rect.getAttribute("svgwidth"), w);
815
    this.height = new STLength(rect.getAttribute("svgheight"), h);
816
    var rx = rect.getAttribute("rx"), ry = rect.getAttribute("ry");
817
    if (rx || ry) {
818
      this.rx = new STLength((rx || ry), w);
819
      this.ry = new STLength((ry || rx), h);
820
      if (this.rx.value > this.width.value / 2) { //rx属性が幅より大きければ、幅の半分を属性に設定
821
        this.rx.value = this.width.value / 2;
822
      }
823
      if (this.ry.value > this.height.value / 2) {
824
        this.ry.value = this.height.value / 2;
825
      }
826
    }
827
    this.paint = new NAIBU.PaintColor(rect);
828
    this.transformable = NAIBU.transformToCTM(rect,matrix);
829
    w = h = rx = ry = null;
830
  } catch(ee) {stlog.add(ee,545);}
831
  return this;
832
}
833
STRectElement.prototype.set = function rectset(w,h) {
834
  try {
835
    var x = this.x.value, y = this.y.value, xw = x + this.width.value, yh = y + this.height.value;
836
    var list;
837
    if (this.rx) {
838
      var rx = this.rx.value, ry = this.ry.value;
839
      var rrx = rx * 0.55228, rry = ry * 0.55228;
840
      var a = xw - rx, b = x + rx, c = y + ry, d = yh - ry;
841
      list = ["m",b,y, "l",a,y, "c",a+rrx,y,xw,c-rry,xw,c, "l",xw,d, "c",xw,d+rry,a+rrx,yh,a,yh, "l",b,yh, "c",b-rrx,yh,x,d+rry,x,d, "l",x,c, "c",x,c-rry,b-rrx,y,b,y];
842
    } else {
843
      list = ["m",x,y, "l",x,yh, xw,yh, xw,y, "x e"];
844
    }
845
    var ttm = this.transformable;
846
    var pl = new PList(list);
847
    var plm = pl.matrixTransform(ttm);
848
    var dat = plm.list.join(" ");
849
  } catch(e) {stlog.add(e,564);}
850
  try {
851
    var ele = this.tar;
852
    ele.path = dat;
853
    ele.coordsize = w + " " + h;
854
    this.paint.set(w, h, ttm);
855
    dat = list = pl = plm = this.paint = ttm = this.transformable = w = h = null; //解放
856
  } catch(ee) {stlog.add(ee,576);}
857
}
858

  
859
//image要素の処理
860
function STImage( /*element*/ ele, /*Matrix*/ matrix, /*float*/w, h){
861
  this.tar = ele;
862
  this.x = new STLength((ele.getAttribute("x") || 0), w);
863
  this.y = new STLength((ele.getAttribute("y") || 0), h);
864
  this.width = new STLength(ele.getAttribute("svgwidth"), w);
865
  this.height = new STLength(ele.getAttribute("svgheight"), h);
866
  ele.setAttribute("xlink:show", "embed");
867
  this.xlink = new NAIBU.XLink(ele);
868
  this.paint = new NAIBU.PaintColor(ele);
869
  this.transformable = NAIBU.transformToCTM(ele,matrix);
870
  w = h = null
871
  return this;
872
}
873
STImage.prototype.set = function imagesets(w,h){
874
  try {
875
    var ttm = this.transformable;
876
    var ts = this.tar.style;
877
    ts.position = "absolute";
878
    var pt = new Point(this.x.value, this.y.value);
879
    var ptt = pt.matrixTransform(ttm);
880
    ts.left = ptt.x+ "px";
881
    ts.top =  ptt.y+ "px";
882
    ts.width = this.width.value * ttm.a+ "px";
883
    ts.height = this.height.value * ttm.d+ "px";
884
    if (ttm.b !== 0 || ttm.c !== 0 || this.paint.fillopacity != 1) {//フィルター プロパティを使うと、PNGの透過性がなくなるので注意
885
      ts.filter = "progid:DXImageTransform.Microsoft.Matrix progid:DXImageTransform.Microsoft.Alpha";
886
      var ttfi = this.tar.filters.item('DXImageTransform.Microsoft.Matrix');
887
      ttfi.M11 = 1;
888
      ttfi.M12 = ttm.b;
889
      ttfi.M21 = ttm.c;
890
      ttfi.M22 = 1;
891
      ttfi.sizingMethod = "auto expand";
892
      var ttfia = this.tar.filters.item('DXImageTransform.Microsoft.Alpha');
893
      ttfia.Style = 0;
894
      ttfia.Opacity = parseFloat(this.paint.fillopacity)*100;
895
    }
896
    this.xlink.set();
897
    dat = pt = this.xlink = this.paint = ttm = this.transformable = w = h = null; //解放
898
  } catch(e) {stlog.set(e,21896);}
899
}
900

  
901
/*use要素の処理*/
902
function STUseElement( /*element*/ ele,  /*float*/w, h){
903
  this.tar = ele;
904
  var tns = ele.nextSibling;
905
  tns.setAttribute("xlink:show", "embed")
906
  this.x = new STLength((tns.getAttribute("x") || 0), w);
907
  this.y = new STLength((tns.getAttribute("y") || 0), h);
908
  this.width = new STLength(tns.getAttribute("svgwidth"), w);
909
  this.height = new STLength(tns.getAttribute("svgheight"), h);
910
  this.xlink = new NAIBU.XLink(tns);
911
  var ts = tns.getAttribute("transform") || "";
912
  this.xlink.set();
913
  tns.setAttribute("transform", ts+ " translate(" +this.x.value+ "," +this.y.value+ ")");
914
  tns.firstChild.setAttribute("id","");
915
  tns.coordorgin = "0  0";
916
  this.paint = new NAIBU.PaintColor(this.xlink.resource);
917
  this.paint.tar = tns;
918
  w = h = null;
919
  return this;
920
}
921
STUseElement.prototype.set = function(){
922
  try {
923
    this.paint.setStyle();
924
    this.paint = this.xlink = null;
925
  } catch(e) {stlog.add(e,85436);}
926
}
927

  
928
//色のキーワード
929
//PaintColor 色、線などをすべてコントロール
930
NAIBU.PaintColor = function( /*element*/ ele) {
931
if (ele) {
932
  this.tar = ele;
933
  var defaults = this.defaults;
934
  var parent = this.getParent(ele); //親要素のPaintColorオブジェクト
935
  if (parent) {
936
    for (var name in defaults) {
937
      if (defaults.hasOwnProperty(name)) {
938
        if (name === "opacity") {
939
          this[name] = (this.getAttribute(name) || 1) * parent[name]; //親要素のopacityを掛け合わせる
940
        } else {
941
          this[name] = this.getAttribute(name) || parent[name]; //指定がなければ親要素の値を継承
942
          if (this[name] === "inherit") { //値がinheritなら親のを継承
943
            this[name] = parent[name];
944
          } else if (this[name] === "currentColor") {
945
            this[name] = this.getAttribute("color") || parent.getAttribute("color");
946
          }
947
        }
948
      }
949
      name = null;
950
    }
951
  } else {
952
    for (var name in defaults) {
953
      this[name] = this.getAttribute(name) || defaults[name]; //指定がなければデフォルト値に設定
954
      name = null;
955
    }
956
  }
957
}
958
  return this;
959
};
960
//デフォルト値のリスト
961
NAIBU.PaintColor.prototype.defaults = {
962
  fill: "black",
963
  fillopacity: 1,
964
  stroke: "none",
965
  strokewidth: "1",
966
  strokelinecap: "butt",
967
  strokelinejoin: "miter",
968
  strokemiterlimit: "4",
969
  strokedasharray: "none",
970
  strokeopacity: 1,
971
  opacity: 1,
972
  cursor: "default"
973
};
974
//キャッシュ用
975
NAIBU.PaintColor.prototype.cache = {};
976
//親コンテナ要素のPaintColorオブジェクトを返す
977
NAIBU.PaintColor.prototype.getParent = function( /*element*/ ele) {
978
  var parent = ele.parentNode;
979
  if (parent.tagName !== "group" && parent.tagName !== "A") {
980
    return null;
981
  } else {
982
    var cache = this.cache;
983
    var id = parent.uniqueID;
984
    if (!cache[id]) {
985
      cache[id] = new NAIBU.PaintColor(parent);
986
    }
987
    return cache[id];
988
  }
989
};
990
NAIBU.PaintColor.prototype.getAttribute = function ( /*string*/ name) {
991
  try {
992
    var element = this.tar;
993
    var style = element.style[name];
994
    if (style) {
995
      return style;
996
    }
997
    var attribute = element.attributes[name];
998
    var s = attribute ? attribute.nodeValue : null;
999
    return s;
1000
  } catch(e) {stlog.add(e,659); return null;}
1001
};
1002
//内部プロパティを、styleに設定する
1003
NAIBU.PaintColor.prototype.setStyle = function() {
1004
  try {
1005
    var tst = this.tar
1006
    for (var i in this) {
1007
      if ((typeof this[i]) === "string") { //string型以外は除く
1008
        tst.style[i] = this[i];
1009
      }
1010
    }
1011
  } catch(e) {stlog.add(e,899); return "";}
1012
};
1013
NAIBU.PaintColor.prototype._urlreg = /url\(#([^)]+)/;
1014
NAIBU.PaintColor.prototype.set = function (/*float*/ w, /*float*/ h, /*Matrix*/ matrix) {
1015
  var el = this.tar;
1016
  if (this.fill === "none") {
1017
    el.filled = "false";
1018
  } else {
1019
    var fillElement = document.createElement("v:fill");
1020
    var isRadial = false;
1021
    try {
1022
    if (this._urlreg.test(this.fill)) { //fill属性の値がurl(#id)ならば、idを設定したグラデーション関連要素を呼び出す
1023
      this.w = w; this.h = h; //radialGradientで必要
1024
      isRadial = this.gradient(fillElement, RegExp.$1, matrix);
1025
    } else {
1026
      fillElement.setAttribute("color", this.color(this.fill));
1027
      var fillOpacity = this.fillopacity * this.opacity; //opacityを掛け合わせる
1028
      if (fillOpacity < 1) {
1029
        fillElement.setAttribute("opacity", fillOpacity);
1030
      }
1031
    }
1032
    } catch(e) {stlog.add(e,682); fillElement.on = "true";
1033
    fillElement.color = "black";}
1034
    if (!isRadial) {
1035
      el.appendChild(fillElement);
1036
    }
1037
    isRadial = fillOpacity = null;
1038
  }
1039
  if (this.stroke === "none") {
1040
    el.stroked = "false";
1041
  } else {
1042
    var strokeElement = document.createElement("v:stroke");
1043
    try {
1044
    var sw = new STLength(this.strokewidth, Math.sqrt((w*w + h*h) / 2));
1045
    var swx = sw.value * Math.sqrt(Math.abs(matrix.determinant()));
1046
    strokeElement.setAttribute("weight", swx + "px");
1047
    if (this.stroke.match(/url\(#([^)]+)/)) {
1048
      this.gradient(strokeElement, RegExp.$1);
1049
    } else {
1050
      strokeElement.setAttribute("color", this.color(this.stroke));
1051
      var strokeOpacity = this.strokeopacity * this.opacity; //opacityを掛け合わせる
1052
      if (swx < 1) {
1053
        strokeOpacity *= swx; //太さが1px未満なら色を薄くする
1054
      }
1055
      if (strokeOpacity < 1) {
1056
        strokeElement.setAttribute("opacity", strokeOpacity);
1057
      }
1058
      strokeOpacity = null;
1059
    }
1060
    strokeElement.setAttribute("miterlimit", this.strokemiterlimit);
1061
    strokeElement.setAttribute("joinstyle", this.strokelinejoin);
1062
    if (this.strokelinecap === "butt") {
1063
      strokeElement.setAttribute("endcap", "flat");
1064
    } else {
1065
      strokeElement.setAttribute("endcap", this.strokelinecap);
1066
    }
1067
    var tsd = this.strokedasharray;
1068
    if (tsd !== "none") {
1069
      if (tsd.indexOf(",") > 0) { //コンマ区切りの文字列の場合
1070
        var strs = tsd.split(",");
1071
        for (var i = 0, sli = strs.length; i < sli; ++i) {
1072
          strs[i] = Math.ceil(parseFloat(strs[i]) / parseFloat(this.strokewidth)); //精密ではないので注意
1073
        }
1074
        this.strokedasharray = strs.join(" ");
1075
        if (strs.length % 2 == 1) {
1076
          this.strokedasharray += " " + this.strokedasharray;
1077
        }
1078
      }
1079
      strokeElement.setAttribute("dashstyle", this.strokedasharray);
1080
      tsd = strs = null;
1081
    }
1082
    } catch(e) {stlog.add(e,720); strokeElement.on =  "false";}
1083
    el.appendChild(strokeElement);
1084
    sw = tsd = null;
1085
  }
1086
  if (this.cursor !== "default") {
1087
    this.tar.style.cursor = this.cursor;
1088
  }
1089
  w = h = null;
1090
};
1091
//色キーワード
1092
NAIBU.PaintColor.prototype.keywords = {
1093
  aliceblue: "#F0F8FF",
1094
  antiquewhite: "#FAEBD7",
1095
  aquamarine: "#7FFFD4",
1096
  azure: "#F0FFFF",
1097
  beige: "#F5F5DC",
1098
  bisque: "#FFE4C4",
1099
  blanchedalmond: "#FFEBCD",
1100
  blueviolet: "#8A2BE2",
1101
  brown: "#A52A2A",
1102
  burlywood: "#DEB887",
1103
  cadetblue: "#5F9EA0",
1104
  chartreuse: "#7FFF00",
1105
  chocolate: "#D2691E",
1106
  coral: "#FF7F50",
1107
  cornflowerblue: "#6495ED",
1108
  cornsilk: "#FFF8DC",
1109
  crimson: "#DC143C",
1110
  cyan: "#00FFFF",
1111
  darkblue: "#00008B",
1112
  darkcyan: "#008B8B",
1113
  darkgoldenrod: "#B8860B",
1114
  darkgray: "#A9A9A9",
1115
  darkgreen: "#006400",
1116
  darkgrey: "#A9A9A9",
1117
  darkkhaki: "#BDB76B",
1118
  darkmagenta: "#8B008B",
1119
  darkolivegreen: "#556B2F",
1120
  darkorange: "#FF8C00",
1121
  darkorchid: "#9932CC",
1122
  darkred: "#8B0000",
1123
  darksalmon: "#E9967A",
1124
  darkseagreen: "#8FBC8F",
1125
  darkslateblue: "#483D8B",
1126
  darkslategray: "#2F4F4F",
1127
  darkslategrey: "#2F4F4F",
1128
  darkturquoise: "#00CED1",
1129
  darkviolet: "#9400D3",
1130
  deeppink: "#FF1493",
1131
  deepskyblue: "#00BFFF",
1132
  dimgray: "#696969",
1133
  dimgrey: "#696969",
1134
  dodgerblue: "#1E90FF",
1135
  firebrick: "#B22222",
1136
  floralwhite: "#FFFAF0",
1137
  forestgreen: "#228B22",
1138
  gainsboro: "#DCDCDC",
1139
  ghostwhite: "#F8F8FF",
1140
  gold: "#FFD700",
1141
  goldenrod: "#DAA520",
1142
  grey: "#808080",
1143
  greenyellow: "#ADFF2F",
1144
  honeydew: "#F0FFF0",
1145
  hotpink: "#FF69B4",
1146
  indianred: "#CD5C5C",
1147
  indigo: "#4B0082",
1148
  ivory: "#FFFFF0",
1149
  khaki: "#F0E68C",
1150
  lavender: "#E6E6FA",
1151
  lavenderblush: "#FFF0F5",
1152
  lawngreen: "#7CFC00",
1153
  lemonchiffon: "#FFFACD",
1154
  lightblue: "#ADD8E6",
1155
  lightcoral: "#F08080",
1156
  lightcyan: "#E0FFFF",
1157
  lightgoldenrodyellow: "#FAFAD2",
1158
  lightgray: "#D3D3D3",
1159
  lightgreen: "#90EE90",
1160
  lightgrey: "#D3D3D3",
1161
  lightpink: "#FFB6C1",
1162
  lightsalmon: "#FFA07A",
1163
  lightseagreen: "#20B2AA",
1164
  lightskyblue: "#87CEFA",
1165
  lightslategray: "#778899",
1166
  lightslategrey: "#778899",
1167
  lightsteelblue: "#B0C4DE",
1168
  lightyellow: "#FFFFE0",
1169
  limegreen: "#32CD32",
1170
  linen: "#FAF0E6",
1171
  magenta: "#FF00FF",
1172
  mediumaquamarine: "#66CDAA",
1173
  mediumblue: "#0000CD",
1174
  mediumorchid: "#BA55D3",
1175
  mediumpurple: "#9370DB",
1176
  mediumseagreen: "#3CB371",
1177
  mediumslateblue: "#7B68EE",
1178
  mediumspringgreen: "#00FA9A",
1179
  mediumturquoise: "#48D1CC",
1180
  mediumvioletred: "#C71585",
1181
  midnightblue: "#191970",
1182
  mintcream: "#F5FFFA",
1183
  mistyrose: "#FFE4E1",
1184
  moccasin: "#FFE4B5",
1185
  navajowhite: "#FFDEAD",
1186
  oldlace: "#FDF5E6",
1187
  olivedrab: "#6B8E23",
1188
  orange: "#FFA500",
1189
  orangered: "#FF4500",
1190
  orchid: "#DA70D6",
1191
  palegoldenrod: "#EEE8AA",
1192
  palegreen: "#98FB98",
1193
  paleturquoise: "#AFEEEE",
1194
  palevioletred: "#DB7093",
1195
  papayawhip: "#FFEFD5",
1196
  peachpuff: "#FFDAB9",
1197
  peru: "#CD853F",
1198
  pink: "#FFC0CB",
1199
  plum: "#DDA0DD",
1200
  powderblue: "#B0E0E6",
1201
  rosybrown: "#BC8F8F",
1202
  royalblue: "#4169E1",
1203
  saddlebrown: "#8B4513",
1204
  salmon: "#FA8072",
1205
  sandybrown: "#F4A460",
1206
  seagreen: "#2E8B57",
1207
  seashell: "#FFF5EE",
1208
  sienna: "#A0522D",
1209
  skyblue: "#87CEEB",
1210
  slateblue: "#6A5ACD",
1211
  slategray: "#708090",
1212
  slategrey: "#708090",
1213
  snow: "#FFFAFA",
1214
  springgreen: "#00FF7F",
1215
  steelblue: "#4682B4",
1216
  tan: "#D2B48C",
1217
  thistle: "#D8BFD8",
1218
  tomato: "#FF6347",
1219
  turquoise: "#40E0D0",
1220
  violet: "#EE82EE",
1221
  wheat: "#F5DEB3",
1222
  whitesmoke: "#F5F5F5",
1223
  yellowgreen: "#9ACD32"
1224
};
1225
//<color>をVML用に変換
1226
NAIBU.PaintColor.prototype.color = function( /*string*/ color) {
1227
  if (this.keywords[color]) {
1228
    return this.keywords[color];
1229
  }
1230
  if (color.indexOf("%", 5) > 0) { // %を含むrgb形式の場合
1231
    return color.replace(/[\d.]+%/g, function(s) {
1232
      return Math.round(2.55 * parseFloat(s));
1233
    });
1234
  }
1235
  return color;
1236
};
1237
//linearGradient、radialGradient要素を処理
1238
NAIBU.PaintColor.prototype.gradient = function ( /*element*/ ele, /*string*/ id, /*Matrix*/ matrix) {
1239
  var grad = document.getElementById(id);
1240
  if (grad) {
1241
  var grad2 = grad;
1242
  while (grad2 && !grad2.hasChildNodes()) { //stopを子要素に持つgradient要素を探す
1243
    grad2.getAttribute("xlink:href").match(/#(.+)/);
1244
    grad2 = document.getElementById(RegExp.$1);
1245
  }
1246
  var stops = grad2.getElementsByTagName("stop");
1247
  if (!stops) {
1248
    grad = grad2 = stops = null;
1249
    return false;
1250
  }
1251
  var length = stops.length;
1252
  var color = [], colors = [], opacity = [];
1253
  for (var i = 0; i < length; ++i) {
1254
    var stop = stops[i];
1255
    color[i] = this.color(stop.style.stopcolor || stop.getAttribute("stopcolor")) || "black";
1256
    colors[i] = stop.getAttribute("offset") + " " + color[i];
1257
    opacity[i] = (stop.style.stopopacity || stop.getAttribute("stopopacity") || 1) * this.fillopacity * this.opacity;
1258
  }
1259
  ele.setAttribute("method", "none");
1260
  ele.setAttribute("color",  color[0]);
1261
  ele.setAttribute("color2", color[length-1]);
1262
  ele.setAttribute("colors", colors.join(","));
1263
  // When colors attribute is used, the meanings of opacity and o:opacity2 are reversed.
1264
  ele.setAttribute("opacity", opacity[length-1]);
1265
  ele.setAttribute("o:opacity2", opacity[0]);
1266
  var type = grad.getAttribute("type");
1267
  if (type === "gradient") {
1268
  try {
1269
    var angle;
1270
    var x1 = parseFloat((grad.getAttribute("x1") || "0").replace(/%/, ""));
1271
    var y1 = parseFloat((grad.getAttribute("y1") || "0").replace(/%/, ""));
1272
    var x2 = parseFloat((grad.getAttribute("x2") || "100").replace(/%/, ""));
1273
    var y2 = parseFloat((grad.getAttribute("y2") || "0").replace(/%/, ""));
1274
    angle = 270 - Math.atan2(y2-y1, x2-x1) * 180 / Math.PI;
1275
    if (angle >= 360) {
1276
      angle -= 360;
1277
    }
1278
  } catch(e) {stlog.add(e,749); angle = 270;}
1279
    ele.setAttribute("type", "gradient");
1280
    ele.setAttribute("angle", angle + "");
1281
    x1 = y1 = x2 = y2 = angle = null;
1282
  } else if (type === "gradientRadial") {
1283
  try{
1284
    ele.setAttribute("type", "gradientTitle");
1285
    ele.setAttribute("focus", "100%");
1286
    ele.setAttribute("focusposition", "0.5 0.5");
1287
    if (this.tar.getAttribute("tag") === "rect") {
1288
    var cx = parseFloat((grad.getAttribute("cx") || "0.5").replace(/%/, ""));
1289
    var cy = parseFloat((grad.getAttribute("cy") || "0.5").replace(/%/, ""));
1290
    var r = rx = ry = parseFloat((grad.getAttribute("r") || "0.5").replace(/%/, ""));
1291
    var el = this.w, et = this.h, er = 0, eb = 0;
1292
    var data = this.tar.getAttribute("path")+"";
1293
    var units = grad.getAttribute("gradientUnits");
1294
    if (!units || units === "objectBoundingBox") {
1295
      //%の場合は小数点に変換(10% -> 0.1)
1296
      cx = cx > 1 ? cx/100 : cx; cy = cy > 1 ? cy/100 : cy; r = r > 1 ? r/100 : r;
1297
      //要素の境界領域を求める(四隅の座標を求める)
1298
      var degis = data.match(/[0-9\-]+/g);
1299
      for (var i=0,degisli=degis.length;i<degisli;i+=2) {
1300
        var nx = parseInt(degis[i]), ny = parseInt(degis[i+1]);
1301
        el = el > nx ? nx : el;
1302
        et = et > ny ? ny : et;
1303
        er = er > nx ? er : nx;
1304
        eb = eb > ny ? eb : ny; nx = ny = null;
1305
      }
1306
      degis = null;
1307
      cx = cx*(er - el) + el; cy = cy*(eb - et) + et; rx = r*(er - el); ry = r*(eb - et);
1308
    }
1309
    var gt = grad.getAttribute("gradientTransform");
1310
    if (gt) {
1311
      grad.setAttribute("transform",gt);
1312
      matrix = NAIBU.transformToCTM(grad, matrix);
1313
    }
1314
    el = cx - rx; et = cy - ry; er = cx + rx; eb = cy + ry;
1315
    var rrx = rx * 0.55228, rry = ry * 0.55228;
1316
    var list = ["m", cx,et, "c", cx-rrx,et, el,cy-rry, el,cy, el,cy+rry, cx-rrx,eb, cx,eb, cx+rrx,eb, er,cy+rry, er,cy, er,cy-rry, cx+rrx,et, cx,et, "x e"];
1317
    var pl = new PList(list);
1318
    var plm = pl.matrixTransform(matrix);
1319
    var ellipse = plm.list.join(" ");
1320
    var outline = document.getElementById("_NAIBU_outline");
1321
    var background = document.createElement("div");
1322
    background.style.position = "absolute";
1323
    background.style.textAlign = "left"; background.style.top = "0px"; background.style.left = "0px"; background.style.width = this.w+ "px"; background.style.height = this.h+ "px";
1324
    outline.appendChild(background);
1325
    background.style.filter = "progid:DXImageTransform.Microsoft.Compositor";
1326
    background.filters.item('DXImageTransform.Microsoft.Compositor').Function = 23;
1327
    var circle = '<v:shape style="position:relative; antialias:false; top:0px; left:0px;" coordsize="' +this.w+ ' ' +this.h+ '" path="' +ellipse+ '" stroked="f">' +ele.outerHTML+ '</v:shape>';
1328
    background.innerHTML = '<v:shape style="position:relative; top:0px; left:0px;" coordsize="' +this.w+ ' ' +this.h+ '" path="' +data+ '" stroked="f" fillcolor="' +color[color.length-1]+ '" ></v:shape>';
1329
    background.filters[0].apply();
1330
    background.innerHTML = circle;
1331
    background.filters[0].play();
1332
    this.tar.parentNode.insertBefore(background, this.tar);
1333
    this.tar.filled = "false";
1334
    ellipse = circle = data = list = pl = plm = gt = cx = cy = r = null;
1335
    } else {
1336
      return false;
1337
    }
1338
    return true;
1339
    } catch(e) {stlog.add(e,1175);}
1340
  }
1341
  } else {
1342
    return false;
1343
  }
1344
  stops = type = lengh = color = colors = opacity = null;
1345
  return false;
1346
};
1347

  
1348
//font属性、関連プロパティを処理する
1349
//PaintColorを継承
1350
NAIBU.FontStyle = function( /*element*/ ele) {
1351
  var td = this.defaults;
1352
  td["font-size"] = "12";
1353
  td["font-family"] = "sans-serif";
1354
  td["font-style"] = "normal";
1355
  td["font-weight"] = "400";
1356
  td["text-transform"] = "none";
1357
  td["text-decoration"] = "none";
1358
  td["writing-mode"] = "lr-tb";
1359
  td["text-anchor"] = "start";
1360
  NAIBU.PaintColor.apply(this,arguments);
1361
  return this;
1362
}
1363
NAIBU.FontStyle.prototype = new NAIBU.PaintColor(false);
1364
//キャッシュ用
1365
NAIBU.FontStyle.prototype.cache = {};
1366
//親コンテナ要素のPaintColorオブジェクトを返す
1367
NAIBU.FontStyle.prototype.getParent = function( /*element*/ ele) {
1368
  try{
1369
  var parent = ele.parentNode;
1370
  if (parent.tagName !== "group" && parent.tagName !== "A" && parent.tagName !== "DIV") {
1371
    return null;
1372
  }
1373
  var cache = this.cache;
1374
  var id = parent.uniqueID;
1375
  if (!cache[id]) {
1376
    cache[id] = new NAIBU.FontStyle(parent);
1377
  }
1378
  } catch(e){stlog.add(e,1179);}
1379
  return cache[id];
1380
}
1381

  
1382
//内部プロパティを、styleに設定する
1383
NAIBU.FontStyle.prototype.setStyle = function() {
1384
  try {
1385
    var tst = this.tar
1386
    for (var i in this) {
1387
      var ti = this[i];
1388
      if ((typeof ti) === "string") { //string型以外は除く
1389
        var sname = i.replace(/\-([a-z])/, "-").replace(/\-/,RegExp.$1.toUpperCase());
1390
        if (ti === "lr") {
1391
          ti = "lr-tb";
1392
        } else if (ti === "tb") {
1393
          ti = "tb-rl";
1394
        }
1395
        tst.style[sname] = ti;
1396
      }
1397
    }
1398
  } catch(e) {stlog.add(e,1396); return "";}
1399
}
1400
NAIBU.FontStyle.prototype.fset = function( /*float*/ w, /*float*/ h, /*Matrix*/ matrix) {
1401
  try{
1402
  this.setStyle();
1403
  var tts = this.tar.style;
1404
  tts.whiteSpace = "nowrap";
1405
  tts.color = this.fill === "none" ? "transparent"  :  this.fill;
1406
  this.fontSize = fontset(this["font-size"],w,h,matrix);
1407
  tts.fontSize = this.fontSize+ "px";
1408
  if (this.cursor !== "default") {
1409
    tts.cursor = this.cursor;
1410
  }
1411
  this.writingMode = tts.writingMode;
1412
  tts.marginTop = (this.writingMode === "tb-rl") ? "0px" : -parseFloat(tts.fontSize)+ "px";
1413
  tts.textIndent = "0px";
1414
 } catch(e){stlog.add(e,1185);}
1415
}
1416

  
1417
//NAIBU.transformToCTM transform属性を処理。Matrix型に変換
1418
//あらかじめ正規表現オブジェクトを生成しておく
1419
NAIBU.comaR = /[A-Za-z]+(?=\s*\()/g;
1420
NAIBU.listR = /\([^\)]+\)/g;
1421
NAIBU.degR = /[\-\d\.e]+/g;
1422
NAIBU.transformToCTM = function ( /*element*/ ele, /*Matrix*/ matrix) {
1423
  try {
1424
  var tft = ele.getAttribute("transform");
1425
  if (tft) {
1426
    var coma = tft.match(NAIBU.comaR); //コマンド文字にマッチ translate
1427
    var list = tft.match(NAIBU.listR); //カッコ内のリストにマッチ (10 20 30...)
1428
    var a,b,c,d,e,f,lis,deg,rad,degli,matri;
1429
    for (var j=0,cli=coma.length;j<cli;j++) {
1430
      lis = list[j], com = coma[j];
1431
      deg = lis.match(NAIBU.degR);
1432
      degli = deg.length;
1433
      if (degli === 6) {
1434
        a = parseFloat(deg[0]); b = parseFloat(deg[1]); c = parseFloat(deg[2]); d = parseFloat(deg[3]); e = parseFloat(deg[4]); f = parseFloat(deg[5]);
1435
      } else {
1436
        rad = parseFloat(deg[0]) / 180 * Math.PI;
1437
        if (degli === 3) {
1438
          var cx = parseFloat(deg[1]), cy = parseFloat(deg[2]);
1439
          a = Math.cos(rad); b = Math.sin(rad); c = -b; d = a; e = (1-a)*cx-c*cy; f = -b*cx+(1-d)*cy;
1440
        } else if (degli <= 2) {
1441
          switch (com) {
1442
          case "translate":
1443
            a = 1; b = 0; c = 0; d = 1; e = parseFloat(deg[0]); f = parseFloat(deg[1] || 0);
1444
          break;
1445
          case "scale":
1446
            a = parseFloat(deg[0]); b = 0; c = 0; d = parseFloat(deg[1] || deg[0]); e = 0; f = 0;
1447
          break;
1448
          case "rotate":
1449
            a = Math.cos(rad); b = Math.sin(rad); c = -b; d = a; e = 0; f = 0;
1450
          break;
1451
          case "skewX":
1452
            a = 1; b = 0; c = Math.tan(rad); d = 1; e = 0; f = 0;
... This diff was truncated because it exceeds the maximum size that can be displayed.
(1-1/2)