4 ** member-functions for the drawgif-class
7 ** Copyright (C) 1998 Kurt Van den Branden
9 ** This program is free software; you can redistribute it and/or modify
10 ** it under the terms of the GNU General Public License as published by
11 ** the Free Software Foundation; either version 2 of the License, or
12 ** (at your option) any later version.
14 ** This program is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ** GNU General Public License for more details.
19 ** You should have received a copy of the GNU General Public License
20 ** along with this program; if not, write to the Free Software
21 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
40 #define round(x) (int)(x + 0.5)
43 // x and y-position of each first point of a column
44 // based on a square of 2.5 by 2.5
45 double gif_rowbase
[9][2] = {
47 {.6005, 2.125}, // row b
48 {.817, 2.25}, // row c
49 {1.0335, 2.375}, // row d
51 {1.4665, 2.375}, // row f
52 {1.683, 2.25}, // row g
53 {1.8995, 2.125}, // row h
56 /* lines on the board */
57 const position gif_linetable
[21][2] = {
58 {{0, 4}, {5, 8}}, {{0, 3}, {6, 7}}, {{0, 2}, {7, 6}},
59 {{0, 1}, {8, 5}}, {{1, 1}, {8, 4}}, {{2, 1}, {8, 3}},
60 {{3, 1}, {8, 2}}, {{0, 2}, {5, 1}}, {{0, 3}, {6, 1}},
61 {{0, 4}, {7, 1}}, {{0, 5}, {8, 1}}, {{1, 6}, {8, 2}},
62 {{2, 7}, {8, 3}}, {{3, 8}, {8, 4}}, {{1, 6}, {1, 1}},
63 {{2, 7}, {2, 1}}, {{3, 8}, {3, 1}}, {{4, 9}, {4, 1}},
64 {{5, 8}, {5, 1}}, {{6, 7}, {6, 1}}, {{7, 6}, {7, 1}}
67 /* possible from-points */
68 const position gif_fromtable
[24] = {
69 {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {1, 6},
70 {2, 7}, {3, 8}, {4, 9}, {5, 8}, {6, 7}, {7, 6},
71 {8, 5}, {8, 4}, {8, 3}, {8, 2}, {8, 1}, {7, 1},
72 {6, 1}, {5, 1}, {4, 1}, {3, 1}, {2, 1}, {1, 1},
76 const position gif_hexagon
[7] = {
77 {1, 2}, {1, 5}, {4, 8}, {7, 5}, {7, 2}, {4, 2}, {1, 2}
103 if (extratext
!= NULL
)
105 while ((ptr
= (char *) llrembynr (extratext
, 1)) != NULL
)
115 void drawgif::filename (const char * fn
)
126 void drawgif::gifboard (board
* gb
)
137 void drawgif::addtext (const char * text
)
143 if (extratext
== NULL
)
145 extratext
= (listheader
*) malloc (sizeof (listheader
));
149 tempstr
= strdup (text
);
153 while ((kar2
= strchr (kar1
, '\n')) != NULL
)
156 pushll (extratext
, strdup (kar1
));
159 pushll (extratext
, strdup (kar1
));
191 gdFontPtr thefont
= gdFontTiny
;
193 listheader
* extralist
;
199 /* choose font according to drawing-size */
201 thefont
= gdFontTiny
;
203 thefont
= gdFontSmall
;
205 thefont
= gdFontMediumBold
;
207 thefont
= gdFontLarge
;
209 thefont
= gdFontGiant
;
212 ** find out how many extra lines have to be displayed
213 ** and split lines that are to long to fit
215 extralist
= (listheader
*) malloc (sizeof (listheader
));
217 maxchar
= size
/ thefont
->w
- 2;
219 while ((strptr
= (char *) llitembynr (extratext
, counter
)) != NULL
)
222 extralines
+= splitline (extralist
, strptr
, maxchar
);
227 image
= gdImageCreate(size
, size
+ thefont
->h
*
228 (extralines
== 0 ? 0 : extralines
+ 1));
229 gdImageInterlace(image
, 1);
231 /* all colors have been chosen to be the ones used by Netscape
232 when used in 256 color mode */
234 /* Allocate the color lgray (red, green and blue).
235 Since this is the first color in a new image, it will
236 be the background color. */
239 white
= gdImageColorAllocate(image
, 255, 255, 255);
240 black
= gdImageColorAllocate(image
, 0, 0, 0);
245 lgray
= gdImageColorAllocate(image
, 204, 204, 204);
247 /* Allocate the color black (red, green and blue). */
256 white
= gdImageColorAllocate(image
, 255, 255, 255);
257 black
= gdImageColorAllocate(image
, 0, 0, 0);
258 yellow
= gdImageColorAllocate(image
, 255, 255, 204);
259 gray
= gdImageColorAllocate (image
, 153, 153, 153);
260 red
= gdImageColorAllocate (image
, 255, 0, 0);
263 /* the 'notused' color can be used for drawing the outline of a figure
264 you want to fill later */
265 notused
= gdImageColorAllocate (image
, 1, 1, 1);
267 /* draw rectangle around image */
268 gdImageRectangle (image
, 0, 0, size
-1, size
-1, black
);
271 for (i
= 0; i
< 6; i
++)
273 pos2coor (&gif_hexagon
[i
], hexa
[i
].x
, hexa
[i
].y
);
275 gdImageFilledPolygon(image
, hexa
, 6, white
);
277 /* draw from-points */
278 diam
= round (base
/ 12);
279 for (i
= 0; i
< 24; i
++)
281 pos2coor (&gif_fromtable
[i
], x
, y
);
286 gdImageFillToBorder(image
,
292 for (i
= 0 ; i
< 21; i
++)
294 pos2coor (&gif_linetable
[i
][0], x1
, y1
);
295 pos2coor (&gif_linetable
[i
][1], x2
, y2
);
302 /* calculate size of piece */
303 diam
= round (base
/ 6);
304 diam2
= round (base
/ 10);
306 temppos
= (position
*) malloc (sizeof (position
));
308 for (i
= 1; i
< 8; i
++)
309 for (j
= 2; j
<= b_colsize (i
); j
++)
311 posp_col (temppos
) = i
;
312 posp_row (temppos
) = j
;
314 if (b_ppiece (gipfb
, temppos
) != '.')
316 /* calculate position of center of the piece */
317 pos2coor (temppos
, x
, y
);
319 gdImageArc (image
, x
, y
, diam
, diam
, 0, 360, notused
);
320 if ((b_ppiece (gipfb
, temppos
) == 'o') ||
321 (b_ppiece (gipfb
, temppos
) == 'O'))
323 gdImageFillToBorder (image
, x
, y
, notused
, yellow
);
327 gdImageFillToBorder (image
, x
, y
, notused
, black
);
329 gdImageArc (image
, x
, y
, diam
, diam
, 0, 360, black
);
331 if ((b_ppiece (gipfb
, temppos
) == 'X') ||
332 (b_ppiece (gipfb
, temppos
) == 'O'))
336 if (b_ppiece (gipfb
, temppos
) == 'O')
342 gdImageArc (image
, x
, y
, diam2
, diam2
, 0, 360, gray
);
344 gdImageArc (image
, x
, y
, diam2
-1, diam2
-1, 0, 360,
360 while ((arr
= (arrowitem
*) llrembynr (arrowlist
, 1)) != NULL
)
362 /* calculate position */
363 x
= round (rowbase
[arr
->col
][0] * base
);
364 y
= round ((rowbase
[arr
->col
][1] - arr
->row
* .25) * base
);
366 cosa
= cos ((double) arr
->angle
* MY_PI
/ 180);
367 sina
= sin ((double) arr
->angle
* MY_PI
/ 180);
368 for (i
= 0; i
< 8; i
++)
369 { /* the 8th point is the center and used by the fill */
371 round (base8
* (arrow
[i
][0] * cosa
- arrow
[i
][1] * sina
));
373 round (base8
* (arrow
[i
][0] * sina
+ arrow
[i
][1] * cosa
));
376 gdImagePolygon (image
, rotarrow
, 7, notused
);
377 gdImageFillToBorder (image
, rotarrow
[7].x
, rotarrow
[7].y
,
379 gdImagePolygon (image
, rotarrow
, 7, black
);
386 /* draw position-names */
387 for (i
= 0; i
< 9; i
++)
389 sprintf (tempstr
, "%c1", i
+'a');
390 x
= round (gif_rowbase
[i
][0] * base
) - thefont
->w
;
391 y
= round ((gif_rowbase
[i
][1] - .125) * base
) - 3;
393 gdImageString(image
, thefont
, x
, y
, (unsigned char*)tempstr
, black
);
395 nr
= (i
< 5 ? i
+ 5 : 13 - i
);
396 sprintf (tempstr
, "%c%d", i
+'a', nr
);
397 y
= size
- round ((gif_rowbase
[i
][1] - .125) * base
) - thefont
->h
+ 3;
399 gdImageString(image
, thefont
, x
, y
, (unsigned char*)tempstr
, black
);
402 /* draw piles of available pieces */
403 pieceh
= round (base
/ 30);
404 poffset
= round (base
/ 20);
405 diam
= round (base
/ 6);
409 sprintf (tempstr
, "white: %d", b_white (gipfb
));
410 gdImageString (image
, thefont
, diam
/4, size
-texth
*2-3, (unsigned char*)tempstr
, black
);
412 offset
= size
- texth
*2 - 3;
413 for (i
= 1; i
<= b_white (gipfb
); i
++)
415 gdImageRectangle (image
,
416 diam
/2, offset
- poffset
* i
,
417 round (diam
* 1.5), offset
- poffset
* i
+ pieceh
,
419 gdImageFillToBorder (image
, diam
/2+1,
420 offset
- poffset
* i
+ 1,
423 sprintf (tempstr
, "lost : %d", b_white_lost (gipfb
));
424 gdImageString (image
, thefont
, diam
/4, size
-texth
-3, (unsigned char*)tempstr
, black
);
427 sprintf (tempstr
, "%d :black", b_black (gipfb
));
428 gdImageString (image
, thefont
,
429 size
- diam
/4 - thefont
->w
* strlen (tempstr
),
430 size
-texth
*2-3, (unsigned char*)tempstr
, black
);
432 offset
= size
- texth
*2 - 3;
433 for (i
= 1; i
<= b_black (gipfb
); i
++)
435 gdImageRectangle (image
,
436 round (size
- diam
* 1.5), offset
- poffset
* i
,
437 size
- diam
/2, offset
- poffset
* i
+ pieceh
,
439 gdImageFillToBorder (image
, size
- diam
/2 - 1,
440 offset
- poffset
* i
+ 1,
443 sprintf (tempstr
, "%d : lost", b_black_lost (gipfb
));
444 gdImageString (image
, thefont
,
445 size
- diam
/4 - thefont
->w
* strlen (tempstr
),
446 size
-texth
-3, (unsigned char*)tempstr
, black
);
450 ** (if the file is available)
452 if ((imagefp
= fopen ("small_logo.png", "rb")) != NULL
)
454 gdImagePtr loadimage
;
456 loadimage
= gdImageCreateFromPng (imagefp
);
458 if (loadimage
!= NULL
)
460 gdImageCopy(image
, loadimage
, 1, 1, 0, 0,
461 loadimage
->sx
, loadimage
->sy
);
464 gdImageDestroy (loadimage
);
468 /* draw extra lines of text */
471 gdImageFilledRectangle (image
, 0, size
, size
-1,
472 size
+ thefont
->h
* (extralines
+ 1) - 1,
474 gdImageRectangle (image
, 0, size
, size
-1,
475 size
+ thefont
->h
* (extralines
+ 1) - 1,
478 while ((strptr
= (char *) llrembynr (extralist
, 1)) != NULL
)
480 gdImageString (image
, thefont
, thefont
->w
,
481 size
+ thefont
->h
/ 2 + thefont
->h
* i
,
482 (unsigned char*)strptr
, black
);
489 gdImageColorDeallocate(image
, notused
);
491 /* open file for output */
492 fp
= fopen(filen
, "wb");
493 /* Output the image to the disk file. */
494 gdImagePng(image
, fp
);
495 /* Close the file. */
498 /* Destroy the image in memory. */
499 gdImageDestroy(image
);
506 ** the 'string' will be copied and added to 'llist'
507 ** if 'string' is longer then 'maxchar', it will be splitted
508 ** into several strings and added to 'llist'
510 ** returns: nr of strings added to 'llist'
512 int drawgif::splitline (listheader
* llist
, char * string
, int maxchar
)
521 tempstr
= strdup (string
);
523 while (strlen(kar
) > maxchar
)
525 kar2
= kar
+ maxchar
;
526 while ((kar2
> kar
) && (!isspace ((int) kar2
[0])))
531 { /* string too long to be splitted, do the dirty split */
532 savechar
= kar
[maxchar
];
533 kar2
= kar
+ maxchar
;
536 newstring
= (char *) malloc (strlen (kar
) + 1);
537 strcpy (newstring
, kar
);
538 pushll (llist
, (void *) newstring
);
543 kar
[maxchar
] = savechar
;
554 newstring
= (char *) malloc (strlen (kar
) + 1);
555 strcpy (newstring
, kar
);
556 pushll (llist
, (void *) newstring
);
565 ** calculate coordinates starting from a board-position
567 void drawgif::pos2coor (const position
*pos
, int& x
, int& y
)
569 x
= round (gif_rowbase
[pos
->col
][0] * base
);
570 y
= round ((gif_rowbase
[pos
->col
][1] - pos
->row
* .25) * base
);