On 7/15/07, Øystein Johansen <[EMAIL PROTECTED]> wrote:
I've earlier suggested that the export to graphic formats
should be rewritten and based on cairo.
http://lists.gnu.org/archive/html/bug-gnubg/2007-04/msg00053.html
I don't think I have motivation to write in this right now. (or maybe.... maybe
I feel some motivation ..... I'm visitiong my parents now, let me have a look
when I'm back home. OK? Warning: I may lose any motivation by then....)
-Øystein
Hi Øystein,
I played a bit with designing a cairo board back then, but got tired
of it. I'm attaching the code to get you started ;)
compile with
gcc board.c main.c -o board `pkg-config --cflags --libs gtk+-2.0`
Christian.
/**
* board.c
*
* A GTK+ widget that implements a backgammon board
*
*/
#include <gtk/gtk.h>
#include <math.h>
#include "board.h"
G_DEFINE_TYPE(BgBoard, bg_board, GTK_TYPE_DRAWING_AREA);
static gboolean bg_board_expose(GtkWidget * board,
GdkEventExpose * event);
static void bg_board_class_init(BgBoardClass * class)
{
GtkWidgetClass *widget_class;
widget_class = GTK_WIDGET_CLASS(class);
widget_class->expose_event = bg_board_expose;
}
static void bg_board_init(BgBoard * board)
{
}
static get_point_base(int i, int *x, int *y, int *direction)
{
if (i < 7) {
*x = 220 + (6 - i) * 20;
*y = 320;
*direction = -1;
} else if (i < 13) {
*x = 80 + (12 - i) * 20;
*y = 320;
*direction = -1;
} else if (i < 19) {
*x = 80 + (i - 13) * 20;
*y = 80;
*direction = 1;
} else if (i < 25) {
*x = 220 + (i - 19) * 20;
*y = 80;
*direction = 1;
} else {
g_assert_not_reached();
}
}
static void draw_text(cairo_t * cr, int x, int y, double f, double size,
const gchar * text)
{
PangoLayout *layout;
PangoFontDescription *desc;
gchar font_size[200];
g_ascii_formatd(font_size, sizeof(font_size), "%.1f", f * size);
gchar *font_name = g_strdup_printf("Sans %s", font_size);
int i;
int width, height;
/* Create a PangoLayout, set the font and text */
layout = pango_cairo_create_layout(cr);
pango_layout_set_text(layout, text, -1);
desc = pango_font_description_from_string(font_name);
pango_layout_set_font_description(layout, desc);
pango_font_description_free(desc);
pango_layout_get_size(layout, &width, &height);
cairo_move_to(cr, (x * f - width / 2.0 / PANGO_SCALE),
(y * f - height / 2.0 / PANGO_SCALE));
pango_cairo_show_layout(cr, layout);
cairo_stroke(cr);
g_object_unref(layout);
}
static void draw_point(cairo_t * cr, double f, int i)
{
int x, y, direction;
int even_point;
double point_color;
get_point_base(i, &x, &y, &direction);
even_point = (i % 2);
point_color = 1.0 - (double) even_point / 2.0;
cairo_save(cr);
cairo_translate(cr, x * f, y * f);
cairo_move_to(cr, -10 * f, 0);
cairo_line_to(cr, 0, direction * 100 * f);
cairo_line_to(cr, 10 * f, 0);
cairo_close_path(cr);
cairo_set_source_rgb(cr, point_color, point_color, point_color);
cairo_fill_preserve(cr);
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_stroke(cr);
cairo_move_to(cr, 0, 0);
draw_text(cr, 0, -10 * direction, f, 9.0,
g_strdup_printf("%d", i));
cairo_restore(cr);
}
static void draw_cube(cairo_t * cr, double f, int i)
{
int y;
y = (i + 1) * 110 + 82;
cairo_rectangle(cr, 192 * f, y * f, 16 * f, 16 * f);
draw_text(cr, 200, y + 8, f, 9.0, "64");
cairo_stroke(cr);
}
static void draw_turn(cairo_t * cr, double f, int i)
{
cairo_rectangle(cr, 58 * f, 185 * f, 4 * f, 16 * f);
cairo_fill(cr);
cairo_move_to(cr, 53 * f, 201 * f);
cairo_line_to(cr, 60 * f, 215 * f);
cairo_line_to(cr, 67 * f, 201 * f);
cairo_close_path(cr);
cairo_fill(cr);
}
static void draw_checker(cairo_t * cr, double f, int player, int point, int c)
{
int i, x, y, direction, p;
g_return_if_fail( c > 0 && c < 16);
get_point_base(point, &x, &y, &direction);
y -= 10*direction;
for (p=0;c > 0 && p<5; c--,p++)
{
y += 20*direction;
cairo_arc(cr, x*f, y*f, 10*f, 0, 2*M_PI);
cairo_set_source_rgb(cr, 1, 1, 1);
cairo_fill_preserve(cr);
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_stroke(cr);
}
if (c)
draw_text(cr, x, y, f, 8.0, g_strdup_printf("%d", c+5));
}
static void draw_checkers(cairo_t * cr, double f)
{
int board[2][25] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};
int player, point, c;
for (player = 0; player < 2; player++) {
for (point = 0; point < 25; point++) {
board[player][point] = 15;
if (c = board[player][point])
draw_checker(cr, f, player, point, c);
}
}
}
static void draw_board(double x, double y, double size, cairo_t * cr)
{
int i;
double f;
f = size / 400.0;
cairo_save(cr);
cairo_set_line_width(cr, 2);
cairo_rectangle(cr, 50 * f, 60 * f, 300 * f, 280 * f);
cairo_set_source_rgb(cr, 1, 1, 1);
cairo_fill_preserve(cr);
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_rectangle(cr, 70 * f, 80 * f, 260 * f, 240 * f);
cairo_rectangle(cr, 190 * f, 80 * f, 20 * f, 240 * f);
cairo_rectangle(cr, 50 * f, 182 * f, 20 * f, 36 * f);
cairo_rectangle(cr, 330 * f, 182 * f, 20 * f, 36 * f);
cairo_stroke(cr);
for (i = 1; i < 25; i++)
draw_point(cr, f, i);
for (i = -1; i < 2; i++)
draw_cube(cr, f, i);
draw_checkers(cr, f);
draw_turn(cr, f, -1);
cairo_restore(cr);
}
static void draw(GtkWidget * board, cairo_t * cr)
{
double x, y;
double size;
x = board->allocation.x;
y = board->allocation.y;
size = MIN(board->allocation.width, board->allocation.height);
draw_board(x, y, size, cr);
}
static gboolean bg_board_expose(GtkWidget * board,
GdkEventExpose * event)
{
cairo_t *cr;
/* get a cairo_t */
cr = gdk_cairo_create(board->window);
cairo_rectangle(cr,
event->area.x, event->area.y,
event->area.width, event->area.height);
//cairo_clip(cr);
draw(board, cr);
cairo_destroy(cr);
return FALSE;
}
GtkWidget *bg_board_new(void)
{
return g_object_new(BG_TYPE_BOARD, NULL);
}
#include <gtk/gtk.h>
typedef struct _BgBoard BgBoard;
typedef struct _BgBoardClass BgBoardClass;
struct _BgBoard {
GtkDrawingArea parent;
/* private */
};
struct _BgBoardClass {
GtkDrawingAreaClass parent_class;
};
#define BG_TYPE_BOARD (bg_board_get_type ())
#define BG_BOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BG_TYPE_BOARD, BgBoard))
#define BG_BOARD_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), BG_BOARD, BgBoardClass))
#define BG_IS_BOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BG_TYPE_BOARD))
#define BG_IS_BOARD_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), BG_TYPE_BOARD))
#define BG_BOARD_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS ((obj), BG_TYPE_BOARD, BgBoardClass))
GtkWidget *bg_board_new(void);
#include "board.h"
int main(int argc, char **argv)
{
GtkWidget *window;
GtkWidget *board;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window), 400, 400);
board = bg_board_new();
gtk_container_add(GTK_CONTAINER(window), board);
g_signal_connect
(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
}
_______________________________________________
Bug-gnubg mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/bug-gnubg