support HANE adjustment method
authorKoichi KAMICHI <kamichi@fonts.jp>
Wed, 2 Jan 2013 11:10:27 +0000 (20:10 +0900)
committerKoichi KAMICHI <kamichi@fonts.jp>
Wed, 2 Jan 2013 11:10:27 +0000 (20:10 +0900)
kage.js [new file with mode: 0755]
kagecd.js [new file with mode: 0755]
kagedf.js [new file with mode: 0755]

diff --git a/kage.js b/kage.js
new file mode 100755 (executable)
index 0000000..e6dda8c
--- /dev/null
+++ b/kage.js
@@ -0,0 +1,374 @@
+function Kage(size){\r
+  // method\r
+  function makeGlyph(polygons, buhin){ // void\r
+    var glyphData = this.kBuhin.search(buhin);\r
+    if(glyphData != ""){\r
+       this.drawStrokesArray(polygons, this.adjustKirikuchi(this.adjustUroko2(this.adjustUroko(this.adjustKakato(this.adjustTate(this.adjustMage(this.adjustHane(this.getEachStrokes(glyphData)))))))));\r
+    }\r
+  }\r
+  Kage.prototype.makeGlyph = makeGlyph;\r
+  \r
+  function getEachStrokes(glyphData){ // strokes array\r
+    var strokesArray = new Array();\r
+    var strokes = glyphData.split("$");\r
+    for(var i = 0; i < strokes.length; i++){\r
+      var columns = strokes[i].split(":");\r
+      if(Math.floor(columns[0]) != 99){\r
+        strokesArray.push([\r
+          Math.floor(columns[0]),\r
+          Math.floor(columns[1]),\r
+          Math.floor(columns[2]),\r
+          Math.floor(columns[3]),\r
+          Math.floor(columns[4]),\r
+          Math.floor(columns[5]),\r
+          Math.floor(columns[6]),\r
+          Math.floor(columns[7]),\r
+          Math.floor(columns[8]),\r
+          Math.floor(columns[9]),\r
+          Math.floor(columns[10])\r
+          ]);\r
+      } else {\r
+        var buhin = this.kBuhin.search(columns[7]);\r
+        if(buhin != ""){\r
+          strokesArray = strokesArray.concat(this.getEachStrokesOfBuhin(buhin,\r
+                                                  Math.floor(columns[3]),\r
+                                                  Math.floor(columns[4]),\r
+                                                  Math.floor(columns[5]),\r
+                                                  Math.floor(columns[6]))\r
+                            );\r
+        }\r
+      }\r
+    }\r
+    return strokesArray;\r
+  }\r
+  Kage.prototype.getEachStrokes = getEachStrokes;\r
+  \r
+  function getEachStrokesOfBuhin(buhin, x1, y1, x2, y2){\r
+    var temp = this.getEachStrokes(buhin);\r
+    var result = new Array();\r
+    for(var i = 0; i < temp.length; i++){\r
+      result.push([temp[i][0],\r
+                   temp[i][1],\r
+                   temp[i][2],\r
+                   x1 + temp[i][3] * (x2 - x1) / 200,\r
+                   y1 + temp[i][4] * (y2 - y1) / 200,\r
+                   x1 + temp[i][5] * (x2 - x1) / 200,\r
+                   y1 + temp[i][6] * (y2 - y1) / 200,\r
+                   x1 + temp[i][7] * (x2 - x1) / 200,\r
+                   y1 + temp[i][8] * (y2 - y1) / 200,\r
+                   x1 + temp[i][9] * (x2 - x1) / 200,\r
+                   y1 + temp[i][10] * (y2 - y1) / 200]);\r
+    }\r
+    return result;\r
+  }\r
+  Kage.prototype.getEachStrokesOfBuhin = getEachStrokesOfBuhin;\r
+  \r
+  function adjustHane(sa){ // strokesArray\r
+      for(var i = 0; i < sa.length; i++){\r
+         if((sa[i][0] == 1 || sa[i][0] == 2) && sa[i][2] == 4){\r
+             var lpx; // lastPointX\r
+             var lpy; // lastPointY\r
+             if(sa[i][0] == 1){\r
+                 lpx = sa[i][5];\r
+                 lpy = sa[i][6];\r
+             } else {\r
+                 lpx = sa[i][7];\r
+                 lpy = sa[i][8];\r
+             }\r
+             var mn = Infinity; // mostNear\r
+             if(lpx + 18 < 100){\r
+                 mn = lpx + 18;\r
+             }\r
+             for(var j = 0; j < sa.length; j++){\r
+                 if(i != j && sa[j][0] == 1 && sa[j][3] == sa[j][5] && sa[j][4] <= lpy && sa[j][6] >= lpy){\r
+                     if(lpx - sa[j][3] < 900){\r
+                         mn = Math.min(mn, lpx - sa[j][3]);\r
+                     }\r
+                 }\r
+             }\r
+             if(mn != Infinity){\r
+                 sa[i][2] += Math.min(400, 400 - Math.floor(mn / 20) * 100); // 0-8 -> 0-400\r
+             }\r
+         }\r
+      }\r
+      return sa;\r
+  }\r
+  Kage.prototype.adjustHane = adjustHane;\r
+\r
+  function adjustUroko(strokesArray){ // strokesArray\r
+    for(var i = 0; i < strokesArray.length; i++){\r
+      if(strokesArray[i][0] == 1 && strokesArray[i][2] == 0){ // no operation for TATE\r
+        for(var k = 0; k < this.kAdjustUrokoLengthStep; k++){\r
+          var tx, ty, tlen;\r
+          if(strokesArray[i][4] == strokesArray[i][6]){ // YOKO\r
+            tx = strokesArray[i][5] - this.kAdjustUrokoLine[k];\r
+            ty = strokesArray[i][6] - 0.5;\r
+            tlen = strokesArray[i][5] - strokesArray[i][3];\r
+          } else {\r
+            var rad = Math.atan((strokesArray[i][6] - strokesArray[i][4]) / (strokesArray[i][5] - strokesArray[i][3]));\r
+            tx = strokesArray[i][5] - this.kAdjustUrokoLine[k] * Math.cos(rad) - 0.5 * Math.sin(rad);\r
+            ty = strokesArray[i][6] - this.kAdjustUrokoLine[k] * Math.sin(rad) - 0.5 * Math.cos(rad);\r
+            tlen = Math.sqrt((strokesArray[i][6] - strokesArray[i][4]) * (strokesArray[i][6] - strokesArray[i][4]) +\r
+                             (strokesArray[i][5] - strokesArray[i][3]) * (strokesArray[i][5] - strokesArray[i][3]));\r
+          }\r
+          if(tlen < this.kAdjustUrokoLength[k] ||\r
+             isCrossWithOthers(strokesArray, i, tx, ty, strokesArray[i][5], strokesArray[i][6])\r
+             ){\r
+            strokesArray[i][2] += (this.kAdjustUrokoLengthStep - k) * 100;\r
+            k = Infinity;\r
+          }\r
+        }\r
+      }\r
+    }\r
+    return strokesArray;\r
+  }\r
+  Kage.prototype.adjustUroko = adjustUroko;\r
+  \r
+  function adjustUroko2(strokesArray){ // strokesArray\r
+    for(var i = 0; i < strokesArray.length; i++){\r
+      if(strokesArray[i][0] == 1 && strokesArray[i][2] == 0 && strokesArray[i][4] == strokesArray[i][6]){\r
+        var pressure = 0;\r
+        for(var j = 0; j < strokesArray.length; j++){\r
+          if(i != j && (\r
+             (strokesArray[j][0] == 1 && strokesArray[j][4] == strokesArray[j][6] &&\r
+              !(strokesArray[i][3] + 1 > strokesArray[j][5] || strokesArray[i][5] - 1 < strokesArray[j][3]) &&\r
+              Math.abs(strokesArray[i][4] - strokesArray[j][4]) < this.kAdjustUroko2Length) ||\r
+             (strokesArray[j][0] == 3 && strokesArray[j][6] == strokesArray[j][8] &&\r
+              !(strokesArray[i][3] + 1 > strokesArray[j][7] || strokesArray[i][5] - 1 < strokesArray[j][5]) &&\r
+              Math.abs(strokesArray[i][4] - strokesArray[j][6]) < this.kAdjustUroko2Length)\r
+             )){\r
+            pressure += Math.pow(this.kAdjustUroko2Length - Math.abs(strokesArray[i][4] - strokesArray[j][6]), 1.1);\r
+          }\r
+        }\r
+        var result = Math.min(Math.floor(pressure / this.kAdjustUroko2Length), this.kAdjustUroko2Step) * 100;\r
+        if(strokesArray[i][2] < result){\r
+          strokesArray[i][2] = strokesArray[i][2] % 100 + Math.min(Math.floor(pressure / this.kAdjustUroko2Length), this.kAdjustUroko2Step) * 100;\r
+        }\r
+      }\r
+    }\r
+    return strokesArray;\r
+  }\r
+  Kage.prototype.adjustUroko2 = adjustUroko2;\r
+  \r
+  function adjustTate(strokesArray){ // strokesArray\r
+    for(var i = 0; i < strokesArray.length; i++){\r
+      if((strokesArray[i][0] == 1 || strokesArray[i][0] == 3 || strokesArray[i][0] == 7) && strokesArray[i][3] == strokesArray[i][5]){\r
+        for(var j = 0; j < strokesArray.length; j++){\r
+          if(i != j && (strokesArray[j][0] == 1 || strokesArray[j][0] == 3 || strokesArray[j][0] == 7) && strokesArray[j][3] == strokesArray[j][5] &&\r
+             !(strokesArray[i][4] + 1 > strokesArray[j][6] || strokesArray[i][6] - 1 < strokesArray[j][4]) &&\r
+             Math.abs(strokesArray[i][3] - strokesArray[j][3]) < this.kMinWidthT * this.kAdjustTateStep){\r
+            strokesArray[i][1] += (this.kAdjustTateStep - Math.floor(Math.abs(strokesArray[i][3] - strokesArray[j][3]) / this.kMinWidthT)) * 1000;\r
+            if(strokesArray[i][1] > this.kAdjustTateStep * 1000){\r
+              strokesArray[i][1] = strokesArray[i][1] % 1000 + this.kAdjustTateStep * 1000;\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+    return strokesArray;\r
+  }\r
+  Kage.prototype.adjustTate = adjustTate;\r
+  \r
+  function adjustMage(strokesArray){ // strokesArray\r
+    for(var i = 0; i < strokesArray.length; i++){\r
+      if((strokesArray[i][0] == 3) && strokesArray[i][6] == strokesArray[i][8]){\r
+        for(var j = 0; j < strokesArray.length; j++){\r
+          if(i != j && (\r
+             (strokesArray[j][0] == 1 && strokesArray[j][4] == strokesArray[j][6] &&\r
+              !(strokesArray[i][5] + 1 > strokesArray[j][5] || strokesArray[i][7] - 1 < strokesArray[j][3]) &&\r
+              Math.abs(strokesArray[i][6] - strokesArray[j][4]) < this.kMinWidthT * this.kAdjustMageStep) ||\r
+             (strokesArray[j][0] == 3 && strokesArray[j][6] == strokesArray[j][8] &&\r
+              !(strokesArray[i][5] + 1 > strokesArray[j][7] || strokesArray[i][7] - 1 < strokesArray[j][5]) &&\r
+              Math.abs(strokesArray[i][6] - strokesArray[j][6]) < this.kMinWidthT * this.kAdjustMageStep)\r
+             )){\r
+            strokesArray[i][2] += (this.kAdjustMageStep - Math.floor(Math.abs(strokesArray[i][6] - strokesArray[j][6]) / this.kMinWidthT)) * 1000;\r
+            if(strokesArray[i][2] > this.kAdjustMageStep * 1000){\r
+              strokesArray[i][2] = strokesArray[i][2] % 1000 + this.kAdjustMageStep * 1000;\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+    return strokesArray;\r
+  }\r
+  Kage.prototype.adjustMage = adjustMage;\r
+  \r
+  function adjustKirikuchi(strokesArray){ // strokesArray\r
+    for(var i = 0; i < strokesArray.length; i++){\r
+      if(strokesArray[i][0] == 2 && strokesArray[i][1] == 32 &&\r
+         strokesArray[i][3] > strokesArray[i][5] &&\r
+         strokesArray[i][4] < strokesArray[i][6]){\r
+        for(var j = 0; j < strokesArray.length; j++){ // no need to skip when i == j\r
+          if(strokesArray[j][0] == 1 &&\r
+             strokesArray[j][3] < strokesArray[i][3] && strokesArray[j][5] > strokesArray[i][3] &&\r
+             strokesArray[j][4] == strokesArray[i][4] && strokesArray[j][4] == strokesArray[j][6]){\r
+            strokesArray[i][1] = 132;\r
+            j = strokesArray.length;\r
+          }\r
+        }\r
+      }\r
+    }\r
+    return strokesArray;\r
+  }\r
+  Kage.prototype.adjustKirikuchi = adjustKirikuchi;\r
+  \r
+  function adjustKakato(strokesArray){ // strokesArray\r
+    for(var i = 0; i < strokesArray.length; i++){\r
+      if(strokesArray[i][0] == 1 &&\r
+         (strokesArray[i][2] == 13 || strokesArray[i][2] == 23)){\r
+        for(var k = 0; k < this.kAdjustKakatoStep; k++){\r
+          if(isCrossBoxWithOthers(strokesArray, i,\r
+                               strokesArray[i][5] - this.kAdjustKakatoRangeX / 2,\r
+                               strokesArray[i][6] + this.kAdjustKakatoRangeY[k],\r
+                               strokesArray[i][5] + this.kAdjustKakatoRangeX / 2,\r
+                               strokesArray[i][6] + this.kAdjustKakatoRangeY[k + 1])\r
+             | strokesArray[i][6] + this.kAdjustKakatoRangeY[k + 1] > 200 // adjust for baseline\r
+             | strokesArray[i][6] - strokesArray[i][4] < this.kAdjustKakatoRangeY[k + 1] // for thin box\r
+             ){\r
+            strokesArray[i][2] += (3 - k) * 100;\r
+            k = Infinity;\r
+          }\r
+        }\r
+      }\r
+    }\r
+    return strokesArray;\r
+  }\r
+  Kage.prototype.adjustKakato = adjustKakato;\r
+  \r
+  function drawStrokesArray(polygons, strokesArray){\r
+    for(var i = 0; i < strokesArray.length; i++){\r
+      dfDrawFont(this, polygons,\r
+                 strokesArray[i][0],\r
+                 strokesArray[i][1],\r
+                 strokesArray[i][2],\r
+                 strokesArray[i][3],\r
+                 strokesArray[i][4],\r
+                 strokesArray[i][5],\r
+                 strokesArray[i][6],\r
+                 strokesArray[i][7],\r
+                 strokesArray[i][8],\r
+                 strokesArray[i][9],\r
+                 strokesArray[i][10]);\r
+    }\r
+  }\r
+  Kage.prototype.drawStrokesArray = drawStrokesArray;\r
+  \r
+  function drawGlyph(polygons, glyph){ // void\r
+    // [glyph] : [stroke]$[stroke]$.....\r
+    // [stroke] : [column]:[column]:.....\r
+    var strokes = glyph.split("$");\r
+    for(var i = 0; i < strokes.length; i++){\r
+      var columns = strokes[i].split(":");\r
+      if(Math.floor(columns[0]) != 99){\r
+        dfDrawFont(this, polygons,\r
+                   Math.floor(columns[0]),\r
+                   Math.floor(columns[1]), Math.floor(columns[2]),\r
+                   Math.floor(columns[3]), Math.floor(columns[4]),\r
+                   Math.floor(columns[5]), Math.floor(columns[6]),\r
+                   Math.floor(columns[7]), Math.floor(columns[8]),\r
+                   Math.floor(columns[9]), Math.floor(columns[10]));\r
+      } else {\r
+        var buhin = this.kBuhin.search(columns[7]);\r
+        if(buhin != ""){\r
+          this.drawBuhin(polygons, buhin,\r
+                         Math.floor(columns[3]),\r
+                         Math.floor(columns[4]),\r
+                         Math.floor(columns[5]),\r
+                         Math.floor(columns[6]));\r
+        }\r
+      }\r
+    }\r
+  }\r
+  Kage.prototype.drawGlyph = drawGlyph;\r
+  \r
+  function drawBuhin(polygons, glyph, x1, y1, x2, y2){ // void\r
+    var strokes = glyph.split("$");\r
+    for(var i = 0; i < strokes.length; i++){\r
+      var columns = strokes[i].split(":");\r
+      if(Math.floor(columns[0]) != 99){\r
+        dfDrawFont(this, polygons,\r
+                   Math.floor(columns[0]),\r
+                   Math.floor(columns[1]),\r
+                   Math.floor(columns[2]),\r
+                   x1 + Math.floor(columns[3]) * (x2 - x1) / 200,\r
+                   y1 + Math.floor(columns[4]) * (y2 - y1) / 200,\r
+                   x1 + Math.floor(columns[5]) * (x2 - x1) / 200,\r
+                   y1 + Math.floor(columns[6]) * (y2 - y1) / 200,\r
+                   x1 + Math.floor(columns[7]) * (x2 - x1) / 200,\r
+                   y1 + Math.floor(columns[8]) * (y2 - y1) / 200,\r
+                   x1 + Math.floor(columns[9]) * (x2 - x1) / 200,\r
+                   y1 + Math.floor(columns[10]) * (y2 - y1) / 200);\r
+      } else {\r
+        var buhin = this.kBuhin.search(columns[7]);\r
+        if(buhin != ""){\r
+          this.drawBuhin(polygons, buhin,\r
+                         x1 + Math.floor(columns[3]) * (x2 - x1) / 200,\r
+                         y1 + Math.floor(columns[4]) * (y2 - y1) / 200,\r
+                         x1 + Math.floor(columns[5]) * (x2 - x1) / 200,\r
+                         y1 + Math.floor(columns[6]) * (y2 - y1) / 200);\r
+        }\r
+      }\r
+    }\r
+  }\r
+  Kage.prototype.drawBuhin = drawBuhin;\r
+  \r
+  //properties\r
+  Kage.prototype.kMincho = 0;\r
+  Kage.prototype.kGothic = 1;\r
+  this.kShotai = this.kMincho;\r
+  \r
+  this.kRate = 100;\r
+  \r
+  if(size == 1){\r
+    this.kMinWidthY = 1.2;\r
+    this.kMinWidthT = 3.6;\r
+    this.kWidth = 3;\r
+    this.kKakato = 1.8;\r
+    this.kL2RDfatten = 1.1;\r
+    this.kMage = 6;\r
+    this.kUseCurve = 0;\r
+    \r
+    this.kAdjustKakatoL = ([8, 5, 3, 1]); // for KAKATO adjustment 000,100,200,300\r
+    this.kAdjustKakatoR = ([4, 3, 2, 1]); // for KAKATO adjustment 000,100,200,300\r
+    this.kAdjustKakatoRangeX = 12; // check area width\r
+    this.kAdjustKakatoRangeY = ([1, 11, 14, 18]); // 3 steps of checking\r
+    this.kAdjustKakatoStep = 3; // number of steps\r
+    \r
+    this.kAdjustUrokoX = ([14, 12, 9, 7]); // for UROKO adjustment 000,100,200,300\r
+    this.kAdjustUrokoY = ([7, 6, 5, 4]); // for UROKO adjustment 000,100,200,300\r
+    this.kAdjustUrokoLength = ([13, 21, 30]); // length for checking\r
+    this.kAdjustUrokoLengthStep = 3; // number of steps\r
+    this.kAdjustUrokoLine = ([13, 15, 18]); // check for crossing. corresponds to length\r
+  } else {\r
+    this.kMinWidthY = 2;\r
+    this.kMinWidthT = 6;\r
+    this.kWidth = 5;\r
+    this.kKakato = 3;\r
+    this.kL2RDfatten = 1.1;\r
+    this.kMage = 10;\r
+    this.kUseCurve = 0;\r
+    \r
+    this.kAdjustKakatoL = ([14, 9, 5, 2]); // for KAKATO adjustment 000,100,200,300\r
+    this.kAdjustKakatoR = ([8, 6, 4, 2]); // for KAKATO adjustment 000,100,200,300\r
+    this.kAdjustKakatoRangeX = 20; // check area width\r
+    this.kAdjustKakatoRangeY = ([1, 19, 24, 30]); // 3 steps of checking\r
+    this.kAdjustKakatoStep = 3; // number of steps\r
+    \r
+    this.kAdjustUrokoX = ([24, 20, 16, 12]); // for UROKO adjustment 000,100,200,300\r
+    this.kAdjustUrokoY = ([12, 11, 9, 8]); // for UROKO adjustment 000,100,200,300\r
+    this.kAdjustUrokoLength = ([22, 36, 50]); // length for checking\r
+    this.kAdjustUrokoLengthStep = 3; // number of steps\r
+    this.kAdjustUrokoLine = ([22, 26, 30]); // check for crossing. corresponds to length\r
+    \r
+    this.kAdjustUroko2Step = 3;\r
+    this.kAdjustUroko2Length = 40;\r
+    \r
+    this.kAdjustTateStep = 4;\r
+    \r
+    this.kAdjustMageStep = 5;\r
+  }\r
+  \r
+  this.kBuhin = new Buhin();\r
+  \r
+  return this;\r
+}\r
diff --git a/kagecd.js b/kagecd.js
new file mode 100755 (executable)
index 0000000..914cdbb
--- /dev/null
+++ b/kagecd.js
@@ -0,0 +1,1244 @@
+function cdDrawCurveU(kage, polygons, x1, y1, sx1, sy1, sx2, sy2, x2, y2, ta1, ta2){\r
+  var rad, t;\r
+  var x, y, v;\r
+  var ix, iy, ia, ib, ir;\r
+  var tt;\r
+  var delta;\r
+  var deltad;\r
+  var XX, XY, YX, YY;\r
+  var poly, poly2;\r
+  var hosomi;\r
+  var kMinWidthT, kMinWidthT2;\r
+  var a1, a2, opt1, opt2, opt3, opt4;\r
+  \r
+  if(kage.kShotai == kage.kMincho){ // mincho\r
+    a1 = ta1 % 1000;\r
+    a2 = ta2 % 100;\r
+    opt1 = Math.floor((ta1 % 10000) / 1000);\r
+    opt2 = Math.floor((ta2 % 1000) / 100);\r
+    opt3 = Math.floor(ta1 / 10000);\r
+    opt4 = Math.floor(ta2 / 1000);\r
+    \r
+    kMinWidthT = kage.kMinWidthT - opt1 / 2;\r
+    kMinWidthT2 = kage.kMinWidthT - opt4 / 2;\r
+    \r
+    switch(a1 % 100){\r
+    case 0:\r
+    case 7:\r
+      delta = -1 * kage.kMinWidthY * 0.5;\r
+      break;\r
+    case 1:\r
+    case 2: // ... must be 32\r
+    case 6:\r
+    case 22:\r
+    case 32: // changed\r
+      delta = 0;\r
+      break;\r
+    case 12:\r
+    //case 32:\r
+      delta = kage.kMinWidthY;\r
+      break;\r
+    default:\r
+      break;\r
+    }\r
+    \r
+    if(x1 == sx1){\r
+      if(y1 < sy1){ y1 = y1 - delta; }\r
+      else{ y1 = y1 + delta; }\r
+    }\r
+    else if(y1 == sy1){\r
+      if(x1 < sx1){ x1 = x1 - delta; }\r
+      else{ x1 = x1 + delta; }\r
+    }\r
+    else{\r
+      rad = Math.atan((sy1 - y1) / (sx1 - x1));\r
+      if(x1 < sx1){ v = 1; } else{ v = -1; }\r
+      x1 = x1 - delta * Math.cos(rad) * v;\r
+      y1 = y1 - delta * Math.sin(rad) * v;\r
+    }\r
+    \r
+    switch(a2 % 100){\r
+    case 0:\r
+    case 1:\r
+    case 7:\r
+    case 9:\r
+    case 15: // it can change to 15->5\r
+    case 14: // it can change to 14->4\r
+    case 17: // no need\r
+    case 5:\r
+      delta = 0;\r
+      break;\r
+    case 8: // get shorten for tail's circle\r
+      delta = -1 * kMinWidthT * 0.5;\r
+      break;\r
+    default:\r
+      break;\r
+    }\r
+    \r
+    if(sx2 == x2){\r
+      if(sy2 < y2){ y2 = y2 + delta; }\r
+      else{ y2 = y2 - delta; }\r
+    }\r
+    else if(sy2 == y2){\r
+      if(sx2 < x2){ x2 = x2 + delta; }\r
+      else{ x2 = x2 - delta; }\r
+    }\r
+    else{\r
+      rad = Math.atan((y2 - sy2) / (x2 - sx2));\r
+      if(sx2 < x2){ v = 1; } else{ v = -1; }\r
+      x2 = x2 + delta * Math.cos(rad) * v;\r
+      y2 = y2 + delta * Math.sin(rad) * v;\r
+    }\r
+    \r
+    hosomi = 0.5;\r
+    if(Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) < 50){\r
+      hosomi += 0.4 * (1 - Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) / 50);\r
+    }\r
+    \r
+    //---------------------------------------------------------------\r
+    \r
+    poly = new Polygon();\r
+    poly2 = new Polygon();\r
+    \r
+    if(sx1 == sx2 && sy1 == sy2){ // Spline\r
+      if(kage.kUseCurve){\r
+        // generating fatten curve -- begin\r
+        var kage2 = new Kage();\r
+        kage2.kMinWidthY = kage.kMinWidthY;\r
+        kage2.kMinWidthT = kMinWidthT;\r
+        kage2.kWidth = kage.kWidth;\r
+        kage2.kKakato = kage.kKakato;\r
+        kage2.kRate = 10;\r
+        \r
+        var curve = new Array(2); // L and R\r
+        get_candidate(kage2, curve, a1, a2, x1, y1, sx1, sy1, x2, y2, opt3, opt4);\r
+        \r
+        var dcl12_34 = new Array(2);\r
+        var dcr12_34 = new Array(2);\r
+        var dpl12_34 = new Array(2);\r
+        var dpr12_34 = new Array(2);\r
+        divide_curve(kage2, x1, y1, sx1, sy1, x2, y2, curve[0], dcl12_34, dpl12_34);\r
+        divide_curve(kage2, x1, y1, sx1, sy1, x2, y2, curve[1], dcr12_34, dpr12_34);\r
+        \r
+        var ncl1 = new Array(7);\r
+        var ncl2 = new Array(7);\r
+        find_offcurve(kage2, dcl12_34[0], dpl12_34[0][2], dpl12_34[0][3], ncl1);\r
+        find_offcurve(kage2, dcl12_34[1], dpl12_34[1][2], dpl12_34[1][3], ncl2);\r
+        \r
+        poly.push(ncl1[0], ncl1[1]);\r
+        poly.push(ncl1[2], ncl1[3], 1);\r
+        poly.push(ncl1[4], ncl1[5]);\r
+        poly.push(ncl2[2], ncl2[3], 1);\r
+        poly.push(ncl2[4], ncl2[5]);\r
+        \r
+        poly2.push(dcr12_34[0][0][0], dcr12_34[0][0][1]);\r
+        poly2.push(dpr12_34[0][2] - (ncl1[2] - dpl12_34[0][2]), dpl12_34[0][3] - (ncl1[3] - dpl12_34[0][3]), 1);\r
+        poly2.push(dcr12_34[0][dcr12_34[0].length - 1][0], dcr12_34[0][dcr12_34[0].length - 1][1]);\r
+        poly2.push(dpr12_34[1][2] - (ncl2[2] - dpl12_34[1][2]), dpl12_34[1][3] - (ncl2[3] - dpl12_34[1][3]), 1);\r
+        poly2.push(dcr12_34[1][dcr12_34[1].length - 1][0], dcr12_34[1][dcr12_34[1].length - 1][1]);\r
+        \r
+        poly2.reverse();\r
+        poly.concat(poly2);\r
+        polygons.push(poly);\r
+        // generating fatten curve -- end\r
+      } else {\r
+        for(tt = 0; tt <= 1000; tt = tt + kage.kRate){\r
+          t = tt / 1000;\r
+          \r
+          // calculate a dot\r
+          x = ((1.0 - t) * (1.0 - t) * x1 + 2.0 * t * (1.0 - t) * sx1 + t * t * x2);\r
+          y = ((1.0 - t) * (1.0 - t) * y1 + 2.0 * t * (1.0 - t) * sy1 + t * t * y2);\r
+          \r
+          // KATAMUKI of vector by BIBUN\r
+          ix = (x1 - 2.0 * sx1 + x2) * 2.0 * t + (-2.0 * x1 + 2.0 * sx1);\r
+          iy = (y1 - 2.0 * sy1 + y2) * 2.0 * t + (-2.0 * y1 + 2.0 * sy1);\r
+          \r
+          // line SUICHOKU by vector\r
+          if(ix != 0 && iy != 0){\r
+            ir = Math.atan(iy / ix * -1);\r
+            ia = Math.sin(ir) * (kMinWidthT);\r
+            ib = Math.cos(ir) * (kMinWidthT);\r
+          }\r
+          else if(ix == 0){\r
+            ia = kMinWidthT;\r
+            ib = 0;\r
+          }\r
+          else{\r
+            ia = 0;\r
+            ib = kMinWidthT;\r
+          }\r
+          \r
+          if(a1 == 7 && a2 == 0){ // L2RD: fatten\r
+            deltad = Math.pow(t, hosomi) * kage.kL2RDfatten;\r
+          }\r
+          else if(a1 == 7){\r
+            deltad = Math.pow(t, hosomi);\r
+          }\r
+          else if(a2 == 7){\r
+            deltad = Math.pow(1.0 - t, hosomi);\r
+          }\r
+          else if(opt3 > 0 || opt4 > 0){\r
+              deltad = ((kage.kMinWidthT - opt3 / 2) - (opt4 - opt3) / 2 * t) / kage.kMinWidthT;\r
+          }\r
+          else{ deltad = 1; }\r
+          \r
+          if(deltad < 0.15){\r
+            deltad = 0.15;\r
+          }\r
+          ia = ia * deltad;\r
+          ib = ib * deltad;\r
+          \r
+          //reverse if vector is going 2nd/3rd quadrants\r
+          if(ix <= 0){\r
+            ia = ia * -1;\r
+            ib = ib * -1;\r
+          }\r
+          \r
+          //copy to polygon structure\r
+          poly.push(x - ia, y - ib);\r
+          poly2.push(x + ia, y + ib);\r
+        }\r
+        \r
+        // suiheisen ni setsuzoku\r
+        if(a1 == 132){\r
+          var index = 0;\r
+          while(true){\r
+            if(poly2.array[index].y <= y1 && y1 <= poly2.array[index + 1].y){\r
+              break;\r
+            }\r
+            index++;\r
+          }\r
+          newx1 = poly2.array[index + 1].x + (poly2.array[index].x - poly2.array[index + 1].x) *\r
+            (poly2.array[index + 1].y - y1) / (poly2.array[index + 1].y - poly2.array[index].y);\r
+          newy1 = y1;\r
+          newx2 = poly.array[0].x + (poly.array[0].x - poly.array[1].x) * (poly.array[0].y - y1) /\r
+            (poly.array[1].y - poly.array[0].y);\r
+          newy2 = y1;\r
+          \r
+          for(var i = 0; i < index; i++){\r
+            poly2.shift();\r
+          }\r
+          poly2.set(0, newx1, newy1);\r
+          poly.unshift(newx2, newy2);\r
+        }\r
+        \r
+        // suiheisen ni setsuzoku 2\r
+        if(a1 == 22 && y1 > y2){\r
+          var index = 0;\r
+          while(true){\r
+            if(poly2.array[index].y <= y1 && y1 <= poly2.array[index + 1].y){\r
+              break;\r
+            }\r
+            index++;\r
+          }\r
+          newx1 = poly2.array[index + 1].x + (poly2.array[index].x - poly2.array[index + 1].x) *\r
+            (poly2.array[index + 1].y - y1) / (poly2.array[index + 1].y - poly2.array[index].y);\r
+          newy1 = y1;\r
+          newx2 = poly.array[0].x + (poly.array[0].x - poly.array[1].x - 1) * (poly.array[0].y - y1) /\r
+            (poly.array[1].y - poly.array[0].y);\r
+          newy2 = y1 + 1;\r
+          \r
+          for(var i = 0; i < index; i++){\r
+            poly2.shift();\r
+          }\r
+          poly2.set(0, newx1, newy1);\r
+          poly.unshift(newx2, newy2);\r
+        }\r
+        \r
+        poly2.reverse();\r
+        poly.concat(poly2);\r
+        polygons.push(poly);\r
+      }\r
+    } else { // Bezier\r
+      for(tt = 0; tt <= 1000; tt = tt + kage.kRate){\r
+        t = tt / 1000;\r
+        \r
+        // calculate a dot\r
+        x = (1.0 - t) * (1.0 - t) * (1.0 - t) * x1 + 3.0 * t * (1.0 - t) * (1.0 - t) * sx1 + 3 * t * t * (1.0 - t) * sx2 + t * t * t * x2;\r
+        y = (1.0 - t) * (1.0 - t) * (1.0 - t) * y1 + 3.0 * t * (1.0 - t) * (1.0 - t) * sy1 + 3 * t * t * (1.0 - t) * sy2 + t * t * t * y2;\r
+        // KATAMUKI of vector by BIBUN\r
+        ix = t * t * (-3 * x1 + 9 * sx1 + -9 * sx2 + 3 * x2) + t * (6 * x1 + -12 * sx1 + 6 * sx2) + -3 * x1 + 3 * sx1;\r
+        iy = t * t * (-3 * y1 + 9 * sy1 + -9 * sy2 + 3 * y2) + t * (6 * y1 + -12 * sy1 + 6 * sy2) + -3 * y1 + 3 * sy1;\r
+        \r
+        // line SUICHOKU by vector\r
+        if(ix != 0 && iy != 0){\r
+          ir = Math.atan(iy / ix * -1);\r
+          ia = Math.sin(ir) * (kMinWidthT);\r
+          ib = Math.cos(ir) * (kMinWidthT);\r
+        }\r
+        else if(ix == 0){\r
+          ia = kMinWidthT;\r
+          ib = 0;\r
+        }\r
+        else{\r
+          ia = 0;\r
+          ib = kMinWidthT;\r
+        }\r
+        \r
+        if(a1 == 7 && a2 == 0){ // L2RD: fatten\r
+          deltad = Math.pow(t, hosomi) * kage.kL2RDfatten;\r
+        }\r
+        else if(a1 == 7){\r
+          deltad = Math.pow(t, hosomi);\r
+          deltad = Math.pow(deltad, 0.7); // make fatten\r
+        }\r
+        else if(a2 == 7){\r
+          deltad = Math.pow(1.0 - t, hosomi);\r
+        }\r
+        else{ deltad = 1; }\r
+        \r
+        if(deltad < 0.15){\r
+          deltad = 0.15;\r
+        }\r
+        ia = ia * deltad;\r
+        ib = ib * deltad;\r
+        \r
+        //reverse if vector is going 2nd/3rd quadrants\r
+        if(ix <= 0){\r
+          ia = ia * -1;\r
+          ib = ib * -1;\r
+        }\r
+        \r
+        //copy to polygon structure\r
+        poly.push(x - ia, y - ib);\r
+        poly2.push(x + ia, y + ib);\r
+      }\r
+      \r
+      // suiheisen ni setsuzoku\r
+      if(a1 == 132){\r
+        var index = 0;\r
+        while(true){\r
+          if(poly2.array[index].y <= y1 && y1 <= poly2.array[index + 1].y){\r
+            break;\r
+          }\r
+          index++;\r
+        }\r
+        newx1 = poly2.array[index + 1].x + (poly2.array[index].x - poly2.array[index + 1].x) *\r
+          (poly2.array[index + 1].y - y1) / (poly2.array[index + 1].y - poly2.array[index].y);\r
+        newy1 = y1;\r
+        newx2 = poly.array[0].x + (poly.array[0].x - poly.array[1].x) * (poly.array[0].y - y1) /\r
+          (poly.array[1].y - poly.array[0].y);\r
+        newy2 = y1;\r
+        \r
+        for(var i = 0; i < index; i++){\r
+          poly2.shift();\r
+        }\r
+        poly2.set(0, newx1, newy1);\r
+        poly.unshift(newx2, newy2);\r
+      }\r
+      \r
+      // suiheisen ni setsuzoku 2\r
+      if(a1 == 22){\r
+        var index = 0;\r
+        while(true){\r
+          if(poly2.array[index].y <= y1 && y1 <= poly2.array[index + 1].y){\r
+            break;\r
+          }\r
+          index++;\r
+        }\r
+        newx1 = poly2.array[index + 1].x + (poly2.array[index].x - poly2.array[index + 1].x) *\r
+          (poly2.array[index + 1].y - y1) / (poly2.array[index + 1].y - poly2.array[index].y);\r
+        newy1 = y1;\r
+        newx2 = poly.array[0].x + (poly.array[0].x - poly.array[1].x - 1) * (poly.array[0].y - y1) /\r
+          (poly.array[1].y - poly.array[0].y);\r
+        newy2 = y1 + 1;\r
+        \r
+        for(var i = 0; i < index; i++){\r
+          poly2.shift();\r
+        }\r
+        poly2.set(0, newx1, newy1);\r
+        poly.unshift(newx2, newy2);\r
+      }\r
+      \r
+      poly2.reverse();\r
+      poly.concat(poly2);\r
+      polygons.push(poly);\r
+    }\r
+    \r
+    //process for head of stroke\r
+    rad = Math.atan((sy1 - y1) / (sx1 - x1));\r
+    if(x1 < sx1){ v = 1; } else{ v = -1; }\r
+    XX = Math.sin(rad) * v;\r
+    XY = Math.cos(rad) * v * -1;\r
+    YX = Math.cos(rad) * v;\r
+    YY = Math.sin(rad) * v;\r
+    \r
+    if(a1 == 12){\r
+      if(x1 == x2){\r
+        poly= new Polygon();\r
+        poly.push(x1 - kMinWidthT, y1);\r
+        poly.push(x1 + kMinWidthT, y1);\r
+        poly.push(x1 - kMinWidthT, y1 - kMinWidthT);\r
+        polygons.push(poly);\r
+      }\r
+      else{\r
+        poly = new Polygon();\r
+        poly.push(x1 - kMinWidthT * XX, y1 - kMinWidthT * XY);\r
+        poly.push(x1 + kMinWidthT * XX, y1 + kMinWidthT * XY);\r
+        poly.push(x1 - kMinWidthT * XX - kMinWidthT * YX, y1 - kMinWidthT * XY - kMinWidthT * YY);\r
+        polygons.push(poly);\r
+      }\r
+    }\r
+    \r
+    var type;\r
+    var pm = 0;\r
+    if(a1 == 0){\r
+      if(y1 <= y2){ //from up to bottom\r
+        type = (Math.atan2(Math.abs(y1 - sy1), Math.abs(x1 - sx1)) / Math.PI * 2 - 0.4);\r
+        if(type > 0){\r
+          type = type * 2;\r
+        } else {\r
+          type = type * 16;\r
+        }\r
+        if(type < 0){\r
+          pm = -1;\r
+        } else {\r
+          pm = 1;\r
+        }\r
+        if(x1 == sx1){\r
+          poly = new Polygon();\r
+          poly.push(x1 - kMinWidthT, y1 + 1);\r
+          poly.push(x1 + kMinWidthT, y1);\r
+          poly.push(x1 - kMinWidthT * pm, y1 - kage.kMinWidthY * type * pm);\r
+          //if(x1 > x2){\r
+          //  poly.reverse();\r
+          //}\r
+          polygons.push(poly);\r
+        }\r
+        else{\r
+          poly = new Polygon();\r
+          poly.push(x1 - kMinWidthT * XX + 1 * YX, y1 - kMinWidthT * XY + 1 * YY);\r
+          poly.push(x1 + kMinWidthT * XX, y1 + kMinWidthT * XY);\r
+          poly.push(x1 - kMinWidthT * pm * XX - kage.kMinWidthY * type * pm * YX, y1 - kMinWidthT * pm * XY - kage.kMinWidthY * type * pm * YY);\r
+          //if(x1 > x2){\r
+          //  poly.reverse();\r
+          //}\r
+          polygons.push(poly);\r
+        }\r
+      }\r
+      else{ //bottom to up\r
+        if(x1 == sx1){\r
+          poly = new Polygon();\r
+          poly.push(x1 - kMinWidthT, y1);\r
+          poly.push(x1 + kMinWidthT, y1);\r
+          poly.push(x1 + kMinWidthT, y1 - kage.kMinWidthY);\r
+          polygons.push(poly);\r
+        }\r
+        else{\r
+          poly = new Polygon();\r
+          poly.push(x1 - kMinWidthT * XX, y1 - kMinWidthT * XY);\r
+          poly.push(x1 + kMinWidthT * XX, y1 + kMinWidthT * XY);\r
+          poly.push(x1 + kMinWidthT * XX - kage.kMinWidthY * YX, y1 + kMinWidthT * XY - kage.kMinWidthY * YY);\r
+          //if(x1 < x2){\r
+          //  poly.reverse();\r
+          //}\r
+          polygons.push(poly);\r
+        }\r
+      }\r
+    }\r
+    \r
+    if(a1 == 22){ //box's up-right corner, any time same degree\r
+      poly = new Polygon();\r
+      poly.push(x1 - kMinWidthT, y1 - kage.kMinWidthY);\r
+      poly.push(x1, y1 - kage.kMinWidthY - kage.kWidth);\r
+      poly.push(x1 + kMinWidthT + kage.kWidth, y1 + kage.kMinWidthY);\r
+      poly.push(x1 + kMinWidthT, y1 + kMinWidthT - 1);\r
+      poly.push(x1 - kMinWidthT, y1 + kMinWidthT + 4);\r
+      polygons.push(poly);\r
+    }\r
+    \r
+    if(a1 == 0){ //beginning of the stroke\r
+      if(y1 <= y2){ //from up to bottom\r
+        if(pm > 0){\r
+          type = 0;\r
+        }\r
+        var move = kage.kMinWidthY * type * pm;\r
+        if(x1 == sx1){\r
+          poly = new Polygon();\r
+          poly.push(x1 + kMinWidthT, y1 - move);\r
+          poly.push(x1 + kMinWidthT * 1.5, y1 + kage.kMinWidthY - move);\r
+          poly.push(x1 + kMinWidthT - 2, y1 + kage.kMinWidthY * 2 + 1);\r
+          polygons.push(poly);\r
+        }\r
+        else{\r
+          poly = new Polygon();\r
+          poly.push(x1 + kMinWidthT * XX - move * YX,\r
+                    y1 + kMinWidthT * XY - move * YY);\r
+          poly.push(x1 + kMinWidthT * 1.5 * XX + (kage.kMinWidthY - move * 1.2) * YX,\r
+                    y1 + kMinWidthT * 1.5 * XY + (kage.kMinWidthY - move * 1.2) * YY);\r
+          poly.push(x1 + (kMinWidthT - 2) * XX + (kage.kMinWidthY * 2 - move * 0.8 + 1) * YX,\r
+                    y1 + (kMinWidthT - 2) * XY + (kage.kMinWidthY * 2 - move * 0.8 + 1) * YY);\r
+          //if(x1 < x2){\r
+          //  poly.reverse();\r
+          //}\r
+          polygons.push(poly);\r
+        }\r
+      }\r
+      else{ //from bottom to up\r
+        if(x1 == sx1){\r
+          poly = new Polygon();\r
+          poly.push(x1 - kMinWidthT, y1);\r
+          poly.push(x1 - kMinWidthT * 1.5, y1 + kage.kMinWidthY);\r
+          poly.push(x1 - kMinWidthT * 0.5, y1 + kage.kMinWidthY * 3);\r
+          polygons.push(poly);\r
+        }\r
+        else{\r
+          poly = new Polygon();\r
+          poly.push(x1 - kMinWidthT * XX, y1 - kMinWidthT * XY);\r
+          poly.push(x1 - kMinWidthT * 1.5 * XX + kage.kMinWidthY * YX, y1 + kage.kMinWidthY * YY - kMinWidthT * 1.5 * XY);\r
+          poly.push(x1 - kMinWidthT * 0.5 * XX + kage.kMinWidthY * 3 * YX, y1 + kage.kMinWidthY * 3 * YY - kMinWidthT * 0.5 * XY);\r
+          //if(x1 < x2){\r
+          //  poly.reverse();\r
+          //}\r
+          polygons.push(poly);\r
+        }\r
+      }\r
+    }\r
+    \r
+    //process for tail\r
+    rad = Math.atan((y2 - sy2) / (x2 - sx2));\r
+    if(sx2 < x2){ v = 1; } else{ v = -1; }\r
+    YX = Math.sin(rad) * v * -1;\r
+    YY = Math.cos(rad) * v;\r
+    XX = Math.cos(rad) * v;\r
+    XY = Math.sin(rad) * v;\r
+    \r
+    if(a2 == 1 || a2 == 8 || a2 == 15){ //the last filled circle ... it can change 15->5\r
+      if(sx2 == x2){\r
+        poly = new Polygon();\r
+        if(kage.kUseCurve){\r
+          // by curve path\r
+          poly.push(x2 - kMinWidthT2, y2);\r
+          poly.push(x2 - kMinWidthT2 * 0.9, y2 + kMinWidthT2 * 0.9, 1);\r
+          poly.push(x2, y2 + kMinWidthT2);\r
+          poly.push(x2 + kMinWidthT2 * 0.9, y2 + kMinWidthT2 * 0.9, 1);\r
+          poly.push(x2 + kMinWidthT2, y2);\r
+        } else {\r
+          // by polygon\r
+          poly.push(x2 - kMinWidthT2, y2);\r
+          poly.push(x2 - kMinWidthT2 * 0.7, y2 + kMinWidthT2 * 0.7);\r
+          poly.push(x2, y2 + kMinWidthT2);\r
+          poly.push(x2 + kMinWidthT2 * 0.7, y2 + kMinWidthT2 * 0.7);\r
+          poly.push(x2 + kMinWidthT2, y2);\r
+        }\r
+        polygons.push(poly);\r
+      }\r
+      else if(sy2 == y2){\r
+        poly = new Polygon();\r
+        if(kage.kUseCurve){\r
+          // by curve path\r
+          poly.push(x2, y2 - kMinWidthT2);\r
+          poly.push(x2 + kMinWidthT2 * 0.9, y2 - kMinWidthT2 * 0.9, 1);\r
+          poly.push(x2 + kMinWidthT2, y2);\r
+          poly.push(x2 + kMinWidthT2 * 0.9, y2 + kMinWidthT2 * 0.9, 1);\r
+          poly.push(x2, y2 + kMinWidthT2);\r
+        } else {\r
+          // by polygon\r
+          poly.push(x2, y2 - kMinWidthT2);\r
+          poly.push(x2 + kMinWidthT2 * 0.7, y2 - kMinWidthT2 * 0.7);\r
+          poly.push(x2 + kMinWidthT2, y2);\r
+          poly.push(x2 + kMinWidthT2 * 0.7, y2 + kMinWidthT2 * 0.7);\r
+          poly.push(x2, y2 + kMinWidthT2);\r
+        }\r
+        polygons.push(poly);\r
+      }\r
+      else{\r
+        poly = new Polygon();\r
+        if(kage.kUseCurve){\r
+          poly.push(x2 + Math.sin(rad) * kMinWidthT2 * v, y2 - Math.cos(rad) * kMinWidthT2 * v);\r
+          poly.push(x2 + Math.cos(rad) * kMinWidthT2 * 0.9 * v + Math.sin(rad) * kMinWidthT2 * 0.9 * v,\r
+                    y2 + Math.sin(rad) * kMinWidthT2 * 0.9 * v - Math.cos(rad) * kMinWidthT2 * 0.9 * v, 1);\r
+          poly.push(x2 + Math.cos(rad) * kMinWidthT2 * v, y2 + Math.sin(rad) * kMinWidthT2 * v);\r
+          poly.push(x2 + Math.cos(rad) * kMinWidthT2 * 0.9 * v - Math.sin(rad) * kMinWidthT2 * 0.9 * v,\r
+                    y2 + Math.sin(rad) * kMinWidthT2 * 0.9 * v + Math.cos(rad) * kMinWidthT2 * 0.9 * v, 1);\r
+          poly.push(x2 - Math.sin(rad) * kMinWidthT2 * v, y2 + Math.cos(rad) * kMinWidthT2 * v);\r
+        } else {\r
+          poly.push(x2 + Math.sin(rad) * kMinWidthT2 * v, y2 - Math.cos(rad) * kMinWidthT2 * v);\r
+          poly.push(x2 + Math.cos(rad) * kMinWidthT2 * 0.7 * v + Math.sin(rad) * kMinWidthT2 * 0.7 * v,\r
+                    y2 + Math.sin(rad) * kMinWidthT2 * 0.7 * v - Math.cos(rad) * kMinWidthT2 * 0.7 * v);\r
+          poly.push(x2 + Math.cos(rad) * kMinWidthT2 * v, y2 + Math.sin(rad) * kMinWidthT2 * v);\r
+          poly.push(x2 + Math.cos(rad) * kMinWidthT2 * 0.7 * v - Math.sin(rad) * kMinWidthT2 * 0.7 * v,\r
+                    y2 + Math.sin(rad) * kMinWidthT2 * 0.7 * v + Math.cos(rad) * kMinWidthT2 * 0.7 * v);\r
+          poly.push(x2 - Math.sin(rad) * kMinWidthT2 * v, y2 + Math.cos(rad) * kMinWidthT2 * v);\r
+        }\r
+        polygons.push(poly);\r
+      }\r
+    }\r
+    \r
+    if(a2 == 9 || (a1 == 7 && a2 == 0)){ // Math.sinnyu & L2RD Harai ... no need for a2=9\r
+      var type = (Math.atan2(Math.abs(y2 - sy2), Math.abs(x2 - sx2)) / Math.PI * 2 - 0.6);\r
+      if(type > 0){\r
+        type = type * 8;\r
+      } else {\r
+        type = type * 3;\r
+      }\r
+      var pm = 0;\r
+      if(type < 0){\r
+        pm = -1;\r
+      } else {\r
+        pm = 1;\r
+      }\r
+      if(sy2 == y2){\r
+        poly = new Polygon();\r
+        poly.push(x2, y2 + kMinWidthT * kage.kL2RDfatten);\r
+        poly.push(x2, y2 - kMinWidthT * kage.kL2RDfatten);\r
+        poly.push(x2 + kMinWidthT * kage.kL2RDfatten * Math.abs(type), y2 + kMinWidthT * kage.kL2RDfatten * pm);\r
+        polygons.push(poly);\r
+      }\r
+      else{\r
+        poly = new Polygon();\r
+        poly.push(x2 + kMinWidthT * kage.kL2RDfatten * YX, y2 + kMinWidthT * kage.kL2RDfatten * YY);\r
+        poly.push(x2 - kMinWidthT * kage.kL2RDfatten * YX, y2 - kMinWidthT * kage.kL2RDfatten * YY);\r
+        poly.push(x2 + kMinWidthT * kage.kL2RDfatten * Math.abs(type) * XX + kMinWidthT * kage.kL2RDfatten * pm * YX,\r
+                  y2 + kMinWidthT * kage.kL2RDfatten * Math.abs(type) * XY + kMinWidthT * kage.kL2RDfatten * pm * YY);\r
+        polygons.push(poly);\r
+      }\r
+    }\r
+    \r
+    if(a2 == 15){ //jump up ... it can change 15->5\r
+      // anytime same degree\r
+      poly = new Polygon();\r
+      if(y1 < y2){\r
+        poly.push(x2, y2 - kMinWidthT + 1);\r
+        poly.push(x2 + 2, y2 - kMinWidthT - kage.kWidth * 5);\r
+        poly.push(x2, y2 - kMinWidthT - kage.kWidth * 5);\r
+        poly.push(x2 - kMinWidthT, y2 - kMinWidthT + 1);\r
+      } else {\r
+        poly.push(x2, y2 + kMinWidthT - 1);\r
+        poly.push(x2 - 2, y2 + kMinWidthT + kage.kWidth * 5);\r
+        poly.push(x2, y2 + kMinWidthT + kage.kWidth * 5);\r
+        poly.push(x2 + kMinWidthT, y2 + kMinWidthT - 1);\r
+      }\r
+      polygons.push(poly);\r
+    }\r
+    \r
+    if(a2 == 14){ //jump to left, allways go left\r
+      poly = new Polygon();\r
+      poly.push(x2, y2);\r
+      poly.push(x2, y2 - kMinWidthT);\r
+      poly.push(x2 - kage.kWidth * 4 * Math.min(1 - opt2 / 10, Math.pow(kMinWidthT / kage.kMinWidthT, 3)), y2 - kMinWidthT);\r
+      poly.push(x2 - kage.kWidth * 4 * Math.min(1 - opt2 / 10, Math.pow(kMinWidthT / kage.kMinWidthT, 3)), y2 - kMinWidthT * 0.5);\r
+      //poly.reverse();\r
+      polygons.push(poly);\r
+    }\r
+  }\r
+  else{ //gothic\r
+    if(a1 % 10 == 2){\r
+      if(x1 == sx1){\r
+        if(y1 < sy1){ y1 = y1 - kage.kWidth; } else{ y1 = y1 + kage.kWidth; }\r
+      }\r
+      else if(y1 == sy1){\r
+        if(x1 < sx1){ x1 = x1 - kage.kWidth; } else{ x1 = x1 + kage.kWidth; }\r
+      }\r
+      else{\r
+        rad = Math.atan((sy1 - y1) / (sx1 - x1));\r
+        if(x1 < sx1){ v = 1; } else{ v = -1; }\r
+        x1 = x1 - kage.kWidth * Math.cos(rad) * v;\r
+        y1 = y1 - kage.kWidth * Math.sin(rad) * v;\r
+      }\r
+    }\r
+    \r
+    if(a1 % 10 == 3){\r
+      if(x1 == sx1){\r
+        if(y1 < sy1){\r
+          y1 = y1 - kage.kWidth * kage.kKakato;\r
+        }\r
+        else{\r
+          y1 = y1 + kage.kWidth * kage.kKakato;\r
+        }\r
+      }\r
+      else if(y1 == sy1){\r
+        if(x1 < sx1){\r
+          x1 = x1 - kage.kWidth * kage.kKakato;\r
+        }\r
+        else{\r
+          x1 = x1 + kage.kWidth * kage.kKakato;\r
+        }\r
+      }\r
+      else{\r
+        rad = Math.atan((sy1 - y1) / (sx1 - x1));\r
+        if(x1 < sx1){ v = 1; } else{ v = -1; }\r
+        x1 = x1 - kage.kWidth * Math.cos(rad) * v * kage.kKakato;\r
+        y1 = y1 - kage.kWidth * Math.sin(rad) * v * kage.kKakato;\r
+      }\r
+    }\r
+    if(a2 % 10 == 2){\r
+      if(sx2 == x2){\r
+        if(sy2 < y2){ y2 = y2 + kage.kWidth; } else{ y2 = y2 - kage.kWidth; }\r
+      }\r
+      else if(sy2 == y2){\r
+        if(sx2 < x2){ x2 = x2 + kage.kWidth; } else{ x2 = x2 - kage.kWidth; }\r
+      }\r
+      else{\r
+        rad = Math.atan((y2 - sy2) / (x2 - sx2));\r
+        if(sx2 < x2){ v = 1; } else{ v = -1; }\r
+        x2 = x2 + kage.kWidth * Math.cos(rad) * v;\r
+        y2 = y2 + kage.kWidth * Math.sin(rad) * v;\r
+      }\r
+    }\r
+    \r
+    if(a2 % 10 == 3){\r
+      if(sx2 == x2){\r
+        if(sy2 < y2){\r
+          y2 = y2 + kage.kWidth * kage.kKakato;\r
+        }\r
+        else{\r
+          y2 = y2 - kage.kWidth * kage.kKakato;\r
+        }\r
+      }\r
+      else if(sy2 == y2){\r
+        if(sx2 < x2){\r
+          x2 = x2 + kage.kWidth * kage.kKakato;\r
+        }\r
+        else{\r
+          x2 = x2 - kage.kWidth * kage.kKakato;\r
+        }\r
+      }\r
+      else{\r
+        rad = Math.atan((y2 - sy2) / (x2 - sx2));\r
+        if(sx2 < x2){ v = 1; } else{ v = -1; }\r
+        x2 = x2 + kage.kWidth * Math.cos(rad) * v * kage.kKakato;\r
+        y2 = y2 + kage.kWidth * Math.sin(rad) * v * kage.kKakato;\r
+      }\r
+    }\r
+    \r
+    poly = new Polygon();\r
+    poly2 = new Polygon();\r
+    \r
+    for(tt = 0; tt <= 1000; tt = tt + kage.kRate){\r
+      t = tt / 1000;\r
+      \r
+      if(sx1 == sx2 && sy1 == sy2){\r
+        //calculating each point\r
+        x = ((1.0 - t) * (1.0 - t) * x1 + 2.0 * t * (1.0 - t) * sx1 + t * t * x2);\r
+        y = ((1.0 - t) * (1.0 - t) * y1 + 2.0 * t * (1.0 - t) * sy1 + t * t * y2);\r
+        \r
+        //SESSEN NO KATAMUKI NO KEISAN(BIBUN)\r
+        ix = (x1 - 2.0 * sx1 + x2) * 2.0 * t + (-2.0 * x1 + 2.0 * sx1);\r
+        iy = (y1 - 2.0 * sy1 + y2) * 2.0 * t + (-2.0 * y1 + 2.0 * sy1);\r
+      } else {\r
+      }\r
+      //SESSEN NI SUICHOKU NA CHOKUSEN NO KEISAN\r
+      if(kage.kShotai == kage.kMincho){ //always false ?\r
+        if(ix != 0 && iy != 0){\r
+          ir = Math.atan(iy / ix * -1.0);\r
+          ia = Math.sin(ir) * kage.kMinWidthT;\r
+          ib = Math.cos(ir) * kage.kMinWidthT;\r
+        }\r
+        else if(ix == 0){\r
+          ia = kage.kMinWidthT;\r
+          ib = 0;\r
+        }\r
+        else{\r
+          ia = 0;\r
+          ib = kage.kMinWidthT;\r
+        }\r
+        ia = ia * Math.sqrt(1.0 - t);\r
+        ib = ib * Math.sqrt(1.0 - t);\r
+      }\r
+      else{\r
+        if(ix != 0 && iy != 0){\r
+          ir = Math.atan(iy / ix * -1.0);\r
+          ia = Math.sin(ir) * kage.kWidth;\r
+          ib = Math.cos(ir) * kage.kWidth;\r
+        }\r
+        else if(ix == 0){\r
+          ia = kage.kWidth;\r
+          ib = 0;\r
+        }\r
+        else{\r
+          ia = 0;\r
+          ib = kage.kWidth;\r
+        }\r
+      }\r
+      \r
+      //reverse if vector is going 2nd/3rd quadrants\r
+      if(ix <= 0){\r
+        ia = ia * -1;\r
+        ib = ib * -1;\r
+      }\r
+      \r
+      //save to polygon\r
+      poly.push(x - ia, y - ib);\r
+      poly2.push(x + ia, y + ib);\r
+    }\r
+    \r
+    poly2.reverse();\r
+    poly.concat(poly2);\r
+    polygons.push(poly);\r
+  }\r
+}\r
+\r
+function cdDrawBezier(kage, polygons, x1, y1, x2, y2, x3, y3, x4, y4, a1, a2){\r
+  cdDrawCurveU(kage, polygons, x1, y1, x2, y2, x3, y3, x4, y4, a1, a2);\r
+}\r
+\r
+function cdDrawCurve(kage, polygons, x1, y1, x2, y2, x3, y3, a1, a2){\r
+  cdDrawCurveU(kage, polygons, x1, y1, x2, y2, x2, y2, x3, y3, a1, a2);\r
+}\r
+\r
+function cdDrawLine(kage, polygons, tx1, ty1, tx2, ty2, ta1, ta2){\r
+  var rad;\r
+  var v, x1, y1, x2, y2;\r
+  var a1, a2, opt1, opt2;\r
+  var XX, XY, YX, YY;\r
+  var poly;\r
+  var kMinWidthT;\r
+  \r
+  if(kage.kShotai == kage.kMincho){ //mincho\r
+    x1 = tx1;\r
+    y1 = ty1;\r
+    x2 = tx2;\r
+    y2 = ty2;\r
+    a1 = ta1 % 1000;\r
+    a2 = ta2 % 100;\r
+    opt1 = Math.floor(ta1 / 1000);\r
+    opt2 = Math.floor(ta2 / 100);\r
+    \r
+    kMinWidthT = kage.kMinWidthT - opt1 / 2;\r
+    \r
+    if(x1 == x2){ //if TATE stroke, use y-axis\r
+      poly = new Polygon(4);\r
+      switch(a1){\r
+      case 0:\r
+        poly.set(3, x1 - kMinWidthT, y1 - kage.kMinWidthY / 2);\r
+        poly.set(0, x1 + kMinWidthT, y1 + kage.kMinWidthY / 2);\r
+        break;\r
+      case 1:\r
+      case 6: //... no need\r
+      case 22:\r
+        poly.set(3, x1 - kMinWidthT, y1);\r
+        poly.set(0, x1 + kMinWidthT, y1);\r
+        break;\r
+      case 12:\r
+        poly.set(3, x1 - kMinWidthT, y1 - kage.kMinWidthY - kMinWidthT);\r
+        poly.set(0, x1 + kMinWidthT, y1 - kage.kMinWidthY);\r
+        break;\r
+      case 32:\r
+        poly.set(3, x1 - kMinWidthT, y1 - kage.kMinWidthY);\r
+        poly.set(0, x1 + kMinWidthT, y1 - kage.kMinWidthY);\r
+        break;\r
+      }\r
+      \r
+      switch(a2){\r
+      case 0:\r
+        if(a1 == 6){ //KAGI's tail ... no need\r
+          poly.set(2, x2 - kMinWidthT, y2);\r
+          poly.set(1, x2 + kMinWidthT, y2);\r
+        }\r
+        else{\r
+          poly.set(2, x2 - kMinWidthT, y2 + kMinWidthT / 2);\r
+          poly.set(1, x2 + kMinWidthT, y2 - kMinWidthT / 2);\r
+        }\r
+        break;\r
+      case 1:\r
+        poly.set(2, x2 - kMinWidthT, y2);\r
+        poly.set(1, x2 + kMinWidthT, y2);\r
+        break;\r
+      case 13:\r
+        poly.set(2, x2 - kMinWidthT, y2 + kage.kAdjustKakatoL[opt2] + kMinWidthT);\r
+        poly.set(1, x2 + kMinWidthT, y2 + kage.kAdjustKakatoL[opt2]);\r
+        break;\r
+      case 23:\r
+        poly.set(2, x2 - kMinWidthT, y2 + kage.kAdjustKakatoR[opt2] + kMinWidthT);\r
+        poly.set(1, x2 + kMinWidthT, y2 + kage.kAdjustKakatoR[opt2]);\r
+        break;\r
+      case 32:\r
+        poly.set(2, x2 - kMinWidthT, y2 + kage.kMinWidthY);\r
+        poly.set(1, x2 + kMinWidthT, y2 + kage.kMinWidthY);\r
+        break;\r
+      }\r
+      \r
+      polygons.push(poly);\r
+      \r
+      if(a1 == 22){ //box's right top corner\r
+        poly = new Polygon();\r
+        poly.push(x1 - kMinWidthT, y1 - kage.kMinWidthY);\r
+        poly.push(x1, y1 - kage.kMinWidthY - kage.kWidth);\r
+        poly.push(x1 + kMinWidthT + kage.kWidth, y1 + kage.kMinWidthY);\r
+        poly.push(x1 + kMinWidthT, y1 + kMinWidthT);\r
+        poly.push(x1 - kMinWidthT, y1);\r
+        polygons.push(poly);\r
+      }\r
+      \r
+      if(a1 == 0){ //beginning of the stroke\r
+        poly = new Polygon();\r
+        poly.push(x1 + kMinWidthT, y1 + kage.kMinWidthY * 0.5);\r
+        poly.push(x1 + kMinWidthT + kMinWidthT * 0.5, y1 + kage.kMinWidthY * 0.5 + kage.kMinWidthY);\r
+        poly.push(x1 + kMinWidthT - 2, y1 + kage.kMinWidthY * 0.5 + kage.kMinWidthY * 2 + 1);\r
+        polygons.push(poly);\r
+      }\r
+      \r
+      if((a1 == 6 && a2 == 0) || a2 == 1){ //KAGI NO YOKO BOU NO SAIGO NO MARU ... no need only used at 1st=yoko\r
+        poly = new Polygon();\r
+       if(kage.kUseCurve){\r
+          poly.push(x2 - kMinWidthT, y2);\r
+          poly.push(x2 - kMinWidthT * 0.9, y2 + kMinWidthT * 0.9, 1);\r
+          poly.push(x2, y2 + kMinWidthT);\r
+          poly.push(x2 + kMinWidthT * 0.9, y2 + kMinWidthT * 0.9, 1);\r
+          poly.push(x2 + kMinWidthT, y2);\r
+        } else {\r
+          poly.push(x2 - kMinWidthT, y2);\r
+          poly.push(x2 - kMinWidthT * 0.6, y2 + kMinWidthT * 0.6);\r
+          poly.push(x2, y2 + kMinWidthT);\r
+          poly.push(x2 + kMinWidthT * 0.6, y2 + kMinWidthT * 0.6);\r
+          poly.push(x2 + kMinWidthT, y2);\r
+        }\r
+        //poly.reverse(); // for fill-rule\r
+        polygons.push(poly);\r
+      }\r
+    }\r
+    else if(y1 == y2){ //if it is YOKO stroke, use x-axis\r
+      if(a1 == 6){ //if it is KAGI's YOKO stroke, get bold\r
+        poly = new Polygon();\r
+        poly.push(x1, y1 - kMinWidthT);\r
+        poly.push(x2, y2 - kMinWidthT);\r
+        poly.push(x2, y2 + kMinWidthT);\r
+        poly.push(x1, y1 + kMinWidthT);\r
+        polygons.push(poly);\r
+        \r
+        if(a2 == 1 || a2 == 0 || a2 == 5){ // no need a2=1\r
+          //KAGI NO YOKO BOU NO SAIGO NO MARU\r
+          poly = new Polygon();\r
+          if(kage.kUseCurve){\r
+            if(x1 < x2){\r
+              poly.push(x2, y2 - kMinWidthT);\r
+              poly.push(x2 + kMinWidthT * 0.9, y2 - kMinWidthT * 0.9, 1);\r
+              poly.push(x2 + kMinWidthT, y2);\r
+              poly.push(x2 + kMinWidthT * 0.9, y2 + kMinWidthT * 0.9, 1);\r
+              poly.push(x2, y2 + kMinWidthT);\r
+            } else {\r
+              poly.push(x2, y2 - kMinWidthT);\r
+              poly.push(x2 - kMinWidthT * 0.9, y2 - kMinWidthT * 0.9, 1);\r
+              poly.push(x2 - kMinWidthT, y2);\r
+              poly.push(x2 - kMinWidthT * 0.9, y2 + kMinWidthT * 0.9, 1);\r
+              poly.push(x2, y2 + kMinWidthT);\r
+            }\r
+          } else {\r
+            if(x1 < x2){\r
+              poly.push(x2, y2 - kMinWidthT);\r
+              poly.push(x2 + kMinWidthT * 0.6, y2 - kMinWidthT * 0.6);\r
+              poly.push(x2 + kMinWidthT, y2);\r
+              poly.push(x2 + kMinWidthT * 0.6, y2 + kMinWidthT * 0.6);\r
+              poly.push(x2, y2 + kMinWidthT);\r
+            } else {\r
+              poly.push(x2, y2 - kMinWidthT);\r
+              poly.push(x2 - kMinWidthT * 0.6, y2 - kMinWidthT * 0.6);\r
+              poly.push(x2 - kMinWidthT, y2);\r
+              poly.push(x2 - kMinWidthT * 0.6, y2 + kMinWidthT * 0.6);\r
+              poly.push(x2, y2 + kMinWidthT);\r
+            }\r
+          }\r
+          polygons.push(poly);\r
+        }\r
+        \r
+        if(a2 == 5){\r
+          //KAGI NO YOKO BOU NO HANE\r
+          poly = new Polygon();\r
+          if(x1 < x2){\r
+            poly.push(x2, y2 - kMinWidthT + 1);\r
+            poly.push(x2 + 2, y2 - kMinWidthT - kage.kWidth * (4 * (1 - opt1 / kage.kAdjustMageStep) + 1));\r
+            poly.push(x2, y2 - kMinWidthT - kage.kWidth * (4 * (1 - opt1 / kage.kAdjustMageStep) + 1));\r
+            poly.push(x2 - kMinWidthT, y2 - kMinWidthT + 1);\r
+          } else {\r
+            poly.push(x2, y2 - kMinWidthT + 1);\r
+            poly.push(x2 - 2, y2 - kMinWidthT - kage.kWidth * (4 * (1 - opt1 / kage.kAdjustMageStep) + 1));\r
+            poly.push(x2, y2 - kMinWidthT - kage.kWidth * (4 * (1 - opt1 / kage.kAdjustMageStep) + 1));\r
+            poly.push(x2 + kMinWidthT, y2 - kMinWidthT + 1);\r
+          }\r
+          //poly.reverse(); // for fill-rule\r
+          polygons.push(poly);\r
+        }\r
+      }\r
+      else{\r
+        //always same\r
+        poly = new Polygon(4);\r
+        poly.set(0, x1, y1 - kage.kMinWidthY);\r
+        poly.set(1, x2, y2 - kage.kMinWidthY);\r
+        poly.set(2, x2, y2 + kage.kMinWidthY);\r
+        poly.set(3, x1, y1 + kage.kMinWidthY);\r
+        polygons.push(poly);\r
+        \r
+        //UROKO\r
+        if(a2 == 0){\r
+          poly = new Polygon();\r
+          poly.push(x2, y2 - kage.kMinWidthY);\r
+          poly.push(x2 - kage.kAdjustUrokoX[opt2], y2);\r
+          poly.push(x2 - kage.kAdjustUrokoX[opt2] / 2, y2 - kage.kAdjustUrokoY[opt2]);\r
+          polygons.push(poly);\r
+        }\r
+      }\r
+    }\r
+    else{ //for others, use x-axis\r
+      rad = Math.atan((y2 - y1) / (x2 - x1));\r
+      if((Math.abs(y2 - y1) < Math.abs(x2 - x1)) && (a1 != 6) && (a2 != 6) && !(x1 > x2)){ //ASAI KAUDO\r
+        //always same\r
+        poly = new Polygon(4);\r
+        poly.set(0, x1 + Math.sin(rad) * kage.kMinWidthY, y1 - Math.cos(rad) * kage.kMinWidthY);\r
+        poly.set(1, x2 + Math.sin(rad) * kage.kMinWidthY, y2 - Math.cos(rad) * kage.kMinWidthY);\r
+        poly.set(2, x2 - Math.sin(rad) * kage.kMinWidthY, y2 + Math.cos(rad) * kage.kMinWidthY);\r
+        poly.set(3, x1 - Math.sin(rad) * kage.kMinWidthY, y1 + Math.cos(rad) * kage.kMinWidthY);\r
+        polygons.push(poly);\r
+        \r
+        //UROKO\r
+        if(a2 == 0){\r
+          poly = new Polygon();\r
+          poly.push(x2 + Math.sin(rad) * kage.kMinWidthY, y2 - Math.cos(rad) * kage.kMinWidthY);\r
+          poly.push(x2 - Math.cos(rad) * kage.kAdjustUrokoX[opt2], y2 - Math.sin(rad) * kage.kAdjustUrokoX[opt2]);\r
+          poly.push(x2 - Math.cos(rad) * kage.kAdjustUrokoX[opt2] / 2 + Math.sin(rad) * kage.kAdjustUrokoX[opt2] / 2, y2 - Math.sin(rad) * kage.kAdjustUrokoY[opt2] - Math.cos(rad) * kage.kAdjustUrokoY[opt2]);\r
+          polygons.push(poly);\r
+        }\r
+      }\r
+      \r
+      else{ //KAKUDO GA FUKAI or KAGI NO YOKO BOU\r
+        if(x1 > x2){ v = -1; } else{ v = 1; }\r
+        poly = new Polygon(4);\r
+        switch(a1){\r
+        case 0:\r
+          poly.set(0, x1 + Math.sin(rad) * kMinWidthT * v + kage.kMinWidthY * Math.cos(rad) * 0.5 * v,\r
+                   y1 - Math.cos(rad) * kMinWidthT * v + kage.kMinWidthY * Math.sin(rad) * 0.5 * v);\r
+          poly.set(3, x1 - Math.sin(rad) * kMinWidthT * v - kage.kMinWidthY * Math.cos(rad) * 0.5 * v,\r
+                   y1 + Math.cos(rad) * kMinWidthT * v - kage.kMinWidthY * Math.sin(rad) * 0.5 * v);\r
+          break;\r
+        case 1:\r
+        case 6:\r
+          poly.set(0, x1 + Math.sin(rad) * kMinWidthT * v, y1 - Math.cos(rad) * kMinWidthT * v);\r
+          poly.set(3, x1 - Math.sin(rad) * kMinWidthT * v, y1 + Math.cos(rad) * kMinWidthT * v);\r
+          break;\r
+        case 12:\r
+          poly.set(0, x1 + Math.sin(rad) * kMinWidthT * v - kage.kMinWidthY * Math.cos(rad) * v,\r
+                   y1 - Math.cos(rad) * kMinWidthT * v - kage.kMinWidthY * Math.sin(rad) * v);\r
+          poly.set(3, x1 - Math.sin(rad) * kMinWidthT * v - (kMinWidthT + kage.kMinWidthY) * Math.cos(rad) * v,\r
+                   y1 + Math.cos(rad) * kMinWidthT * v - (kMinWidthT + kage.kMinWidthY) * Math.sin(rad) * v);\r
+          break;\r
+        case 22:\r
+          poly.set(0, x1 + (kMinWidthT * v + 1) / Math.sin(rad), y1 + 1);\r
+          poly.set(3, x1 - (kMinWidthT * v) / Math.sin(rad), y1);\r
+          break;\r
+        case 32:\r
+          poly.set(0, x1 + (kMinWidthT * v) / Math.sin(rad), y1);\r
+          poly.set(3, x1 - (kMinWidthT * v) / Math.sin(rad), y1);\r
+          break;\r
+        }\r
+        \r
+        switch(a2){\r
+        case 0:\r
+          if(a1 == 6){\r
+            poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v, y2 - Math.cos(rad) * kMinWidthT * v);\r
+            poly.set(2, x2 - Math.sin(rad) * kMinWidthT * v, y2 + Math.cos(rad) * kMinWidthT * v);\r
+          }\r
+          else{\r
+            poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v - kMinWidthT * 0.5 * Math.cos(rad) * v,\r
+                     y2 - Math.cos(rad) * kMinWidthT * v - kMinWidthT * 0.5 * Math.sin(rad) * v);\r
+            poly.set(2, x2 - Math.sin(rad) * kMinWidthT * v + kMinWidthT * 0.5 * Math.cos(rad) * v,\r
+                     y2 + Math.cos(rad) * kMinWidthT * v + kMinWidthT * 0.5 * Math.sin(rad) * v);\r
+          }\r
+          break;\r
+        case 1: // is needed?\r
+        case 5:\r
+          poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v, y2 - Math.cos(rad) * kMinWidthT * v);\r
+          poly.set(2, x2 - Math.sin(rad) * kMinWidthT * v, y2 + Math.cos(rad) * kMinWidthT * v);\r
+          break;\r
+        case 13:\r
+          poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v + kage.kAdjustKakatoL[opt2] * Math.cos(rad) * v,\r
+                   y2 - Math.cos(rad) * kMinWidthT * v + kage.kAdjustKakatoL[opt2] * Math.sin(rad) * v);\r
+          poly.set(2, x2 - Math.sin(rad) * kMinWidthT * v + (kage.kAdjustKakatoL[opt2] + kMinWidthT) * Math.cos(rad) * v,\r
+                   y2 + Math.cos(rad) * kMinWidthT * v + (kage.kAdjustKakatoL[opt2] + kMinWidthT) * Math.sin(rad) * v);\r
+          break;\r
+        case 23:\r
+          poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v + kage.kAdjustKakatoR[opt2] * Math.cos(rad) * v,\r
+                   y2 - Math.cos(rad) * kMinWidthT * v + kage.kAdjustKakatoR[opt2] * Math.sin(rad) * v);\r
+          poly.set(2,\r
+                   x2 - Math.sin(rad) * kMinWidthT * v + (kage.kAdjustKakatoR[opt2] + kMinWidthT) * Math.cos(rad) * v,\r
+                   y2 + Math.cos(rad) * kMinWidthT * v + (kage.kAdjustKakatoR[opt2] + kMinWidthT) * Math.sin(rad) * v);\r
+          break;\r
+        case 32:\r
+          poly.set(1, x2 + (kMinWidthT * v) / Math.sin(rad), y2);\r
+          poly.set(2, x2 - (kMinWidthT * v) / Math.sin(rad), y2);\r
+          break;\r
+        }\r
+        \r
+        polygons.push(poly);\r
+        \r
+        if((a1 == 6) && (a2 == 0 || a2 == 5)){ //KAGI NO YOKO BOU NO SAIGO NO MARU\r
+          poly = new Polygon();\r
+          if(kage.kUseCurve){\r
+            poly.push(x2 + Math.sin(rad) * kMinWidthT * v, y2 - Math.cos(rad) * kMinWidthT * v);\r
+            poly.push(x2 - Math.cos(rad) * kMinWidthT * 0.9 * v + Math.sin(rad) * kMinWidthT * 0.9 * v,\r
+                      y2 + Math.sin(rad) * kMinWidthT * 0.9 * v - Math.cos(rad) * kMinWidthT * 0.9 * v, 1);\r
+            poly.push(x2 + Math.cos(rad) * kMinWidthT * v, y2 + Math.sin(rad) * kMinWidthT * v);\r
+            poly.push(x2 + Math.cos(rad) * kMinWidthT * 0.9 * v - Math.sin(rad) * kMinWidthT * 0.9 * v,\r
+                      y2 + Math.sin(rad) * kMinWidthT * 0.9 * v + Math.cos(rad) * kMinWidthT * 0.9 * v, 1);\r
+            poly.push(x2 - Math.sin(rad) * kMinWidthT * v, y2 + Math.cos(rad) * kMinWidthT * v);\r
+          } else {\r
+            poly.push(x2 + Math.sin(rad) * kMinWidthT * v, y2 - Math.cos(rad) * kMinWidthT * v);\r
+            poly.push(x2 + Math.cos(rad) * kMinWidthT * 0.8 * v + Math.sin(rad) * kMinWidthT * 0.6 * v,\r
+                      y2 + Math.sin(rad) * kMinWidthT * 0.8 * v - Math.cos(rad) * kMinWidthT * 0.6 * v);\r
+            poly.push(x2 + Math.cos(rad) * kMinWidthT * v, y2 + Math.sin(rad) * kMinWidthT * v);\r
+            poly.push(x2 + Math.cos(rad) * kMinWidthT * 0.8 * v - Math.sin(rad) * kMinWidthT * 0.6 * v,\r
+                      y2 + Math.sin(rad) * kMinWidthT * 0.8 * v + Math.cos(rad) * kMinWidthT * 0.6 * v);\r
+            poly.push(x2 - Math.sin(rad) * kMinWidthT * v, y2 + Math.cos(rad) * kMinWidthT * v);\r
+          }\r
+          polygons.push(poly);\r
+        }\r
+        \r
+        if(a1 == 6 && a2 == 5){\r
+          //KAGI NO YOKO BOU NO HANE\r
+          poly = new Polygon();\r
+          if(x1 < x2){\r
+            poly.push(x2 + (kMinWidthT - 1) * Math.sin(rad) * v, y2 - (kMinWidthT - 1) * Math.cos(rad) * v);\r
+            poly.push(x2 + 2 * Math.cos(rad) * v + (kMinWidthT + kage.kWidth * 5) * Math.sin(rad) * v,\r
+                      y2 + 2 * Math.sin(rad) * v - (kMinWidthT + kage.kWidth * 5) * Math.cos(rad) * v);\r
+            poly.push(x2 + (kMinWidthT + kage.kWidth * 5) * Math.sin(rad) * v,\r
+                      y2 - (kMinWidthT + kage.kWidth * 5) * Math.cos(rad) * v);\r
+            poly.push(x2 + (kMinWidthT - 1) * Math.sin(rad) * v - kMinWidthT * Math.cos(rad) * v,\r
+                      y2 - (kMinWidthT - 1) * Math.cos(rad) * v - kMinWidthT * Math.sin(rad) * v);\r
+          } else {\r
+            poly.push(x2 - (kMinWidthT - 1) * Math.sin(rad) * v, y2 + (kMinWidthT - 1) * Math.cos(rad) * v);\r
+            poly.push(x2 + 2 * Math.cos(rad) * v - (kMinWidthT + kage.kWidth * 5) * Math.sin(rad) * v,\r
+                      y2 + 2 * Math.sin(rad) * v + (kMinWidthT + kage.kWidth * 5) * Math.cos(rad) * v);\r
+            poly.push(x2 - (kMinWidthT + kage.kWidth * 5) * Math.sin(rad) * v,\r
+                      y2 + (kMinWidthT + kage.kWidth * 5) * Math.cos(rad) * v);\r
+            poly.push(x2 + (kMinWidthT - 1) * Math.sin(rad) * v - kMinWidthT * Math.cos(rad) * v,\r
+                      y2 - (kMinWidthT - 1) * Math.cos(rad) * v - kMinWidthT * Math.sin(rad) * v);\r
+          }\r
+          polygons.push(poly);\r
+        }\r
+        \r
+        if(a1 == 22){ //SHIKAKU MIGIUE UROKO NANAME DEMO MASSUGU MUKI\r
+          poly = new Polygon();\r
+          poly.push(x1 - kMinWidthT, y1 - kage.kMinWidthY);\r
+          poly.push(x1, y1 - kage.kMinWidthY - kage.kWidth);\r
+          poly.push(x1 + kMinWidthT + kage.kWidth, y1 + kage.kMinWidthY);\r
+          poly.push(x1 + kMinWidthT, y1 + kMinWidthT - 1);\r
+          poly.push(x1 - kMinWidthT, y1 + kMinWidthT + 4);\r
+          polygons.push(poly);\r
+        }\r
+        \r
+        XX = Math.sin(rad) * v;\r
+        XY = Math.cos(rad) * v * -1;\r
+        YX = Math.cos(rad) * v;\r
+        YY = Math.sin(rad) * v;\r
+        \r
+        if(a1 == 0){ //beginning of the storke\r
+          poly = new Polygon();\r
+          poly.push(x1 + kMinWidthT * XX + (kage.kMinWidthY * 0.5) * YX,\r
+                    y1 + kMinWidthT * XY + (kage.kMinWidthY * 0.5) * YY);\r
+          poly.push(x1 + (kMinWidthT + kMinWidthT * 0.5) * XX + (kage.kMinWidthY * 0.5 + kage.kMinWidthY) * YX,\r
+                    y1 + (kMinWidthT + kMinWidthT * 0.5) * XY + (kage.kMinWidthY * 0.5 + kage.kMinWidthY) * YY);\r
+          poly.push(x1 + kMinWidthT * XX + (kage.kMinWidthY * 0.5 + kage.kMinWidthY * 2) * YX - 2 * XX,\r
+                    y1 + kMinWidthT * XY + (kage.kMinWidthY * 0.5 + kage.kMinWidthY * 2) * YY + 1 * XY);\r
+          polygons.push(poly);\r
+        }\r
+      }\r
+    }\r
+  }\r
+  else{ //gothic\r
+    if(tx1 == tx2){ //if TATE stroke, use y-axis\r
+      if(ty1 > ty2){\r
+        x1 = tx2;\r
+        y1 = ty2;\r
+        x2 = tx1;\r
+        y2 = ty1;\r
+        a1 = ta2;\r
+        a2 = ta1;\r
+      }\r
+      else{\r
+        x1 = tx1;\r
+        y1 = ty1;\r
+        x2 = tx2;\r
+        y2 = ty2;\r
+        a1 = ta1;\r
+        a2 = ta2;\r
+      }\r
+      \r
+      if(a1 % 10 == 2){ y1 = y1 - kage.kWidth; }\r
+      if(a2 % 10 == 2){ y2 = y2 + kage.kWidth; }\r
+      if(a1 % 10 == 3){ y1 = y1 - kage.kWidth * kage.kKakato; }\r
+      if(a2 % 10 == 3){ y2 = y2 + kage.kWidth * kage.kKakato; }\r
+      \r
+      poly = new Polygon();\r
+      poly.push(x1 - kage.kWidth, y1);\r
+      poly.push(x2 - kage.kWidth, y2);\r
+      poly.push(x2 + kage.kWidth, y2);\r
+      poly.push(x1 + kage.kWidth, y1);\r
+      //poly.reverse(); // for fill-rule\r
+      \r
+      polygons.push(poly);\r
+    }\r
+    else if(ty1 == ty2){ //if YOKO stroke, use x-axis\r
+      if(tx1 > tx2){\r
+        x1 = tx2;\r
+        y1 = ty2;\r
+        x2 = tx1;\r
+        y2 = ty1;\r
+        a1 = ta2;\r
+        a2 = ta1;\r
+      }\r
+      else{\r
+        x1 = tx1;\r
+        y1 = ty1;\r
+        x2 = tx2;\r
+        y2 = ty2;\r
+        a1 = ta1;\r
+        a2 = ta2;\r
+      }\r
+      if(a1 % 10 == 2){ x1 = x1 - kage.kWidth; }\r
+      if(a2 % 10 == 2){ x2 = x2 + kage.kWidth; }\r
+      if(a1 % 10 == 3){ x1 = x1 - kage.kWidth * kage.kKakato; }\r
+      if(a2 % 10 == 3){ x2 = x2 + kage.kWidth * kage.kKakato; }\r
+      \r
+      poly = new Polygon();\r
+      poly.push(x1, y1 - kage.kWidth);\r
+      poly.push(x2, y2 - kage.kWidth);\r
+      poly.push(x2, y2 + kage.kWidth);\r
+      poly.push(x1, y1 + kage.kWidth);\r
+      \r
+      polygons.push(poly);\r
+    }\r
+    else{ //for others, use x-axis\r
+      if(tx1 > tx2){\r
+        x1 = tx2;\r
+        y1 = ty2;\r
+        x2 = tx1;\r
+        y2 = ty1;\r
+        a1 = ta2;\r
+        a2 = ta1;\r
+      }\r
+      else{\r
+        x1 = tx1;\r
+        y1 = ty1;\r
+        x2 = tx2;\r
+        y2 = ty2;\r
+        a1 = ta1;\r
+        a2 = ta2;\r
+      }\r
+      rad = Math.atan((y2 - y1) / (x2 - x1));\r
+      if(a1 % 10 == 2){\r
+        x1 = x1 - kage.kWidth * Math.cos(rad);\r
+        y1 = y1 - kage.kWidth * Math.sin(rad);\r
+      }\r
+      if(a2 % 10 == 2){\r
+        x2 = x2 + kage.kWidth * Math.cos(rad);\r
+        y2 = y2 + kage.kWidth * Math.sin(rad);\r
+      }\r
+      if(a1 % 10 == 3){\r
+        x1 = x1 - kage.kWidth * Math.cos(rad) * kage.kKakato;\r
+        y1 = y1 - kage.kWidth * Math.sin(rad) * kage.kKakato;\r
+      }\r
+      if(a2 % 10 == 3){\r
+        x2 = x2 + kage.kWidth * Math.cos(rad) * kage.kKakato;\r
+        y2 = y2 + kage.kWidth * Math.sin(rad) * kage.kKakato;\r
+      }\r
+      \r
+      //SUICHOKU NO ICHI ZURASHI HA Math.sin TO Math.cos NO IREKAE + x-axis MAINASU KA\r
+      poly = new Polygon();\r
+      poly.push(x1 + Math.sin(rad) * kage.kWidth, y1 - Math.cos(rad) * kage.kWidth);\r
+      poly.push(x2 + Math.sin(rad) * kage.kWidth, y2 - Math.cos(rad) * kage.kWidth);\r
+      poly.push(x2 - Math.sin(rad) * kage.kWidth, y2 + Math.cos(rad) * kage.kWidth);\r
+      poly.push(x1 - Math.sin(rad) * kage.kWidth, y1 + Math.cos(rad) * kage.kWidth);\r
+      \r
+      polygons.push(poly);\r
+    }\r
+  }\r
+}\r
diff --git a/kagedf.js b/kagedf.js
new file mode 100755 (executable)
index 0000000..c420387
--- /dev/null
+++ b/kagedf.js
@@ -0,0 +1,447 @@
+function dfDrawFont(kage, polygons, a1, a2, a3, x1, y1, x2, y2, x3, y3, x4, y4){\r
+  var tx1, tx2, tx3, tx4, ty1, ty2, ty3, ty4, v;\r
+  var rad;\r
+       \r
+  if(kage.kShotai == kage.kMincho){\r
+    switch(a1 % 100){ // ... no need to divide\r
+    case 0:\r
+      break;\r
+    case 1:\r
+      if(a3 % 100 == 4){\r
+        if(x1 == x2){\r
+          if(y1 < y2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2;\r
+          ty1 = y2 - kage.kMage * v;\r
+        }\r
+        else if(y1 == y2){ // ... no need\r
+          if(x1 < x2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2 - kage.kMage * v;\r
+          ty1 = y2;\r
+        }\r
+        else{\r
+          rad = Math.atan((y2 - y1) / (x2 - x1));\r
+          if(x1 < x2){ v = 1; } else{v = -1; }\r
+          tx1 = x2 - kage.kMage * Math.cos(rad) * v;\r
+          ty1 = y2 - kage.kMage * Math.sin(rad) * v;\r
+        }\r
+        cdDrawLine(kage, polygons, x1, y1, tx1, ty1, a2, 1);\r
+        cdDrawCurve(kage, polygons, tx1, ty1, x2, y2, x2 - kage.kMage * (((kage.kAdjustTateStep + 4) - Math.floor(a2 / 1000)) / (kage.kAdjustTateStep + 4)), y2, 1 + (a2 - a2 % 1000), a3 + 10);\r
+      }\r
+      else{\r
+        cdDrawLine(kage, polygons, x1, y1, x2, y2, a2, a3);\r
+      }\r
+      break;\r
+    case 2:\r
+    //case 12: // ... no need\r
+      if(a3 % 100 == 4){\r
+        if(x2 == x3){\r
+          tx1 = x3;\r
+          ty1 = y3 - kage.kMage;\r
+        }\r
+        else if(y2 == y3){\r
+          tx1 = x3 - kage.kMage;\r
+          ty1 = y3;\r
+        }\r
+        else{\r
+          rad = Math.atan((y3 - y2) / (x3 - x2));\r
+          if(x2 < x3){ v = 1; } else{ v = -1; }\r
+          tx1 = x3 - kage.kMage * Math.cos(rad) * v;\r
+          ty1 = y3 - kage.kMage * Math.sin(rad) * v;\r
+        }\r
+        cdDrawCurve(kage, polygons, x1, y1, x2, y2, tx1, ty1, a2, 1);\r
+        cdDrawCurve(kage, polygons, tx1, ty1, x3, y3, x3 - kage.kMage, y3, 1, a3 + 10);\r
+      }\r
+      else if(a3 == 5){\r
+        cdDrawCurve(kage, polygons, x1, y1, x2, y2, x3, y3, a2, 15);\r
+      }\r
+      else{\r
+        cdDrawCurve(kage, polygons, x1, y1, x2, y2, x3, y3, a2, a3);\r
+      }\r
+      break;\r
+    case 3:\r
+      if(a3 % 1000 == 5){\r
+        if(x1 == x2){\r
+          if(y1 < y2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2;\r
+          ty1 = y2 - kage.kMage * v;\r
+        }\r
+        else if(y1 == y2){\r
+          if(x1 < x2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2 - kage.kMage * v;\r
+          ty1 = y2;\r
+        }\r
+        else{\r
+          rad = Math.atan((y2 - y1) / (x2 - x1));\r
+          if(x1 < x2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2 - kage.kMage * Math.cos(rad) * v;\r
+          ty1 = y2 - kage.kMage * Math.sin(rad) * v;\r
+        }\r
+        if(x2 == x3){\r
+          if(y2 < y3){ v = 1; } else{ v = -1; }\r
+          tx2 = x2;\r
+          ty2 = y2 + kage.kMage * v;\r
+        }\r
+        else if(y2 == y3){\r
+          if(x2 < x3){ v = 1; } else { v = -1; }\r
+          tx2 = x2 + kage.kMage * v;\r
+          ty2 = y2;\r
+        }\r
+        else{\r
+          rad = Math.atan((y3 - y2) / (x3 - x2));\r
+          if(x2 < x3){ v = 1; } else{ v = -1; }\r
+          tx2 = x2 + kage.kMage * Math.cos(rad) * v;\r
+          ty2 = y2 + kage.kMage * Math.sin(rad) * v;\r
+        }\r
+        tx3 = x3;\r
+        ty3 = y3;\r
+        \r
+        cdDrawLine(kage, polygons, x1, y1, tx1, ty1, a2, 1);\r
+        cdDrawCurve(kage, polygons, tx1, ty1, x2, y2, tx2, ty2, 1 + (a2 - a2 % 1000) * 10, 1 + (a3 - a3 % 1000));\r
+        if((x2 < x3 && tx3 - tx2 > 0) || (x2 > x3 && tx2 - tx3 > 0)){ // for closer position\r
+          cdDrawLine(kage, polygons, tx2, ty2, tx3, ty3, 6 + (a3 - a3 % 1000), 5); // bolder by force\r
+        }\r
+      }\r
+      else{\r
+        if(x1 == x2){\r
+          if(y1 < y2){ v = 1; } else { v = -1; }\r
+          tx1 = x2;\r
+          ty1 = y2 - kage.kMage * v;\r
+        }\r
+        else if(y1 == y2){\r
+          if(x1 < x2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2 - kage.kMage * v;\r
+          ty1 = y2;\r
+        }\r
+        else{\r
+          rad = Math.atan((y2 - y1) / (x2 - x1));\r
+          if(x1 < x2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2 - kage.kMage * Math.cos(rad) * v;\r
+          ty1 = y2 - kage.kMage * Math.sin(rad) * v;\r
+        }\r
+        if(x2 == x3){\r
+          if(y2 < y3){ v = 1; } else{ v = -1; }\r
+          tx2 = x2;\r
+          ty2 = y2 + kage.kMage * v;\r
+        }\r
+        else if(y2 == y3){\r
+          if(x2 < x3){ v = 1; } else{ v = -1; }\r
+          tx2 = x2 + kage.kMage * v;\r
+          ty2 = y2;\r
+        }\r
+        else{\r
+          rad = Math.atan((y3 - y2) / (x3 - x2));\r
+          if(x2 < x3){ v = 1; } else{ v = -1; }\r
+          tx2 = x2 + kage.kMage * Math.cos(rad) * v;\r
+          ty2 = y2 + kage.kMage * Math.sin(rad) * v;\r
+        }\r
+        cdDrawLine(kage, polygons, x1, y1, tx1, ty1, a2, 1);\r
+        cdDrawCurve(kage, polygons, tx1, ty1, x2, y2, tx2, ty2, 1 + (a2 - a2 % 1000) * 10, 1 + (a3 - a3 % 1000));\r
+        cdDrawLine(kage, polygons, tx2, ty2, x3, y3, 6 + (a3 - a3 % 1000), a3); // bolder by force\r
+      }\r
+      break;\r
+    case 12:\r
+      cdDrawCurve(kage, polygons, x1, y1, x2, y2, x3, y3, a2, 1);\r
+      cdDrawLine(kage, polygons, x3, y3, x4, y4, 6, a3);\r
+      break;\r
+    case 4:\r
+      rate = 6;\r
+      if((x3 - x2) * (x3 - x2) + (y3 - y2) * (y3 - y2) < 14400){ // smaller than 120 x 120\r
+        rate = Math.sqrt((x3 - x2) * (x3 - x2) + (y3 - y2) * (y3 - y2)) / 120 * 6;\r
+      }\r
+      if(a3 == 5){\r
+        if(x1 == x2){\r
+          if(y1 < y2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2;\r
+          ty1 = y2 - kage.kMage * v * rate;\r
+        }\r
+        else if(y1 == y2){\r
+          if(x1 < x2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2 - kage.kMage * v * rate;\r
+          ty1 = y2;\r
+        }\r
+        else{\r
+          rad = Math.atan((y2 - y1) / (x2 - x1));\r
+          if(x1 < x2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2 - kage.kMage * Math.cos(rad) * v * rate;\r
+          ty1 = y2 - kage.kMage * Math.sin(rad) * v * rate;\r
+        }\r
+        if(x2 == x3){\r
+          if(y2 < y3){ v = 1; } else{ v = -1; }\r
+          tx2 = x2;\r
+          ty2 = y2 + kage.kMage * v * rate;\r
+        }\r
+        else if(y2 == y3){\r
+          if(x2 < x3){ v = 1; } else { v = -1; }\r
+          tx2 = x2 + kage.kMage * v * rate;\r
+          ty2 = y2;\r
+        }\r
+        else{\r
+          rad = Math.atan((y3 - y2) / (x3 - x2));\r
+          if(x2 < x3){ v = 1; } else{ v = -1; }\r
+          tx2 = x2 + kage.kMage * Math.cos(rad) * v * rate;\r
+          ty2 = y2 + kage.kMage * Math.sin(rad) * v * rate;\r
+        }\r
+        tx3 = x3;\r
+        ty3 = y3;\r
+        \r
+        cdDrawLine(kage, polygons, x1, y1, tx1, ty1, a2, 1);\r
+        cdDrawCurve(kage, polygons, tx1, ty1, x2, y2, tx2, ty2, 1, 1);\r
+        if(tx3 - tx2 > 0){ // for closer position\r
+          cdDrawLine(kage, polygons, tx2, ty2, tx3, ty3, 6, 5); // bolder by force\r
+        }\r
+      }\r
+      else{\r
+        if(x1 == x2){\r
+          if(y1 < y2){ v = 1; } else { v = -1; }\r
+          tx1 = x2;\r
+          ty1 = y2 - kage.kMage * v * rate;\r
+        }\r
+        else if(y1 == y2){\r
+          if(x1 < x2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2 - kage.kMage * v * rate;\r
+          ty1 = y2;\r
+        }\r
+        else{\r
+          rad = Math.atan((y2 - y1) / (x2 - x1));\r
+          if(x1 < x2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2 - kage.kMage * Math.cos(rad) * v * rate;\r
+          ty1 = y2 - kage.kMage * Math.sin(rad) * v * rate;\r
+        }\r
+        if(x2 == x3){\r
+          if(y2 < y3){ v = 1; } else{ v = -1; }\r
+          tx2 = x2;\r
+          ty2 = y2 + kage.kMage * v * rate;\r
+        }\r
+        else if(y2 == y3){\r
+          if(x2 < x3){ v = 1; } else{ v = -1; }\r
+          tx2 = x2 + kage.kMage * v * rate;\r
+          ty2 = y2;\r
+        }\r
+        else{\r
+          rad = Math.atan((y3 - y2) / (x3 - x2));\r
+          if(x2 < x3){ v = 1; } else{ v = -1; }\r
+          tx2 = x2 + kage.kMage * Math.cos(rad) * v * rate;\r
+          ty2 = y2 + kage.kMage * Math.sin(rad) * v * rate;\r
+        }\r
+        cdDrawLine(kage, polygons, x1, y1, tx1, ty1, a2, 1);\r
+        cdDrawCurve(kage, polygons, tx1, ty1, x2, y2, tx2, ty2, 1, 1);\r
+        cdDrawLine(kage, polygons, tx2, ty2, x3, y3, 6, a3); // bolder by force\r
+      }\r
+      break;\r
+    case 6:\r
+      if(a3 == 4){\r
+        if(x3 == x4){\r
+          tx1 = x4;\r
+          ty1 = y4 - kage.kMage;\r
+        }\r
+        else if(y3 == y4){\r
+          tx1 = x4 - kage.kMage;\r
+          ty1 = y4;\r
+        }\r
+        else{\r
+          rad = Math.atan((y4 - y3) / (x4 - x3));\r
+          if(x3 < x4){ v = 1; } else{ v = -1; }\r
+          tx1 = x4 - kage.kMage * Math.cos(rad) * v;\r
+          ty1 = y4 - kage.kMage * Math.sin(rad) * v;\r
+        }\r
+        cdDrawBezier(kage, polygons, x1, y1, x2, y2, x3, y3, tx1, ty1, a2, 1);\r
+        cdDrawCurve(kage, polygons, tx1, ty1, x4, y4, x4 - kage.kMage, y4, 1, 14);\r
+      }\r
+      else if(a3 == 5){\r
+        cdDrawBezier(kage, polygons, x1, y1, x2, y2, x3, y3, x4, y4, a2, 15);\r
+      }\r
+      else{\r
+        cdDrawBezier(kage, polygons, x1, y1, x2, y2, x3, y3, x4, y4, a2, a3);\r
+      }\r
+      break;\r
+    case 7:\r
+      cdDrawLine(kage, polygons, x1, y1, x2, y2, a2, 1);\r
+      cdDrawCurve(kage, polygons, x2, y2, x3, y3, x4, y4, 1 + (a2 - a2 % 1000), a3);\r
+      break;\r
+    case 9: // may not be exist ... no need\r
+      //kageCanvas[y1][x1] = 0;\r
+      //kageCanvas[y2][x2] = 0;\r
+      break;\r
+    default:\r
+      break;\r
+    }\r
+  }\r
+    \r
+  else{ // gothic\r
+    switch(a1 % 100){\r
+    case 0:\r
+      break;\r
+    case 1:\r
+      if(a3 == 4){\r
+        if(x1 == x2){\r
+          if(y1 < y2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2;\r
+          ty1 = y2 - kage.kMage * v;\r
+        }\r
+        else if(y1 == y2){\r
+          if(x1 < x2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2 - kage.kMage * v;\r
+          ty1 = y2;\r
+        }\r
+        else{\r
+          rad = Math.atan((y2 - y1) / (x2 - x1));\r
+          if(x1 < x2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2 - kage.kMage * Math.cos(rad) * v;\r
+          ty1 = y2 - kage.kMage * Math.sin(rad) * v;\r
+        }\r
+        cdDrawLine(kage, polygons, x1, y1, tx1, ty1, a2, 1);\r
+        cdDrawCurve(kage, polygons, tx1, ty1, x2, y2, x2 - kage.kMage * 2, y2 - kage.kMage * 0.5, 1, 0);\r
+      }\r
+      else{\r
+        cdDrawLine(kage, polygons, x1, y1, x2, y2, a2, a3);\r
+      }\r
+      break;\r
+    case 2:\r
+    case 12:\r
+      if(a3 == 4){\r
+        if(x2 == x3){\r
+          tx1 = x3;\r
+          ty1 = y3 - kage.kMage;\r
+        }\r
+        else if(y2 == y3){\r
+          tx1 = x3 - kage.kMage;\r
+          ty1 = y3;\r
+        }\r
+        else{\r
+          rad = Math.atan((y3 - y2) / (x3 - x2));\r
+          if(x2 < x3){ v = 1; } else{ v = -1; }\r
+          tx1 = x3 - kage.kMage * Math.cos(rad) * v;\r
+          ty1 = y3 - kage.kMage * Math.sin(rad) * v;\r
+        }\r
+        cdDrawCurve(kage, polygons, x1, y1, x2, y2, tx1, ty1, a2, 1);\r
+        cdDrawCurve(kage, polygons, tx1, ty1, x3, y3, x3 - kage.kMage * 2, y3 - kage.kMage * 0.5, 1, 0);\r
+      }\r
+      else if(a3 == 5){\r
+        tx1 = x3 + kage.kMage;\r
+        ty1 = y3;\r
+        tx2 = tx1 + kage.kMage * 0.5;\r
+        ty2 = y3 - kage.kMage * 2;\r
+        cdDrawCurve(kage, polygons, x1, y1, x2, y2, x3, y3, a2, 1);\r
+        cdDrawCurve(kage, polygons, x3, y3, tx1, ty1, tx2, ty2, 1, 0);\r
+      }\r
+      else{\r
+        cdDrawCurve(kage, polygons, x1, y1, x2, y2, x3, y3, a2, a3);\r
+      }\r
+      break;\r
+    case 3:\r
+      if(a3 == 5){\r
+        if(x1 == x2){\r
+          if(y1 < y2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2;\r
+          ty1 = y2 - kage.kMage * v;\r
+        }\r
+        else if(y1 == y2){\r
+          if(x1 < x2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2 - kage.kMage * v;\r
+          ty1 = y2;\r
+        }\r
+        else{\r
+          rad = Math.atan((y2 - y1) / (x2 - x1));\r
+          if(x1 < x2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2 - kage.kMage * Math.cos(rad) * v;\r
+          ty1 = y2 - kage.kMage * Math.sin(rad) * v;\r
+        }\r
+        if(x2 == x3){\r
+          if(y2 < y3){ v = 1; } else{ v = -1; }\r
+          tx2 = x2;\r
+          ty2 = y2 + kage.kMage * v;\r
+        }\r
+        else if(y2 == y3){\r
+          if(x2 < x3){ v = 1; } else{ v = -1; }\r
+          tx2 = x2 + kage.kMage * v;\r
+          ty2 = y2;\r
+        }\r
+        else{\r
+          rad = Math.atan((y3 - y2) / (x3 - x2));\r
+          if(x2 < x3){ v = 1; } else{ v = -1; }\r
+          tx2 = x2 + kage.kMage * Math.cos(rad) * v;\r
+          ty2 = y2 + kage.kMage * Math.sin(rad) * v;\r
+        }\r
+        tx3 = x3 - kage.kMage;\r
+        ty3 = y3;\r
+        tx4 = x3 + kage.kMage * 0.5;\r
+        ty4 = y3 - kage.kMage * 2;\r
+        \r
+        cdDrawLine(kage, polygons, x1, y1, tx1, ty1, a2, 1);\r
+        cdDrawCurve(kage, polygons, tx1, ty1, x2, y2, tx2, ty2, 1, 1);\r
+        cdDrawLine(kage, polygons, tx2, ty2, tx3, ty3, 1, 1);\r
+        cdDrawCurve(kage, polygons, tx3, ty3, x3, y3, tx4, ty4, 1, 0);\r
+      }\r
+      else{\r
+        if(x1 == x2){\r
+          if(y1 < y2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2;\r
+          ty1 = y2 - kage.kMage * v;\r
+        }\r
+        else if(y1 == y2){\r
+          if(x1 < x2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2 - kage.kMage * v;\r
+          ty1 = y2;\r
+        }\r
+        else{\r
+          rad = Math.atan((y2 - y1) / (x2 - x1));\r
+          if(x1 < x2){ v = 1; } else{ v = -1; }\r
+          tx1 = x2 - kage.kMage * Math.cos(rad) * v;\r
+          ty1 = y2 - kage.kMage * Math.sin(rad) * v;\r
+        }\r
+        if(x2 == x3){\r
+          if(y2 < y3){ v = 1; } else{ v = -1; }\r
+          tx2 = x2;\r
+          ty2 = y2 + kage.kMage * v;\r
+        }\r
+        else if(y2 == y3){\r
+          if(x2 < x3){ v = 1; } else{ v = -1; }\r
+          tx2 = x2 + kage.kMage * v;\r
+          ty2 = y2;\r
+        }\r
+        else{\r
+          rad = Math.atan((y3 - y2) / (x3 - x2));\r
+          if(x2 < x3){ v = 1; } else{ v = -1; }\r
+          tx2 = x2 + kage.kMage * Math.cos(rad) * v;\r
+          ty2 = y2 + kage.kMage * Math.sin(rad) * v;\r
+        }\r
+        \r
+        cdDrawLine(kage, polygons, x1, y1, tx1, ty1, a2, 1);\r
+        cdDrawCurve(kage, polygons, tx1, ty1, x2, y2, tx2, ty2, 1, 1);\r
+        cdDrawLine(kage, polygons, tx2, ty2, x3, y3, 1, a3);\r
+      }\r
+      break;\r
+    case 6:\r
+      if(a3 == 5){\r
+        tx1 = x4 - kage.kMage;\r
+        ty1 = y4;\r
+        tx2 = x4 + kage.kMage * 0.5;\r
+        ty2 = y4 - kage.kMage * 2;\r
+        /*\r
+                               cdDrawCurve(x1, y1, x2, y2, (x2 + x3) / 2, (y2 + y3) / 2, a2, 1);\r
+                               cdDrawCurve((x2 + x3) / 2, (y2 + y3) / 2, x3, y3, tx1, ty1, 1, 1);\r
+         */\r
+        cdDrawBezier(kage, polygons, x1, y1, x2, y2, x3, y3, tx1, ty1, a2, 1);\r
+        cdDrawCurve(kage, polygons, tx1, ty1, x4, y4, tx2, ty2, 1, 0);\r
+      }\r
+      else{\r
+        /*\r
+                               cdDrawCurve(x1, y1, x2, y2, (x2 + x3) / 2, (y2 + y3) / 2, a2, 1);\r
+                               cdDrawCurve((x2 + x3) / 2, (y2 + y3) / 2, x3, y3, x4, y4, 1, a3);\r
+         */\r
+        cdDrawBezier(kage, polygons, x1, y1, x2, y2, x3, y3, x4, y4, a2, a3);\r
+      }\r
+      break;\r
+    case 7:\r
+      cdDrawLine(kage, polygons, x1, y1, x2, y2, a2, 1);\r
+      cdDrawCurve(kage, polygons, x2, y2, x3, y3, x4, y4, 1, a3);\r
+      break;\r
+    case 9: // may not be exist\r
+      //kageCanvas[y1][x1] = 0;\r
+      //kageCanvas[y2][x2] = 0;\r
+      break;\r
+    default:\r
+      break;\r
+    }\r
+  }\r
+}\r