1
/* This file is a part of gtkboard, a board games system.
2
Copyright (C) 2003, Arvind Narayanan <arvindn@users.sourceforge.net>
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; either version 2 of the License, or
7
(at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
28
\brief routines for generating antialiased images, primarily balls.
31
static char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8' ,
32
'9', 'A', 'B', 'C', 'D', 'E', 'F'};
35
static int pixmap_get_color(int fg, int bg, float ratio)
37
int f1, f2, f3, b1, b2, b3, w1, w2, w3;
39
if (ratio < 0) ratio = 0;
40
if (ratio > 1) ratio = 1;
41
// FIXME: could we have problems with equality of floats?
45
w2 = (fg >> 8) & 0xff;
51
w2 = (bg >> 8) & 0xff;
57
f2 = (fg >> 8) & 0xff;
60
b2 = (bg >> 8) & 0xff;
62
w1 = (1 - ratio) * f1 + (ratio) * b1;
63
w2 = (1 - ratio) * f2 + (ratio) * b2;
64
w3 = (1 - ratio) * f3 + (ratio) * b3;
65
lf = sqrt(f1 * f1 + f2 * f2 + f3 * f3);
66
lb = sqrt(b1 * b1 + b2 * b2 + b3 * b3);
67
lw = sqrt(w1 * w1 + w2 * w2 + w3 * w3);
68
lw /= ((1 - ratio) * lf + ratio * lb);
69
w1 /= lw; if (w1 > 0xff) w1 = 0xff;
70
w2 /= lw; if (w2 > 0xff) w2 = 0xff;
71
w3 /= lw; if (w3 > 0xff) w3 = 0xff;
73
return (w1 << 16) + (w2 << 8) + w3;
76
static char *pixmap_get_hex_color(int fg, int bg, float ratio)
78
int red, green, blue, val;
79
static char color[7] = { 0 };
80
val = pixmap_get_color (fg, bg, ratio);
82
green = (val >> 8) & 0xff;
84
color[0] = hex[red/16];
85
color[1] = hex[red%16];
86
color[2] = hex[green/16];
87
color[3] = hex[green%16];
88
color[4] = hex[blue/16];
89
color[5] = hex[blue%16];
93
static char *pixmap_map [256];
97
@param len = size of ball
98
@param pixbuf = buffer to store the pixmap in
99
@param fg = foreground color (color of the ball)
100
@param bg = background color (color of the square)
101
@param rad = radius of the ball
102
@param grad = gradient with which the ball merges into the backgound (larger gradient indicates sharper boundary)*/
103
char ** pixmap_ball_gen(int len, char *pixbuf, int fg, int bg, float rad, float grad)
105
char **map = pixmap_map;
107
static char colbuf[18][20];
109
for(i=0; i<18; i++) map[i] = colbuf[i];
110
g_snprintf(map[0], 20, "%d %d 16 1", len, len);
113
g_snprintf (map[i+1], 20, "%c c #%s", hex[i],
114
pixmap_get_hex_color(fg, bg, i / 15.0));
116
for (i=0; i<len; i++)
118
char *ptr = map[i+17] = buf + i * (len+1);
119
for (j=0; j<len; j++)
121
int mid = len/2, x = i - mid, y = j - mid;
122
float q = (x * x + y * y) / rad / rad;
124
if (q<1) *ptr++ = '0';else
126
if ((q >= 1 + (k-1) / grad && q < 1 + k/grad) || k == 15)
127
{ *ptr++ = hex[k]; break; }
135
static void rgbmap_ball_gen_real (int len, unsigned char *rgbbuf, int fg, float rad, float grad, float midx, float midy)
138
unsigned char *bufp = rgbbuf;
139
for (i=0; i<len; i++)
140
for (j=0; j<len; j++)
142
float x = i - midx, y = j - midy;
143
float q = (x * x + y * y) / rad / rad;
144
int bg = (bufp[0] << 16) + (bufp[1] << 8) + bufp[2];
145
int color = q < 1 ? fg : pixmap_get_color (fg, bg, (q - 1) * grad / 16);
146
*bufp++ = color >> 16;
147
*bufp++ = (color >> 8) & 0xFF;
148
*bufp++ = color & 0xFF;
152
void rgbmap_square_gen (int len, unsigned char *rgbbuf, int fg, int bg, float side)
155
unsigned char *bufp = rgbbuf;
156
for (i=0; i<len; i++)
157
for (j=0; j<len; j++)
159
float x = 2*i - len, y = 2*j - len;
163
color = x < side && y < side ? fg : bg;
164
*bufp++ = color >> 16;
165
*bufp++ = (color >> 8) & 0xFF;
166
*bufp++ = color & 0xFF;
170
void rgbmap_ball_gen (int len, unsigned char *rgbbuf, int fg, int bg, float rad, float grad)
173
unsigned char *bufp = rgbbuf;
174
for (i=0; i<len; i++)
175
for (j=0; j<len; j++)
178
*bufp++ = (bg >> 8) & 0xFF;
181
rgbmap_ball_gen_real (len, rgbbuf, fg, rad, grad, len/2, len/2);
184
//! Same as rgbmap_ball_gen but don't generate the background - i.e, overlay the ball on the existing image
185
void rgbmap_ball_gen_nobg (int len, unsigned char *rgbbuf, int fg, int bg, float rad, float grad)
187
rgbmap_ball_gen_real (len, rgbbuf, fg, rad, grad, len/2, len/2);
190
void rgbmap_ball_shadow_gen (int len, unsigned char *rgbbuf, int fg, int bg, float rad, float grad, int shadowlen)
193
unsigned char *bufp = rgbbuf;
194
int red, green, blue, lighting_color, shadow_color;
195
float shadow_factor = 0.25;
196
red = (fg >> 16) / 4 + 192;
197
green = ((fg >> 8) & 0xff) / 4 + 192;
198
blue = (fg & 0xff) / 4 + 192;
199
lighting_color = (red << 16) + (green << 8) + blue;
200
red = (fg >> 16) * shadow_factor;
201
green = ((fg >> 8) & 0xff) * shadow_factor;
202
blue = (fg & 0xff) * shadow_factor;
203
shadow_color = (red << 16) + (green << 8) + blue;
204
for (i=0; i<len; i++)
205
for (j=0; j<len; j++)
208
*bufp++ = (bg >> 8) & 0xFF;
211
rgbmap_ball_gen_real (len, rgbbuf, shadow_color, rad, grad,
212
(len + shadowlen)/2, (len + shadowlen)/2);
213
rgbmap_ball_gen_real (len, rgbbuf, lighting_color, rad, grad,
214
(len - 1.5 * shadowlen)/2, (len - 1.5 * shadowlen)/2);
215
rgbmap_ball_gen_real (len, rgbbuf, fg, rad, grad,
216
(len - shadowlen)/2, (len - shadowlen)/2);
220
//! Used if you already have the pixmap and only want to generate the header (i.e, same shape, different color)
221
char ** pixmap_header_gen(int len, char *pixbuf, int fg, int bg)
223
char **map = pixmap_map;
225
static char colbuf[18][20];
227
for(i=0; i<18; i++) map[i] = colbuf[i];
228
g_snprintf(map[0], 20, "%d %d 16 1", len, len);
231
g_snprintf (map[i+1], 20, "%c c #%s", hex[i],
232
pixmap_get_hex_color(fg, bg, i / 15.0));
234
for (i=0; i<len; i++)
235
map[i+17] = buf + i * (len+1);
242
/** Args same as pixmap_ball_gen() except num which is the number on the die */
243
char ** pixmap_die_gen(int len, char *pixbuf, int fg, int bg, float rad, float grad, int num)
245
char **map = pixmap_map;
247
static char colbuf[18][20];
254
{ 0.25, 0.25, 0.75, 0.75 },
255
{ 0.2, 0.2, 0.5, 0.8, 0.8 },
256
{ 0.25, 0.25, 0.25, 0.75, 0.75, 0.75 }
263
{ 0.25, 0.75, 0.25, 0.75 },
264
{ 0.2, 0.8, 0.5, 0.2, 0.8 },
265
{ 0.2, 0.5, 0.8, 0.2, 0.5, 0.8 }
267
for(i=0; i<18; i++) map[i] = colbuf[i];
268
g_snprintf(map[0], 20, "%d %d 16 1", len, len);
271
g_snprintf (map[i+1], 20, "%c c #%s", hex[i],
272
pixmap_get_hex_color(fg, bg, i / 15.0));
274
for (i=0; i<len; i++)
276
char *ptr = map[i+17] = buf + i * (len+1);
277
memset (ptr, 'F', len);
279
for (k=0; k<num; k++)
281
float midx = cenx[num-1][k] * len;
282
float midy = (1 - ceny[num-1][k]) * len;
283
for (j=0; j<len; j++)
285
float x = i - midx, y = j - midy;
286
float q = (x * x + y * y) / rad / rad;
288
if (q < 1) {ptr[j] = '0';}
291
if ((q >= 1 + (k-1) / grad && q < 1 + k/grad))
292
{ ptr[j] = hex[k]; break; }