/*
* htmlimages.c
*
* by Gary Wong , 1997-2002.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* 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
*
* $Id: htmlimages.c,v 1.26 2004/04/30 17:33:58 Superfly_Jon Exp $
*/
#if HAVE_CONFIG_H
#include
#endif
#include
#if HAVE_SYS_STAT_H
#include
#endif
#include
#include
#include
#if HAVE_SYS_TYPES_H
#include
#endif
#if HAVE_UNISTD_H
#include
#endif
#if HAVE_LIBART
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#endif
#include "backgammon.h"
#include "export.h"
#include "i18n.h"
#include "render.h"
#include "renderprefs.h"
#include "boardpos.h"
#include "boarddim.h"
#if HAVE_LIBPNG
char *szFile, *pchFile;
int imagesWritten;
#define NUM_IMAGES 344
/* Overall board size */
int s;
/* Size of cube and dice - now same as rest of board */
#define ss s
/* Helpers for 2d position in arrays */
#define boardStride (BOARD_WIDTH * s * 3)
#define coord(x, y) ((x) * s * 3 + (y) * s * boardStride)
#define coordStride(x, y, stride) ((x) * s * 3 + (y) * s * stride)
unsigned char *auchBoard, *auchChequer[2], *auchChequerLabels, *auchLo, *auchHi,
*auchLoRev, *auchHiRev, *auchCube, *auchCubeFaces, *auchDice[2], *auchPips[2],
*auchLabel, *auchOff[2], *auchMidBoard, *auchBar[2], *auchPoint[2][2][2];
unsigned short *asRefract[2];
#if HAVE_LIBART
unsigned char *auchArrow[ 2 ];
#endif
unsigned char *auchMidlb;
static void WriteImageStride(unsigned char* img, int stride, int cx, int cy)
{
if (WritePNG(szFile, img, stride, cx, cy) == -1)
outputf("Error creating file %s\n", szFile);
imagesWritten++;
ProgressValueAdd(1);
}
static void WriteStride(const char* name, unsigned char* img, int stride, int cx, int cy)
{
strcpy(pchFile, name);
WriteImageStride(img, stride, cx, cy);
}
static void WriteImage(unsigned char* img, int cx, int cy)
{
WriteImageStride(img, boardStride, cx, cy);
}
static void Write(const char* name, unsigned char* img, int cx, int cy)
{
strcpy(pchFile, name);
WriteImage(img, cx, cy);
}
static void DrawArrow(int side, int player)
{ /* side 0 = left, 1 = right */
#if HAVE_LIBART
int x, y;
#endif
int offset_x = 0;
memcpy( auchMidlb, auchBoard, BOARD_WIDTH * s * BOARD_HEIGHT * s * 3 );
#if HAVE_LIBART
ArrowPosition(side /* rd.fClockwise */, s, &x, &y);
AlphaBlendClip2( auchMidlb, boardStride,
x, y,
BOARD_WIDTH * s, BOARD_HEIGHT * s,
auchMidlb, boardStride,
x, y,
auchArrow[player],
s * ARROW_WIDTH * 4,
0, 0,
s * ARROW_WIDTH,
s * ARROW_HEIGHT );
#endif
sprintf( pchFile, "b-mid%cb-%c.png", side ? 'r' : 'l', player ? 'o' : 'x' );
if (side == 1)
offset_x = BOARD_WIDTH - BEAROFF_WIDTH;
WriteImage(auchMidlb + coord(offset_x, BOARD_HEIGHT / 2 - BOARD_CENTER_HEIGHT / 2),
BEAROFF_WIDTH * s, BOARD_CENTER_HEIGHT * s);
}
static void DrawPips(unsigned char *auchDest, int nStride,
unsigned char *auchPip, int n)
{
int ix, iy, afPip[9];
afPip[0] = afPip[8] = (n == 2) || (n == 3) || (n == 4) || (n == 5) || (n == 6);
afPip[1] = afPip[7] = 0;
afPip[2] = afPip[6] = (n == 4) || (n == 5) || (n == 6);
afPip[3] = afPip[5] = n == 6;
afPip[4] = n & 1;
for (iy = 0; iy < 3; iy++)
{
for (ix = 0; ix < 3; ix++)
{
if (afPip[iy * 3 + ix])
CopyArea(auchDest + (int)(1.5 * (ix + 1) * ss) * 3 +
((int)(1.5 * (iy + 1) * ss) * nStride), nStride,
auchPip, ss * 3, ss, ss);
}
}
}
static void WriteBorder(char* file, unsigned char *auchSrc, unsigned char *auchBoardSrc)
{
CopyArea(auchLabel, boardStride, auchBoardSrc, boardStride,
BOARD_WIDTH * s, BORDER_HEIGHT * s);
AlphaBlendClip(auchLabel, boardStride, 0, 0,
BOARD_WIDTH * s, BORDER_HEIGHT * s,
auchLabel, boardStride, 0, 0,
auchSrc, BOARD_WIDTH * s * 4, 0, 0,
BOARD_WIDTH * s, BORDER_HEIGHT * s);
Write(file, auchLabel, BOARD_WIDTH * s, BORDER_HEIGHT * s);
}
static void WriteImages()
{
int i, j, k;
imagesWritten = 0;
/* top border-high numbers */
WriteBorder("b-hitop.png", auchHi, auchBoard);
WriteBorder("b-hitopr.png", auchHiRev, auchBoard);
/* top border-low numbers */
WriteBorder("b-lotop.png", auchLo, auchBoard);
WriteBorder("b-lotopr.png", auchLoRev, auchBoard);
/* empty points */
Write("b-gd.png", auchBoard + coord(BEAROFF_WIDTH, BORDER_HEIGHT),
POINT_WIDTH * s, POINT_HEIGHT * s);
Write("b-rd.png", auchBoard + coord(BEAROFF_WIDTH + POINT_WIDTH, BORDER_HEIGHT),
POINT_WIDTH * s, POINT_HEIGHT * s);
Write("b-ru.png", auchBoard + coord(BEAROFF_WIDTH, BOARD_HEIGHT / 2 + BOARD_CENTER_HEIGHT / 2),
POINT_WIDTH * s, POINT_HEIGHT * s);
Write("b-gu.png", auchBoard + coord(BEAROFF_WIDTH + POINT_WIDTH, BOARD_HEIGHT / 2 + BOARD_CENTER_HEIGHT / 2),
POINT_WIDTH * s, POINT_HEIGHT * s);
/* upper left bearoff tray */
Write("b-loff-x0.png", auchBoard + coord(0, BORDER_HEIGHT),
BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s);
/* upper right bearoff tray */
Write("b-roff-x0.png", auchBoard + coord(BOARD_WIDTH - BEAROFF_WIDTH, BORDER_HEIGHT),
BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s);
/* lower right bearoff tray */
Write("b-roff-o0.png", auchBoard + coord(BOARD_WIDTH - BEAROFF_WIDTH, BORDER_HEIGHT + POINT_HEIGHT + BOARD_CENTER_HEIGHT),
BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s);
/* lower left bearoff tray */
Write("b-loff-o0.png", auchBoard + coord(0, BORDER_HEIGHT + POINT_HEIGHT + BOARD_CENTER_HEIGHT),
BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s);
/* bar top */
Write("b-ct.png", auchBoard + coord(BOARD_WIDTH / 2 - BAR_WIDTH / 2, BORDER_HEIGHT),
BAR_WIDTH * s, CUBE_HEIGHT * s);
/* bearoff tray dividers */
/* 4 arrows, left+right side for each player */
DrawArrow(0, 0);
DrawArrow(0, 1);
DrawArrow(1, 0);
DrawArrow(1, 1);
/* left bearoff centre */
strcpy( pchFile, "b-midlb.png" );
WriteImage(auchBoard + coord(0, BOARD_HEIGHT / 2 - BOARD_CENTER_HEIGHT / 2),
BEAROFF_WIDTH * s, BOARD_CENTER_HEIGHT * s);
/* right bearoff centre */
strcpy( pchFile, "b-midrb.png" );
WriteImage(auchBoard + coord(BOARD_WIDTH - BEAROFF_WIDTH, BOARD_HEIGHT / 2 - BOARD_CENTER_HEIGHT / 2),
BEAROFF_WIDTH * s, BOARD_CENTER_HEIGHT * s);
/* left board centre */
strcpy( pchFile, "b-midl.png" );
WriteImage(auchBoard + coord(BEAROFF_WIDTH, BOARD_HEIGHT / 2 - BOARD_CENTER_HEIGHT / 2),
BOARD_CENTER_WIDTH * s, BOARD_CENTER_HEIGHT * s);
/* bar centre */
strcpy( pchFile, "b-midc.png" );
WriteImage(auchBoard + coord(BOARD_WIDTH / 2 - BAR_WIDTH / 2, BOARD_HEIGHT / 2 - BOARD_CENTER_HEIGHT / 2),
BAR_WIDTH * s, BOARD_CENTER_HEIGHT * s);
/* right board centre */
strcpy( pchFile, "b-midr.png" );
WriteImage(auchBoard + coord(BOARD_WIDTH / 2 + BAR_WIDTH / 2, BOARD_HEIGHT / 2 - BOARD_CENTER_HEIGHT / 2),
BOARD_CENTER_WIDTH * s, BOARD_CENTER_HEIGHT * s);
/* bar bottom */
Write("b-cb.png", auchBoard + coord(BOARD_WIDTH / 2 - BAR_WIDTH / 2, BOARD_HEIGHT - CUBE_HEIGHT - BORDER_HEIGHT),
BAR_WIDTH * s, CUBE_HEIGHT * s);
/* bottom border-high numbers */
WriteBorder("b-hibot.png", auchHi, auchBoard + coord(0, BOARD_HEIGHT - BORDER_HEIGHT));
WriteBorder("b-hibotr.png", auchHiRev, auchBoard + coord(0, BOARD_HEIGHT - BORDER_HEIGHT));
/* bottom border-low numbers */
WriteBorder("b-lobot.png", auchLo, auchBoard + coord(0, BOARD_HEIGHT - BORDER_HEIGHT));
WriteBorder("b-lobotr.png", auchLoRev, auchBoard + coord(0, BOARD_HEIGHT - BORDER_HEIGHT));
/* Copy 4 points (top/bottom and both colours) */
CopyArea(auchPoint[0][0][0], POINT_WIDTH * s * 3,
auchBoard + coord(BEAROFF_WIDTH, BORDER_HEIGHT), boardStride,
POINT_WIDTH * s, POINT_HEIGHT * s);
CopyArea(auchPoint[0][0][1], POINT_WIDTH * s * 3,
auchBoard + coord(BEAROFF_WIDTH, BORDER_HEIGHT), boardStride,
POINT_WIDTH * s, POINT_HEIGHT * s);
CopyArea(auchPoint[0][1][0], POINT_WIDTH * s * 3,
auchBoard + coord(BEAROFF_WIDTH + POINT_WIDTH, BOARD_HEIGHT / 2 + BOARD_CENTER_HEIGHT / 2), boardStride,
POINT_WIDTH * s, POINT_HEIGHT * s);
CopyArea(auchPoint[0][1][1], POINT_WIDTH * s * 3,
auchBoard + coord(BEAROFF_WIDTH + POINT_WIDTH, BOARD_HEIGHT / 2 + BOARD_CENTER_HEIGHT / 2), boardStride,
POINT_WIDTH * s, POINT_HEIGHT * s);
CopyArea(auchPoint[1][0][0], POINT_WIDTH * s * 3,
auchBoard + coord(BEAROFF_WIDTH + POINT_WIDTH, BORDER_HEIGHT), boardStride,
POINT_WIDTH * s, POINT_HEIGHT * s);
CopyArea(auchPoint[1][0][1], POINT_WIDTH * s * 3,
auchBoard + coord(BEAROFF_WIDTH + POINT_WIDTH, BORDER_HEIGHT), boardStride,
POINT_WIDTH * s, POINT_HEIGHT * s);
CopyArea(auchPoint[1][1][0], POINT_WIDTH * s * 3,
auchBoard + coord(BEAROFF_WIDTH, BOARD_HEIGHT / 2 + BOARD_CENTER_HEIGHT / 2), boardStride,
POINT_WIDTH * s, POINT_HEIGHT * s);
CopyArea(auchPoint[1][1][1], POINT_WIDTH * s * 3,
auchBoard + coord(BEAROFF_WIDTH, BOARD_HEIGHT / 2 + BOARD_CENTER_HEIGHT / 2), boardStride,
POINT_WIDTH * s, POINT_HEIGHT * s);
/* Bear off trays */
CopyArea(auchOff[0], BEAROFF_WIDTH * s * 3,
auchBoard + coord(BOARD_WIDTH - BEAROFF_WIDTH, BORDER_HEIGHT), boardStride,
BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s);
CopyArea(auchOff[1], BEAROFF_WIDTH * s * 3,
auchBoard + coord(BOARD_WIDTH - BEAROFF_WIDTH, BOARD_HEIGHT / 2 + BOARD_CENTER_HEIGHT / 2), boardStride,
BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s);
/* Bar areas */
CopyArea(auchBar[0], BAR_WIDTH * s * 3,
auchBoard + coord(BOARD_WIDTH / 2 - BAR_WIDTH / 2, BORDER_HEIGHT + CUBE_HEIGHT), boardStride,
BAR_WIDTH * s, (POINT_HEIGHT - CUBE_HEIGHT) * s);
CopyArea(auchBar[1], BAR_WIDTH * s * 3,
auchBoard + coord(BOARD_WIDTH / 2 - BAR_WIDTH / 2, BOARD_HEIGHT / 2 + BOARD_CENTER_HEIGHT / 2), boardStride,
BAR_WIDTH * s, (POINT_HEIGHT - CUBE_HEIGHT) * s);
for (i = 1; i <= 5; i++)
{
for (j = 0; j < 2; j++)
{ /* 1-5 chequers, both colours, down point */
RefractBlend(auchPoint[0][0][j] + coordStride(0, CHEQUER_HEIGHT * (i - 1), POINT_WIDTH * s * 3), POINT_WIDTH * s * 3,
auchBoard + coord(BEAROFF_WIDTH, BORDER_HEIGHT + CHEQUER_HEIGHT * (i - 1)), boardStride,
auchChequer[j], CHEQUER_WIDTH * s * 4,
asRefract[j], CHEQUER_WIDTH * s,
CHEQUER_WIDTH * s, CHEQUER_HEIGHT * s);
sprintf(pchFile, "b-gd-%c%d.png", j ? 'o' : 'x', i);
WriteImageStride(auchPoint[0][0][j], POINT_WIDTH * s * 3, POINT_WIDTH * s, POINT_HEIGHT * s);
}
for (j = 0; j < 2; j++)
{ /* 1-5 chequers, both colours, other down point */
RefractBlend(auchPoint[1][0][j] + coordStride(0, CHEQUER_HEIGHT * (i - 1), POINT_WIDTH * s * 3), POINT_WIDTH * s * 3,
auchBoard + coord(BEAROFF_WIDTH + POINT_WIDTH, BORDER_HEIGHT + CHEQUER_HEIGHT * (i - 1)), boardStride,
auchChequer[j], CHEQUER_WIDTH * s * 4,
asRefract[j], CHEQUER_WIDTH * s,
CHEQUER_WIDTH * s, CHEQUER_HEIGHT * s);
sprintf(pchFile, "b-rd-%c%d.png", j ? 'o' : 'x', i);
WriteImageStride(auchPoint[1][0][j], POINT_WIDTH * s * 3, POINT_WIDTH * s, POINT_HEIGHT * s);
}
for (j = 0; j < 2; j++)
{ /* 1-5 chequers, both colours, up point */
RefractBlend(auchPoint[0][1][j] + coordStride(0, CHEQUER_HEIGHT * (5 - i), POINT_WIDTH * s * 3), POINT_WIDTH * s * 3,
auchBoard + coord(BEAROFF_WIDTH + POINT_WIDTH, BOARD_HEIGHT - BORDER_HEIGHT - CHEQUER_HEIGHT * i), boardStride,
auchChequer[j], CHEQUER_WIDTH * s * 4,
asRefract[j], CHEQUER_WIDTH * s,
CHEQUER_WIDTH * s, CHEQUER_HEIGHT * s);
sprintf(pchFile, "b-gu-%c%d.png", j ? 'o' : 'x', i);
WriteImageStride(auchPoint[0][1][j], POINT_WIDTH * s * 3, POINT_WIDTH * s, POINT_HEIGHT * s);
}
for (j = 0; j < 2; j++)
{ /* 1-5 chequers, both colours, other up point */
RefractBlend(auchPoint[1][1][j] + coordStride(0, CHEQUER_HEIGHT * (5 - i), POINT_WIDTH * s * 3), POINT_WIDTH * s * 3,
auchBoard + coord(BEAROFF_WIDTH, BOARD_HEIGHT - BORDER_HEIGHT - CHEQUER_HEIGHT * i), boardStride,
auchChequer[j], CHEQUER_WIDTH * s * 4,
asRefract[j], CHEQUER_WIDTH * s,
CHEQUER_WIDTH * s, CHEQUER_HEIGHT * s);
sprintf(pchFile, "b-ru-%c%d.png", j ? 'o' : 'x', i);
WriteImageStride(auchPoint[1][1][j], POINT_WIDTH * s * 3, POINT_WIDTH * s, POINT_HEIGHT * s);
}
/* 1-5 chequers in bear-off trays */
RefractBlend(auchOff[0] + coordStride(BORDER_WIDTH, CHEQUER_HEIGHT * (i - 1), BEAROFF_WIDTH * s * 3), BEAROFF_WIDTH * s * 3,
auchBoard + coord(BOARD_WIDTH - BORDER_WIDTH - CHEQUER_WIDTH, BORDER_HEIGHT + CHEQUER_HEIGHT * (i - 1)), boardStride,
auchChequer[0], CHEQUER_WIDTH * s * 4,
asRefract[0], CHEQUER_WIDTH * s,
CHEQUER_WIDTH * s, CHEQUER_HEIGHT * s);
sprintf(pchFile, "b-roff-x%d.png", i);
WriteImageStride(auchOff[0], BEAROFF_WIDTH * s * 3, BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s);
RefractBlend(auchOff[1] + coordStride(BORDER_WIDTH, CHEQUER_HEIGHT * (5 - i), BEAROFF_WIDTH * s * 3), BEAROFF_WIDTH * s * 3,
auchBoard + coord(BOARD_WIDTH - BORDER_WIDTH - CHEQUER_WIDTH, BOARD_HEIGHT - BORDER_HEIGHT - CHEQUER_HEIGHT * i), boardStride,
auchChequer[1], CHEQUER_WIDTH * s * 4,
asRefract[1], CHEQUER_WIDTH * s,
CHEQUER_WIDTH * s, CHEQUER_HEIGHT * s);
sprintf(pchFile, "b-roff-o%d.png", i);
WriteImageStride(auchOff[1], BEAROFF_WIDTH * s * 3, BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s);
}
for (i = 6; i <= 15; i++)
{
for (j = 0; j < 2; j++)
{ /* 6-15 chequers, both colours, down point */
CopyArea(auchPoint[0][0][j] + coordStride(1, CHEQUER_HEIGHT * 4 + 1, POINT_WIDTH * s * 3), POINT_WIDTH * s * 3,
auchChequerLabels + coordStride(0, (i - 4) * CHEQUER_LABEL_HEIGHT, CHEQUER_LABEL_WIDTH * s * 3), CHEQUER_LABEL_WIDTH * s * 3,
CHEQUER_LABEL_WIDTH * s, CHEQUER_LABEL_HEIGHT * s);
sprintf(pchFile, "b-gd-%c%d.png", j ? 'o' : 'x', i);
WriteImageStride(auchPoint[0][0][j], POINT_WIDTH * s * 3, POINT_WIDTH * s, POINT_HEIGHT * s);
}
for (j = 0; j < 2; j++)
{ /* 6-15 chequers, both colours, other down point */
CopyArea(auchPoint[1][0][j] + coordStride(1, CHEQUER_HEIGHT * 4 + 1, POINT_WIDTH * s * 3), POINT_WIDTH * s * 3,
auchChequerLabels + coordStride(0, (i - 4) * CHEQUER_LABEL_HEIGHT, CHEQUER_LABEL_WIDTH * s * 3), CHEQUER_LABEL_WIDTH * s * 3,
CHEQUER_LABEL_WIDTH * s, CHEQUER_LABEL_HEIGHT * s);
sprintf(pchFile, "b-rd-%c%d.png", j ? 'o' : 'x', i);
WriteImageStride(auchPoint[1][0][j], POINT_WIDTH * s * 3, POINT_WIDTH * s, POINT_HEIGHT * s);
}
for (j = 0; j < 2; j++)
{ /* 6-15 chequers, both colours, up point */
CopyArea(auchPoint[0][1][j] + coordStride(1, 1, POINT_WIDTH * s * 3), POINT_WIDTH * s * 3,
auchChequerLabels + coordStride(0, (i - 4) * CHEQUER_LABEL_HEIGHT, CHEQUER_LABEL_WIDTH * s * 3), CHEQUER_LABEL_WIDTH * s * 3,
CHEQUER_LABEL_WIDTH * s, CHEQUER_LABEL_HEIGHT * s);
sprintf(pchFile, "b-gu-%c%d.png", j ? 'o' : 'x', i);
WriteImageStride(auchPoint[0][1][j], POINT_WIDTH * s * 3, POINT_WIDTH * s, POINT_HEIGHT * s);
}
for (j = 0; j < 2; j++)
{ /* 6-15 chequers, both colours, other up point */
CopyArea(auchPoint[1][1][j] + coordStride(1, 1, POINT_WIDTH * s * 3), POINT_WIDTH * s * 3,
auchChequerLabels + coordStride(0, (i - 4) * CHEQUER_LABEL_HEIGHT, CHEQUER_LABEL_WIDTH * s * 3), CHEQUER_LABEL_WIDTH * s * 3,
CHEQUER_LABEL_WIDTH * s, CHEQUER_LABEL_HEIGHT * s);
sprintf(pchFile, "b-ru-%c%d.png", j ? 'o' : 'x', i);
WriteImageStride(auchPoint[1][1][j], POINT_WIDTH * s * 3, POINT_WIDTH * s, POINT_HEIGHT * s);
}
/* 6-15 chequers in bear-off trays */
CopyArea(auchOff[0] + coordStride(CHEQUER_LABEL_WIDTH, CHEQUER_HEIGHT * 4 + 1, BEAROFF_WIDTH * s * 3), BEAROFF_WIDTH * s * 3,
auchChequerLabels + coordStride(0, (i - 4) * CHEQUER_LABEL_HEIGHT, CHEQUER_LABEL_WIDTH * s * 3), CHEQUER_LABEL_WIDTH * s * 3,
CHEQUER_LABEL_WIDTH * s, CHEQUER_LABEL_HEIGHT * s);
sprintf(pchFile, "b-roff-x%d.png", i);
WriteImageStride(auchOff[0], BEAROFF_WIDTH * s * 3, BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s);
CopyArea(auchOff[1] + coordStride(CHEQUER_LABEL_WIDTH, 1, BEAROFF_WIDTH * s * 3), BEAROFF_WIDTH * s * 3,
auchChequerLabels + coordStride(0, (i - 4) * CHEQUER_LABEL_HEIGHT, CHEQUER_LABEL_WIDTH * s * 3), CHEQUER_LABEL_WIDTH * s * 3,
CHEQUER_LABEL_WIDTH * s, CHEQUER_LABEL_HEIGHT * s);
sprintf(pchFile, "b-roff-o%d.png", i);
WriteImageStride(auchOff[1], BEAROFF_WIDTH * s * 3, BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s);
}
/* 0-15 chequers on bar */
WriteStride("b-bar-o0.png", auchBar[0], BAR_WIDTH * s * 3, BAR_WIDTH * s, (POINT_HEIGHT - CUBE_HEIGHT) * s);
WriteStride("b-bar-x0.png", auchBar[1], BAR_WIDTH * s * 3, BAR_WIDTH * s, (POINT_HEIGHT - CUBE_HEIGHT) * s);
for (i = 1; i <= 3; i++)
{
RefractBlend(auchBar[0] + coordStride(BAR_WIDTH / 2 - CHEQUER_WIDTH / 2, (CHEQUER_HEIGHT + 1) * (3 - i) + 1, BAR_WIDTH * s * 3), BAR_WIDTH * s * 3,
auchBoard + coord(BOARD_WIDTH / 2 - CHEQUER_WIDTH / 2, (BORDER_HEIGHT + CUBE_HEIGHT) + (CHEQUER_HEIGHT + 1) * (3 - i)), boardStride,
auchChequer[0], CHEQUER_WIDTH * s * 4,
asRefract[0], CHEQUER_WIDTH * s,
CHEQUER_WIDTH * s, CHEQUER_HEIGHT * s);
sprintf(pchFile, "b-bar-o%d.png", i);
WriteImageStride(auchBar[0], BAR_WIDTH * s * 3, BAR_WIDTH * s, (POINT_HEIGHT - CUBE_HEIGHT) * s);
RefractBlend(auchBar[1] + coordStride(BAR_WIDTH / 2 - CHEQUER_WIDTH / 2, (CHEQUER_HEIGHT + 1) * (i - 1) + 1, BAR_WIDTH * s * 3), BAR_WIDTH * s * 3,
auchBoard + coord(BOARD_WIDTH / 2 - CHEQUER_WIDTH / 2, (BOARD_HEIGHT / 2 + BOARD_CENTER_HEIGHT / 2) + (CHEQUER_HEIGHT + 1) * (i - 1)), boardStride,
auchChequer[1], CHEQUER_WIDTH * s * 4,
asRefract[1], CHEQUER_WIDTH * s,
CHEQUER_WIDTH * s, CHEQUER_HEIGHT * s);
sprintf(pchFile, "b-bar-x%d.png", i);
WriteImageStride(auchBar[1], BAR_WIDTH * s * 3, BAR_WIDTH * s, (POINT_HEIGHT - CUBE_HEIGHT) * s);
}
for (i = 4; i <= 15; i++)
{
CopyArea(auchBar[0] + coordStride(CHEQUER_LABEL_WIDTH, 2, BAR_WIDTH * s * 3), BAR_WIDTH * s * 3,
auchChequerLabels + coordStride(0, (i - 4) * CHEQUER_LABEL_HEIGHT, CHEQUER_LABEL_WIDTH * s * 3), CHEQUER_LABEL_WIDTH * s * 3,
CHEQUER_LABEL_WIDTH * s, CHEQUER_LABEL_HEIGHT * s);
sprintf(pchFile, "b-bar-o%d.png", i);
WriteImageStride(auchBar[0], BAR_WIDTH * s * 3, BAR_WIDTH * s, (POINT_HEIGHT - CUBE_HEIGHT) * s);
CopyArea(auchBar[1] + coordStride(CHEQUER_LABEL_WIDTH, POINT_HEIGHT - CUBE_HEIGHT - CHEQUER_HEIGHT, BAR_WIDTH * s * 3), BAR_WIDTH * s * 3,
auchChequerLabels + coordStride(0, (i - 4) * CHEQUER_LABEL_HEIGHT, CHEQUER_LABEL_WIDTH * s * 3), CHEQUER_LABEL_WIDTH * s * 3,
CHEQUER_LABEL_WIDTH * s, CHEQUER_LABEL_HEIGHT * s);
sprintf(pchFile, "b-bar-x%d.png", i);
WriteImageStride(auchBar[1], BAR_WIDTH * s * 3, BAR_WIDTH * s, (POINT_HEIGHT - CUBE_HEIGHT) * s);
}
/* cube - top and bottom of bar */
for (i = 0; i < 2; i++)
{
int offset;
int cube_y = i ? ((BOARD_HEIGHT - BORDER_HEIGHT) * s - CUBE_HEIGHT * ss) : (BORDER_HEIGHT * s);
AlphaBlendBase(auchBoard + (BOARD_WIDTH / 2) * s * 3 - (CUBE_WIDTH / 2) * ss * 3 +
cube_y * boardStride, boardStride,
auchBoard + (BOARD_WIDTH / 2) * s * 3 - (CUBE_WIDTH / 2) * ss * 3 +
cube_y * boardStride, boardStride,
auchCube, CUBE_WIDTH * ss * 4,
CUBE_WIDTH * ss, CUBE_HEIGHT * ss);
offset = i ? coord(BOARD_WIDTH / 2 - BAR_WIDTH / 2, BOARD_HEIGHT - BORDER_HEIGHT - CUBE_HEIGHT)
: coord(BOARD_WIDTH / 2 - BAR_WIDTH / 2, BORDER_HEIGHT);
for (j = 0; j < 12; j++)
{
CopyAreaRotateClip(auchBoard, boardStride,
(BOARD_WIDTH / 2) * s - (CUBE_WIDTH / 2) * ss + ss, cube_y + ss,
BOARD_WIDTH * s, BOARD_HEIGHT * s,
auchCubeFaces, CUBE_LABEL_WIDTH * ss * 3,
0, CUBE_LABEL_HEIGHT * ss * j,
ss * CUBE_LABEL_WIDTH, ss * CUBE_LABEL_HEIGHT,
2 - 2 * i);
sprintf(pchFile, "b-%s-%d.png", i ? "cb" : "ct", 2 << j);
WriteImage(auchBoard + offset, BAR_WIDTH * s, CUBE_HEIGHT * s);
if (j == 5)
{ /* 64 cube is also the cube for 1 */
sprintf(pchFile, "b-%sc-1.png", i ? "cb" : "ct");
WriteImage(auchBoard + offset, BAR_WIDTH * s, CUBE_HEIGHT * s);
}
}
}
/* cube - doubles */
for (i = 0; i < 2; i++)
{
int offset;
CopyArea(auchMidBoard, BOARD_CENTER_WIDTH * s * 3,
auchBoard + coord(i ? BOARD_WIDTH / 2 + BAR_WIDTH / 2 : BEAROFF_WIDTH, BOARD_HEIGHT / 2 - BOARD_CENTER_HEIGHT / 2), boardStride,
BOARD_CENTER_WIDTH * s, BOARD_CENTER_HEIGHT * s);
offset = ((BOARD_CENTER_HEIGHT / 2) * s - (CUBE_HEIGHT / 2) * ss) * BOARD_CENTER_WIDTH * s * 3 +
3 * POINT_WIDTH * s * 3 - (CUBE_WIDTH / 2) * ss * 3;
AlphaBlendBase(auchMidBoard + offset, BOARD_CENTER_WIDTH * s * 3,
auchMidBoard + offset, BOARD_CENTER_WIDTH * s * 3,
auchCube, CUBE_WIDTH * ss * 4,
CUBE_WIDTH * ss, CUBE_HEIGHT * ss);
for (j = 0; j < 12; j++)
{
CopyAreaRotateClip( auchMidBoard, BOARD_CENTER_WIDTH * s * 3,
POINT_WIDTH * s * 3 - ss * CUBE_LABEL_WIDTH / 2,
(BOARD_CENTER_HEIGHT / 2) * s - (CUBE_LABEL_HEIGHT / 2) * ss,
BOARD_CENTER_WIDTH * s, BOARD_CENTER_HEIGHT * s,
auchCubeFaces, CUBE_LABEL_WIDTH * ss * 3,
0, CUBE_LABEL_HEIGHT * ss * j,
ss * CUBE_LABEL_WIDTH, ss * CUBE_LABEL_HEIGHT,
i << 1);
sprintf(pchFile, "b-mid%c-c%d.png", i ? 'r' : 'l', 2 << j);
WriteImageStride(auchMidBoard, BOARD_CENTER_WIDTH * s * 3,
BOARD_CENTER_WIDTH * s, BOARD_CENTER_HEIGHT * s);
}
}
/* cube - centered */
AlphaBlendBase( auchBoard +
((BOARD_HEIGHT / 2) * s - (CUBE_HEIGHT / 2) * ss) * boardStride +
(BOARD_WIDTH / 2) * s * 3 - (CUBE_WIDTH / 2) * ss * 3,
boardStride,
auchBoard +
((BOARD_HEIGHT / 2) * s - (CUBE_HEIGHT / 2) * ss) * boardStride +
(BOARD_WIDTH / 2) * s * 3 - (CUBE_WIDTH / 2) * ss * 3,
boardStride,
auchCube, CUBE_WIDTH * ss *4 ,
CUBE_WIDTH * ss, CUBE_HEIGHT * ss );
for (j = 0; j < 12; j++)
{
CopyAreaRotateClip(auchBoard, boardStride,
(BOARD_WIDTH / 2) * s - (CUBE_WIDTH / 2) * ss + ss,
(BOARD_HEIGHT / 2) * s - (CUBE_HEIGHT / 2) * ss + ss,
BOARD_WIDTH * s, BOARD_HEIGHT * s,
auchCubeFaces, CUBE_LABEL_WIDTH * ss * 3,
0, CUBE_LABEL_HEIGHT * ss * j,
CUBE_LABEL_WIDTH * ss, CUBE_LABEL_HEIGHT * ss,
1);
sprintf(pchFile, "b-midc-%d.png", 2 << j);
WriteImage(auchBoard + coord((BOARD_WIDTH / 2) - (BAR_WIDTH / 2), ((BOARD_HEIGHT / 2) - (BOARD_CENTER_HEIGHT / 2))),
BAR_WIDTH * s, BOARD_CENTER_HEIGHT * s);
if (j == 5)
{ /* 64 cube is also the cube for 1 */
Write("b-midc-1.png", auchBoard + coord((BOARD_WIDTH / 2) - (BAR_WIDTH / 2), ((BOARD_HEIGHT / 2) - (BOARD_CENTER_HEIGHT / 2))),
BAR_WIDTH * s, BOARD_CENTER_HEIGHT * s);
}
}
/* dice rolls */
for (i = 0; i < 2; i++)
{
int dice_x = (BEAROFF_WIDTH + 3 * POINT_WIDTH +
(6 * POINT_WIDTH + BAR_WIDTH) * i) * s * 3
- (DIE_WIDTH / 2) * ss * 3;
int dice_y = ((BOARD_HEIGHT / 2) * s - (DIE_HEIGHT / 2) * ss) * boardStride;
AlphaBlendBase(auchBoard + dice_x - DIE_WIDTH * ss * 3 + dice_y, boardStride,
auchBoard + dice_x - DIE_WIDTH * ss * 3 + dice_y, boardStride,
auchDice[i], DIE_WIDTH * ss * 4,
DIE_WIDTH * ss, DIE_HEIGHT * ss);
AlphaBlendBase(auchBoard + dice_x + DIE_WIDTH * ss * 3 + dice_y, boardStride,
auchBoard + dice_x + DIE_WIDTH * ss * 3 + dice_y, boardStride,
auchDice[i], DIE_WIDTH * ss * 4,
DIE_WIDTH * ss, DIE_HEIGHT * ss);
for( j = 0; j < 6; j++ )
{
for( k = 0; k < 6; k++ )
{
CopyArea(auchMidBoard, BOARD_CENTER_WIDTH * s * 3,
auchBoard + coord(i ? BOARD_WIDTH / 2 + BAR_WIDTH / 2 : BEAROFF_WIDTH, BORDER_HEIGHT + POINT_HEIGHT), boardStride,
BOARD_CENTER_WIDTH * s, BOARD_CENTER_HEIGHT * s);
DrawPips(auchMidBoard + 3 * POINT_WIDTH * s * 3
- (DIE_WIDTH / 2) * ss * 3 - DIE_WIDTH * ss * 3
+ ((BOARD_CENTER_HEIGHT / 2) * s - (DIE_HEIGHT / 2) * ss )
* BOARD_CENTER_WIDTH * s * 3, BOARD_CENTER_WIDTH * s * 3,
auchPips[i], j + 1);
DrawPips(auchMidBoard + 3 * POINT_WIDTH * s * 3
- (DIE_WIDTH / 2) * ss * 3 + DIE_WIDTH * ss * 3
+ ((BOARD_CENTER_HEIGHT / 2) * s - (DIE_HEIGHT / 2) * ss )
* BOARD_CENTER_WIDTH * s * 3, BOARD_CENTER_WIDTH * s * 3,
auchPips[i], k + 1);
sprintf(pchFile, "b-mid%c-%c%d%d.png", i ? 'r' : 'l', i ? 'o' : 'x', j + 1, k + 1);
WriteImageStride(auchMidBoard, BOARD_CENTER_WIDTH * s * 3,
BOARD_CENTER_WIDTH * s, BOARD_CENTER_HEIGHT * s);
}
}
}
if (imagesWritten != NUM_IMAGES)
g_print("Wrong number of images generated - %d written, expected %d\n",
imagesWritten, NUM_IMAGES);
}
static void RenderObjects()
{
int clockwise;
renderdata rd;
CopyAppearance(&rd);
rd.fLabels = TRUE;
rd.nSize = s;
RenderBoard( &rd, auchBoard, boardStride );
RenderChequers( &rd, auchChequer[ 0 ], auchChequer[ 1 ], asRefract[ 0 ],
asRefract[ 1 ], CHEQUER_WIDTH * s * 4 );
RenderChequerLabels( &rd, auchChequerLabels, CHEQUER_LABEL_WIDTH * s * 3 );
#if HAVE_LIBART
RenderArrows( &rd, auchArrow[0], auchArrow[1], s * ARROW_WIDTH * 4 );
#endif /* HAVE_LIBART */
/* Render numbers in both directions */
clockwise = rd.fClockwise;
rd.fClockwise = TRUE;
RenderBoardLabels(&rd, auchLo, auchHi, BOARD_WIDTH * s * 4);
rd.fClockwise = FALSE;
RenderBoardLabels(&rd, auchLoRev, auchHiRev, BOARD_WIDTH * s * 4);
rd.fClockwise = clockwise;
/* cubes and dices are rendered a bit smaller */
rd.nSize = ss;
RenderCube( &rd, auchCube, CUBE_WIDTH * ss * 4 );
RenderCubeFaces( &rd, auchCubeFaces, CUBE_LABEL_WIDTH * ss * 3, auchCube, CUBE_WIDTH * ss * 4 );
RenderDice( &rd, auchDice[ 0 ], auchDice[ 1 ], DIE_WIDTH * ss * 4 );
RenderPips( &rd, auchPips[ 0 ], auchPips[ 1 ], ss * 3 );
}
static char* GetFilenameBase(char* sz)
{
sz = NextToken( &sz );
if( !sz || !*sz )
{
outputf( _("You must specify a file to export to (see `%s')\n" ),
"help export htmlimages" );
return 0;
}
if( mkdir( sz
#ifndef WIN32
, 0777
#endif
) < 0 && errno != EEXIST )
{
outputerr ( sz );
return 0;
}
szFile = malloc( strlen( sz ) + 32 );
strcpy( szFile, sz );
if( szFile[ strlen( szFile ) - 1 ] != '/' )
strcat( szFile, "/" );
pchFile = strchr(szFile, 0);
return szFile;
}
static void AllocObjects()
{
int i, j, k;
s = exsExport.nHtmlSize;
auchMidlb = malloc((BOARD_WIDTH * s * 3 * BOARD_HEIGHT * s) * sizeof(char));
#if HAVE_LIBART
for (i = 0; i < 2; i++)
auchArrow[i] = art_new( art_u8, s * ARROW_WIDTH * 4 * s * ARROW_HEIGHT );
#endif
auchBoard = malloc((BOARD_WIDTH * s * 3 * BOARD_HEIGHT * s) * sizeof(char));
for (i = 0; i < 2; i++)
auchChequer[i] = malloc((CHEQUER_WIDTH * s * 4 * CHEQUER_HEIGHT * s) * sizeof(char));
auchChequerLabels = malloc((12 * CHEQUER_LABEL_WIDTH * s * 3 * CHEQUER_LABEL_HEIGHT * s) * sizeof(char));
auchLo = malloc((BOARD_WIDTH * s * 4 * BORDER_HEIGHT * s) * sizeof(char));
auchHi = malloc((BOARD_WIDTH * s * 4 * BORDER_HEIGHT * s) * sizeof(char));
auchLoRev = malloc((BOARD_WIDTH * s * 4 * BORDER_HEIGHT * s) * sizeof(char));
auchHiRev = malloc((BOARD_WIDTH * s * 4 * BORDER_HEIGHT * s) * sizeof(char));
auchCube = malloc((CUBE_WIDTH * ss * 4 * CUBE_HEIGHT * ss) * sizeof(char));
auchCubeFaces = malloc((12 * CUBE_LABEL_WIDTH * ss * 3 * CUBE_LABEL_HEIGHT * ss) * sizeof(char));
for (i = 0; i < 2; i++)
{
auchDice[i] = malloc((DIE_WIDTH * ss * 4 * DIE_HEIGHT * ss) * sizeof(char));
auchPips[i] = malloc((ss * ss * 3) * sizeof(char));
}
auchLabel = malloc((BOARD_WIDTH * s * 3 * BOARD_HEIGHT * s) * sizeof(char));
for (i = 0; i < 2; i++)
auchOff[i] = malloc((BEAROFF_WIDTH * s * 3 * DISPLAY_BEAROFF_HEIGHT * s) * sizeof(char));
auchMidBoard = malloc((BOARD_CENTER_WIDTH * s * 3 * BOARD_CENTER_HEIGHT * s) * sizeof(char));
for (i = 0; i < 2; i++)
auchBar[i] = malloc((BAR_WIDTH * s * 3 * (POINT_HEIGHT - CUBE_HEIGHT) * s) * sizeof(char));
for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++)
for (k = 0; k < 2; k++)
auchPoint[i][j][k] = malloc((POINT_WIDTH * s * 3 * DISPLAY_POINT_HEIGHT * s) * sizeof(char));
for (i = 0; i < 2; i++)
asRefract[i] = malloc((CHEQUER_WIDTH * s * CHEQUER_HEIGHT * s) * sizeof(short));
}
static void TidyObjects()
{
int i, j, k;
free(auchMidlb);
#if HAVE_LIBART
for (i = 0; i < 2; i++)
art_free( auchArrow[ i ] );
#endif /* HAVE_LIBART */
free(szFile);
free(auchBoard);
for (i = 0; i < 2; i++)
free(auchChequer[i]);
free(auchChequerLabels);
free(auchLo);
free(auchHi);
free(auchLoRev);
free(auchHiRev);
free(auchCube);
free(auchCubeFaces);
for (i = 0; i < 2; i++)
{
free(auchDice[i]);
free(auchPips[i]);
}
free(auchLabel);
for (i = 0; i < 2; i++)
free(auchOff[i]);
free(auchMidBoard);
for (i = 0; i < 2; i++)
free(auchBar[i]);
for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++)
for (k = 0; k < 2; k++)
free(auchPoint[i][j][k]);
for (i = 0; i < 2; i++)
free(asRefract[i]);
}
extern void CommandExportHTMLImages( char *sz )
{
szFile = GetFilenameBase(sz);
if (!szFile)
return;
ProgressStartValue(_("Generating image:"), NUM_IMAGES);
AllocObjects();
RenderObjects();
WriteImages();
ProgressEnd();
TidyObjects();
}
#else /* not HAVE_LIBPNG */
extern void CommandExportHTMLImages( char *sz )
{
outputl( _("This installation of GNU Backgammon was compiled without\n"
"support for writing HTML images.") );
}
#endif /* not HAVE_LIBPNG */