X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=draw.c;h=79518a04c98e340ac2c0014320892d687e09a97f;hb=refs%2Fheads%2Fv4.9.x;hp=1604a23a4bd2fe8ceadca00538fa428587019563;hpb=2f0884e0846edf141d42ea2d5e3fcbc6949f50f6;p=xboard.git diff --git a/draw.c b/draw.c index 1604a23..f51c771 100644 --- a/draw.c +++ b/draw.c @@ -106,10 +106,10 @@ extern char *getenv(); Boolean cairoAnimate; Option *currBoard; cairo_surface_t *csBoardWindow; -static cairo_surface_t *pngPieceImages[2][(int)BlackPawn]; // png 256 x 256 images -static cairo_surface_t *pngPieceBitmaps[2][(int)BlackPawn]; // scaled pieces as used -static cairo_surface_t *pngPieceBitmaps2[2][(int)BlackPawn]; // scaled pieces in store -static RsvgHandle *svgPieces[2][(int)BlackPawn]; // vector pieces in store +static cairo_surface_t *pngPieceImages[2][(int)BlackPawn+1]; // png 256 x 256 images +static cairo_surface_t *pngPieceBitmaps[2][(int)BlackPawn+1]; // scaled pieces as used +static cairo_surface_t *pngPieceBitmaps2[2][(int)BlackPawn+1]; // scaled pieces in store +static RsvgHandle *svgPieces[2][(int)BlackPawn+1]; // vector pieces in store static cairo_surface_t *pngBoardBitmap[2], *pngOriginalBoardBitmap[2]; int useTexture, textureW[2], textureH[2]; @@ -165,7 +165,7 @@ SelectPieces(VariantClass v) int i; for(i=0; i<2; i++) { int p; - for(p=0; p<=(int)WhiteKing; p++) + for(p=0; p<=(int)WhiteKing+1; p++) pngPieceBitmaps[i][p] = pngPieceBitmaps2[i][p]; // defaults if(v == VariantShogi && BOARD_HEIGHT != 7) { // no exceptions in Tori Shogi pngPieceBitmaps[i][(int)WhiteCannon] = pngPieceBitmaps2[i][(int)WhiteTokin]; @@ -187,20 +187,6 @@ SelectPieces(VariantClass v) if(v == VariantChuChess) { pngPieceBitmaps[i][(int)WhiteNightrider] = pngPieceBitmaps2[i][(int)WhiteLion]; } - if(v == VariantChu) { - pngPieceBitmaps[i][(int)WhiteNightrider] = pngPieceBitmaps2[i][(int)WhiteClaw]; - pngPieceBitmaps[i][(int)WhiteClaw] = pngPieceBitmaps2[i][(int)WhiteNightrider]; - pngPieceBitmaps[i][(int)WhiteUnicorn] = pngPieceBitmaps2[i][(int)WhiteCat]; - pngPieceBitmaps[i][(int)WhiteSilver] = pngPieceBitmaps2[i][(int)WhiteSword]; - pngPieceBitmaps[i][(int)WhiteFalcon] = pngPieceBitmaps2[i][(int)WhiteDagger]; - pngPieceBitmaps[i][(int)WhiteCat] = pngPieceBitmaps2[i][(int)WhiteUnicorn]; - pngPieceBitmaps[i][(int)WhiteSword] = pngPieceBitmaps2[i][(int)WhiteSilver]; - pngPieceBitmaps[i][(int)WhiteDagger] = pngPieceBitmaps2[i][(int)WhiteFalcon]; - pngPieceBitmaps[i][(int)WhiteMan] = pngPieceBitmaps2[i][(int)WhiteCopper]; - pngPieceBitmaps[i][(int)WhiteCopper] = pngPieceBitmaps2[i][(int)WhiteMan]; - pngPieceBitmaps[i][(int)WhiteAxe] = pngPieceBitmaps2[i][(int)WhiteCannon]; - pngPieceBitmaps[i][(int)WhiteCannon] = pngPieceBitmaps2[i][(int)WhiteAxe]; - } } } @@ -288,13 +274,14 @@ CreatePNGBoard (char *s, int kind) useTexture |= kind + 1; pngOriginalBoardBitmap[kind] = img; w = textureW[kind] = cairo_image_surface_get_width (img); h = textureH[kind] = cairo_image_surface_get_height (img); + transparency[kind] = cairo_image_surface_get_format (img) == CAIRO_FORMAT_ARGB32; n[kind] = 1.; modV[kind] = modH[kind] = -1; while((q = strchr(p+1, '-'))) p = q; // find last '-' if(strlen(p) < 11 && sscanf(p, "-%dx%d.pn%c", &f, &r, &c) == 3 && c == 'g') { if(f == 0 || r == 0) f = BOARD_WIDTH, r = BOARD_HEIGHT; // 0x0 means 'fits any', so make it fit textureW[kind] = (w*BOARD_WIDTH)/f; // sync cutting locations with square pattern textureH[kind] = (h*BOARD_HEIGHT)/r; - n[kind] = r*squareSize/h; // scale to make it fit exactly vertically + n[kind] = (r*squareSize + 0.99)/h; // scale to make it fit exactly vertically modV[kind] = r; modH[kind] = f; } else if((p = strstr(s, "xq")) && (p == s || p[-1] == '/')) { // assume full-board image for Xiangqi @@ -324,7 +311,7 @@ char *pngPieceNames[] = // must be in same order as internal piece encoding "LShield", "Pegasus", "Wizard", "Copper", "Iron", "Viking", "Flag", "Axe", "Dolphin", "Leopard", "Claw", "Left", "Butterfly", "PromoBishop", "PromoRook", "HCrown", "RShield", "Prince", "Phoenix", "Kylin", "Drunk", "Right", "GoldPawn", "GoldKnight", "PromoHorse", "PromoDragon", "GoldLance", "GoldSilver", "HSword", "PromoSword", "PromoHSword", "Princess", "King", - NULL + "Ducky", NULL }; char *backupPiece[] = { // pieces that map on other in default theme ("Crown" - "Drunk") @@ -388,6 +375,40 @@ LoadSVG (char *dir, int color, int piece, int retry) return NULL; } +static void Wint(FILE *f, int n) +{ // write 32-bit int, lsb first + fprintf(f, "%c%c%c%c", n&255, n>>8&255, n>>16&255, n>>24&255); +} + +static void +SaveWindowsBitmap(ChessSquare piece, int color, int *data, int stride, int w, int h, int bpp) +{ + int i, v, line = (w*bpp + 3)>>2, size = line*4*h; + char buf[100]; + FILE *f; + snprintf(buf, 100, "bmaps/piece%d_%d%c.bmp", piece, w, color ? 's': 'o'); + if(piece >= appData.bmpSave && piece != WhiteKing) return; + f = fopen(buf, "wb"); + if(!f) return; + fprintf(f, "BM"); + Wint(f, size+54); Wint(f, 0); Wint(f, 54); Wint(f, 40); // file size, reserved, image offset, header size + Wint(f, w); Wint(f, h); Wint(f, 8*bpp << 16 | 1); // width, height, planes & bits/pix + Wint(f, 0); // compression + Wint(f, size); Wint(f, 3780); Wint(f, 3780); Wint(f, 0); Wint(f, 0); // image size, pix/m (H and V), color-table size (2x) + for(v=h-1; v>=0; v--) { + for(i=0; i>16&255, g=pix>>8&255, b=pix&255, a=pix>>24&255; + r = r*a/255; b = b*a/255; g = g*a/255; + if(bpp == 4) fprintf(f, "%c%c%c%c", b, g, r, a); else fprintf(f, "%c%c%c", b, g, r); + } + i *= bpp; while(i++ < line*4) fprintf(f, "%c", 0); // padding + } + fclose(f); + if(appData.bmpSave && piece == WhiteKing && color) exit(0); +} + +void InscribeKanji (cairo_surface_t *canvas, ChessSquare piece, int x, int y); + static void ScaleOnePiece (int color, int piece, char *pieceDir) { @@ -437,6 +458,9 @@ ScaleOnePiece (int color, int piece, char *pieceDir) cairo_set_source_surface (cr, img, 0, 0); cairo_paint (cr); cairo_destroy (cr); +if(appData.inscriptions[0]) InscribeKanji(cs, piece+BlackPawn*color, 0, 0); +//sprintf(buf, "%c2%d.png", color ? 'b' : 'w', piece); +//if(piece < 66) cairo_surface_write_to_png(cs, buf); if(!appData.trueColors || !*pieceDir) { // operate on bitmap to color it (king-size hack...) int stride = cairo_image_surface_get_stride(cs)/4; @@ -444,6 +468,7 @@ ScaleOnePiece (int color, int piece, char *pieceDir) int i, j, p; sscanf(color ? appData.blackPieceColor+1 : appData.whitePieceColor+1, "%x", &p); // replacement color cairo_surface_flush(cs); + SaveWindowsBitmap(piece, color, buf, stride, squareSize, squareSize, 4); for(i=0; i= BlackPawn) piece = BLACK_TO_WHITE piece; p = appData.inscriptions; - n = piece; + if(*p > '0' && *p < '3') nr = *p++ - '0'; // nr of kanji per piece + n = piece; i = 0; while(piece > WhitePawn) { + if(*p == '/') p++, piece = n - WhitePBishop; // secondary series if(*p++ == NULLCHAR) { if(n != WhiteKing) return; - p = q; + p = oldq; break; } - q = p - 1; + oldq = q; q = p - 1; while((*p & 0xC0) == 0x80) p++; // skip UTF-8 continuation bytes - piece--; + if(*q != '.' && ++i < nr) continue; // yet more kanji for the current piece + piece--; i = 0; } - strncpy(buf, p, 10); - for(q=buf; (*++q & 0xC0) == 0x80;); + strncpy(buf, p, 20); + for(q=buf; (*++q & 0xC0) == 0x80;); // skip first unicode + if(nr > 1) { + p = q; + while((*++p & 0xC0) == 0x80) {} // skip second unicode + *p = NULLCHAR; size = 30; i = -12; + DrawUnicode(canvas, q, x, y, PieceToChar(n), flip, size, 16); + } else i = 4; *q = NULLCHAR; - DrawUnicode(canvas, buf, x, y, PieceToChar(n), flip); + DrawUnicode(canvas, buf, x, y, PieceToChar(n), flip, size, i); } void @@ -927,7 +965,7 @@ DrawOneSquare (int x, int y, ChessSquare piece, int square_color, int marker, ch BlankSquare(CsBoardWindow(currBoard), x, y, square_color, piece, 1); } else { pngDrawPiece(CsBoardWindow(currBoard), piece, square_color, x, y); - if(appData.inscriptions[0]) InscribeKanji(CsBoardWindow(currBoard), piece, x, y); +// if(appData.inscriptions[0]) InscribeKanji(CsBoardWindow(currBoard), piece, x, y); } if(align) { // square carries inscription (coord or piece count)