8 void combineYoko2(const KGString *parts1, const KGString *parts3, int *result){
9 int f, g, h, i, j, k, l;
10 int flg_boxL, flg_boxR;
11 int YsideLa, YsideLb, YsideRa, YsideRb, YheightL, YnanameL, YsmallL;
12 int pxL, pxR, pyL, pyR;
13 double prL, prR, pryL, pryR, rL, rR, rTemp;
14 int lxL, rxL, lxR, rxR;
15 int dlyL, dryL, dlyR, dryR;
18 double yokoL, tateL, yokoR, tateR;
21 int bodyline1[pngWidth], bodyline2[pngWidth];
40 YheightL = pngWidth * 0.9;
45 CalcOptions(parts1, &mitsuL, &flg_boxL, &yokoL, &tateL);
46 CalcOptions(parts3, &mitsuR, &flg_boxR, &yokoR, &tateR);
48 //get thin when the left parts is radical
49 if(flg_boxL & FLAG_RADICAL_LEFT) yokoL = yokoL / 2;
51 //left parts Y-axis processing #1
53 //if its upper and bottom are flat
54 if(flg_boxL & FLAG_FLAT_TOP) YsideLa++;
55 if(flg_boxL & FLAG_FLAT_BOTTOM) YsideLb++;
57 //if its goes right-up
59 buf = convertStroke(parts1->str, buf, &strokes);
60 for(i = 0; i < strokes; i++){
61 if(buf[i * 11 + 0] / 10 == 1){
71 YheightL = YheightL - (YsideLa + YsideLb) * 2 * kWidth;
73 //left parts Y-axis processing #2
76 if(flg_boxL & FLAG_FLAT_TOP && flg_boxL & FLAG_FLAT_BOTTOM && tateL <= 4){
77 YheightL = (double)YheightL * (max(0.65, tateL * 0.22));
78 } else if(flg_boxL & FLAG_FLAT_BOTTOM && tateL <= 3){
79 YheightL = (double)YheightL * 0.8;
80 } else if(YnanameL != 0 && flg_boxL & FLAG_FLAT_TOP && tateL <= 4){
81 YheightL = (double)YheightL * (max(0.65, tateL * 0.22));
82 } else if(YnanameL != 0 && tateL <= 3){
83 YheightL = (double)YheightL * 0.8;
88 //left parts Y-axis processing #3
89 DoDrawParts(parts1, pxL, prL, pyL, pryL);
90 DotsHeight(&dlyL, &dryL);
91 pryL = (double)YheightL / (dryL - dlyL);
94 if(flg_boxL & FLAG_FLAT_TOP){
95 pyL = kBaseline - (double)pngWidth * 0.9 + 6 * kWidth - dlyL * pryL;
97 pyL = kBaseline - (double)pngWidth * 0.9 + 2 * kWidth - dlyL * pryL;
100 if(flg_boxL & FLAG_FLAT_BOTTOM || YnanameL != 0){
101 pyL = kBaseline - 2 * kWidth - dryL * pryL;
103 pyL = kBaseline - dryL * pryL;
107 //right parts Y-axis processing #1
108 if(flg_boxR & FLAG_FLAT_TOP) YsideRa++;
109 if(flg_boxR & FLAG_FLAT_BOTTOM) YsideRb++;
111 DoDrawParts(parts3, pxR, prR, pyR, pryR);
112 DotsHeight(&dlyR, &dryR);
114 pryR = ((double)pngWidth * 0.9 - (YsideRa + YsideRb) * 2 * kWidth) / (dryR - dlyR);
115 pyR = kBaseline - dryR * pryR;
116 if(flg_boxR & FLAG_FLAT_BOTTOM){
117 pyR = pyR - 2 * kWidth;
124 if(flg_boxL & FLAG_FLAT_LEFT) rL = rL * 0.7;
125 if(flg_boxL & FLAG_FLAT_RIGHT) rL = rL * 0.7;
126 if(flg_boxR & FLAG_FLAT_LEFT) rR = rR * 0.7;
127 if(flg_boxR & FLAG_FLAT_RIGHT) rR = rR * 0.7;
142 pxR = pngWidth * prL;
144 //scan body line of left parts
145 DoDrawParts(parts1, pxL, prL, pyL, pryL);
146 for(i = 0; i < pngWidth; i++){
148 for(j = pngWidth - 1; j >= 0; j--){
149 if(kageCanvas[i][j] == 0 ||
150 kageCanvas[i + 1][j] == 0 ||
151 kageCanvas[i + 2][j] == 0 ||
152 kageCanvas[i + 3][j] == 0 ||
153 kageCanvas[i + 4][j] == 0 ||
154 kageCanvas[i + 5][j] == 0 ||
155 kageCanvas[i + 6][j] == 0 ||
156 kageCanvas[i + 7][j] == 0){
158 kageCanvas[i + 7][j] == 0 ||
159 kageCanvas[i + 8][j] == 0 ||
160 kageCanvas[i + 9][j] == 0 ||
161 kageCanvas[i + 10][j] == 0){
169 //scan body line of right parts
170 DoDrawParts(parts3, pxR, prR, pyR, pryR);
171 for(i = 0; i < pngWidth; i++){
172 bodyline2[i] = pngWidth;
173 for(j = 0; j < pngWidth; j++){
174 if(kageCanvas[i][j] == 0 ||
175 kageCanvas[i + 1][j] == 0 ||
176 kageCanvas[i + 2][j] == 0 ||
177 kageCanvas[i + 3][j] == 0 ||
178 kageCanvas[i + 4][j] == 0 ||
179 kageCanvas[i + 5][j] == 0 ||
180 kageCanvas[i + 6][j] == 0 ||
181 kageCanvas[i + 7][j] == 0){
183 kageCanvas[i + 7][j] == 0 ||
184 kageCanvas[i + 8][j] == 0 ||
185 kageCanvas[i + 9][j] == 0 ||
186 kageCanvas[i + 10][j] == 0){
194 //calculate the most thin length of two parts and fix right parts
196 for(i = 0; i < pngWidth; i++){
197 if(bodyline2[i] - bodyline1[i] < k){
198 k = bodyline2[i] - bodyline1[i];
205 //calculate if the two are too close
207 for(i = 0; i < pngWidth; i++){
208 if((bodyline2[i] - bodyline1[i]) - k < kWidth * 2){ // must be seperate with shotai?
214 if(kShotai == kMincho){
219 complex = 1 / ((yokoL + yokoR) / 2);
220 if(tooclose > pngWidth * 0.25){
221 complex = complex * 1.5;
223 pxR = pxR + pow((complex * (double)k), 2.3);
228 result[2] = pxL + pngWidth * prL;
229 result[3] = pyL + pngWidth * pryL;
232 result[10] = pxR + pngWidth * prR;
233 result[11] = pyR + pngWidth * pryR;
235 kShotai = tempShotai;
238 void combineYoko3(const KGString *parts1, const KGString *parts2, const KGString *parts3, int *result){
240 KGString *tempString;
241 int tempResult[8], tempResult2[4];
242 int minx, miny, maxx, maxy, width, height, width2, height2;
244 tempString = kg_string_new("");
245 combineYoko2(parts2, parts3, result);
246 addStrokeWithTransform(parts2, 1, result, tempString, 1);
247 addStrokeWithTransform(parts3, 3, result, tempString, 1);
248 tempResult[0] = result[0];
249 tempResult[1] = result[1];
250 tempResult[2] = result[2];
251 tempResult[3] = result[3];
252 tempResult[4] = result[8];
253 tempResult[5] = result[9];
254 tempResult[6] = result[10];
255 tempResult[7] = result[11];
257 miny = min(result[1], result[9]);
259 maxy = max(result[3], result[11]);
261 height = maxy - miny;
263 combineYoko2(parts1, tempString, result);
264 tempResult2[0] = result[8];
265 tempResult2[1] = result[9];
266 tempResult2[2] = result[10];
267 tempResult2[3] = result[11];
268 width2 = result[10] - result[8];
269 height2 = result[11] - result[9];
271 result[4] = tempResult2[0] + (tempResult[0] - minx) * ((double)width2 / width); // always 0
272 result[5] = tempResult2[1] + (tempResult[1] - miny) * ((double)height2 / height);
273 result[6] = tempResult2[0] + (tempResult[2] - minx) * ((double)width2 / width);
274 result[7] = tempResult2[1] + (tempResult[3] - miny) * ((double)height2 / height);
275 result[8] = tempResult2[0] + (tempResult[4] - minx) * ((double)width2 / width);
276 result[9] = tempResult2[1] + (tempResult[5] - miny) * ((double)height2 / height);
277 result[10] = tempResult2[0] + (tempResult[6] - minx) * ((double)width2 / width);
278 result[11] = tempResult2[1] + (tempResult[7] - miny) * ((double)height2 / height);
281 void combineTate2(const KGString *parts1, const KGString *parts3, int *result){
282 int f, g, h, i, j, k, l;
283 int flg_boxL, flg_boxR;
284 int pxL, pxR, pyL, pyR;
285 double prL, prR, pryL, pryR, rL, rR, rTemp;
286 int lxL, rxL, lxR, rxR;
287 int lyL, ryL, lyR, ryR;
288 int dlxL, drxL, dlxR, drxR;
291 double yokoL, tateL, yokoR, tateR;
304 tempShotai = kShotai;
307 CalcOptions(parts1, &mitsuL, &flg_boxL, &yokoL, &tateL);
308 CalcOptions(parts3, &mitsuR, &flg_boxR, &yokoR, &tateR);
310 if(flg_boxL & FLAG_REPLACE_2FF1_TO_2FF5){
311 combineHame2((KGString *)parts1, (KGString *)parts3, (int *)result,
313 FLAG_SURROUND_RIGHT |
315 kShotai = tempShotai;
323 if(flg_boxL & FLAG_FLAT_TOP) rL = rL * 0.7;
324 if(flg_boxL & FLAG_FLAT_BOTTOM) rL = rL * 0.7;
325 if(flg_boxR & FLAG_FLAT_TOP) rR = rR * 0.7;
326 if(flg_boxR & FLAG_FLAT_BOTTOM) rR = rR * 0.7;
340 //calucurate size of X-axis
341 PartsWidth(parts1, &lxL, &rxL);
342 PartsWidth(parts3, &lxR, &rxR);
343 PartsHeight(parts1, &lyL, &ryL);
344 PartsHeight(parts3, &lyR, &ryR);
347 if(flg_boxL & FLAG_FLAT_LEFT && flg_boxL & FLAG_FLAT_RIGHT){
348 prL = min(1.0, (double)yokoL * 0.1 + 0.5) - ((kWidth * 6) / (kSize * 0.9));
349 DoDrawParts(parts1, pxL, prL, pyL, pryL);
350 DotsWidth(&dlxL, &drxL);
351 pxL = (kSize / 2 - (dlxL + drxL) / 2);
352 } else if(flg_boxL & FLAG_FLAT_LEFT){
353 prL = (kSize * 0.9 - kWidth * 4) / (rxL - lxL);
355 } else if(flg_boxL & FLAG_FLAT_RIGHT){
356 prL = (kSize * 0.9 - kWidth * 4) / (rxL - lxL);
357 pxL = (kSize * 0.05 + kWidth * 2) - lxL * prL;
361 if(flg_boxR & FLAG_FLAT_LEFT && flg_boxR & FLAG_FLAT_RIGHT){
362 prR = min(1.0, (double)yokoR * 0.1 + 0.5) - ((kWidth * 6) / (kSize * 0.9));
363 DoDrawParts(parts3, pxR, prR, pyR, pryR);
364 DotsWidth(&dlxR, &drxR);
365 pxR = (kSize / 2 - (dlxR + drxR) / 2);
366 } else if(flg_boxR & FLAG_FLAT_LEFT){
367 prR = (kSize * 0.9 - kWidth * 4) / (rxR - lxR);
368 pxR = (kSize * 0.05 + kWidth * 3) - lxR * prR;
369 } else if(flg_boxR & FLAG_FLAT_RIGHT){
370 prR = (kSize * 0.9 - kWidth * 4) / (rxR - lxR);
371 pxR = (kSize * 0.05 + kWidth * 1) - lxR * prR;
376 //calculate width of each parts
377 pyL = kWidth * 1.5 + (kSize - kWidth * 1.5 * 4) * pryL * 0.5 - (lyL + ryL) / 2 * pryL;
378 pyR = kWidth * 1.5 + (kSize - kWidth * 1.5 * 4) * pryL + kWidth * 1.5 * 2 + (kSize - kWidth * 1.5 * 4) * pryR * 0.5 - (lyR + ryR) / 2 * pryR;
380 DoDrawMixFont(parts1, pxL, prL, parts3, pxR, prR, pyL, pryL, pyR, pryR);
382 //count dots for check crossing over
383 DotsWidth(&chk_x1, &chk_x2);
385 for(i = 0; i < pngWidth * 1.1; i++){
386 for(j = chk_x1; j <= chk_x2; j++){
387 if(kageCanvas[i][j] != kWhite) k++;
392 //get close both parts
394 while(k - l < kMixdot && g < kWidth * (kKasane + 4)){
397 DoDrawMixFont(parts1, pxL, prL, parts3, pxR, prR, pyL, pryL, f, pryR);
400 for(i = 0; i < pngWidth * 1.1; i++){
401 for(j = chk_x1; j <= chk_x2; j++){
402 if(kageCanvas[i][j] != kWhite) l++;
408 if(k - l > pngWidth * 0.4){
409 pyR = pyR + kWidth * 4;
411 pyR = pyR + kWidth * 2;
414 if(flg_boxL & FLAG_FLAT_BOTTOM && flg_boxR & FLAG_FLAT_TOP){
415 pyR = pyR + kWidth * 4;
416 } else if(k - l > pngWidth * 0.4){
417 pyR = pyR + kWidth * 2;
425 result[2] = pxL + pngWidth * prL;
426 result[3] = pyL + pngWidth * pryL;
429 result[10] = pxR + pngWidth * prR;
430 result[11] = pyR + pngWidth * pryR;
432 kShotai = tempShotai;
435 void combineTate3(const KGString *parts1, const KGString *parts2, const KGString *parts3, int *result){
437 KGString *tempString;
438 int tempResult[8], tempResult2[4];
439 int minx, miny, maxx, maxy, width, height, width2, height2;
441 tempString = kg_string_new("");
442 combineTate2(parts2, parts3, result);
443 addStrokeWithTransform(parts2, 1, result, tempString, 1);
444 addStrokeWithTransform(parts3, 3, result, tempString, 1);
445 tempResult[0] = result[0];
446 tempResult[1] = result[1];
447 tempResult[2] = result[2];
448 tempResult[3] = result[3];
449 tempResult[4] = result[8];
450 tempResult[5] = result[9];
451 tempResult[6] = result[10];
452 tempResult[7] = result[11];
453 minx = min(result[0], result[8]);
454 miny = min(result[1], result[9]);
455 maxx = max(result[2], result[10]);
456 maxy = max(result[3], result[11]);
458 height = maxy - miny;
460 combineTate2(parts1, tempString, result);
461 tempResult2[0] = result[8];
462 tempResult2[1] = result[9];
463 tempResult2[2] = result[10];
464 tempResult2[3] = result[11];
465 width2 = result[10] - result[8];
466 height2 = result[11] - result[9];
468 result[4] = tempResult2[0] + (tempResult[0] - minx) * ((double)width2 / width); // always 0
469 result[5] = tempResult2[1] + (tempResult[1] - miny) * ((double)height2 / height);
470 result[6] = tempResult2[0] + (tempResult[2] - minx) * ((double)width2 / width);
471 result[7] = tempResult2[1] + (tempResult[3] - miny) * ((double)height2 / height);
472 result[8] = tempResult2[0] + (tempResult[4] - minx) * ((double)width2 / width);
473 result[9] = tempResult2[1] + (tempResult[5] - miny) * ((double)height2 / height);
474 result[10] = tempResult2[0] + (tempResult[6] - minx) * ((double)width2 / width);
475 result[11] = tempResult2[1] + (tempResult[7] - miny) * ((double)height2 / height);
478 void adjust(int *x, int *y, int x1, int y1, int x2, int y2, double ratio){
482 *x = pngWidth - (pngWidth - *x) * ratio;
487 *y = pngHeight - (pngHeight - *y) * ratio;
491 void combineHame2(KGString *parts1, KGString *parts3, int *result, int surround){
500 CalcOptions(parts3, &mitsu, &flg_box, &yoko, &tate);
502 if(yoko * tate > 12){
503 ratio = sqrt(12 / (yoko * tate));
504 temp = kg_string_new("");
505 buf = convertStroke(parts1->str, buf, &strokes);
506 for(i = 0; i < strokes; i++){
507 if(buf[i * 11] == 9){
508 x1 = buf[i * 11 + 3];
509 y1 = buf[i * 11 + 4];
510 x2 = buf[i * 11 + 5];
511 y2 = buf[i * 11 + 6];
515 for(i = 0; i <strokes; i++){
519 adjust(&buf[i * 11 + 9], &buf[i * 11 + 10], x1,y1,x2,y2, ratio);
523 adjust(&buf[i * 11 + 7], &buf[i * 11 + 8], x1,y1,x2,y2, ratio);
528 adjust(&buf[i * 11 + 5], &buf[i * 11 + 6], x1,y1,x2,y2, ratio);
529 adjust(&buf[i * 11 + 3], &buf[i * 11 + 4], x1,y1,x2,y2, ratio);
532 convertArray(buf, temp, strokes, 0);
533 kg_string_assign(parts1, temp->str);
543 buf = convertStroke(parts1->str, buf, &strokes);
544 for(i = 0; i < strokes; i++){
545 if(buf[i * 11 + 0] == 9){
546 result[8] = buf[i * 11 + 3];
547 if(flg_box & FLAG_FLAT_LEFT){
548 if(surround & FLAG_SURROUND_LEFT){
549 result[8] += kWidth * 4;
551 result[8] += kWidth * 2;
554 result[9] = buf[i * 11 + 4];
555 if(flg_box & FLAG_FLAT_TOP){
556 if(surround & FLAG_SURROUND_TOP){
557 result[9] += kWidth * 4;
559 result[9] += kWidth * 2;
562 result[10] = buf[i * 11 + 5];
563 if(flg_box & FLAG_FLAT_RIGHT){
564 if(surround & FLAG_SURROUND_RIGHT){
565 result[10] -= kWidth * 4;
567 result[10] -= kWidth * 2;
570 result[11] = buf[i * 11 + 6];
571 if(flg_box & FLAG_FLAT_BOTTOM){
572 if(surround & FLAG_SURROUND_BOTTOM){
573 result[11] -= kWidth * 4;
575 result[11] -= kWidth * 2;
581 if(flag == 0){ //error