914cdbb092f68901acaf8265a5a398d936e9ac4d
[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           //if(x1 > x2){\r
404           //  poly.reverse();\r
405           //}\r
406           polygons.push(poly);\r
407         }\r
408         else{\r
409           poly = new Polygon();\r
410           poly.push(x1 - kMinWidthT * XX + 1 * YX, y1 - kMinWidthT * XY + 1 * YY);\r
411           poly.push(x1 + kMinWidthT * XX, y1 + kMinWidthT * XY);\r
412           poly.push(x1 - kMinWidthT * pm * XX - kage.kMinWidthY * type * pm * YX, y1 - kMinWidthT * pm * XY - kage.kMinWidthY * type * pm * YY);\r
413           //if(x1 > x2){\r
414           //  poly.reverse();\r
415           //}\r
416           polygons.push(poly);\r
417         }\r
418       }\r
419       else{ //bottom to up\r
420         if(x1 == sx1){\r
421           poly = new Polygon();\r
422           poly.push(x1 - kMinWidthT, y1);\r
423           poly.push(x1 + kMinWidthT, y1);\r
424           poly.push(x1 + kMinWidthT, y1 - kage.kMinWidthY);\r
425           polygons.push(poly);\r
426         }\r
427         else{\r
428           poly = new Polygon();\r
429           poly.push(x1 - kMinWidthT * XX, y1 - kMinWidthT * XY);\r
430           poly.push(x1 + kMinWidthT * XX, y1 + kMinWidthT * XY);\r
431           poly.push(x1 + kMinWidthT * XX - kage.kMinWidthY * YX, y1 + kMinWidthT * XY - kage.kMinWidthY * YY);\r
432           //if(x1 < x2){\r
433           //  poly.reverse();\r
434           //}\r
435           polygons.push(poly);\r
436         }\r
437       }\r
438     }\r
439     \r
440     if(a1 == 22){ //box's up-right corner, any time same degree\r
441       poly = new Polygon();\r
442       poly.push(x1 - kMinWidthT, y1 - kage.kMinWidthY);\r
443       poly.push(x1, y1 - kage.kMinWidthY - kage.kWidth);\r
444       poly.push(x1 + kMinWidthT + kage.kWidth, y1 + kage.kMinWidthY);\r
445       poly.push(x1 + kMinWidthT, y1 + kMinWidthT - 1);\r
446       poly.push(x1 - kMinWidthT, y1 + kMinWidthT + 4);\r
447       polygons.push(poly);\r
448     }\r
449     \r
450     if(a1 == 0){ //beginning of the stroke\r
451       if(y1 <= y2){ //from up to bottom\r
452         if(pm > 0){\r
453           type = 0;\r
454         }\r
455         var move = kage.kMinWidthY * type * pm;\r
456         if(x1 == sx1){\r
457           poly = new Polygon();\r
458           poly.push(x1 + kMinWidthT, y1 - move);\r
459           poly.push(x1 + kMinWidthT * 1.5, y1 + kage.kMinWidthY - move);\r
460           poly.push(x1 + kMinWidthT - 2, y1 + kage.kMinWidthY * 2 + 1);\r
461           polygons.push(poly);\r
462         }\r
463         else{\r
464           poly = new Polygon();\r
465           poly.push(x1 + kMinWidthT * XX - move * YX,\r
466                     y1 + kMinWidthT * XY - move * YY);\r
467           poly.push(x1 + kMinWidthT * 1.5 * XX + (kage.kMinWidthY - move * 1.2) * YX,\r
468                     y1 + kMinWidthT * 1.5 * XY + (kage.kMinWidthY - move * 1.2) * YY);\r
469           poly.push(x1 + (kMinWidthT - 2) * XX + (kage.kMinWidthY * 2 - move * 0.8 + 1) * YX,\r
470                     y1 + (kMinWidthT - 2) * XY + (kage.kMinWidthY * 2 - move * 0.8 + 1) * YY);\r
471           //if(x1 < x2){\r
472           //  poly.reverse();\r
473           //}\r
474           polygons.push(poly);\r
475         }\r
476       }\r
477       else{ //from bottom to up\r
478         if(x1 == sx1){\r
479           poly = new Polygon();\r
480           poly.push(x1 - kMinWidthT, y1);\r
481           poly.push(x1 - kMinWidthT * 1.5, y1 + kage.kMinWidthY);\r
482           poly.push(x1 - kMinWidthT * 0.5, y1 + kage.kMinWidthY * 3);\r
483           polygons.push(poly);\r
484         }\r
485         else{\r
486           poly = new Polygon();\r
487           poly.push(x1 - kMinWidthT * XX, y1 - kMinWidthT * XY);\r
488           poly.push(x1 - kMinWidthT * 1.5 * XX + kage.kMinWidthY * YX, y1 + kage.kMinWidthY * YY - kMinWidthT * 1.5 * XY);\r
489           poly.push(x1 - kMinWidthT * 0.5 * XX + kage.kMinWidthY * 3 * YX, y1 + kage.kMinWidthY * 3 * YY - kMinWidthT * 0.5 * XY);\r
490           //if(x1 < x2){\r
491           //  poly.reverse();\r
492           //}\r
493           polygons.push(poly);\r
494         }\r
495       }\r
496     }\r
497     \r
498     //process for tail\r
499     rad = Math.atan((y2 - sy2) / (x2 - sx2));\r
500     if(sx2 < x2){ v = 1; } else{ v = -1; }\r
501     YX = Math.sin(rad) * v * -1;\r
502     YY = Math.cos(rad) * v;\r
503     XX = Math.cos(rad) * v;\r
504     XY = Math.sin(rad) * v;\r
505     \r
506     if(a2 == 1 || a2 == 8 || a2 == 15){ //the last filled circle ... it can change 15->5\r
507       if(sx2 == x2){\r
508         poly = new Polygon();\r
509         if(kage.kUseCurve){\r
510           // by curve path\r
511           poly.push(x2 - kMinWidthT2, y2);\r
512           poly.push(x2 - kMinWidthT2 * 0.9, y2 + kMinWidthT2 * 0.9, 1);\r
513           poly.push(x2, y2 + kMinWidthT2);\r
514           poly.push(x2 + kMinWidthT2 * 0.9, y2 + kMinWidthT2 * 0.9, 1);\r
515           poly.push(x2 + kMinWidthT2, y2);\r
516         } else {\r
517           // by polygon\r
518           poly.push(x2 - kMinWidthT2, y2);\r
519           poly.push(x2 - kMinWidthT2 * 0.7, y2 + kMinWidthT2 * 0.7);\r
520           poly.push(x2, y2 + kMinWidthT2);\r
521           poly.push(x2 + kMinWidthT2 * 0.7, y2 + kMinWidthT2 * 0.7);\r
522           poly.push(x2 + kMinWidthT2, y2);\r
523         }\r
524         polygons.push(poly);\r
525       }\r
526       else if(sy2 == y2){\r
527         poly = new Polygon();\r
528         if(kage.kUseCurve){\r
529           // by curve path\r
530           poly.push(x2, y2 - kMinWidthT2);\r
531           poly.push(x2 + kMinWidthT2 * 0.9, y2 - kMinWidthT2 * 0.9, 1);\r
532           poly.push(x2 + kMinWidthT2, y2);\r
533           poly.push(x2 + kMinWidthT2 * 0.9, y2 + kMinWidthT2 * 0.9, 1);\r
534           poly.push(x2, y2 + kMinWidthT2);\r
535         } else {\r
536           // by polygon\r
537           poly.push(x2, y2 - kMinWidthT2);\r
538           poly.push(x2 + kMinWidthT2 * 0.7, y2 - kMinWidthT2 * 0.7);\r
539           poly.push(x2 + kMinWidthT2, y2);\r
540           poly.push(x2 + kMinWidthT2 * 0.7, y2 + kMinWidthT2 * 0.7);\r
541           poly.push(x2, y2 + kMinWidthT2);\r
542         }\r
543         polygons.push(poly);\r
544       }\r
545       else{\r
546         poly = new Polygon();\r
547         if(kage.kUseCurve){\r
548           poly.push(x2 + Math.sin(rad) * kMinWidthT2 * v, y2 - Math.cos(rad) * kMinWidthT2 * v);\r
549           poly.push(x2 + Math.cos(rad) * kMinWidthT2 * 0.9 * v + Math.sin(rad) * kMinWidthT2 * 0.9 * v,\r
550                     y2 + Math.sin(rad) * kMinWidthT2 * 0.9 * v - Math.cos(rad) * kMinWidthT2 * 0.9 * v, 1);\r
551           poly.push(x2 + Math.cos(rad) * kMinWidthT2 * v, y2 + Math.sin(rad) * kMinWidthT2 * v);\r
552           poly.push(x2 + Math.cos(rad) * kMinWidthT2 * 0.9 * v - Math.sin(rad) * kMinWidthT2 * 0.9 * v,\r
553                     y2 + Math.sin(rad) * kMinWidthT2 * 0.9 * v + Math.cos(rad) * kMinWidthT2 * 0.9 * v, 1);\r
554           poly.push(x2 - Math.sin(rad) * kMinWidthT2 * v, y2 + Math.cos(rad) * kMinWidthT2 * v);\r
555         } else {\r
556           poly.push(x2 + Math.sin(rad) * kMinWidthT2 * v, y2 - Math.cos(rad) * kMinWidthT2 * v);\r
557           poly.push(x2 + Math.cos(rad) * kMinWidthT2 * 0.7 * v + Math.sin(rad) * kMinWidthT2 * 0.7 * v,\r
558                     y2 + Math.sin(rad) * kMinWidthT2 * 0.7 * v - Math.cos(rad) * kMinWidthT2 * 0.7 * v);\r
559           poly.push(x2 + Math.cos(rad) * kMinWidthT2 * v, y2 + Math.sin(rad) * kMinWidthT2 * v);\r
560           poly.push(x2 + Math.cos(rad) * kMinWidthT2 * 0.7 * v - Math.sin(rad) * kMinWidthT2 * 0.7 * v,\r
561                     y2 + Math.sin(rad) * kMinWidthT2 * 0.7 * v + Math.cos(rad) * kMinWidthT2 * 0.7 * v);\r
562           poly.push(x2 - Math.sin(rad) * kMinWidthT2 * v, y2 + Math.cos(rad) * kMinWidthT2 * v);\r
563         }\r
564         polygons.push(poly);\r
565       }\r
566     }\r
567     \r
568     if(a2 == 9 || (a1 == 7 && a2 == 0)){ // Math.sinnyu & L2RD Harai ... no need for a2=9\r
569       var type = (Math.atan2(Math.abs(y2 - sy2), Math.abs(x2 - sx2)) / Math.PI * 2 - 0.6);\r
570       if(type > 0){\r
571         type = type * 8;\r
572       } else {\r
573         type = type * 3;\r
574       }\r
575       var pm = 0;\r
576       if(type < 0){\r
577         pm = -1;\r
578       } else {\r
579         pm = 1;\r
580       }\r
581       if(sy2 == y2){\r
582         poly = new Polygon();\r
583         poly.push(x2, y2 + kMinWidthT * kage.kL2RDfatten);\r
584         poly.push(x2, y2 - kMinWidthT * kage.kL2RDfatten);\r
585         poly.push(x2 + kMinWidthT * kage.kL2RDfatten * Math.abs(type), y2 + kMinWidthT * kage.kL2RDfatten * pm);\r
586         polygons.push(poly);\r
587       }\r
588       else{\r
589         poly = new Polygon();\r
590         poly.push(x2 + kMinWidthT * kage.kL2RDfatten * YX, y2 + kMinWidthT * kage.kL2RDfatten * YY);\r
591         poly.push(x2 - kMinWidthT * kage.kL2RDfatten * YX, y2 - kMinWidthT * kage.kL2RDfatten * YY);\r
592         poly.push(x2 + kMinWidthT * kage.kL2RDfatten * Math.abs(type) * XX + kMinWidthT * kage.kL2RDfatten * pm * YX,\r
593                   y2 + kMinWidthT * kage.kL2RDfatten * Math.abs(type) * XY + kMinWidthT * kage.kL2RDfatten * pm * YY);\r
594         polygons.push(poly);\r
595       }\r
596     }\r
597     \r
598     if(a2 == 15){ //jump up ... it can change 15->5\r
599       // anytime same degree\r
600       poly = new Polygon();\r
601       if(y1 < y2){\r
602         poly.push(x2, y2 - kMinWidthT + 1);\r
603         poly.push(x2 + 2, y2 - kMinWidthT - kage.kWidth * 5);\r
604         poly.push(x2, y2 - kMinWidthT - kage.kWidth * 5);\r
605         poly.push(x2 - kMinWidthT, y2 - kMinWidthT + 1);\r
606       } else {\r
607         poly.push(x2, y2 + kMinWidthT - 1);\r
608         poly.push(x2 - 2, y2 + kMinWidthT + kage.kWidth * 5);\r
609         poly.push(x2, y2 + kMinWidthT + kage.kWidth * 5);\r
610         poly.push(x2 + kMinWidthT, y2 + kMinWidthT - 1);\r
611       }\r
612       polygons.push(poly);\r
613     }\r
614     \r
615     if(a2 == 14){ //jump to left, allways go left\r
616       poly = new Polygon();\r
617       poly.push(x2, y2);\r
618       poly.push(x2, y2 - kMinWidthT);\r
619       poly.push(x2 - kage.kWidth * 4 * Math.min(1 - opt2 / 10, Math.pow(kMinWidthT / kage.kMinWidthT, 3)), y2 - kMinWidthT);\r
620       poly.push(x2 - kage.kWidth * 4 * Math.min(1 - opt2 / 10, Math.pow(kMinWidthT / kage.kMinWidthT, 3)), y2 - kMinWidthT * 0.5);\r
621       //poly.reverse();\r
622       polygons.push(poly);\r
623     }\r
624   }\r
625   else{ //gothic\r
626     if(a1 % 10 == 2){\r
627       if(x1 == sx1){\r
628         if(y1 < sy1){ y1 = y1 - kage.kWidth; } else{ y1 = y1 + kage.kWidth; }\r
629       }\r
630       else if(y1 == sy1){\r
631         if(x1 < sx1){ x1 = x1 - kage.kWidth; } else{ x1 = x1 + kage.kWidth; }\r
632       }\r
633       else{\r
634         rad = Math.atan((sy1 - y1) / (sx1 - x1));\r
635         if(x1 < sx1){ v = 1; } else{ v = -1; }\r
636         x1 = x1 - kage.kWidth * Math.cos(rad) * v;\r
637         y1 = y1 - kage.kWidth * Math.sin(rad) * v;\r
638       }\r
639     }\r
640     \r
641     if(a1 % 10 == 3){\r
642       if(x1 == sx1){\r
643         if(y1 < sy1){\r
644           y1 = y1 - kage.kWidth * kage.kKakato;\r
645         }\r
646         else{\r
647           y1 = y1 + kage.kWidth * kage.kKakato;\r
648         }\r
649       }\r
650       else if(y1 == sy1){\r
651         if(x1 < sx1){\r
652           x1 = x1 - kage.kWidth * kage.kKakato;\r
653         }\r
654         else{\r
655           x1 = x1 + kage.kWidth * kage.kKakato;\r
656         }\r
657       }\r
658       else{\r
659         rad = Math.atan((sy1 - y1) / (sx1 - x1));\r
660         if(x1 < sx1){ v = 1; } else{ v = -1; }\r
661         x1 = x1 - kage.kWidth * Math.cos(rad) * v * kage.kKakato;\r
662         y1 = y1 - kage.kWidth * Math.sin(rad) * v * kage.kKakato;\r
663       }\r
664     }\r
665     if(a2 % 10 == 2){\r
666       if(sx2 == x2){\r
667         if(sy2 < y2){ y2 = y2 + kage.kWidth; } else{ y2 = y2 - kage.kWidth; }\r
668       }\r
669       else if(sy2 == y2){\r
670         if(sx2 < x2){ x2 = x2 + kage.kWidth; } else{ x2 = x2 - kage.kWidth; }\r
671       }\r
672       else{\r
673         rad = Math.atan((y2 - sy2) / (x2 - sx2));\r
674         if(sx2 < x2){ v = 1; } else{ v = -1; }\r
675         x2 = x2 + kage.kWidth * Math.cos(rad) * v;\r
676         y2 = y2 + kage.kWidth * Math.sin(rad) * v;\r
677       }\r
678     }\r
679     \r
680     if(a2 % 10 == 3){\r
681       if(sx2 == x2){\r
682         if(sy2 < y2){\r
683           y2 = y2 + kage.kWidth * kage.kKakato;\r
684         }\r
685         else{\r
686           y2 = y2 - kage.kWidth * kage.kKakato;\r
687         }\r
688       }\r
689       else if(sy2 == y2){\r
690         if(sx2 < x2){\r
691           x2 = x2 + kage.kWidth * kage.kKakato;\r
692         }\r
693         else{\r
694           x2 = x2 - kage.kWidth * kage.kKakato;\r
695         }\r
696       }\r
697       else{\r
698         rad = Math.atan((y2 - sy2) / (x2 - sx2));\r
699         if(sx2 < x2){ v = 1; } else{ v = -1; }\r
700         x2 = x2 + kage.kWidth * Math.cos(rad) * v * kage.kKakato;\r
701         y2 = y2 + kage.kWidth * Math.sin(rad) * v * kage.kKakato;\r
702       }\r
703     }\r
704     \r
705     poly = new Polygon();\r
706     poly2 = new Polygon();\r
707     \r
708     for(tt = 0; tt <= 1000; tt = tt + kage.kRate){\r
709       t = tt / 1000;\r
710       \r
711       if(sx1 == sx2 && sy1 == sy2){\r
712         //calculating each point\r
713         x = ((1.0 - t) * (1.0 - t) * x1 + 2.0 * t * (1.0 - t) * sx1 + t * t * x2);\r
714         y = ((1.0 - t) * (1.0 - t) * y1 + 2.0 * t * (1.0 - t) * sy1 + t * t * y2);\r
715         \r
716         //SESSEN NO KATAMUKI NO KEISAN(BIBUN)\r
717         ix = (x1 - 2.0 * sx1 + x2) * 2.0 * t + (-2.0 * x1 + 2.0 * sx1);\r
718         iy = (y1 - 2.0 * sy1 + y2) * 2.0 * t + (-2.0 * y1 + 2.0 * sy1);\r
719       } else {\r
720       }\r
721       //SESSEN NI SUICHOKU NA CHOKUSEN NO KEISAN\r
722       if(kage.kShotai == kage.kMincho){ //always false ?\r
723         if(ix != 0 && iy != 0){\r
724           ir = Math.atan(iy / ix * -1.0);\r
725           ia = Math.sin(ir) * kage.kMinWidthT;\r
726           ib = Math.cos(ir) * kage.kMinWidthT;\r
727         }\r
728         else if(ix == 0){\r
729           ia = kage.kMinWidthT;\r
730           ib = 0;\r
731         }\r
732         else{\r
733           ia = 0;\r
734           ib = kage.kMinWidthT;\r
735         }\r
736         ia = ia * Math.sqrt(1.0 - t);\r
737         ib = ib * Math.sqrt(1.0 - t);\r
738       }\r
739       else{\r
740         if(ix != 0 && iy != 0){\r
741           ir = Math.atan(iy / ix * -1.0);\r
742           ia = Math.sin(ir) * kage.kWidth;\r
743           ib = Math.cos(ir) * kage.kWidth;\r
744         }\r
745         else if(ix == 0){\r
746           ia = kage.kWidth;\r
747           ib = 0;\r
748         }\r
749         else{\r
750           ia = 0;\r
751           ib = kage.kWidth;\r
752         }\r
753       }\r
754       \r
755       //reverse if vector is going 2nd/3rd quadrants\r
756       if(ix <= 0){\r
757         ia = ia * -1;\r
758         ib = ib * -1;\r
759       }\r
760       \r
761       //save to polygon\r
762       poly.push(x - ia, y - ib);\r
763       poly2.push(x + ia, y + ib);\r
764     }\r
765     \r
766     poly2.reverse();\r
767     poly.concat(poly2);\r
768     polygons.push(poly);\r
769   }\r
770 }\r
771 \r
772 function cdDrawBezier(kage, polygons, x1, y1, x2, y2, x3, y3, x4, y4, a1, a2){\r
773   cdDrawCurveU(kage, polygons, x1, y1, x2, y2, x3, y3, x4, y4, a1, a2);\r
774 }\r
775 \r
776 function cdDrawCurve(kage, polygons, x1, y1, x2, y2, x3, y3, a1, a2){\r
777   cdDrawCurveU(kage, polygons, x1, y1, x2, y2, x2, y2, x3, y3, a1, a2);\r
778 }\r
779 \r
780 function cdDrawLine(kage, polygons, tx1, ty1, tx2, ty2, ta1, ta2){\r
781   var rad;\r
782   var v, x1, y1, x2, y2;\r
783   var a1, a2, opt1, opt2;\r
784   var XX, XY, YX, YY;\r
785   var poly;\r
786   var kMinWidthT;\r
787   \r
788   if(kage.kShotai == kage.kMincho){ //mincho\r
789     x1 = tx1;\r
790     y1 = ty1;\r
791     x2 = tx2;\r
792     y2 = ty2;\r
793     a1 = ta1 % 1000;\r
794     a2 = ta2 % 100;\r
795     opt1 = Math.floor(ta1 / 1000);\r
796     opt2 = Math.floor(ta2 / 100);\r
797     \r
798     kMinWidthT = kage.kMinWidthT - opt1 / 2;\r
799     \r
800     if(x1 == x2){ //if TATE stroke, use y-axis\r
801       poly = new Polygon(4);\r
802       switch(a1){\r
803       case 0:\r
804         poly.set(3, x1 - kMinWidthT, y1 - kage.kMinWidthY / 2);\r
805         poly.set(0, x1 + kMinWidthT, y1 + kage.kMinWidthY / 2);\r
806         break;\r
807       case 1:\r
808       case 6: //... no need\r
809       case 22:\r
810         poly.set(3, x1 - kMinWidthT, y1);\r
811         poly.set(0, x1 + kMinWidthT, y1);\r
812         break;\r
813       case 12:\r
814         poly.set(3, x1 - kMinWidthT, y1 - kage.kMinWidthY - kMinWidthT);\r
815         poly.set(0, x1 + kMinWidthT, y1 - kage.kMinWidthY);\r
816         break;\r
817       case 32:\r
818         poly.set(3, x1 - kMinWidthT, y1 - kage.kMinWidthY);\r
819         poly.set(0, x1 + kMinWidthT, y1 - kage.kMinWidthY);\r
820         break;\r
821       }\r
822       \r
823       switch(a2){\r
824       case 0:\r
825         if(a1 == 6){ //KAGI's tail ... no need\r
826           poly.set(2, x2 - kMinWidthT, y2);\r
827           poly.set(1, x2 + kMinWidthT, y2);\r
828         }\r
829         else{\r
830           poly.set(2, x2 - kMinWidthT, y2 + kMinWidthT / 2);\r
831           poly.set(1, x2 + kMinWidthT, y2 - kMinWidthT / 2);\r
832         }\r
833         break;\r
834       case 1:\r
835         poly.set(2, x2 - kMinWidthT, y2);\r
836         poly.set(1, x2 + kMinWidthT, y2);\r
837         break;\r
838       case 13:\r
839         poly.set(2, x2 - kMinWidthT, y2 + kage.kAdjustKakatoL[opt2] + kMinWidthT);\r
840         poly.set(1, x2 + kMinWidthT, y2 + kage.kAdjustKakatoL[opt2]);\r
841         break;\r
842       case 23:\r
843         poly.set(2, x2 - kMinWidthT, y2 + kage.kAdjustKakatoR[opt2] + kMinWidthT);\r
844         poly.set(1, x2 + kMinWidthT, y2 + kage.kAdjustKakatoR[opt2]);\r
845         break;\r
846       case 32:\r
847         poly.set(2, x2 - kMinWidthT, y2 + kage.kMinWidthY);\r
848         poly.set(1, x2 + kMinWidthT, y2 + kage.kMinWidthY);\r
849         break;\r
850       }\r
851       \r
852       polygons.push(poly);\r
853       \r
854       if(a1 == 22){ //box's right top corner\r
855         poly = new Polygon();\r
856         poly.push(x1 - kMinWidthT, y1 - kage.kMinWidthY);\r
857         poly.push(x1, y1 - kage.kMinWidthY - kage.kWidth);\r
858         poly.push(x1 + kMinWidthT + kage.kWidth, y1 + kage.kMinWidthY);\r
859         poly.push(x1 + kMinWidthT, y1 + kMinWidthT);\r
860         poly.push(x1 - kMinWidthT, y1);\r
861         polygons.push(poly);\r
862       }\r
863       \r
864       if(a1 == 0){ //beginning of the stroke\r
865         poly = new Polygon();\r
866         poly.push(x1 + kMinWidthT, y1 + kage.kMinWidthY * 0.5);\r
867         poly.push(x1 + kMinWidthT + kMinWidthT * 0.5, y1 + kage.kMinWidthY * 0.5 + kage.kMinWidthY);\r
868         poly.push(x1 + kMinWidthT - 2, y1 + kage.kMinWidthY * 0.5 + kage.kMinWidthY * 2 + 1);\r
869         polygons.push(poly);\r
870       }\r
871       \r
872       if((a1 == 6 && a2 == 0) || a2 == 1){ //KAGI NO YOKO BOU NO SAIGO NO MARU ... no need only used at 1st=yoko\r
873         poly = new Polygon();\r
874         if(kage.kUseCurve){\r
875           poly.push(x2 - kMinWidthT, y2);\r
876           poly.push(x2 - kMinWidthT * 0.9, y2 + kMinWidthT * 0.9, 1);\r
877           poly.push(x2, y2 + kMinWidthT);\r
878           poly.push(x2 + kMinWidthT * 0.9, y2 + kMinWidthT * 0.9, 1);\r
879           poly.push(x2 + kMinWidthT, y2);\r
880         } else {\r
881           poly.push(x2 - kMinWidthT, y2);\r
882           poly.push(x2 - kMinWidthT * 0.6, y2 + kMinWidthT * 0.6);\r
883           poly.push(x2, y2 + kMinWidthT);\r
884           poly.push(x2 + kMinWidthT * 0.6, y2 + kMinWidthT * 0.6);\r
885           poly.push(x2 + kMinWidthT, y2);\r
886         }\r
887         //poly.reverse(); // for fill-rule\r
888         polygons.push(poly);\r
889       }\r
890     }\r
891     else if(y1 == y2){ //if it is YOKO stroke, use x-axis\r
892       if(a1 == 6){ //if it is KAGI's YOKO stroke, get bold\r
893         poly = new Polygon();\r
894         poly.push(x1, y1 - kMinWidthT);\r
895         poly.push(x2, y2 - kMinWidthT);\r
896         poly.push(x2, y2 + kMinWidthT);\r
897         poly.push(x1, y1 + kMinWidthT);\r
898         polygons.push(poly);\r
899         \r
900         if(a2 == 1 || a2 == 0 || a2 == 5){ // no need a2=1\r
901           //KAGI NO YOKO BOU NO SAIGO NO MARU\r
902           poly = new Polygon();\r
903           if(kage.kUseCurve){\r
904             if(x1 < x2){\r
905               poly.push(x2, y2 - kMinWidthT);\r
906               poly.push(x2 + kMinWidthT * 0.9, y2 - kMinWidthT * 0.9, 1);\r
907               poly.push(x2 + kMinWidthT, y2);\r
908               poly.push(x2 + kMinWidthT * 0.9, y2 + kMinWidthT * 0.9, 1);\r
909               poly.push(x2, y2 + kMinWidthT);\r
910             } else {\r
911               poly.push(x2, y2 - kMinWidthT);\r
912               poly.push(x2 - kMinWidthT * 0.9, y2 - kMinWidthT * 0.9, 1);\r
913               poly.push(x2 - kMinWidthT, y2);\r
914               poly.push(x2 - kMinWidthT * 0.9, y2 + kMinWidthT * 0.9, 1);\r
915               poly.push(x2, y2 + kMinWidthT);\r
916             }\r
917           } else {\r
918             if(x1 < x2){\r
919               poly.push(x2, y2 - kMinWidthT);\r
920               poly.push(x2 + kMinWidthT * 0.6, y2 - kMinWidthT * 0.6);\r
921               poly.push(x2 + kMinWidthT, y2);\r
922               poly.push(x2 + kMinWidthT * 0.6, y2 + kMinWidthT * 0.6);\r
923               poly.push(x2, y2 + kMinWidthT);\r
924             } else {\r
925               poly.push(x2, y2 - kMinWidthT);\r
926               poly.push(x2 - kMinWidthT * 0.6, y2 - kMinWidthT * 0.6);\r
927               poly.push(x2 - kMinWidthT, y2);\r
928               poly.push(x2 - kMinWidthT * 0.6, y2 + kMinWidthT * 0.6);\r
929               poly.push(x2, y2 + kMinWidthT);\r
930             }\r
931           }\r
932           polygons.push(poly);\r
933         }\r
934         \r
935         if(a2 == 5){\r
936           //KAGI NO YOKO BOU NO HANE\r
937           poly = new Polygon();\r
938           if(x1 < x2){\r
939             poly.push(x2, y2 - kMinWidthT + 1);\r
940             poly.push(x2 + 2, y2 - kMinWidthT - kage.kWidth * (4 * (1 - opt1 / kage.kAdjustMageStep) + 1));\r
941             poly.push(x2, y2 - kMinWidthT - kage.kWidth * (4 * (1 - opt1 / kage.kAdjustMageStep) + 1));\r
942             poly.push(x2 - kMinWidthT, y2 - kMinWidthT + 1);\r
943           } else {\r
944             poly.push(x2, y2 - kMinWidthT + 1);\r
945             poly.push(x2 - 2, y2 - kMinWidthT - kage.kWidth * (4 * (1 - opt1 / kage.kAdjustMageStep) + 1));\r
946             poly.push(x2, y2 - kMinWidthT - kage.kWidth * (4 * (1 - opt1 / kage.kAdjustMageStep) + 1));\r
947             poly.push(x2 + kMinWidthT, y2 - kMinWidthT + 1);\r
948           }\r
949           //poly.reverse(); // for fill-rule\r
950           polygons.push(poly);\r
951         }\r
952       }\r
953       else{\r
954         //always same\r
955         poly = new Polygon(4);\r
956         poly.set(0, x1, y1 - kage.kMinWidthY);\r
957         poly.set(1, x2, y2 - kage.kMinWidthY);\r
958         poly.set(2, x2, y2 + kage.kMinWidthY);\r
959         poly.set(3, x1, y1 + kage.kMinWidthY);\r
960         polygons.push(poly);\r
961         \r
962         //UROKO\r
963         if(a2 == 0){\r
964           poly = new Polygon();\r
965           poly.push(x2, y2 - kage.kMinWidthY);\r
966           poly.push(x2 - kage.kAdjustUrokoX[opt2], y2);\r
967           poly.push(x2 - kage.kAdjustUrokoX[opt2] / 2, y2 - kage.kAdjustUrokoY[opt2]);\r
968           polygons.push(poly);\r
969         }\r
970       }\r
971     }\r
972     else{ //for others, use x-axis\r
973       rad = Math.atan((y2 - y1) / (x2 - x1));\r
974       if((Math.abs(y2 - y1) < Math.abs(x2 - x1)) && (a1 != 6) && (a2 != 6) && !(x1 > x2)){ //ASAI KAUDO\r
975         //always same\r
976         poly = new Polygon(4);\r
977         poly.set(0, x1 + Math.sin(rad) * kage.kMinWidthY, y1 - Math.cos(rad) * kage.kMinWidthY);\r
978         poly.set(1, x2 + Math.sin(rad) * kage.kMinWidthY, y2 - Math.cos(rad) * kage.kMinWidthY);\r
979         poly.set(2, x2 - Math.sin(rad) * kage.kMinWidthY, y2 + Math.cos(rad) * kage.kMinWidthY);\r
980         poly.set(3, x1 - Math.sin(rad) * kage.kMinWidthY, y1 + Math.cos(rad) * kage.kMinWidthY);\r
981         polygons.push(poly);\r
982         \r
983         //UROKO\r
984         if(a2 == 0){\r
985           poly = new Polygon();\r
986           poly.push(x2 + Math.sin(rad) * kage.kMinWidthY, y2 - Math.cos(rad) * kage.kMinWidthY);\r
987           poly.push(x2 - Math.cos(rad) * kage.kAdjustUrokoX[opt2], y2 - Math.sin(rad) * kage.kAdjustUrokoX[opt2]);\r
988           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
989           polygons.push(poly);\r
990         }\r
991       }\r
992       \r
993       else{ //KAKUDO GA FUKAI or KAGI NO YOKO BOU\r
994         if(x1 > x2){ v = -1; } else{ v = 1; }\r
995         poly = new Polygon(4);\r
996         switch(a1){\r
997         case 0:\r
998           poly.set(0, x1 + Math.sin(rad) * kMinWidthT * v + kage.kMinWidthY * Math.cos(rad) * 0.5 * v,\r
999                    y1 - Math.cos(rad) * kMinWidthT * v + kage.kMinWidthY * Math.sin(rad) * 0.5 * v);\r
1000           poly.set(3, x1 - Math.sin(rad) * kMinWidthT * v - kage.kMinWidthY * Math.cos(rad) * 0.5 * v,\r
1001                    y1 + Math.cos(rad) * kMinWidthT * v - kage.kMinWidthY * Math.sin(rad) * 0.5 * v);\r
1002           break;\r
1003         case 1:\r
1004         case 6:\r
1005           poly.set(0, x1 + Math.sin(rad) * kMinWidthT * v, y1 - Math.cos(rad) * kMinWidthT * v);\r
1006           poly.set(3, x1 - Math.sin(rad) * kMinWidthT * v, y1 + Math.cos(rad) * kMinWidthT * v);\r
1007           break;\r
1008         case 12:\r
1009           poly.set(0, x1 + Math.sin(rad) * kMinWidthT * v - kage.kMinWidthY * Math.cos(rad) * v,\r
1010                    y1 - Math.cos(rad) * kMinWidthT * v - kage.kMinWidthY * Math.sin(rad) * v);\r
1011           poly.set(3, x1 - Math.sin(rad) * kMinWidthT * v - (kMinWidthT + kage.kMinWidthY) * Math.cos(rad) * v,\r
1012                    y1 + Math.cos(rad) * kMinWidthT * v - (kMinWidthT + kage.kMinWidthY) * Math.sin(rad) * v);\r
1013           break;\r
1014         case 22:\r
1015           poly.set(0, x1 + (kMinWidthT * v + 1) / Math.sin(rad), y1 + 1);\r
1016           poly.set(3, x1 - (kMinWidthT * v) / Math.sin(rad), y1);\r
1017           break;\r
1018         case 32:\r
1019           poly.set(0, x1 + (kMinWidthT * v) / Math.sin(rad), y1);\r
1020           poly.set(3, x1 - (kMinWidthT * v) / Math.sin(rad), y1);\r
1021           break;\r
1022         }\r
1023         \r
1024         switch(a2){\r
1025         case 0:\r
1026           if(a1 == 6){\r
1027             poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v, y2 - Math.cos(rad) * kMinWidthT * v);\r
1028             poly.set(2, x2 - Math.sin(rad) * kMinWidthT * v, y2 + Math.cos(rad) * kMinWidthT * v);\r
1029           }\r
1030           else{\r
1031             poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v - kMinWidthT * 0.5 * Math.cos(rad) * v,\r
1032                      y2 - Math.cos(rad) * kMinWidthT * v - kMinWidthT * 0.5 * Math.sin(rad) * v);\r
1033             poly.set(2, x2 - Math.sin(rad) * kMinWidthT * v + kMinWidthT * 0.5 * Math.cos(rad) * v,\r
1034                      y2 + Math.cos(rad) * kMinWidthT * v + kMinWidthT * 0.5 * Math.sin(rad) * v);\r
1035           }\r
1036           break;\r
1037         case 1: // is needed?\r
1038         case 5:\r
1039           poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v, y2 - Math.cos(rad) * kMinWidthT * v);\r
1040           poly.set(2, x2 - Math.sin(rad) * kMinWidthT * v, y2 + Math.cos(rad) * kMinWidthT * v);\r
1041           break;\r
1042         case 13:\r
1043           poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v + kage.kAdjustKakatoL[opt2] * Math.cos(rad) * v,\r
1044                    y2 - Math.cos(rad) * kMinWidthT * v + kage.kAdjustKakatoL[opt2] * Math.sin(rad) * v);\r
1045           poly.set(2, x2 - Math.sin(rad) * kMinWidthT * v + (kage.kAdjustKakatoL[opt2] + kMinWidthT) * Math.cos(rad) * v,\r
1046                    y2 + Math.cos(rad) * kMinWidthT * v + (kage.kAdjustKakatoL[opt2] + kMinWidthT) * Math.sin(rad) * v);\r
1047           break;\r
1048         case 23:\r
1049           poly.set(1, x2 + Math.sin(rad) * kMinWidthT * v + kage.kAdjustKakatoR[opt2] * Math.cos(rad) * v,\r
1050                    y2 - Math.cos(rad) * kMinWidthT * v + kage.kAdjustKakatoR[opt2] * Math.sin(rad) * v);\r
1051           poly.set(2,\r
1052                    x2 - Math.sin(rad) * kMinWidthT * v + (kage.kAdjustKakatoR[opt2] + kMinWidthT) * Math.cos(rad) * v,\r
1053                    y2 + Math.cos(rad) * kMinWidthT * v + (kage.kAdjustKakatoR[opt2] + kMinWidthT) * Math.sin(rad) * v);\r
1054           break;\r
1055         case 32:\r
1056           poly.set(1, x2 + (kMinWidthT * v) / Math.sin(rad), y2);\r
1057           poly.set(2, x2 - (kMinWidthT * v) / Math.sin(rad), y2);\r
1058           break;\r
1059         }\r
1060         \r
1061         polygons.push(poly);\r
1062         \r
1063         if((a1 == 6) && (a2 == 0 || a2 == 5)){ //KAGI NO YOKO BOU NO SAIGO NO MARU\r
1064           poly = new Polygon();\r
1065           if(kage.kUseCurve){\r
1066             poly.push(x2 + Math.sin(rad) * kMinWidthT * v, y2 - Math.cos(rad) * kMinWidthT * v);\r
1067             poly.push(x2 - Math.cos(rad) * kMinWidthT * 0.9 * v + Math.sin(rad) * kMinWidthT * 0.9 * v,\r
1068                       y2 + Math.sin(rad) * kMinWidthT * 0.9 * v - Math.cos(rad) * kMinWidthT * 0.9 * v, 1);\r
1069             poly.push(x2 + Math.cos(rad) * kMinWidthT * v, y2 + Math.sin(rad) * kMinWidthT * v);\r
1070             poly.push(x2 + Math.cos(rad) * kMinWidthT * 0.9 * v - Math.sin(rad) * kMinWidthT * 0.9 * v,\r
1071                       y2 + Math.sin(rad) * kMinWidthT * 0.9 * v + Math.cos(rad) * kMinWidthT * 0.9 * v, 1);\r
1072             poly.push(x2 - Math.sin(rad) * kMinWidthT * v, y2 + Math.cos(rad) * kMinWidthT * v);\r
1073           } else {\r
1074             poly.push(x2 + Math.sin(rad) * kMinWidthT * v, y2 - Math.cos(rad) * kMinWidthT * v);\r
1075             poly.push(x2 + Math.cos(rad) * kMinWidthT * 0.8 * v + Math.sin(rad) * kMinWidthT * 0.6 * v,\r
1076                       y2 + Math.sin(rad) * kMinWidthT * 0.8 * v - Math.cos(rad) * kMinWidthT * 0.6 * v);\r
1077             poly.push(x2 + Math.cos(rad) * kMinWidthT * v, y2 + Math.sin(rad) * kMinWidthT * v);\r
1078             poly.push(x2 + Math.cos(rad) * kMinWidthT * 0.8 * v - Math.sin(rad) * kMinWidthT * 0.6 * v,\r
1079                       y2 + Math.sin(rad) * kMinWidthT * 0.8 * v + Math.cos(rad) * kMinWidthT * 0.6 * v);\r
1080             poly.push(x2 - Math.sin(rad) * kMinWidthT * v, y2 + Math.cos(rad) * kMinWidthT * v);\r
1081           }\r
1082           polygons.push(poly);\r
1083         }\r
1084         \r
1085         if(a1 == 6 && a2 == 5){\r
1086           //KAGI NO YOKO BOU NO HANE\r
1087           poly = new Polygon();\r
1088           if(x1 < x2){\r
1089             poly.push(x2 + (kMinWidthT - 1) * Math.sin(rad) * v, y2 - (kMinWidthT - 1) * Math.cos(rad) * v);\r
1090             poly.push(x2 + 2 * Math.cos(rad) * v + (kMinWidthT + kage.kWidth * 5) * Math.sin(rad) * v,\r
1091                       y2 + 2 * Math.sin(rad) * v - (kMinWidthT + kage.kWidth * 5) * Math.cos(rad) * v);\r
1092             poly.push(x2 + (kMinWidthT + kage.kWidth * 5) * Math.sin(rad) * v,\r
1093                       y2 - (kMinWidthT + kage.kWidth * 5) * Math.cos(rad) * v);\r
1094             poly.push(x2 + (kMinWidthT - 1) * Math.sin(rad) * v - kMinWidthT * Math.cos(rad) * v,\r
1095                       y2 - (kMinWidthT - 1) * Math.cos(rad) * v - kMinWidthT * Math.sin(rad) * v);\r
1096           } else {\r
1097             poly.push(x2 - (kMinWidthT - 1) * Math.sin(rad) * v, y2 + (kMinWidthT - 1) * Math.cos(rad) * v);\r
1098             poly.push(x2 + 2 * Math.cos(rad) * v - (kMinWidthT + kage.kWidth * 5) * Math.sin(rad) * v,\r
1099                       y2 + 2 * Math.sin(rad) * v + (kMinWidthT + kage.kWidth * 5) * Math.cos(rad) * v);\r
1100             poly.push(x2 - (kMinWidthT + kage.kWidth * 5) * Math.sin(rad) * v,\r
1101                       y2 + (kMinWidthT + kage.kWidth * 5) * Math.cos(rad) * v);\r
1102             poly.push(x2 + (kMinWidthT - 1) * Math.sin(rad) * v - kMinWidthT * Math.cos(rad) * v,\r
1103                       y2 - (kMinWidthT - 1) * Math.cos(rad) * v - kMinWidthT * Math.sin(rad) * v);\r
1104           }\r
1105           polygons.push(poly);\r
1106         }\r
1107         \r
1108         if(a1 == 22){ //SHIKAKU MIGIUE UROKO NANAME DEMO MASSUGU MUKI\r
1109           poly = new Polygon();\r
1110           poly.push(x1 - kMinWidthT, y1 - kage.kMinWidthY);\r
1111           poly.push(x1, y1 - kage.kMinWidthY - kage.kWidth);\r
1112           poly.push(x1 + kMinWidthT + kage.kWidth, y1 + kage.kMinWidthY);\r
1113           poly.push(x1 + kMinWidthT, y1 + kMinWidthT - 1);\r
1114           poly.push(x1 - kMinWidthT, y1 + kMinWidthT + 4);\r
1115           polygons.push(poly);\r
1116         }\r
1117         \r
1118         XX = Math.sin(rad) * v;\r
1119         XY = Math.cos(rad) * v * -1;\r
1120         YX = Math.cos(rad) * v;\r
1121         YY = Math.sin(rad) * v;\r
1122         \r
1123         if(a1 == 0){ //beginning of the storke\r
1124           poly = new Polygon();\r
1125           poly.push(x1 + kMinWidthT * XX + (kage.kMinWidthY * 0.5) * YX,\r
1126                     y1 + kMinWidthT * XY + (kage.kMinWidthY * 0.5) * YY);\r
1127           poly.push(x1 + (kMinWidthT + kMinWidthT * 0.5) * XX + (kage.kMinWidthY * 0.5 + kage.kMinWidthY) * YX,\r
1128                     y1 + (kMinWidthT + kMinWidthT * 0.5) * XY + (kage.kMinWidthY * 0.5 + kage.kMinWidthY) * YY);\r
1129           poly.push(x1 + kMinWidthT * XX + (kage.kMinWidthY * 0.5 + kage.kMinWidthY * 2) * YX - 2 * XX,\r
1130                     y1 + kMinWidthT * XY + (kage.kMinWidthY * 0.5 + kage.kMinWidthY * 2) * YY + 1 * XY);\r
1131           polygons.push(poly);\r
1132         }\r
1133       }\r
1134     }\r
1135   }\r
1136   else{ //gothic\r
1137     if(tx1 == tx2){ //if TATE stroke, use y-axis\r
1138       if(ty1 > ty2){\r
1139         x1 = tx2;\r
1140         y1 = ty2;\r
1141         x2 = tx1;\r
1142         y2 = ty1;\r
1143         a1 = ta2;\r
1144         a2 = ta1;\r
1145       }\r
1146       else{\r
1147         x1 = tx1;\r
1148         y1 = ty1;\r
1149         x2 = tx2;\r
1150         y2 = ty2;\r
1151         a1 = ta1;\r
1152         a2 = ta2;\r
1153       }\r
1154       \r
1155       if(a1 % 10 == 2){ y1 = y1 - kage.kWidth; }\r
1156       if(a2 % 10 == 2){ y2 = y2 + kage.kWidth; }\r
1157       if(a1 % 10 == 3){ y1 = y1 - kage.kWidth * kage.kKakato; }\r
1158       if(a2 % 10 == 3){ y2 = y2 + kage.kWidth * kage.kKakato; }\r
1159       \r
1160       poly = new Polygon();\r
1161       poly.push(x1 - kage.kWidth, y1);\r
1162       poly.push(x2 - kage.kWidth, y2);\r
1163       poly.push(x2 + kage.kWidth, y2);\r
1164       poly.push(x1 + kage.kWidth, y1);\r
1165       //poly.reverse(); // for fill-rule\r
1166       \r
1167       polygons.push(poly);\r
1168     }\r
1169     else if(ty1 == ty2){ //if YOKO stroke, use x-axis\r
1170       if(tx1 > tx2){\r
1171         x1 = tx2;\r
1172         y1 = ty2;\r
1173         x2 = tx1;\r
1174         y2 = ty1;\r
1175         a1 = ta2;\r
1176         a2 = ta1;\r
1177       }\r
1178       else{\r
1179         x1 = tx1;\r
1180         y1 = ty1;\r
1181         x2 = tx2;\r
1182         y2 = ty2;\r
1183         a1 = ta1;\r
1184         a2 = ta2;\r
1185       }\r
1186       if(a1 % 10 == 2){ x1 = x1 - kage.kWidth; }\r
1187       if(a2 % 10 == 2){ x2 = x2 + kage.kWidth; }\r
1188       if(a1 % 10 == 3){ x1 = x1 - kage.kWidth * kage.kKakato; }\r
1189       if(a2 % 10 == 3){ x2 = x2 + kage.kWidth * kage.kKakato; }\r
1190       \r
1191       poly = new Polygon();\r
1192       poly.push(x1, y1 - kage.kWidth);\r
1193       poly.push(x2, y2 - kage.kWidth);\r
1194       poly.push(x2, y2 + kage.kWidth);\r
1195       poly.push(x1, y1 + kage.kWidth);\r
1196       \r
1197       polygons.push(poly);\r
1198     }\r
1199     else{ //for others, use x-axis\r
1200       if(tx1 > tx2){\r
1201         x1 = tx2;\r
1202         y1 = ty2;\r
1203         x2 = tx1;\r
1204         y2 = ty1;\r
1205         a1 = ta2;\r
1206         a2 = ta1;\r
1207       }\r
1208       else{\r
1209         x1 = tx1;\r
1210         y1 = ty1;\r
1211         x2 = tx2;\r
1212         y2 = ty2;\r
1213         a1 = ta1;\r
1214         a2 = ta2;\r
1215       }\r
1216       rad = Math.atan((y2 - y1) / (x2 - x1));\r
1217       if(a1 % 10 == 2){\r
1218         x1 = x1 - kage.kWidth * Math.cos(rad);\r
1219         y1 = y1 - kage.kWidth * Math.sin(rad);\r
1220       }\r
1221       if(a2 % 10 == 2){\r
1222         x2 = x2 + kage.kWidth * Math.cos(rad);\r
1223         y2 = y2 + kage.kWidth * Math.sin(rad);\r
1224       }\r
1225       if(a1 % 10 == 3){\r
1226         x1 = x1 - kage.kWidth * Math.cos(rad) * kage.kKakato;\r
1227         y1 = y1 - kage.kWidth * Math.sin(rad) * kage.kKakato;\r
1228       }\r
1229       if(a2 % 10 == 3){\r
1230         x2 = x2 + kage.kWidth * Math.cos(rad) * kage.kKakato;\r
1231         y2 = y2 + kage.kWidth * Math.sin(rad) * kage.kKakato;\r
1232       }\r
1233       \r
1234       //SUICHOKU NO ICHI ZURASHI HA Math.sin TO Math.cos NO IREKAE + x-axis MAINASU KA\r
1235       poly = new Polygon();\r
1236       poly.push(x1 + Math.sin(rad) * kage.kWidth, y1 - Math.cos(rad) * kage.kWidth);\r
1237       poly.push(x2 + Math.sin(rad) * kage.kWidth, y2 - Math.cos(rad) * kage.kWidth);\r
1238       poly.push(x2 - Math.sin(rad) * kage.kWidth, y2 + Math.cos(rad) * kage.kWidth);\r
1239       poly.push(x1 - Math.sin(rad) * kage.kWidth, y1 + Math.cos(rad) * kage.kWidth);\r
1240       \r
1241       polygons.push(poly);\r
1242     }\r
1243   }\r
1244 }\r