#include #include #include #include #include #include #include using namespace std; /* This program generates nice graphics for Kifu tables. Copyright (C) 1992,2003 Joel Yliluoma (http://iki.fi/bisqwit/) Requires libgd2, freetype2, libpng, (g++). Included circlefun.c can be found where this too. Example input: SIZE 9 9 DATA ......... DATA ......... DATA ......... DATA ......... DATA ....OXX.. DATA ...OOOX.. DATA ....OXXX. DATA .....OXX. DATA ......... SYMS E4[15]G3[2]F4[12]H3[5]E5[4]G4[3]F2[8]F5[9]E3[10]G2[7]G5[11]D4[16]H2[13]F3[1] NOTE B17=B1 NOTE W14 B19=W2 NOTE W18=B15 (DATA format (for board format): .=empty, X=black, O=white SYMS format (for placing text on the board): coordinate[whatiswrittenthere]... NOTE format (for displaying ko-takers): stone(...)=stone ) Also settings: SET DC 1 = set drawcoords on SET VF 1 = set varyfont on SET BC #010456 = set blackcolour SET AC #000000 = set bancolour SET WC #FFFFFF = set whitecolour SET MC #700707 = set messagecolour Compile like this: g++ kifugrafgen.cc -o kifugrafgen /usr/local/lib/libgd.a -lpng -lfreetype& Try: kifugrafgen test.png display test.png */ #include "circlefun.c" static bool DrawCoords = true; static bool VaryFont = true; static string BlackColor = "#000000"; static string BanColor = "#C89650"; static string WhiteColor = "#FFFFFF"; static string MesgColor = "#787878"; #define RAD 21 #define RAD2 10 static void GetColour(const string &str, int &r, int &g, int &b) { r = 0; g = 0; b = 0; unsigned l=0; if(str.size() == 7 && str[0] == '#') sscanf(str.c_str()+1, "%X", &l); else if(str.size() == 6 && isxdigit(str[0]) && isxdigit(str[1]) && isxdigit(str[2])) sscanf(str.c_str(), "%X", &l); else if(str.size() == 4 && str[0] == '#') { sscanf(str.c_str()+1, "%X", &l); l = ((((l )&15)*255/15)) + ((((l>>4)&15)*255/15)<<8) + ((((l>>8)&15)*255/15)<<16); } else if(str.size() == 3 && isxdigit(str[0]) && isxdigit(str[1]) && isxdigit(str[2])) { sscanf(str.c_str(), "%X", &l); l = ((((l )&15)*255/15)) + ((((l>>4)&15)*255/15)<<8) + ((((l>>8)&15)*255/15)<<16); } b = l&255; g = (l>>8) & 255; r = (l>>16) & 255; } struct notestring { unsigned length; string target; vector items; void Load(const char *s) { for(;;) { string item; while(*s != ' ' && *s != '=') item += *s++; items.push_back(item); if(*s++ == '=') break; } while(*s != '\n') target += *s++; length = items.size() + 2; } }; static int b,h,w,m, alareuna, ylax, ylay; static int wid,hei; static gdImagePtr im; static char *white; static vector notestrings; static unsigned GetNoteStringSpace() { unsigned x=0, y=0; for(unsigned a=0; a (wid*RAD+ylax*2+RAD-6)/RAD) { x = 0; ++y; } x += len; } if(x) ++y; return y; } static bool notestringcompare(const notestring &a, const notestring &b) { int aa; sscanf(a.items[0].c_str()+1, "%d", &aa); int bb; sscanf(b.items[0].c_str()+1, "%d", &bb); if(aa < bb)return true; return false; } static void ArrangeNoteStrings() { sort(notestrings.begin(), notestrings.end(), notestringcompare); } static void Open() { ArrangeNoteStrings(); if(DrawCoords) ylax=ylay=13; else ylax=ylay=0; int ww=RAD*wid + ylax*2; int hh=ylay*2 + RAD*hei; alareuna = hh; hh += GetNoteStringSpace() * RAD; im = gdImageCreateTrueColor(ww, hh); gdImageAlphaBlending(im, 1); int R,G,B; GetColour(BlackColor, R,G,B); b = gdImageColorAllocate(im, R,G,B); GetColour(BanColor, R,G,B); h = gdImageColorAllocate(im, R,G,B); GetColour(WhiteColor, R,G,B); w = gdImageColorAllocate(im, R,G,B); GetColour(MesgColor, R,G,B); m = gdImageColorAllocate(im, R,G,B); white = new char[wid*hei]; memset(white,0,wid*hei); gdImageFilledRectangle(im, 0,0, ww,hh,m); } static void DrawBan() { gdImageFilledRectangle(im, 0,0, ylax*2+RAD*wid, ylay*2+RAD*hei, h); } static void DrawHoshi(int x, int y) { DrawFilledCircle(im, ylax+x*RAD+RAD2, ylay+y*RAD+RAD2, 1, b); } static void DrawGrid() { int brect[8]; for(int y=0; y=8?1:0)); gdImageStringFT(im, brect, b, "/WWW/arialbd.ttf", ptsize, 0, ylax+x*RAD+4, ylay-3, Buf); gdImageStringFT(im, brect, b, "/WWW/arialbd.ttf", ptsize, 0, ylax+x*RAD+4, ylay*2-3+hei*RAD, Buf); } } int edge = hei < 12 ? 2 : 3; DrawHoshi(edge, edge); DrawHoshi(edge, hei-1-edge); DrawHoshi(wid-1-edge, edge); DrawHoshi(wid-1-edge, hei-1-edge); if(hei%2) { int center = (hei-1)/2; DrawHoshi(center,center); if(edge > 2) { DrawHoshi(center, edge); DrawHoshi(center, hei-1-edge); DrawHoshi(wid-1-edge, center); DrawHoshi(edge, center); } } } static void DrawSym(int x, int y, const string &sym, int c) { int brect[8]; if(sym == "TR") { // triangle gdImageSetThickness(im, 2); gdImageLine(im, x+RAD2,y+1, x+3,y+RAD-7, c); gdImageLine(im, x+3,y+RAD-6, x+RAD-3,y+RAD-7, c); gdImageLine(im, x+RAD2,y+1, x+RAD-3,y+RAD-7, c); gdImageSetThickness(im, 1); int ptsize = 14; } else if(sym == "SQ") { // square gdImageSetThickness(im, 1); gdImageRectangle(im, x+5,y+5, x+RAD-5,y+RAD-6, c); gdImageSetThickness(im, 1); } else if(sym == "CR") { // circle int ptsize = 16; const char *s = "C"; gdImageStringFT(im, brect, c, "/WWW/arialbd.ttf", ptsize, 0, x+5,y+RAD-3, const_cast(s)); } else if(sym[0] == '"') { // text int ptsize = 14; const char *s = sym.c_str() + 1; gdImageStringFT(im, brect, c, "/WWW/arialbd.ttf", ptsize, 0, x+4,y+RAD-4, const_cast(s)); } else { // number int num, ptsize=13; sscanf(sym.c_str(), "%d", &num); if(num < 10 && VaryFont) { ptsize = 14; x += 5; y += RAD-4; } else if(num < 100 && VaryFont) { ptsize = 10; x += 3; y += RAD-5; } else { ptsize = 7; x += 2; y += RAD-7; } gdImageStringFT(im, brect, c, "/WWW/arialbd.ttf", ptsize, 0, x,y, const_cast(sym.c_str())); } } static void DrawSym(const string &coord, const string &sym) { //printf("'%s' at '%s'\n", sym.c_str(), coord.c_str()); int x = coord[0]-'A', y; if(coord[0] >= 'J')--x; sscanf(coord.c_str()+1, "%d", &y); y = hei-y; int c = white[x + y*wid] ? w : b; DrawSym(ylax+x*RAD,ylay+y*RAD, sym, c); } static void DrawBlackStone(unsigned x,unsigned y) { DrawFilledCircle(im, x+RAD2, y+RAD2, RAD2, b); } static void DrawWhiteStone(unsigned x,unsigned y) { DrawFilledCircle(im, x+RAD2, y+RAD2, RAD2, w); DrawCircle(im, x+RAD2, y+RAD2, RAD2, b); } static void Close() { //FILE *pngout; //pngout = fopen("test.png", "wb"); //gdImagePng(im, pngout); gdImagePng(im, stdout); //fclose(pngout); delete[] white; } static void DrawNoteString(unsigned x,unsigned y, const notestring &n) { int c; for(unsigned a=0; a (wid*RAD+ylax*2+RAD-6)/RAD) { x = 0; ++y; } DrawNoteString(x, y, notestrings[a]); x += len; } } int main(void) { char Buf[16384]; int x,y; vector lines; while(fgets(Buf,sizeof Buf, stdin)) { lines.push_back(Buf); if(!strncmp(Buf, "NOTE", 4)) { notestring n; n.Load(Buf+5); notestrings.push_back(n); } char *k = strchr(Buf, '\n'); if(k) *k = 0; if(!strncmp(Buf, "SET DC ", 7)) DrawCoords = Buf[7] == '1'; if(!strncmp(Buf, "SET VF ", 7)) VaryFont = Buf[7] == '1'; if(!strncmp(Buf, "SET BC ", 7)) BlackColor = Buf+7; if(!strncmp(Buf, "SET AC ", 7)) BanColor = Buf+7; if(!strncmp(Buf, "SET WC ", 7)) WhiteColor = Buf+7; if(!strncmp(Buf, "SET MC ", 7)) MesgColor = Buf+7; } for(unsigned a=0; a