Fixed Parts{Width, Height}().
[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 KGString *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 1; //true\r
13   }\r
14   return 0; //false\r
15 }\r
16 \r
17 void divideInto2(const KGString *in, KGString *partIDS1, KGString *partIDS3){\r
18   KGString *buffer[16];\r
19   char tmp[kMaxIDCLength + 1];\r
20   int i, counter, pointer, flag;\r
21   \r
22   kg_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] = kg_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] = kg_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     kg_string_append(partIDS1, (buffer[pointer])->str);\r
48     kg_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   kg_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     kg_string_append(partIDS3, (buffer[pointer])->str);\r
78     kg_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   kg_string_erase(partIDS3, partIDS3->len - 1, 1);\r
103 }\r
104 \r
105 void divideInto3(const KGString *in, KGString *partIDS1, KGString *partIDS2, KGString *partIDS3){\r
106   KGString *buffer[16];\r
107   char tmp[kMaxIDCLength + 1];\r
108   int i, counter, pointer, flag;\r
109   \r
110   kg_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] = kg_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] = kg_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     kg_string_append(partIDS1, (buffer[pointer])->str);\r
136     kg_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   kg_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     kg_string_append(partIDS2, (buffer[pointer])->str);\r
166     kg_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   kg_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     kg_string_append(partIDS3, (buffer[pointer])->str);\r
196     kg_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   kg_string_erase(partIDS3, partIDS3->len - 1, 1);\r
221 }\r
222 \r
223 void addStrokeWithTransform(const KGString *stroke, const int num, const int *tf, KGString *out, int mode){\r
224   int *buf, i, size;\r
225   KGString *tmp;\r
226   \r
227   tmp = kg_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) kg_string_append(out, "$");\r
252   kg_string_append(out, tmp->str);\r
253   \r
254   free((void *)buf);\r
255 }\r
256 \r
257 void convertArray(int *buf, KGString *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       kg_string_append(out, tmp);\r
276     }\r
277   }\r
278   out = kg_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 KGString *in, KGString *out){\r
333   int i, pointer;\r
334   char tmp[kMaxStrokeDataLength + 1];\r
335   KGString *buf;\r
336   \r
337   kg_string_set_size(out, 0);\r
338   buf = kg_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           kg_string_set_size(out, 0);\r
348           return;\r
349         }\r
350         kg_string_append(out, buf->str);\r
351       }\r
352       else kg_string_append(out, tmp);\r
353       kg_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       kg_string_set_size(out, 0);\r
364       return;\r
365     }\r
366     kg_string_append(out, buf->str);\r
367   }\r
368   else kg_string_append(out, tmp);\r
369 }\r
370 \r
371 void convert99calc(const char *in, KGString *out){\r
372   KGString *buf1, *buf2;\r
373   int a1,x1,y1,x2,y2,option,option2;\r
374   char pname[kMaxStrokeDataLength];\r
375   int tf[12];\r
376   \r
377   kg_string_set_size(out, 0);\r
378   buf2 = kg_string_new("");\r
379   \r
380   //get parts data\r
381   sscanf(in, "%d:%d:%d:%d:%d:%d:%d:%s",\r
382          &a1,&option,&option2,&x1,&y1,&x2,&y2,pname);\r
383   //end = strchr(pname, ':');\r
384   //*end = '\0';\r
385   buf1 = kg_string_new(pname);\r
386   generateGlyph(buf1, buf2);\r
387   if(buf2->len == 0) return;\r
388   \r
389   //convert\r
390   tf[0] = x1;\r
391   tf[1] = y1;\r
392   tf[2] = x2;\r
393   tf[3] = y2;\r
394   addStrokeWithTransform(buf2, 1, tf, out, 1);\r
395 }\r