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