Adjust LR combine function.
[chise/kage.git] / kagecgi / kagetool.c
1 //kagetool.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 DotsWidth(int *dlx, int *drx){\r
9         int i, j;\r
10         \r
11     *dlx = 0;\r
12     *drx = 0;\r
13     for(i = 0; i < canvasWidth && *dlx == 0; i++){\r
14                 for(j = 0; j < canvasHeight; j++){\r
15                         if(kageCanvas[j][i] == 0){\r
16                                 *dlx = i;\r
17                                 break;\r
18                         }\r
19                 }\r
20         }\r
21         \r
22         for(i = canvasWidth - 1; i >= 0 && *drx == 0; i--){\r
23                 for(j = 0; j < canvasHeight; j++){\r
24                         if(kageCanvas[j][i] == 0){\r
25                                 *drx = i;\r
26                                 break;\r
27                         }\r
28                 }\r
29         }\r
30 }\r
31 \r
32 void DotsHeight(int *dly, int *dry){\r
33     int i, j;\r
34         \r
35     *dly = 0;\r
36         *dry = 0;\r
37     for(j = 0; j < canvasHeight && *dly == 0; j++){\r
38         for(i = 0; i < canvasWidth; i++){\r
39             if(kageCanvas[j][i] == 0){\r
40                 *dly = j;\r
41                 break;\r
42             }\r
43         }\r
44     }\r
45         \r
46     for(j = canvasHeight - 1; j >= 0 && *dry == 0; j--){\r
47         for(i = 0; i < canvasWidth; i++){\r
48             if(kageCanvas[j][i] == 0){\r
49                 *dry = j;\r
50                 break;\r
51             }\r
52         }\r
53     }\r
54 }\r
55 \r
56 void PartsWidth(const KGString *in, int *lx, int *rx){\r
57         int tempShotai;\r
58     DrawBox();\r
59     tempShotai = kShotai;\r
60     kShotai = kGothic;\r
61     drawGlyph(in, 1);\r
62     kShotai = tempShotai;\r
63     DotsWidth(lx, rx);\r
64         /*\r
65     int i;\r
66         int *buf, strokes;\r
67         double t, x;\r
68         \r
69         *lx = 1000; *rx = 0;\r
70         buf = convertStroke(in->str, buf, &strokes);\r
71         \r
72     for(i = 0; i < strokes; i++){\r
73                 switch(buf[i * 11 + 0] % 10){\r
74                 \r
75                 case 0:\r
76                 case 9:\r
77                         break;\r
78                 case 1:\r
79                 if(*lx > buf[i * 11 + 3]) *lx = buf[i * 11 + 3];\r
80                         if(*rx < buf[i * 11 + 3]) *rx = buf[i * 11 + 3];\r
81                 if(*lx > buf[i * 11 + 5]) *lx = buf[i * 11 + 5];\r
82                 if(*rx < buf[i * 11 + 5]) *rx = buf[i * 11 + 5];\r
83                         break;\r
84                 case 2:\r
85                         for(t = 0; t <= 1; t = t + 0.05){\r
86                                 x = (1.0 - t) * (1.0 - t) * buf[i * 11 + 3] + 2.0 * t * (1.0 - t) * buf[i * 11 + 5] + t * t * buf[i * 11 + 7];\r
87                         if(*lx > x) *lx = x;\r
88                     if(*rx < x) *rx = x;\r
89                         }\r
90                         break;\r
91                 case 3:\r
92                 if(*lx > buf[i * 11 + 3]) *lx = buf[i * 11 + 3];\r
93                         if(*rx < buf[i * 11 + 3]) *rx = buf[i * 11 + 3];\r
94                 if(*lx > buf[i * 11 + 5]) *lx = buf[i * 11 + 5];\r
95                 if(*rx < buf[i * 11 + 5]) *rx = buf[i * 11 + 5];\r
96                 if(*lx > buf[i * 11 + 7]) *lx = buf[i * 11 + 7];\r
97             if(*rx < buf[i * 11 + 7]) *rx = buf[i * 11 + 7];\r
98                         break;\r
99                 case 6:\r
100                         for(t = 0; t < 1; t = t + 0.05){\r
101                                 x = (1.0 - t) * (1.0 - t) * (1.0 - t) * buf[i * 11 + 3] + 3.0 * t * (1.0 - t) * (1.0 - t) * buf[i * 11 + 5] + 3 * t * t * (1.0 - t) * buf[i * 11 + 7] + t * t * t * buf[i * 11 + 9];\r
102                         if(*lx > x) *lx = x;\r
103                     if(*rx < x) *rx = x;\r
104                         }\r
105                         break;\r
106                 case 7:\r
107                 if(*lx > buf[i * 11 + 3]) *lx = buf[i * 11 + 3];\r
108                         if(*rx < buf[i * 11 + 3]) *rx = buf[i * 11 + 3];\r
109                         for(t = 0; t < 1; t = t + 0.05){\r
110                                 x = (1.0 - t) * (1.0 - t) * buf[i * 11 + 5] + 2.0 * t * (1.0 - t) * buf[i * 11 + 7] + t * t * buf[i * 11 + 9];\r
111                         if(*lx > x) *lx = x;\r
112                     if(*rx < x) *rx = x;\r
113                         }\r
114                 }\r
115         }\r
116         free(buf);\r
117         */\r
118 }\r
119 \r
120 void PartsHeight(const KGString *in, int *ly, int *ry){\r
121         int tempShotai;\r
122     DrawBox();\r
123     tempShotai = kShotai;\r
124     kShotai = kGothic;\r
125     drawGlyph(in, 1);\r
126     kShotai = tempShotai;\r
127     DotsHeight(ly, ry);\r
128         /*\r
129     int i;\r
130         int *buf, strokes;\r
131         double t, y;\r
132         \r
133         *ly = 1000; *ry = 0;\r
134         buf = convertStroke(in->str, buf, &strokes);\r
135         \r
136     for(i = 0; i < strokes; i++){\r
137                 switch(buf[i * 11 + 0] % 10){\r
138                 \r
139                 case 0:\r
140                 case 9:\r
141                         break;\r
142                 case 1:\r
143                 if(*ly > buf[i * 11 + 4]) *ly = buf[i * 11 + 4];\r
144                         if(*ry < buf[i * 11 + 4]) *ry = buf[i * 11 + 4];\r
145                 if(*ly > buf[i * 11 + 6]) *ly = buf[i * 11 + 6];\r
146                 if(*ry < buf[i * 11 + 6]) *ry = buf[i * 11 + 6];\r
147                         break;\r
148                 case 2:\r
149                         for(t = 0; t <= 1; t = t + 0.05){\r
150                                 y = (1.0 - t) * (1.0 - t) * buf[i * 11 + 4] + 2.0 * t * (1.0 - t) * buf[i * 11 + 6] + t * t * buf[i * 11 + 8];\r
151                         if(*ly > y) *ly = y;\r
152                     if(*ry < y) *ry = y;\r
153                         }\r
154                         break;\r
155                 case 3:\r
156                 if(*ly > buf[i * 11 + 4]) *ly = buf[i * 11 + 4];\r
157                         if(*ry < buf[i * 11 + 4]) *ry = buf[i * 11 + 4];\r
158                 if(*ly > buf[i * 11 + 6]) *ly = buf[i * 11 + 6];\r
159                 if(*ry < buf[i * 11 + 6]) *ry = buf[i * 11 + 6];\r
160                 if(*ly > buf[i * 11 + 8]) *ly = buf[i * 11 + 8];\r
161             if(*ry < buf[i * 11 + 8]) *ry = buf[i * 11 + 8];\r
162                         break;\r
163                 case 6:\r
164                         for(t = 0; t < 1; t = t + 0.05){\r
165                                 y = (1.0 - t) * (1.0 - t) * (1.0 - t) * buf[i * 11 + 4] + 3.0 * t * (1.0 - t) * (1.0 - t) * buf[i * 11 + 6] + 3 * t * t * (1.0 - t) * buf[i * 11 + 8] + t * t * t * buf[i * 11 + 10];\r
166                         if(*ly > y) *ly = y;\r
167                     if(*ry < y) *ry = y;\r
168                         }\r
169                         break;\r
170                 case 7:\r
171                 if(*ly > buf[i * 11 + 4]) *ly = buf[i * 11 + 4];\r
172                         if(*ry < buf[i * 11 + 4]) *ry = buf[i * 11 + 4];\r
173                         for(t = 0; t < 1; t = t + 0.05){\r
174                                 y = (1.0 - t) * (1.0 - t) * buf[i * 11 + 6] + 2.0 * t * (1.0 - t) * buf[i * 11 + 8] + t * t * buf[i * 11 + 10];\r
175                         if(*ly > y) *ly = y;\r
176                     if(*ry < y) *ry = y;\r
177                         }\r
178                 }\r
179         }\r
180         free(buf);\r
181         */\r
182         /*\r
183     int i;\r
184         int *buf, strokes;\r
185         \r
186         buf = convertStroke(in->str, buf, &strokes);\r
187         *ly = 1000; *ry = 0;\r
188         \r
189     for(i = 0; i < strokes; i++){\r
190         if(buf[i * 11 + 0] % 10 == 0) continue;\r
191                 \r
192         if(*ly > buf[i * 11 + 4]) *ly = buf[i * 11 + 4];\r
193                 if(*ry < buf[i * 11 + 4]) *ry = buf[i * 11 + 4];\r
194         if(*ly > buf[i * 11 + 6]) *ly = buf[i * 11 + 6];\r
195         if(*ry < buf[i * 11 + 6]) *ry = buf[i * 11 + 6];\r
196                 \r
197         if(buf[i * 11 + 0] % 10 == 2 || buf[i * 11 + 0] % 10 == 3 || buf[i * 11 + 0] % 10 == 8){\r
198                 if(*ly > buf[i * 11 + 8]) *ly = buf[i * 11 + 8];\r
199             if(*ry < buf[i * 11 + 8]) *ry = buf[i * 11 + 8];\r
200                 }\r
201         if(buf[i * 11 + 0] % 10 == 4 || buf[i * 11 + 0] % 10 == 6 || buf[i * 11 + 0] % 10 == 7){\r
202                 if(*ly > buf[i * 11 + 10]) *ly = buf[i * 11 + 10];\r
203                 if(*ry < buf[i * 11 + 10]) *ry = buf[i * 11 + 10];\r
204         }\r
205         }\r
206         free(buf);\r
207         */\r
208 }\r
209 \r
210 KGString * CalcSizes(const KGString *in, int mode){\r
211     int i, j, k, basewidth, one_lineX, one_lineY;\r
212     int dlx1, drx1, dly1, dry1;\r
213         int px1, py1;\r
214     double pr1, pry1;\r
215         \r
216     int mitsuT, flg_boxT, widthT, heightT;\r
217     double tateT, yokoT;\r
218     int cutx, cuty;\r
219         \r
220         int *buf, strokes;\r
221         int tf[12];\r
222         KGString *out;\r
223         \r
224         out = kg_string_new("");\r
225     basewidth = pngWidth * 0.9;\r
226         \r
227     if(mode == 0){\r
228         //temporary adjustment X-axis\r
229         PartsWidth(in, &dlx1, &drx1);\r
230         if(dlx1 == drx1){\r
231             pr1 = 1.0;\r
232             px1 = pngWidth / 2 - dlx1;\r
233             one_lineX = 1;\r
234         }\r
235         else{\r
236             pr1 = (double)basewidth/(drx1 - dlx1);\r
237             px1 = (pngWidth-basewidth)/2 - (double)(dlx1 * pr1);\r
238             one_lineX = 0;\r
239         }\r
240                 \r
241         //temporary adjustment Y-axis\r
242         PartsHeight(in, &dly1, &dry1);\r
243         if(dly1 == dry1){\r
244             pry1 = 1.0;\r
245             py1 = pngWidth / 2 - dly1;\r
246             one_lineY = 1;\r
247         }\r
248                 else{\r
249             pry1 = (double)basewidth/(dry1 - dly1);\r
250             py1 = (pngWidth-basewidth)/2 - (double)(dly1 * pry1);\r
251             one_lineY = 0;\r
252         }\r
253     }\r
254         else{\r
255         PartsWidth(in, &dlx1, &drx1);\r
256         PartsHeight(in, &dly1, &dry1);\r
257                 \r
258         cutx = 0;\r
259         cuty = 0;\r
260                 \r
261         CalcOptions(in, &mitsuT, &flg_boxT, &yokoT, &tateT);\r
262                 \r
263         widthT = basewidth;\r
264         heightT = basewidth;\r
265                 \r
266         if(flg_boxT % 2 / 1 != 0){\r
267             widthT = widthT - kWidth * 3;\r
268             cutx++;\r
269         }\r
270         if(flg_boxT % 4 / 2 != 0){\r
271             widthT = widthT - kWidth * 3;\r
272             cutx++;\r
273         }\r
274         if(flg_boxT % 8 / 4 != 0){\r
275             heightT = heightT - kWidth * 3;\r
276             cuty++;\r
277         }\r
278         if(flg_boxT % 16 / 8 != 0){\r
279             heightT = heightT - kWidth * 3;\r
280             cuty++;\r
281         }\r
282                 \r
283         //especially get small the 'mouth'\r
284         if(mode == 2 && flg_boxT % 16 == 15){\r
285             widthT = widthT - kWidth * (max(0, 16 - (int)yokoT * 4));\r
286             heightT = heightT - kWidth * (max(0, 16 - (int)tateT * 4));\r
287                 }\r
288         //'dot' as same as 'mouth'\r
289         if(mode == 2 && tateT == 1 && yokoT == 1){\r
290             widthT = pngWidth * 0.9 * 0.5;\r
291             heightT = pngWidth * 0.9 * 0.5;\r
292         }\r
293                 \r
294           /*\r
295 if(flg_boxT % 64 / 32 != 0){\r
296             buf = convertStroke(in->str, buf, &strokes);\r
297             for(i = 0; i < strokes; i++){\r
298               if(buf[i * 11 + 0] == 0) j = buf[i * 11 + 4];// j : center line\r
299             }\r
300             free(buf);\r
301             k = max(j - dlx1, drx1 - j);// k : distance from center line\r
302             pr1 = (basewidth * 0.5) / k;\r
303             \r
304             if(k == j - dlx1) px1 = 0;\r
305             else px1 = pngWidth * 0.5 - j * pr1;\r
306           }\r
307         else\r
308 */\r
309           if(dlx1 == drx1){\r
310             pr1 = 1.0;\r
311             px1 = pngWidth / 2 - dlx1;\r
312           }\r
313           else{\r
314             pr1 = (double)widthT/(drx1 - dlx1);\r
315             px1 = pngWidth / 2 - (double)((dlx1 + drx1) / 2 * pr1);\r
316             if(flg_boxT % 2 / 1 != 0 && flg_boxT % 4 / 2 == 0) px1 = px1 + kWidth * 1.5;\r
317             if(flg_boxT % 2 / 1 == 0 && flg_boxT % 4 / 2 != 0) px1 = px1 - kWidth * 1.5;\r
318           }\r
319                 \r
320         if(dly1 == dry1){\r
321             pry1 = 1.0;\r
322             py1 = pngWidth / 2 - dly1;\r
323         }\r
324         else{\r
325             pry1 = (double)heightT/(dry1 - dly1);\r
326             py1 = pngWidth / 2 - (double)((dly1 + dry1) / 2 * pry1);\r
327             if(flg_boxT % 8 / 4 != 0 && flg_boxT % 16 / 8 == 0) py1 = py1 + kWidth * 1.5;\r
328             if(flg_boxT % 8 / 4 == 0 && flg_boxT % 16 / 8 != 0) py1 = py1 - kWidth * 1.5;\r
329         }\r
330         }\r
331         \r
332         //generate result\r
333         tf[0] = px1;\r
334         tf[1] = py1;\r
335         tf[2] = px1 + pr1 * 200;\r
336         tf[3] = py1 + pry1 * 200;\r
337         addStrokeWithTransform(in, 1, tf, out, 0);\r
338         return kg_string_new(out->str);\r
339 }\r
340 \r
341 void DrawBox(){\r
342         int i, j;\r
343         \r
344         for(i = 0; i < canvasWidth; i++){\r
345                 for(j = 0; j < canvasHeight; j++){\r
346                         kageCanvas[j][i] = 0xFF;\r
347                 }\r
348         }\r
349 }\r
350 \r
351 void CalcOptions(const KGString *in, int *mitsudo, int *flag, double *yoko, double *tate){\r
352     int i, j, k, l, flg;\r
353     int dlx1, drx1, dly1, dry1;\r
354     int kari, mode;\r
355         int tempShotai;\r
356         int *buf, strokes;\r
357         \r
358     *flag = 0;\r
359         \r
360     DrawBox();\r
361     tempShotai = kShotai;\r
362     kShotai = kGothic;\r
363     drawGlyph(in, 1);\r
364     kShotai = tempShotai;\r
365     DotsWidth(&dlx1, &drx1);\r
366     DotsHeight(&dly1, &dry1);\r
367         \r
368         //check left side\r
369     k = 0;\r
370     l = 0;\r
371     for(i = 0; i < pngWidth; i++){\r
372         flg = 0;\r
373         for(j = 0; j < kWidth; j++){\r
374             if(kageCanvas[i][dlx1 + j] == 0) flg = 1;\r
375         }\r
376         if(flg == 1){\r
377                 k++;\r
378         }\r
379         else{\r
380             if(k > l) l = k;\r
381             k = 0;\r
382         }\r
383     }\r
384     if(k > l) l = k;\r
385     \r
386     if(l > pngWidth * 0.9 / 4) *flag = *flag | 1;\r
387         \r
388     //check right side\r
389     k = 0;\r
390     l = 0;\r
391     for(i = 0; i < pngWidth; i++){\r
392         flg = 0;\r
393         for(j = 0; j < kWidth; j++){\r
394             if(kageCanvas[i][drx1 - j] == 0) flg = 1;\r
395         }\r
396         if(flg == 1) k++;\r
397         else{\r
398             if(k > l) l = k;\r
399             k = 0;\r
400         }\r
401     }\r
402     if(k > l) l = k;\r
403         \r
404     if(l > pngWidth * 0.9 / 4) *flag = *flag | 2;\r
405         \r
406     //check upper side\r
407     k = 0;\r
408     l = 0;\r
409     for(i = 0; i < pngWidth; i++){\r
410         flg = 0;\r
411                 for(j = 0; j < kWidth; j++){\r
412             if(kageCanvas[dly1 + j][i] == 0) flg = 1;\r
413         }\r
414         if(flg == 1) k++;\r
415         else{\r
416             if(k > l) l = k;\r
417             k = 0;\r
418         }\r
419     }\r
420     if(k > l) l = k;\r
421         \r
422     if(l > pngWidth * 0.9 / 4) *flag = *flag | 4;\r
423         \r
424     //check bottom side\r
425     k = 0;\r
426     l = 0;\r
427     for(i = 0; i < pngWidth; i++){\r
428         flg = 0;\r
429         for(j = 0; j < kWidth; j++){\r
430             if(kageCanvas[dry1 - j][i] == 0) flg = 1;\r
431         }\r
432         if(flg == 1) k++;\r
433         else{\r
434             if(k > l) l = k;\r
435             k = 0;\r
436         }\r
437     }\r
438     if(k > l) l = k;\r
439         \r
440     if(l > pngWidth * 0.9 / 4) *flag = *flag | 8;\r
441         \r
442     //count black dots\r
443     *mitsudo = 0;\r
444     for(i = 0; i < pngHeight; i++){\r
445         for(j = 0; j < pngWidth; j++){\r
446             if(kageCanvas[i][j] == 0) *mitsudo += 1;\r
447         }\r
448     }\r
449         \r
450     //calculate X-axis complexity\r
451     *yoko = 0;\r
452     for(i = dly1; i <= dry1; i++){\r
453         mode = 0;\r
454         kari = 0;\r
455         for(j = dlx1; j <= drx1; j++){\r
456                         if(kageCanvas[i][j] == 0 &&\r
457              kageCanvas[i][j+1] == 0 &&\r
458              kageCanvas[i][j+2] == 0){\r
459                 if(mode == 0){\r
460                     mode = 1;\r
461                     kari++;\r
462                 }\r
463             }\r
464             else if(mode == 1) mode = 0;\r
465         }\r
466         if(kari > *yoko) *yoko = kari;\r
467     }\r
468         \r
469     //calculate Y-axis complexity\r
470     *tate = 0;\r
471     for(i = dlx1; i <= drx1; i++){\r
472         mode = 0;\r
473         kari = 0;\r
474         for(j = dly1; j <= dry1; j++){\r
475             if(kageCanvas[j][i] == 0 &&\r
476              kageCanvas[j+1][i] == 0 &&\r
477              kageCanvas[j+2][i] == 0){\r
478                 if(mode == 0){\r
479                     mode = 1;\r
480                     kari++;\r
481                 }\r
482             }\r
483             else if(mode == 1) mode = 0;\r
484         }\r
485         if(kari > *tate) *tate = kari;\r
486     }\r
487         \r
488     //use user defined option if it exists\r
489         buf = convertStroke(in->str, buf, &strokes);\r
490         for(i = 0; i < strokes; i++){\r
491         if(buf[i * 11 + 0] % 10 == 0){\r
492             if(buf[i * 11 + 1] != 0) *yoko = (double)(buf[i * 11 + 1]) * 0.1;\r
493             if(buf[i * 11 + 2] != 0) *tate = (double)(buf[i * 11 + 2]) * 0.1;\r
494             if(buf[i * 11 + 3] != 0) *flag = *flag + buf[i * 11 + 3];\r
495         }\r
496     }\r
497     free(buf);\r
498 }\r
499 \r
500 void DoDrawParts(const KGString *in, const int lx1, const double rf1, const int ly1, const double rfy1){\r
501     int i;\r
502         int *buf, strokes;\r
503         \r
504     DrawBox();\r
505         buf = convertStroke(in->str, buf, &strokes);\r
506         for(i = 0; i < strokes; i++){\r
507                 dfDrawFont(buf[i * 11 + 0],\r
508                  buf[i * 11 + 1],\r
509                  buf[i * 11 + 2],\r
510                  buf[i * 11 + 3] * rf1 + lx1,\r
511                  buf[i * 11 + 4] * rfy1 + ly1,\r
512                  buf[i * 11 + 5] * rf1 + lx1,\r
513                  buf[i * 11 + 6] * rfy1 + ly1,\r
514                  buf[i * 11 + 7] * rf1 + lx1,\r
515                  buf[i * 11 + 8] * rfy1 + ly1,\r
516                  buf[i * 11 + 9] * rf1 + lx1,\r
517                  buf[i * 11 + 10] * rfy1 + ly1);\r
518     }\r
519         free(buf);\r
520 }\r
521 \r
522 void DoDrawMixFont(const KGString *in1,\r
523  const int lx1,\r
524  const double rf1,\r
525  const KGString *in2,\r
526  const int lx2,\r
527  const double rf2,\r
528  const int ly1,\r
529  const double rfy1,\r
530  const int ly2,\r
531  const double rfy2){\r
532     int i;\r
533         int *buf, strokes;\r
534         \r
535         DrawBox();\r
536         buf = convertStroke(in1->str, buf, &strokes);\r
537         for(i = 0; i < strokes; i++){\r
538                 dfDrawFont(buf[i * 11 + 0],\r
539                  buf[i * 11 + 1],\r
540                  buf[i * 11 + 2],\r
541                  buf[i * 11 + 3] * rf1 + lx1,\r
542                  buf[i * 11 + 4] * rfy1 + ly1,\r
543                  buf[i * 11 + 5] * rf1 + lx1,\r
544                  buf[i * 11 + 6] * rfy1 + ly1,\r
545                  buf[i * 11 + 7] * rf1 + lx1,\r
546                  buf[i * 11 + 8] * rfy1 + ly1,\r
547                  buf[i * 11 + 9] * rf1 + lx1,\r
548                  buf[i * 11 + 10] * rfy1 + ly1);\r
549     }\r
550         free(buf);\r
551         \r
552         buf = convertStroke(in2->str, buf, &strokes);\r
553         for(i = 0; i < strokes; i++){\r
554                 dfDrawFont(buf[i * 11 + 0],\r
555                  buf[i * 11 + 1],\r
556                  buf[i * 11 + 2],\r
557                  buf[i * 11 + 3] * rf2 + lx2,\r
558                  buf[i * 11 + 4] * rfy2 + ly2,\r
559                  buf[i * 11 + 5] * rf2 + lx2,\r
560                  buf[i * 11 + 6] * rfy2 + ly2,\r
561                  buf[i * 11 + 7] * rf2 + lx2,\r
562                  buf[i * 11 + 8] * rfy2 + ly2,\r
563                  buf[i * 11 + 9] * rf2 + lx2,\r
564                  buf[i * 11 + 10] * rfy2 + ly2);\r
565     }\r
566         free(buf);\r
567 }\r
568 \r