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