(1)Make fatten the bezier curve (2)Adjust box's Kakato (3)Update sample
[chise/kage.git] / kagecgi / kageeg.c
1 //kageeg.c
2 //
3
4 #include "kage.h"
5 #include "kagecgi.h"
6 #include "sysdep.h"
7
8 void generateGlyphByIDS(const KGString *in, KGString *out, int flag){
9   KGString *tmp1, *tmp2;
10   
11   //pass this method if 'in' is not UCS parts
12   if((in->str)[0] != 'u'){
13     generateGlyph(in, out);
14     return;
15   }
16   //pass this method if 'in' is place-variant-flag defined
17   if(in->len < 5 && 7 < in->len){
18     generateGlyph(in, out);
19     return;
20   }
21   
22   tmp1 = kg_string_new(in->str);
23   tmp2 = kg_string_new(in->str);
24   
25   //append place flag
26   if(1 <= flag && flag <= 7){
27     if(tmp1->len != 7) kg_string_append(tmp1, "-");
28     if(flag == 1) kg_string_append(tmp1, "01");
29     else if(flag == 2) kg_string_append(tmp1, "02");
30     else if(flag == 3) kg_string_append(tmp1, "03");
31     else if(flag == 4) kg_string_append(tmp1, "04");
32     else if(flag == 5) kg_string_append(tmp1, "05");
33     else if(flag == 6) kg_string_append(tmp1, "06");
34   }
35   
36   generateGlyph(tmp1, out);
37   if(out->len != 0) return;
38   generateGlyph(tmp2, out);
39   if(out->len != 0) return;
40   return;
41 }
42
43 void generateGlyph(const KGString *in, KGString *out){
44   KGString *tmp;
45   tmp = kg_string_new("");
46   kg_string_set_size(out, 0);
47   
48   //search from parts
49   searchPartsData(in, tmp);
50   if(tmp->len != 0){
51     //fprintf(stderr, "partsFound:%s\n",tmp->str);
52     tmp = CalcSizes(tmp, 1);// this line may not be needed
53     out = kg_string_assign(out, tmp->str);
54     return;
55   }
56   //else{
57   //  fprintf(stderr, "partsNotFound:%s\n",in->str);
58   //}
59   
60   //search from alias
61   searchAliasData(in, tmp);
62   if(tmp->len != 0){
63     //fprintf(stderr, "aliasFound:%s(%d)\n",tmp->str,tmp->len);
64     generateGlyph(tmp, out);
65     if(out->len == 0) return;
66     //save to cache ... not yet
67     return;
68   }
69   //else{
70   //  fprintf(stderr, "aliasNotFound:%s\n",in->str);
71   //}
72   
73   //check if its IDS
74   if(isIDS(in)){
75     doCombine(in, out);
76     if(out->len == 0) return;
77     //save to cache ... not yet
78     return;
79   }
80 }
81
82 void doCombine(const KGString *in, KGString *out){
83   KGString *partIDS1, *partIDS2, *partIDS3;
84   KGString *partStroke1, *partStroke2, *partStroke3;
85   int result[12];
86   
87   partIDS1 = kg_string_new("");
88   partIDS2 = kg_string_new("");
89   partIDS3 = kg_string_new("");
90   partStroke1 = kg_string_new("");
91   partStroke2 = kg_string_new("");
92   partStroke3 = kg_string_new("");
93   
94   kg_string_set_size(out, 0);
95   
96   //check first IDC
97   if(strncmp(in->str, "u2ff", 4) != 0) return;
98   //switch by combine types
99   switch((in->str)[4]){
100   case '0':
101     divideInto2(in, partIDS1, partIDS3);
102     if(partIDS1->len == 0) return;
103     //ready each parts
104     generateGlyphByIDS(partIDS1, partStroke1, 1);
105     if(partStroke1->len == 0) return;
106     partStroke1 = CalcSizes(partStroke1, 0);
107     generateGlyphByIDS(partIDS3, partStroke3, 2);
108     if(partStroke3->len == 0) return;
109     partStroke3 = CalcSizes(partStroke3, 0);
110     break;
111   case '1':
112     divideInto2(in, partIDS1, partIDS3);
113     if(partIDS1->len == 0) return;
114     //ready each parts
115     generateGlyphByIDS(partIDS1, partStroke1, 3);
116     if(partStroke1->len == 0) return;
117     partStroke1 = CalcSizes(partStroke1, 0);
118     generateGlyphByIDS(partIDS3, partStroke3, 4);
119     if(partStroke3->len == 0) return;
120     partStroke3 = CalcSizes(partStroke3, 0);
121     break;
122   case '4': //full surround
123   case '5': //surround from above
124   case '6': //surround from below
125   case '7': //surround from left
126   case '8': //surround from upper left
127   case '9': //surround from upper right
128   case 'a': //surround from lower left
129     //case 'b': //overlaid (not supported)
130     divideInto2(in, partIDS1, partIDS3);
131     if(partIDS1->len == 0) return;
132     //ready each parts
133     generateGlyphByIDS(partIDS1, partStroke1, 5);
134     if(partStroke1->len == 0) return;
135     partStroke1 = CalcSizes(partStroke1, 0);
136     generateGlyphByIDS(partIDS3, partStroke3, 6);
137     if(partStroke3->len == 0) return;
138     partStroke3 = CalcSizes(partStroke3, 0);
139     break;
140   case '2':
141     divideInto3(in, partIDS1, partIDS2, partIDS3);
142     if(partIDS1->len == 0) return;
143     //ready each parts
144     generateGlyphByIDS(partIDS1, partStroke1, 1);
145     if(partStroke1->len == 0) return;
146     partStroke1 = CalcSizes(partStroke1, 0);
147     generateGlyphByIDS(partIDS2, partStroke2, 1);
148     if(partStroke2->len == 0) return;
149     partStroke2 = CalcSizes(partStroke2, 0);
150     generateGlyphByIDS(partIDS3, partStroke3, 2);
151     if(partStroke3->len == 0) return;
152     partStroke3 = CalcSizes(partStroke3, 0);
153     break;
154   case '3':
155     divideInto3(in, partIDS1, partIDS2, partIDS3);
156     if(partIDS1->len == 0) return;
157     //ready each parts
158     generateGlyphByIDS(partIDS1, partStroke1, 3);
159     if(partStroke1->len == 0) return;
160     partStroke1 = CalcSizes(partStroke1, 0);
161     generateGlyphByIDS(partIDS2, partStroke2, 3);
162     if(partStroke2->len == 0) return;
163     partStroke2 = CalcSizes(partStroke2, 0);
164     generateGlyphByIDS(partIDS3, partStroke3, 4);
165     if(partStroke3->len == 0) return;
166     partStroke3 = CalcSizes(partStroke3, 0);
167     break;
168   }
169   switch((in->str)[4]){
170   case '0':
171     combineYoko2(partStroke1, partStroke3, result);
172     break;
173   case '1':
174     combineTate2(partStroke1, partStroke3, result);
175     break;
176   case '2':
177     combineYoko3(partStroke1, partStroke2, partStroke3, result);
178     break;
179   case '3':
180     combineTate3(partStroke1, partStroke2, partStroke3, result);
181     break;
182   case '4': //full surround
183     combineHame2(partStroke1, partStroke3, result,
184                  FLAG_SURROUND_LEFT |
185                  FLAG_SURROUND_RIGHT |
186                  FLAG_SURROUND_TOP |
187                  FLAG_SURROUND_BOTTOM);
188     break;
189   case '5': //surround from above
190     combineHame2(partStroke1, partStroke3, result,
191                  FLAG_SURROUND_LEFT |
192                  FLAG_SURROUND_RIGHT |
193                  FLAG_SURROUND_TOP);
194     break;
195   case '6': //surround from below
196     combineHame2(partStroke1, partStroke3, result,
197                  FLAG_SURROUND_LEFT |
198                  FLAG_SURROUND_RIGHT |
199                  FLAG_SURROUND_BOTTOM);
200     break;
201   case '7': //surround from left
202     combineHame2(partStroke1, partStroke3, result,
203                  FLAG_SURROUND_LEFT |
204                  FLAG_SURROUND_TOP |
205                  FLAG_SURROUND_BOTTOM);
206     break;
207   case '8': //surround from upper left
208     combineHame2(partStroke1, partStroke3, result,
209                  FLAG_SURROUND_LEFT |
210                  FLAG_SURROUND_TOP);
211     break;
212   case '9': //surround from upper right
213     combineHame2(partStroke1, partStroke3, result,
214                  FLAG_SURROUND_RIGHT |
215                  FLAG_SURROUND_TOP);
216     break;
217   case 'a': //surround from lower left
218     combineHame2(partStroke1, partStroke3, result,
219                  FLAG_SURROUND_LEFT |
220                  FLAG_SURROUND_BOTTOM);
221     break;
222     //case 'b': //overlaid (not supported)
223   }
224   switch((in->str)[4]){
225   case '0':
226   case '1':
227   case '4':
228   case '5':
229   case '6':
230   case '7':
231   case '8':
232   case '9':
233   case 'a':
234     //case 'b':
235     addStrokeWithTransform(partStroke1, 1, result, out, 1);
236     addStrokeWithTransform(partStroke3, 3, result, out, 1);
237     break;
238   case '2':
239   case '3':
240     addStrokeWithTransform(partStroke1, 1, result, out, 1);
241     addStrokeWithTransform(partStroke2, 2, result, out, 1);
242     addStrokeWithTransform(partStroke3, 3, result, out, 1);
243     break;
244   }
245   //fprintf(stderr,"%s\n",out->str);
246 }
247
248 void drawGlyph(const KGString *in, const int mode){
249   int i, j;
250   int *buf;
251   buf = convertStroke(in->str, buf, &j);
252   for(i = 0; i < j; i++){
253     if(mode == DRAW_GLYPH_MODE_NORMAL){ //normal
254       dfDrawFont(buf[i * 11 + 0],
255                  buf[i * 11 + 1],
256                  buf[i * 11 + 2],
257                  buf[i * 11 + 3],
258                  buf[i * 11 + 4],
259                  buf[i * 11 + 5],
260                  buf[i * 11 + 6],
261                  buf[i * 11 + 7],
262                  buf[i * 11 + 8],
263                  buf[i * 11 + 9],
264                  buf[i * 11 + 10]);
265     }
266     else if(mode == DRAW_GLYPH_MODE_WITHOUT_DECORATION){ //without decoration
267       dfDrawFont(buf[i * 11 + 0],
268                  0,
269                  0,
270                  buf[i * 11 + 3],
271                  buf[i * 11 + 4],
272                  buf[i * 11 + 5],
273                  buf[i * 11 + 6],
274                  buf[i * 11 + 7],
275                  buf[i * 11 + 8],
276                  buf[i * 11 + 9],
277                  buf[i * 11 + 10]);
278     }
279   }
280   free(buf);
281 }
282
283 KGString* finalAdjustment(const KGString *in){
284   int i, j, k, l, m, n;
285   int *buf;
286   KGString *temp;
287   
288   n = kShotai;
289   kShotai = kGothic;
290   temp = kg_string_new("");
291   
292   DrawBox();
293   drawGlyph(in, DRAW_GLYPH_MODE_WITHOUT_DECORATION);
294   
295   buf = convertStroke(in->str, buf, &j);
296   for(i = 0; i < j; i++){
297     m = 0;
298     if(buf[i * 11 + 2] == 13){
299       for(k = buf[i * 11 + 5] - kMinWidthT; k < buf[i * 11 + 5] + kMinWidthT; k++){
300         for(l = buf[i * 11 + 6] + kWidth * kKakato * 0.5; l < buf[i * 11 + 6] + kWidth * kKakato + pngHeight * 0.1; l++){
301           if(0 <= l && l < canvasHeight && 0 <= k && k < canvasHeight && kageCanvas[l][k] != kWhite) m++;
302         }
303       }
304       if(m != 0) buf[i * 11 + 2] = 23;
305     }
306   }
307   convertArray(buf, temp, j, 0);
308   free(buf);
309   kShotai = n;
310   return kg_string_new(temp->str);
311 }
312