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