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