Fixed a bug.(stroke type 2 - tail jump up)
[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       if(y1 < y2){\r
587         poly.push(x2, y2 - kMinWidthT + 1);\r
588         poly.push(x2 + 2, y2 - kMinWidthT - kage.kWidth * 5);\r
589         poly.push(x2, y2 - kMinWidthT - kage.kWidth * 5);\r
590         poly.push(x2 - kMinWidthT, y2 - kMinWidthT + 1);\r
591       } else {\r
592         poly.push(x2, y2 + kMinWidthT - 1);\r
593         poly.push(x2 - 2, y2 + kMinWidthT + kage.kWidth * 5);\r
594         poly.push(x2, y2 + kMinWidthT + kage.kWidth * 5);\r
595         poly.push(x2 + kMinWidthT, y2 + kMinWidthT - 1);\r
596       }\r
597       polygons.push(poly);\r
598     }\r
599     \r
600     if(a2 == 14){ //jump to left, allways go left\r
601       poly = new Polygon();\r
602       poly.push(x2, y2);\r
603       poly.push(x2, y2 - kMinWidthT);\r
604       poly.push(x2 - kage.kWidth * 4 * Math.pow(kMinWidthT / kage.kMinWidthT, 3), y2 - kMinWidthT);\r
605       poly.push(x2 - kage.kWidth * 4 * Math.pow(kMinWidthT / kage.kMinWidthT, 3), y2 - kMinWidthT * 0.5);\r
606       polygons.push(poly);\r
607     }\r
608   }\r
609   else{ //gothic\r
610     if(a1 % 10 == 2){\r
611       if(x1 == sx1){\r
612         if(y1 < sy1){ y1 = y1 - kage.kWidth; } else{ y1 = y1 + kage.kWidth; }\r
613       }\r
614       else if(y1 == sy1){\r
615         if(x1 < sx1){ x1 = x1 - kage.kWidth; } else{ x1 = x1 + kage.kWidth; }\r
616       }\r
617       else{\r
618         rad = Math.atan((sy1 - y1) / (sx1 - x1));\r
619         if(x1 < sx1){ v = 1; } else{ v = -1; }\r
620         x1 = x1 - kage.kWidth * Math.cos(rad) * v;\r
621         y1 = y1 - kage.kWidth * Math.sin(rad) * v;\r
622       }\r
623     }\r
624     \r
625     if(a1 % 10 == 3){\r
626       if(x1 == sx1){\r
627         if(y1 < sy1){\r
628           y1 = y1 - kage.kWidth * kage.kKakato;\r
629         }\r
630         else{\r
631           y1 = y1 + kage.kWidth * kage.kKakato;\r
632         }\r
633       }\r
634       else if(y1 == sy1){\r
635         if(x1 < sx1){\r
636           x1 = x1 - kage.kWidth * kage.kKakato;\r
637         }\r
638         else{\r
639           x1 = x1 + kage.kWidth * kage.kKakato;\r
640         }\r
641       }\r
642       else{\r
643         rad = Math.atan((sy1 - y1) / (sx1 - x1));\r
644         if(x1 < sx1){ v = 1; } else{ v = -1; }\r
645         x1 = x1 - kage.kWidth * Math.cos(rad) * v * kage.kKakato;\r
646         y1 = y1 - kage.kWidth * Math.sin(rad) * v * kage.kKakato;\r
647       }\r
648     }\r
649     if(a2 % 10 == 2){\r
650       if(sx2 == x2){\r
651         if(sy2 < y2){ y2 = y2 + kage.kWidth; } else{ y2 = y2 - kage.kWidth; }\r
652       }\r
653       else if(sy2 == y2){\r
654         if(sx2 < x2){ x2 = x2 + kage.kWidth; } else{ x2 = x2 - kage.kWidth; }\r
655       }\r
656       else{\r
657         rad = Math.atan((y2 - sy2) / (x2 - sx2));\r
658         if(sx2 < x2){ v = 1; } else{ v = -1; }\r
659         x2 = x2 + kage.kWidth * Math.cos(rad) * v;\r
660         y2 = y2 + kage.kWidth * Math.sin(rad) * v;\r
661       }\r
662     }\r
663     \r
664     if(a2 % 10 == 3){\r
665       if(sx2 == x2){\r
666         if(sy2 < y2){\r
667           y2 = y2 + kage.kWidth * kage.kKakato;\r
668         }\r
669         else{\r
670           y2 = y2 - kage.kWidth * kage.kKakato;\r
671         }\r
672       }\r
673       else if(sy2 == y2){\r
674         if(sx2 < x2){\r
675           x2 = x2 + kage.kWidth * kage.kKakato;\r
676         }\r
677         else{\r
678           x2 = x2 - kage.kWidth * kage.kKakato;\r
679         }\r
680       }\r
681       else{\r
682         rad = Math.atan((y2 - sy2) / (x2 - sx2));\r
683         if(sx2 < x2){ v = 1; } else{ v = -1; }\r
684         x2 = x2 + kage.kWidth * Math.cos(rad) * v * kage.kKakato;\r
685         y2 = y2 + kage.kWidth * Math.sin(rad) * v * kage.kKakato;\r
686       }\r
687     }\r
688     \r
689     poly = new Polygon();\r
690     poly2 = new Polygon();\r
691     \r
692     for(tt = 0; tt <= 1000; tt = tt + kage.kRate){\r
693       t = tt / 1000;\r
694       \r
695       if(sx1 == sx2 && sy1 == sy2){\r
696         //calculating each point\r
697         x = ((1.0 - t) * (1.0 - t) * x1 + 2.0 * t * (1.0 - t) * sx1 + t * t * x2);\r
698         y = ((1.0 - t) * (1.0 - t) * y1 + 2.0 * t * (1.0 - t) * sy1 + t * t * y2);\r
699         \r
700         //SESSEN NO KATAMUKI NO KEISAN(BIBUN)\r
701         ix = (x1 - 2.0 * sx1 + x2) * 2.0 * t + (-2.0 * x1 + 2.0 * sx1);\r
702         iy = (y1 - 2.0 * sy1 + y2) * 2.0 * t + (-2.0 * y1 + 2.0 * sy1);\r
703       } else {\r
704       }\r
705       //SESSEN NI SUICHOKU NA CHOKUSEN NO KEISAN\r
706       if(kage.kShotai == kage.kMincho){ //always false ?\r
707         if(ix != 0 && iy != 0){\r
708           ir = Math.atan(iy / ix * -1.0);\r
709           ia = Math.sin(ir) * kage.kMinWidthT;\r
710           ib = Math.cos(ir) * kage.kMinWidthT;\r
711         }\r
712         else if(ix == 0){\r
713           ia = kage.kMinWidthT;\r
714           ib = 0;\r
715         }\r
716         else{\r
717           ia = 0;\r
718           ib = kage.kMinWidthT;\r
719         }\r
720         ia = ia * Math.sqrt(1.0 - t);\r
721         ib = ib * Math.sqrt(1.0 - t);\r
722       }\r
723       else{\r
724         if(ix != 0 && iy != 0){\r
725           ir = Math.atan(iy / ix * -1.0);\r
726           ia = Math.sin(ir) * kage.kWidth;\r
727           ib = Math.cos(ir) * kage.kWidth;\r
728         }\r
729         else if(ix == 0){\r
730           ia = kage.kWidth;\r
731           ib = 0;\r
732         }\r
733         else{\r
734           ia = 0;\r
735           ib = kage.kWidth;\r
736         }\r
737       }\r
738       \r
739       //reverse if vector is going 2nd/3rd quadrants\r
740       if(ix <= 0){\r
741         ia = ia * -1;\r
742         ib = ib * -1;\r
743       }\r
744       \r
745       //save to polygon\r
746       poly.push(x - ia, y - ib);\r
747       poly2.push(x + ia, y + ib);\r
748     }\r
749     \r
750     poly2.reverse();\r
751     poly.concat(poly2);\r
752     polygons.push(poly);\r
753   }\r
754 }\r
755 \r
756 function cdDrawBezier(kage, polygons, x1, y1, x2, y2, x3, y3, x4, y4, a1, a2){\r
757   cdDrawCurveU(kage, polygons, x1, y1, x2, y2, x3, y3, x4, y4, a1, a2);\r
758 }\r
759 \r
760 function cdDrawCurve(kage, polygons, x1, y1, x2, y2, x3, y3, a1, a2){\r
761   cdDrawCurveU(kage, polygons, x1, y1, x2, y2, x2, y2, x3, y3, a1, a2);\r
762 }\r
763 \r
764 function cdDrawLine(kage, polygons, tx1, ty1, tx2, ty2, ta1, ta2){\r
765   var rad;\r
766   var v, x1, y1, x2, y2;\r
767   var a1, a2, opt1, opt2;\r
768   var XX, XY, YX, YY;\r
769   var poly;\r
770   var kMinWidthT;\r
771   \r
772   if(kage.kShotai == kage.kMincho){ //mincho\r
773     x1 = tx1;\r
774     y1 = ty1;\r
775     x2 = tx2;\r
776     y2 = ty2;\r
777     a1 = ta1 % 1000;\r
778     a2 = ta2 % 100;\r
779     opt1 = Math.floor(ta1 / 1000);\r
780     opt2 = Math.floor(ta2 / 100);\r
781     \r
782     kMinWidthT = kage.kMinWidthT - opt1 / 2;\r
783     \r
784     if(x1 == x2){ //if TATE stroke, use y-axis\r
785       poly = new Polygon(4);\r
786       switch(a1){\r
787       case 0:\r
788         poly.set(3, x1 - kMinWidthT, y1 - kage.kMinWidthY / 2);\r
789         poly.set(0, x1 + kMinWidthT, y1 + kage.kMinWidthY / 2);\r
790         break;\r
791       case 1:\r
792       case 6: //... no need\r
793       case 22:\r
794         poly.set(3, x1 - kMinWidthT, y1);\r
795         poly.set(0, x1 + kMinWidthT, y1);\r
796         break;\r
797       case 12:\r
798         poly.set(3, x1 - kMinWidthT, y1 - kage.kMinWidthY - kMinWidthT);\r
799         poly.set(0, x1 + kMinWidthT, y1 - kage.kMinWidthY);\r
800         break;\r
801       case 32:\r
802         poly.set(3, x1 - kMinWidthT, y1 - kage.kMinWidthY);\r
803         poly.set(0, x1 + kMinWidthT, y1 - kage.kMinWidthY);\r
804         break;\r
805       }\r
806       \r
807       switch(a2){\r
808       case 0:\r
809         if(a1 == 6){ //KAGI's tail ... no need\r
810           poly.set(2, x2 - kMinWidthT, y2);\r
811           poly.set(1, x2 + kMinWidthT, y2);\r
812         }\r
813         else{\r
814           poly.set(2, x2 - kMinWidthT, y2 + kMinWidthT / 2);\r
815           poly.set(1, x2 + kMinWidthT, y2 - kMinWidthT / 2);\r
816         }\r
817         break;\r
818       case 1:\r
819         poly.set(2, x2 - kMinWidthT, y2);\r
820         poly.set(1, x2 + kMinWidthT, y2);\r
821         break;\r
822       case 13:\r
823         poly.set(2, x2 - kMinWidthT, y2 + kage.kAdjustKakatoL[opt2] + kMinWidthT);\r
824         poly.set(1, x2 + kMinWidthT, y2 + kage.kAdjustKakatoL[opt2]);\r
825         break;\r
826       case 23:\r
827         poly.set(2, x2 - kMinWidthT, y2 + kage.kAdjustKakatoR[opt2] + kMinWidthT);\r
828         poly.set(1, x2 + kMinWidthT, y2 + kage.kAdjustKakatoR[opt2]);\r
829         break;\r
830       case 32:\r
831         poly.set(2, x2 - kMinWidthT, y2 + kage.kMinWidthY);\r
832         poly.set(1, x2 + kMinWidthT, y2 + kage.kMinWidthY);\r
833         break;\r
834       }\r
835       \r
836       polygons.push(poly);\r
837       \r
838       if(a1 == 22){ //box's right top corner\r
839         poly = new Polygon();\r
840         poly.push(x1 - kMinWidthT, y1 - kage.kMinWidthY);\r
841         poly.push(x1, y1 - kage.kMinWidthY - kage.kWidth);\r
842         poly.push(x1 + kMinWidthT + kage.kWidth, y1 + kage.kMinWidthY);\r
843         poly.push(x1 + kMinWidthT, y1 + kMinWidthT);\r
844         poly.push(x1 - kMinWidthT, y1);\r
845         polygons.push(poly);\r
846       }\r
847       \r
848       if(a1 == 0){ //beginning of the stroke\r
849         poly = new Polygon();\r
850         poly.push(x1 + kMinWidthT, y1 + kage.kMinWidthY * 0.5);\r
851         poly.push(x1 + kMinWidthT + kMinWidthT * 0.5, y1 + kage.kMinWidthY * 0.5 + kage.kMinWidthY);\r
852         poly.push(x1 + kMinWidthT - 2, y1 + kage.kMinWidthY * 0.5 + kage.kMinWidthY * 2 + 1);\r
853         polygons.push(poly);\r
854       }\r
855       \r
856       if((a1 == 6 && a2 == 0) || a2 == 1){ //KAGI NO YOKO BOU NO SAIGO NO MARU ... no need only used at 1st=yoko\r
857         poly = new Polygon();\r
858         if(kage.kUseCurve){\r
859           poly.push(x2 - kMinWidthT, y2);\r
860           poly.push(x2 - kMinWidthT * 0.9, y2 + kMinWidthT * 0.9, 1);\r
861           poly.push(x2, y2 + kMinWidthT);\r
862           poly.push(x2 + kMinWidthT * 0.9, y2 + kMinWidthT * 0.9, 1);\r
863           poly.push(x2 + kMinWidthT, y2);\r
864         } else {\r
865           poly.push(x2 - kMinWidthT, y2);\r
866           poly.push(x2 - kMinWidthT * 0.6, y2 + kMinWidthT * 0.6);\r
867           poly.push(x2, y2 + kMinWidthT);\r
868           poly.push(x2 + kMinWidthT * 0.6, y2 + kMinWidthT * 0.6);\r
869           poly.push(x2 + kMinWidthT, y2);\r
870         }\r
871         poly.reverse(); // for fill-rule\r
872         polygons.push(poly);\r
873       }\r
874     }\r
875     else if(y1 == y2){ //if it is YOKO stroke, use x-axis\r
876       if(a1 == 6){ //if it is KAGI's YOKO stroke, get bold\r
877         poly = new Polygon();\r
878         poly.push(x1, y1 - kMinWidthT);\r
879         poly.push(x2, y2 - kMinWidthT);\r
880         poly.push(x2, y2 + kMinWidthT);\r
881         poly.push(x1, y1 + kMinWidthT);\r
882         polygons.push(poly);\r
883         \r
884         if(a2 == 1 || a2 == 0 || a2 == 5){ // no need a2=1\r
885           //KAGI NO YOKO BOU NO SAIGO NO MARU\r
886           poly = new Polygon();\r
887           if(kage.kUseCurve){\r
888             if(x1 < x2){\r
889               poly.push(x2, y2 - kMinWidthT);\r
890               poly.push(x2 + kMinWidthT * 0.9, y2 - kMinWidthT * 0.9, 1);\r
891               poly.push(x2 + kMinWidthT, y2);\r
892               poly.push(x2 + kMinWidthT * 0.9, y2 + kMinWidthT * 0.9, 1);\r
893               poly.push(x2, y2 + kMinWidthT);\r
894             } else {\r
895               poly.push(x2, y2 - kMinWidthT);\r
896               poly.push(x2 - kMinWidthT * 0.9, y2 - kMinWidthT * 0.9, 1);\r
897               poly.push(x2 - kMinWidthT, y2);\r
898               poly.push(x2 - kMinWidthT * 0.9, y2 + kMinWidthT * 0.9, 1);\r
899               poly.push(x2, y2 + kMinWidthT);\r
900             }\r
901           } else {\r
902             if(x1 < x2){\r
903               poly.push(x2, y2 - kMinWidthT);\r
904               poly.push(x2 + kMinWidthT * 0.6, y2 - kMinWidthT * 0.6);\r
905               poly.push(x2 + kMinWidthT, y2);\r
906               poly.push(x2 + kMinWidthT * 0.6, y2 + kMinWidthT * 0.6);\r
907               poly.push(x2, y2 + kMinWidthT);\r
908             } else {\r
909               poly.push(x2, y2 - kMinWidthT);\r
910               poly.push(x2 - kMinWidthT * 0.6, y2 - kMinWidthT * 0.6);\r
911               poly.push(x2 - kMinWidthT, y2);\r
912               poly.push(x2 - kMinWidthT * 0.6, y2 + kMinWidthT * 0.6);\r
913               poly.push(x2, y2 + kMinWidthT);\r
914             }\r
915           }\r
916           polygons.push(poly);\r
917         }\r
918         \r
919         if(a2 == 5){\r
920           //KAGI NO YOKO BOU NO HANE\r
921           poly = new Polygon();\r
922           if(x1 < x2){\r
923             poly.push(x2, y2 - kMinWidthT + 1);\r
924             poly.push(x2 + 2, y2 - kMinWidthT - kage.kWidth * (4 * (1 - opt1 / kage.kAdjustMageStep) + 1));\r
925             poly.push(x2, y2 - kMinWidthT - kage.kWidth * (4 * (1 - opt1 / kage.kAdjustMageStep) + 1));\r
926             poly.push(x2 - kMinWidthT, y2 - kMinWidthT + 1);\r
927           } else {\r
928             poly.push(x2, y2 - kMinWidthT + 1);\r
929             poly.push(x2 - 2, y2 - kMinWidthT - kage.kWidth * (4 * (1 - opt1 / kage.kAdjustMageStep) + 1));\r
930             poly.push(x2, y2 - kMinWidthT - kage.kWidth * (4 * (1 - opt1 / kage.kAdjustMageStep) + 1));\r
931             poly.push(x2 + kMinWidthT, y2 - kMinWidthT + 1);\r
932           }\r
933           poly.reverse(); // for fill-rule\r
934           polygons.push(poly);\r
935         }\r
936       }\r
937       else{\r
938         //always same\r
939         poly = new Polygon(4);\r
940         poly.set(0, x1, y1 - kage.kMinWidthY);\r
941         poly.set(1, x2, y2 - kage.kMinWidthY);\r
942         poly.set(2, x2, y2 + kage.kMinWidthY);\r
943         poly.set(3, x1, y1 + kage.kMinWidthY);\r
944         polygons.push(poly);\r
945         \r
946         //UROKO\r
947         if(a2 == 0){\r
948           poly = new Polygon();\r
949           poly.push(x2, y2 - kage.kMinWidthY);\r
950           poly.push(x2 - kage.kAdjustUrokoX[opt2], y2);\r
951           poly.push(x2 - kage.kAdjustUrokoX[opt2] / 2, y2 - kage.kAdjustUrokoY[opt2]);\r
952           polygons.push(poly);\r
953         }\r
954       }\r
955     }\r
956     else{ //for others, use x-axis\r
957       rad = Math.atan((y2 - y1) / (x2 - x1));\r
958       if((Math.abs(y2 - y1) < Math.abs(x2 - x1)) && (a1 != 6) && (a2 != 6) && !(x1 > x2)){ //ASAI KAUDO\r
959         //always same\r
960         poly = new Polygon(4);\r
961         poly.set(0, x1 + Math.sin(rad) * kage.kMinWidthY, y1 - Math.cos(rad) * kage.kMinWidthY);\r
962         poly.set(1, x2 + Math.sin(rad) * kage.kMinWidthY, y2 - Math.cos(rad) * kage.kMinWidthY);\r
963         poly.set(2, x2 - Math.sin(rad) * kage.kMinWidthY, y2 + Math.cos(rad) * kage.kMinWidthY);\r
964         poly.set(3, x1 - Math.sin(rad) * kage.kMinWidthY, y1 + Math.cos(rad) * kage.kMinWidthY);\r
965         polygons.push(poly);\r
966         \r
967         //UROKO\r
968         if(a2 == 0){\r
969           poly = new Polygon();\r
970           poly.push(x2 + Math.sin(rad) * kage.kMinWidthY, y2 - Math.cos(rad) * kage.kMinWidthY);\r
971           poly.push(x2 - Math.cos(rad) * kage.kAdjustUrokoX[opt2], y2 - Math.sin(rad) * kage.kAdjustUrokoX[opt2]);\r
972           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
973           polygons.push(poly);\r
974         }\r
975       }\r
976       \r
977       else{ //KAKUDO GA FUKAI or KAGI NO YOKO BOU\r
978         if(x1 > x2){ v = -1; } else{ v = 1; }\r
979         poly = new Polygon(4);\r
980         switch(a1){\r
981         case 0:\r
982           poly.set(0, x1 + Math.sin(rad) * kMinWidthT * v + kage.kMinWidthY * Math.cos(rad) * 0.5 * v,\r
983                    y1 - Math.cos(rad) * kMinWidthT * v + kage.kMinWidthY * Math.sin(rad) * 0.5 * v);\r
984           poly.set(3, x1 - Math.sin(rad) * kMinWidthT * v - kage.kMinWidthY * Math.cos(rad) * 0.5 * v,\r
985                    y1 + Math.cos(rad) * kMinWidthT * v - kage.kMinWidthY * Math.sin(rad) * 0.5 * v);\r
986           break;\r
987         case 1:\r
988         case 6:\r
989           poly.set(0, x1 + Math.sin(rad) * kMinWidthT * v, y1 - Math.cos(rad) * kMinWidthT * v);\r
990           poly.set(3, x1 - Math.sin(rad) * kMinWidthT * v, y1 + Math.cos(rad) * kMinWidthT * v);\r
991           break;\r
992         case 12:\r
993           poly.set(0, x1 + Math.sin(rad) * kMinWidthT * v - kage.kMinWidthY * Math.cos(rad) * v,\r
994                    y1 - Math.cos(rad) * kMinWidthT * v - kage.kMinWidthY * Math.sin(rad) * v);\r
995           poly.set(3, x1 - Math.sin(rad) * kMinWidthT * v - (kMinWidthT + kage.kMinWidthY) * Math.cos(rad) * v,\r
996                    y1 + Math.cos(rad) * kMinWidthT * v - (kMinWidthT + kage.kMinWidthY) * Math.sin(rad) * v);\r
997           break;\r
998         case 22:\r
999           poly.set(0, x1 + (kMinWidthT * v + 1) / Math.sin(rad), y1 + 1);\r
1000           poly.set(3, x1 - (kMinWidthT * v) / Math.sin(rad), y1);\r
1001           break;\r
1002         case 32:\r
1003           poly.set(0, x1 + (kMinWidthT * v) / Math.sin(rad), y1);\r
1004           poly.set(3, x1 - (kMinWidthT * v) / Math.sin(rad), y1);\r
1005           break;\r
1006         }\r
1007         \r
1008         switch(a2){\r
1009         case 0:\r
1010           if(a1 == 6){\r
1011             poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v, y2 - Math.cos(rad) * kMinWidthT * v);\r
1012             poly.set(2, x2 - Math.sin(rad) * kMinWidthT * v, y2 + Math.cos(rad) * kMinWidthT * v);\r
1013           }\r
1014           else{\r
1015             poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v - kMinWidthT * 0.5 * Math.cos(rad) * v,\r
1016                      y2 - Math.cos(rad) * kMinWidthT * v - kMinWidthT * 0.5 * Math.sin(rad) * v);\r
1017             poly.set(2, x2 - Math.sin(rad) * kMinWidthT * v + kMinWidthT * 0.5 * Math.cos(rad) * v,\r
1018                      y2 + Math.cos(rad) * kMinWidthT * v + kMinWidthT * 0.5 * Math.sin(rad) * v);\r
1019           }\r
1020           break;\r
1021         case 1: // is needed?\r
1022         case 5:\r
1023           poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v, y2 - Math.cos(rad) * kMinWidthT * v);\r
1024           poly.set(2, x2 - Math.sin(rad) * kMinWidthT * v, y2 + Math.cos(rad) * kMinWidthT * v);\r
1025           break;\r
1026         case 13:\r
1027           poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v + kage.kAdjustKakatoL[opt2] * Math.cos(rad) * v,\r
1028                    y2 - Math.cos(rad) * kMinWidthT * v + kage.kAdjustKakatoL[opt2] * Math.sin(rad) * v);\r
1029           poly.set(2, x2 - Math.sin(rad) * kMinWidthT * v + (kage.kAdjustKakatoL[opt2] + kMinWidthT) * Math.cos(rad) * v,\r
1030                    y2 + Math.cos(rad) * kMinWidthT * v + (kage.kAdjustKakatoL[opt2] + kMinWidthT) * Math.sin(rad) * v);\r
1031           break;\r
1032         case 23:\r
1033           poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v + kage.kAdjustKakatoR[opt2] * Math.cos(rad) * v,\r
1034                    y2 - Math.cos(rad) * kMinWidthT * v + kage.kAdjustKakatoR[opt2] * Math.sin(rad) * v);\r
1035           poly.set(2,\r
1036                    x2 - Math.sin(rad) * kMinWidthT * v + (kage.kAdjustKakatoR[opt2] + kMinWidthT) * Math.cos(rad) * v,\r
1037                    y2 + Math.cos(rad) * kMinWidthT * v + (kage.kAdjustKakatoR[opt2] + kMinWidthT) * Math.sin(rad) * v);\r
1038           break;\r
1039         case 32:\r
1040           poly.set(1, x2 + (kMinWidthT * v) / Math.sin(rad), y2);\r
1041           poly.set(2, x2 - (kMinWidthT * v) / Math.sin(rad), y2);\r
1042           break;\r
1043         }\r
1044         \r
1045         polygons.push(poly);\r
1046         \r
1047         if((a1 == 6) && (a2 == 0 || a2 == 5)){ //KAGI NO YOKO BOU NO SAIGO NO MARU\r
1048           poly = new Polygon();\r
1049           if(kage.kUseCurve){\r
1050             poly.push(x2 + Math.sin(rad) * kMinWidthT * v, y2 - Math.cos(rad) * kMinWidthT * v);\r
1051             poly.push(x2 - Math.cos(rad) * kMinWidthT * 0.9 * v + Math.sin(rad) * kMinWidthT * 0.9 * v,\r
1052                       y2 + Math.sin(rad) * kMinWidthT * 0.9 * v - Math.cos(rad) * kMinWidthT * 0.9 * v, 1);\r
1053             poly.push(x2 + Math.cos(rad) * kMinWidthT * v, y2 + Math.sin(rad) * kMinWidthT * v);\r
1054             poly.push(x2 + Math.cos(rad) * kMinWidthT * 0.9 * v - Math.sin(rad) * kMinWidthT * 0.9 * v,\r
1055                       y2 + Math.sin(rad) * kMinWidthT * 0.9 * v + Math.cos(rad) * kMinWidthT * 0.9 * v, 1);\r
1056             poly.push(x2 - Math.sin(rad) * kMinWidthT * v, y2 + Math.cos(rad) * kMinWidthT * v);\r
1057           } else {\r
1058             poly.push(x2 + Math.sin(rad) * kMinWidthT * v, y2 - Math.cos(rad) * kMinWidthT * v);\r
1059             poly.push(x2 + Math.cos(rad) * kMinWidthT * 0.8 * v + Math.sin(rad) * kMinWidthT * 0.6 * v,\r
1060                       y2 + Math.sin(rad) * kMinWidthT * 0.8 * v - Math.cos(rad) * kMinWidthT * 0.6 * v);\r
1061             poly.push(x2 + Math.cos(rad) * kMinWidthT * v, y2 + Math.sin(rad) * kMinWidthT * v);\r
1062             poly.push(x2 + Math.cos(rad) * kMinWidthT * 0.8 * v - Math.sin(rad) * kMinWidthT * 0.6 * v,\r
1063                       y2 + Math.sin(rad) * kMinWidthT * 0.8 * v + Math.cos(rad) * kMinWidthT * 0.6 * v);\r
1064             poly.push(x2 - Math.sin(rad) * kMinWidthT * v, y2 + Math.cos(rad) * kMinWidthT * v);\r
1065           }\r
1066           polygons.push(poly);\r
1067         }\r
1068         \r
1069         if(a1 == 6 && a2 == 5){\r
1070           //KAGI NO YOKO BOU NO HANE\r
1071           poly = new Polygon();\r
1072           if(x1 < x2){\r
1073             poly.push(x2 + (kMinWidthT - 1) * Math.sin(rad) * v, y2 - (kMinWidthT - 1) * Math.cos(rad) * v);\r
1074             poly.push(x2 + 2 * Math.cos(rad) * v + (kMinWidthT + kage.kWidth * 5) * Math.sin(rad) * v,\r
1075                       y2 + 2 * Math.sin(rad) * v - (kMinWidthT + kage.kWidth * 5) * Math.cos(rad) * v);\r
1076             poly.push(x2 + (kMinWidthT + kage.kWidth * 5) * Math.sin(rad) * v,\r
1077                       y2 - (kMinWidthT + kage.kWidth * 5) * Math.cos(rad) * v);\r
1078             poly.push(x2 + (kMinWidthT - 1) * Math.sin(rad) * v - kMinWidthT * Math.cos(rad) * v,\r
1079                       y2 - (kMinWidthT - 1) * Math.cos(rad) * v - kMinWidthT * Math.sin(rad) * v);\r
1080           } else {\r
1081             poly.push(x2 - (kMinWidthT - 1) * Math.sin(rad) * v, y2 + (kMinWidthT - 1) * Math.cos(rad) * v);\r
1082             poly.push(x2 + 2 * Math.cos(rad) * v - (kMinWidthT + kage.kWidth * 5) * Math.sin(rad) * v,\r
1083                       y2 + 2 * Math.sin(rad) * v + (kMinWidthT + kage.kWidth * 5) * Math.cos(rad) * v);\r
1084             poly.push(x2 - (kMinWidthT + kage.kWidth * 5) * Math.sin(rad) * v,\r
1085                       y2 + (kMinWidthT + kage.kWidth * 5) * Math.cos(rad) * v);\r
1086             poly.push(x2 + (kMinWidthT - 1) * Math.sin(rad) * v - kMinWidthT * Math.cos(rad) * v,\r
1087                       y2 - (kMinWidthT - 1) * Math.cos(rad) * v - kMinWidthT * Math.sin(rad) * v);\r
1088           }\r
1089           polygons.push(poly);\r
1090         }\r
1091         \r
1092         if(a1 == 22){ //SHIKAKU MIGIUE UROKO NANAME DEMO MASSUGU MUKI\r
1093           poly = new Polygon();\r
1094           poly.push(x1 - kMinWidthT, y1 - kage.kMinWidthY);\r
1095           poly.push(x1, y1 - kage.kMinWidthY - kage.kWidth);\r
1096           poly.push(x1 + kMinWidthT + kage.kWidth, y1 + kage.kMinWidthY);\r
1097           poly.push(x1 + kMinWidthT, y1 + kMinWidthT - 1);\r
1098           poly.push(x1 - kMinWidthT, y1 + kMinWidthT + 4);\r
1099           polygons.push(poly);\r
1100         }\r
1101         \r
1102         XX = Math.sin(rad) * v;\r
1103         XY = Math.cos(rad) * v * -1;\r
1104         YX = Math.cos(rad) * v;\r
1105         YY = Math.sin(rad) * v;\r
1106         \r
1107         if(a1 == 0){ //beginning of the storke\r
1108           poly = new Polygon();\r
1109           poly.push(x1 + kMinWidthT * XX + (kage.kMinWidthY * 0.5) * YX,\r
1110                     y1 + kMinWidthT * XY + (kage.kMinWidthY * 0.5) * YY);\r
1111           poly.push(x1 + (kMinWidthT + kMinWidthT * 0.5) * XX + (kage.kMinWidthY * 0.5 + kage.kMinWidthY) * YX,\r
1112                     y1 + (kMinWidthT + kMinWidthT * 0.5) * XY + (kage.kMinWidthY * 0.5 + kage.kMinWidthY) * YY);\r
1113           poly.push(x1 + kMinWidthT * XX + (kage.kMinWidthY * 0.5 + kage.kMinWidthY * 2) * YX - 2 * XX,\r
1114                     y1 + kMinWidthT * XY + (kage.kMinWidthY * 0.5 + kage.kMinWidthY * 2) * YY + 1 * XY);\r
1115           polygons.push(poly);\r
1116         }\r
1117       }\r
1118     }\r
1119   }\r
1120   else{ //gothic\r
1121     if(tx1 == tx2){ //if TATE stroke, use y-axis\r
1122       if(ty1 > ty2){\r
1123         x1 = tx2;\r
1124         y1 = ty2;\r
1125         x2 = tx1;\r
1126         y2 = ty1;\r
1127         a1 = ta2;\r
1128         a2 = ta1;\r
1129       }\r
1130       else{\r
1131         x1 = tx1;\r
1132         y1 = ty1;\r
1133         x2 = tx2;\r
1134         y2 = ty2;\r
1135         a1 = ta1;\r
1136         a2 = ta2;\r
1137       }\r
1138       \r
1139       if(a1 % 10 == 2){ y1 = y1 - kage.kWidth; }\r
1140       if(a2 % 10 == 2){ y2 = y2 + kage.kWidth; }\r
1141       if(a1 % 10 == 3){ y1 = y1 - kage.kWidth * kage.kKakato; }\r
1142       if(a2 % 10 == 3){ y2 = y2 + kage.kWidth * kage.kKakato; }\r
1143       \r
1144       poly = new Polygon();\r
1145       poly.push(x1 - kage.kWidth, y1);\r
1146       poly.push(x2 - kage.kWidth, y2);\r
1147       poly.push(x2 + kage.kWidth, y2);\r
1148       poly.push(x1 + kage.kWidth, y1);\r
1149       poly.reverse(); // for fill-rule\r
1150       \r
1151       polygons.push(poly);\r
1152     }\r
1153     else if(ty1 == ty2){ //if YOKO stroke, use x-axis\r
1154       if(tx1 > tx2){\r
1155         x1 = tx2;\r
1156         y1 = ty2;\r
1157         x2 = tx1;\r
1158         y2 = ty1;\r
1159         a1 = ta2;\r
1160         a2 = ta1;\r
1161       }\r
1162       else{\r
1163         x1 = tx1;\r
1164         y1 = ty1;\r
1165         x2 = tx2;\r
1166         y2 = ty2;\r
1167         a1 = ta1;\r
1168         a2 = ta2;\r
1169       }\r
1170       if(a1 % 10 == 2){ x1 = x1 - kage.kWidth; }\r
1171       if(a2 % 10 == 2){ x2 = x2 + kage.kWidth; }\r
1172       if(a1 % 10 == 3){ x1 = x1 - kage.kWidth * kage.kKakato; }\r
1173       if(a2 % 10 == 3){ x2 = x2 + kage.kWidth * kage.kKakato; }\r
1174       \r
1175       poly = new Polygon();\r
1176       poly.push(x1, y1 - kage.kWidth);\r
1177       poly.push(x2, y2 - kage.kWidth);\r
1178       poly.push(x2, y2 + kage.kWidth);\r
1179       poly.push(x1, y1 + kage.kWidth);\r
1180       \r
1181       polygons.push(poly);\r
1182     }\r
1183     else{ //for others, use x-axis\r
1184       if(tx1 > tx2){\r
1185         x1 = tx2;\r
1186         y1 = ty2;\r
1187         x2 = tx1;\r
1188         y2 = ty1;\r
1189         a1 = ta2;\r
1190         a2 = ta1;\r
1191       }\r
1192       else{\r
1193         x1 = tx1;\r
1194         y1 = ty1;\r
1195         x2 = tx2;\r
1196         y2 = ty2;\r
1197         a1 = ta1;\r
1198         a2 = ta2;\r
1199       }\r
1200       rad = Math.atan((y2 - y1) / (x2 - x1));\r
1201       if(a1 % 10 == 2){\r
1202         x1 = x1 - kage.kWidth * Math.cos(rad);\r
1203         y1 = y1 - kage.kWidth * Math.sin(rad);\r
1204       }\r
1205       if(a2 % 10 == 2){\r
1206         x2 = x2 + kage.kWidth * Math.cos(rad);\r
1207         y2 = y2 + kage.kWidth * Math.sin(rad);\r
1208       }\r
1209       if(a1 % 10 == 3){\r
1210         x1 = x1 - kage.kWidth * Math.cos(rad) * kage.kKakato;\r
1211         y1 = y1 - kage.kWidth * Math.sin(rad) * kage.kKakato;\r
1212       }\r
1213       if(a2 % 10 == 3){\r
1214         x2 = x2 + kage.kWidth * Math.cos(rad) * kage.kKakato;\r
1215         y2 = y2 + kage.kWidth * Math.sin(rad) * kage.kKakato;\r
1216       }\r
1217       \r
1218       //SUICHOKU NO ICHI ZURASHI HA Math.sin TO Math.cos NO IREKAE + x-axis MAINASU KA\r
1219       poly = new Polygon();\r
1220       poly.push(x1 + Math.sin(rad) * kage.kWidth, y1 - Math.cos(rad) * kage.kWidth);\r
1221       poly.push(x2 + Math.sin(rad) * kage.kWidth, y2 - Math.cos(rad) * kage.kWidth);\r
1222       poly.push(x2 - Math.sin(rad) * kage.kWidth, y2 + Math.cos(rad) * kage.kWidth);\r
1223       poly.push(x1 - Math.sin(rad) * kage.kWidth, y1 + Math.cos(rad) * kage.kWidth);\r
1224       \r
1225       polygons.push(poly);\r
1226     }\r
1227   }\r
1228 }\r