Supports width adjustment of MAGE's tail.
[chise/kage.git] / engine / kagecd.js
1 function cdDrawCurveU(kage, polygons, x1, y1, sx1, sy1, sx2, sy2, x2, y2, ta1, ta2){\r
2   var rad, t;\r
3   var x, y, v;\r
4   var ix, iy, ia, ib, ir;\r
5   var tt;\r
6   var delta;\r
7   var deltad;\r
8   var XX, XY, YX, YY;\r
9   var poly, poly2;\r
10   var hosomi;\r
11   var kMinWidthT, kMinWidthT2;\r
12   var a1, a2, opt1, opt2, opt3, opt4;\r
13   \r
14   if(kage.kShotai == kage.kMincho){ // mincho\r
15     a1 = ta1 % 1000;\r
16     a2 = ta2 % 100;\r
17     opt1 = Math.floor((ta1 % 10000) / 1000);\r
18     opt2 = Math.floor((ta2 % 1000) / 100);\r
19     opt3 = Math.floor(ta1 / 10000);\r
20     opt4 = Math.floor(ta2 / 1000);\r
21     \r
22     kMinWidthT = kage.kMinWidthT - opt1 / 2;\r
23     kMinWidthT2 = kage.kMinWidthT - opt4 / 2;\r
24     \r
25     switch(a1 % 100){\r
26     case 0:\r
27     case 7:\r
28       delta = -1 * kage.kMinWidthY * 0.5;\r
29       break;\r
30     case 1:\r
31     case 2: // ... must be 32\r
32     case 6:\r
33     case 22:\r
34     case 32: // changed\r
35       delta = 0;\r
36       break;\r
37     case 12:\r
38     //case 32:\r
39       delta = kage.kMinWidthY;\r
40       break;\r
41     default:\r
42       break;\r
43     }\r
44     \r
45     if(x1 == sx1){\r
46       if(y1 < sy1){ y1 = y1 - delta; }\r
47       else{ y1 = y1 + delta; }\r
48     }\r
49     else if(y1 == sy1){\r
50       if(x1 < sx1){ x1 = x1 - delta; }\r
51       else{ x1 = x1 + delta; }\r
52     }\r
53     else{\r
54       rad = Math.atan((sy1 - y1) / (sx1 - x1));\r
55       if(x1 < sx1){ v = 1; } else{ v = -1; }\r
56       x1 = x1 - delta * Math.cos(rad) * v;\r
57       y1 = y1 - delta * Math.sin(rad) * v;\r
58     }\r
59     \r
60     switch(a2 % 100){\r
61     case 0:\r
62     case 1:\r
63     case 7:\r
64     case 9:\r
65     case 15: // it can change to 15->5\r
66     case 14: // it can change to 14->4\r
67     case 17: // no need\r
68     case 5:\r
69       delta = 0;\r
70       break;\r
71     case 8: // get shorten for tail's circle\r
72       delta = -1 * kMinWidthT * 0.5;\r
73       break;\r
74     default:\r
75       break;\r
76     }\r
77     \r
78     if(sx2 == x2){\r
79       if(sy2 < y2){ y2 = y2 + delta; }\r
80       else{ y2 = y2 - delta; }\r
81     }\r
82     else if(sy2 == y2){\r
83       if(sx2 < x2){ x2 = x2 + delta; }\r
84       else{ x2 = x2 - delta; }\r
85     }\r
86     else{\r
87       rad = Math.atan((y2 - sy2) / (x2 - sx2));\r
88       if(sx2 < x2){ v = 1; } else{ v = -1; }\r
89       x2 = x2 + delta * Math.cos(rad) * v;\r
90       y2 = y2 + delta * Math.sin(rad) * v;\r
91     }\r
92     \r
93     hosomi = 0.5;\r
94     if(Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) < 50){\r
95       hosomi += 0.4 * (1 - Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) / 50);\r
96     }\r
97     \r
98     //---------------------------------------------------------------\r
99     \r
100     poly = new Polygon();\r
101     poly2 = new Polygon();\r
102     \r
103     if(sx1 == sx2 && sy1 == sy2){ // Spline\r
104       if(kage.kUseCurve){\r
105         // generating fatten curve -- begin\r
106         var kage2 = new Kage();\r
107         kage2.kMinWidthY = kage.kMinWidthY;\r
108         kage2.kMinWidthT = kMinWidthT;\r
109         kage2.kWidth = kage.kWidth;\r
110         kage2.kKakato = kage.kKakato;\r
111         kage2.kRate = 10;\r
112         \r
113         var curve = new Array(2); // L and R\r
114         get_candidate(kage2, curve, a1, a2, x1, y1, sx1, sy1, x2, y2, opt3, opt4);\r
115         \r
116         var dcl12_34 = new Array(2);\r
117         var dcr12_34 = new Array(2);\r
118         var dpl12_34 = new Array(2);\r
119         var dpr12_34 = new Array(2);\r
120         divide_curve(kage2, x1, y1, sx1, sy1, x2, y2, curve[0], dcl12_34, dpl12_34);\r
121         divide_curve(kage2, x1, y1, sx1, sy1, x2, y2, curve[1], dcr12_34, dpr12_34);\r
122         \r
123         var ncl1 = new Array(7);\r
124         var ncl2 = new Array(7);\r
125         find_offcurve(kage2, dcl12_34[0], dpl12_34[0][2], dpl12_34[0][3], ncl1);\r
126         find_offcurve(kage2, dcl12_34[1], dpl12_34[1][2], dpl12_34[1][3], ncl2);\r
127         \r
128         poly.push(ncl1[0], ncl1[1]);\r
129         poly.push(ncl1[2], ncl1[3], 1);\r
130         poly.push(ncl1[4], ncl1[5]);\r
131         poly.push(ncl2[2], ncl2[3], 1);\r
132         poly.push(ncl2[4], ncl2[5]);\r
133         \r
134         poly2.push(dcr12_34[0][0][0], dcr12_34[0][0][1]);\r
135         poly2.push(dpr12_34[0][2] - (ncl1[2] - dpl12_34[0][2]), dpl12_34[0][3] - (ncl1[3] - dpl12_34[0][3]), 1);\r
136         poly2.push(dcr12_34[0][dcr12_34[0].length - 1][0], dcr12_34[0][dcr12_34[0].length - 1][1]);\r
137         poly2.push(dpr12_34[1][2] - (ncl2[2] - dpl12_34[1][2]), dpl12_34[1][3] - (ncl2[3] - dpl12_34[1][3]), 1);\r
138         poly2.push(dcr12_34[1][dcr12_34[1].length - 1][0], dcr12_34[1][dcr12_34[1].length - 1][1]);\r
139         \r
140         poly2.reverse();\r
141         poly.concat(poly2);\r
142         polygons.push(poly);\r
143         // generating fatten curve -- end\r
144       } else {\r
145         for(tt = 0; tt <= 1000; tt = tt + kage.kRate){\r
146           t = tt / 1000;\r
147           \r
148           // calculate a dot\r
149           x = ((1.0 - t) * (1.0 - t) * x1 + 2.0 * t * (1.0 - t) * sx1 + t * t * x2);\r
150           y = ((1.0 - t) * (1.0 - t) * y1 + 2.0 * t * (1.0 - t) * sy1 + t * t * y2);\r
151           \r
152           // KATAMUKI of vector by BIBUN\r
153           ix = (x1 - 2.0 * sx1 + x2) * 2.0 * t + (-2.0 * x1 + 2.0 * sx1);\r
154           iy = (y1 - 2.0 * sy1 + y2) * 2.0 * t + (-2.0 * y1 + 2.0 * sy1);\r
155           \r
156           // line SUICHOKU by vector\r
157           if(ix != 0 && iy != 0){\r
158             ir = Math.atan(iy / ix * -1);\r
159             ia = Math.sin(ir) * (kMinWidthT);\r
160             ib = Math.cos(ir) * (kMinWidthT);\r
161           }\r
162           else if(ix == 0){\r
163             ia = kMinWidthT;\r
164             ib = 0;\r
165           }\r
166           else{\r
167             ia = 0;\r
168             ib = kMinWidthT;\r
169           }\r
170           \r
171           if(a1 == 7 && a2 == 0){ // L2RD: fatten\r
172             deltad = Math.pow(t, hosomi) * kage.kL2RDfatten;\r
173           }\r
174           else if(a1 == 7){\r
175             deltad = Math.pow(t, hosomi);\r
176           }\r
177           else if(a2 == 7){\r
178             deltad = Math.pow(1.0 - t, hosomi);\r
179           }\r
180           else if(opt3 > 0 || opt4 > 0){\r
181               deltad = ((kage.kMinWidthT - opt3 / 2) - (opt4 - opt3) / 2 * t) / kage.kMinWidthT;\r
182           }\r
183           else{ deltad = 1; }\r
184           \r
185           if(deltad < 0.15){\r
186             deltad = 0.15;\r
187           }\r
188           ia = ia * deltad;\r
189           ib = ib * deltad;\r
190           \r
191           //reverse if vector is going 2nd/3rd quadrants\r
192           if(ix <= 0){\r
193             ia = ia * -1;\r
194             ib = ib * -1;\r
195           }\r
196           \r
197           //copy to polygon structure\r
198           poly.push(x - ia, y - ib);\r
199           poly2.push(x + ia, y + ib);\r
200         }\r
201         \r
202         // suiheisen ni setsuzoku\r
203         if(a1 == 132){\r
204           var index = 0;\r
205           while(true){\r
206             if(poly2.array[index].y <= y1 && y1 <= poly2.array[index + 1].y){\r
207               break;\r
208             }\r
209             index++;\r
210           }\r
211           newx1 = poly2.array[index + 1].x + (poly2.array[index].x - poly2.array[index + 1].x) *\r
212             (poly2.array[index + 1].y - y1) / (poly2.array[index + 1].y - poly2.array[index].y);\r
213           newy1 = y1;\r
214           newx2 = poly.array[0].x + (poly.array[0].x - poly.array[1].x) * (poly.array[0].y - y1) /\r
215             (poly.array[1].y - poly.array[0].y);\r
216           newy2 = y1;\r
217           \r
218           for(var i = 0; i < index; i++){\r
219             poly2.shift();\r
220           }\r
221           poly2.set(0, newx1, newy1);\r
222           poly.unshift(newx2, newy2);\r
223         }\r
224         \r
225         // suiheisen ni setsuzoku 2\r
226         if(a1 == 22 && y1 > y2){\r
227           var index = 0;\r
228           while(true){\r
229             if(poly2.array[index].y <= y1 && y1 <= poly2.array[index + 1].y){\r
230               break;\r
231             }\r
232             index++;\r
233           }\r
234           newx1 = poly2.array[index + 1].x + (poly2.array[index].x - poly2.array[index + 1].x) *\r
235             (poly2.array[index + 1].y - y1) / (poly2.array[index + 1].y - poly2.array[index].y);\r
236           newy1 = y1;\r
237           newx2 = poly.array[0].x + (poly.array[0].x - poly.array[1].x - 1) * (poly.array[0].y - y1) /\r
238             (poly.array[1].y - poly.array[0].y);\r
239           newy2 = y1 + 1;\r
240           \r
241           for(var i = 0; i < index; i++){\r
242             poly2.shift();\r
243           }\r
244           poly2.set(0, newx1, newy1);\r
245           poly.unshift(newx2, newy2);\r
246         }\r
247         \r
248         poly2.reverse();\r
249         poly.concat(poly2);\r
250         polygons.push(poly);\r
251       }\r
252     } else { // Bezier\r
253       for(tt = 0; tt <= 1000; tt = tt + kage.kRate){\r
254         t = tt / 1000;\r
255         \r
256         // calculate a dot\r
257         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
258         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
259         // KATAMUKI of vector by BIBUN\r
260         ix = t * t * (-3 * x1 + 9 * sx1 + -9 * sx2 + 3 * x2) + t * (6 * x1 + -12 * sx1 + 6 * sx2) + -3 * x1 + 3 * sx1;\r
261         iy = t * t * (-3 * y1 + 9 * sy1 + -9 * sy2 + 3 * y2) + t * (6 * y1 + -12 * sy1 + 6 * sy2) + -3 * y1 + 3 * sy1;\r
262         \r
263         // line SUICHOKU by vector\r
264         if(ix != 0 && iy != 0){\r
265           ir = Math.atan(iy / ix * -1);\r
266           ia = Math.sin(ir) * (kMinWidthT);\r
267           ib = Math.cos(ir) * (kMinWidthT);\r
268         }\r
269         else if(ix == 0){\r
270           ia = kMinWidthT;\r
271           ib = 0;\r
272         }\r
273         else{\r
274           ia = 0;\r
275           ib = kMinWidthT;\r
276         }\r
277         \r
278         if(a1 == 7 && a2 == 0){ // L2RD: fatten\r
279           deltad = Math.pow(t, hosomi) * kage.kL2RDfatten;\r
280         }\r
281         else if(a1 == 7){\r
282           deltad = Math.pow(t, hosomi);\r
283           deltad = Math.pow(deltad, 0.7); // make fatten\r
284         }\r
285         else if(a2 == 7){\r
286           deltad = Math.pow(1.0 - t, hosomi);\r
287         }\r
288         else{ deltad = 1; }\r
289         \r
290         if(deltad < 0.15){\r
291           deltad = 0.15;\r
292         }\r
293         ia = ia * deltad;\r
294         ib = ib * deltad;\r
295         \r
296         //reverse if vector is going 2nd/3rd quadrants\r
297         if(ix <= 0){\r
298           ia = ia * -1;\r
299           ib = ib * -1;\r
300         }\r
301         \r
302         //copy to polygon structure\r
303         poly.push(x - ia, y - ib);\r
304         poly2.push(x + ia, y + ib);\r
305       }\r
306       \r
307       // suiheisen ni setsuzoku\r
308       if(a1 == 132){\r
309         var index = 0;\r
310         while(true){\r
311           if(poly2.array[index].y <= y1 && y1 <= poly2.array[index + 1].y){\r
312             break;\r
313           }\r
314           index++;\r
315         }\r
316         newx1 = poly2.array[index + 1].x + (poly2.array[index].x - poly2.array[index + 1].x) *\r
317           (poly2.array[index + 1].y - y1) / (poly2.array[index + 1].y - poly2.array[index].y);\r
318         newy1 = y1;\r
319         newx2 = poly.array[0].x + (poly.array[0].x - poly.array[1].x) * (poly.array[0].y - y1) /\r
320           (poly.array[1].y - poly.array[0].y);\r
321         newy2 = y1;\r
322         \r
323         for(var i = 0; i < index; i++){\r
324           poly2.shift();\r
325         }\r
326         poly2.set(0, newx1, newy1);\r
327         poly.unshift(newx2, newy2);\r
328       }\r
329       \r
330       // suiheisen ni setsuzoku 2\r
331       if(a1 == 22){\r
332         var index = 0;\r
333         while(true){\r
334           if(poly2.array[index].y <= y1 && y1 <= poly2.array[index + 1].y){\r
335             break;\r
336           }\r
337           index++;\r
338         }\r
339         newx1 = poly2.array[index + 1].x + (poly2.array[index].x - poly2.array[index + 1].x) *\r
340           (poly2.array[index + 1].y - y1) / (poly2.array[index + 1].y - poly2.array[index].y);\r
341         newy1 = y1;\r
342         newx2 = poly.array[0].x + (poly.array[0].x - poly.array[1].x - 1) * (poly.array[0].y - y1) /\r
343           (poly.array[1].y - poly.array[0].y);\r
344         newy2 = y1 + 1;\r
345         \r
346         for(var i = 0; i < index; i++){\r
347           poly2.shift();\r
348         }\r
349         poly2.set(0, newx1, newy1);\r
350         poly.unshift(newx2, newy2);\r
351       }\r
352       \r
353       poly2.reverse();\r
354       poly.concat(poly2);\r
355       polygons.push(poly);\r
356     }\r
357     \r
358     //process for head of stroke\r
359     rad = Math.atan((sy1 - y1) / (sx1 - x1));\r
360     if(x1 < sx1){ v = 1; } else{ v = -1; }\r
361     XX = Math.sin(rad) * v;\r
362     XY = Math.cos(rad) * v * -1;\r
363     YX = Math.cos(rad) * v;\r
364     YY = Math.sin(rad) * v;\r
365     \r
366     if(a1 == 12){\r
367       if(x1 == x2){\r
368         poly= new Polygon();\r
369         poly.push(x1 - kMinWidthT, y1);\r
370         poly.push(x1 + kMinWidthT, y1);\r
371         poly.push(x1 - kMinWidthT, y1 - kMinWidthT);\r
372         polygons.push(poly);\r
373       }\r
374       else{\r
375         poly = new Polygon();\r
376         poly.push(x1 - kMinWidthT * XX, y1 - kMinWidthT * XY);\r
377         poly.push(x1 + kMinWidthT * XX, y1 + kMinWidthT * XY);\r
378         poly.push(x1 - kMinWidthT * XX - kMinWidthT * YX, y1 - kMinWidthT * XY - kMinWidthT * YY);\r
379         polygons.push(poly);\r
380       }\r
381     }\r
382     \r
383     var type;\r
384     var pm = 0;\r
385     if(a1 == 0){\r
386       if(y1 <= y2){ //from up to bottom\r
387         type = (Math.atan2(Math.abs(y1 - sy1), Math.abs(x1 - sx1)) / Math.PI * 2 - 0.4);\r
388         if(type > 0){\r
389           type = type * 2;\r
390         } else {\r
391           type = type * 16;\r
392         }\r
393         if(type < 0){\r
394           pm = -1;\r
395         } else {\r
396           pm = 1;\r
397         }\r
398         if(x1 == sx1){\r
399           poly = new Polygon();\r
400           poly.push(x1 - kMinWidthT, y1 + 1);\r
401           poly.push(x1 + kMinWidthT, y1);\r
402           poly.push(x1 - kMinWidthT * pm, y1 - kage.kMinWidthY * type * pm);\r
403           polygons.push(poly);\r
404         }\r
405         else{\r
406           poly = new Polygon();\r
407           poly.push(x1 - kMinWidthT * XX + 1 * YX, y1 - kMinWidthT * XY + 1 * YY);\r
408           poly.push(x1 + kMinWidthT * XX, y1 + kMinWidthT * XY);\r
409           poly.push(x1 - kMinWidthT * pm * XX - kage.kMinWidthY * type * pm * YX, y1 - kMinWidthT * pm * XY - kage.kMinWidthY * type * pm * YY);\r
410           polygons.push(poly);\r
411         }\r
412       }\r
413       else{ //bottom to up\r
414         if(x1 == sx1){\r
415           poly = new Polygon();\r
416           poly.push(x1 - kMinWidthT, y1);\r
417           poly.push(x1 + kMinWidthT, y1);\r
418           poly.push(x1 + kMinWidthT, y1 - kage.kMinWidthY);\r
419           polygons.push(poly);\r
420         }\r
421         else{\r
422           poly = new Polygon();\r
423           poly.push(x1 - kMinWidthT * XX, y1 - kMinWidthT * XY);\r
424           poly.push(x1 + kMinWidthT * XX, y1 + kMinWidthT * XY);\r
425           poly.push(x1 + kMinWidthT * XX - kage.kMinWidthY * YX, y1 + kMinWidthT * XY - kage.kMinWidthY * YY);\r
426           polygons.push(poly);\r
427         }\r
428       }\r
429     }\r
430     \r
431     if(a1 == 22){ //box's up-right corner, any time same degree\r
432       poly = new Polygon();\r
433       poly.push(x1 - kMinWidthT, y1 - kage.kMinWidthY);\r
434       poly.push(x1, y1 - kage.kMinWidthY - kage.kWidth);\r
435       poly.push(x1 + kMinWidthT + kage.kWidth, y1 + kage.kMinWidthY);\r
436       poly.push(x1 + kMinWidthT, y1 + kMinWidthT - 1);\r
437       poly.push(x1 - kMinWidthT, y1 + kMinWidthT + 4);\r
438       polygons.push(poly);\r
439     }\r
440     \r
441     if(a1 == 0){ //beginning of the stroke\r
442       if(y1 <= y2){ //from up to bottom\r
443         if(pm > 0){\r
444           type = 0;\r
445         }\r
446         var move = kage.kMinWidthY * type * pm;\r
447         if(x1 == sx1){\r
448           poly = new Polygon();\r
449           poly.push(x1 + kMinWidthT, y1 - move);\r
450           poly.push(x1 + kMinWidthT * 1.5, y1 + kage.kMinWidthY - move);\r
451           poly.push(x1 + kMinWidthT - 2, y1 + kage.kMinWidthY * 2 + 1);\r
452           polygons.push(poly);\r
453         }\r
454         else{\r
455           poly = new Polygon();\r
456           poly.push(x1 + kMinWidthT * XX - move * YX,\r
457                     y1 + kMinWidthT * XY - move * YY);\r
458           poly.push(x1 + kMinWidthT * 1.5 * XX + (kage.kMinWidthY - move * 1.2) * YX,\r
459                     y1 + kMinWidthT * 1.5 * XY + (kage.kMinWidthY - move * 1.2) * YY);\r
460           poly.push(x1 + (kMinWidthT - 2) * XX + (kage.kMinWidthY * 2 - move * 0.8 + 1) * YX,\r
461                     y1 + (kMinWidthT - 2) * XY + (kage.kMinWidthY * 2 - move * 0.8 + 1) * YY);\r
462           polygons.push(poly);\r
463         }\r
464       }\r
465       else{ //from bottom to up\r
466         if(x1 == sx1){\r
467           poly = new Polygon();\r
468           poly.push(x1 - kMinWidthT, y1);\r
469           poly.push(x1 - kMinWidthT * 1.5, y1 + kage.kMinWidthY);\r
470           poly.push(x1 - kMinWidthT * 0.5, y1 + kage.kMinWidthY * 3);\r
471           polygons.push(poly);\r
472         }\r
473         else{\r
474           poly = new Polygon();\r
475           poly.push(x1 - kMinWidthT * XX, y1 - kMinWidthT * XY);\r
476           poly.push(x1 - kMinWidthT * 1.5 * XX + kage.kMinWidthY * YX, y1 + kage.kMinWidthY * YY - kMinWidthT * 1.5 * XY);\r
477           poly.push(x1 - kMinWidthT * 0.5 * XX + kage.kMinWidthY * 3 * YX, y1 + kage.kMinWidthY * 3 * YY - kMinWidthT * 0.5 * XY);\r
478           polygons.push(poly);\r
479         }\r
480       }\r
481     }\r
482     \r
483     //process for tail\r
484     rad = Math.atan((y2 - sy2) / (x2 - sx2));\r
485     if(sx2 < x2){ v = 1; } else{ v = -1; }\r
486     YX = Math.sin(rad) * v * -1;\r
487     YY = Math.cos(rad) * v;\r
488     XX = Math.cos(rad) * v;\r
489     XY = Math.sin(rad) * v;\r
490     \r
491     if(a2 == 1 || a2 == 8 || a2 == 15){ //the last filled circle ... it can change 15->5\r
492       if(sx2 == x2){\r
493         poly = new Polygon();\r
494         if(kage.kUseCurve){\r
495           // by curve path\r
496           poly.push(x2 - kMinWidthT2, y2);\r
497           poly.push(x2 - kMinWidthT2 * 0.9, y2 + kMinWidthT2 * 0.9, 1);\r
498           poly.push(x2, y2 + kMinWidthT2);\r
499           poly.push(x2 + kMinWidthT2 * 0.9, y2 + kMinWidthT2 * 0.9, 1);\r
500           poly.push(x2 + kMinWidthT2, y2);\r
501         } else {\r
502           // by polygon\r
503           poly.push(x2 - kMinWidthT2, y2);\r
504           poly.push(x2 - kMinWidthT2 * 0.7, y2 + kMinWidthT2 * 0.7);\r
505           poly.push(x2, y2 + kMinWidthT2);\r
506           poly.push(x2 + kMinWidthT2 * 0.7, y2 + kMinWidthT2 * 0.7);\r
507           poly.push(x2 + kMinWidthT2, y2);\r
508         }\r
509         polygons.push(poly);\r
510       }\r
511       else if(sy2 == y2){\r
512         poly = new Polygon();\r
513         if(kage.kUseCurve){\r
514           // by curve path\r
515           poly.push(x2, y2 - kMinWidthT2);\r
516           poly.push(x2 + kMinWidthT2 * 0.9, y2 - kMinWidthT2 * 0.9, 1);\r
517           poly.push(x2 + kMinWidthT2, y2);\r
518           poly.push(x2 + kMinWidthT2 * 0.9, y2 + kMinWidthT2 * 0.9, 1);\r
519           poly.push(x2, y2 + kMinWidthT2);\r
520         } else {\r
521           // by polygon\r
522           poly.push(x2, y2 - kMinWidthT2);\r
523           poly.push(x2 + kMinWidthT2 * 0.7, y2 - kMinWidthT2 * 0.7);\r
524           poly.push(x2 + kMinWidthT2, y2);\r
525           poly.push(x2 + kMinWidthT2 * 0.7, y2 + kMinWidthT2 * 0.7);\r
526           poly.push(x2, y2 + kMinWidthT2);\r
527         }\r
528         polygons.push(poly);\r
529       }\r
530       else{\r
531         poly = new Polygon();\r
532         if(kage.kUseCurve){\r
533           poly.push(x2 + Math.sin(rad) * kMinWidthT2 * v, y2 - Math.cos(rad) * kMinWidthT2 * v);\r
534           poly.push(x2 + Math.cos(rad) * kMinWidthT2 * 0.9 * v + Math.sin(rad) * kMinWidthT2 * 0.9 * v,\r
535                     y2 + Math.sin(rad) * kMinWidthT2 * 0.9 * v - Math.cos(rad) * kMinWidthT2 * 0.9 * v, 1);\r
536           poly.push(x2 + Math.cos(rad) * kMinWidthT2 * v, y2 + Math.sin(rad) * kMinWidthT2 * v);\r
537           poly.push(x2 + Math.cos(rad) * kMinWidthT2 * 0.9 * v - Math.sin(rad) * kMinWidthT2 * 0.9 * v,\r
538                     y2 + Math.sin(rad) * kMinWidthT2 * 0.9 * v + Math.cos(rad) * kMinWidthT2 * 0.9 * v, 1);\r
539           poly.push(x2 - Math.sin(rad) * kMinWidthT2 * v, y2 + Math.cos(rad) * kMinWidthT2 * v);\r
540         } else {\r
541           poly.push(x2 + Math.sin(rad) * kMinWidthT2 * v, y2 - Math.cos(rad) * kMinWidthT2 * v);\r
542           poly.push(x2 + Math.cos(rad) * kMinWidthT2 * 0.7 * v + Math.sin(rad) * kMinWidthT2 * 0.7 * v,\r
543                     y2 + Math.sin(rad) * kMinWidthT2 * 0.7 * v - Math.cos(rad) * kMinWidthT2 * 0.7 * v);\r
544           poly.push(x2 + Math.cos(rad) * kMinWidthT2 * v, y2 + Math.sin(rad) * kMinWidthT2 * v);\r
545           poly.push(x2 + Math.cos(rad) * kMinWidthT2 * 0.7 * v - Math.sin(rad) * kMinWidthT2 * 0.7 * v,\r
546                     y2 + Math.sin(rad) * kMinWidthT2 * 0.7 * v + Math.cos(rad) * kMinWidthT2 * 0.7 * v);\r
547           poly.push(x2 - Math.sin(rad) * kMinWidthT2 * v, y2 + Math.cos(rad) * kMinWidthT2 * v);\r
548         }\r
549         polygons.push(poly);\r
550       }\r
551     }\r
552     \r
553     if(a2 == 9 || (a1 == 7 && a2 == 0)){ // Math.sinnyu & L2RD Harai ... no need for a2=9\r
554       var type = (Math.atan2(Math.abs(y2 - sy2), Math.abs(x2 - sx2)) / Math.PI * 2 - 0.6);\r
555       if(type > 0){\r
556         type = type * 8;\r
557       } else {\r
558         type = type * 3;\r
559       }\r
560       var pm = 0;\r
561       if(type < 0){\r
562         pm = -1;\r
563       } else {\r
564         pm = 1;\r
565       }\r
566       if(sy2 == y2){\r
567         poly = new Polygon();\r
568         poly.push(x2, y2 + kMinWidthT * kage.kL2RDfatten);\r
569         poly.push(x2, y2 - kMinWidthT * kage.kL2RDfatten);\r
570         poly.push(x2 + kMinWidthT * kage.kL2RDfatten * Math.abs(type), y2 + kMinWidthT * kage.kL2RDfatten * pm);\r
571         polygons.push(poly);\r
572       }\r
573       else{\r
574         poly = new Polygon();\r
575         poly.push(x2 + kMinWidthT * kage.kL2RDfatten * YX, y2 + kMinWidthT * kage.kL2RDfatten * YY);\r
576         poly.push(x2 - kMinWidthT * kage.kL2RDfatten * YX, y2 - kMinWidthT * kage.kL2RDfatten * YY);\r
577         poly.push(x2 + kMinWidthT * kage.kL2RDfatten * Math.abs(type) * XX + kMinWidthT * kage.kL2RDfatten * pm * YX,\r
578                   y2 + kMinWidthT * kage.kL2RDfatten * Math.abs(type) * XY + kMinWidthT * kage.kL2RDfatten * pm * YY);\r
579         polygons.push(poly);\r
580       }\r
581     }\r
582     \r
583     if(a2 == 15){ //jump up ... it can change 15->5\r
584       // anytime same degree\r
585       poly = new Polygon();\r
586       poly.push(x2, y2 - kMinWidthT + 1);\r
587       poly.push(x2 + 2, y2 - kMinWidthT - kage.kWidth * 5);\r
588       poly.push(x2, y2 - kMinWidthT - kage.kWidth * 5);\r
589       poly.push(x2 - kMinWidthT, y2 - kMinWidthT + 1);\r
590       polygons.push(poly);\r
591     }\r
592     \r
593     if(a2 == 14){ //jump to left, allways go left\r
594       poly = new Polygon();\r
595       poly.push(x2, y2);\r
596       poly.push(x2, y2 - kMinWidthT);\r
597       poly.push(x2 - kage.kWidth * 4 * Math.pow(kMinWidthT / kage.kMinWidthT, 3), y2 - kMinWidthT);\r
598       poly.push(x2 - kage.kWidth * 4 * Math.pow(kMinWidthT / kage.kMinWidthT, 3), y2 - kMinWidthT * 0.5);\r
599       polygons.push(poly);\r
600     }\r
601   }\r
602   else{ //gothic\r
603     if(a1 % 10 == 2){\r
604       if(x1 == sx1){\r
605         if(y1 < sy1){ y1 = y1 - kage.kWidth; } else{ y1 = y1 + kage.kWidth; }\r
606       }\r
607       else if(y1 == sy1){\r
608         if(x1 < sx1){ x1 = x1 - kage.kWidth; } else{ x1 = x1 + kage.kWidth; }\r
609       }\r
610       else{\r
611         rad = Math.atan((sy1 - y1) / (sx1 - x1));\r
612         if(x1 < sx1){ v = 1; } else{ v = -1; }\r
613         x1 = x1 - kage.kWidth * Math.cos(rad) * v;\r
614         y1 = y1 - kage.kWidth * Math.sin(rad) * v;\r
615       }\r
616     }\r
617     \r
618     if(a1 % 10 == 3){\r
619       if(x1 == sx1){\r
620         if(y1 < sy1){\r
621           y1 = y1 - kage.kWidth * kage.kKakato;\r
622         }\r
623         else{\r
624           y1 = y1 + kage.kWidth * kage.kKakato;\r
625         }\r
626       }\r
627       else if(y1 == sy1){\r
628         if(x1 < sx1){\r
629           x1 = x1 - kage.kWidth * kage.kKakato;\r
630         }\r
631         else{\r
632           x1 = x1 + kage.kWidth * kage.kKakato;\r
633         }\r
634       }\r
635       else{\r
636         rad = Math.atan((sy1 - y1) / (sx1 - x1));\r
637         if(x1 < sx1){ v = 1; } else{ v = -1; }\r
638         x1 = x1 - kage.kWidth * Math.cos(rad) * v * kage.kKakato;\r
639         y1 = y1 - kage.kWidth * Math.sin(rad) * v * kage.kKakato;\r
640       }\r
641     }\r
642     if(a2 % 10 == 2){\r
643       if(sx2 == x2){\r
644         if(sy2 < y2){ y2 = y2 + kage.kWidth; } else{ y2 = y2 - kage.kWidth; }\r
645       }\r
646       else if(sy2 == y2){\r
647         if(sx2 < x2){ x2 = x2 + kage.kWidth; } else{ x2 = x2 - kage.kWidth; }\r
648       }\r
649       else{\r
650         rad = Math.atan((y2 - sy2) / (x2 - sx2));\r
651         if(sx2 < x2){ v = 1; } else{ v = -1; }\r
652         x2 = x2 + kage.kWidth * Math.cos(rad) * v;\r
653         y2 = y2 + kage.kWidth * Math.sin(rad) * v;\r
654       }\r
655     }\r
656     \r
657     if(a2 % 10 == 3){\r
658       if(sx2 == x2){\r
659         if(sy2 < y2){\r
660           y2 = y2 + kage.kWidth * kage.kKakato;\r
661         }\r
662         else{\r
663           y2 = y2 - kage.kWidth * kage.kKakato;\r
664         }\r
665       }\r
666       else if(sy2 == y2){\r
667         if(sx2 < x2){\r
668           x2 = x2 + kage.kWidth * kage.kKakato;\r
669         }\r
670         else{\r
671           x2 = x2 - kage.kWidth * kage.kKakato;\r
672         }\r
673       }\r
674       else{\r
675         rad = Math.atan((y2 - sy2) / (x2 - sx2));\r
676         if(sx2 < x2){ v = 1; } else{ v = -1; }\r
677         x2 = x2 + kage.kWidth * Math.cos(rad) * v * kage.kKakato;\r
678         y2 = y2 + kage.kWidth * Math.sin(rad) * v * kage.kKakato;\r
679       }\r
680     }\r
681     \r
682     poly = new Polygon();\r
683     poly2 = new Polygon();\r
684     \r
685     for(tt = 0; tt <= 1000; tt = tt + kage.kRate){\r
686       t = tt / 1000;\r
687       \r
688       if(sx1 == sx2 && sy1 == sy2){\r
689         //calculating each point\r
690         x = ((1.0 - t) * (1.0 - t) * x1 + 2.0 * t * (1.0 - t) * sx1 + t * t * x2);\r
691         y = ((1.0 - t) * (1.0 - t) * y1 + 2.0 * t * (1.0 - t) * sy1 + t * t * y2);\r
692         \r
693         //SESSEN NO KATAMUKI NO KEISAN(BIBUN)\r
694         ix = (x1 - 2.0 * sx1 + x2) * 2.0 * t + (-2.0 * x1 + 2.0 * sx1);\r
695         iy = (y1 - 2.0 * sy1 + y2) * 2.0 * t + (-2.0 * y1 + 2.0 * sy1);\r
696       } else {\r
697       }\r
698       //SESSEN NI SUICHOKU NA CHOKUSEN NO KEISAN\r
699       if(kage.kShotai == kage.kMincho){ //always false ?\r
700         if(ix != 0 && iy != 0){\r
701           ir = Math.atan(iy / ix * -1.0);\r
702           ia = Math.sin(ir) * kage.kMinWidthT;\r
703           ib = Math.cos(ir) * kage.kMinWidthT;\r
704         }\r
705         else if(ix == 0){\r
706           ia = kage.kMinWidthT;\r
707           ib = 0;\r
708         }\r
709         else{\r
710           ia = 0;\r
711           ib = kage.kMinWidthT;\r
712         }\r
713         ia = ia * Math.sqrt(1.0 - t);\r
714         ib = ib * Math.sqrt(1.0 - t);\r
715       }\r
716       else{\r
717         if(ix != 0 && iy != 0){\r
718           ir = Math.atan(iy / ix * -1.0);\r
719           ia = Math.sin(ir) * kage.kWidth;\r
720           ib = Math.cos(ir) * kage.kWidth;\r
721         }\r
722         else if(ix == 0){\r
723           ia = kage.kWidth;\r
724           ib = 0;\r
725         }\r
726         else{\r
727           ia = 0;\r
728           ib = kage.kWidth;\r
729         }\r
730       }\r
731       \r
732       //reverse if vector is going 2nd/3rd quadrants\r
733       if(ix <= 0){\r
734         ia = ia * -1;\r
735         ib = ib * -1;\r
736       }\r
737       \r
738       //save to polygon\r
739       poly.push(x - ia, y - ib);\r
740       poly2.push(x + ia, y + ib);\r
741     }\r
742     \r
743     poly2.reverse();\r
744     poly.concat(poly2);\r
745     polygons.push(poly);\r
746   }\r
747 }\r
748 \r
749 function cdDrawBezier(kage, polygons, x1, y1, x2, y2, x3, y3, x4, y4, a1, a2){\r
750   cdDrawCurveU(kage, polygons, x1, y1, x2, y2, x3, y3, x4, y4, a1, a2);\r
751 }\r
752 \r
753 function cdDrawCurve(kage, polygons, x1, y1, x2, y2, x3, y3, a1, a2){\r
754   cdDrawCurveU(kage, polygons, x1, y1, x2, y2, x2, y2, x3, y3, a1, a2);\r
755 }\r
756 \r
757 function cdDrawLine(kage, polygons, tx1, ty1, tx2, ty2, ta1, ta2){\r
758   var rad;\r
759   var v, x1, y1, x2, y2;\r
760   var a1, a2, opt1, opt2;\r
761   var XX, XY, YX, YY;\r
762   var poly;\r
763   var kMinWidthT;\r
764   \r
765   if(kage.kShotai == kage.kMincho){ //mincho\r
766     x1 = tx1;\r
767     y1 = ty1;\r
768     x2 = tx2;\r
769     y2 = ty2;\r
770     a1 = ta1 % 1000;\r
771     a2 = ta2 % 100;\r
772     opt1 = Math.floor(ta1 / 1000);\r
773     opt2 = Math.floor(ta2 / 100);\r
774     \r
775     kMinWidthT = kage.kMinWidthT - opt1 / 2;\r
776     \r
777     if(x1 == x2){ //if TATE stroke, use y-axis\r
778       poly = new Polygon(4);\r
779       switch(a1){\r
780       case 0:\r
781         poly.set(3, x1 - kMinWidthT, y1 - kage.kMinWidthY / 2);\r
782         poly.set(0, x1 + kMinWidthT, y1 + kage.kMinWidthY / 2);\r
783         break;\r
784       case 1:\r
785       case 6: //... no need\r
786       case 22:\r
787         poly.set(3, x1 - kMinWidthT, y1);\r
788         poly.set(0, x1 + kMinWidthT, y1);\r
789         break;\r
790       case 12:\r
791         poly.set(3, x1 - kMinWidthT, y1 - kage.kMinWidthY - kMinWidthT);\r
792         poly.set(0, x1 + kMinWidthT, y1 - kage.kMinWidthY);\r
793         break;\r
794       case 32:\r
795         poly.set(3, x1 - kMinWidthT, y1 - kage.kMinWidthY);\r
796         poly.set(0, x1 + kMinWidthT, y1 - kage.kMinWidthY);\r
797         break;\r
798       }\r
799       \r
800       switch(a2){\r
801       case 0:\r
802         if(a1 == 6){ //KAGI's tail ... no need\r
803           poly.set(2, x2 - kMinWidthT, y2);\r
804           poly.set(1, x2 + kMinWidthT, y2);\r
805         }\r
806         else{\r
807           poly.set(2, x2 - kMinWidthT, y2 + kMinWidthT / 2);\r
808           poly.set(1, x2 + kMinWidthT, y2 - kMinWidthT / 2);\r
809         }\r
810         break;\r
811       case 1:\r
812         poly.set(2, x2 - kMinWidthT, y2);\r
813         poly.set(1, x2 + kMinWidthT, y2);\r
814         break;\r
815       case 13:\r
816         poly.set(2, x2 - kMinWidthT, y2 + kage.kAdjustKakatoL[opt2] + kMinWidthT);\r
817         poly.set(1, x2 + kMinWidthT, y2 + kage.kAdjustKakatoL[opt2]);\r
818         break;\r
819       case 23:\r
820         poly.set(2, x2 - kMinWidthT, y2 + kage.kAdjustKakatoR[opt2] + kMinWidthT);\r
821         poly.set(1, x2 + kMinWidthT, y2 + kage.kAdjustKakatoR[opt2]);\r
822         break;\r
823       case 32:\r
824         poly.set(2, x2 - kMinWidthT, y2 + kage.kMinWidthY);\r
825         poly.set(1, x2 + kMinWidthT, y2 + kage.kMinWidthY);\r
826         break;\r
827       }\r
828       \r
829       polygons.push(poly);\r
830       \r
831       if(a1 == 22){ //box's right top corner\r
832         poly = new Polygon();\r
833         poly.push(x1 - kMinWidthT, y1 - kage.kMinWidthY);\r
834         poly.push(x1, y1 - kage.kMinWidthY - kage.kWidth);\r
835         poly.push(x1 + kMinWidthT + kage.kWidth, y1 + kage.kMinWidthY);\r
836         poly.push(x1 + kMinWidthT, y1 + kMinWidthT);\r
837         poly.push(x1 - kMinWidthT, y1);\r
838         polygons.push(poly);\r
839       }\r
840       \r
841       if(a1 == 0){ //beginning of the stroke\r
842         poly = new Polygon();\r
843         poly.push(x1 + kMinWidthT, y1 + kage.kMinWidthY * 0.5);\r
844         poly.push(x1 + kMinWidthT + kMinWidthT * 0.5, y1 + kage.kMinWidthY * 0.5 + kage.kMinWidthY);\r
845         poly.push(x1 + kMinWidthT - 2, y1 + kage.kMinWidthY * 0.5 + kage.kMinWidthY * 2 + 1);\r
846         polygons.push(poly);\r
847       }\r
848       \r
849       if((a1 == 6 && a2 == 0) || a2 == 1){ //KAGI NO YOKO BOU NO SAIGO NO MARU ... no need only used at 1st=yoko\r
850         poly = new Polygon();\r
851         if(kage.kUseCurve){\r
852           poly.push(x2 - kMinWidthT, y2);\r
853           poly.push(x2 - kMinWidthT * 0.9, y2 + kMinWidthT * 0.9, 1);\r
854           poly.push(x2, y2 + kMinWidthT);\r
855           poly.push(x2 + kMinWidthT * 0.9, y2 + kMinWidthT * 0.9, 1);\r
856           poly.push(x2 + kMinWidthT, y2);\r
857         } else {\r
858           poly.push(x2 - kMinWidthT, y2);\r
859           poly.push(x2 - kMinWidthT * 0.6, y2 + kMinWidthT * 0.6);\r
860           poly.push(x2, y2 + kMinWidthT);\r
861           poly.push(x2 + kMinWidthT * 0.6, y2 + kMinWidthT * 0.6);\r
862           poly.push(x2 + kMinWidthT, y2);\r
863         }\r
864         poly.reverse(); // for fill-rule\r
865         polygons.push(poly);\r
866       }\r
867     }\r
868     else if(y1 == y2){ //if it is YOKO stroke, use x-axis\r
869       if(a1 == 6){ //if it is KAGI's YOKO stroke, get bold\r
870         poly = new Polygon();\r
871         poly.push(x1, y1 - kMinWidthT);\r
872         poly.push(x2, y2 - kMinWidthT);\r
873         poly.push(x2, y2 + kMinWidthT);\r
874         poly.push(x1, y1 + kMinWidthT);\r
875         polygons.push(poly);\r
876         \r
877         if(a2 == 1 || a2 == 0 || a2 == 5){ // no need a2=1\r
878           //KAGI NO YOKO BOU NO SAIGO NO MARU\r
879           poly = new Polygon();\r
880           if(kage.kUseCurve){\r
881             if(x1 < x2){\r
882               poly.push(x2, y2 - kMinWidthT);\r
883               poly.push(x2 + kMinWidthT * 0.9, y2 - kMinWidthT * 0.9, 1);\r
884               poly.push(x2 + kMinWidthT, y2);\r
885               poly.push(x2 + kMinWidthT * 0.9, y2 + kMinWidthT * 0.9, 1);\r
886               poly.push(x2, y2 + kMinWidthT);\r
887             } else {\r
888               poly.push(x2, y2 - kMinWidthT);\r
889               poly.push(x2 - kMinWidthT * 0.9, y2 - kMinWidthT * 0.9, 1);\r
890               poly.push(x2 - kMinWidthT, y2);\r
891               poly.push(x2 - kMinWidthT * 0.9, y2 + kMinWidthT * 0.9, 1);\r
892               poly.push(x2, y2 + kMinWidthT);\r
893             }\r
894           } else {\r
895             if(x1 < x2){\r
896               poly.push(x2, y2 - kMinWidthT);\r
897               poly.push(x2 + kMinWidthT * 0.6, y2 - kMinWidthT * 0.6);\r
898               poly.push(x2 + kMinWidthT, y2);\r
899               poly.push(x2 + kMinWidthT * 0.6, y2 + kMinWidthT * 0.6);\r
900               poly.push(x2, y2 + kMinWidthT);\r
901             } else {\r
902               poly.push(x2, y2 - kMinWidthT);\r
903               poly.push(x2 - kMinWidthT * 0.6, y2 - kMinWidthT * 0.6);\r
904               poly.push(x2 - kMinWidthT, y2);\r
905               poly.push(x2 - kMinWidthT * 0.6, y2 + kMinWidthT * 0.6);\r
906               poly.push(x2, y2 + kMinWidthT);\r
907             }\r
908           }\r
909           polygons.push(poly);\r
910         }\r
911         \r
912         if(a2 == 5){\r
913           //KAGI NO YOKO BOU NO HANE\r
914           poly = new Polygon();\r
915           if(x1 < x2){\r
916             poly.push(x2, y2 - kMinWidthT + 1);\r
917             poly.push(x2 + 2, y2 - kMinWidthT - kage.kWidth * (4 * (1 - opt1 / kage.kAdjustMageStep) + 1));\r
918             poly.push(x2, y2 - kMinWidthT - kage.kWidth * (4 * (1 - opt1 / kage.kAdjustMageStep) + 1));\r
919             poly.push(x2 - kMinWidthT, y2 - kMinWidthT + 1);\r
920           } else {\r
921             poly.push(x2, y2 - kMinWidthT + 1);\r
922             poly.push(x2 - 2, y2 - kMinWidthT - kage.kWidth * (4 * (1 - opt1 / kage.kAdjustMageStep) + 1));\r
923             poly.push(x2, y2 - kMinWidthT - kage.kWidth * (4 * (1 - opt1 / kage.kAdjustMageStep) + 1));\r
924             poly.push(x2 + kMinWidthT, y2 - kMinWidthT + 1);\r
925           }\r
926           poly.reverse(); // for fill-rule\r
927           polygons.push(poly);\r
928         }\r
929       }\r
930       else{\r
931         //always same\r
932         poly = new Polygon(4);\r
933         poly.set(0, x1, y1 - kage.kMinWidthY);\r
934         poly.set(1, x2, y2 - kage.kMinWidthY);\r
935         poly.set(2, x2, y2 + kage.kMinWidthY);\r
936         poly.set(3, x1, y1 + kage.kMinWidthY);\r
937         polygons.push(poly);\r
938         \r
939         //UROKO\r
940         if(a2 == 0){\r
941           poly = new Polygon();\r
942           poly.push(x2, y2 - kage.kMinWidthY);\r
943           poly.push(x2 - kage.kAdjustUrokoX[opt2], y2);\r
944           poly.push(x2 - kage.kAdjustUrokoX[opt2] / 2, y2 - kage.kAdjustUrokoY[opt2]);\r
945           polygons.push(poly);\r
946         }\r
947       }\r
948     }\r
949     else{ //for others, use x-axis\r
950       rad = Math.atan((y2 - y1) / (x2 - x1));\r
951       if((Math.abs(y2 - y1) < Math.abs(x2 - x1)) && (a1 != 6) && (a2 != 6) && !(x1 > x2)){ //ASAI KAUDO\r
952         //always same\r
953         poly = new Polygon(4);\r
954         poly.set(0, x1 + Math.sin(rad) * kage.kMinWidthY, y1 - Math.cos(rad) * kage.kMinWidthY);\r
955         poly.set(1, x2 + Math.sin(rad) * kage.kMinWidthY, y2 - Math.cos(rad) * kage.kMinWidthY);\r
956         poly.set(2, x2 - Math.sin(rad) * kage.kMinWidthY, y2 + Math.cos(rad) * kage.kMinWidthY);\r
957         poly.set(3, x1 - Math.sin(rad) * kage.kMinWidthY, y1 + Math.cos(rad) * kage.kMinWidthY);\r
958         polygons.push(poly);\r
959         \r
960         //UROKO\r
961         if(a2 == 0){\r
962           poly = new Polygon();\r
963           poly.push(x2 + Math.sin(rad) * kage.kMinWidthY, y2 - Math.cos(rad) * kage.kMinWidthY);\r
964           poly.push(x2 - Math.cos(rad) * kage.kAdjustUrokoX[opt2], y2 - Math.sin(rad) * kage.kAdjustUrokoX[opt2]);\r
965           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
966           polygons.push(poly);\r
967         }\r
968       }\r
969       \r
970       else{ //KAKUDO GA FUKAI or KAGI NO YOKO BOU\r
971         if(x1 > x2){ v = -1; } else{ v = 1; }\r
972         poly = new Polygon(4);\r
973         switch(a1){\r
974         case 0:\r
975           poly.set(0, x1 + Math.sin(rad) * kMinWidthT * v + kage.kMinWidthY * Math.cos(rad) * 0.5 * v,\r
976                    y1 - Math.cos(rad) * kMinWidthT * v + kage.kMinWidthY * Math.sin(rad) * 0.5 * v);\r
977           poly.set(3, x1 - Math.sin(rad) * kMinWidthT * v - kage.kMinWidthY * Math.cos(rad) * 0.5 * v,\r
978                    y1 + Math.cos(rad) * kMinWidthT * v - kage.kMinWidthY * Math.sin(rad) * 0.5 * v);\r
979           break;\r
980         case 1:\r
981         case 6:\r
982           poly.set(0, x1 + Math.sin(rad) * kMinWidthT * v, y1 - Math.cos(rad) * kMinWidthT * v);\r
983           poly.set(3, x1 - Math.sin(rad) * kMinWidthT * v, y1 + Math.cos(rad) * kMinWidthT * v);\r
984           break;\r
985         case 12:\r
986           poly.set(0, x1 + Math.sin(rad) * kMinWidthT * v - kage.kMinWidthY * Math.cos(rad) * v,\r
987                    y1 - Math.cos(rad) * kMinWidthT * v - kage.kMinWidthY * Math.sin(rad) * v);\r
988           poly.set(3, x1 - Math.sin(rad) * kMinWidthT * v - (kMinWidthT + kage.kMinWidthY) * Math.cos(rad) * v,\r
989                    y1 + Math.cos(rad) * kMinWidthT * v - (kMinWidthT + kage.kMinWidthY) * Math.sin(rad) * v);\r
990           break;\r
991         case 22:\r
992           poly.set(0, x1 + (kMinWidthT * v + 1) / Math.sin(rad), y1 + 1);\r
993           poly.set(3, x1 - (kMinWidthT * v) / Math.sin(rad), y1);\r
994           break;\r
995         case 32:\r
996           poly.set(0, x1 + (kMinWidthT * v) / Math.sin(rad), y1);\r
997           poly.set(3, x1 - (kMinWidthT * v) / Math.sin(rad), y1);\r
998           break;\r
999         }\r
1000         \r
1001         switch(a2){\r
1002         case 0:\r
1003           if(a1 == 6){\r
1004             poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v, y2 - Math.cos(rad) * kMinWidthT * v);\r
1005             poly.set(2, x2 - Math.sin(rad) * kMinWidthT * v, y2 + Math.cos(rad) * kMinWidthT * v);\r
1006           }\r
1007           else{\r
1008             poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v - kMinWidthT * 0.5 * Math.cos(rad) * v,\r
1009                      y2 - Math.cos(rad) * kMinWidthT * v - kMinWidthT * 0.5 * Math.sin(rad) * v);\r
1010             poly.set(2, x2 - Math.sin(rad) * kMinWidthT * v + kMinWidthT * 0.5 * Math.cos(rad) * v,\r
1011                      y2 + Math.cos(rad) * kMinWidthT * v + kMinWidthT * 0.5 * Math.sin(rad) * v);\r
1012           }\r
1013           break;\r
1014         case 1: // is needed?\r
1015         case 5:\r
1016           poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v, y2 - Math.cos(rad) * kMinWidthT * v);\r
1017           poly.set(2, x2 - Math.sin(rad) * kMinWidthT * v, y2 + Math.cos(rad) * kMinWidthT * v);\r
1018           break;\r
1019         case 13:\r
1020           poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v + kage.kAdjustKakatoL[opt2] * Math.cos(rad) * v,\r
1021                    y2 - Math.cos(rad) * kMinWidthT * v + kage.kAdjustKakatoL[opt2] * Math.sin(rad) * v);\r
1022           poly.set(2, x2 - Math.sin(rad) * kMinWidthT * v + (kage.kAdjustKakatoL[opt2] + kMinWidthT) * Math.cos(rad) * v,\r
1023                    y2 + Math.cos(rad) * kMinWidthT * v + (kage.kAdjustKakatoL[opt2] + kMinWidthT) * Math.sin(rad) * v);\r
1024           break;\r
1025         case 23:\r
1026           poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v + kage.kAdjustKakatoR[opt2] * Math.cos(rad) * v,\r
1027                    y2 - Math.cos(rad) * kMinWidthT * v + kage.kAdjustKakatoR[opt2] * Math.sin(rad) * v);\r
1028           poly.set(2,\r
1029                    x2 - Math.sin(rad) * kMinWidthT * v + (kage.kAdjustKakatoR[opt2] + kMinWidthT) * Math.cos(rad) * v,\r
1030                    y2 + Math.cos(rad) * kMinWidthT * v + (kage.kAdjustKakatoR[opt2] + kMinWidthT) * Math.sin(rad) * v);\r
1031           break;\r
1032         case 32:\r
1033           poly.set(1, x2 + (kMinWidthT * v) / Math.sin(rad), y2);\r
1034           poly.set(2, x2 - (kMinWidthT * v) / Math.sin(rad), y2);\r
1035           break;\r
1036         }\r
1037         \r
1038         polygons.push(poly);\r
1039         \r
1040         if((a1 == 6) && (a2 == 0 || a2 == 5)){ //KAGI NO YOKO BOU NO SAIGO NO MARU\r
1041           poly = new Polygon();\r
1042           if(kage.kUseCurve){\r
1043             poly.push(x2 + Math.sin(rad) * kMinWidthT * v, y2 - Math.cos(rad) * kMinWidthT * v);\r
1044             poly.push(x2 - Math.cos(rad) * kMinWidthT * 0.9 * v + Math.sin(rad) * kMinWidthT * 0.9 * v,\r
1045                       y2 + Math.sin(rad) * kMinWidthT * 0.9 * v - Math.cos(rad) * kMinWidthT * 0.9 * v, 1);\r
1046             poly.push(x2 + Math.cos(rad) * kMinWidthT * v, y2 + Math.sin(rad) * kMinWidthT * v);\r
1047             poly.push(x2 + Math.cos(rad) * kMinWidthT * 0.9 * v - Math.sin(rad) * kMinWidthT * 0.9 * v,\r
1048                       y2 + Math.sin(rad) * kMinWidthT * 0.9 * v + Math.cos(rad) * kMinWidthT * 0.9 * v, 1);\r
1049             poly.push(x2 - Math.sin(rad) * kMinWidthT * v, y2 + Math.cos(rad) * kMinWidthT * v);\r
1050           } else {\r
1051             poly.push(x2 + Math.sin(rad) * kMinWidthT * v, y2 - Math.cos(rad) * kMinWidthT * v);\r
1052             poly.push(x2 + Math.cos(rad) * kMinWidthT * 0.8 * v + Math.sin(rad) * kMinWidthT * 0.6 * v,\r
1053                       y2 + Math.sin(rad) * kMinWidthT * 0.8 * v - Math.cos(rad) * kMinWidthT * 0.6 * v);\r
1054             poly.push(x2 + Math.cos(rad) * kMinWidthT * v, y2 + Math.sin(rad) * kMinWidthT * v);\r
1055             poly.push(x2 + Math.cos(rad) * kMinWidthT * 0.8 * v - Math.sin(rad) * kMinWidthT * 0.6 * v,\r
1056                       y2 + Math.sin(rad) * kMinWidthT * 0.8 * v + Math.cos(rad) * kMinWidthT * 0.6 * v);\r
1057             poly.push(x2 - Math.sin(rad) * kMinWidthT * v, y2 + Math.cos(rad) * kMinWidthT * v);\r
1058           }\r
1059           polygons.push(poly);\r
1060         }\r
1061         \r
1062         if(a1 == 6 && a2 == 5){\r
1063           //KAGI NO YOKO BOU NO HANE\r
1064           poly = new Polygon();\r
1065           if(x1 < x2){\r
1066             poly.push(x2 + (kMinWidthT - 1) * Math.sin(rad) * v, y2 - (kMinWidthT - 1) * Math.cos(rad) * v);\r
1067             poly.push(x2 + 2 * Math.cos(rad) * v + (kMinWidthT + kage.kWidth * 5) * Math.sin(rad) * v,\r
1068                       y2 + 2 * Math.sin(rad) * v - (kMinWidthT + kage.kWidth * 5) * Math.cos(rad) * v);\r
1069             poly.push(x2 + (kMinWidthT + kage.kWidth * 5) * Math.sin(rad) * v,\r
1070                       y2 - (kMinWidthT + kage.kWidth * 5) * Math.cos(rad) * v);\r
1071             poly.push(x2 + (kMinWidthT - 1) * Math.sin(rad) * v - kMinWidthT * Math.cos(rad) * v,\r
1072                       y2 - (kMinWidthT - 1) * Math.cos(rad) * v - kMinWidthT * Math.sin(rad) * v);\r
1073           } else {\r
1074             poly.push(x2 - (kMinWidthT - 1) * Math.sin(rad) * v, y2 + (kMinWidthT - 1) * Math.cos(rad) * v);\r
1075             poly.push(x2 + 2 * Math.cos(rad) * v - (kMinWidthT + kage.kWidth * 5) * Math.sin(rad) * v,\r
1076                       y2 + 2 * Math.sin(rad) * v + (kMinWidthT + kage.kWidth * 5) * Math.cos(rad) * v);\r
1077             poly.push(x2 - (kMinWidthT + kage.kWidth * 5) * Math.sin(rad) * v,\r
1078                       y2 + (kMinWidthT + kage.kWidth * 5) * Math.cos(rad) * v);\r
1079             poly.push(x2 + (kMinWidthT - 1) * Math.sin(rad) * v - kMinWidthT * Math.cos(rad) * v,\r
1080                       y2 - (kMinWidthT - 1) * Math.cos(rad) * v - kMinWidthT * Math.sin(rad) * v);\r
1081           }\r
1082           polygons.push(poly);\r
1083         }\r
1084         \r
1085         if(a1 == 22){ //SHIKAKU MIGIUE UROKO NANAME DEMO MASSUGU MUKI\r
1086           poly = new Polygon();\r
1087           poly.push(x1 - kMinWidthT, y1 - kage.kMinWidthY);\r
1088           poly.push(x1, y1 - kage.kMinWidthY - kage.kWidth);\r
1089           poly.push(x1 + kMinWidthT + kage.kWidth, y1 + kage.kMinWidthY);\r
1090           poly.push(x1 + kMinWidthT, y1 + kMinWidthT - 1);\r
1091           poly.push(x1 - kMinWidthT, y1 + kMinWidthT + 4);\r
1092           polygons.push(poly);\r
1093         }\r
1094         \r
1095         XX = Math.sin(rad) * v;\r
1096         XY = Math.cos(rad) * v * -1;\r
1097         YX = Math.cos(rad) * v;\r
1098         YY = Math.sin(rad) * v;\r
1099         \r
1100         if(a1 == 0){ //beginning of the storke\r
1101           poly = new Polygon();\r
1102           poly.push(x1 + kMinWidthT * XX + (kage.kMinWidthY * 0.5) * YX,\r
1103                     y1 + kMinWidthT * XY + (kage.kMinWidthY * 0.5) * YY);\r
1104           poly.push(x1 + (kMinWidthT + kMinWidthT * 0.5) * XX + (kage.kMinWidthY * 0.5 + kage.kMinWidthY) * YX,\r
1105                     y1 + (kMinWidthT + kMinWidthT * 0.5) * XY + (kage.kMinWidthY * 0.5 + kage.kMinWidthY) * YY);\r
1106           poly.push(x1 + kMinWidthT * XX + (kage.kMinWidthY * 0.5 + kage.kMinWidthY * 2) * YX - 2 * XX,\r
1107                     y1 + kMinWidthT * XY + (kage.kMinWidthY * 0.5 + kage.kMinWidthY * 2) * YY + 1 * XY);\r
1108           polygons.push(poly);\r
1109         }\r
1110       }\r
1111     }\r
1112   }\r
1113   else{ //gothic\r
1114     if(tx1 == tx2){ //if TATE stroke, use y-axis\r
1115       if(ty1 > ty2){\r
1116         x1 = tx2;\r
1117         y1 = ty2;\r
1118         x2 = tx1;\r
1119         y2 = ty1;\r
1120         a1 = ta2;\r
1121         a2 = ta1;\r
1122       }\r
1123       else{\r
1124         x1 = tx1;\r
1125         y1 = ty1;\r
1126         x2 = tx2;\r
1127         y2 = ty2;\r
1128         a1 = ta1;\r
1129         a2 = ta2;\r
1130       }\r
1131       \r
1132       if(a1 % 10 == 2){ y1 = y1 - kage.kWidth; }\r
1133       if(a2 % 10 == 2){ y2 = y2 + kage.kWidth; }\r
1134       if(a1 % 10 == 3){ y1 = y1 - kage.kWidth * kage.kKakato; }\r
1135       if(a2 % 10 == 3){ y2 = y2 + kage.kWidth * kage.kKakato; }\r
1136       \r
1137       poly = new Polygon();\r
1138       poly.push(x1 - kage.kWidth, y1);\r
1139       poly.push(x2 - kage.kWidth, y2);\r
1140       poly.push(x2 + kage.kWidth, y2);\r
1141       poly.push(x1 + kage.kWidth, y1);\r
1142       poly.reverse(); // for fill-rule\r
1143       \r
1144       polygons.push(poly);\r
1145     }\r
1146     else if(ty1 == ty2){ //if YOKO stroke, use x-axis\r
1147       if(tx1 > tx2){\r
1148         x1 = tx2;\r
1149         y1 = ty2;\r
1150         x2 = tx1;\r
1151         y2 = ty1;\r
1152         a1 = ta2;\r
1153         a2 = ta1;\r
1154       }\r
1155       else{\r
1156         x1 = tx1;\r
1157         y1 = ty1;\r
1158         x2 = tx2;\r
1159         y2 = ty2;\r
1160         a1 = ta1;\r
1161         a2 = ta2;\r
1162       }\r
1163       if(a1 % 10 == 2){ x1 = x1 - kage.kWidth; }\r
1164       if(a2 % 10 == 2){ x2 = x2 + kage.kWidth; }\r
1165       if(a1 % 10 == 3){ x1 = x1 - kage.kWidth * kage.kKakato; }\r
1166       if(a2 % 10 == 3){ x2 = x2 + kage.kWidth * kage.kKakato; }\r
1167       \r
1168       poly = new Polygon();\r
1169       poly.push(x1, y1 - kage.kWidth);\r
1170       poly.push(x2, y2 - kage.kWidth);\r
1171       poly.push(x2, y2 + kage.kWidth);\r
1172       poly.push(x1, y1 + kage.kWidth);\r
1173       \r
1174       polygons.push(poly);\r
1175     }\r
1176     else{ //for others, use x-axis\r
1177       if(tx1 > tx2){\r
1178         x1 = tx2;\r
1179         y1 = ty2;\r
1180         x2 = tx1;\r
1181         y2 = ty1;\r
1182         a1 = ta2;\r
1183         a2 = ta1;\r
1184       }\r
1185       else{\r
1186         x1 = tx1;\r
1187         y1 = ty1;\r
1188         x2 = tx2;\r
1189         y2 = ty2;\r
1190         a1 = ta1;\r
1191         a2 = ta2;\r
1192       }\r
1193       rad = Math.atan((y2 - y1) / (x2 - x1));\r
1194       if(a1 % 10 == 2){\r
1195         x1 = x1 - kage.kWidth * Math.cos(rad);\r
1196         y1 = y1 - kage.kWidth * Math.sin(rad);\r
1197       }\r
1198       if(a2 % 10 == 2){\r
1199         x2 = x2 + kage.kWidth * Math.cos(rad);\r
1200         y2 = y2 + kage.kWidth * Math.sin(rad);\r
1201       }\r
1202       if(a1 % 10 == 3){\r
1203         x1 = x1 - kage.kWidth * Math.cos(rad) * kage.kKakato;\r
1204         y1 = y1 - kage.kWidth * Math.sin(rad) * kage.kKakato;\r
1205       }\r
1206       if(a2 % 10 == 3){\r
1207         x2 = x2 + kage.kWidth * Math.cos(rad) * kage.kKakato;\r
1208         y2 = y2 + kage.kWidth * Math.sin(rad) * kage.kKakato;\r
1209       }\r
1210       \r
1211       //SUICHOKU NO ICHI ZURASHI HA Math.sin TO Math.cos NO IREKAE + x-axis MAINASU KA\r
1212       poly = new Polygon();\r
1213       poly.push(x1 + Math.sin(rad) * kage.kWidth, y1 - Math.cos(rad) * kage.kWidth);\r
1214       poly.push(x2 + Math.sin(rad) * kage.kWidth, y2 - Math.cos(rad) * kage.kWidth);\r
1215       poly.push(x2 - Math.sin(rad) * kage.kWidth, y2 + Math.cos(rad) * kage.kWidth);\r
1216       poly.push(x1 - Math.sin(rad) * kage.kWidth, y1 + Math.cos(rad) * kage.kWidth);\r
1217       \r
1218       polygons.push(poly);\r
1219     }\r
1220   }\r
1221 }\r