Fixed (Temporary).
[chise/kage.git] / kagecgi / kagecomb.c
1 //kagecomb.c\r
2 //\r
3 \r
4 #include "kage.h"\r
5 #include "kagecgi.h"\r
6 #include "sysdep.h"\r
7 \r
8 void combineYoko2(const KGString *parts1, const KGString *parts3, int *result){\r
9     int f, g, h, i, j, k, l;\r
10     int flg_boxL, flg_boxR;\r
11     int Xside, YsideLa, YsideLb, YsideRa, YsideRb, YheightL, YnanameL, YsmallL;\r
12     int pxL, pxR, pyL, pyR;\r
13     double prL, prR, pryL, pryR, rL, rR, rTemp;\r
14     int lxL, rxL, lxR, rxR;\r
15     int dlyL, dryL, dlyR, dryR;\r
16     int chk_y1, chk_y2;\r
17     int mitsuL, mitsuR;\r
18     double yokoL, tateL, yokoR, tateR;\r
19         int *buf, strokes;\r
20         int tempShotai;\r
21         \r
22         //initialize\r
23     pxL = 0;\r
24     pyL = 0;\r
25     prL = 1.0;\r
26     pryL = 1.0;\r
27     pxR = 0;\r
28     pyR = 0;\r
29     prR = 1.0;\r
30     pryR = 1.0;\r
31         \r
32     YsideLa = 0;\r
33     YsideLb = 0;\r
34     YsideRa = 0;\r
35     YsideRb = 0;\r
36         YnanameL = 0;\r
37     YheightL = pngWidth * 0.9;\r
38         \r
39         tempShotai = kShotai;\r
40         kShotai = kGothic;\r
41         \r
42     CalcOptions(parts1, &mitsuL, &flg_boxL, &yokoL, &tateL);\r
43     CalcOptions(parts3, &mitsuR, &flg_boxR, &yokoR, &tateR);\r
44         \r
45         //left parts Y-axis processing #1\r
46     //if its upper and bottom are flat\r
47     if(flg_boxL % 8 / 4 != 0) YsideLa++;\r
48     if(flg_boxL % 16 / 8 != 0) YsideLb++;\r
49         \r
50     //if its goes right-up\r
51         if(flg_boxL % 1024 / 512 == 0){\r
52             j = 0;\r
53                 buf = convertStroke(parts1->str, buf, &strokes);\r
54                 for(i = 0; i < strokes; i++) if(buf[i * 11 + 0] / 10 == 1) j++;\r
55             free(buf);\r
56             l = 0;\r
57             if(j != 0){\r
58                         YsideLb++;\r
59                 YnanameL++;\r
60                 }\r
61         }\r
62     YheightL = YheightL - (YsideLa + YsideLb) * 2 * kWidth;\r
63         \r
64         //left parts Y-axis processing #2\r
65     YsmallL = 0;\r
66         if(flg_boxL % 1024 / 512 == 0){\r
67                 YsmallL = 1;\r
68             if(flg_boxL % 16 / 8 != 0 && flg_boxL % 8 / 4 != 0 && tateL <= 4) YheightL = (double)YheightL * (max(0.65, tateL * 0.22));\r
69                 else if(flg_boxL % 16 / 8 != 0 && tateL <= 3) YheightL = (double)YheightL * 0.8;\r
70         else if(YnanameL != 0 && flg_boxL % 8 / 4 != 0 && tateL <= 4) YheightL = (double)YheightL * (max(0.65, tateL * 0.22));\r
71             else if(YnanameL != 0 && tateL <= 3) YheightL = (double)YheightL * 0.8;\r
72             else YsmallL = 0;\r
73         }\r
74         \r
75         //left parts Y-axis processing #3\r
76     DoDrawParts(parts1, pxL, prL, pyL, pryL);\r
77     DotsHeight(&dlyL, &dryL);\r
78     pryL = (double)YheightL / (dryL - dlyL);\r
79         \r
80     if(YsmallL != 0){\r
81         if(flg_boxL % 8 / 4 != 0) pyL = kBaseline - (double)pngWidth * 0.9 + 6 * kWidth - dlyL * pryL;\r
82         else pyL = kBaseline - (double)pngWidth * 0.9 + 2 * kWidth - dlyL * pryL;\r
83     }\r
84     else{\r
85         if(flg_boxL % 16 / 8 != 0 || YnanameL != 0) pyL = kBaseline - 2 * kWidth - dryL * pryL;\r
86         else pyL = kBaseline - dryL * pryL;\r
87     }\r
88         \r
89         //right parts Y-axis processing #1\r
90     if(flg_boxR % 8 / 4 != 0) YsideRa++;\r
91     if(flg_boxR % 16 / 8 != 0) YsideRb++;\r
92         \r
93     DoDrawParts(parts3, pxR, prR, pyR, pryR);\r
94         DotsHeight(&dlyR, &dryR);\r
95         \r
96         if(flg_boxR % 512 / 256 != 0 && flg_boxR % 1024 / 512 == 0){\r
97                 pryR = pngWidth * 0.9 * 0.8 / (dryR - dlyR);\r
98                 pyR = kBaseline - pngWidth * 0.9 + 6 * kWidth - dlyR * pryR;\r
99         }\r
100         else{\r
101                 pryR = ((double)pngWidth * 0.9 - (YsideRa + YsideRb) * 2 * kWidth) / (dryR - dlyR);\r
102                 pyR = kBaseline - dryR * pryR;\r
103                 if(flg_boxR % 16 / 8 != 0) pyR = pyR - 2 * kWidth;\r
104         }\r
105         \r
106         //calculate ratio\r
107         rL = yokoL;\r
108         rR = yokoR;\r
109         \r
110         if(flg_boxL % 2 / 1 != 0) rL = rL * 0.7;\r
111         if(flg_boxL % 4 / 2 != 0) rL = rL * 0.7;\r
112         if(flg_boxR % 2 / 1 != 0) rR = rR * 0.7;\r
113         if(flg_boxR % 4 / 2 != 0) rR = rR * 0.7;\r
114         \r
115         rL = pow(rL, 0.6);\r
116         rR = pow(rR, 0.6);\r
117         \r
118         rR = rR * 1.05;\r
119         \r
120         rTemp = rL + rR;\r
121         rL = rL / rTemp;\r
122         rR = rR / rTemp;\r
123         \r
124 //    if(r < 0.3) r = 0.3;\r
125 //    else if(r > 0.7) r = 0.7;\r
126         \r
127     prL = rL;\r
128     prR = rR;\r
129         \r
130         //calculate width of each parts #1\r
131         Xside = 0;\r
132     if(flg_boxL % 2 / 1 != 0) Xside++;\r
133     if(flg_boxR % 4 / 2 != 0) Xside++;\r
134         \r
135 //    DrawBox();\r
136 //    drawGlyph(parts1, 1);\r
137 //    DotsWidth(&lxL, &rxL);\r
138 //    DrawBox();\r
139 //    drawGlyph(parts3, 1);\r
140 //    DotsWidth(&lxR, &rxR);\r
141     PartsWidth(parts1, &lxL, &rxL);\r
142     PartsWidth(parts3, &lxR, &rxR);\r
143     g = 0;\r
144         \r
145         //calculate width of each parts #2\r
146 //1    pxL = kWidth * 2 + (pngWidth - kWidth * 2 * 2) * prL * 0.5 - (lxL + rxL) / 2 * prL;\r
147 //1    pxR = kWidth * 2 + (pngWidth - kWidth * 2 * 2) * prL + kWidth * 2 * 2 + (pngWidth - kWidth * 2 * 2) * prR * 0.5 - (lxR + rxR) / 2 * prR;\r
148 //2    pxR = pngWidth * prL + kWidth * 4 + pngWidth * prR * 0.5 - (lxR + rxR) / 2 * prR;\r
149 //3    pxL = pngWidth * prL * 0.5 - (lxL + rxL) / 2 * prL;\r
150 //3    pxR = pngWidth * prL + pngWidth * prR * 0.5 - (lxR + rxR) / 2 * prR;\r
151     pxL = 0;\r
152     pxR = pngWidth * prL;\r
153         \r
154     DoDrawMixFont(parts1, pxL, prL, parts3, pxR, prR, pyL, pryL, pyR, pryR);\r
155         \r
156         //count dots for check crossing over\r
157         DotsHeight(&chk_y1, &chk_y2);\r
158         k = 0;\r
159         for(i = 0; i < pngWidth * 1.1; i++){\r
160                 for(j = chk_y1; j <= chk_y2; j++){\r
161                         if(kageCanvas[j][i] == 0) k++;\r
162                 }\r
163         }\r
164         l = k;\r
165         //fprintf(stderr,"%d,%d\n",chk_y1,chk_y2);\r
166         \r
167         //get close both parts\r
168         h = pxR;\r
169         while(k - l < kMixdot && g < kWidth * 2 * kKasane * 2){\r
170                 g = g + 2;\r
171                 f = pxR - g;\r
172         DoDrawMixFont(parts1, pxL, prL, parts3, f, prR, pyL, pryL, pyR, pryR);\r
173                 \r
174                 //char fn[256];\r
175                 //FILE *fp;\r
176                 //snprintf(fn,sizeof(fn),"%03d.png",g);\r
177         //fp = fopen(fn, "w");\r
178         //writePng(pngWidth, pngHeight, kageCanvas, fp);\r
179         //fclose(fp);\r
180                 \r
181         l = 0;\r
182         for(i = 0; i < pngWidth * 1.1; i++){\r
183                         for(j = chk_y1; j <= chk_y2; j++){\r
184                 if(kageCanvas[j][i] == 0) l++;\r
185             }\r
186         }\r
187     }\r
188         //fprintf(stderr,"%d:%d:%d\n",g,k,l);\r
189     pxR = f;\r
190     //if(flg_boxR % 256 / 128 != 0) pxR = pxR + kWidth * 2 * kKasane * 10 / 2;\r
191     //if(flg_boxR % 64 / 32 != 0) pxR = pxR + kWidth * 2 * kKasane * 8 / 2;\r
192     //else if(k - l > pngWidth * 0.4){\r
193     //  if(kShotai == kMincho) pxR = pxR + kMinWidthT * 2 * kKasane * 8 / 2;\r
194         //      else if(kShotai == kGothic)  pxR = pxR + kWidth * 2 * kKasane * 8 / 2;\r
195     //}\r
196     if((flg_boxL % 2 / 1 != 0) && (flg_boxR % 4 / 2 != 0)){\r
197         if(kShotai == kMincho) pxR = pxR + kMinWidthT * 2 * kKasane * 6 / 2;\r
198         else pxR = pxR + kWidth * 2 * kKasane * 6 / 2;\r
199     }\r
200     else pxR = pxR + kWidth * 2 * kKasane * 2 / 2;\r
201         \r
202         //set results\r
203         result[0] = pxL;\r
204         result[1] = pyL;\r
205         result[2] = pxL + pngWidth * prL;\r
206         result[3] = pyL + pngWidth * pryL;\r
207         result[8] = pxR;\r
208         result[9] = pyR;\r
209         result[10] = pxR + pngWidth * prR;\r
210         result[11] = pyR + pngWidth * pryR;\r
211         \r
212         kShotai = tempShotai;\r
213 }\r
214 \r
215 void combineYoko3(const KGString *parts1, const KGString *parts2, const KGString *parts3, int *result){\r
216         //not yet\r
217 }\r
218 \r
219 void combineTate2(const KGString *parts1, const KGString *parts3, int *result){\r
220     int f, g, h, i, j, k, l;\r
221     int flg_boxL, flg_boxR;\r
222     int pxL, pxR, pyL, pyR;\r
223     double prL, prR, pryL, pryR, rL, rR, rTemp;\r
224     int lxL, rxL, lxR, rxR;\r
225     int lyL, ryL, lyR, ryR;\r
226     int dlxL, drxL, dlxR, drxR;\r
227     int chk_x1, chk_x2;\r
228     int mitsuL, mitsuR;\r
229     double yokoL, tateL, yokoR, tateR;\r
230         int *buf, strokes;\r
231         int tempShotai;\r
232         \r
233         //initialize\r
234     pxL = 0;\r
235     pyL = 0;\r
236     prL = 1.0;\r
237     pryL = 1.0;\r
238     pxR = 0;\r
239     pyR = 0;\r
240     prR = 1.0;\r
241     pryR = 1.0;\r
242         \r
243         tempShotai = kShotai;\r
244         kShotai = kGothic;\r
245         \r
246     CalcOptions(parts1, &mitsuL, &flg_boxL, &yokoL, &tateL);\r
247     CalcOptions(parts3, &mitsuR, &flg_boxR, &yokoR, &tateR);\r
248         \r
249         //calculate ratio\r
250         rL = tateL;\r
251         rR = tateR;\r
252         \r
253         if(flg_boxL % 8 / 4 != 0) rL = rL * 0.7;\r
254         if(flg_boxL % 16 / 8 != 0) rL = rL * 0.7;\r
255         if(flg_boxR % 8 / 4 != 0) rR = rR * 0.7;\r
256         if(flg_boxR % 16 / 8 != 0) rR = rR * 0.7;\r
257         \r
258         rL = pow(rL, 0.8);\r
259         rR = pow(rR, 0.8);\r
260         \r
261         rR = rR * 1.1;\r
262         \r
263         rTemp = rL + rR;\r
264         rL = rL / rTemp;\r
265         rR = rR / rTemp;\r
266         \r
267 //    if(r < 0.3) r = 0.3;\r
268 //    else if(r > 0.7) r = 0.7;\r
269         \r
270     pryL = rL;\r
271     pryR = rR;\r
272         \r
273         //calucurate size of X-axis\r
274     PartsWidth(parts1, &lxL, &rxL);\r
275     PartsWidth(parts3, &lxR, &rxR);\r
276     PartsHeight(parts1, &lyL, &ryL);\r
277     PartsHeight(parts3, &lyR, &ryR);\r
278         \r
279         //left parts\r
280     if(flg_boxL % 64 / 32 != 0){\r
281                 buf = convertStroke(parts1->str, buf, &strokes);\r
282                 for(i = 0; i < strokes; i++){\r
283                         if(buf[i * 11 + 0] == 0) j = buf[i * 11 + 4]; // center line\r
284         }\r
285         k = max(j - lxL, rxL - j);// k : distance from center line\r
286         prL = (kSize * 0.9 * 0.5) / k;\r
287         if(k == j - lxL) pxL = 0;\r
288         else pxL = kSize * 0.5 - j * prL;\r
289     }\r
290     else if(flg_boxL % 2 / 1 != 0 && flg_boxL % 4 / 2 != 0 && flg_boxL % 32 / 16 == 0){\r
291         prL = min(1.0, (double)yokoL * 0.1 + 0.5) - ((kWidth * 6) / (kSize * 0.9));\r
292         DoDrawParts(parts1, pxL, prL, pyL, pryL);\r
293         DotsWidth(&dlxL, &drxL);\r
294         pxL = (kSize / 2 - (dlxL + drxL) / 2);\r
295     }\r
296     else if(flg_boxL % 128 / 64 != 0){\r
297         prL = 0.77;\r
298         DoDrawParts(parts1, pxL, prL, pyL, pryL);\r
299         DotsWidth(&dlxL, &drxL);\r
300         pxL = (kSize / 2 - (dlxL + drxL) / 2);\r
301     }\r
302     else if(flg_boxL % 2 / 1 != 0 && flg_boxL % 32 / 16 == 0){\r
303         prL = (kSize * 0.9 - kWidth * 4) / (rxL - lxL);\r
304                 pxL = kWidth * 4;\r
305     }\r
306     else if(flg_boxL % 4 / 2 != 0 && flg_boxL % 32 / 16 == 0){\r
307         prL = (kSize * 0.9 - kWidth * 4) / (rxL - lxL);\r
308         pxL = (kSize*0.05+kWidth*2) - lxL * prL;\r
309     }\r
310         \r
311         //right parts\r
312     if(flg_boxR % 64 / 32 != 0){\r
313                 buf = convertStroke(parts3->str, buf, &strokes);\r
314                 for(i = 0; i < strokes; i++){\r
315                         if(buf[i * 11 + 0] == 0) j = buf[i * 11 + 4]; // center line\r
316         }\r
317         k = max(j - lxR, rxR - j);// k : distance from center line\r
318         prR = (kSize * 0.9 * 0.5) / k;\r
319         if(k == j - lxR) pxR = 0;\r
320                 else pxR = kSize * 0.5 - j * prR;\r
321         }\r
322         else if(flg_boxR % 2 / 1 != 0 && flg_boxR % 4 / 2 != 0 && flg_boxR % 32 / 16 == 0){\r
323                 prR = min(1.0, (double)yokoR * 0.1 + 0.5) - ((kWidth * 6) / (kSize * 0.9));\r
324                 DoDrawParts(parts3, pxR, prR, pyR, pryR);\r
325                 DotsWidth(&dlxR, &drxR);\r
326                 pxR = (kSize / 2 - (dlxR + drxR) / 2);\r
327         }\r
328         else if(flg_boxR % 128 / 64 != 0){\r
329                 prR = 0.77;\r
330                 DoDrawParts(parts3, pxR, prR, pyR, pryR);\r
331                 DotsWidth(&dlxR, &drxR);\r
332                 pxR = (kSize / 2 - (dlxR + drxR) / 2);\r
333         }\r
334         else if(flg_boxR % 2 / 1 != 0 && flg_boxR % 32 / 16 == 0){\r
335                 prR = (kSize * 0.9 - kWidth * 4) / (rxR - lxR);\r
336 //            pxR = width * 4;\r
337                 pxR = (kSize*0.05+kWidth*3) - lxR * prR;\r
338         }\r
339         else if(flg_boxR % 4 / 2 != 0 && flg_boxR % 32 / 16 == 0){\r
340                 prR = (kSize * 0.9 - kWidth * 4) / (rxR - lxR);\r
341 //            pxR = (size*0.05+width*2) - lxR * prR;\r
342                 pxR = (kSize*0.05+kWidth*1) - lxR * prR;\r
343         }\r
344         \r
345         g = 0;\r
346         \r
347         //calculate width of each parts\r
348         pyL = kWidth * 1.5 + (kSize - kWidth * 1.5 * 4) * pryL * 0.5 - (lyL + ryL) / 2 * pryL;\r
349         pyR = kWidth * 1.5 + (kSize - kWidth * 1.5 * 4) * pryL + kWidth * 1.5 * 2 + (kSize - kWidth * 1.5 * 4) * pryR * 0.5 - (lyR + ryR) / 2 * pryR;\r
350         \r
351         DoDrawMixFont(parts1, pxL, prL, parts3, pxR, prR, pyL, pryL, pyR, pryR);\r
352         \r
353         //count dots for check crossing over\r
354         DotsWidth(&chk_x1, &chk_x2);\r
355         k = 0;\r
356         for(i = 0; i < pngWidth * 1.1; i++){\r
357                 for(j = chk_x1; j <= chk_x2; j++){\r
358                         if(kageCanvas[i][j] == 0) k++;\r
359                 }\r
360         }\r
361         l = k;\r
362         \r
363         //get close both parts\r
364         h = pyR;\r
365         while(k - l < kMixdot && g < kWidth * (kKasane + 4)){\r
366                 g = g + 2;\r
367                 f = pyR - g;\r
368         DoDrawMixFont(parts1, pxL, prL, parts3, pxR, prR, pyL, pryL, f, pryR);\r
369                 \r
370         l = 0;\r
371         for(i = 0; i < pngWidth * 1.1; i++){\r
372             for(j = chk_x1; j <= chk_x2; j++){\r
373                 if(kageCanvas[i][j] == 0) l++;\r
374             }\r
375         }\r
376     }\r
377     pyR = f;\r
378     if(k - l > pngWidth * 0.4) pyR = pyR + kWidth * 5;\r
379     else pyR = pyR + kWidth * 3;\r
380         \r
381         //set results\r
382         result[0] = pxL;\r
383         result[1] = pyL;\r
384         result[2] = pxL + pngWidth * prL;\r
385         result[3] = pyL + pngWidth * pryL;\r
386         result[8] = pxR;\r
387         result[9] = pyR;\r
388         result[10] = pxR + pngWidth * prR;\r
389         result[11] = pyR + pngWidth * pryR;\r
390         \r
391         kShotai = tempShotai;\r
392 }\r
393 \r
394 void combineTate3(const KGString *parts1, const KGString *parts2, const KGString *parts3, int *result){\r
395   //not yet\r
396 }\r
397 \r
398 void combineHame2(const KGString *parts1, const KGString *parts3, int *result){\r
399   int i, flag;\r
400   int *buf, strokes;\r
401 \r
402   flag = 0;\r
403 \r
404   //set results\r
405   result[0] = 0;\r
406   result[1] = 0;\r
407   result[2] = 200;\r
408   result[3] = 200;\r
409   buf = convertStroke(parts1->str, buf, &strokes);\r
410   for(i = 0; i < strokes; i++){\r
411     if(buf[i * 11 + 0] == 9){\r
412       result[8] = buf[i * 11 + 3];\r
413       result[9] = buf[i * 11 + 4];\r
414       result[10] = buf[i * 11 + 5];\r
415       result[11] = buf[i * 11 + 6];\r
416       flag = 1;\r
417     }\r
418   }\r
419   if(flag == 0){ //error\r
420     result[8] = 50;\r
421     result[9] = 50;\r
422     result[10] = 150;\r
423     result[11] = 150;\r
424   }\r
425   //not yet\r
426 }\r