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