Fixed `#include' descriptions for system independent and create `sysdep.h'.
[chise/kage.git] / kagecgi / kagechar.c
1 //kagechar.c\r
2 //\r
3 \r
4 #include "kage.h"\r
5 #include "kagecgi.h"\r
6 #include "sysdep.h"\r
7 \r
8 int isIDS(const GString *in){\r
9         //check IDC "u2ff*"\r
10         if(strncmp(in->str, "u2ff", 4) == 0){\r
11                 //check the last char\r
12                 if('0' <= (in->str)[4] && (in->str)[4] <= 'a') return TRUE;\r
13         }\r
14         return FALSE;\r
15 }\r
16 \r
17 void divideInto2(const GString *in, GString *partIDS1, GString *partIDS3){\r
18         GString *buffer[16];\r
19         char tmp[kMaxIDCLength + 1];\r
20         int i, counter, pointer, flag;\r
21         \r
22         g_string_set_size(partIDS1, 0);\r
23         \r
24         counter = 0;\r
25         pointer = 0;\r
26         for(i = 0; i < in->len; i++){\r
27                 if((in->str)[i] == '.'){\r
28                         strncpy(tmp, (in->str) + pointer, i - pointer);\r
29                         tmp[i - pointer] = '\0';\r
30                         buffer[counter] = g_string_new(tmp);\r
31                         counter++;\r
32                         pointer = i + 1;\r
33                 }\r
34         }\r
35         strncpy(tmp, (in->str) + pointer, i - pointer);\r
36         tmp[i - pointer] = '\0';\r
37         buffer[counter] = g_string_new(tmp);\r
38         counter++;\r
39         \r
40         //reject over-length of IDS\r
41         if(counter > kMaxIDSSequenceLength) return;\r
42         \r
43         //1st scan\r
44         pointer = 1;\r
45         flag = 0;\r
46         while(flag >= 0 && pointer < counter){\r
47                 g_string_append(partIDS1, (buffer[pointer])->str);\r
48                 g_string_append(partIDS1, ".");\r
49                 if(strncmp((buffer[pointer])->str, "u2ff", 4) == 0){\r
50                         switch (((buffer[pointer])->str)[4]){\r
51                                 case '0':\r
52                                 case '1':\r
53                                 case '4':\r
54                                 case '5':\r
55                                 case '6':\r
56                                 case '7':\r
57                                 case '8':\r
58                                 case '9':\r
59                                 case 'a':\r
60                                 case 'b':\r
61                                         flag++;\r
62                                         break;\r
63                                 case '2':\r
64                                 case '3':\r
65                                         flag = flag + 2;\r
66                                         break;\r
67                         }\r
68                 }\r
69                 else flag--;\r
70                 pointer++;\r
71         }\r
72         g_string_erase(partIDS1, partIDS1->len - 1, 1);\r
73         \r
74         //2nd scan\r
75         flag = 0;\r
76         while(flag >= 0 && pointer < counter){\r
77                 g_string_append(partIDS3, (buffer[pointer])->str);\r
78                 g_string_append(partIDS3, ".");\r
79                 if(strncmp((buffer[pointer])->str, "u2ff", 4) == 0){\r
80                         switch (((buffer[pointer])->str)[4]){\r
81                                 case '0':\r
82                                 case '1':\r
83                                 case '4':\r
84                                 case '5':\r
85                                 case '6':\r
86                                 case '7':\r
87                                 case '8':\r
88                                 case '9':\r
89                                 case 'a':\r
90                                 case 'b':\r
91                                         flag++;\r
92                                         break;\r
93                                 case '2':\r
94                                 case '3':\r
95                                         flag = flag + 2;\r
96                                         break;\r
97                         }\r
98                 }\r
99                 else flag--;\r
100                 pointer++;\r
101         }\r
102         g_string_erase(partIDS3, partIDS3->len - 1, 1);\r
103 }\r
104 \r
105 void divideInto3(const GString *in, GString *partIDS1, GString *partIDS2, GString *partIDS3){\r
106         GString *buffer[16];\r
107         char tmp[kMaxIDCLength + 1];\r
108         int i, counter, pointer, flag;\r
109         \r
110         g_string_set_size(partIDS1, 0);\r
111         \r
112         counter = 0;\r
113         pointer = 0;\r
114         for(i = 0; i < in->len; i++){\r
115                 if((in->str)[i] == '.'){\r
116                         strncpy(tmp, (in->str) + pointer, i - pointer);\r
117                         tmp[i - pointer] = '\0';\r
118                         buffer[counter] = g_string_new(tmp);\r
119                         counter++;\r
120                         pointer = i + 1;\r
121                 }\r
122         }\r
123         strncpy(tmp, (in->str) + pointer, i - pointer);\r
124         tmp[i - pointer] = '\0';\r
125         buffer[counter] = g_string_new(tmp);\r
126         counter++;\r
127         \r
128         //reject over-length of IDS\r
129         if(counter > kMaxIDSSequenceLength) return;\r
130         \r
131         //1st scan\r
132         pointer = 1;\r
133         flag = 0;\r
134         while(flag >= 0 && pointer < counter){\r
135                 g_string_append(partIDS1, (buffer[pointer])->str);\r
136                 g_string_append(partIDS1, ".");\r
137                 if(strncmp((buffer[pointer])->str, "u2ff", 4) == 0){\r
138                         switch (((buffer[pointer])->str)[4]){\r
139                                 case '0':\r
140                                 case '1':\r
141                                 case '4':\r
142                                 case '5':\r
143                                 case '6':\r
144                                 case '7':\r
145                                 case '8':\r
146                                 case '9':\r
147                                 case 'a':\r
148                                 case 'b':\r
149                                         flag++;\r
150                                         break;\r
151                                 case '2':\r
152                                 case '3':\r
153                                         flag = flag + 2;\r
154                                         break;\r
155                         }\r
156                 }\r
157                 else flag--;\r
158                 pointer++;\r
159         }\r
160         g_string_erase(partIDS1, partIDS1->len - 1, 1);\r
161         \r
162         //2nd scan\r
163         flag = 0;\r
164         while(flag >= 0 && pointer < counter){\r
165                 g_string_append(partIDS2, (buffer[pointer])->str);\r
166                 g_string_append(partIDS2, ".");\r
167                 if(strncmp((buffer[pointer])->str, "u2ff", 4) == 0){\r
168                         switch (((buffer[pointer])->str)[4]){\r
169                                 case '0':\r
170                                 case '1':\r
171                                 case '4':\r
172                                 case '5':\r
173                                 case '6':\r
174                                 case '7':\r
175                                 case '8':\r
176                                 case '9':\r
177                                 case 'a':\r
178                                 case 'b':\r
179                                         flag++;\r
180                                         break;\r
181                                 case '2':\r
182                                 case '3':\r
183                                         flag = flag + 2;\r
184                                         break;\r
185                         }\r
186                 }\r
187                 else flag--;\r
188                 pointer++;\r
189         }\r
190         g_string_erase(partIDS2, partIDS2->len - 1, 1);\r
191         \r
192         //3rd scan\r
193         flag = 0;\r
194         while(flag >= 0 && pointer < counter){\r
195                 g_string_append(partIDS3, (buffer[pointer])->str);\r
196                 g_string_append(partIDS3, ".");\r
197                 if(strncmp((buffer[pointer])->str, "u2ff", 4) == 0){\r
198                         switch (((buffer[pointer])->str)[4]){\r
199                                 case '0':\r
200                                 case '1':\r
201                                 case '4':\r
202                                 case '5':\r
203                                 case '6':\r
204                                 case '7':\r
205                                 case '8':\r
206                                 case '9':\r
207                                 case 'a':\r
208                                 case 'b':\r
209                                         flag++;\r
210                                         break;\r
211                                 case '2':\r
212                                 case '3':\r
213                                         flag = flag + 2;\r
214                                         break;\r
215                         }\r
216                 }\r
217                 else flag--;\r
218                 pointer++;\r
219         }\r
220         g_string_erase(partIDS3, partIDS3->len - 1, 1);\r
221 }\r
222 \r
223 void addStrokeWithTransform(const GString *stroke, const int num, const int *tf, GString *out, int mode){\r
224         int *buf, i, size;\r
225         GString *tmp;\r
226         \r
227         tmp = g_string_new("");\r
228         buf = convertStroke(stroke->str, buf, &size);\r
229         \r
230         for(i = 0; i < size; i++){\r
231                 if(buf[i * 11 + 0] != 0 && buf[i * 11 + 0] != 99){\r
232                         buf[i * 11 + 3] =\r
233                          tf[(num - 1) * 4 + 0] + buf[i * 11 + 3] * (tf[(num - 1) * 4 + 2] - tf[(num - 1) * 4 + 0]) / pngWidth;\r
234                         buf[i * 11 + 5] =\r
235                          tf[(num - 1) * 4 + 0] + buf[i * 11 + 5] * (tf[(num - 1) * 4 + 2] - tf[(num - 1) * 4 + 0]) / pngWidth;\r
236                         buf[i * 11 + 7] =\r
237                          tf[(num - 1) * 4 + 0] + buf[i * 11 + 7] * (tf[(num - 1) * 4 + 2] - tf[(num - 1) * 4 + 0]) / pngWidth;\r
238                         buf[i * 11 + 9] =\r
239                          tf[(num - 1) * 4 + 0] + buf[i * 11 + 9] * (tf[(num - 1) * 4 + 2] - tf[(num - 1) * 4 + 0]) / pngWidth;\r
240                         buf[i * 11 + 4] =\r
241                          tf[(num - 1) * 4 + 1] + buf[i * 11 + 4] * (tf[(num - 1) * 4 + 3] - tf[(num - 1) * 4 + 1]) / pngHeight;\r
242                         buf[i * 11 + 6] =\r
243                          tf[(num - 1) * 4 + 1] + buf[i * 11 + 6] * (tf[(num - 1) * 4 + 3] - tf[(num - 1) * 4 + 1]) / pngHeight;\r
244                         buf[i * 11 + 8] =\r
245                          tf[(num - 1) * 4 + 1] + buf[i * 11 + 8] * (tf[(num - 1) * 4 + 3] - tf[(num - 1) * 4 + 1]) / pngHeight;\r
246                         buf[i * 11 + 10] =\r
247                          tf[(num - 1) * 4 + 1] + buf[i * 11 + 10] * (tf[(num - 1) * 4 + 3] - tf[(num - 1) * 4 + 1]) / pngHeight;\r
248                 }\r
249         }\r
250         convertArray(buf, tmp, size, mode);\r
251         if(out->len != 0) g_string_append(out, "$");\r
252         g_string_append(out, tmp->str);\r
253         \r
254         free((void *)buf);\r
255 }\r
256 \r
257 void convertArray(int *buf, GString *out, int size, int mode){\r
258         int i;\r
259         char tmp[kMaxStrokeDataLength];\r
260         \r
261         for(i = 0; i < size; i++){\r
262                 if(!(mode == 1 && (buf[i * 11 + 0] == 0 || buf[i * 11 + 0] == 99))){\r
263                         sprintf(tmp, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d$",\r
264                          buf[i * 11 + 0],\r
265                          buf[i * 11 + 1],\r
266                          buf[i * 11 + 2],\r
267                          buf[i * 11 + 3],\r
268                          buf[i * 11 + 4],\r
269                          buf[i * 11 + 5],\r
270                          buf[i * 11 + 6],\r
271                          buf[i * 11 + 7],\r
272                          buf[i * 11 + 8],\r
273                          buf[i * 11 + 9],\r
274                          buf[i * 11 + 10]);\r
275                         g_string_append(out, tmp);\r
276                 }\r
277         }\r
278         g_string_erase(out, (out->len - 1), 1);\r
279 }\r
280 \r
281 int * convertStroke(const char *in, int *a, int *size){\r
282         int i, counter, pointer;\r
283         int a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10;\r
284         char tmp[kMaxStrokeDataLength + 1];\r
285         \r
286         a = (int *)malloc(0);\r
287         counter = 0;\r
288         pointer = 0;\r
289         for(i = 0; i < strlen(in); i++){\r
290                 if(in[i] == '$'){\r
291                         strncpy(tmp, &in[pointer], i - pointer);\r
292                         tmp[i - pointer] = '\0';\r
293                         a = (int *)realloc(a, sizeof(int) * 11 * (counter + 1));\r
294                         sscanf(tmp, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",\r
295                          &a0,&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10);\r
296                         a[counter * 11 + 0] = a0;\r
297                         a[counter * 11 + 1] = a1;\r
298                         a[counter * 11 + 2] = a2;\r
299                         a[counter * 11 + 3] = a3;\r
300                         a[counter * 11 + 4] = a4;\r
301                         a[counter * 11 + 5] = a5;\r
302                         a[counter * 11 + 6] = a6;\r
303                         a[counter * 11 + 7] = a7;\r
304                         a[counter * 11 + 8] = a8;\r
305                         a[counter * 11 + 9] = a9;\r
306                         a[counter * 11 + 10] = a10;\r
307                         counter++;\r
308                         pointer = i + 1;\r
309                 }\r
310         }\r
311         strncpy(tmp, &in[pointer], i - pointer);\r
312         tmp[i - pointer] = '\0';\r
313         a = (int *)realloc(a, sizeof(int) * 11 * (counter + 1));\r
314                         sscanf(tmp, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",\r
315                          &a0,&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10);\r
316                         a[counter * 11 + 0] = a0;\r
317                         a[counter * 11 + 1] = a1;\r
318                         a[counter * 11 + 2] = a2;\r
319                         a[counter * 11 + 3] = a3;\r
320                         a[counter * 11 + 4] = a4;\r
321                         a[counter * 11 + 5] = a5;\r
322                         a[counter * 11 + 6] = a6;\r
323                         a[counter * 11 + 7] = a7;\r
324                         a[counter * 11 + 8] = a8;\r
325                         a[counter * 11 + 9] = a9;\r
326                         a[counter * 11 + 10] = a10;\r
327                 counter++;\r
328         *(size) = counter;\r
329         return a;\r
330 }\r
331 \r
332 void convert99(const GString *in, GString *out){\r
333         int i, pointer;\r
334         char tmp[kMaxStrokeDataLength + 1];\r
335         GString *buf;\r
336         \r
337         g_string_set_size(out, 0);\r
338         buf = g_string_new("");\r
339         pointer = 0;\r
340         for(i = 0; i < in->len; i++){\r
341                 if((in->str)[i] == '$'){\r
342                         strncpy(tmp, in->str + pointer, i - pointer);\r
343                         tmp[i - pointer] = '\0';\r
344                         if(strncmp(tmp, "99:", 3) == 0){\r
345                                 convert99calc(tmp, buf);\r
346                                 if(buf->len == 0){\r
347                                         g_string_set_size(out, 0);\r
348                                         return;\r
349                                 }\r
350                                 g_string_append(out, buf->str);\r
351                         }\r
352                         else g_string_append(out, tmp);\r
353                         g_string_append(out, "$");\r
354                         \r
355                         pointer = i + 1;\r
356                 }\r
357         }\r
358         strncpy(tmp, in->str + pointer, i - pointer);\r
359         tmp[i - pointer] = '\0';\r
360         if(strncmp(tmp, "99:", 3) == 0){\r
361                 convert99calc(tmp, buf);\r
362                 if(buf->len == 0){\r
363                         g_string_set_size(out, 0);\r
364                         return;\r
365                 }\r
366                 g_string_append(out, buf->str);\r
367         }\r
368         else g_string_append(out, tmp);\r
369 }\r
370 \r
371 void convert99calc(const char *in, GString *out){\r
372         GString *buf1, *buf2;\r
373         int a1,x1,y1,x2,y2,option,option2;\r
374         char pname[kMaxStrokeDataLength];\r
375         int tf[12];\r
376         char *end;\r
377         \r
378         g_string_set_size(out, 0);\r
379         buf2 = g_string_new("");\r
380         \r
381         //get parts data\r
382         sscanf(in, "%d:%d:%d:%d:%d:%d:%d:%s",\r
383                 &a1,&option,&option2,&x1,&y1,&x2,&y2,pname);\r
384         //end = strchr(pname, ':');\r
385         //*end = '\0';\r
386         buf1 = g_string_new(pname);\r
387         generateGlyph(buf1, buf2);\r
388         if(buf2->len == 0) return;\r
389         \r
390         //convert\r
391         tf[0] = x1;\r
392         tf[1] = y1;\r
393         tf[2] = x2;\r
394         tf[3] = y2;\r
395         addStrokeWithTransform(buf2, 1, tf, out, 1);\r
396 }\r