Divide combining function of U+2FF4-U+2FFA.
authorKoichi KAMICHI <kamichi@fonts.jp>
Tue, 28 Dec 2004 04:27:31 +0000 (04:27 +0000)
committerKoichi KAMICHI <kamichi@fonts.jp>
Tue, 28 Dec 2004 04:27:31 +0000 (04:27 +0000)
kagecgi/kage.h
kagecgi/kagecgi.h
kagecgi/kagecomb.c
kagecgi/kageeg.c

index 9a9dd11..2c5e4f0 100755 (executable)
@@ -1,52 +1,57 @@
-//kage.h\r
-//\r
-\r
-#include "sysdep.h"\r
-\r
-#ifndef _KAGE_H_\r
-#define _KAGE_H_\r
-\r
-int kShotai;\r
-#define kMincho 0\r
-#define kGothic 1\r
-\r
-#define kMage 10\r
-#define kRate 20\r
-#define kResolution (1000 / kRate + 1) * 2\r
-#define kMinWidthY 2\r
-#define kMinWidthT 6\r
-#define kWidth 5\r
-#define kKakato 3 //has KAKATO = 2, no KAKATO = 1\r
-#define kKasane 3\r
-#define kMixdot (kWidth * 2) * (kWidth * 2 - 1)\r
-#define kL2RDfatten 1.1\r
-\r
-#define kMaxIDSSequenceLength 16\r
-#define kMaxIDCLength 16\r
-#define kMaxStrokeDataLength 256 // over 12(digits per integer with +/- flag) * 11(columns) + 1(line end)\r
+//kage.h
+//
+
+#include "sysdep.h"
+
+#ifndef _KAGE_H_
+#define _KAGE_H_
+
+int kShotai;
+#define kMincho 0
+#define kGothic 1
+
+#define kMage 10
+#define kRate 20
+#define kResolution (1000 / kRate + 1) * 2
+#define kMinWidthY 2
+#define kMinWidthT 6
+#define kWidth 5
+#define kKakato 3 //has KAKATO = 2, no KAKATO = 1
+#define kKasane 3
+#define kMixdot (kWidth * 2) * (kWidth * 2 - 1)
+#define kL2RDfatten 1.1
+
+#define kMaxIDSSequenceLength 16
+#define kMaxIDCLength 16
+#define kMaxStrokeDataLength 256 // over 12(digits per integer with +/- flag) * 11(columns) + 1(line end)
 
 #define FLAG_FLAT_LEFT 1
 #define FLAG_FLAT_RIGHT 2
 #define FLAG_FLAT_TOP 4
 #define FLAG_FLAT_BOTTOM 8
-\r
-typedef struct _kPoint{\r
-       double X;\r
-       double Y;\r
-} kPoint;\r
-\r
-kPoint poly[kResolution];\r
-kPoint poly2[3];\r
-kPoint poly3[5];\r
-kPoint poly4[4];\r
-\r
-//kagedf.c\r
-void dfDrawFont(int, int, int, int, int, int, int, int, int, int, int);\r
-//kagecd.c\r
-void cdDrawBezier(double, double, double, double, double, double, double, double, int, int);\r
-void cdDrawCurve(double, double, double, double, double, double, int, int);\r
-void cdDrawLine(double, double, double, double, int, int);\r
-//kageic.c\r
-void icPolygon(kPoint *, int);\r
-\r
-#endif\r
+
+#define FLAG_SURROUND_LEFT 1
+#define FLAG_SURROUND_RIGHT 2
+#define FLAG_SURROUND_TOP 4
+#define FLAG_SURROUND_BOTTOM 8
+
+typedef struct _kPoint{
+       double X;
+       double Y;
+} kPoint;
+
+kPoint poly[kResolution];
+kPoint poly2[3];
+kPoint poly3[5];
+kPoint poly4[4];
+
+//kagedf.c
+void dfDrawFont(int, int, int, int, int, int, int, int, int, int, int);
+//kagecd.c
+void cdDrawBezier(double, double, double, double, double, double, double, double, int, int);
+void cdDrawCurve(double, double, double, double, double, double, int, int);
+void cdDrawLine(double, double, double, double, int, int);
+//kageic.c
+void icPolygon(kPoint *, int);
+
+#endif
index 26836e6..aec5f0f 100755 (executable)
@@ -1,85 +1,85 @@
-//kagecgi.h\r
-//\r
-\r
-#include "kage.h"\r
-#include "sysdep.h"\r
-\r
-#ifndef _KAGECGI_H_\r
-#define _KAGECGI_H_\r
-\r
-// define for localhost environment\r
-#define errorFileSize 3992\r
-#define errorFileName "error.png"\r
-#define pngFilePath "/var/www/v0.4/"\r
-#define partsdbFileName "/var/www/kagedb/partsdb"\r
-#define idsdbFileName "/var/www/kagedb/idsdb"\r
-#define aliasdbFileName "/var/www/kagedb/aliasdb"\r
-\r
-#define kBaseline 188\r
-#define pngWidth 200\r
-#define pngHeight 200\r
-#define canvasWidth 400\r
-#define canvasHeight 400\r
-\r
-#define min(x1,x2) ((x1) > (x2))? (x2):(x1)\r
-#define max(x1,x2) ((x1) > (x2))? (x1):(x2)\r
-\r
-DB *kPartsdbDatabase;\r
-DB *kIdsdbDatabase;\r
-DB *kAliasdbDatabase;\r
-\r
-FILE *debug;\r
-\r
-png_bytepp kageCanvas;\r
-\r
-int kDesign;\r
-int kSize;\r
-int kType;\r
-int kInput;\r
-KGString *kResultText;\r
-int kMode;\r
-\r
-void generateGlyph(const KGString *in, KGString *out);\r
-void searchPartsData(const KGString *in, KGString *out);\r
-void searchAliasData(const KGString *in, KGString *out);\r
-void searchCacheData(const KGString *in, KGString *out);\r
-void doCombine(const KGString *in, KGString *out);\r
-void drawGlyph(const KGString *in, const int mode);\r
-\r
-int isIDS(const KGString *in);\r
-void divideInto2(const KGString *in, KGString *partIDS1, KGString *partIDS3);\r
-void divideInto3(const KGString *in, KGString *partIDS1, KGString *partIDS2, KGString *partIDS3);\r
-void addStrokeWithTransform(const KGString *stroke, const int num, const int *tf, KGString *out, int mode);\r
-void convertArray(int *buf, KGString *out, int size, int mode);\r
-int * convertStroke(const char *in, int *a, int *size);\r
-void convert99(const KGString *in, KGString *out);\r
-void convert99calc(const char *in, KGString *out);\r
-\r
-void DotsWidth(int *dlx, int *drx);\r
-void DotsHeight(int *dly, int *dry);\r
-void PartsWidth(const KGString *in, int *lx, int *rx);\r
-void PartsHeight(const KGString *in, int *ly, int *ry);\r
-KGString * CalcSizes(const KGString *in, int mode);\r
-void DrawBox();\r
-void CalcOptions(const KGString *in, int *mitsudo, int *flag, double *yoko, double *tate);\r
-void DoDrawParts(const KGString *in, const int lx1, const double rf1, const int ly1, const double rfy1);\r
-void DoDrawMixFont(const KGString *in1, const int lx1, const double rf1, const KGString *in2, const int lx2, const double rf2, const int ly1, const double rfy1, const int ly2, const double rfy2);\r
-\r
-void combineYoko2(const KGString *parts1, const KGString *parts3, int *result);\r
-void combineYoko3(const KGString *parts1, const KGString *parts2, const KGString *parts3, int *result);\r
-void combineTate2(const KGString *parts1, const KGString *parts3, int *result);\r
-void combineTate3(const KGString *parts1, const KGString *parts2, const KGString *parts3, int *result);\r
-void combineHame2(const KGString *parts1, const KGString *parts3, int *result);\r
-\r
-int initDB();\r
-int closeDB();\r
-void searchPartsData(const KGString *in, KGString *out);\r
-void searchAliasData(const KGString *in, KGString *out);\r
-\r
-png_bytepp initPng(int width, int height);\r
-int closePng(int width, int height, png_bytepp canvas);\r
-int writePng(int width, int height, png_bytepp image, FILE *fp);\r
-\r
-void fillPolygon(kPoint *p, int number, int col, unsigned char **image);\r
-\r
-#endif\r
+//kagecgi.h
+//
+
+#include "kage.h"
+#include "sysdep.h"
+
+#ifndef _KAGECGI_H_
+#define _KAGECGI_H_
+
+// define for localhost environment
+#define errorFileSize 3992
+#define errorFileName "error.png"
+#define pngFilePath "/var/www/v0.4/"
+#define partsdbFileName "/var/www/kagedb/partsdb"
+#define idsdbFileName "/var/www/kagedb/idsdb"
+#define aliasdbFileName "/var/www/kagedb/aliasdb"
+
+#define kBaseline 188
+#define pngWidth 200
+#define pngHeight 200
+#define canvasWidth 400
+#define canvasHeight 400
+
+#define min(x1,x2) ((x1) > (x2))? (x2):(x1)
+#define max(x1,x2) ((x1) > (x2))? (x1):(x2)
+
+DB *kPartsdbDatabase;
+DB *kIdsdbDatabase;
+DB *kAliasdbDatabase;
+
+FILE *debug;
+
+png_bytepp kageCanvas;
+
+int kDesign;
+int kSize;
+int kType;
+int kInput;
+KGString *kResultText;
+int kMode;
+
+void generateGlyph(const KGString *in, KGString *out);
+void searchPartsData(const KGString *in, KGString *out);
+void searchAliasData(const KGString *in, KGString *out);
+void searchCacheData(const KGString *in, KGString *out);
+void doCombine(const KGString *in, KGString *out);
+void drawGlyph(const KGString *in, const int mode);
+
+int isIDS(const KGString *in);
+void divideInto2(const KGString *in, KGString *partIDS1, KGString *partIDS3);
+void divideInto3(const KGString *in, KGString *partIDS1, KGString *partIDS2, KGString *partIDS3);
+void addStrokeWithTransform(const KGString *stroke, const int num, const int *tf, KGString *out, int mode);
+void convertArray(int *buf, KGString *out, int size, int mode);
+int * convertStroke(const char *in, int *a, int *size);
+void convert99(const KGString *in, KGString *out);
+void convert99calc(const char *in, KGString *out);
+
+void DotsWidth(int *dlx, int *drx);
+void DotsHeight(int *dly, int *dry);
+void PartsWidth(const KGString *in, int *lx, int *rx);
+void PartsHeight(const KGString *in, int *ly, int *ry);
+KGString * CalcSizes(const KGString *in, int mode);
+void DrawBox();
+void CalcOptions(const KGString *in, int *mitsudo, int *flag, double *yoko, double *tate);
+void DoDrawParts(const KGString *in, const int lx1, const double rf1, const int ly1, const double rfy1);
+void DoDrawMixFont(const KGString *in1, const int lx1, const double rf1, const KGString *in2, const int lx2, const double rf2, const int ly1, const double rfy1, const int ly2, const double rfy2);
+
+void combineYoko2(const KGString *parts1, const KGString *parts3, int *result);
+void combineYoko3(const KGString *parts1, const KGString *parts2, const KGString *parts3, int *result);
+void combineTate2(const KGString *parts1, const KGString *parts3, int *result);
+void combineTate3(const KGString *parts1, const KGString *parts2, const KGString *parts3, int *result);
+void combineHame2(const KGString *parts1, const KGString *parts3, int *result, int surround);
+
+int initDB();
+int closeDB();
+void searchPartsData(const KGString *in, KGString *out);
+void searchAliasData(const KGString *in, KGString *out);
+
+png_bytepp initPng(int width, int height);
+int closePng(int width, int height, png_bytepp canvas);
+int writePng(int width, int height, png_bytepp image, FILE *fp);
+
+void fillPolygon(kPoint *p, int number, int col, unsigned char **image);
+
+#endif
index 0f4a297..7860322 100755 (executable)
-//kagecomb.c\r
-//\r
-\r
-#include "kage.h"\r
-#include "kagecgi.h"\r
-#include "sysdep.h"\r
-\r
-void combineYoko2(const KGString *parts1, const KGString *parts3, int *result){\r
-       int f, g, h, i, j, k, l;\r
-       int flg_boxL, flg_boxR;\r
-       int YsideLa, YsideLb, YsideRa, YsideRb, YheightL, YnanameL, YsmallL;\r
-       int pxL, pxR, pyL, pyR;\r
-       double prL, prR, pryL, pryR, rL, rR, rTemp;\r
-       int lxL, rxL, lxR, rxR;\r
-       int dlyL, dryL, dlyR, dryR;\r
-       int chk_y1, chk_y2;\r
-       int mitsuL, mitsuR;\r
-       double yokoL, tateL, yokoR, tateR;\r
-       int *buf, strokes;\r
-       int tempShotai;\r
-       \r
-       //initialize\r
-       pxL = 0;\r
-       pyL = 0;\r
-       prL = 1.0;\r
-       pryL = 1.0;\r
-       pxR = 0;\r
-       pyR = 0;\r
-       prR = 1.0;\r
-       pryR = 1.0;\r
-       \r
-       YsideLa = 0;\r
-       YsideLb = 0;\r
-       YsideRa = 0;\r
-       YsideRb = 0;\r
-       YnanameL = 0;\r
-       YheightL = pngWidth * 0.9;\r
-       \r
-       tempShotai = kShotai;\r
-       kShotai = kGothic;\r
-       \r
-       CalcOptions(parts1, &mitsuL, &flg_boxL, &yokoL, &tateL);\r
-       CalcOptions(parts3, &mitsuR, &flg_boxR, &yokoR, &tateR);\r
-       \r
-       //left parts Y-axis processing #1\r
-       
-       //if its upper and bottom are flat\r
-       if(flg_boxL & FLAG_FLAT_TOP) YsideLa++;\r
-       if(flg_boxL & FLAG_FLAT_BOTTOM) YsideLb++;\r
-       \r
-       //if its goes right-up\r
-       j = 0;\r
-       buf = convertStroke(parts1->str, buf, &strokes);\r
-       for(i = 0; i < strokes; i++){
-               if(buf[i * 11 + 0] / 10 == 1){
-                       j++;
-               }
-       }\r
-       free(buf);\r
-       l = 0;\r
-       if(j != 0){\r
-               YsideLb++;\r
-               YnanameL++;\r
-       }
-       YheightL = YheightL - (YsideLa + YsideLb) * 2 * kWidth;\r
-       \r
-       //left parts Y-axis processing #2\r
-       YsmallL = 0;\r
-       YsmallL = 1;\r
-       if(flg_boxL & FLAG_FLAT_TOP && flg_boxL & FLAG_FLAT_BOTTOM && tateL <= 4){
-               YheightL = (double)YheightL * (max(0.65, tateL * 0.22));
-       } else if(flg_boxL & FLAG_FLAT_BOTTOM && tateL <= 3){
-               YheightL = (double)YheightL * 0.8;
-       } else if(YnanameL != 0 && flg_boxL & FLAG_FLAT_TOP && tateL <= 4){
-               YheightL = (double)YheightL * (max(0.65, tateL * 0.22));
-       } else if(YnanameL != 0 && tateL <= 3){
-               YheightL = (double)YheightL * 0.8;
-       } else{
-               YsmallL = 0;
-       }\r
-       \r
-       //left parts Y-axis processing #3\r
-       DoDrawParts(parts1, pxL, prL, pyL, pryL);\r
-       DotsHeight(&dlyL, &dryL);\r
-       pryL = (double)YheightL / (dryL - dlyL);\r
-       \r
-       if(YsmallL != 0){\r
-               if(flg_boxL & FLAG_FLAT_TOP){
-                       pyL = kBaseline - (double)pngWidth * 0.9 + 6 * kWidth - dlyL * pryL;
-               } else{
-                       pyL = kBaseline - (double)pngWidth * 0.9 + 2 * kWidth - dlyL * pryL;
-               }\r
-       } else{\r
-               if(flg_boxL & FLAG_FLAT_BOTTOM || YnanameL != 0){
-                       pyL = kBaseline - 2 * kWidth - dryL * pryL;
-               } else{
-                       pyL = kBaseline - dryL * pryL;
-               }\r
-       }\r
-       \r
-       //right parts Y-axis processing #1\r
-       if(flg_boxR & FLAG_FLAT_TOP) YsideRa++;\r
-       if(flg_boxR & FLAG_FLAT_BOTTOM) YsideRb++;\r
-       \r
-       DoDrawParts(parts3, pxR, prR, pyR, pryR);\r
-       DotsHeight(&dlyR, &dryR);\r
-       \r
-       pryR = ((double)pngWidth * 0.9 - (YsideRa + YsideRb) * 2 * kWidth) / (dryR - dlyR);\r
-       pyR = kBaseline - dryR * pryR;\r
-       if(flg_boxR & FLAG_FLAT_BOTTOM){
-               pyR = pyR - 2 * kWidth;
-       }\r
-       \r
-       //calculate ratio\r
-       rL = yokoL;\r
-       rR = yokoR;\r
-       \r
-       if(flg_boxL & FLAG_FLAT_LEFT) rL = rL * 0.7;\r
-       if(flg_boxL & FLAG_FLAT_RIGHT) rL = rL * 0.7;\r
-       if(flg_boxR & FLAG_FLAT_LEFT) rR = rR * 0.7;\r
-       if(flg_boxR & FLAG_FLAT_RIGHT) rR = rR * 0.7;\r
-       \r
-       rL = pow(rL, 0.6);\r
-       rR = pow(rR, 0.6);\r
-       \r
-       rR = rR * 1.05;\r
-       \r
-       rTemp = rL + rR;\r
-       rL = rL / rTemp;\r
-       rR = rR / rTemp;\r
-       \r
-       prL = rL;\r
-       prR = rR;\r
-       \r
-       //calculate width of each parts #1\r
-       PartsWidth(parts1, &lxL, &rxL);\r
-       PartsWidth(parts3, &lxR, &rxR);\r
-       g = 0;\r
-       \r
-       //calculate width of each parts #2\r
-       pxL = 0;\r
-       pxR = pngWidth * prL;\r
-       \r
-       DoDrawMixFont(parts1, pxL, prL, parts3, pxR, prR, pyL, pryL, pyR, pryR);\r
-       \r
-       //count dots for check crossing over\r
-       DotsHeight(&chk_y1, &chk_y2);\r
-       k = 0;\r
-       for(i = 0; i < pngWidth * 1.1; i++){\r
-               for(j = chk_y1; j <= chk_y2; j++){\r
-                       if(kageCanvas[j][i] == 0) k++;\r
-               }\r
-       }\r
-       l = k;\r
-       \r
-       //get close both parts\r
-       h = pxR;\r
-       while(k - l < kMixdot && g < kWidth * 2 * kKasane * 2){\r
-               g = g + 2;\r
-               f = pxR - g;\r
-               DoDrawMixFont(parts1, pxL, prL, parts3, f, prR, pyL, pryL, pyR, pryR);\r
-               
-               //FOR DEBUG\r
-               //char fn[256];\r
-               //FILE *fp;\r
-               //snprintf(fn,sizeof(fn),"%03d.png",g);\r
-               //fp = fopen(fn, "w");\r
-               //writePng(pngWidth, pngHeight, kageCanvas, fp);\r
-               //fclose(fp);\r
-               \r
-               l = 0;\r
-               for(i = 0; i < pngWidth * 1.1; i++){\r
-                       for(j = chk_y1; j <= chk_y2; j++){\r
-                               if(kageCanvas[j][i] == 0) l++;\r
-                       }\r
-               }\r
-       }\r
-       pxR = f;\r
-       
-       if(flg_boxL & FLAG_FLAT_RIGHT && flg_boxR & FLAG_FLAT_LEFT){\r
-               if(kShotai == kMincho){
-                       pxR = pxR + kMinWidthT * 2 * kKasane * 3 / 2;\r
-               } else {
-                       pxR = pxR + kWidth * 2 * kKasane * 3 / 2;
-               }\r
-       } else {
-               pxR = pxR + kWidth * 2 * kKasane * 2 / 2;
-       }\r
-       \r
-       //set results\r
-       result[0] = pxL;\r
-       result[1] = pyL;\r
-       result[2] = pxL + pngWidth * prL;\r
-       result[3] = pyL + pngWidth * pryL;\r
-       result[8] = pxR;\r
-       result[9] = pyR;\r
-       result[10] = pxR + pngWidth * prR;\r
-       result[11] = pyR + pngWidth * pryR;\r
-       \r
-       kShotai = tempShotai;\r
-}\r
-\r
-void combineYoko3(const KGString *parts1, const KGString *parts2, const KGString *parts3, int *result){\r
-       //temp.
-       KGString *tempString;
-       int tempResult[8], tempResult2[4];
-       int minx, miny, maxx, maxy, width, height, width2, height2;
-       
-       tempString = kg_string_new("");
-       combineYoko2(parts2, parts3, result);
-       addStrokeWithTransform(parts2, 1, result, tempString, 1);\r
-       addStrokeWithTransform(parts3, 3, result, tempString, 1);\r
-       tempResult[0] = result[0];
-       tempResult[1] = result[1];
-       tempResult[2] = result[2];
-       tempResult[3] = result[3];
-       tempResult[4] = result[8];
-       tempResult[5] = result[9];
-       tempResult[6] = result[10];
-       tempResult[7] = result[11];
-       minx = result[0];
-       miny = min(result[1], result[9]);
-       maxx = result[10];
-       maxy = max(result[3], result[11]);
-       width = maxx - minx;
-       height = maxy - miny;
-       
-       combineYoko2(parts1, tempString, result);
-       tempResult2[0] = result[8];
-       tempResult2[1] = result[9];
-       tempResult2[2] = result[10];
-       tempResult2[3] = result[11];
-       width2 = result[10] - result[8];
-       height2 = result[11] - result[9];
-       \r
-       result[4] = tempResult2[0] + (tempResult[0] - minx) * ((double)width2 / width); // always 0
-       result[5] = tempResult2[1] + (tempResult[1] - miny) * ((double)height2 / height);
-       result[6] = tempResult2[0] + (tempResult[2] - minx) * ((double)width2 / width);
-       result[7] = tempResult2[1] + (tempResult[3] - miny) * ((double)height2 / height);
-       result[8] = tempResult2[0] + (tempResult[4] - minx) * ((double)width2 / width);
-       result[9] = tempResult2[1] + (tempResult[5] - miny) * ((double)height2 / height);
-       result[10] = tempResult2[0] + (tempResult[6] - minx) * ((double)width2 / width);
-       result[11] = tempResult2[1] + (tempResult[7] - miny) * ((double)height2 / height);
-}\r
-\r
-void combineTate2(const KGString *parts1, const KGString *parts3, int *result){\r
-       int f, g, h, i, j, k, l;\r
-       int flg_boxL, flg_boxR;\r
-       int pxL, pxR, pyL, pyR;\r
-       double prL, prR, pryL, pryR, rL, rR, rTemp;\r
-       int lxL, rxL, lxR, rxR;\r
-       int lyL, ryL, lyR, ryR;\r
-       int dlxL, drxL, dlxR, drxR;\r
-       int chk_x1, chk_x2;\r
-       int mitsuL, mitsuR;\r
-       double yokoL, tateL, yokoR, tateR;\r
-       int tempShotai;\r
-       \r
-       //initialize\r
-       pxL = 0;\r
-       pyL = 0;\r
-       prL = 1.0;\r
-       pryL = 1.0;\r
-       pxR = 0;\r
-       pyR = 0;\r
-       prR = 1.0;\r
-       pryR = 1.0;\r
-       \r
-       tempShotai = kShotai;\r
-       kShotai = kGothic;\r
-       \r
-       CalcOptions(parts1, &mitsuL, &flg_boxL, &yokoL, &tateL);\r
-       CalcOptions(parts3, &mitsuR, &flg_boxR, &yokoR, &tateR);\r
-       \r
-       //calculate ratio\r
-       rL = tateL;\r
-       rR = tateR;\r
-       \r
-       if(flg_boxL & FLAG_FLAT_TOP) rL = rL * 0.7;\r
-       if(flg_boxL & FLAG_FLAT_BOTTOM) rL = rL * 0.7;\r
-       if(flg_boxR & FLAG_FLAT_TOP) rR = rR * 0.7;\r
-       if(flg_boxR & FLAG_FLAT_BOTTOM) rR = rR * 0.7;\r
-       \r
-       rL = pow(rL, 0.8);\r
-       rR = pow(rR, 0.8);\r
-       \r
-       rR = rR * 1.1;\r
-       \r
-       rTemp = rL + rR;\r
-       rL = rL / rTemp;\r
-       rR = rR / rTemp;\r
-               \r
-       pryL = rL;\r
-       pryR = rR;\r
-       \r
-       //calucurate size of X-axis\r
-       PartsWidth(parts1, &lxL, &rxL);\r
-       PartsWidth(parts3, &lxR, &rxR);\r
-       PartsHeight(parts1, &lyL, &ryL);\r
-       PartsHeight(parts3, &lyR, &ryR);\r
-       \r
-       //left parts\r
-       if(flg_boxL & FLAG_FLAT_LEFT && flg_boxL & FLAG_FLAT_RIGHT){\r
-               prL = min(1.0, (double)yokoL * 0.1 + 0.5) - ((kWidth * 6) / (kSize * 0.9));\r
-               DoDrawParts(parts1, pxL, prL, pyL, pryL);\r
-               DotsWidth(&dlxL, &drxL);\r
-               pxL = (kSize / 2 - (dlxL + drxL) / 2);\r
-       } else if(flg_boxL & FLAG_FLAT_LEFT){\r
-               prL = (kSize * 0.9 - kWidth * 4) / (rxL - lxL);\r
-               pxL = kWidth * 4;\r
-       } else if(flg_boxL & FLAG_FLAT_RIGHT){\r
-               prL = (kSize * 0.9 - kWidth * 4) / (rxL - lxL);\r
-               pxL = (kSize * 0.05 + kWidth * 2) - lxL * prL;\r
-       }\r
-       \r
-       //right parts\r
-       if(flg_boxR & FLAG_FLAT_LEFT && flg_boxR & FLAG_FLAT_RIGHT){\r
-               prR = min(1.0, (double)yokoR * 0.1 + 0.5) - ((kWidth * 6) / (kSize * 0.9));\r
-               DoDrawParts(parts3, pxR, prR, pyR, pryR);\r
-               DotsWidth(&dlxR, &drxR);\r
-               pxR = (kSize / 2 - (dlxR + drxR) / 2);\r
-       } else if(flg_boxR & FLAG_FLAT_LEFT){\r
-               prR = (kSize * 0.9 - kWidth * 4) / (rxR - lxR);\r
-               pxR = (kSize * 0.05 + kWidth * 3) - lxR * prR;\r
-       } else if(flg_boxR & FLAG_FLAT_RIGHT){\r
-               prR = (kSize * 0.9 - kWidth * 4) / (rxR - lxR);\r
-               pxR = (kSize * 0.05 + kWidth * 1) - lxR * prR;\r
-       }\r
-       \r
-       g = 0;\r
-       \r
-       //calculate width of each parts\r
-       pyL = kWidth * 1.5 + (kSize - kWidth * 1.5 * 4) * pryL * 0.5 - (lyL + ryL) / 2 * pryL;\r
-       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;\r
-       \r
-       DoDrawMixFont(parts1, pxL, prL, parts3, pxR, prR, pyL, pryL, pyR, pryR);\r
-       \r
-       //count dots for check crossing over\r
-       DotsWidth(&chk_x1, &chk_x2);\r
-       k = 0;\r
-       for(i = 0; i < pngWidth * 1.1; i++){\r
-               for(j = chk_x1; j <= chk_x2; j++){\r
-                       if(kageCanvas[i][j] == 0) k++;\r
-               }\r
-       }\r
-       l = k;\r
-       \r
-       //get close both parts\r
-       h = pyR;\r
-       while(k - l < kMixdot && g < kWidth * (kKasane + 4)){\r
-               g = g + 2;\r
-               f = pyR - g;\r
-               DoDrawMixFont(parts1, pxL, prL, parts3, pxR, prR, pyL, pryL, f, pryR);\r
-               \r
-               l = 0;\r
-               for(i = 0; i < pngWidth * 1.1; i++){\r
-                       for(j = chk_x1; j <= chk_x2; j++){\r
-                               if(kageCanvas[i][j] == 0) l++;\r
-                       }\r
-               }\r
-       }\r
-       pyR = f;\r
-       if(k - l > pngWidth * 0.4){
-               pyR = pyR + kWidth * 4;
-       } else {
-               pyR = pyR + kWidth * 2;\r
-       }
-       \r
-       //set results\r
-       result[0] = pxL;\r
-       result[1] = pyL;\r
-       result[2] = pxL + pngWidth * prL;\r
-       result[3] = pyL + pngWidth * pryL;\r
-       result[8] = pxR;\r
-       result[9] = pyR;\r
-       result[10] = pxR + pngWidth * prR;\r
-       result[11] = pyR + pngWidth * pryR;\r
-       \r
-       kShotai = tempShotai;\r
-}\r
-\r
-void combineTate3(const KGString *parts1, const KGString *parts2, const KGString *parts3, int *result){\r
-       //temp.
-       //temp.
-       KGString *tempString;
-       int tempResult[8], tempResult2[4];
-       int minx, miny, maxx, maxy, width, height, width2, height2;
-       
-       tempString = kg_string_new("");
-       combineTate2(parts2, parts3, result);
-       addStrokeWithTransform(parts2, 1, result, tempString, 1);\r
-       addStrokeWithTransform(parts3, 3, result, tempString, 1);\r
-       tempResult[0] = result[0];
-       tempResult[1] = result[1];
-       tempResult[2] = result[2];
-       tempResult[3] = result[3];
-       tempResult[4] = result[8];
-       tempResult[5] = result[9];
-       tempResult[6] = result[10];
-       tempResult[7] = result[11];
-       minx = min(result[0], result[8]);
-       miny = min(result[1], result[9]);
-       maxx = max(result[2], result[10]);
-       maxy = max(result[3], result[11]);
-       width = maxx - minx;
-       height = maxy - miny;
-       
-       combineTate2(parts1, tempString, result);
-       tempResult2[0] = result[8];
-       tempResult2[1] = result[9];
-       tempResult2[2] = result[10];
-       tempResult2[3] = result[11];
-       width2 = result[10] - result[8];
-       height2 = result[11] - result[9];
-       \r
-       result[4] = tempResult2[0] + (tempResult[0] - minx) * ((double)width2 / width); // always 0
-       result[5] = tempResult2[1] + (tempResult[1] - miny) * ((double)height2 / height);
-       result[6] = tempResult2[0] + (tempResult[2] - minx) * ((double)width2 / width);
-       result[7] = tempResult2[1] + (tempResult[3] - miny) * ((double)height2 / height);
-       result[8] = tempResult2[0] + (tempResult[4] - minx) * ((double)width2 / width);
-       result[9] = tempResult2[1] + (tempResult[5] - miny) * ((double)height2 / height);
-       result[10] = tempResult2[0] + (tempResult[6] - minx) * ((double)width2 / width);
-       result[11] = tempResult2[1] + (tempResult[7] - miny) * ((double)height2 / height);
-}\r
-\r
-void combineHame2(const KGString *parts1, const KGString *parts3, int *result){\r
-       int i, flag;\r
-       int *buf, strokes;
-       double yoko, tate;
-       int mitsu, flg_box;\r
-       \r
-       flag = 0;\r
-       CalcOptions(parts3, &mitsu, &flg_box, &yoko, &tate);\r
-       \r
-       //set results\r
-       result[0] = 0;\r
-       result[1] = 0;\r
-       result[2] = 200;\r
-       result[3] = 200;\r
-       buf = convertStroke(parts1->str, buf, &strokes);\r
-       for(i = 0; i < strokes; i++){\r
-               if(buf[i * 11 + 0] == 9){\r
-                       result[8] = buf[i * 11 + 3];
-                       if(flg_box & FLAG_FLAT_LEFT) result[8] += kWidth * 4;\r
-                       result[9] = buf[i * 11 + 4];
-                       if(flg_box & FLAG_FLAT_TOP) result[9] += kWidth * 4;\r
-                       result[10] = buf[i * 11 + 5];\r
-                       if(flg_box & FLAG_FLAT_RIGHT) result[10] -= kWidth * 4;\r
-                       result[11] = buf[i * 11 + 6];
-                       if(flg_box & FLAG_FLAT_BOTTOM) result[11] -= kWidth * 4;\r
-                       flag = 1;\r
-               }\r
-       }\r
-       if(flag == 0){ //error\r
-               result[8] = 50;\r
-               result[9] = 50;\r
-               result[10] = 150;\r
-               result[11] = 150;\r
-       }\r
-}\r
+//kagecomb.c
+//
+
+#include "kage.h"
+#include "kagecgi.h"
+#include "sysdep.h"
+
+void combineYoko2(const KGString *parts1, const KGString *parts3, int *result){
+  int f, g, h, i, j, k, l;
+  int flg_boxL, flg_boxR;
+  int YsideLa, YsideLb, YsideRa, YsideRb, YheightL, YnanameL, YsmallL;
+  int pxL, pxR, pyL, pyR;
+  double prL, prR, pryL, pryR, rL, rR, rTemp;
+  int lxL, rxL, lxR, rxR;
+  int dlyL, dryL, dlyR, dryR;
+  int chk_y1, chk_y2;
+  int mitsuL, mitsuR;
+  double yokoL, tateL, yokoR, tateR;
+  int *buf, strokes;
+  int tempShotai;
+  
+  //initialize
+  pxL = 0;
+  pyL = 0;
+  prL = 1.0;
+  pryL = 1.0;
+  pxR = 0;
+  pyR = 0;
+  prR = 1.0;
+  pryR = 1.0;
+  
+  YsideLa = 0;
+  YsideLb = 0;
+  YsideRa = 0;
+  YsideRb = 0;
+  YnanameL = 0;
+  YheightL = pngWidth * 0.9;
+  
+  tempShotai = kShotai;
+  kShotai = kGothic;
+  
+  CalcOptions(parts1, &mitsuL, &flg_boxL, &yokoL, &tateL);
+  CalcOptions(parts3, &mitsuR, &flg_boxR, &yokoR, &tateR);
+  
+  //left parts Y-axis processing #1
+  
+  //if its upper and bottom are flat
+  if(flg_boxL & FLAG_FLAT_TOP) YsideLa++;
+  if(flg_boxL & FLAG_FLAT_BOTTOM) YsideLb++;
+  
+  //if its goes right-up
+  j = 0;
+  buf = convertStroke(parts1->str, buf, &strokes);
+  for(i = 0; i < strokes; i++){
+    if(buf[i * 11 + 0] / 10 == 1){
+      j++;
+    }
+  }
+  free(buf);
+  l = 0;
+  if(j != 0){
+    YsideLb++;
+    YnanameL++;
+  }
+  YheightL = YheightL - (YsideLa + YsideLb) * 2 * kWidth;
+  
+  //left parts Y-axis processing #2
+  YsmallL = 0;
+  YsmallL = 1;
+  if(flg_boxL & FLAG_FLAT_TOP && flg_boxL & FLAG_FLAT_BOTTOM && tateL <= 4){
+    YheightL = (double)YheightL * (max(0.65, tateL * 0.22));
+  } else if(flg_boxL & FLAG_FLAT_BOTTOM && tateL <= 3){
+    YheightL = (double)YheightL * 0.8;
+  } else if(YnanameL != 0 && flg_boxL & FLAG_FLAT_TOP && tateL <= 4){
+    YheightL = (double)YheightL * (max(0.65, tateL * 0.22));
+  } else if(YnanameL != 0 && tateL <= 3){
+    YheightL = (double)YheightL * 0.8;
+  } else{
+    YsmallL = 0;
+  }
+  
+  //left parts Y-axis processing #3
+  DoDrawParts(parts1, pxL, prL, pyL, pryL);
+  DotsHeight(&dlyL, &dryL);
+  pryL = (double)YheightL / (dryL - dlyL);
+  
+  if(YsmallL != 0){
+    if(flg_boxL & FLAG_FLAT_TOP){
+      pyL = kBaseline - (double)pngWidth * 0.9 + 6 * kWidth - dlyL * pryL;
+    } else{
+      pyL = kBaseline - (double)pngWidth * 0.9 + 2 * kWidth - dlyL * pryL;
+    }
+  } else{
+    if(flg_boxL & FLAG_FLAT_BOTTOM || YnanameL != 0){
+      pyL = kBaseline - 2 * kWidth - dryL * pryL;
+    } else{
+      pyL = kBaseline - dryL * pryL;
+    }
+  }
+  
+  //right parts Y-axis processing #1
+  if(flg_boxR & FLAG_FLAT_TOP) YsideRa++;
+  if(flg_boxR & FLAG_FLAT_BOTTOM) YsideRb++;
+  
+  DoDrawParts(parts3, pxR, prR, pyR, pryR);
+  DotsHeight(&dlyR, &dryR);
+  
+  pryR = ((double)pngWidth * 0.9 - (YsideRa + YsideRb) * 2 * kWidth) / (dryR - dlyR);
+  pyR = kBaseline - dryR * pryR;
+  if(flg_boxR & FLAG_FLAT_BOTTOM){
+    pyR = pyR - 2 * kWidth;
+  }
+  
+  //calculate ratio
+  rL = yokoL;
+  rR = yokoR;
+  
+  if(flg_boxL & FLAG_FLAT_LEFT) rL = rL * 0.7;
+  if(flg_boxL & FLAG_FLAT_RIGHT) rL = rL * 0.7;
+  if(flg_boxR & FLAG_FLAT_LEFT) rR = rR * 0.7;
+  if(flg_boxR & FLAG_FLAT_RIGHT) rR = rR * 0.7;
+  
+  rL = pow(rL, 0.6);
+  rR = pow(rR, 0.6);
+  
+  rR = rR * 1.05;
+  
+  rTemp = rL + rR;
+  rL = rL / rTemp;
+  rR = rR / rTemp;
+  
+  prL = rL;
+  prR = rR;
+  
+  //calculate width of each parts #1
+  PartsWidth(parts1, &lxL, &rxL);
+  PartsWidth(parts3, &lxR, &rxR);
+  g = 0;
+  
+  //calculate width of each parts #2
+  pxL = 0;
+  pxR = pngWidth * prL;
+  
+  DoDrawMixFont(parts1, pxL, prL, parts3, pxR, prR, pyL, pryL, pyR, pryR);
+  
+  //count dots for check crossing over
+  DotsHeight(&chk_y1, &chk_y2);
+  k = 0;
+  for(i = 0; i < pngWidth * 1.1; i++){
+    for(j = chk_y1; j <= chk_y2; j++){
+      if(kageCanvas[j][i] == 0) k++;
+    }
+  }
+  l = k;
+  
+  //get close both parts
+  h = pxR;
+  while(k - l < kMixdot && g < kWidth * 2 * kKasane * 2){
+    g = g + 2;
+    f = pxR - g;
+    DoDrawMixFont(parts1, pxL, prL, parts3, f, prR, pyL, pryL, pyR, pryR);
+    
+    //FOR DEBUG
+    //char fn[256];
+    //FILE *fp;
+    //snprintf(fn,sizeof(fn),"%03d.png",g);
+    //fp = fopen(fn, "w");
+    //writePng(pngWidth, pngHeight, kageCanvas, fp);
+    //fclose(fp);
+    
+    l = 0;
+    for(i = 0; i < pngWidth * 1.1; i++){
+      for(j = chk_y1; j <= chk_y2; j++){
+        if(kageCanvas[j][i] == 0) l++;
+      }
+    }
+  }
+  pxR = f;
+  
+  if(flg_boxL & FLAG_FLAT_RIGHT && flg_boxR & FLAG_FLAT_LEFT){
+    if(kShotai == kMincho){
+      pxR = pxR + kMinWidthT * 2 * kKasane * 3 / 2;
+    } else {
+      pxR = pxR + kWidth * 2 * kKasane * 3 / 2;
+    }
+  } else {
+    pxR = pxR + kWidth * 2 * kKasane * 2 / 2;
+  }
+  
+  //set results
+  result[0] = pxL;
+  result[1] = pyL;
+  result[2] = pxL + pngWidth * prL;
+  result[3] = pyL + pngWidth * pryL;
+  result[8] = pxR;
+  result[9] = pyR;
+  result[10] = pxR + pngWidth * prR;
+  result[11] = pyR + pngWidth * pryR;
+  
+  kShotai = tempShotai;
+}
+
+void combineYoko3(const KGString *parts1, const KGString *parts2, const KGString *parts3, int *result){
+  //temp.
+  KGString *tempString;
+  int tempResult[8], tempResult2[4];
+  int minx, miny, maxx, maxy, width, height, width2, height2;
+  
+  tempString = kg_string_new("");
+  combineYoko2(parts2, parts3, result);
+  addStrokeWithTransform(parts2, 1, result, tempString, 1);
+  addStrokeWithTransform(parts3, 3, result, tempString, 1);
+  tempResult[0] = result[0];
+  tempResult[1] = result[1];
+  tempResult[2] = result[2];
+  tempResult[3] = result[3];
+  tempResult[4] = result[8];
+  tempResult[5] = result[9];
+  tempResult[6] = result[10];
+  tempResult[7] = result[11];
+  minx = result[0];
+  miny = min(result[1], result[9]);
+  maxx = result[10];
+  maxy = max(result[3], result[11]);
+  width = maxx - minx;
+  height = maxy - miny;
+  
+  combineYoko2(parts1, tempString, result);
+  tempResult2[0] = result[8];
+  tempResult2[1] = result[9];
+  tempResult2[2] = result[10];
+  tempResult2[3] = result[11];
+  width2 = result[10] - result[8];
+  height2 = result[11] - result[9];
+  
+  result[4] = tempResult2[0] + (tempResult[0] - minx) * ((double)width2 / width); // always 0
+  result[5] = tempResult2[1] + (tempResult[1] - miny) * ((double)height2 / height);
+  result[6] = tempResult2[0] + (tempResult[2] - minx) * ((double)width2 / width);
+  result[7] = tempResult2[1] + (tempResult[3] - miny) * ((double)height2 / height);
+  result[8] = tempResult2[0] + (tempResult[4] - minx) * ((double)width2 / width);
+  result[9] = tempResult2[1] + (tempResult[5] - miny) * ((double)height2 / height);
+  result[10] = tempResult2[0] + (tempResult[6] - minx) * ((double)width2 / width);
+  result[11] = tempResult2[1] + (tempResult[7] - miny) * ((double)height2 / height);
+}
+
+void combineTate2(const KGString *parts1, const KGString *parts3, int *result){
+  int f, g, h, i, j, k, l;
+  int flg_boxL, flg_boxR;
+  int pxL, pxR, pyL, pyR;
+  double prL, prR, pryL, pryR, rL, rR, rTemp;
+  int lxL, rxL, lxR, rxR;
+  int lyL, ryL, lyR, ryR;
+  int dlxL, drxL, dlxR, drxR;
+  int chk_x1, chk_x2;
+  int mitsuL, mitsuR;
+  double yokoL, tateL, yokoR, tateR;
+  int tempShotai;
+  
+  //initialize
+  pxL = 0;
+  pyL = 0;
+  prL = 1.0;
+  pryL = 1.0;
+  pxR = 0;
+  pyR = 0;
+  prR = 1.0;
+  pryR = 1.0;
+  
+  tempShotai = kShotai;
+  kShotai = kGothic;
+  
+  CalcOptions(parts1, &mitsuL, &flg_boxL, &yokoL, &tateL);
+  CalcOptions(parts3, &mitsuR, &flg_boxR, &yokoR, &tateR);
+  
+  //calculate ratio
+  rL = tateL;
+  rR = tateR;
+  
+  if(flg_boxL & FLAG_FLAT_TOP) rL = rL * 0.7;
+  if(flg_boxL & FLAG_FLAT_BOTTOM) rL = rL * 0.7;
+  if(flg_boxR & FLAG_FLAT_TOP) rR = rR * 0.7;
+  if(flg_boxR & FLAG_FLAT_BOTTOM) rR = rR * 0.7;
+  
+  rL = pow(rL, 0.8);
+  rR = pow(rR, 0.8);
+  
+  rR = rR * 1.1;
+  
+  rTemp = rL + rR;
+  rL = rL / rTemp;
+  rR = rR / rTemp;
+  
+  pryL = rL;
+  pryR = rR;
+  
+  //calucurate size of X-axis
+  PartsWidth(parts1, &lxL, &rxL);
+  PartsWidth(parts3, &lxR, &rxR);
+  PartsHeight(parts1, &lyL, &ryL);
+  PartsHeight(parts3, &lyR, &ryR);
+  
+  //left parts
+  if(flg_boxL & FLAG_FLAT_LEFT && flg_boxL & FLAG_FLAT_RIGHT){
+    prL = min(1.0, (double)yokoL * 0.1 + 0.5) - ((kWidth * 6) / (kSize * 0.9));
+    DoDrawParts(parts1, pxL, prL, pyL, pryL);
+    DotsWidth(&dlxL, &drxL);
+    pxL = (kSize / 2 - (dlxL + drxL) / 2);
+  } else if(flg_boxL & FLAG_FLAT_LEFT){
+    prL = (kSize * 0.9 - kWidth * 4) / (rxL - lxL);
+    pxL = kWidth * 4;
+  } else if(flg_boxL & FLAG_FLAT_RIGHT){
+    prL = (kSize * 0.9 - kWidth * 4) / (rxL - lxL);
+    pxL = (kSize * 0.05 + kWidth * 2) - lxL * prL;
+  }
+  
+  //right parts
+  if(flg_boxR & FLAG_FLAT_LEFT && flg_boxR & FLAG_FLAT_RIGHT){
+    prR = min(1.0, (double)yokoR * 0.1 + 0.5) - ((kWidth * 6) / (kSize * 0.9));
+    DoDrawParts(parts3, pxR, prR, pyR, pryR);
+    DotsWidth(&dlxR, &drxR);
+    pxR = (kSize / 2 - (dlxR + drxR) / 2);
+  } else if(flg_boxR & FLAG_FLAT_LEFT){
+    prR = (kSize * 0.9 - kWidth * 4) / (rxR - lxR);
+    pxR = (kSize * 0.05 + kWidth * 3) - lxR * prR;
+  } else if(flg_boxR & FLAG_FLAT_RIGHT){
+    prR = (kSize * 0.9 - kWidth * 4) / (rxR - lxR);
+    pxR = (kSize * 0.05 + kWidth * 1) - lxR * prR;
+  }
+  
+  g = 0;
+  
+  //calculate width of each parts
+  pyL = kWidth * 1.5 + (kSize - kWidth * 1.5 * 4) * pryL * 0.5 - (lyL + ryL) / 2 * pryL;
+  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;
+  
+  DoDrawMixFont(parts1, pxL, prL, parts3, pxR, prR, pyL, pryL, pyR, pryR);
+  
+  //count dots for check crossing over
+  DotsWidth(&chk_x1, &chk_x2);
+  k = 0;
+  for(i = 0; i < pngWidth * 1.1; i++){
+    for(j = chk_x1; j <= chk_x2; j++){
+      if(kageCanvas[i][j] == 0) k++;
+    }
+  }
+  l = k;
+  
+  //get close both parts
+  h = pyR;
+  while(k - l < kMixdot && g < kWidth * (kKasane + 4)){
+    g = g + 2;
+    f = pyR - g;
+    DoDrawMixFont(parts1, pxL, prL, parts3, pxR, prR, pyL, pryL, f, pryR);
+    
+    l = 0;
+    for(i = 0; i < pngWidth * 1.1; i++){
+      for(j = chk_x1; j <= chk_x2; j++){
+        if(kageCanvas[i][j] == 0) l++;
+      }
+    }
+  }
+  pyR = f;
+  if(k - l > pngWidth * 0.4){
+    pyR = pyR + kWidth * 4;
+  } else {
+    pyR = pyR + kWidth * 2;
+  }
+  
+  //set results
+  result[0] = pxL;
+  result[1] = pyL;
+  result[2] = pxL + pngWidth * prL;
+  result[3] = pyL + pngWidth * pryL;
+  result[8] = pxR;
+  result[9] = pyR;
+  result[10] = pxR + pngWidth * prR;
+  result[11] = pyR + pngWidth * pryR;
+  
+  kShotai = tempShotai;
+}
+
+void combineTate3(const KGString *parts1, const KGString *parts2, const KGString *parts3, int *result){
+  //temp.
+  KGString *tempString;
+  int tempResult[8], tempResult2[4];
+  int minx, miny, maxx, maxy, width, height, width2, height2;
+  
+  tempString = kg_string_new("");
+  combineTate2(parts2, parts3, result);
+  addStrokeWithTransform(parts2, 1, result, tempString, 1);
+  addStrokeWithTransform(parts3, 3, result, tempString, 1);
+  tempResult[0] = result[0];
+  tempResult[1] = result[1];
+  tempResult[2] = result[2];
+  tempResult[3] = result[3];
+  tempResult[4] = result[8];
+  tempResult[5] = result[9];
+  tempResult[6] = result[10];
+  tempResult[7] = result[11];
+  minx = min(result[0], result[8]);
+  miny = min(result[1], result[9]);
+  maxx = max(result[2], result[10]);
+  maxy = max(result[3], result[11]);
+  width = maxx - minx;
+  height = maxy - miny;
+  
+  combineTate2(parts1, tempString, result);
+  tempResult2[0] = result[8];
+  tempResult2[1] = result[9];
+  tempResult2[2] = result[10];
+  tempResult2[3] = result[11];
+  width2 = result[10] - result[8];
+  height2 = result[11] - result[9];
+  
+  result[4] = tempResult2[0] + (tempResult[0] - minx) * ((double)width2 / width); // always 0
+  result[5] = tempResult2[1] + (tempResult[1] - miny) * ((double)height2 / height);
+  result[6] = tempResult2[0] + (tempResult[2] - minx) * ((double)width2 / width);
+  result[7] = tempResult2[1] + (tempResult[3] - miny) * ((double)height2 / height);
+  result[8] = tempResult2[0] + (tempResult[4] - minx) * ((double)width2 / width);
+  result[9] = tempResult2[1] + (tempResult[5] - miny) * ((double)height2 / height);
+  result[10] = tempResult2[0] + (tempResult[6] - minx) * ((double)width2 / width);
+  result[11] = tempResult2[1] + (tempResult[7] - miny) * ((double)height2 / height);
+}
+
+void combineHame2(const KGString *parts1, const KGString *parts3, int *result, int surround){
+  int i, flag;
+  int *buf, strokes;
+  double yoko, tate;
+  int mitsu, flg_box;
+  
+  flag = 0;
+  CalcOptions(parts3, &mitsu, &flg_box, &yoko, &tate);
+  
+  //set results
+  result[0] = 0;
+  result[1] = 0;
+  result[2] = 200;
+  result[3] = 200;
+  buf = convertStroke(parts1->str, buf, &strokes);
+  for(i = 0; i < strokes; i++){
+    if(buf[i * 11 + 0] == 9){
+      result[8] = buf[i * 11 + 3];
+      if(flg_box & FLAG_FLAT_LEFT){
+        if(surround & FLAG_SURROUND_LEFT){
+          result[8] += kWidth * 4;
+        } else {
+          result[8] += kWidth * 2;
+        }
+      }
+      result[9] = buf[i * 11 + 4];
+      if(flg_box & FLAG_FLAT_TOP){
+        if(surround & FLAG_SURROUND_TOP){
+          result[9] += kWidth * 4;
+        } else {
+          result[9] += kWidth * 2;
+        }
+      }
+      result[10] = buf[i * 11 + 5];
+      if(flg_box & FLAG_FLAT_RIGHT){
+        if(surround & FLAG_SURROUND_RIGHT){
+          result[10] -= kWidth * 4;
+        } else {
+          result[10] -= kWidth * 2;
+        }
+      }
+      result[11] = buf[i * 11 + 6];
+      if(flg_box & FLAG_FLAT_BOTTOM){
+        if(surround & FLAG_SURROUND_BOTTOM){
+          result[11] -= kWidth * 4;
+        } else {
+          result[11] -= kWidth * 2;
+        }
+      }
+      flag = 1;
+    }
+  }
+  if(flag == 0){ //error
+    result[8] = 50;
+    result[9] = 50;
+    result[10] = 150;
+    result[11] = 150;
+  }
+}
index 891a67c..785047a 100755 (executable)
-//kageeg.c\r
-//\r
-\r
-#include "kage.h"\r
-#include "kagecgi.h"\r
-#include "sysdep.h"\r
-\r
-void generateGlyphByIDS(const KGString *in, KGString *out, int flag){\r
-       KGString *tmp1, *tmp2;\r
-       \r
-       //pass this method if 'in' is not UCS parts\r
-       if((in->str)[0] != 'u'){\r
-               generateGlyph(in, out);\r
-               return;\r
-       }\r
-       //pass this method if 'in' is place-variant-flag defined\r
-       if(in->len < 5 && 7 < in->len){\r
-               generateGlyph(in, out);\r
-               return;\r
-       }\r
-       \r
-       tmp1 = kg_string_new(in->str);\r
-       tmp2 = kg_string_new(in->str);\r
-       \r
-       //append place flag\r
-       if(1 <= flag && flag <= 7){\r
-               if(tmp1->len != 7) kg_string_append(tmp1, "-");\r
-               if(flag == 1) kg_string_append(tmp1, "01");\r
-               else if(flag == 2) kg_string_append(tmp1, "02");\r
-               else if(flag == 3) kg_string_append(tmp1, "03");\r
-               else if(flag == 4) kg_string_append(tmp1, "04");\r
-               else if(flag == 5) kg_string_append(tmp1, "05");\r
-               else if(flag == 6) kg_string_append(tmp1, "06");\r
-       }\r
-\r
-       generateGlyph(tmp1, out);\r
-       if(out->len != 0) return;\r
-       generateGlyph(tmp2, out);\r
-       if(out->len != 0) return;\r
-       return;\r
-}\r
-\r
-void generateGlyph(const KGString *in, KGString *out){\r
-  KGString *tmp;\r
-       tmp = kg_string_new("");\r
-       kg_string_set_size(out, 0);\r
-       \r
-       //search from parts\r
-       searchPartsData(in, tmp);\r
-       if(tmp->len != 0){\r
-         tmp = CalcSizes(tmp, 1);\r
-         out = kg_string_assign(out, tmp->str);\r
-         return;\r
-       }\r
-       \r
-       //search from alias\r
-       searchAliasData(in, tmp);\r
-       if(tmp->len != 0){\r
-               generateGlyph(tmp, out);\r
-               if(out->len == 0) return;\r
-               //save to cache ... not yet\r
-               return;\r
-       }\r
-       \r
-       //check if its IDS\r
-       if(isIDS(in)){\r
-               doCombine(in, out);\r
-               if(out->len == 0) return;\r
-               //save to cache ... not yet\r
-               return;\r
-       }\r
-}\r
-\r
-void doCombine(const KGString *in, KGString *out){\r
-       KGString *partIDS1, *partIDS2, *partIDS3;\r
-       KGString *partStroke1, *partStroke2, *partStroke3;\r
-       int result[12];\r
-       \r
-       partIDS1 = kg_string_new("");\r
-       partIDS2 = kg_string_new("");\r
-       partIDS3 = kg_string_new("");\r
-       partStroke1 = kg_string_new("");\r
-       partStroke2 = kg_string_new("");\r
-       partStroke3 = kg_string_new("");\r
-       \r
-       kg_string_set_size(out, 0);\r
-       \r
-       //check first IDC\r
-       if(strncmp(in->str, "u2ff", 4) != 0) return;\r
-       //switch by combine types\r
-       switch((in->str)[4]){\r
-               case '0':\r
-                       divideInto2(in, partIDS1, partIDS3);\r
-                       if(partIDS1->len == 0) return;\r
-                       //ready each parts\r
-                       generateGlyphByIDS(partIDS1, partStroke1, 1);\r
-                       if(partStroke1->len == 0) return;\r
-                       partStroke1 = CalcSizes(partStroke1, 0);\r
-                       generateGlyphByIDS(partIDS3, partStroke3, 2);\r
-                       if(partStroke3->len == 0) return;\r
-                       partStroke3 = CalcSizes(partStroke3, 0);\r
-                       break;\r
-               case '1':\r
-                       divideInto2(in, partIDS1, partIDS3);\r
-                       if(partIDS1->len == 0) return;\r
-                       //ready each parts\r
-                       generateGlyphByIDS(partIDS1, partStroke1, 3);\r
-                       if(partStroke1->len == 0) return;\r
-                       partStroke1 = CalcSizes(partStroke1, 0);\r
-                       generateGlyphByIDS(partIDS3, partStroke3, 4);\r
-                       if(partStroke3->len == 0) return;\r
-                       partStroke3 = CalcSizes(partStroke3, 0);\r
-                       break;\r
-               case '4':\r
-               case '5':\r
-               case '6':\r
-               case '7':\r
-               case '8':\r
-               case '9':\r
-               case 'a':\r
-//             case 'b':\r
-                       divideInto2(in, partIDS1, partIDS3);\r
-                       if(partIDS1->len == 0) return;\r
-                       //ready each parts\r
-                       generateGlyphByIDS(partIDS1, partStroke1, 5);\r
-                       if(partStroke1->len == 0) return;\r
-                       partStroke1 = CalcSizes(partStroke1, 0);\r
-                       generateGlyphByIDS(partIDS3, partStroke3, 6);\r
-                       if(partStroke3->len == 0) return;\r
-                       partStroke3 = CalcSizes(partStroke3, 0);\r
-                       break;\r
-               case '2':\r
-                       divideInto3(in, partIDS1, partIDS2, partIDS3);\r
-                       if(partIDS1->len == 0) return;\r
-                       //ready each parts\r
-                       generateGlyphByIDS(partIDS1, partStroke1, 1);\r
-                       if(partStroke1->len == 0) return;\r
-                       partStroke1 = CalcSizes(partStroke1, 0);\r
-                       generateGlyphByIDS(partIDS2, partStroke2, 1);\r
-                       if(partStroke2->len == 0) return;\r
-                       partStroke2 = CalcSizes(partStroke2, 0);\r
-                       generateGlyphByIDS(partIDS3, partStroke3, 2);\r
-                       if(partStroke3->len == 0) return;\r
-                       partStroke3 = CalcSizes(partStroke3, 0);\r
-                       break;\r
-               case '3':\r
-                       divideInto3(in, partIDS1, partIDS2, partIDS3);\r
-                       if(partIDS1->len == 0) return;\r
-                       //ready each parts\r
-                       generateGlyphByIDS(partIDS1, partStroke1, 3);\r
-                       if(partStroke1->len == 0) return;\r
-                       partStroke1 = CalcSizes(partStroke1, 0);\r
-                       generateGlyphByIDS(partIDS2, partStroke2, 3);\r
-                       if(partStroke2->len == 0) return;\r
-                       partStroke2 = CalcSizes(partStroke2, 0);\r
-                       generateGlyphByIDS(partIDS3, partStroke3, 4);\r
-                       if(partStroke3->len == 0) return;\r
-                       partStroke3 = CalcSizes(partStroke3, 0);\r
-                       break;\r
-       }\r
-       switch((in->str)[4]){\r
-               case '0':\r
-                       combineYoko2(partStroke1, partStroke3, result);\r
-                       break;\r
-               case '1':\r
-                       combineTate2(partStroke1, partStroke3, result);\r
-                       break;\r
-               case '2':\r
-                       combineYoko3(partStroke1, partStroke2, partStroke3, result);\r
-                       break;\r
-               case '3':\r
-                       combineTate3(partStroke1, partStroke2, partStroke3, result);\r
-                       break;\r
-               case '4':\r
-               case '5':\r
-               case '6':\r
-               case '7':\r
-               case '8':\r
-               case '9':\r
-               case 'a':\r
-//             case 'b':\r
-                       combineHame2(partStroke1, partStroke3, result);\r
-                       break;\r
-       }\r
-       switch((in->str)[4]){\r
-               case '0':\r
-               case '1':\r
-               case '4':\r
-               case '5':\r
-               case '6':\r
-               case '7':\r
-               case '8':\r
-               case '9':\r
-               case 'a':\r
-//             case 'b':\r
-                       addStrokeWithTransform(partStroke1, 1, result, out, 1);\r
-                       addStrokeWithTransform(partStroke3, 3, result, out, 1);\r
-                       break;\r
-               case '2':\r
-               case '3':\r
-                       addStrokeWithTransform(partStroke1, 1, result, out, 1);\r
-                       addStrokeWithTransform(partStroke2, 2, result, out, 1);\r
-                       addStrokeWithTransform(partStroke3, 3, result, out, 1);\r
-                       break;\r
-       }\r
-}\r
-\r
-void drawGlyph(const KGString *in, const int mode){\r
-       int i, j;\r
-       int *buf;\r
-       buf = convertStroke(in->str, buf, &j);\r
-       for(i = 0; i < j; i++){\r
-               if(mode == 0){ //normal\r
-                       dfDrawFont(buf[i * 11 + 0],\r
-                        buf[i * 11 + 1],\r
-                        buf[i * 11 + 2],\r
-                        buf[i * 11 + 3],\r
-                        buf[i * 11 + 4],\r
-                        buf[i * 11 + 5],\r
-                        buf[i * 11 + 6],\r
-                        buf[i * 11 + 7],\r
-                        buf[i * 11 + 8],\r
-                        buf[i * 11 + 9],\r
-                        buf[i * 11 + 10]);\r
-               }\r
-               else if(mode == 1){ //without decoration\r
-                       dfDrawFont(buf[i * 11 + 0],\r
-                        0,\r
-                        0,\r
-                        buf[i * 11 + 3],\r
-                        buf[i * 11 + 4],\r
-                        buf[i * 11 + 5],\r
-                        buf[i * 11 + 6],\r
-                        buf[i * 11 + 7],\r
-                        buf[i * 11 + 8],\r
-                        buf[i * 11 + 9],\r
-                        buf[i * 11 + 10]);\r
-               }\r
-       }\r
-       free(buf);\r
-}\r
-\r
+//kageeg.c
+//
+
+#include "kage.h"
+#include "kagecgi.h"
+#include "sysdep.h"
+
+void generateGlyphByIDS(const KGString *in, KGString *out, int flag){
+  KGString *tmp1, *tmp2;
+  
+  //pass this method if 'in' is not UCS parts
+  if((in->str)[0] != 'u'){
+    generateGlyph(in, out);
+    return;
+  }
+  //pass this method if 'in' is place-variant-flag defined
+  if(in->len < 5 && 7 < in->len){
+    generateGlyph(in, out);
+    return;
+  }
+  
+  tmp1 = kg_string_new(in->str);
+  tmp2 = kg_string_new(in->str);
+  
+  //append place flag
+  if(1 <= flag && flag <= 7){
+    if(tmp1->len != 7) kg_string_append(tmp1, "-");
+    if(flag == 1) kg_string_append(tmp1, "01");
+    else if(flag == 2) kg_string_append(tmp1, "02");
+    else if(flag == 3) kg_string_append(tmp1, "03");
+    else if(flag == 4) kg_string_append(tmp1, "04");
+    else if(flag == 5) kg_string_append(tmp1, "05");
+    else if(flag == 6) kg_string_append(tmp1, "06");
+  }
+  
+  generateGlyph(tmp1, out);
+  if(out->len != 0) return;
+  generateGlyph(tmp2, out);
+  if(out->len != 0) return;
+  return;
+}
+
+void generateGlyph(const KGString *in, KGString *out){
+  KGString *tmp;
+  tmp = kg_string_new("");
+  kg_string_set_size(out, 0);
+  
+  //search from parts
+  searchPartsData(in, tmp);
+  if(tmp->len != 0){
+    tmp = CalcSizes(tmp, 1);
+    out = kg_string_assign(out, tmp->str);
+    return;
+  }
+  
+  //search from alias
+  searchAliasData(in, tmp);
+  if(tmp->len != 0){
+    generateGlyph(tmp, out);
+    if(out->len == 0) return;
+    //save to cache ... not yet
+    return;
+  }
+  
+  //check if its IDS
+  if(isIDS(in)){
+    doCombine(in, out);
+    if(out->len == 0) return;
+    //save to cache ... not yet
+    return;
+  }
+}
+
+void doCombine(const KGString *in, KGString *out){
+  KGString *partIDS1, *partIDS2, *partIDS3;
+  KGString *partStroke1, *partStroke2, *partStroke3;
+  int result[12];
+  
+  partIDS1 = kg_string_new("");
+  partIDS2 = kg_string_new("");
+  partIDS3 = kg_string_new("");
+  partStroke1 = kg_string_new("");
+  partStroke2 = kg_string_new("");
+  partStroke3 = kg_string_new("");
+  
+  kg_string_set_size(out, 0);
+  
+  //check first IDC
+  if(strncmp(in->str, "u2ff", 4) != 0) return;
+  //switch by combine types
+  switch((in->str)[4]){
+  case '0':
+    divideInto2(in, partIDS1, partIDS3);
+    if(partIDS1->len == 0) return;
+    //ready each parts
+    generateGlyphByIDS(partIDS1, partStroke1, 1);
+    if(partStroke1->len == 0) return;
+    partStroke1 = CalcSizes(partStroke1, 0);
+    generateGlyphByIDS(partIDS3, partStroke3, 2);
+    if(partStroke3->len == 0) return;
+    partStroke3 = CalcSizes(partStroke3, 0);
+    break;
+  case '1':
+    divideInto2(in, partIDS1, partIDS3);
+    if(partIDS1->len == 0) return;
+    //ready each parts
+    generateGlyphByIDS(partIDS1, partStroke1, 3);
+    if(partStroke1->len == 0) return;
+    partStroke1 = CalcSizes(partStroke1, 0);
+    generateGlyphByIDS(partIDS3, partStroke3, 4);
+    if(partStroke3->len == 0) return;
+    partStroke3 = CalcSizes(partStroke3, 0);
+    break;
+  case '4': //full surround
+  case '5': //surround from above
+  case '6': //surround from below
+  case '7': //surround from left
+  case '8': //surround from upper left
+  case '9': //surround from upper right
+  case 'a': //surround from lower left
+    //case 'b': //overlaid (not supported)
+    divideInto2(in, partIDS1, partIDS3);
+    if(partIDS1->len == 0) return;
+    //ready each parts
+    generateGlyphByIDS(partIDS1, partStroke1, 5);
+    if(partStroke1->len == 0) return;
+    partStroke1 = CalcSizes(partStroke1, 0);
+    generateGlyphByIDS(partIDS3, partStroke3, 6);
+    if(partStroke3->len == 0) return;
+    partStroke3 = CalcSizes(partStroke3, 0);
+    break;
+  case '2':
+    divideInto3(in, partIDS1, partIDS2, partIDS3);
+    if(partIDS1->len == 0) return;
+    //ready each parts
+    generateGlyphByIDS(partIDS1, partStroke1, 1);
+    if(partStroke1->len == 0) return;
+    partStroke1 = CalcSizes(partStroke1, 0);
+    generateGlyphByIDS(partIDS2, partStroke2, 1);
+    if(partStroke2->len == 0) return;
+    partStroke2 = CalcSizes(partStroke2, 0);
+    generateGlyphByIDS(partIDS3, partStroke3, 2);
+    if(partStroke3->len == 0) return;
+    partStroke3 = CalcSizes(partStroke3, 0);
+    break;
+  case '3':
+    divideInto3(in, partIDS1, partIDS2, partIDS3);
+    if(partIDS1->len == 0) return;
+    //ready each parts
+    generateGlyphByIDS(partIDS1, partStroke1, 3);
+    if(partStroke1->len == 0) return;
+    partStroke1 = CalcSizes(partStroke1, 0);
+    generateGlyphByIDS(partIDS2, partStroke2, 3);
+    if(partStroke2->len == 0) return;
+    partStroke2 = CalcSizes(partStroke2, 0);
+    generateGlyphByIDS(partIDS3, partStroke3, 4);
+    if(partStroke3->len == 0) return;
+    partStroke3 = CalcSizes(partStroke3, 0);
+    break;
+  }
+  switch((in->str)[4]){
+  case '0':
+    combineYoko2(partStroke1, partStroke3, result);
+    break;
+  case '1':
+    combineTate2(partStroke1, partStroke3, result);
+    break;
+  case '2':
+    combineYoko3(partStroke1, partStroke2, partStroke3, result);
+    break;
+  case '3':
+    combineTate3(partStroke1, partStroke2, partStroke3, result);
+    break;
+  case '4': //full surround
+    combineHame2(partStroke1, partStroke3, result,
+                 FLAG_SURROUND_LEFT |
+                 FLAG_SURROUND_RIGHT |
+                 FLAG_SURROUND_TOP |
+                 FLAG_SURROUND_BOTTOM);
+    break;
+  case '5': //surround from above
+    combineHame2(partStroke1, partStroke3, result,
+                 FLAG_SURROUND_LEFT |
+                 FLAG_SURROUND_RIGHT |
+                 FLAG_SURROUND_TOP);
+    break;
+  case '6': //surround from below
+    combineHame2(partStroke1, partStroke3, result,
+                 FLAG_SURROUND_LEFT |
+                 FLAG_SURROUND_RIGHT |
+                 FLAG_SURROUND_BOTTOM);
+    break;
+  case '7': //surround from left
+    combineHame2(partStroke1, partStroke3, result,
+                 FLAG_SURROUND_LEFT |
+                 FLAG_SURROUND_TOP |
+                 FLAG_SURROUND_BOTTOM);
+    break;
+  case '8': //surround from upper left
+    combineHame2(partStroke1, partStroke3, result,
+                 FLAG_SURROUND_LEFT |
+                 FLAG_SURROUND_TOP);
+    break;
+  case '9': //surround from upper right
+    combineHame2(partStroke1, partStroke3, result,
+                 FLAG_SURROUND_RIGHT |
+                 FLAG_SURROUND_TOP);
+    break;
+  case 'a': //surround from lower left
+    combineHame2(partStroke1, partStroke3, result,
+                 FLAG_SURROUND_LEFT |
+                 FLAG_SURROUND_BOTTOM);
+    break;
+    //case 'b': //overlaid (not supported)
+  }
+  switch((in->str)[4]){
+  case '0':
+  case '1':
+  case '4':
+  case '5':
+  case '6':
+  case '7':
+  case '8':
+  case '9':
+  case 'a':
+    //case 'b':
+    addStrokeWithTransform(partStroke1, 1, result, out, 1);
+    addStrokeWithTransform(partStroke3, 3, result, out, 1);
+    break;
+  case '2':
+  case '3':
+    addStrokeWithTransform(partStroke1, 1, result, out, 1);
+    addStrokeWithTransform(partStroke2, 2, result, out, 1);
+    addStrokeWithTransform(partStroke3, 3, result, out, 1);
+    break;
+  }
+}
+
+void drawGlyph(const KGString *in, const int mode){
+  int i, j;
+  int *buf;
+  buf = convertStroke(in->str, buf, &j);
+  for(i = 0; i < j; i++){
+    if(mode == 0){ //normal
+      dfDrawFont(buf[i * 11 + 0],
+                 buf[i * 11 + 1],
+                 buf[i * 11 + 2],
+                 buf[i * 11 + 3],
+                 buf[i * 11 + 4],
+                 buf[i * 11 + 5],
+                 buf[i * 11 + 6],
+                 buf[i * 11 + 7],
+                 buf[i * 11 + 8],
+                 buf[i * 11 + 9],
+                 buf[i * 11 + 10]);
+    }
+    else if(mode == 1){ //without decoration
+      dfDrawFont(buf[i * 11 + 0],
+                 0,
+                 0,
+                 buf[i * 11 + 3],
+                 buf[i * 11 + 4],
+                 buf[i * 11 + 5],
+                 buf[i * 11 + 6],
+                 buf[i * 11 + 7],
+                 buf[i * 11 + 8],
+                 buf[i * 11 + 9],
+                 buf[i * 11 + 10]);
+    }
+  }
+  free(buf);
+}
+