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