From b755cadf536858496296e43b30baec2cd9ec8c13 Mon Sep 17 00:00:00 2001 From: Koichi KAMICHI Date: Tue, 3 Feb 2004 16:11:30 +0000 Subject: [PATCH 1/1] Initial revision --- kagecgi/.DS_Store | Bin 0 -> 12292 bytes kagecgi/COPYING | 341 ++++++++++++++++ kagecgi/Makefile | 37 ++ kagecgi/error.png | Bin 0 -> 3992 bytes kagecgi/kage.h | 57 +++ kagecgi/kagecd.c | 1087 ++++++++++++++++++++++++++++++++++++++++++++++++++++ kagecgi/kagecgi.c | 193 ++++++++++ kagecgi/kagecgi.h | 85 ++++ kagecgi/kagechar.c | 397 +++++++++++++++++++ kagecgi/kagecomb.c | 400 +++++++++++++++++++ kagecgi/kagedb.c | 123 ++++++ kagecgi/kagedf.c | 356 +++++++++++++++++ kagecgi/kageeg.c | 306 +++++++++++++++ kagecgi/kageic.c | 25 ++ kagecgi/kagepng.c | 84 ++++ kagecgi/kagepoly.c | 29 ++ kagecgi/kagetool.c | 466 ++++++++++++++++++++++ 17 files changed, 3986 insertions(+) create mode 100644 kagecgi/.DS_Store create mode 100644 kagecgi/COPYING create mode 100755 kagecgi/Makefile create mode 100755 kagecgi/error.png create mode 100755 kagecgi/kage.h create mode 100755 kagecgi/kagecd.c create mode 100755 kagecgi/kagecgi.c create mode 100755 kagecgi/kagecgi.h create mode 100755 kagecgi/kagechar.c create mode 100755 kagecgi/kagecomb.c create mode 100755 kagecgi/kagedb.c create mode 100755 kagecgi/kagedf.c create mode 100755 kagecgi/kageeg.c create mode 100755 kagecgi/kageic.c create mode 100755 kagecgi/kagepng.c create mode 100755 kagecgi/kagepoly.c create mode 100755 kagecgi/kagetool.c diff --git a/kagecgi/.DS_Store b/kagecgi/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..1a57a1e8df746b98dadcfb19bb125f815649001c GIT binary patch literal 12292 zcmeI1J5Iwu5Qb+%gc4{{(je^#khp<`prD|F9>_bw5X7UP^HDeo_n_e>@XzcjS;w0$ z3JCoZ?T)jae;=P6k5>^9ck((s7U_vd2St5*4^_tWyq1QwVvCBM_3s!s@!EG9-%a8tGHWX28j7!Egr;J3PC7=a*h|KkVkNrn)p=nZu1H2nHFLR_ zep90}bMJ{}x%Oc$Ub(J~ALsjTNw)tHu10nZYvN}z$i!nlwfH4jd#Yy?pwzlaX0)XA zi2JFOx28rZwLY?%7id(KUrDOz$OW$39qzy}?vYYP^}9;P*zw62UAdB}yxMhpM*p}T zO+{^1xMlviA!n;~_Je0l0wh2J3j+Fl@F?nw=&RuE(Sgdg0Pt-zo8eerDOBU5FQTu4 z#~GLlQurWsaf{)C9PK{F713A02f4Vo`EYS$7k4PmMo0hN!jZy*XH5bmP$#exzV?8Q6mx51ahhvA$_ + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/kagecgi/Makefile b/kagecgi/Makefile new file mode 100755 index 0000000..1e88ed3 --- /dev/null +++ b/kagecgi/Makefile @@ -0,0 +1,37 @@ +# +# +# CC=gcc -g +CC= gcc -Wall + +VERSION=0.0.1 + +#for cygwin with glib gdk gtk +#CFLAGS= -I/usr/local/include -I/usr/local/include/glib-2.0 -I/usr/local/include/glib-2.0/glib -I/usr/local/include/glib-2.0/gobject -I/usr/local/include/gtk-2.0 -I/usr/local/include/gtk-2.0/gtk -I/usr/local/include/gtk-2.0/gdk -I/usr/local/include/gtk-2.0/gdk-pixbuf -I/usr/local/lib/glib-2.0/include -I/usr/local/lib/gtk-2.0/include -I/usr/local/include/pango-1.0 -I/usr/local/include/atk-1.0 +#LIBS= -lpng -ldb -L/usr/local/lib -lglib-2.0 -lgtk-win32-2.0 -lgdk-win32-2.0 -lgthread-2.0 -lpangowin32-1.0 -lgobject-2.0 -lgmodule-2.0 -lpangoft2-1.0 -lpango-1.0 -latk-1.0 -lgdk_pixbuf-2.0 + +#for cygwin with glib +#CFLAGS= -I/usr/local/include -I/usr/local/include/glib-2.0 -I/usr/local/include/glib-2.0/glib -I/usr/local/lib/glib-2.0/include +#LIBS= -L/usr/local/lib -lpng -ldb -lglib-2.0 + +#for linux +CFLAGS= -I/usr/local/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/X11R6/include +LIBS= -L/usr/local/lib -lpng -ldb -lglib-2.0 -L/usr/X11R6/lib -lX11 + +kage.cgi: kagecgi.o kagepng.o kagedf.o kagecd.o kageic.o kagepoly.o kagedb.o kageeg.o kagecomb.o kagechar.o kagetool.o + $(CC) $(CFLAGS) -o kage.cgi kagecgi.o kagepng.o kagedf.o kagecd.o kageic.o kagepoly.o kagedb.o kageeg.o kagecomb.o kagechar.o kagetool.o $(LIBS) + +kagecgi.o: kagecgi.c +kagedf.o: kagedf.c +kagecd.o: kagecd.c +kageic.o: kageic.c +kagepoly.o: kagepoly.c +kagedb.o: kagedb.c +kageeg.o: kageeg.c +kagechar.o: kagechar.c +kagecomb.o: kagecomb.c +kagetool.o: kagetool.c +kagepng.o: kagepng.c + +clean: + \rm -r -f *.o *~ *.exe *.cgi *.stackdump + diff --git a/kagecgi/error.png b/kagecgi/error.png new file mode 100755 index 0000000000000000000000000000000000000000..4c3a4d28247907795cf6da1973700606e7d2d824 GIT binary patch literal 3992 zcmb_fdpOgN_kXiC8J39LDTx@-rzum4TtY5GHusfKb18GbWk?dGTtCL##WWfvQ{eLjX(h5%5TCiM3jc+XbyyliI$0FlQ5fN&20w)R|v z9{>=d4FDW003iPbfWvq48&T)>0)lrgI|Ts%tnI(Vm!$!d1%Ly5=EjB&;qFT$ozSV* zu*9z}-xifqK8V%D`zgh2k^8Lmy;#A+hIdovnfn2|Oyl_M@R-?;foczxP8uYLs`Tyd zZYjFk7A5fSliV?kn}rh8)p||hv>xepD2gap#}#5@zJtM`YD%Bg3A9UQ`BjGi%*B!v ze&Bfu<>n!5T$~mZplH>Vpa@_{qZ&YM{P56}Pg3ef3BcqW)sO*WutooqWNj$?k4Zon zmTZ)xQ~C)2$G2QBn5JuKUfi|N+GRQdAh#=P5KDiZr`wV*_#d?JySTkp=)H-i9#c&1 zzus%-bL1u%+dE;5rdBqoZ%kLFuYIu}IUuXK;ix1=Ax4NgtZ#(dZnt204N`xtd-PoW z%PdmAKO5=mdo;DV>C1p$@j)fW@OF6XKkuC9t*$OCS)rdw{^6B$xVzW*k3jyop0bj( z&s)2{6YTLkvf)duf<$COR-T9#E9*V&X;oJ)J(jF_G+9UmiMUAh@bXg6d_fGQ(4_{` z4t&i*Je&VW#4RUP3tVLACbZPOyaq+%V+=hmYq74GMBjZQy|ukL$UG`~NN^14pq9{a zUBA9(pFJ|=CktFG(@_x{??|=vA=0srgCZW~b!c;|k zO&LCdHS(bXY1QXZXDME?ogP?;jl6Uq>dwnA-olt<&9LY!+qB7U&aZg zIWwoEf3(9KL*_C?#6<*9!{uXZM3#mX+R??h*gtUsJM1@35((-OK`Wf>^V(3!Vkc@K zb3ILoL%-p<7A~qZ{OAi0bV~oFP1p85L( zSMDoyzs%;kf3Zt~*}n*0s;5Y4vA%&M#YA+yt8Am*Nt6BS*Jte}+m9F@Kc5veHZo1h z?N-4=F{@Hz{Xw6v`;wj+$!6fhD4Gr@a(;#{LPaZ@Pl%vnB_}f^0yQyymhL50-ejF2!Zh%-i@e^acF{nWQth_-ahx zlgY*~{0G8o=PL_B_YN0+K;zC&wk#|Rh&DS()Z*&6w_5CK=jw4GsAFO6KH_zsX~lLO=ahz!DurcP{7Zji6a`VZV&?|MT$}@CJu@OTHCx$5N zrOkIqSyFe-lf34*F4}EXdT}cwiS)V!<(qb+ntY zKDv0!ojqyX!CuR~5YlRGowIn`>ywDoIfeSXDB!+tRUUyMa9VebDvliBYvA3UcZhHA z9Bh>C-M-`6wYa6k%N4uqZ*=u+4*uNjd+sg zXqt#7%t1+t5~rLvZwm$-E609GfiS;*BZJET4Tt53R6a^Xv^>&|Afdi_?maMg?hQ=- z1QVJSrQiwpDtIJ4K7>tVolnytAkto3GJ{f$W(qo_n8c2uVr4L<7~kV5jAc(P^giXM z*fQpHAk^8_kRO-%{vVjfLW6yM86(Qc7NJOMM8oTZ&(=|@2D}FBI-$rcPxXGq>C*(2 z0X_`d03rZhn3`%$B(R)_iZ1DYM^*l8wzh&KKJTtgT%`(U<9@EMuMchR7$;up6m_W} zrlqA-fl?~Y{0hTd+AHPpNTgLR_uUG444k55+uPuGLO|o>hf=@O11IE4N{!P^vZ3QO zRoShVZ~FZx!ZtTI*FN8W@UG2F4V`tD4QA}k$5O5^hVx|69kwiP-6869AU(;=89zHwDx!h_eYyu zndUOy9nrr%A{MgcoeU`q?|smIO{v#H{x!*y`MuLLpA?Y50Rkdtj5U`V!3LloCG3m=x4I}6`@weU5F65_5S&0IYySuNi% zG)LC1hF9Jrnu$#Z&#f z(+j@A8?ZDPE#^bJ$W!`&@2Mm+k;7P%6X$c~35eX*()&WxlFWjSFedTicT_7FgR-#k zp4(|D(Wm_-5O}av#yE|0cP7R>a1N_^H|h7Ae!p>9!hrK9%P8(bHz!W~&!ai5`jt`? zVW9m0N55@Z8SmHN{T@CJUpYxonCVh0K zxd=jqzI5k-_c1?T1X04Nc*FAJ$fMU0`#TXvO@=0tp;i+EN{2<#*a;p$ctYt>oUv?L2eEyMD)G)Nx#@mm0)o`#2@$4V4=(72GKt+YIv@x}2WjI2##+sB|K$Twq(~Jn`Kix>B0duM z98(R!CGn3+W%7+9=6r-@ozb&v+NmIJRF3Vl4Uk}11_W|W&Ns=CtKzYRP)*t-c*?iZyBSusB=bcoThk zqUC97zZv{$#^zgl{Y{4aoSW)6YZ;~MBRkC-u6#T`ZMB}E@tib>#~$qX+jRW&!M<&| z;gr$3EERR%x}jYi?C?0E?__9$OU&%XZsrU;M&0#B%7W!HC;g~bRDt=)faN8=GroTRbS-w-IMmW zwAh5`n)P65N}X|xI3?wFJf0$FI?8k&kV%pbd;d|sdhyHkl9yG_!KJ<}>d^u7woVz% z-*IBpvmeWT7rQe`FEP_QEA!Bu-9y?WA&!?7Fla?5CJzjxmuy{fS6ClTc zevv0z8*QBxMmvEA8CNfKq0b`s!7WDmB~J4g5sV`__p=eVS_eDva1E%(&!)nicb|@6 z%XdaiV#CC~%GI)n0Hx}=(HlZojQv@pC>*a@?au0*xj)LrW+C`6SFu?c$?rbZVxNYM zn>;+;8MV1@AsU^?>GO{Duy#~al;?Lm#UjB^_WP$`W>9oNbO$)afQ=7KCl$Y%z44C6 z-sGZ&$at^(Eu{qLuI{AwQN5vVo^uI~A?#>f!maEPl#F#RzmaHE^FHic=HOqcjg?AIo)_=dZ-h*dqp>T9bJE~9so`RCe`#jF#7>FM&ugF?hQ$={Kt1GhO zOlGEKxze%AOFb~h_$=A*NWc3h1!p|}(Y^94eXPgXC0Wue2A~o{R-29tU1L|vl^aUD zwWqIKF1agI#y%fxR)tU;-GVrYNT==jKyftp=zJY(J_5pe+uj9&sR&(ZXyKy-jueiZ zVj^i#9U?I7qrRQ~Y`#JAxPHJLz&C%RqF$J4y)+S+0K!bYx +#include +#include + +#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 kMaxIDSSequenceLength 16 +#define kMaxIDCLength 16 +#define kMaxStrokeDataLength 256 // over 12(digits per integer with +/- flag) * 11(columns) + 1(line end) + +struct kPoint{ + int X; + int Y; +}; + +XPoint xpoly[kResolution]; + +struct kPoint poly[kResolution]; +struct kPoint poly2[3]; +struct kPoint poly3[5]; +struct kPoint poly4[4]; + +struct EDGE { + struct EDGE *next; + long yTop, yBot; + long xNowWhole, xNowNum, xNowDen, xNowDir; + long xNowNumStep; +}; + +#define SGN(a) ( (a) > 0 ? 1 : ( (a) < 0 ? -1 : 0 ) ) + +//kagedf.c +void dfDrawFont(int, int, int, int, int, int, int, int, int, int, int); +//kagecd.c +void cdDrawCurve(int, int, int, int, int, int, int, int); +void cdDrawLine(int, int, int, int, int, int); +//kageic.c +void icPolygon(struct kPoint *, int); + +#endif diff --git a/kagecgi/kagecd.c b/kagecgi/kagecd.c new file mode 100755 index 0000000..93fc8e2 --- /dev/null +++ b/kagecgi/kagecd.c @@ -0,0 +1,1087 @@ +//kagecd.c +// +#include "kage.h" + +void cdDrawCurve(int x1, int y1, + int x2, int y2, + int x3, int y3, + int a1, int a2){ + + double rad, t; + double x, y, v; + double ix, iy, ia, ib, ir; + int ox1, oy1, ox2, oy2; + int count, tt; + int delta; + double deltad; + double XX, XY, YX, YY; + + if(kShotai == kMincho){ // mincho + switch(a1){ + case 0: + case 7: + delta = -1 * kMinWidthY * 0.5; + break; + case 1: + case 2: + case 6: + case 22: + delta = 0; + break; + case 12: + case 32: + delta = kMinWidthY; + break; + default: + break; + } + + if(x1 == x2){ + if(y1 < y2){ y1 = y1 - delta; } + else{ y1 = y1 + delta; } + } + else if(y1 == y2){ + if(x1 < x2){ x1 = x1 - delta; } + else{ x1 = x1 + delta; } + } + else{ + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{ v = -1; } + x1 = x1 - delta * cos(rad) * v; + y1 = y1 - delta * sin(rad) * v; + } + + switch(a2){ + case 0: + case 1: + case 8: + case 7: + case 9: + case 15: + case 14: + case 17: + case 5: + delta = 0; + break; + default: + break; + } + + if(x2 == x3){ + if(y2 < y3){ y3 = y3 + delta; } + else{ y3 = y3 - delta; } + } + else if(y2 == y3){ + if(x2 < x3){ x3 = x3 + delta; } + else{ x3 = x3 - delta; } + } + else{ + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + x3 = x3 + delta * cos(rad) * v; + y3 = y3 + delta * sin(rad) * v; + } + + count = 0; + + for(tt = 0; tt <= 1000; tt = tt + kRate){ + t = (double)(tt) / 1000; + + //calculate a dot + x = ((1.0 - t) * (1.0 - t) * x1 + 2.0 * t * (1.0 - t) * x2 + t * t * x3); + y = ((1.0 - t) * (1.0 - t) * y1 + 2.0 * t * (1.0 - t) * y2 + t * t * y3); + + //KATAMUKI of vector by BIBUN + ix = (x1 - 2.0 * x2 + x3) * 2.0 * t + (-2.0 * x1 + 2.0 * x2); + iy = (y1 - 2.0 * y2 + y3) * 2.0 * t + (-2.0 * y1 + 2.0 * y2); + + //line SUICHOKU by vector + if(ix != 0 && iy != 0){ + ir = atan(iy / ix * -1.0); + ia = sin(ir) * (double)(kMinWidthT); + ib = cos(ir) * (double)(kMinWidthT); + } + else if(ix == 0){ + ia = kMinWidthT; + ib = 0; + } + else{ + ia = 0; + ib = kMinWidthT; + } + + if(a1 == 7 && a2 != 17){ deltad = sqrt(t); } + else if(a2 == 7 && a1 != 17){ deltad = sqrt(1.0 - t); } + else if(a1 == 7 && a2 == 17){ deltad = sqrt(t / 2); } + else if(a1 == 17 && a2 != 7){ deltad = sqrt(t / 2 + 0.5); } + else if(a1 != 7 && a2 == 17){ deltad = sqrt(1.0 - t / 2); } + else if(a1 == 17 && a2 == 7){ deltad = sqrt(0.5 - t / 2); } + else{ deltad = 1; } + ia = ia * deltad; + ib = ib * deltad; + + //swap if two lines are crossing + if(((x + ia) - ox1) * ((x + ia) - ox1) + + ((y + ib) - oy1) * ((y + ib) - oy1) > + ((x - ia) - ox1) * ((x - ia) - ox1) + + ((y - ib) - oy1) * ((y - ib) - oy1) && count != 0){ + ia = ia * -1; + ib = ib * -1; + } + + //copy as an old point + ox1 = x + ia; + oy1 = y + ib; + ox2 = x - ia; + oy2 = y - ib; + + //copy to polygon structuer + poly[count].X = x + ia; + poly[count].Y = y + ib; + poly[(1000 / kRate + 1) * 2 - 1 - count].X = x - ia; + poly[(1000 / kRate + 1) * 2 - 1 - count].Y = y - ib; + count += 1; + } + + icPolygon(poly, (1000 / kRate + 1) * 2); + + //process for head of stroke + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{ v = -1; } + XX = sin(rad) * v; + XY = cos(rad) * v * -1; + YX = cos(rad) * v; + YY = sin(rad) * v; + + if(a1 == 12){ + if(x1 == x2){ + poly2[0].X = x1 - kMinWidthT; + poly2[0].Y = y1; + poly2[1].X = x1 + kMinWidthT; + poly2[1].Y = y1; + poly2[2].X = x1 - kMinWidthT; + poly2[2].Y = y1 - kMinWidthT; + icPolygon(poly2, 3); + } + else{ + poly2[0].X = x1 - kMinWidthT * XX; + poly2[0].Y = y1 - kMinWidthT * XY; + poly2[1].X = x1 + kMinWidthT * XX; + poly2[1].Y = y1 + kMinWidthT * XY; + poly2[2].X = x1 - kMinWidthT * XX - kMinWidthT * YX; + poly2[2].Y = y1 - kMinWidthT * XY - kMinWidthT * YY; + icPolygon(poly2, 3); + } + } + + if(a1 == 0){ + if(y1 <= y3){ //from up to bottom + if(x1 == x2){ + poly2[0].X = x1 - kMinWidthT; + poly2[0].Y = y1; + poly2[1].X = x1 + kMinWidthT; + poly2[1].Y = y1; + poly2[2].X = x1 - kMinWidthT; + poly2[2].Y = y1 - kMinWidthY; + icPolygon(poly2, 3); + } + else{ + poly2[0].X = x1 - kMinWidthT * XX; + poly2[0].Y = y1 - kMinWidthT * XY; + poly2[1].X = x1 + kMinWidthT * XX; + poly2[1].Y = y1 + kMinWidthT * XY; + poly2[2].X = x1 - kMinWidthT * XX - kMinWidthY * YX; + poly2[2].Y = y1 - kMinWidthT * XY - kMinWidthY * YY; + icPolygon(poly2, 3); + } + } + else{ //bottom to up + if(x1 == x2){ //is it right? + poly2[0].X = x1 - kMinWidthT; + poly2[0].Y = y1; + poly2[1].X = x1 + kMinWidthT; + poly2[1].Y = y1; + poly2[2].X = x1 - kMinWidthT; + poly2[2].Y = y1 + kMinWidthY; + icPolygon(poly2, 3); + } + else{ + poly2[0].X = x1 - kMinWidthT * XX; + poly2[0].Y = y1 - kMinWidthT * XY; + poly2[1].X = x1 + kMinWidthT * XX; + poly2[1].Y = y1 + kMinWidthT * XY; + poly2[2].X = x1 + kMinWidthT * XX - kMinWidthY * YX; + poly2[2].Y = y1 + kMinWidthT * XY - kMinWidthY * YY; + icPolygon(poly2, 3); + } + } + } + + if(a1 == 22){ //box's up-right corner, any time same degree + poly3[0].X = x1 - kMinWidthT; + poly3[0].Y = y1 - kMinWidthY; + poly3[1].X = x1; + poly3[1].Y = y1 - kMinWidthY - kWidth; + poly3[2].X = x1 + kMinWidthT + kWidth; + poly3[2].Y = y1 + kMinWidthY; + poly3[3].X = x1 + kMinWidthT; + poly3[3].Y = y1 + kMinWidthT; + poly3[4].X = x1 - kMinWidthT; + poly3[4].Y = y1; + icPolygon(poly3, 5); + } + + if(a1 == 0){ //beginning of the stroke + if(y1 <= y3){ //from up to bottom + if(x1 == x2){ + poly2[0].X = x1 + kMinWidthT; + poly2[0].Y = y1 + kMinWidthY * 0.5; + poly2[1].X = x1 + kMinWidthT + kMinWidthT * 0.5; + poly2[1].Y = y1 + kMinWidthY * 0.5 + kMinWidthY; + poly2[2].X = x1 + kMinWidthT; + poly2[2].Y = y1 + kMinWidthY * 0.5 + kMinWidthY * 2; + icPolygon(poly2, 3); + } + else{ + poly2[0].X = x1 + kMinWidthT * XX + (kMinWidthY * 0.5) * YX; + poly2[0].Y = y1 + kMinWidthT * XY + (kMinWidthY * 0.5) * YY; + poly2[1].X = x1 + (kMinWidthT + kMinWidthT * 0.5) * XX + (kMinWidthY * 0.5 + kMinWidthY) * YX; + poly2[1].Y = y1 + (kMinWidthT + kMinWidthT * 0.5) * XY + (kMinWidthY * 0.5 + kMinWidthY) * YY; + poly2[2].X = x1 + kMinWidthT * XX + (kMinWidthY * 0.5 + kMinWidthY * 2) * YX; + poly2[2].Y = y1 + kMinWidthT * XY + (kMinWidthY * 0.5 + kMinWidthY * 2) * YY; + icPolygon(poly2, 3); + } + } + else{ //from bottom to up + if(x1 == x2){ //is it right? + poly2[0].X = x1 + kMinWidthT; + poly2[0].Y = y1 - kMinWidthY * 0.5; + poly2[1].X = x1 + kMinWidthT + kMinWidthT * 0.5; + poly2[1].Y = y1 - kMinWidthY * 0.5 - kMinWidthY; + poly2[2].X = x1 + kMinWidthT; + poly2[2].Y = y1 - kMinWidthY * 0.5 - kMinWidthY * 2; + icPolygon(poly2, 3); + } + else //SETSUGOUMEN GA KAKERUNODE HOKYOU + poly3[0].X = x1 - (kMinWidthT - 1) * XX + (kMinWidthY * 0.5) * YX; + poly3[0].Y = y1 - (kMinWidthT - 1) * XY + (kMinWidthY * 0.5) * YY; + poly3[1].X = x1 - (kMinWidthT - 0) * XX + (kMinWidthY * 0.5) * YX; + poly3[1].Y = y1 - (kMinWidthT - 0) * XY + (kMinWidthY * 0.5) * YY; + poly3[2].X = x1 - (kMinWidthT + kMinWidthT * 0.5) * XX + (kMinWidthY * 0.5 + kMinWidthY) * YX; + poly3[2].Y = y1 - (kMinWidthT + kMinWidthT * 0.5) * XY + (kMinWidthY * 0.5 + kMinWidthY) * YY; + poly3[3].X = x1 - (kMinWidthT - 0) * XX + (kMinWidthY * 0.5 + kMinWidthY * 2) * YX; + poly3[3].Y = y1 - (kMinWidthT - 0) * XY + (kMinWidthY * 0.5 + kMinWidthY * 2) * YY; + poly3[4].X = x1 - (kMinWidthT - 1) * XX + (kMinWidthY * 0.5 + kMinWidthY * 2) * YX; + poly3[4].Y = y1 - (kMinWidthT - 1) * XY + (kMinWidthY * 0.5 + kMinWidthY * 2) * YY; + icPolygon(poly3, 5); + } + } + + //process for tail + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + YX = sin(rad) * v * -1; + YY = cos(rad) * v; + XX = cos(rad) * v; + XY = sin(rad) * v; + + if(a2 == 1 || a2 == 8 || a2 == 15){ //the last filled circle + if(x2 == x3){ + poly3[0].X = x3 - kMinWidthT; + poly3[0].Y = y3; + poly3[1].X = x3 - kMinWidthT * 0.6; + poly3[1].Y = y3 + kMinWidthT * 0.6; + poly3[2].X = x3; + poly3[2].Y = y3 + kMinWidthT; + poly3[3].X = x3 + kMinWidthT * 0.6; + poly3[3].Y = y3 + kMinWidthT * 0.6; + poly3[4].X = x3 + kMinWidthT; + poly3[4].Y = y3; + icPolygon(poly3, 5); + } + else if(y2 == y3){ + poly3[0].X = x3; + poly3[0].Y = y3 - kMinWidthT; + poly3[1].X = x3 + kMinWidthT * 0.6; + poly3[1].Y = y3 - kMinWidthT * 0.6; + poly3[2].X = x3 + kMinWidthT; + poly3[2].Y = y3; + poly3[3].X = x3 + kMinWidthT * 0.6; + poly3[3].Y = y3 + kMinWidthT * 0.6; + poly3[4].X = x3; + poly3[4].Y = y3 + kMinWidthT; + icPolygon(poly3, 5); + } + else{ + poly3[0].X = x3 + sin(rad) * kMinWidthT * v; + poly3[0].Y = y3 - cos(rad) * kMinWidthT * v; + poly3[1].X = x3 + cos(rad) * kMinWidthT * 0.8 * v + sin(rad) * kMinWidthT * 0.6 * v; + poly3[1].Y = y3 + sin(rad) * kMinWidthT * 0.8 * v - cos(rad) * kMinWidthT * 0.6 * v; + poly3[2].X = x3 + cos(rad) * kMinWidthT * v; + poly3[2].Y = y3 + sin(rad) * kMinWidthT * v; + poly3[3].X = x3 + cos(rad) * kMinWidthT * 0.8 * v - sin(rad) * kMinWidthT * 0.6 * v; + poly3[3].Y = y3 + sin(rad) * kMinWidthT * 0.8 * v + cos(rad) * kMinWidthT * 0.6 * v; + poly3[4].X = x3 - sin(rad) * kMinWidthT * v; + poly3[4].Y = y3 + cos(rad) * kMinWidthT * v; + icPolygon(poly3, 5); + } + } + + if(a2 == 17){ //the last filled half circle + if(x2 == x3){ + poly3[0].X = x3 - kMinWidthT * 0.5; + poly3[0].Y = y3; + poly3[1].X = x3 - kMinWidthT * 0.6 * 0.5; + poly3[1].Y = y3 + kMinWidthT * 0.6 * 0.5; + poly3[2].X = x3; + poly3[2].Y = y3 + kMinWidthT * 0.5; + poly3[3].X = x3 + kMinWidthT * 0.6 * 0.5; + poly3[3].Y = y3 + kMinWidthT * 0.6 * 0.5; + poly3[4].X = x3 + kMinWidthT * 0.5; + poly3[4].Y = y3; + icPolygon(poly3, 5); + } + else if(y2 == y3){ + poly3[0].X = x3; + poly3[0].Y = y3 - kMinWidthT * 0.5; + poly3[1].X = x3 + kMinWidthT * 0.6 * 0.5; + poly3[1].Y = y3 - kMinWidthT * 0.6 * 0.5; + poly3[2].X = x3 + kMinWidthT * 0.5; + poly3[2].Y = y3; + poly3[3].X = x3 + kMinWidthT * 0.6 * 0.5; + poly3[3].Y = y3 + kMinWidthT * 0.6 * 0.5; + poly3[4].X = x3; + poly3[4].Y = y3 + kMinWidthT * 0.5; + icPolygon(poly3, 5); + } + else{ + poly3[0].X = x3 + sin(rad) * kMinWidthT * 0.5 * v; + poly3[0].Y = y3 - cos(rad) * kMinWidthT * 0.5 * v; + poly3[1].X = x3 + cos(rad) * kMinWidthT * 0.8 * 0.5 * v + sin(rad) * kMinWidthT * 0.6 * 0.5 * v; + poly3[1].Y = y3 + sin(rad) * kMinWidthT * 0.8 * 0.5 * v - cos(rad) * kMinWidthT * 0.6 * 0.5 * v; + poly3[2].X = x3 + cos(rad) * kMinWidthT * 0.5 * v; + poly3[2].Y = y3 + sin(rad) * kMinWidthT * 0.5 * v; + poly3[3].X = x3 + cos(rad) * kMinWidthT * 0.5 * 0.8 * v - sin(rad) * kMinWidthT * 0.6 * 0.5 * v; + poly3[3].Y = y3 + sin(rad) * kMinWidthT * 0.5 * 0.8 * v + cos(rad) * kMinWidthT * 0.6 * 0.5 * v; + poly3[4].X = x3 - sin(rad) * kMinWidthT * 0.5 * v; + poly3[4].Y = y3 + cos(rad) * kMinWidthT * 0.5 * v; + icPolygon(poly3, 5); + } + } + + if(a2 == 9){ + if(y2 == y3){ + poly2[0].X = x3; + poly2[0].Y = y3 + kMinWidthT; + poly2[1].X = x3; + poly2[1].Y = y3 - kMinWidthT; + poly2[2].X = x3 + kMinWidthT; + poly2[2].Y = y3 - kMinWidthT; + icPolygon(poly2, 3); + } + else{ + poly2[0].X = x3 + kMinWidthT * YX; + poly2[0].Y = y3 + kMinWidthT * YY; + poly2[1].X = x3 - kMinWidthT * YX; + poly2[1].Y = y3 - kMinWidthT * YY; + poly2[2].X = x3 + kMinWidthT * XX - kMinWidthT * YX; + poly2[2].Y = y3 + kMinWidthT * XY - kMinWidthT * YY; + icPolygon(poly2, 3); + } + } + + if(a2 == 15){ //jump up + if(y2 == y3){ + poly4[0].X = x3; + poly4[0].Y = y3 - kMinWidthT + 1; + poly4[1].X = x3 + 2; + poly4[1].Y = y3 - kMinWidthT - kWidth * 5; + poly4[2].X = x3; + poly4[2].Y = y3 - kMinWidthT - kWidth * 5; + poly4[3].X = x3 - kMinWidthT; + poly4[3].Y = y3 - kMinWidthT + 1; + icPolygon(poly4, 4); + } + else{ + poly4[0].X = x3 + (kMinWidthT - 1) * sin(rad) * v; + poly4[0].Y = y3 - (kMinWidthT - 1) * cos(rad) * v; + poly4[1].X = x3 + 2 * cos(rad) * v + (kMinWidthT + kWidth * 5) * sin(rad) * v; + poly4[1].Y = y3 + 2 * sin(rad) * v - (kMinWidthT + kWidth * 5) * cos(rad) * v; + poly4[2].X = x3 + (kMinWidthT + kWidth * 5) * sin(rad) * v; + poly4[2].Y = y3 - (kMinWidthT + kWidth * 5) * cos(rad) * v; + poly4[3].X = x3 + (kMinWidthT - 1) * sin(rad) * v - kMinWidthT * cos(rad) * v; + poly4[3].Y = y3 - (kMinWidthT - 1) * cos(rad) * v - kMinWidthT * sin(rad) * v; + icPolygon(poly4, 4); + } + } + + if(a2 == 14){ //jump to left, allways go left + poly4[0].X = x3; + poly4[0].Y = y3; + poly4[1].X = x3; + poly4[1].Y = y3 - kMinWidthT; + poly4[2].X = x3 - kWidth * 4; + poly4[2].Y = y3 - kMinWidthT; + poly4[3].X = x3 - kWidth * 4; + poly4[3].Y = y3 - kMinWidthT * 0.5; + icPolygon(poly4, 4); + } + } + else{ //gothic + if(a1 % 10 == 2){ + if(x1 == x2){ + if(y1 < y2){ y1 = y1 - kWidth; } else{ y1 = y1 + kWidth; } + } + else if(y1 == y2){ + if(x1 < x2){ x1 = x1 - kWidth; } else{ x1 = x1 + kWidth; } + } + else{ + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{ v = -1; } + x1 = x1 - kWidth * cos(rad) * v; + y1 = y1 - kWidth * sin(rad) * v; + } + } + + if(a1 % 10 == 3){ + if(x1 == x2){ + if(y1 < y2){ + y1 = y1 - kWidth * kKakato; + } + else{ + y1 = y1 + kWidth * kKakato; + } + } + else if(y1 == y2){ + if(x1 < x2){ + x1 = x1 - kWidth * kKakato; + } + else{ + x1 = x1 + kWidth * kKakato; + } + } + else{ + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{ v = -1; } + x1 = x1 - kWidth * cos(rad) * v * kKakato; + y1 = y1 - kWidth * sin(rad) * v * kKakato; + } + } + if(a2 % 10 == 2){ + if(x2 == x3){ + if(y2 < y3){ y3 = y3 + kWidth; } else{ y3 = y3 - kWidth; } + } + else if(y2 == y3){ + if(x2 < x3){ x3 = x3 + kWidth; } else{ x3 = x3 - kWidth; } + } + else{ + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + x3 = x3 + kWidth * cos(rad) * v; + y3 = y3 + kWidth * sin(rad) * v; + } + } + + if(a2 % 10 == 3){ + if(x2 == x3){ + if(y2 < y3){ + y3 = y3 + kWidth * kKakato; + } + else{ + y3 = y3 - kWidth * kKakato; + } + } + else if(y2 == y3){ + if(x2 < x3){ + x3 = x3 + kWidth * kKakato; + } + else{ + x3 = x3 - kWidth * kKakato; + } + } + else{ + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + x3 = x3 + kWidth * cos(rad) * v * kKakato; + y3 = y3 + kWidth * sin(rad) * v * kKakato; + } + } + + count = 0; + + for(tt = 0; tt <= 1000; tt = tt + kRate){ + t = (double)tt / 1000; + + //calculating each point + x = ((1.0 - t) * (1.0 - t) * x1 + 2.0 * t * (1.0 - t) * x2 + t * t * x3); + y = ((1.0 - t) * (1.0 - t) * y1 + 2.0 * t * (1.0 - t) * y2 + t * t * y3); + + //SESSEN NO KATAMUKI NO KEISAN(BIBUN) + ix = (x1 - 2.0 * x2 + x3) * 2.0 * t + (-2.0 * x1 + 2.0 * x2); + iy = (y1 - 2.0 * y2 + y3) * 2.0 * t + (-2.0 * y1 + 2.0 * y2); + + //SESSEN NI SUICHOKU NA CHOKUSEN NO KEISAN + if(kShotai == kMincho){ //always false ? + if(ix != 0 && iy != 0){ + ir = atan(iy / ix * -1.0); + ia = sin(ir) * (double)kMinWidthT; + ib = cos(ir) * (double)kMinWidthT; + } + else if(ix == 0){ + ia = kMinWidthT; + ib = 0; + } + else{ + ia = 0; + ib = kMinWidthT; + } + ia = ia * sqrt(1.0 - t); + ib = ib * sqrt(1.0 - t); + } + else{ + if(ix != 0 && iy != 0){ + ir = atan(iy / ix * -1.0); + ia = sin(ir) * (double)kWidth; + ib = cos(ir) * (double)kWidth; + } + else if(ix == 0){ + ia = kWidth; + ib = 0; + } + else{ + ia = 0; + ib = kWidth; + } + } + + //if it is crossing, swap each other + if(((x + ia) - ox1) * ((x + ia) - ox1) + + ((y + ib) - oy1) * ((y + ib) - oy1) > + ((x - ia) - ox1) * ((x - ia) - ox1) + + ((y - ib) - oy1) * ((y - ib) - oy1) && count != 0){ + ia = ia * -1; + ib = ib * -1; + } + + //save old points for calculate crossing + ox1 = x + ia; + oy1 = y + ib; + ox2 = x - ia; + oy2 = y - ib; + + //save to polygon + poly[count].X = x + ia; + poly[count].Y = y + ib; + poly[(1000 / kRate + 1) * 2 - 1 - count].X = x - ia; + poly[(1000 / kRate + 1) * 2 - 1 - count].Y = y - ib; + count += 1; + } + + icPolygon(poly, (1000 / kRate + 1) * 2); + } +} + +void cdDrawLine(int tx1, int ty1, int tx2, int ty2, int ta1, int ta2){ + double rad; + int v, x1, y1, x2, y2, a1, a2; + double XX, XY, YX, YY; + + if(kShotai == kMincho){ //mincho + x1 = tx1; + y1 = ty1; + x2 = tx2; + y2 = ty2; + a1 = ta1; + a2 = ta2; + + if(x1 == x2){ //if TATE stroke, use y-axis + switch(a1){ + case 0: + poly[0].X = x1 - kMinWidthT; + poly[0].Y = y1 - kMinWidthY / 2; + poly[3].X = x1 + kMinWidthT; + poly[3].Y = y1 + kMinWidthY / 2; + break; + case 1: + case 6: + case 22: + poly[0].X = x1 - kMinWidthT; + poly[0].Y = y1; + poly[3].X = x1 + kMinWidthT; + poly[3].Y = y1; + break; + case 12: + poly[0].X = x1 - kMinWidthT; + poly[0].Y = y1 - kMinWidthY - kMinWidthT; + poly[3].X = x1 + kMinWidthT; + poly[3].Y = y1 - kMinWidthY; + break; + case 32: + poly[0].X = x1 - kMinWidthT; + poly[0].Y = y1 - kMinWidthY; + poly[3].X = x1 + kMinWidthT; + poly[3].Y = y1 - kMinWidthY; + break; + } + + switch(a2){ + case 0: + if(a1 == 6){ //KAGI's tail + poly[1].X = x2 - kMinWidthT; + poly[1].Y = y2; + poly[2].X = x2 + kMinWidthT; + poly[2].Y = y2; + } + else{ + poly[1].X = x2 - kMinWidthT; + poly[1].Y = y2 + kMinWidthT / 2; + poly[2].X = x2 + kMinWidthT; + poly[2].Y = y2 - kMinWidthT / 2; + } + break; + case 1: + poly[1].X = x2 - kMinWidthT; + poly[1].Y = y2; + poly[2].X = x2 + kMinWidthT; + poly[2].Y = y2; + break; + case 13: + poly[1].X = x2 - kMinWidthT; + poly[1].Y = y2 + kWidth * kKakato + kMinWidthT; + poly[2].X = x2 + kMinWidthT; + poly[2].Y = y2 + kWidth * kKakato; + break; + case 23: + poly[1].X = x2 - kMinWidthT; + poly[1].Y = y2 + kWidth * kKakato * 0.5 + kMinWidthT; + poly[2].X = x2 + kMinWidthT; + poly[2].Y = y2 + kWidth * kKakato * 0.5; + break; + case 32: + poly[1].X = x2 - kMinWidthT; + poly[1].Y = y2 + kMinWidthY; + poly[2].X = x2 + kMinWidthT; + poly[2].Y = y2 + kMinWidthY; + break; + } + + icPolygon(poly, 4); + + if(a1 == 22){ //box's right top corner + poly3[0].X = x1 - kMinWidthT; + poly3[0].Y = y1 - kMinWidthY; + poly3[1].X = x1; + poly3[1].Y = y1 - kMinWidthY - kWidth; + poly3[2].X = x1 + kMinWidthT + kWidth; + poly3[2].Y = y1 + kMinWidthY; + poly3[3].X = x1 + kMinWidthT; + poly3[3].Y = y1 + kMinWidthT; + poly3[4].X = x1 - kMinWidthT; + poly3[4].Y = y1; + icPolygon(poly3, 5); + } + + if(a1 == 0){ //beginning of the stroke + poly2[0].X = x1 + kMinWidthT; + poly2[0].Y = y1 + kMinWidthY * 0.5; + poly2[1].X = x1 + kMinWidthT + kMinWidthT * 0.5; + poly2[1].Y = y1 + kMinWidthY * 0.5 + kMinWidthY; + poly2[2].X = x1 + kMinWidthT; + poly2[2].Y = y1 + kMinWidthY * 0.5 + kMinWidthY * 2; + icPolygon(poly2, 3); + } + + if((a1 == 6 && a2 == 0) || a2 == 1){ //KAGI NO YOKO BOU NO SAIGO NO MARU + poly3[0].X = x2 - kMinWidthT; + poly3[0].Y = y2; + poly3[1].X = x2 - kMinWidthT * 0.6; + poly3[1].Y = y2 + kMinWidthT * 0.6; + poly3[2].X = x2; + poly3[2].Y = y2 + kMinWidthT; + poly3[3].X = x2 + kMinWidthT * 0.6; + poly3[3].Y = y2 + kMinWidthT * 0.6; + poly3[4].X = x2 + kMinWidthT; + poly3[4].Y = y2; + icPolygon(poly3, 5); + } + } + else if(y1 == y2){ //if it is YOKO stroke, use x-axis + if(a1 == 6){ //if it is KAGI's YOKO stroke, get bold + poly[0].X = x1; + poly[0].Y = y1 - kMinWidthT; + poly[1].X = x2; + poly[1].Y = y2 - kMinWidthT; + poly[2].X = x2; + poly[2].Y = y2 + kMinWidthT; + poly[3].X = x1; + poly[3].Y = y1 + kMinWidthT; + icPolygon(poly, 4); + + if(a2 == 1 || a2 == 0 || a2 == 5){ + //KAGI NO YOKO BOU NO SAIGO NO MARU + poly3[0].X = x2; + poly3[0].Y = y2 - kMinWidthT; + poly3[1].X = x2 + kMinWidthT * 0.6; + poly3[1].Y = y2 - kMinWidthT * 0.6; + poly3[2].X = x2 + kMinWidthT; + poly3[2].Y = y2; + poly3[3].X = x2 + kMinWidthT * 0.6; + poly3[3].Y = y2 + kMinWidthT * 0.6; + poly3[4].X = x2; + poly3[4].Y = y2 + kMinWidthT; + icPolygon(poly3, 5); + } + + if(a2 == 5){ + //KAGI NO YOKO BOU NO HANE + poly[0].X = x2; + poly[0].Y = y2 - kMinWidthT + 1; + poly[1].X = x2 + 2; + poly[1].Y = y2 - kMinWidthT - kWidth * 5; + poly[2].X = x2; + poly[2].Y = y2 - kMinWidthT - kWidth * 5; + poly[3].X = x2 - kMinWidthT; + poly[3].Y = y2 - kMinWidthT + 1; + icPolygon(poly, 4); + } + } + else{ + switch(a1){ + case 0: + poly[0].X = x1; + poly[0].Y = y1 - kMinWidthY; + poly[3].X = x1; + poly[3].Y = y1 + kMinWidthY; + break; + case 2: + poly[0].X = x1 - kMinWidthT; + poly[0].Y = y1 - kMinWidthY; + poly[3].X = x1 - kMinWidthT; + poly[3].Y = y1 + kMinWidthY; + break; + } + + switch(a2){ + case 0: + poly[1].X = x2; + poly[1].Y = y2 - kMinWidthY; + poly[2].X = x2; + poly[2].Y = y2 + kMinWidthY; + break; + case 2: + poly[1].X = x2 + kMinWidthT; + poly[1].Y = y2 - kMinWidthY; + poly[2].X = x2 + kMinWidthT; + poly[2].Y = y2 + kMinWidthY; + } + + icPolygon(poly, 4); + + //UROKO + if(a2 == 0){ + poly2[0].X = x2; + poly2[0].Y = y2 - kMinWidthY; + poly2[1].X = x2 - 24; + poly2[1].Y = y2; + poly2[2].X = x2 - 12; + poly2[2].Y = y2 - 12; + icPolygon(poly2, 3); + } + } + } + else{ //for others, use x-axis + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if((abs(y2 - y1) < abs(x2 - x1)) && (a1 != 6) && (a2 != 6)){ //ASAI KAUDO + switch(a1){ //must be 0 or 2 + case 0: + poly[0].X = x1 + sin(rad) * kMinWidthY; + poly[0].Y = y1 - cos(rad) * kMinWidthY; + poly[3].X = x1 - sin(rad) * kMinWidthY; + poly[3].Y = y1 + cos(rad) * kMinWidthY; + break; + case 2: + poly[0].X = x1 + sin(rad) * kMinWidthY - kMinWidthT * cos(rad); + poly[0].Y = y1 - cos(rad) * kMinWidthY - kMinWidthT * sin(rad); + poly[3].X = x1 - sin(rad) * kMinWidthY - kMinWidthT * cos(rad); + poly[3].Y = y1 + cos(rad) * kMinWidthY - kMinWidthT * sin(rad); + break; + } + + switch(a2){ //must be 0 or 2 + case 0: + poly[1].X = x2 + sin(rad) * kMinWidthY; + poly[1].Y = y2 - cos(rad) * kMinWidthY; + poly[2].X = x2 - sin(rad) * kMinWidthY; + poly[2].Y = y2 + cos(rad) * kMinWidthY; + break; + case 2: + poly[1].X = x2 + sin(rad) * kMinWidthY + kMinWidthT * cos(rad); + poly[1].Y = y2 - cos(rad) * kMinWidthY + kMinWidthT * sin(rad); + poly[2].X = x2 - sin(rad) * kMinWidthY + kMinWidthT * cos(rad); + poly[2].Y = y2 + cos(rad) * kMinWidthY + kMinWidthT * sin(rad); + } + + icPolygon(poly, 4); + + //UROKO + if(a2 == 0){ + poly2[0].X = x2 + sin(rad) * kMinWidthY; + poly2[0].Y = y2 - cos(rad) * kMinWidthY; + poly2[1].X = x2 - cos(rad) * 24; + poly2[1].Y = y2 - sin(rad) * 24; + poly2[2].X = x2 - cos(rad) * 12 + sin(rad) * 12; + poly2[2].Y = y2 - sin(rad) * 12 - cos(rad) * 12; + icPolygon(poly2, 3); + } + } + + else{ //KAKUDO GA FUKAI or KAGI NO YOKO BOU + if(x1 > x2){ v = -1; } else{ v = 1; } + switch(a1){ + case 0: + poly[0].X = x1 + sin(rad) * kMinWidthT * v + kMinWidthY * cos(rad) * 0.5 * v; + poly[0].Y = y1 - cos(rad) * kMinWidthT * v + kMinWidthY * sin(rad) * 0.5 * v; + poly[3].X = x1 - sin(rad) * kMinWidthT * v - kMinWidthY * cos(rad) * 0.5 * v; + poly[3].Y = y1 + cos(rad) * kMinWidthT * v - kMinWidthY * sin(rad) * 0.5 * v; + break; + case 1: + case 6: + case 22: + poly[0].X = x1 + sin(rad) * kMinWidthT * v; + poly[0].Y = y1 - cos(rad) * kMinWidthT * v; + poly[3].X = x1 - sin(rad) * kMinWidthT * v; + poly[3].Y = y1 + cos(rad) * kMinWidthT * v; + break; + case 12: + poly[0].X = x1 + sin(rad) * kMinWidthT * v - kMinWidthY * cos(rad) * v; + poly[0].Y = y1 - cos(rad) * kMinWidthT * v - kMinWidthY * sin(rad) * v; + poly[3].X = x1 - sin(rad) * kMinWidthT * v - (kMinWidthT + kMinWidthY) * cos(rad) * v; + poly[3].Y = y1 + cos(rad) * kMinWidthT * v - (kMinWidthT + kMinWidthY) * sin(rad) * v; + break; + case 32: + poly[0].X = x1 + sin(rad) * kMinWidthT * v - kMinWidthY * cos(rad) * v; + poly[0].Y = y1 - cos(rad) * kMinWidthT * v - kMinWidthY * sin(rad) * v; + poly[3].X = x1 - sin(rad) * kMinWidthT * v - kMinWidthY * cos(rad) * v; + poly[3].Y = y1 + cos(rad) * kMinWidthT * v - kMinWidthY * sin(rad) * v; + break; + } + + switch(a2){ + case 0: + if(a1 == 6){ + poly[1].X = x2 + sin(rad) * kMinWidthT * v; + poly[1].Y = y2 - cos(rad) * kMinWidthT * v; + poly[2].X = x2 - sin(rad) * kMinWidthT * v; + poly[2].Y = y2 + cos(rad) * kMinWidthT * v; + } + else{ + poly[1].X = x2 + sin(rad) * kMinWidthT * v - kMinWidthT * 0.5 * cos(rad) * v; + poly[1].Y = y2 - cos(rad) * kMinWidthT * v - kMinWidthT * 0.5 * sin(rad) * v; + poly[2].X = x2 - sin(rad) * kMinWidthT * v + kMinWidthT * 0.5 * cos(rad) * v; + poly[2].Y = y2 + cos(rad) * kMinWidthT * v + kMinWidthT * 0.5 * sin(rad) * v; + } + break; + case 1: + case 5: + poly[1].X = x2 + sin(rad) * kMinWidthT * v; + poly[1].Y = y2 - cos(rad) * kMinWidthT * v; + poly[2].X = x2 - sin(rad) * kMinWidthT * v; + poly[2].Y = y2 + cos(rad) * kMinWidthT * v; + break; + case 13: + poly[1].X = x2 + sin(rad) * kMinWidthT * v + kWidth * kKakato * cos(rad) * v; + poly[1].Y = y2 - cos(rad) * kMinWidthT * v + kWidth * kKakato * sin(rad) * v; + poly[2].X = x2 - sin(rad) * kMinWidthT * v + (kWidth * kKakato + kMinWidthT) * cos(rad) * v; + poly[2].Y = y2 + cos(rad) * kMinWidthT * v + (kWidth * kKakato + kMinWidthT) * sin(rad) * v; + break; + case 23: + poly[1].X = x2 + sin(rad) * kMinWidthT * v + kWidth * kKakato * 0.5 * cos(rad) * v; + poly[1].Y = y2 - cos(rad) * kMinWidthT * v + kWidth * kKakato * 0.5 * sin(rad) * v; + poly[2].X = x2 - sin(rad) * kMinWidthT * v + (kWidth * kKakato * 0.5 + kMinWidthT) * cos(rad) * v; + poly[2].Y = y2 + cos(rad) * kMinWidthT * v + (kWidth * kKakato * 0.5 + kMinWidthT) * sin(rad) * v; + break; + case 32: + poly[1].X = x2 + sin(rad) * kMinWidthT * v + kMinWidthY * cos(rad) * v; + poly[1].Y = y2 - cos(rad) * kMinWidthT * v + kMinWidthY * sin(rad) * v; + poly[2].X = x2 - sin(rad) * kMinWidthT * v + kMinWidthY * cos(rad) * v; + poly[2].Y = y2 + cos(rad) * kMinWidthT * v + kMinWidthY * sin(rad) * v; + break; + } + + icPolygon(poly, 4); + + if((a1 == 6) && (a2 == 0 || a2 == 5)){ //KAGI NO YOKO BOU NO SAIGO NO MARU + poly3[0].X = x2 + sin(rad) * kMinWidthT * v; + poly3[0].Y = y2 - cos(rad) * kMinWidthT * v; + poly3[1].X = x2 + cos(rad) * kMinWidthT * 0.8 * v + sin(rad) * kMinWidthT * 0.6 * v; + poly3[1].Y = y2 + sin(rad) * kMinWidthT * 0.8 * v - cos(rad) * kMinWidthT * 0.6 * v; + poly3[2].X = x2 + cos(rad) * kMinWidthT * v; + poly3[2].Y = y2 + sin(rad) * kMinWidthT * v; + poly3[3].X = x2 + cos(rad) * kMinWidthT * 0.8 * v - sin(rad) * kMinWidthT * 0.6 * v; + poly3[3].Y = y2 + sin(rad) * kMinWidthT * 0.8 * v + cos(rad) * kMinWidthT * 0.6 * v; + poly3[4].X = x2 - sin(rad) * kMinWidthT * v; + poly3[4].Y = y2 + cos(rad) * kMinWidthT * v; + icPolygon(poly3, 5); + } + + if(a1 == 6 && a2 == 5){ + //KAGI NO YOKO BOU NO HANE + poly[0].X = x2 + (kMinWidthT - 1) * sin(rad) * v; + poly[0].Y = y2 - (kMinWidthT - 1) * cos(rad) * v; + poly[1].X = x2 + 2 * cos(rad) * v + (kMinWidthT + kWidth * 5) * sin(rad) * v; + poly[1].Y = y2 + 2 * sin(rad) * v - (kMinWidthT + kWidth * 5) * cos(rad) * v; + poly[2].X = x2 + (kMinWidthT + kWidth * 5) * sin(rad) * v; + poly[2].Y = y2 - (kMinWidthT + kWidth * 5) * cos(rad) * v; + poly[3].X = x2 + (kMinWidthT - 1) * sin(rad) * v - kMinWidthT * cos(rad) * v; + poly[3].Y = y2 - (kMinWidthT - 1) * cos(rad) * v - kMinWidthT * sin(rad) * v; + icPolygon(poly, 4); + } + + if(a1 == 22){ //SHIKAKU MIGIUE UROKO NANAME DEMO MASSUGU MUKI + poly3[0].X = x1 - kMinWidthT; + poly3[0].Y = y1 - kMinWidthY; + poly3[1].X = x1; + poly3[1].Y = y1 - kMinWidthY - kWidth; + poly3[2].X = x1 + kMinWidthT + kWidth; + poly3[2].Y = y1 + kMinWidthY; + poly3[3].X = x1 + kMinWidthT; + poly3[3].Y = y1 + kMinWidthT; + poly3[4].X = x1 - kMinWidthT; + poly3[4].Y = y1; + icPolygon(poly3, 5); + } + + XX = sin(rad) * v; + XY = cos(rad) * v * -1; + YX = cos(rad) * v; + YY = sin(rad) * v; + + if(a1 == 0){ //beginning of the storke + poly2[0].X = x1 + kMinWidthT * XX + (kMinWidthY * 0.5) * YX; + poly2[0].Y = y1 + kMinWidthT * XY + (kMinWidthY * 0.5) * YY; + poly2[1].X = x1 + (kMinWidthT + kMinWidthT * 0.5) * XX + (kMinWidthY * 0.5 + kMinWidthY) * YX; + poly2[1].Y = y1 + (kMinWidthT + kMinWidthT * 0.5) * XY + (kMinWidthY * 0.5 + kMinWidthY) * YY; + poly2[2].X = x1 + kMinWidthT * XX + (kMinWidthY * 0.5 + kMinWidthY * 2) * YX; + poly2[2].Y = y1 + kMinWidthT * XY + (kMinWidthY * 0.5 + kMinWidthY * 2) * YY; + icPolygon(poly2, 3); + } + } + } + } + else{ //gothic + if(tx1 == tx2){ //if TATE stroke, use y-axis + if(ty1 > ty2){ + x1 = tx2; + y1 = ty2; + x2 = tx1; + y2 = ty1; + a1 = ta2; + a2 = ta1; + } + else{ + x1 = tx1; + y1 = ty1; + x2 = tx2; + y2 = ty2; + a1 = ta1; + a2 = ta2; + } + + if(a1 % 10 == 2){ y1 = y1 - kWidth; } + if(a2 % 10 == 2){ y2 = y2 + kWidth; } + if(a1 % 10 == 3){ y1 = y1 - kWidth * kKakato; } + if(a2 % 10 == 3){ y2 = y2 + kWidth * kKakato; } + + poly[0].X = x1 - kWidth; + poly[0].Y = y1; + poly[1].X = x2 - kWidth; + poly[1].Y = y2; + poly[2].X = x2 + kWidth; + poly[2].Y = y2; + poly[3].X = x1 + kWidth; + poly[3].Y = y1; + + icPolygon(poly, 4); + } + else if(ty1 == ty2){ //if YOKO stroke, use x-axis + if(tx1 > tx2){ + x1 = tx2; + y1 = ty2; + x2 = tx1; + y2 = ty1; + a1 = ta2; + a2 = ta1; + } + else{ + x1 = tx1; + y1 = ty1; + x2 = tx2; + y2 = ty2; + a1 = ta1; + a2 = ta2; + } + if(a1 % 10 == 2){ x1 = x1 - kWidth; } + if(a2 % 10 == 2){ x2 = x2 + kWidth; } + if(a1 % 10 == 3){ x1 = x1 - kWidth * kKakato; } + if(a2 % 10 == 3){ x2 = x2 + kWidth * kKakato; } + + poly[0].X = x1; + poly[0].Y = y1 - kWidth; + poly[1].X = x2; + poly[1].Y = y2 - kWidth; + poly[2].X = x2; + poly[2].Y = y2 + kWidth; + poly[3].X = x1; + poly[3].Y = y1 + kWidth; + + icPolygon(poly, 4); + } + else{ //for others, use x-axis + if(tx1 > tx2){ + x1 = tx2; + y1 = ty2; + x2 = tx1; + y2 = ty1; + a1 = ta2; + a2 = ta1; + } + else{ + x1 = tx1; + y1 = ty1; + x2 = tx2; + y2 = ty2; + a1 = ta1; + a2 = ta2; + } + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(a1 % 10 == 2){ + x1 = x1 - kWidth * cos(rad); + y1 = y1 - kWidth * sin(rad); + } + if(a2 % 10 == 2){ + x2 = x2 + kWidth * cos(rad); + y2 = y2 + kWidth * sin(rad); + } + if(a1 % 10 == 3){ + x1 = x1 - kWidth * cos(rad) * kKakato; + y1 = y1 - kWidth * sin(rad) * kKakato; + } + if(a2 % 10 == 3){ + x2 = x2 + kWidth * cos(rad) * kKakato; + y2 = y2 + kWidth * sin(rad) * kKakato; + } + + //SUICHOKU NO ICHI ZURASHI HA sin TO cos NO IREKAE + x-axis MAINASU KA + poly[0].X = x1 + sin(rad) * kWidth; + poly[0].Y = y1 - cos(rad) * kWidth; + poly[1].X = x2 + sin(rad) * kWidth; + poly[1].Y = y2 - cos(rad) * kWidth; + poly[2].X = x2 - sin(rad) * kWidth; + poly[2].Y = y2 + cos(rad) * kWidth; + poly[3].X = x1 - sin(rad) * kWidth; + poly[3].Y = y1 + cos(rad) * kWidth; + + icPolygon(poly, 4); + } + } +} diff --git a/kagecgi/kagecgi.c b/kagecgi/kagecgi.c new file mode 100755 index 0000000..6fce983 --- /dev/null +++ b/kagecgi/kagecgi.c @@ -0,0 +1,193 @@ +//kagecgi.c +// + +#include +#include +#include +#include +#include "kage.h" +#include "kagecgi.h" + +int main(int argc, char *argv[]){ + GString *tmp1, *tmp2, *test1, *test2, *filename; + FILE *err, *fp; + char errbuf[errorFileSize]; + char *pos, *cur; + int dummy; + int i; + + dummy = initDB(); + + //set default + kShotai = kMincho; +// kShotai = kGothic; +// kDesign = 0; //jp + kSize = 200; + kType = 0; //png + kInput = 0; //ids or direct + kResultText = g_string_new(""); + kMode = 0; + + //set some param by request +// tmp1 = g_string_new((gchar *)argv[1]); + tmp1 = g_string_new((gchar *)getenv("QUERY_STRING")); + pos = tmp1->str; + + //separate token + if(tmp1->len != 0){ + while(1){ + cur = strchr(pos, '&'); + tmp2 = g_string_new(pos); + if(cur != NULL) g_string_set_size(tmp2, cur - pos); + //got request string +// if(strncmp(tmp2->str, "design=jp", 9) == 0) kDesign = 0; +// else if(strncmp(tmp2->str, "design=cs", 9) == 0) kDesign = 10; +// else if(strncmp(tmp2->str, "design=ct", 9) == 0) kDesign = 11; +// else if(strncmp(tmp2->str, "design=kr", 9) == 0) kDesign = 20; +// else if(strncmp(tmp2->str, "design=vn", 9) == 0) kDesign = 30; +// else if(strncmp(tmp2->str, "design=un", 9) == 0) kDesign = 40; +// else if(strncmp(tmp2->str, "shotai=mincho", 13) == 0) kShotai = kMincho; + if(strncmp(tmp2->str, "shotai=mincho", 13) == 0) kShotai = kMincho; + else if(strncmp(tmp2->str, "shotai=gothic", 13) == 0) kShotai = kGothic; + else if(strncmp(tmp2->str, "shotai=skeleton", 15) == 0) kShotai = kGothic; + else if(strncmp(tmp2->str, "type=png", 8) == 0) kType = 0; + else if(strncmp(tmp2->str, "type=svg", 8) == 0) kType = 1; + else if(strncmp(tmp2->str, "type=eps", 8) == 0) kType = 2; + else if(strncmp(tmp2->str, "type=raw", 8) == 0) kType = 3; + else if(strncmp(tmp2->str, "input=ids", 9) == 0) kInput = 0; + else if(strncmp(tmp2->str, "input=directwithadjust", 22) == 0) kInput = 2; + else if(strncmp(tmp2->str, "input=direct", 12) == 0) kInput = 1; + else if(strncmp(tmp2->str, "size=24", 7) == 0) kSize = 24; + else if(strncmp(tmp2->str, "size=200", 8) == 0) kSize = 200; + else test1 = g_string_new(tmp2->str); + if(cur == NULL) break; + pos = cur + 1; + } + } + else{ // redirected request + kInput = 0; + tmp1 = g_string_new((gchar *)getenv("REDIRECT_URL")); + pos = tmp1->str; + while(1){ + cur = strchr(pos, '/'); + tmp2 = g_string_new(pos); + if(cur != NULL) g_string_set_size(tmp2, cur - pos); + //got request string +// if(strncmp(tmp2->str, "jp", 2) == 0) kDesign = 0; +// else if(strncmp(tmp2->str, "cs", 2) == 0) kDesign = 10; +// else if(strncmp(tmp2->str, "ct", 2) == 0) kDesign = 11; +// else if(strncmp(tmp2->str, "kr", 2) == 0) kDesign = 20; +// else if(strncmp(tmp2->str, "vn", 2) == 0) kDesign = 30; +// else if(strncmp(tmp2->str, "un", 2) == 0) kDesign = 40; +// else if(strncmp(tmp2->str, "mincho", 6) == 0) kShotai = kMincho; + if(strncmp(tmp2->str, "mincho", 6) == 0) kShotai = kMincho; + else if(strncmp(tmp2->str, "gothic", 6) == 0) kShotai = kGothic; + else if(strncmp(tmp2->str, "skeleton", 8) == 0) kShotai = kGothic; + else if(strncmp(tmp2->str, "v0.4", 4) == 0); + else test1 = g_string_new(tmp2->str); + if(cur == NULL) break; + pos = cur + 1; + } + if(strncmp(test1->str + test1->len - 4, ".png", 4) == 0) kType = 0; + if(strncmp(test1->str + test1->len - 4, ".svg", 4) == 0) kType = 1; + if(strncmp(test1->str + test1->len - 4, ".eps", 4) == 0) kType = 2; + if(strncmp(test1->str + test1->len - 4, ".raw", 4) == 0) kType = 3; + g_string_set_size(test1, test1->len - 4); + } + + //clear result buffer + test2 = g_string_new(""); + if(kType == 2){ + g_string_append(kResultText, "%!PS-Adobe-3.0 EPSF-3.0\n"); + g_string_append(kResultText, "%%BoundingBox: 0 -208 1024 816\n"); + g_string_append(kResultText, "%%Pages: 0\n"); + g_string_append(kResultText, "%%Title: "); + g_string_append(kResultText, test1->str); + g_string_append(kResultText, "\n"); + g_string_append(kResultText, "%%Creator: KAGE System\n"); + g_string_append(kResultText, "%%CreationDate: 00:00 1-1-2004\n"); + g_string_append(kResultText, "%%EndComments\n"); + g_string_append(kResultText, "%%EndProlog\n"); + g_string_append(kResultText, "%%Page \""); + g_string_append(kResultText, test1->str); + g_string_append(kResultText, "\" 1\n"); + g_string_append(kResultText, "newpath\n"); + } + kageCanvas = initPng(canvasWidth, canvasHeight); + if(kInput == 0) generateGlyph(test1, test2); + else{ + convert99(test1, test2); + // g_string_append(test2, test1->str); + } + + if(kType == 0){ //png(image) + if(test2->len != 0){ + if(kInput != 1){ //0 and 2 + test2 = CalcSizes(test2, 1); + } + DrawBox(); + drawGlyph(test2, 0); + //output to file + filename = g_string_new(pngFilePath); +// if(kDesign == 0) g_string_append(filename, "jp/"); +// else if(kDesign == 10) g_string_append(filename, "cs/"); +// else if(kDesign == 11) g_string_append(filename, "ct/"); +// else if(kDesign == 20) g_string_append(filename, "kr/"); +// else if(kDesign == 30) g_string_append(filename, "vn/"); +// else if(kDesign == 40) g_string_append(filename, "un/"); + if(kShotai == kMincho) g_string_append(filename, "mincho/"); + else if(kShotai == kGothic) g_string_append(filename, "gothic/");//skeleton?? + g_string_append(filename, test1->str); + g_string_append(filename, ".png"); + +//skip for adjustment mode +// fp = fopen(filename->str, "w"); +// writePng(pngWidth, pngHeight, kageCanvas, fp); +// fclose(fp); + //output to stdout + fprintf(stdout, "Content-type: image/png\n\n"); + writePng(pngWidth, pngHeight, kageCanvas, stdout); + //done + closePng(pngWidth, pngHeight, kageCanvas); + } + else{ + err = fopen("error.png", "r"); + fread(errbuf, sizeof(char), errorFileSize, err); + // printf("An error occurred.\r\n"); + fprintf(stdout, "Content-type: image/png\n\n"); + fwrite(errbuf, sizeof(char), errorFileSize, stdout); + fclose(err); + } + } + else if(kType == 1){ //svg(vector graphics) + } + else if(kType == 2){ //eps(vector graphics) + if(test2->len != 0){ + test2 = CalcSizes(test2, 1); + kMode = 1; + drawGlyph(test2, 0); + g_string_append(kResultText, "fill\n"); + g_string_append(kResultText, "%%EOF\n"); + fprintf(stdout, "Content-type: application/postscript\n\n"); + fprintf(stdout, "%s", kResultText->str); + } + else{ + fprintf(stdout, "Content-type: text/plain\n\n"); + fprintf(stdout, "An error occurred."); + } + } + else{ //raw(text) + if(test2->len != 0){ + fprintf(stdout, "Content-type: text/plain\n\n"); + fprintf(stdout, "result=%s", test2->str); + } + else{ + fprintf(stdout, "Content-type: text/plain\n\n"); + fprintf(stdout, "result=nodata"); + } + } + dummy = closeDB(); + + return 0; +} + diff --git a/kagecgi/kagecgi.h b/kagecgi/kagecgi.h new file mode 100755 index 0000000..36dad00 --- /dev/null +++ b/kagecgi/kagecgi.h @@ -0,0 +1,85 @@ +//kagecgi.h +// + +#include +//#include + +#include +#include +#include "kage.h" + +#ifndef _KAGECGI_H_ +#define _KAGECGI_H_ + +// define for localhost environment +#define errorFileSize 4009 +#define errorFileName "error.png" +#define pngFilePath "/var/www/fontsjp/v0.4/" +#define databaseFileName "../../kagedb/wiki" + +#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 *kDatabase; + +FILE *debug; + +png_bytepp kageCanvas; + +int kDesign; +int kSize; +int kType; +int kInput; +GString *kResultText; +int kMode; + +void generateGlyph(const GString *in, GString *out); +void searchPartsData(const GString *in, GString *out); +void searchAliasData(const GString *in, GString *out); +void searchCacheData(const GString *in, GString *out); +void doCombine(const GString *in, GString *out); +void drawGlyph(const GString *in, const int mode); + +int isIDS(const GString *in); +void divideInto2(const GString *in, GString *partIDS1, GString *partIDS3); +void divideInto3(const GString *in, GString *partIDS1, GString *partIDS2, GString *partIDS3); +void addStrokeWithTransform(const GString *stroke, const int num, const int *tf, GString *out, int mode); +void convertArray(int *buf, GString *out, int size, int mode); +int * convertStroke(const char *in, int *a, int *size); +void convert99(const GString *in, GString *out); +void convert99calc(const char *in, GString *out); + +void DotsWidth(int *dlx, int *drx); +void DotsHeight(int *dly, int *dry); +void PartsWidth(const GString *in, int *lx, int *rx); +void PartsHeight(const GString *in, int *ly, int *ry); +GString * CalcSizes(const GString *in, int mode); +void DrawBox(); +void CalcOptions(const GString *in, int *mitsudo, int *flag, double *yoko, double *tate); +void DoDrawParts(const GString *in, const int lx1, const double rf1, const int ly1, const double rfy1); +void DoDrawMixFont(const GString *in1, const int lx1, const double rf1, const GString *in2, const int lx2, const double rf2, const int ly1, const double rfy1, const int ly2, const double rfy2); + +void combineYoko2(const GString *parts1, const GString *parts3, int *result); +void combineYoko3(const GString *parts1, const GString *parts2, const GString *parts3, int *result); +void combineTate2(const GString *parts1, const GString *parts3, int *result); +void combineTate3(const GString *parts1, const GString *parts2, const GString *parts3, int *result); +void combineHame2(const GString *parts1, const GString *parts3, int *result); + +int initDB(); +int closeDB(); +void searchPartsData(const GString *in, GString *out); +void searchAliasData(const GString *in, GString *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(struct kPoint *p, int number, int col, unsigned char **image); + +#endif diff --git a/kagecgi/kagechar.c b/kagecgi/kagechar.c new file mode 100755 index 0000000..daa2d25 --- /dev/null +++ b/kagecgi/kagechar.c @@ -0,0 +1,397 @@ +//kagechar.c +// + +#include +#include +#include "kagecgi.h" +#include "kage.h" + +int isIDS(const GString *in){ + //check IDC "u2ff*" + if(strncmp(in->str, "u2ff", 4) == 0){ + //check the last char + if('0' <= (in->str)[4] && (in->str)[4] <= 'a') return TRUE; + } + return FALSE; +} + +void divideInto2(const GString *in, GString *partIDS1, GString *partIDS3){ + GString *buffer[16]; + char tmp[kMaxIDCLength + 1]; + int i, counter, pointer, flag; + + g_string_set_size(partIDS1, 0); + + counter = 0; + pointer = 0; + for(i = 0; i < in->len; i++){ + if((in->str)[i] == '.'){ + strncpy(tmp, (in->str) + pointer, i - pointer); + tmp[i - pointer] = '\0'; + buffer[counter] = g_string_new(tmp); + counter++; + pointer = i + 1; + } + } + strncpy(tmp, (in->str) + pointer, i - pointer); + tmp[i - pointer] = '\0'; + buffer[counter] = g_string_new(tmp); + counter++; + + //reject over-length of IDS + if(counter > kMaxIDSSequenceLength) return; + + //1st scan + pointer = 1; + flag = 0; + while(flag >= 0 && pointer < counter){ + g_string_append(partIDS1, (buffer[pointer])->str); + g_string_append(partIDS1, "."); + if(strncmp((buffer[pointer])->str, "u2ff", 4) == 0){ + switch (((buffer[pointer])->str)[4]){ + case '0': + case '1': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': + case 'b': + flag++; + break; + case '2': + case '3': + flag = flag + 2; + break; + } + } + else flag--; + pointer++; + } + g_string_erase(partIDS1, partIDS1->len - 1, 1); + + //2nd scan + flag = 0; + while(flag >= 0 && pointer < counter){ + g_string_append(partIDS3, (buffer[pointer])->str); + g_string_append(partIDS3, "."); + if(strncmp((buffer[pointer])->str, "u2ff", 4) == 0){ + switch (((buffer[pointer])->str)[4]){ + case '0': + case '1': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': + case 'b': + flag++; + break; + case '2': + case '3': + flag = flag + 2; + break; + } + } + else flag--; + pointer++; + } + g_string_erase(partIDS3, partIDS3->len - 1, 1); +} + +void divideInto3(const GString *in, GString *partIDS1, GString *partIDS2, GString *partIDS3){ + GString *buffer[16]; + char tmp[kMaxIDCLength + 1]; + int i, counter, pointer, flag; + + g_string_set_size(partIDS1, 0); + + counter = 0; + pointer = 0; + for(i = 0; i < in->len; i++){ + if((in->str)[i] == '.'){ + strncpy(tmp, (in->str) + pointer, i - pointer); + tmp[i - pointer] = '\0'; + buffer[counter] = g_string_new(tmp); + counter++; + pointer = i + 1; + } + } + strncpy(tmp, (in->str) + pointer, i - pointer); + tmp[i - pointer] = '\0'; + buffer[counter] = g_string_new(tmp); + counter++; + + //reject over-length of IDS + if(counter > kMaxIDSSequenceLength) return; + + //1st scan + pointer = 1; + flag = 0; + while(flag >= 0 && pointer < counter){ + g_string_append(partIDS1, (buffer[pointer])->str); + g_string_append(partIDS1, "."); + if(strncmp((buffer[pointer])->str, "u2ff", 4) == 0){ + switch (((buffer[pointer])->str)[4]){ + case '0': + case '1': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': + case 'b': + flag++; + break; + case '2': + case '3': + flag = flag + 2; + break; + } + } + else flag--; + pointer++; + } + g_string_erase(partIDS1, partIDS1->len - 1, 1); + + //2nd scan + flag = 0; + while(flag >= 0 && pointer < counter){ + g_string_append(partIDS2, (buffer[pointer])->str); + g_string_append(partIDS2, "."); + if(strncmp((buffer[pointer])->str, "u2ff", 4) == 0){ + switch (((buffer[pointer])->str)[4]){ + case '0': + case '1': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': + case 'b': + flag++; + break; + case '2': + case '3': + flag = flag + 2; + break; + } + } + else flag--; + pointer++; + } + g_string_erase(partIDS2, partIDS2->len - 1, 1); + + //3rd scan + flag = 0; + while(flag >= 0 && pointer < counter){ + g_string_append(partIDS3, (buffer[pointer])->str); + g_string_append(partIDS3, "."); + if(strncmp((buffer[pointer])->str, "u2ff", 4) == 0){ + switch (((buffer[pointer])->str)[4]){ + case '0': + case '1': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': + case 'b': + flag++; + break; + case '2': + case '3': + flag = flag + 2; + break; + } + } + else flag--; + pointer++; + } + g_string_erase(partIDS3, partIDS3->len - 1, 1); +} + +void addStrokeWithTransform(const GString *stroke, const int num, const int *tf, GString *out, int mode){ + int *buf, i, size; + GString *tmp; + + tmp = g_string_new(""); + buf = convertStroke(stroke->str, buf, &size); + + for(i = 0; i < size; i++){ + if(buf[i * 11 + 0] != 0 && buf[i * 11 + 0] != 99){ + buf[i * 11 + 3] = + tf[(num - 1) * 4 + 0] + buf[i * 11 + 3] * (tf[(num - 1) * 4 + 2] - tf[(num - 1) * 4 + 0]) / pngWidth; + buf[i * 11 + 5] = + tf[(num - 1) * 4 + 0] + buf[i * 11 + 5] * (tf[(num - 1) * 4 + 2] - tf[(num - 1) * 4 + 0]) / pngWidth; + buf[i * 11 + 7] = + tf[(num - 1) * 4 + 0] + buf[i * 11 + 7] * (tf[(num - 1) * 4 + 2] - tf[(num - 1) * 4 + 0]) / pngWidth; + buf[i * 11 + 9] = + tf[(num - 1) * 4 + 0] + buf[i * 11 + 9] * (tf[(num - 1) * 4 + 2] - tf[(num - 1) * 4 + 0]) / pngWidth; + buf[i * 11 + 4] = + tf[(num - 1) * 4 + 1] + buf[i * 11 + 4] * (tf[(num - 1) * 4 + 3] - tf[(num - 1) * 4 + 1]) / pngHeight; + buf[i * 11 + 6] = + tf[(num - 1) * 4 + 1] + buf[i * 11 + 6] * (tf[(num - 1) * 4 + 3] - tf[(num - 1) * 4 + 1]) / pngHeight; + buf[i * 11 + 8] = + tf[(num - 1) * 4 + 1] + buf[i * 11 + 8] * (tf[(num - 1) * 4 + 3] - tf[(num - 1) * 4 + 1]) / pngHeight; + buf[i * 11 + 10] = + tf[(num - 1) * 4 + 1] + buf[i * 11 + 10] * (tf[(num - 1) * 4 + 3] - tf[(num - 1) * 4 + 1]) / pngHeight; + } + } + convertArray(buf, tmp, size, mode); + if(out->len != 0) g_string_append(out, "$"); + g_string_append(out, tmp->str); + + free((void *)buf); +} + +void convertArray(int *buf, GString *out, int size, int mode){ + int i; + char tmp[kMaxStrokeDataLength]; + + for(i = 0; i < size; i++){ + if(!(mode == 1 && (buf[i * 11 + 0] == 0 || buf[i * 11 + 0] == 99))){ + sprintf(tmp, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d$", + 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]); + g_string_append(out, tmp); + } + } + g_string_erase(out, (out->len - 1), 1); +} + +int * convertStroke(const char *in, int *a, int *size){ + int i, counter, pointer; + int a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10; + char tmp[kMaxStrokeDataLength + 1]; + + a = (int *)malloc(0); + counter = 0; + pointer = 0; + for(i = 0; i < strlen(in); i++){ + if(in[i] == '$'){ + strncpy(tmp, &in[pointer], i - pointer); + tmp[i - pointer] = '\0'; + a = (int *)realloc(a, sizeof(int) * 11 * (counter + 1)); + sscanf(tmp, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", + &a0,&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10); + a[counter * 11 + 0] = a0; + a[counter * 11 + 1] = a1; + a[counter * 11 + 2] = a2; + a[counter * 11 + 3] = a3; + a[counter * 11 + 4] = a4; + a[counter * 11 + 5] = a5; + a[counter * 11 + 6] = a6; + a[counter * 11 + 7] = a7; + a[counter * 11 + 8] = a8; + a[counter * 11 + 9] = a9; + a[counter * 11 + 10] = a10; + counter++; + pointer = i + 1; + } + } + strncpy(tmp, &in[pointer], i - pointer); + tmp[i - pointer] = '\0'; + a = (int *)realloc(a, sizeof(int) * 11 * (counter + 1)); + sscanf(tmp, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", + &a0,&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10); + a[counter * 11 + 0] = a0; + a[counter * 11 + 1] = a1; + a[counter * 11 + 2] = a2; + a[counter * 11 + 3] = a3; + a[counter * 11 + 4] = a4; + a[counter * 11 + 5] = a5; + a[counter * 11 + 6] = a6; + a[counter * 11 + 7] = a7; + a[counter * 11 + 8] = a8; + a[counter * 11 + 9] = a9; + a[counter * 11 + 10] = a10; + counter++; + *(size) = counter; + return a; +} + +void convert99(const GString *in, GString *out){ + int i, pointer; + char tmp[kMaxStrokeDataLength + 1]; + GString *buf; + + g_string_set_size(out, 0); + buf = g_string_new(""); + pointer = 0; + for(i = 0; i < in->len; i++){ + if((in->str)[i] == '$'){ + strncpy(tmp, in->str + pointer, i - pointer); + tmp[i - pointer] = '\0'; + if(strncmp(tmp, "99:", 3) == 0){ + convert99calc(tmp, buf); + if(buf->len == 0){ + g_string_set_size(out, 0); + return; + } + g_string_append(out, buf->str); + } + else g_string_append(out, tmp); + g_string_append(out, "$"); + + pointer = i + 1; + } + } + strncpy(tmp, in->str + pointer, i - pointer); + tmp[i - pointer] = '\0'; + if(strncmp(tmp, "99:", 3) == 0){ + convert99calc(tmp, buf); + if(buf->len == 0){ + g_string_set_size(out, 0); + return; + } + g_string_append(out, buf->str); + } + else g_string_append(out, tmp); +} + +void convert99calc(const char *in, GString *out){ + GString *buf1, *buf2; + int a1,x1,y1,x2,y2,option,option2; + char pname[kMaxStrokeDataLength]; + int tf[12]; + char *end; + + g_string_set_size(out, 0); + buf2 = g_string_new(""); + + //get parts data + sscanf(in, "%d:%d:%d:%d:%d:%d:%d:%s", + &a1,&option,&option2,&x1,&y1,&x2,&y2,pname); + //end = strchr(pname, ':'); + //*end = '\0'; + buf1 = g_string_new(pname); + generateGlyph(buf1, buf2); + if(buf2->len == 0) return; + + //convert + tf[0] = x1; + tf[1] = y1; + tf[2] = x2; + tf[3] = y2; + addStrokeWithTransform(buf2, 1, tf, out, 1); +} diff --git a/kagecgi/kagecomb.c b/kagecgi/kagecomb.c new file mode 100755 index 0000000..d90f0e0 --- /dev/null +++ b/kagecgi/kagecomb.c @@ -0,0 +1,400 @@ +//kagecomb.c +// +#include +#include +#include +#include "kagecgi.h" +#include "kage.h" + +void combineYoko2(const GString *parts1, const GString *parts3, int *result){ + int f, g, h, i, j, k, l; + int flg_boxL, flg_boxR; + int Xside, 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 % 8 / 4 != 0) YsideLa++; + if(flg_boxL % 16 / 8 != 0) YsideLb++; + + //if its goes right-up + if(flg_boxL % 1024 / 512 == 0){ + 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; + if(flg_boxL % 1024 / 512 == 0){ + YsmallL = 1; + if(flg_boxL % 16 / 8 != 0 && flg_boxL % 8 / 4 != 0 && tateL <= 4) YheightL = (double)YheightL * (max(0.65, tateL * 0.22)); + else if(flg_boxL % 16 / 8 != 0 && tateL <= 3) YheightL = (double)YheightL * 0.8; + else if(YnanameL != 0 && flg_boxL % 8 / 4 != 0 && 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 % 8 / 4 != 0) 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 % 16 / 8 != 0 || YnanameL != 0) pyL = kBaseline - 2 * kWidth - dryL * pryL; + else pyL = kBaseline - dryL * pryL; + } + + //right parts Y-axis processing #1 + if(flg_boxR % 8 / 4 != 0) YsideRa++; + if(flg_boxR % 16 / 8 != 0) YsideRb++; + + DoDrawParts(parts3, pxR, prR, pyR, pryR); + DotsHeight(&dlyR, &dryR); + + if(flg_boxR % 512 / 256 != 0 && flg_boxR % 1024 / 512 == 0){ + pryR = pngWidth * 0.9 * 0.8 / (dryR - dlyR); + pyR = kBaseline - pngWidth * 0.9 + 6 * kWidth - dlyR * pryR; + } + else{ + pryR = ((double)pngWidth * 0.9 - (YsideRa + YsideRb) * 2 * kWidth) / (dryR - dlyR); + pyR = kBaseline - dryR * pryR; + if(flg_boxR % 16 / 8 != 0) pyR = pyR - 2 * kWidth; + } + + //calculate ratio + rL = yokoL; + rR = yokoR; + + if(flg_boxL % 2 / 1 != 0) rL = rL * 0.7; + if(flg_boxL % 4 / 2 != 0) rL = rL * 0.7; + if(flg_boxR % 2 / 1 != 0) rR = rR * 0.7; + if(flg_boxR % 4 / 2 != 0) 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; + +// if(r < 0.3) r = 0.3; +// else if(r > 0.7) r = 0.7; + + prL = rL; + prR = rR; + + //calculate width of each parts #1 + Xside = 0; + if(flg_boxL % 2 / 1 != 0) Xside++; + if(flg_boxR % 4 / 2 != 0) Xside++; + +// DrawBox(); +// drawGlyph(parts1, 1); +// DotsWidth(&lxL, &rxL); +// DrawBox(); +// drawGlyph(parts3, 1); +// DotsWidth(&lxR, &rxR); + PartsWidth(parts1, &lxL, &rxL); + PartsWidth(parts3, &lxR, &rxR); + g = 0; + + //calculate width of each parts #2 +// pxL = kWidth * 2 + (pngWidth - kWidth * 2 * 2) * prL * 0.5 - (lxL + rxL) / 2 * prL; +// pxR = kWidth * 2 + (pngWidth - kWidth * 2 * 2) * prL + kWidth * 2 * 2 + (pngWidth - kWidth * 2 * 2) * prR * 0.5 - (lxR + rxR) / 2 * prR; + pxL = pngWidth * prL * 0.5 - (lxL + rxL) / 2 * prL; + pxR = pngWidth * prL + kWidth * 4 + pngWidth * prR * 0.5 - (lxR + rxR) / 2 * prR; + + 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 * (kKasane + 4)){ + g = g + 2; + f = pxR - g; + DoDrawMixFont(parts1, pxL, prL, parts3, f, prR, pyL, pryL, pyR, pryR); + + 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_boxR % 256 / 128 != 0) pxR = pxR + kWidth * 12; + if(flg_boxR % 64 / 32 != 0) pxR = pxR + kWidth * 8; + else if(k - l > pngWidth * 0.4) pxR = pxR + kWidth * 5; + else pxR = pxR + kWidth * 3; + + //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 GString *parts1, const GString *parts2, const GString *parts3, int *result){ + //not yet +} + +void combineTate2(const GString *parts1, const GString *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 *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; + + 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 % 8 / 4 != 0) rL = rL * 0.7; + if(flg_boxL % 16 / 8 != 0) rL = rL * 0.7; + if(flg_boxR % 8 / 4 != 0) rR = rR * 0.7; + if(flg_boxR % 16 / 8 != 0) 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; + +// if(r < 0.3) r = 0.3; +// else if(r > 0.7) r = 0.7; + + 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 % 64 / 32 != 0){ + buf = convertStroke(parts1->str, buf, &strokes); + for(i = 0; i < strokes; i++){ + if(buf[i * 11 + 0] == 0) j = buf[i * 11 + 4]; // center line + } + k = max(j - lxL, rxL - j);// k : distance from center line + prL = (kSize * 0.9 * 0.5) / k; + if(k == j - lxL) pxL = 0; + else pxL = kSize * 0.5 - j * prL; + } + else if(flg_boxL % 2 / 1 != 0 && flg_boxL % 4 / 2 != 0 && flg_boxL % 32 / 16 == 0){ + 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 % 128 / 64 != 0){ + prL = 0.77; + DoDrawParts(parts1, pxL, prL, pyL, pryL); + DotsWidth(&dlxL, &drxL); + pxL = (kSize / 2 - (dlxL + drxL) / 2); + } + else if(flg_boxL % 2 / 1 != 0 && flg_boxL % 32 / 16 == 0){ + prL = (kSize * 0.9 - kWidth * 4) / (rxL - lxL); + pxL = kWidth * 4; + } + else if(flg_boxL % 4 / 2 != 0 && flg_boxL % 32 / 16 == 0){ + prL = (kSize * 0.9 - kWidth * 4) / (rxL - lxL); + pxL = (kSize*0.05+kWidth*2) - lxL * prL; + } + + //right parts + if(flg_boxR % 64 / 32 != 0){ + buf = convertStroke(parts3->str, buf, &strokes); + for(i = 0; i < strokes; i++){ + if(buf[i * 11 + 0] == 0) j = buf[i * 11 + 4]; // center line + } + k = max(j - lxR, rxR - j);// k : distance from center line + prR = (kSize * 0.9 * 0.5) / k; + if(k == j - lxR) pxR = 0; + else pxR = kSize * 0.5 - j * prR; + } + else if(flg_boxR % 2 / 1 != 0 && flg_boxR % 4 / 2 != 0 && flg_boxR % 32 / 16 == 0){ + 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 % 128 / 64 != 0){ + prR = 0.77; + DoDrawParts(parts3, pxR, prR, pyR, pryR); + DotsWidth(&dlxR, &drxR); + pxR = (kSize / 2 - (dlxR + drxR) / 2); + } + else if(flg_boxR % 2 / 1 != 0 && flg_boxR % 32 / 16 == 0){ + prR = (kSize * 0.9 - kWidth * 4) / (rxR - lxR); +// pxR = width * 4; + pxR = (kSize*0.05+kWidth*3) - lxR * prR; + } + else if(flg_boxR % 4 / 2 != 0 && flg_boxR % 32 / 16 == 0){ + prR = (kSize * 0.9 - kWidth * 4) / (rxR - lxR); +// pxR = (size*0.05+width*2) - lxR * prR; + 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 * 5; + else pyR = pyR + kWidth * 3; + + //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 GString *parts1, const GString *parts2, const GString *parts3, int *result){ + //not yet +} + +void combineHame2(const GString *parts1, const GString *parts3, int *result){ + int i; + int *buf, strokes; + + //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]; + result[9] = buf[i * 11 + 4]; + result[10] = buf[i * 11 + 5]; + result[11] = buf[i * 11 + 6]; + } + } + //not yet +} diff --git a/kagecgi/kagedb.c b/kagecgi/kagedb.c new file mode 100755 index 0000000..21cd2ba --- /dev/null +++ b/kagecgi/kagedb.c @@ -0,0 +1,123 @@ +//kagedb.c +// + +#include +//#include + +#include +#include +#include "kagecgi.h" +#include "kage.h" + +int initDB(){ + kDatabase = dbopen(databaseFileName, O_RDWR|O_CREAT, 0666, DB_HASH, NULL); + return 0; +} + +int closeDB(){ + kDatabase->close(kDatabase); + return 0; +} + +void searchPartsData(const GString *in, GString *out){ + DBT dbkey, dbdata; + char *start, *end; + GString *temp, *temp2; + + //cut off the end '-0000' if 'in' end with it + temp = g_string_new(in->str); +// if(strncmp(temp->str + temp->len - 5, "-0000", 5) == 0) g_string_set_size(temp, temp->len - 5); + if((temp->str)[0] == 'u'){ + if(strncmp(temp->str + temp->len - 4, "-j00", 4) == 0) g_string_set_size(temp, temp->len - 4); + else if(strncmp(temp->str + temp->len - 4, "-g00", 4) == 0) g_string_set_size(temp, temp->len - 2); + else if(strncmp(temp->str + temp->len - 4, "-t00", 4) == 0) g_string_set_size(temp, temp->len - 2); + else if(strncmp(temp->str + temp->len - 4, "-k00", 4) == 0) g_string_set_size(temp, temp->len - 2); + else if(strncmp(temp->str + temp->len - 4, "-v00", 4) == 0) g_string_set_size(temp, temp->len - 2); + else if(strncmp(temp->str + temp->len - 4, "-u00", 4) == 0) g_string_set_size(temp, temp->len - 2); + } + + memset(&dbkey,0,sizeof(DBT)); + memset(&dbdata,0,sizeof(DBT)); + dbkey.data = temp->str; + dbkey.size = temp->len; + g_string_set_size(out, 0); + temp2 = g_string_new(""); + kDatabase->get(kDatabase, &dbkey, &dbdata, 0); + if(dbdata.size != 0){ + //first:search selected shotai + if(kShotai == kMincho) start = strstr(dbdata.data, ",mincho,"); + else start = strstr(dbdata.data, ",gothic,"); + if(start != NULL){ + start = strchr((start+8), ','); + if(start != NULL){ + start = strchr((start+1), ','); + if(start != NULL){ + end = strchr((start+1), ','); + if(end != NULL){ + g_string_append_len(temp2, (start+1), end - start - 2 + 1); + convert99(temp2, out); + return; + } + } + } + } + //second:search another shotai + if(kShotai == kMincho) start = strstr(dbdata.data, ",gothic,"); + else start = strstr(dbdata.data, ",mincho,"); + if(start != NULL){ + start = strchr((start+8), ','); + if(start != NULL){ + start = strchr((start+1), ','); + if(start != NULL){ + end = strchr((start+1), ','); + if(end != NULL){ + g_string_append_len(temp2, (start+1), end - start - 2 + 1); + convert99(temp2, out); + return; + } + } + } + } + } +} + +void searchAliasData(const GString *in, GString *out){ + DBT dbkey, dbdata; + char *start, *end; + GString *temp; + + //cut off the end '-0000' if 'in' end with it + temp = g_string_new(in->str); +// if(strncmp(temp->str + temp->len - 5, "-0000", 5) == 0) g_string_set_size(temp, temp->len - 5); + if((temp->str)[0] == 'u'){ + if(strncmp(temp->str + temp->len - 4, "-j00", 4) == 0) g_string_set_size(temp, temp->len - 4); + else if(strncmp(temp->str + temp->len - 4, "-g00", 4) == 0) g_string_set_size(temp, temp->len - 2); + else if(strncmp(temp->str + temp->len - 4, "-t00", 4) == 0) g_string_set_size(temp, temp->len - 2); + else if(strncmp(temp->str + temp->len - 4, "-k00", 4) == 0) g_string_set_size(temp, temp->len - 2); + else if(strncmp(temp->str + temp->len - 4, "-v00", 4) == 0) g_string_set_size(temp, temp->len - 2); + else if(strncmp(temp->str + temp->len - 4, "-u00", 4) == 0) g_string_set_size(temp, temp->len - 2); + } + + memset(&dbkey,0,sizeof(DBT)); + memset(&dbdata,0,sizeof(DBT)); + dbkey.data = temp->str; + dbkey.size = temp->len; + g_string_set_size(out, 0); + kDatabase->get(kDatabase, &dbkey, &dbdata, 0); + if(dbdata.size != 0){ + start = strstr(dbdata.data, ",linkto,"); + if(start != NULL){ + start = strchr((start+8), ','); + if(start != NULL){ + start = strchr((start+1), ','); + if(start != NULL){ + end = strchr((start+1), ','); + if(end != NULL){ + g_string_append_len(out, (start+1), end - start - 2 + 1); + } + } + } + } + } +} + diff --git a/kagecgi/kagedf.c b/kagecgi/kagedf.c new file mode 100755 index 0000000..079c432 --- /dev/null +++ b/kagecgi/kagedf.c @@ -0,0 +1,356 @@ +//kagedf.c +// +#include "kage.h" + +void dfDrawFont(int a1, int a2, int a3, + int x1, int y1, + int x2, int y2, + int x3, int y3, + int x4, int y4){ + int tx1, tx2, tx3, tx4, ty1, ty2, ty3, ty4, v; + double rad; + + if(kShotai == kMincho){ + switch(a1 % 100){ + case 0: + break; + case 1: + if(a3 == 4){ + if(x1 == x2){ + if(y1 < y2){ v = 1; } else{ v = -1; } + tx1 = x2; + ty1 = y2 - kMage * v; + } + else if(y1 == y2){ + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * v; + ty1 = y2; + } + else{ + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{v = -1; } + tx1 = x2 - kMage * cos(rad) * v; + ty1 = y2 - kMage * sin(rad) * v; + } + cdDrawLine(x1, y1, tx1, ty1, a2, 1); + cdDrawCurve(tx1, ty1, x2, y2, x2 - kMage, y2, 1, 14); + } + else{ + cdDrawLine(x1, y1, x2, y2, a2, a3); + } + break; + case 2: + case 12: + if(a3 == 4){ + if(x2 == x3){ + tx1 = x3; + ty1 = y3 - kMage; + } + else if(y2 == y3){ + tx1 = x3 - kMage; + ty1 = y3; + } + else{ + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + tx1 = x3 - kMage * cos(rad) * v; + ty1 = y3 - kMage * sin(rad) * v; + } + cdDrawCurve(x1, y1, x2, y2, tx1, ty1, a2, 1); + cdDrawCurve(tx1, ty1, x3, y3, x3 - kMage, y3, 1, 14); + } + else if(a3 == 5){ + cdDrawCurve(x1, y1, x2, y2, x3, y3, a2, 15); + } + else{ + cdDrawCurve(x1, y1, x2, y2, x3, y3, a2, a3); + } + break; + case 3: + if(a3 == 5){ + if(x1 == x2){ + if(y1 < y2){ v = 1; } else{ v = -1; } + tx1 = x2; + ty1 = y2 - kMage * v; + } + else if(y1 == y2){ + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * v; + ty1 = y2; + } + else{ + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * cos(rad) * v; + ty1 = y2 - kMage * sin(rad) * v; + } + if(x2 == x3){ + if(y2 < y3){ v = 1; } else{ v = -1; } + tx2 = x2; + ty2 = y2 + kMage * v; + } + else if(y2 == y3){ + if(x2 < x3){ v = 1; } else { v = -1; } + tx2 = x2 + kMage * v; + ty2 = y2; + } + else{ + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + tx2 = x2 + kMage * cos(rad) * v; + ty2 = y2 + kMage * sin(rad) * v; + } + tx3 = x3 - kMage; + ty3 = y3; + tx4 = x3 + kMage * 0.5; + ty4 = y3 - kMage * 2; + + cdDrawLine(x1, y1, tx1, ty1, a2, 1); + cdDrawCurve(tx1, ty1, x2, y2, tx2, ty2, 1, 1); + cdDrawLine(tx2, ty2, tx3, ty3, 6, 5); // bolder by force + } + else{ + if(x1 == x2){ + if(y1 < y2){ v = 1; } else { v = -1; } + tx1 = x2; + ty1 = y2 - kMage * v; + } + else if(y1 == y2){ + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * v; + ty1 = y2; + } + else{ + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * cos(rad) * v; + ty1 = y2 - kMage * sin(rad) * v; + } + if(x2 == x3){ + if(y2 < y3){ v = 1; } else{ v = -1; } + tx2 = x2; + ty2 = y2 + kMage * v; + } + else if(y2 == y3){ + if(x2 < x3){ v = 1; } else{ v = -1; } + tx2 = x2 + kMage * v; + ty2 = y2; + } + else{ + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + tx2 = x2 + kMage * cos(rad) * v; + ty2 = y2 + kMage * sin(rad) * v; + } + cdDrawLine(x1, y1, tx1, ty1, a2, 1); + cdDrawCurve(tx1, ty1, x2, y2, tx2, ty2, 1, 1); + cdDrawLine(tx2, ty2, x3, y3, 6, a3); // bolder by force + } + break; + case 6: + if(a3 == 5){ + tx1 = x4 - kMage; + ty1 = y4; + tx2 = x4 + kMage * 0.5; + ty2 = y4 - kMage * 2; + if(a2 == 7 || a3 == 7){ + cdDrawCurve(x1, y1, x2, y2, (x2 + x3) / 2, (y2 + y3) / 2, a2, 17); + cdDrawCurve((x2 + x3) / 2, (y2 + y3) / 2, x3, y3, x4, y4, 17, 15); + } + else{ + cdDrawCurve(x1, y1, x2, y2, (x2 + x3) / 2, (y2 + y3) / 2, a2, 8); + cdDrawCurve((x2 + x3) / 2, (y2 + y3) / 2, x3, y3, x4, y4, 1, 15); + } + } + else{ + if(a2 == 7 || a3 == 7){ + cdDrawCurve(x1, y1, x2, y2, (x2 + x3) / 2, (y2 + y3) / 2, a2, 17); + cdDrawCurve((x2 + x3) / 2, (y2 + y3) / 2, x3, y3, x4, y4, 17, a3); + } + else{ + cdDrawCurve(x1, y1, x2, y2, (x2 + x3) / 2, (y2 + y3) / 2, a2, 8); + cdDrawCurve((x2 + x3) / 2, (y2 + y3) / 2, x3, y3, x4, y4, 1, a3); + } + } + break; + case 7: + cdDrawLine(x1, y1, x2, y2, a2, 1); + cdDrawCurve(x2, y2, x3, y3, x4, y4, 1, 7); + break; + case 9: // may not be exist + break; + default: + break; + } + } + + else{ // gothic + switch(a1 % 100){ + case 0: + break; + case 1: + if(a3 == 4){ + if(x1 == x2){ + if(y1 < y2){ v = 1; } else{ v = -1; } + tx1 = x2; + ty1 = y2 - kMage * v; + } + else if(y1 == y2){ + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * v; + ty1 = y2; + } + else{ + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * cos(rad) * v; + ty1 = y2 - kMage * sin(rad) * v; + } + cdDrawLine(x1, y1, tx1, ty1, a2, 1); + cdDrawCurve(tx1, ty1, x2, y2, x2 - kMage * 2, y2 - kMage * 0.5, 1, 0); + } + else{ + cdDrawLine(x1, y1, x2, y2, a2, a3); + } + break; + case 2: + case 12: + if(a3 == 4){ + if(x2 == x3){ + tx1 = x3; + ty1 = y3 - kMage; + } + else if(y2 == y3){ + tx1 = x3 - kMage; + ty1 = y3; + } + else{ + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + tx1 = x3 - kMage * cos(rad) * v; + ty1 = y3 - kMage * sin(rad) * v; + } + cdDrawCurve(x1, y1, x2, y2, tx1, ty1, a2, 1); + cdDrawCurve(tx1, ty1, x3, y3, x3 - kMage * 2, y3 - kMage * 0.5, 1, 0); + } + else if(a3 == 5){ + tx1 = x3 + kMage; + ty1 = y3; + tx2 = tx1 + kMage * 0.5; + ty2 = y3 - kMage * 2; + cdDrawCurve(x1, y1, x2, y2, x3, y3, a2, 1); + cdDrawCurve(x3, y3, tx1, ty1, tx2, ty2, 1, 0); + } + else{ + cdDrawCurve(x1, y1, x2, y2, x3, y3, a2, a3); + } + break; + case 3: + if(a3 == 5){ + if(x1 == x2){ + if(y1 < y2){ v = 1; } else{ v = -1; } + tx1 = x2; + ty1 = y2 - kMage * v; + } + else if(y1 == y2){ + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * v; + ty1 = y2; + } + else{ + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * cos(rad) * v; + ty1 = y2 - kMage * sin(rad) * v; + } + if(x2 == x3){ + if(y2 < y3){ v = 1; } else{ v = -1; } + tx2 = x2; + ty2 = y2 + kMage * v; + } + else if(y2 == y3){ + if(x2 < x3){ v = 1; } else{ v = -1; } + tx2 = x2 + kMage * v; + ty2 = y2; + } + else{ + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + tx2 = x2 + kMage * cos(rad) * v; + ty2 = y2 + kMage * sin(rad) * v; + } + tx3 = x3 - kMage; + ty3 = y3; + tx4 = x3 + kMage * 0.5; + ty4 = y3 - kMage * 2; + + cdDrawLine(x1, y1, tx1, ty1, a2, 1); + cdDrawCurve(tx1, ty1, x2, y2, tx2, ty2, 1, 1); + cdDrawLine(tx2, ty2, tx3, ty3, 1, 1); + cdDrawCurve(tx3, ty3, x3, y3, tx4, ty4, 1, 0); + } + else{ + if(x1 == x2){ + if(y1 < y2){ v = 1; } else{ v = -1; } + tx1 = x2; + ty1 = y2 - kMage * v; + } + else if(y1 == y2){ + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * v; + ty1 = y2; + } + else{ + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * cos(rad) * v; + ty1 = y2 - kMage * sin(rad) * v; + } + if(x2 == x3){ + if(y2 < y3){ v = 1; } else{ v = -1; } + tx2 = x2; + ty2 = y2 + kMage * v; + } + else if(y2 == y3){ + if(x2 < x3){ v = 1; } else{ v = -1; } + tx2 = x2 + kMage * v; + ty2 = y2; + } + else{ + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + tx2 = x2 + kMage * cos(rad) * v; + ty2 = y2 + kMage * sin(rad) * v; + } + + cdDrawLine(x1, y1, tx1, ty1, a2, 1); + cdDrawCurve(tx1, ty1, x2, y2, tx2, ty2, 1, 1); + cdDrawLine(tx2, ty2, x3, y3, 1, a3); + } + break; + case 6: + if(a3 == 5){ + tx1 = x4 - kMage; + ty1 = y4; + tx2 = x4 + kMage * 0.5; + ty2 = y4 - kMage * 2; + cdDrawCurve(x1, y1, x2, y2, (x2 + x3) / 2, (y2 + y3) / 2, a2, 1); + cdDrawCurve((x2 + x3) / 2, (y2 + y3) / 2, x3, y3, tx1, ty1, 1, 1); + cdDrawCurve(tx1, ty1, x4, y4, tx2, ty2, 1, 0); + } + else{ + cdDrawCurve(x1, y1, x2, y2, (x2 + x3) / 2, (y2 + y3) / 2, a2, 1); + cdDrawCurve((x2 + x3) / 2, (y2 + y3) / 2, x3, y3, x4, y4, 1, a3); + } + break; + case 7: + cdDrawLine(x1, y1, x2, y2, a2, 1); + cdDrawCurve(x2, y2, x3, y3, x4, y4, 1, a3); + break; + case 9: // may not be exist + break; + default: + break; + } + } +} diff --git a/kagecgi/kageeg.c b/kagecgi/kageeg.c new file mode 100755 index 0000000..7fb3613 --- /dev/null +++ b/kagecgi/kageeg.c @@ -0,0 +1,306 @@ +//kageeg.c +// + +#include +//#include + +#include +#include +#include "kagecgi.h" +#include "kage.h" + +void generateGlyphByIDS(const GString *in, GString *out, int flag){ + GString *tmp1, *tmp2, *tmp3, *tmp4; + + //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 = g_string_new(in->str); + tmp2 = g_string_new(in->str); +// tmp3 = g_string_new(in->str); +// tmp4 = g_string_new(in->str); + + //append design flag +// if(kDesign == 10) g_string_append(tmp1, "-10"); +// else if(kDesign == 11) g_string_append(tmp1, "-11"); +// else if(kDesign == 20) g_string_append(tmp1, "-20"); +// else if(kDesign == 30) g_string_append(tmp1, "-30"); +// else if(kDesign == 40) g_string_append(tmp1, "-40"); +// else g_string_append(tmp1, "-00"); +// if(kDesign == 10) g_string_append(tmp2, "-10"); +// else if(kDesign == 11) g_string_append(tmp2, "-11"); +// else if(kDesign == 20) g_string_append(tmp2, "-20"); +// else if(kDesign == 30) g_string_append(tmp2, "-30"); +// else if(kDesign == 40) g_string_append(tmp2, "-40"); +// else g_string_append(tmp2, "-00"); +// g_string_append(tmp3, "-00"); +// g_string_append(tmp4, "-00"); + + //append place flag + if(1 <= flag && flag <= 7){ + if(tmp1->len != 7) g_string_append(tmp1, "-"); + if(flag == 1) g_string_append(tmp1, "01"); + else if(flag == 2) g_string_append(tmp1, "02"); + else if(flag == 3) g_string_append(tmp1, "03"); + else if(flag == 4) g_string_append(tmp1, "04"); + else if(flag == 5) g_string_append(tmp1, "05"); + else if(flag == 6) g_string_append(tmp1, "06"); + } + +// g_string_append(tmp2, "00"); +// if(flag == 1) g_string_append(tmp3, "01"); +// else if(flag == 2) g_string_append(tmp3, "02"); +// else if(flag == 3) g_string_append(tmp3, "03"); +// else if(flag == 4) g_string_append(tmp3, "04"); +// else if(flag == 5) g_string_append(tmp3, "05"); +// else if(flag == 6) g_string_append(tmp3, "06"); +// else g_string_append(tmp3, "00"); +// g_string_append(tmp4, "00"); + + generateGlyph(tmp1, out); + if(out->len != 0) return; + generateGlyph(tmp2, out); + if(out->len != 0) return; +// generateGlyph(tmp3, out); +// if(out->len != 0) return; +// generateGlyph(tmp4, out); + return; +} + +void generateGlyph(const GString *in, GString *out){ + GString *tmp, *in2; + tmp = g_string_new(""); + g_string_set_size(out, 0); + +// in2 = g_string_new(in->str); + + //1st search +// if(*(in2->str) == 'u' && (in2->len == 4 || in2->len == 5)){ +// //append design flag +// if(kDesign == 10) g_string_append(in2, "-1000"); +// else if(kDesign == 11) g_string_append(in2, "-1100"); +// else if(kDesign == 20) g_string_append(in2, "-2000"); +// else if(kDesign == 30) g_string_append(in2, "-3000"); +// else if(kDesign == 40) g_string_append(in2, "-4000"); +// else g_string_append(in2, "-0000"); + + //search from parts(1st) +// searchPartsData(in2, tmp); +// if(tmp->len != 0){ +// g_string_assign(out, tmp->str); +// return; +// } + + //search from alias(1st) +// searchAliasData(in2, tmp); +// if(tmp->len != 0){ +// generateGlyph(tmp, out); +// if(out->len == 0) return; +// //save to cache ... not yet +// return; +// } +// } + + //2nd search + //search from parts(2nd) + searchPartsData(in, tmp); + if(tmp->len != 0){ + g_string_assign(out, tmp->str); + return; + } + + //search from alias(2nd) + 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 GString *in, GString *out){ + GString *partIDS1, *partIDS2, *partIDS3; + GString *partStroke1, *partStroke2, *partStroke3; + int result[12]; + + partIDS1 = g_string_new(""); + partIDS2 = g_string_new(""); + partIDS3 = g_string_new(""); + partStroke1 = g_string_new(""); + partStroke2 = g_string_new(""); + partStroke3 = g_string_new(""); + + g_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': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': +// case 'b': + 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': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': +// case 'b': + combineHame2(partStroke1, partStroke3, result); + break; + } + 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 GString *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); +} + diff --git a/kagecgi/kageic.c b/kagecgi/kageic.c new file mode 100755 index 0000000..70281dc --- /dev/null +++ b/kagecgi/kageic.c @@ -0,0 +1,25 @@ +//kageic.c +// + +#include "kage.h" +#include "kagecgi.h" + +void icPolygon(struct kPoint *poly, int number){ + int i; + char buf[256]; + + if(kMode == 0){ //normal + fillPolygon(poly, number, 0, kageCanvas); + } + else{ //output for eps + sprintf(buf, "%d %d moveto\n", poly[0].X * 5, 1000 - (poly[0].Y * 5) - 200); + g_string_append(kResultText, buf); + for(i = 1; i < number; i++){ + sprintf(buf, " %d %d lineto\n", poly[i].X * 5, 1000 - (poly[i].Y * 5) - 200); + g_string_append(kResultText, buf); + } + sprintf(buf, " %d %d lineto\n", poly[0].X * 5, 1000 - (poly[0].Y * 5) - 200); + g_string_append(kResultText, buf); + g_string_append(kResultText, "closepath\n"); + } +} diff --git a/kagecgi/kagepng.c b/kagecgi/kagepng.c new file mode 100755 index 0000000..7080bb7 --- /dev/null +++ b/kagecgi/kagepng.c @@ -0,0 +1,84 @@ +//kagepng.c +// + +#include +#include +#include + +png_bytepp initPng(int width, int height){ + png_bytepp image; + int i, j; + + image = (png_bytepp)malloc(height * sizeof(png_bytep)); + for(j = 0; j < height; j++) image[j] = (png_bytep)malloc(width * sizeof(png_byte)); + for(i = 0; i < width; i++){ + for(j = 0; j < height; j++){ + image[j][i] = 0xFF; + } + } + return image; +} + +int closePng(int width, int height, png_bytepp image){ + int i; + for(i = 0; i < height; i++) free(image[i]); + free(image); + return 0; +} + +int writePng(int width, int height, png_bytepp image, FILE *fp){ + png_structp pPng; + png_infop pInfo; + png_text pText[5]; + time_t gmt; + png_time pngTime; + + pPng = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if(pPng == NULL){ + return 1; + } + pInfo = png_create_info_struct(pPng); + if(pInfo == NULL){ + png_destroy_write_struct(&pPng, (png_infopp)NULL); + return 1; + } + if(setjmp(pPng->jmpbuf)){ + png_destroy_write_struct(&pPng, &pInfo); + return 1; + } + png_init_io(pPng, fp); + png_set_filter(pPng, 0, PNG_ALL_FILTERS); + png_set_compression_level(pPng, Z_BEST_COMPRESSION); + //png_set_IHDR(pPng, pInfo, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + png_set_IHDR(pPng, pInfo, width, height, 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + png_set_gAMA(pPng, pInfo, 1.0); + + time(&gmt); + png_convert_from_time_t(&pngTime, gmt); + png_set_tIME(pPng, pInfo, &pngTime); + + pText[0].key = "Title"; + pText[0].text = "Kanji glyph generated by KAGE/cgi"; + pText[0].compression = PNG_TEXT_COMPRESSION_NONE; + pText[1].key = "Author"; + pText[1].text = "KAGE/cgi version 0.4"; + pText[1].compression = PNG_TEXT_COMPRESSION_NONE; + pText[2].key = "Description"; + pText[2].text = "see more information at http://fonts.jp/"; + pText[2].compression = PNG_TEXT_COMPRESSION_NONE; + pText[3].key = "Creation Time"; + pText[3].text = png_convert_to_rfc1123(pPng, &pngTime); + pText[3].compression = PNG_TEXT_COMPRESSION_NONE; + pText[4].key = "Software"; + pText[4].text = "KAGE/cgi version 0.4"; + pText[4].compression = PNG_TEXT_COMPRESSION_NONE; + png_set_text(pPng, pInfo, pText, 5); + + png_write_info(pPng, pInfo); + png_write_image(pPng, image); + png_write_end(pPng, pInfo); + png_destroy_write_struct(&pPng, &pInfo); + + return 0; +} + diff --git a/kagecgi/kagepoly.c b/kagecgi/kagepoly.c new file mode 100755 index 0000000..358148e --- /dev/null +++ b/kagecgi/kagepoly.c @@ -0,0 +1,29 @@ +// kagepoly.c +// + +#include +#include +#include "kagecgi.h" +#include "kage.h" + +void fillPolygon(struct kPoint *p, int number, int col, unsigned char **image){ + int i, ix, iy; + Region rgn; + XRectangle rect; + + for(i = 0; i < number; i++){ + xpoly[i].x = p[i].X; + xpoly[i].y = p[i].Y; + } + rgn = XPolygonRegion(xpoly, number, EvenOddRule); + XClipBox(rgn, &rect); + + for(ix = rect.x ; ix <= rect.x + rect.width; ix++){ + for(iy = rect.y ; iy <= rect.y + rect.height; iy++){ + if(XPointInRegion(rgn, ix, iy) && ix >= 0 && iy >= 0 && ix < canvasWidth && iy < canvasHeight){ + image[iy][ix] = col; + } + } + } +} + diff --git a/kagecgi/kagetool.c b/kagecgi/kagetool.c new file mode 100755 index 0000000..5c5a96e --- /dev/null +++ b/kagecgi/kagetool.c @@ -0,0 +1,466 @@ +//kagetool.c +// + +#include "kage.h" +#include "kagecgi.h" +#include +#include + +void DotsWidth(int *dlx, int *drx){ + int i, j; + + *dlx = 0; + *drx = 0; + for(i = 0; i <= pngWidth && *dlx == 0; i++){ + for(j = 0; j <= pngHeight; j++){ + if(kageCanvas[j][i] == 0){ + *dlx = i; + break; + } + } + } + + for(i = pngWidth; i >= 0 && *drx == 0; i--){ + for(j = 0; j <= pngHeight; j++){ + if(kageCanvas[j][i] == 0){ + *drx = i; + break; + } + } + } +} + +void DotsHeight(int *dly, int *dry){ + int i, j; + + *dly = 0; + *dry = 0; + for(j = 0; j <= pngHeight && *dly == 0; j++){ + for(i = 0; i <= pngWidth; i++){ + if(kageCanvas[j][i] == 0){ + *dly = j; + break; + } + } + } + + for(j = pngHeight; j >= 0 && *dry == 0; j--){ + for(i = 0; i <= pngWidth; i++){ + if(kageCanvas[j][i] == 0){ + *dry = j; + break; + } + } + } +} + +void PartsWidth(const GString *in, int *lx, int *rx){ + int i; + int *buf, strokes; + + *lx = 1000; *rx = 0; + buf = convertStroke(in->str, buf, &strokes); + + for(i = 0; i < strokes; i++){ + if(buf[i * 11 + 0] % 10 == 0) continue; + + if(*lx > buf[i * 11 + 3]) *lx = buf[i * 11 + 3]; + if(*rx < buf[i * 11 + 3]) *rx = buf[i * 11 + 3]; + if(*lx > buf[i * 11 + 5]) *lx = buf[i * 11 + 5]; + if(*rx < buf[i * 11 + 5]) *rx = buf[i * 11 + 5]; + + if(buf[i * 11 + 0] % 10 == 2 || buf[i * 11 + 0] % 10 == 3 || buf[i * 11 + 0] % 10 == 8){ + if(*lx > buf[i * 11 + 7]) *lx = buf[i * 11 + 7]; + if(*rx < buf[i * 11 + 7]) *rx = buf[i * 11 + 7]; + } + if(buf[i * 11 + 0] % 10 == 4 || buf[i * 11 + 0] % 10 == 6 || buf[i * 11 + 0] % 10 == 7){ + if(*lx > buf[i * 11 + 9]) *lx = buf[i * 11 + 9]; + if(*rx < buf[i * 11 + 9]) *rx = buf[i * 11 + 9]; + } + } + free(buf); +} + +void PartsHeight(const GString *in, int *ly, int *ry){ + int i; + int *buf, strokes; + + buf = convertStroke(in->str, buf, &strokes); + *ly = 1000; *ry = 0; + + for(i = 0; i < strokes; i++){ + if(buf[i * 11 + 0] % 10 == 0) continue; + + if(*ly > buf[i * 11 + 4]) *ly = buf[i * 11 + 4]; + if(*ry < buf[i * 11 + 4]) *ry = buf[i * 11 + 4]; + if(*ly > buf[i * 11 + 6]) *ly = buf[i * 11 + 6]; + if(*ry < buf[i * 11 + 6]) *ry = buf[i * 11 + 6]; + + if(buf[i * 11 + 0] % 10 == 2 || buf[i * 11 + 0] % 10 == 3 || buf[i * 11 + 0] % 10 == 8){ + if(*ly > buf[i * 11 + 8]) *ly = buf[i * 11 + 8]; + if(*ry < buf[i * 11 + 8]) *ry = buf[i * 11 + 8]; + } + if(buf[i * 11 + 0] % 10 == 4 || buf[i * 11 + 0] % 10 == 6 || buf[i * 11 + 0] % 10 == 7){ + if(*ly > buf[i * 11 + 10]) *ly = buf[i * 11 + 10]; + if(*ry < buf[i * 11 + 10]) *ry = buf[i * 11 + 10]; + } + } + free(buf); +} + +GString * CalcSizes(const GString *in, int mode){ + int i, j, k, basewidth, one_lineX, one_lineY; + int dlx1, drx1, dly1, dry1; + int px1, py1; + double pr1, pry1; + + int mitsuT, flg_boxT, widthT, heightT; + double tateT, yokoT; + int cutx, cuty; + + int *buf, strokes; + int tf[12]; + GString *out; + + out = g_string_new(""); + basewidth = pngWidth * 0.9; + + if(mode == 0){ + //temporary adjustment X-axis + PartsWidth(in, &dlx1, &drx1); + if(dlx1 == drx1){ + pr1 = 1.0; + px1 = pngWidth / 2 - dlx1; + one_lineX = 1; + } + else{ + pr1 = (double)basewidth/(drx1 - dlx1); + px1 = (pngWidth-basewidth)/2 - (double)(dlx1 * pr1); + one_lineX = 0; + } + + //temporary adjustment Y-axis + PartsHeight(in, &dly1, &dry1); + if(dly1 == dry1){ + pry1 = 1.0; + py1 = pngWidth / 2 - dly1; + one_lineY = 1; + } + else{ + pry1 = (double)basewidth/(dry1 - dly1); + py1 = (pngWidth-basewidth)/2 - (double)(dly1 * pry1); + one_lineY = 0; + } + } + else{ + PartsWidth(in, &dlx1, &drx1); + PartsHeight(in, &dly1, &dry1); + + cutx = 0; + cuty = 0; + + CalcOptions(in, &mitsuT, &flg_boxT, &yokoT, &tateT); + + widthT = basewidth; + heightT = basewidth; + + if(flg_boxT % 2 / 1 != 0){ + widthT = widthT - kWidth * 3; + cutx++; + } + if(flg_boxT % 4 / 2 != 0){ + widthT = widthT - kWidth * 3; + cutx++; + } + if(flg_boxT % 8 / 4 != 0){ + heightT = heightT - kWidth * 3; + cuty++; + } + if(flg_boxT % 16 / 8 != 0){ + heightT = heightT - kWidth * 3; + cuty++; + } + + //especially get small the 'mouse' + if(mode == 2 && flg_boxT % 16 == 15){ + widthT = widthT - kWidth * (max(0, 16 - (int)yokoT * 4)); + heightT = heightT - kWidth * (max(0, 16 - (int)tateT * 4)); + } + //'dot' as same as 'mouse' + if(mode == 2 && tateT == 1 && yokoT == 1){ + widthT = pngWidth * 0.9 * 0.5; + heightT = pngWidth * 0.9 * 0.5; + } + + if(flg_boxT % 64 / 32 != 0){ + buf = convertStroke(in->str, buf, &strokes); + for(i = 0; i < strokes; i++){ + if(buf[i * 11 + 0] == 0) j = buf[i * 11 + 4];// j : center line + } + free(buf); + k = max(j - dlx1, drx1 - j);// k : distance from center line + pr1 = (basewidth * 0.5) / k; + + if(k == j - dlx1) px1 = 0; + else px1 = pngWidth * 0.5 - j * pr1; + } + else if(dlx1 == drx1){ + pr1 = 1.0; + px1 = pngWidth / 2 - dlx1; + } + else{ + pr1 = (double)widthT/(drx1 - dlx1); + px1 = pngWidth / 2 - (double)((dlx1 + drx1) / 2 * pr1); + if(flg_boxT % 2 / 1 != 0 && flg_boxT % 4 / 2 == 0) px1 = px1 + kWidth * 1.5; + if(flg_boxT % 2 / 1 == 0 && flg_boxT % 4 / 2 != 0) px1 = px1 - kWidth * 1.5; + } + + if(dly1 == dry1){ + pry1 = 1.0; + py1 = pngWidth / 2 - dly1; + } + else{ + pry1 = (double)heightT/(dry1 - dly1); + py1 = pngWidth / 2 - (double)((dly1 + dry1) / 2 * pry1); + if(flg_boxT % 8 / 4 != 0 && flg_boxT % 16 / 8 == 0) py1 = py1 + kWidth * 1.5; + if(flg_boxT % 8 / 4 == 0 && flg_boxT % 16 / 8 != 0) py1 = py1 - kWidth * 1.5; + } + } + + //generate result + tf[0] = px1; + tf[1] = py1; + tf[2] = px1 + pr1 * 200; + tf[3] = py1 + pry1 * 200; + addStrokeWithTransform(in, 1, tf, out, 0); + return g_string_new(out->str); +} + +void DrawBox(){ + int i, j; + + for(i = 0; i < canvasWidth; i++){ + for(j = 0; j < canvasHeight; j++){ + kageCanvas[j][i] = 0xFF; + } + } +} + +void CalcOptions(const GString *in, int *mitsudo, int *flag, double *yoko, double *tate){ + int i, j, k, l, flg; + int dlx1, drx1, dly1, dry1; + int kari, mode; + int tempShotai; + int *buf, strokes; + + *flag = 0; + + DrawBox(); + tempShotai = kShotai; + kShotai = kGothic; + drawGlyph(in, 1); + kShotai = tempShotai; + DotsWidth(&dlx1, &drx1); + DotsHeight(&dly1, &dry1); + + //check left side + k = 0; + l = 0; + for(i = 0; i < pngWidth; i++){ + flg = 0; + for(j = 0; j < kWidth; j++){ + if(kageCanvas[i][dlx1 + j] == 0) flg = 1; + } + if(flg == 1){ + k++; + } + else{ + if(k > l) l = k; + k = 0; + } + } + if(k > l) l = k; + + if(l > pngWidth * 0.9 / 4) *flag = *flag | 1; + + //check right side + k = 0; + l = 0; + for(i = 0; i < pngWidth; i++){ + flg = 0; + for(j = 0; j < kWidth; j++){ + if(kageCanvas[i][drx1 - j] == 0) flg = 1; + } + if(flg == 1) k++; + else{ + if(k > l) l = k; + k = 0; + } + } + if(k > l) l = k; + + if(l > pngWidth * 0.9 / 4) *flag = *flag | 2; + + //check upper side + k = 0; + l = 0; + for(i = 0; i < pngWidth; i++){ + flg = 0; + for(j = 0; j < kWidth; j++){ + if(kageCanvas[dly1 + j][i] == 0) flg = 1; + } + if(flg == 1) k++; + else{ + if(k > l) l = k; + k = 0; + } + } + if(k > l) l = k; + + if(l > pngWidth * 0.9 / 4) *flag = *flag | 4; + + //check bottom side + k = 0; + l = 0; + for(i = 0; i < pngWidth; i++){ + flg = 0; + for(j = 0; j < kWidth; j++){ + if(kageCanvas[dry1 - j][i] == 0) flg = 1; + } + if(flg == 1) k++; + else{ + if(k > l) l = k; + k = 0; + } + } + if(k > l) l = k; + + if(l > pngWidth * 0.9 / 4) *flag = *flag | 8; + + //count black dots + *mitsudo = 0; + for(i = 0; i < pngHeight; i++){ + for(j = 0; j < pngWidth; j++){ + if(kageCanvas[i][j] == 0) *mitsudo += 1; + } + } + + //calculate X-axis complexity + *yoko = 0; + for(i = dly1; i <= dry1; i++){ + mode = 0; + kari = 0; + for(j = dlx1; j <= drx1; j++){ + if(kageCanvas[i][j] == 0 && + kageCanvas[i][j+1] == 0 && + kageCanvas[i][j+2] == 0){ + if(mode == 0){ + mode = 1; + kari++; + } + } + else if(mode == 1) mode = 0; + } + if(kari > *yoko) *yoko = kari; + } + + //calculate Y-axis complexity + *tate = 0; + for(i = dlx1; i <= drx1; i++){ + mode = 0; + kari = 0; + for(j = dly1; j <= dry1; j++){ + if(kageCanvas[j][i] == 0 && + kageCanvas[j+1][i] == 0 && + kageCanvas[j+2][i] == 0){ + if(mode == 0){ + mode = 1; + kari++; + } + } + else if(mode == 1) mode = 0; + } + if(kari > *tate) *tate = kari; + } + + //use user defined option if it exists + buf = convertStroke(in->str, buf, &strokes); + for(i = 0; i < strokes; i++){ + if(buf[i * 11 + 0] % 10 == 0){ + if(buf[i * 11 + 1] != 0){ *yoko = (double)(buf[i * 11 + 1]) * 0.1;fprintf(stderr,"@@@@@\r\n");} + if(buf[i * 11 + 2] != 0) *tate = (double)(buf[i * 11 + 2]) * 0.1; + if(buf[i * 11 + 3] != 0) *flag = *flag + buf[i * 11 + 3] * 16; + } + } + free(buf); +} + +void DoDrawParts(const GString *in, const int lx1, const double rf1, const int ly1, const double rfy1){ + int i; + int *buf, strokes; + + DrawBox(); + buf = convertStroke(in->str, buf, &strokes); + for(i = 0; i < strokes; i++){ + dfDrawFont(buf[i * 11 + 0], + buf[i * 11 + 1], + buf[i * 11 + 2], + buf[i * 11 + 3] * rf1 + lx1, + buf[i * 11 + 4] * rfy1 + ly1, + buf[i * 11 + 5] * rf1 + lx1, + buf[i * 11 + 6] * rfy1 + ly1, + buf[i * 11 + 7] * rf1 + lx1, + buf[i * 11 + 8] * rfy1 + ly1, + buf[i * 11 + 9] * rf1 + lx1, + buf[i * 11 + 10] * rfy1 + ly1); + } + free(buf); +} + +void DoDrawMixFont(const GString *in1, + const int lx1, + const double rf1, + const GString *in2, + const int lx2, + const double rf2, + const int ly1, + const double rfy1, + const int ly2, + const double rfy2){ + int i; + int *buf, strokes; + + DrawBox(); + buf = convertStroke(in1->str, buf, &strokes); + for(i = 0; i < strokes; i++){ + dfDrawFont(buf[i * 11 + 0], + buf[i * 11 + 1], + buf[i * 11 + 2], + buf[i * 11 + 3] * rf1 + lx1, + buf[i * 11 + 4] * rfy1 + ly1, + buf[i * 11 + 5] * rf1 + lx1, + buf[i * 11 + 6] * rfy1 + ly1, + buf[i * 11 + 7] * rf1 + lx1, + buf[i * 11 + 8] * rfy1 + ly1, + buf[i * 11 + 9] * rf1 + lx1, + buf[i * 11 + 10] * rfy1 + ly1); + } + free(buf); + + buf = convertStroke(in2->str, buf, &strokes); + for(i = 0; i < strokes; i++){ + dfDrawFont(buf[i * 11 + 0], + buf[i * 11 + 1], + buf[i * 11 + 2], + buf[i * 11 + 3] * rf2 + lx2, + buf[i * 11 + 4] * rfy2 + ly2, + buf[i * 11 + 5] * rf2 + lx2, + buf[i * 11 + 6] * rfy2 + ly2, + buf[i * 11 + 7] * rf2 + lx2, + buf[i * 11 + 8] * rfy2 + ly2, + buf[i * 11 + 9] * rf2 + lx2, + buf[i * 11 + 10] * rfy2 + ly2); + } + free(buf); +} + -- 1.7.10.4