From: Carl Worth Date: Wed, 25 Jun 2003 10:52:59 +0000 (+0000) Subject: grrobot will now load SVG icons from /share/grrobot/*.svg X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=f0030bb1862b023fca3914d72e1d307b64824649;p=grrobot grrobot will now load SVG icons from /share/grrobot/*.svg A default SVG icon set is now builtin so the grrobot does not rely on external files. Rendering is a bit faster, (SVG files are only parsed once). --- diff --git a/src/Makefile.am b/src/Makefile.am index 1ec102f..2e21a2e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,6 +8,8 @@ grrobot_SOURCES = \ grrobot.c \ grr_board_view.c \ grr_board_view.h \ + grr_icon.c \ + grr_icon.h \ grr_util.c \ grr_util.h diff --git a/src/grr_board_view.c b/src/grr_board_view.c index 4a3b733..f29ec9b 100644 --- a/src/grr_board_view.c +++ b/src/grr_board_view.c @@ -37,6 +37,7 @@ #include #include "grr_board_view.h" +#include "grr_icon.h" #include "grr_util.h" #define SCROLL_DELAY_LENGTH 300 @@ -45,37 +46,6 @@ #define GRR_SVG_ASSUMED_WIDTH 32.0 #define GRR_SVG_ASSUMED_HEIGHT 32.0 -#define GRR_CELL_SVG "svg/cell.svg" -#define GRR_WALL_SVG "svg/wall.svg" - -#define GRR_ROBOT_BLUE_SVG "svg/robot_blue.svg" -#define GRR_ROBOT_GREEN_SVG "svg/robot_green.svg" -#define GRR_ROBOT_RED_SVG "svg/robot_red.svg" -#define GRR_ROBOT_YELLOW_SVG "svg/robot_yellow.svg" - -#define GRR_TARGET_BLUE_CIRCLE_SVG "svg/target_blue_circle.svg" -#define GRR_TARGET_BLUE_OCTAGON_SVG "svg/target_blue_octagon.svg" -#define GRR_TARGET_BLUE_SQUARE_SVG "svg/target_blue_square.svg" -#define GRR_TARGET_BLUE_TRIANGLE_SVG "svg/target_blue_triangle.svg" - -#define GRR_TARGET_GREEN_CIRCLE_SVG "svg/target_green_circle.svg" -#define GRR_TARGET_GREEN_OCTAGON_SVG "svg/target_green_octagon.svg" -#define GRR_TARGET_GREEN_SQUARE_SVG "svg/target_green_square.svg" -#define GRR_TARGET_GREEN_TRIANGLE_SVG "svg/target_green_triangle.svg" - -#define GRR_TARGET_RED_CIRCLE_SVG "svg/target_red_circle.svg" -#define GRR_TARGET_RED_OCTAGON_SVG "svg/target_red_octagon.svg" -#define GRR_TARGET_RED_SQUARE_SVG "svg/target_red_square.svg" -#define GRR_TARGET_RED_TRIANGLE_SVG "svg/target_red_triangle.svg" - -#define GRR_TARGET_YELLOW_CIRCLE_SVG "svg/target_yellow_circle.svg" -#define GRR_TARGET_YELLOW_OCTAGON_SVG "svg/target_yellow_octagon.svg" -#define GRR_TARGET_YELLOW_SQUARE_SVG "svg/target_yellow_square.svg" -#define GRR_TARGET_YELLOW_TRIANGLE_SVG "svg/target_yellow_triangle.svg" - -#define GRR_TARGET_WHIRL_SVG "svg/target_whirl.svg" - - /* Forward declarations */ static void grr_board_view_class_init (grr_board_view_class_t *klass); @@ -153,11 +123,31 @@ grr_board_view_class_init (grr_board_view_class_t *class) static void grr_board_view_init (grr_board_view_t *view) { + int i; + rr_robot_t robot; + rr_target_t target; + view->board = NULL; view->client = NULL; view->button = 0; view->timer = 0; + + view->cell_width = 0; + view->cell_height = 0; + + view->cell_icon = grr_icon_create ("cell"); + view->wall_icon = grr_icon_create ("wall"); + + for (i=0; i < RR_NUM_ROBOTS; i++) { + robot = rr_robot_from_idx (i); + view->robot_icon[i] = grr_icon_create (grr_icon_robot_name (robot)); + } + + for (i=0; i < RR_NUM_TARGETS; i++) { + target = rr_target_from_idx (i); + view->target_icon[i] = grr_icon_create (grr_icon_target_name (target)); + } } GtkWidget* @@ -264,169 +254,55 @@ grr_board_view_size_allocate (GtkWidget *widget, } static void -grr_svg_draw (XrState *xrs, char *svg) +grr_board_view_draw_walls (grr_board_view_t *view, + XrState *xrs, + rr_wall_t wall) { - xsvg_status_t status; - xsvg_t *xsvg; - - status = xsvg_create (&xsvg); - if (status) { - fprintf (stderr, "xsvg_create error\n"); - return; - } - status = xsvg_parse_file (xsvg, svg); - if (status) { - fprintf (stderr, "xsvg_parse_file error parsing %s\n", svg); - return; - } - xsvg_render (xsvg, xrs); - if (status) { - fprintf (stderr, "xsvg_render error\n"); - return; - } - xsvg_destroy (xsvg); -} - -static void -grr_wall_draw (XrState *xrs, rr_wall_t wall) -{ - char *wall_svg = GRR_WALL_SVG; - if (wall == RR_WALL_NONE) return; if (wall & RR_WALL_ABOVE) { - grr_svg_draw (xrs, wall_svg); + grr_icon_draw (view->wall_icon, xrs); } if (wall & RR_WALL_LEFT) { XrSave (xrs); XrRotate (xrs, M_PI_2); - grr_svg_draw (xrs, wall_svg); + grr_icon_draw (view->wall_icon, xrs); XrRestore (xrs); } if (wall & RR_WALL_RIGHT) { XrSave (xrs); XrTranslate (xrs, GRR_SVG_ASSUMED_WIDTH, 0); XrRotate (xrs, M_PI_2); - grr_svg_draw (xrs, wall_svg); + grr_icon_draw (view->wall_icon, xrs); XrRestore (xrs); } if (wall & RR_WALL_BELOW) { XrSave (xrs); XrTranslate (xrs, 0, GRR_SVG_ASSUMED_HEIGHT); - grr_svg_draw (xrs, wall_svg); + grr_icon_draw (view->wall_icon, xrs); XrRestore (xrs); } } static void -grr_target_draw (XrState *xrs, rr_target_t target) -{ - char *target_svg; - - if (target == RR_TARGET_NONE) - return; - - switch (target) { - case RR_TARGET_BLUE_CIRCLE: - target_svg = GRR_TARGET_BLUE_CIRCLE_SVG; - break; - case RR_TARGET_BLUE_OCTAGON: - target_svg = GRR_TARGET_BLUE_OCTAGON_SVG; - break; - case RR_TARGET_BLUE_SQUARE: - target_svg = GRR_TARGET_BLUE_SQUARE_SVG; - break; - case RR_TARGET_BLUE_TRIANGLE: - target_svg = GRR_TARGET_BLUE_TRIANGLE_SVG; - break; - case RR_TARGET_GREEN_CIRCLE: - target_svg = GRR_TARGET_GREEN_CIRCLE_SVG; - break; - case RR_TARGET_GREEN_OCTAGON: - target_svg = GRR_TARGET_GREEN_OCTAGON_SVG; - break; - case RR_TARGET_GREEN_SQUARE: - target_svg = GRR_TARGET_GREEN_SQUARE_SVG; - break; - case RR_TARGET_GREEN_TRIANGLE: - target_svg = GRR_TARGET_GREEN_TRIANGLE_SVG; - break; - case RR_TARGET_RED_CIRCLE: - target_svg = GRR_TARGET_RED_CIRCLE_SVG; - break; - case RR_TARGET_RED_OCTAGON: - target_svg = GRR_TARGET_RED_OCTAGON_SVG; - break; - case RR_TARGET_RED_SQUARE: - target_svg = GRR_TARGET_RED_SQUARE_SVG; - break; - case RR_TARGET_RED_TRIANGLE: - target_svg = GRR_TARGET_RED_TRIANGLE_SVG; - break; - case RR_TARGET_YELLOW_CIRCLE: - target_svg = GRR_TARGET_YELLOW_CIRCLE_SVG; - break; - case RR_TARGET_YELLOW_OCTAGON: - target_svg = GRR_TARGET_YELLOW_OCTAGON_SVG; - break; - case RR_TARGET_YELLOW_SQUARE: - target_svg = GRR_TARGET_YELLOW_SQUARE_SVG; - break; - case RR_TARGET_YELLOW_TRIANGLE: - target_svg = GRR_TARGET_YELLOW_TRIANGLE_SVG; - break; - case RR_TARGET_WHIRL: - target_svg = GRR_TARGET_WHIRL_SVG; - break; - default: - return; - } - - grr_svg_draw (xrs, target_svg); -} - -static void -grr_robot_draw (XrState *xrs, rr_robot_t robot) -{ - char *robot_svg; - - if (robot == RR_ROBOT_NONE) - return; - - switch (robot) { - case RR_ROBOT_BLUE: - robot_svg = GRR_ROBOT_BLUE_SVG; - break; - case RR_ROBOT_GREEN: - robot_svg = GRR_ROBOT_GREEN_SVG; - break; - case RR_ROBOT_RED: - robot_svg = GRR_ROBOT_RED_SVG; - break; - case RR_ROBOT_YELLOW: - robot_svg = GRR_ROBOT_YELLOW_SVG; - break; - default: - return; - } - - grr_svg_draw (xrs, robot_svg); -} - -static void -grr_cell_draw (XrState *xrs, rr_cell_t cell, rr_target_t goal, - int width, int height) +grr_board_view_draw_cell (grr_board_view_t *view, + XrState *xrs, + rr_cell_t cell, + rr_target_t goal, + int width, + int height) { int xpad, ypad; + rr_robot_t robot; rr_target_t target; XrSave (xrs); XrScale (xrs, width / GRR_SVG_ASSUMED_WIDTH, height / GRR_SVG_ASSUMED_HEIGHT); - grr_svg_draw (xrs, GRR_CELL_SVG); - grr_wall_draw (xrs, RR_CELL_GET_WALLS (cell)); + grr_icon_draw (view->cell_icon, xrs); + grr_board_view_draw_walls (view, xrs, RR_CELL_GET_WALLS (cell)); XrRestore (xrs); xpad = width / 5; @@ -439,12 +315,14 @@ grr_cell_draw (XrState *xrs, rr_cell_t cell, rr_target_t goal, (height - 2*ypad) / GRR_SVG_ASSUMED_HEIGHT); target = RR_CELL_GET_TARGET (cell); - grr_target_draw (xrs, target); + if (target) + grr_icon_draw (view->target_icon[rr_target_idx (target)], xrs); + XrRestore (xrs); - /* This is a hack, (it obscures the cell background in addition to - the target). The real way to do this is to draw the target - itself with less opacity. */ + /* XXX: This is a kludge, (it obscures the cell background in + addition to the target). The real way to do this is to draw the + target itself with less opacity. */ if (target && target != goal) { XrSave (xrs); XrScale (xrs, @@ -465,7 +343,9 @@ grr_cell_draw (XrState *xrs, rr_cell_t cell, rr_target_t goal, (width - 2*xpad) / GRR_SVG_ASSUMED_WIDTH, (height - 2*ypad) / GRR_SVG_ASSUMED_HEIGHT); - grr_robot_draw (xrs, RR_CELL_GET_ROBOT (cell)); + robot = RR_CELL_GET_ROBOT (cell); + if (robot) + grr_icon_draw (view->robot_icon[rr_robot_idx (robot)], xrs); XrRestore (xrs); @@ -484,6 +364,7 @@ grr_board_view_expose (GtkWidget *widget, gint x_off, y_off; int i, j; rr_target_t goal_target; + int new_cell_width, new_cell_height; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GRR_IS_BOARD_VIEW (widget), FALSE); @@ -503,16 +384,58 @@ grr_board_view_expose (GtkWidget *widget, /* Ignore GTK+ and use Xr for drawing. */ xrs = XrCreate (); XrSetTargetDrawable (xrs, dpy, drawable); - XrTranslate (xrs, -x_off, -y_off); rr_board_get_size (board, &view->board_width, &view->board_height); - view->cell_width = widget->allocation.width / view->board_width; - if (view->cell_width == 0) - view->cell_width = 1; - view->cell_height = widget->allocation.height / view->board_height; - if (view->cell_height == 0) - view->cell_height = 1; + new_cell_width = widget->allocation.width / view->board_width; + if (new_cell_width == 0) + new_cell_width = 1; + new_cell_height = widget->allocation.height / view->board_height; + if (new_cell_height == 0) + new_cell_height = 1; + + view->cell_width = new_cell_width; + view->cell_height = new_cell_height; + + /* Pre-render icons if the size has changed */ + /* XXX: This code isn't fully baked yet + if (new_cell_width != view->cell_width + || new_cell_height != view->cell_height) { + int i; + rr_robot_t robot; + rr_target_t target; + + view->cell_width = new_cell_width; + view->cell_height = new_cell_height; + + XrSave (xrs); + XrScale (xrs, + view->cell_width / GRR_SVG_ASSUMED_WIDTH, + view->cell_height / GRR_SVG_ASSUMED_HEIGHT); + + grr_icon_predraw (view->cell_icon, xrs, + view->cell_width, view->cell_height); + + grr_icon_predraw (view->wall_icon, xrs, + view->cell_width, view->cell_height); + + for (i=0; i < RR_NUM_ROBOTS; i++) { + robot = rr_robot_from_idx (i); + grr_icon_predraw (view->robot_icon[i], xrs, + view->cell_width, view->cell_height); + } + + for (i=0; i < RR_NUM_TARGETS; i++) { + target = rr_target_from_idx (i); + grr_icon_predraw (view->target_icon[i], xrs, + view->cell_width, view->cell_height); + } + + XrRestore (xrs); + } + */ + + XrTranslate (xrs, -x_off, -y_off); view->board_pad_x = (widget->allocation.width - view->board_width * view->cell_width) / 2; view->board_pad_y = (widget->allocation.height - view->board_height * view->cell_height) / 2; @@ -526,10 +449,10 @@ grr_board_view_expose (GtkWidget *widget, for (i=0; i < view->board_width; i++) { XrSave (xrs); XrTranslate (xrs, i * view->cell_width, j * view->cell_height); - grr_cell_draw (xrs, - rr_board_get_cell (board, i, j), - goal_target, - view->cell_width, view->cell_height); + grr_board_view_draw_cell (view, xrs, + rr_board_get_cell (board, i, j), + goal_target, + view->cell_width, view->cell_height); XrRestore (xrs); } } @@ -557,8 +480,8 @@ grr_board_view_expose (GtkWidget *widget, XrTranslate (xrs, (view->board_width / 2 - 1) * view->cell_width, (view->board_height / 2 - 1) * view->cell_height); - grr_cell_draw (xrs, goal_target, goal_target, - view->cell_width * 2, view->cell_height * 2); + grr_board_view_draw_cell (view, xrs, goal_target, goal_target, + view->cell_width * 2, view->cell_height * 2); } XrRestore (xrs); @@ -570,7 +493,7 @@ grr_board_view_expose (GtkWidget *widget, XrScale (xrs, view->cell_width / GRR_SVG_ASSUMED_WIDTH, view->cell_height / GRR_SVG_ASSUMED_HEIGHT); - grr_wall_draw (xrs, RR_CELL_GET_WALLS (rr_board_get_cell(board, i, j))); + grr_board_view_draw_walls (view, xrs, RR_CELL_GET_WALLS (rr_board_get_cell(board, i, j))); XrRestore (xrs); } } diff --git a/src/grr_board_view.h b/src/grr_board_view.h index 4fb8507..8a0ffd1 100644 --- a/src/grr_board_view.h +++ b/src/grr_board_view.h @@ -33,6 +33,8 @@ #include +#include "grr_icon.h" + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -65,6 +67,11 @@ struct grr_board_view /* ID of update timer, or 0 if none */ guint32 timer; + + grr_icon_t *cell_icon; + grr_icon_t *wall_icon; + grr_icon_t *robot_icon[RR_NUM_ROBOTS]; + grr_icon_t *target_icon[RR_NUM_TARGETS]; }; struct grr_board_view_class diff --git a/src/grr_icon.c b/src/grr_icon.c index 999f2a6..405dfb0 100644 --- a/src/grr_icon.c +++ b/src/grr_icon.c @@ -24,77 +24,94 @@ * Author: Carl Worth */ +#include +#include +#include +#include +#include + #include "grr_icon.h" -#include "grr_icon_svg.h" +#include "grr_util.h" +#include "svg/grr_icon_svg.h" struct { int type; char *name; char *svg; -} icons[] = { - { RR_ROBOT_BLUE, - "robot_blue", GRR_ICON_SVG_ROBOT_BLUE }, - { RR_ROBOT_GREEN, - "robot_green", GRR_ICON_SVG_ROBOT_GREEN }, - { RR_ROBOT_RED, - "robot_red", GRR_ICON_SVG_ROBOT_RED }, - { RR_ROBOT_YELLOW, - "robot_yellow", GRR_ICON_SVG_ROBOT_YELLOW }, - - { RR_TARGET_BLUE_CIRCLE, - "target_blue_circle", GRR_ICON_SVG_TARGET_BLUE_CIRCLE }, - { RR_TARGET_BLUE_OCTAGON, - "target_blue_octagon", GRR_ICON_SVG_TARGET_BLUE_OCTAGON }, - { RR_TARGET_BLUE_SQUARE, - "target_blue_square", GRR_ICON_SVG_TARGET_BLUE_SQUARE }, - { RR_TARGET_BLUE_TRIANGLE, - "target_blue_triangle", GRR_ICON_SVG_TARGET_BLUE_TRIANGLE }, - - { RR_TARGET_GREEN_CIRCLE, - "target_green_circle", GRR_ICON_SVG_TARGET_GREEN_CIRCLE }, - { RR_TARGET_GREEN_OCTAGON, - "target_green_octagon", GRR_ICON_SVG_TARGET_GREEN_OCTAGON }, - { RR_TARGET_GREEN_SQUARE, - "target_green_square", GRR_ICON_SVG_TARGET_GREEN_SQUARE }, - { RR_TARGET_GREEN_TRIANGLE, - "target_green_triangle", GRR_ICON_SVG_TARGET_GREEN_TRIANGLE }, - - { RR_TARGET_RED_CIRCLE, - "target_red_circle", GRR_ICON_SVG_TARGET_RED_CIRCLE }, - { RR_TARGET_RED_OCTAGON, - "target_red_octagon", GRR_ICON_SVG_TARGET_RED_OCTAGON }, - { RR_TARGET_RED_SQUARE, - "target_red_square", GRR_ICON_SVG_TARGET_RED_SQUARE }, - { RR_TARGET_RED_TRIANGLE, - "target_red_triangle", GRR_ICON_SVG_TARGET_RED_TRIANGLE }, - - { RR_TARGET_YELLOW_CIRCLE, - "target_yellow_circle", GRR_ICON_SVG_TARGET_YELLOW_CIRCLE }, - { RR_TARGET_YELLOW_OCTAGON, - "target_yellow_octagon", GRR_ICON_SVG_TARGET_YELLOW_OCTAGON }, - { RR_TARGET_YELLOW_SQUARE, - "target_yellow_square", GRR_ICON_SVG_TARGET_YELLOW_SQUARE }, - { RR_TARGET_YELLOW_TRIANGLE, - "target_yellow_triangle", GRR_ICON_SVG_TARGET_YELLOW_TRIANGLE }, - - { RR_TARGET_WHIRL, - "whirl", GRR_ICON_SVG_TARGET_WHIRL }, - - { RR_WALL_ABOVE, - "wall", GRR_ICON_SVG_WALL }, - - { RR_CELL, - "cell", GRR_ICON_SVG_CELL } + int svg_len; +} builtins[] = { + { RR_ROBOT_BLUE, "robot_blue", + GRR_ICON_SVG_ROBOT_BLUE, sizeof (GRR_ICON_SVG_ROBOT_BLUE) }, + { RR_ROBOT_GREEN, "robot_green", + GRR_ICON_SVG_ROBOT_GREEN, sizeof (GRR_ICON_SVG_ROBOT_GREEN) }, + { RR_ROBOT_RED, "robot_red", + GRR_ICON_SVG_ROBOT_RED, sizeof (GRR_ICON_SVG_ROBOT_RED) }, + { RR_ROBOT_YELLOW, "robot_yellow", + GRR_ICON_SVG_ROBOT_YELLOW, sizeof (GRR_ICON_SVG_ROBOT_YELLOW) }, + + { RR_TARGET_BLUE_CIRCLE, "target_blue_circle", + GRR_ICON_SVG_TARGET_BLUE_CIRCLE, sizeof (GRR_ICON_SVG_TARGET_BLUE_CIRCLE) }, + { RR_TARGET_BLUE_OCTAGON, "target_blue_octagon", + GRR_ICON_SVG_TARGET_BLUE_OCTAGON, sizeof (GRR_ICON_SVG_TARGET_BLUE_OCTAGON) }, + { RR_TARGET_BLUE_SQUARE, "target_blue_square", + GRR_ICON_SVG_TARGET_BLUE_SQUARE, sizeof (GRR_ICON_SVG_TARGET_BLUE_SQUARE) }, + { RR_TARGET_BLUE_TRIANGLE, "target_blue_triangle", + GRR_ICON_SVG_TARGET_BLUE_TRIANGLE, sizeof (GRR_ICON_SVG_TARGET_BLUE_TRIANGLE) }, + + { RR_TARGET_GREEN_CIRCLE, "target_green_circle", + GRR_ICON_SVG_TARGET_GREEN_CIRCLE, sizeof (GRR_ICON_SVG_TARGET_GREEN_CIRCLE) }, + { RR_TARGET_GREEN_OCTAGON, "target_green_octagon", + GRR_ICON_SVG_TARGET_GREEN_OCTAGON, sizeof (GRR_ICON_SVG_TARGET_GREEN_OCTAGON) }, + { RR_TARGET_GREEN_SQUARE, "target_green_square", + GRR_ICON_SVG_TARGET_GREEN_SQUARE, sizeof (GRR_ICON_SVG_TARGET_GREEN_SQUARE) }, + { RR_TARGET_GREEN_TRIANGLE, "target_green_triangle", + GRR_ICON_SVG_TARGET_GREEN_TRIANGLE, sizeof (GRR_ICON_SVG_TARGET_GREEN_TRIANGLE) }, + + { RR_TARGET_RED_CIRCLE, "target_red_circle", + GRR_ICON_SVG_TARGET_RED_CIRCLE, sizeof (GRR_ICON_SVG_TARGET_RED_CIRCLE) }, + { RR_TARGET_RED_OCTAGON, "target_red_octagon", + GRR_ICON_SVG_TARGET_RED_OCTAGON, sizeof (GRR_ICON_SVG_TARGET_RED_OCTAGON) }, + { RR_TARGET_RED_SQUARE, "target_red_square", + GRR_ICON_SVG_TARGET_RED_SQUARE, sizeof (GRR_ICON_SVG_TARGET_RED_SQUARE) }, + { RR_TARGET_RED_TRIANGLE, "target_red_triangle", + GRR_ICON_SVG_TARGET_RED_TRIANGLE, sizeof (GRR_ICON_SVG_TARGET_RED_TRIANGLE) }, + + { RR_TARGET_YELLOW_CIRCLE, "target_yellow_circle", + GRR_ICON_SVG_TARGET_YELLOW_CIRCLE, sizeof (GRR_ICON_SVG_TARGET_YELLOW_CIRCLE) }, + { RR_TARGET_YELLOW_OCTAGON, "target_yellow_octagon", + GRR_ICON_SVG_TARGET_YELLOW_OCTAGON, sizeof (GRR_ICON_SVG_TARGET_YELLOW_OCTAGON) }, + { RR_TARGET_YELLOW_SQUARE, "target_yellow_square", + GRR_ICON_SVG_TARGET_YELLOW_SQUARE, sizeof (GRR_ICON_SVG_TARGET_YELLOW_SQUARE) }, + { RR_TARGET_YELLOW_TRIANGLE, "target_yellow_triangle", + GRR_ICON_SVG_TARGET_YELLOW_TRIANGLE, sizeof (GRR_ICON_SVG_TARGET_YELLOW_TRIANGLE) }, + + { RR_TARGET_WHIRL, "whirl", + GRR_ICON_SVG_TARGET_WHIRL, sizeof (GRR_ICON_SVG_TARGET_WHIRL) }, + + { RR_WALL_ABOVE, "wall", + GRR_ICON_SVG_WALL, sizeof (GRR_ICON_SVG_WALL) }, + + { RR_WALL_NONE, "cell", + GRR_ICON_SVG_CELL, sizeof (GRR_ICON_SVG_CELL) } }; +#define NUM_BUILTINS (sizeof (builtins) / sizeof (builtins[0])) + +static char * +_grr_icon_builtin_name (int type); -typedef struct grr_icon { - xsvg_t *xsvg; -} grr_icon_t; +static rr_status_t +_grr_icon_init (grr_icon_t *icon, char *name); + +static char * +_grr_icon_find_file (char *name); + +static void +_grr_icon_find_buffer (char *name, char **buf, int *buflen); grr_icon_t * grr_icon_create (char *name) { - grr_icon *icon; + grr_icon_t *icon; icon = malloc (sizeof (grr_icon_t)); if (icon == NULL) @@ -110,12 +127,13 @@ _grr_icon_init (grr_icon_t *icon, char *name) { xsvg_status_t status; char *file, *buf; + int buflen; status = xsvg_create (&icon->xsvg); if (status) return RR_STATUS_NO_MEMORY; - file = grr_icon_find_file (name); + file = _grr_icon_find_file (name); if (file) { status = xsvg_parse_file (icon->xsvg, file); @@ -127,13 +145,15 @@ _grr_icon_init (grr_icon_t *icon, char *name) free (file); } - buf = grr_icon_find_buffer (name); - status = xsvg_parse_buffer (icon->xsvg, buf, strlen (buf)); + _grr_icon_find_buffer (name, &buf, &buflen); + status = xsvg_parse_buffer (icon->xsvg, buf, buflen); if (status) { fprintf (stderr, "Error parsing built-in SVG icon for: %s\n", name); return RR_STATUS_PARSE_ERROR; } + icon->surface = NULL; + return RR_STATUS_SUCCESS; } @@ -146,12 +166,93 @@ _grr_icon_find_file (char *name) char *file; struct stat stat_buf; - rr_string_sprintf_alloc (&file, "%s/%s", GRR_ICON_DIR, name); + grr_sprintf_alloc (&file, "%s/%s.svg", GRR_ICON_DIR, name); if (file == NULL) return NULL; err = stat (file, &stat_buf); - if (err == 0 && S_ISREG (state.st_mode)) + if (err == 0 && S_ISREG (stat_buf.st_mode)) return (file); free (file); + + return NULL; +} + +static void +_grr_icon_find_buffer (char *name, char **buf, int *buflen) +{ + int i; + + for (i=0; i < NUM_BUILTINS; i++){ + if (strcmp (builtins[i].name, name) == 0) { + *buf = builtins[i].svg; + *buflen = builtins[i].svg_len; + return; + } + } + + *buf = ""; + *buflen = 0; +} + +static char * +_grr_icon_builtin_name (int type) +{ + int i; + + for (i=0; i < NUM_BUILTINS; i++) + if (builtins[i].type == type) + return builtins[i].name; + + return ""; +} + +char * +grr_icon_robot_name (rr_robot_t robot) +{ + return _grr_icon_builtin_name (robot); +} + +char * +grr_icon_target_name (rr_target_t target) +{ + return _grr_icon_builtin_name (target); +} + +void +grr_icon_draw (grr_icon_t *icon, XrState *xrs) +{ + xsvg_status_t status; + + status = xsvg_render (icon->xsvg, xrs); + if (status) { + fprintf (stderr, "xsvg_render error\n"); + return; + } +} + +void +grr_icon_predraw (grr_icon_t *icon, XrState *xrs, int width, int height) +{ + if (icon->surface_width != width || icon->surface_height != height) { + if (icon->surface) + XrSurfaceDestroy (icon->surface); + icon->surface_width = width; + icon->surface_height = height; + icon->surface = XrSurfaceCreateNextTo (XrGetTargetSurface (xrs), + XrFormatARGB32, + width, height); + } + + XrSave (xrs); + XrSetTargetSurface (xrs, icon->surface); + grr_icon_draw (icon, xrs); + XrRestore (xrs); +} + +void +grr_icon_draw_predrawn (grr_icon_t *icon, XrState *xrs) +{ + if (icon->surface) + XrShowSurface (xrs, icon->surface, icon->surface_width, icon->surface_height); } diff --git a/src/grr_icon.h b/src/grr_icon.h index 5a8951c..ca8dfef 100644 --- a/src/grr_icon.h +++ b/src/grr_icon.h @@ -27,100 +27,36 @@ #ifndef GRR_ICON_H #define GRR_ICON_H +#include +#include + typedef struct grr_icon { xsvg_t *xsvg; + + XrSurface *surface; + int surface_width; + int surface_height; } grr_icon_t; grr_icon_t * -grr_icon_create (char *name) -{ - grr_icon *icon; - - icon = malloc (sizeof (grr_icon_t)); - if (icon == NULL) - return NULL; - - _grr_icon_init (icon, name); - - return icon; -} - -static rr_status_t -_grr_icon_init (grr_icon_t *icon, char *name) -{ - xsvg_status_t status; - char *file, *buf; - - status = xsvg_create (&icon->xsvg); - if (status) - return RR_STATUS_NO_MEMORY; - - file = grr_icon_find_file (name); - - if (file) { - status = xsvg_parse_file (icon->xsvg, file); - if (status == XSVG_STATUS_SUCCESS) { - free (file); - return RR_STATUS_SUCCESS; - } - fprintf (stderr, "Error parsing SVG icon: %s\n", file); - free (file); - } - - buf = grr_icon_find_buffer (name); - status = xsvg_parse_buffer (icon->xsvg, buf, strlen (buf)); - if (status) { - fprintf (stderr, "Error parsing built-in SVG icon for: %s\n", name); - return RR_STATUS_PARSE_ERROR; - } - - return RR_STATUS_SUCCESS; -} - -/* XXX: This could be made more interesting, (eg. search in ~/.grrobot - or something). */ -static char * -_grr_icon_find_file (char *name) -{ - int err; - char *file; - struct stat stat_buf; - - rr_string_sprintf_alloc (&file, "%s/%s", GRR_ICON_DIR, name); - if (file == NULL) - return NULL; - - err = stat (file, &stat_buf); - if (err == 0 && S_ISREG (state.st_mode)) - return (file); - free (file); -} +grr_icon_create (char *name); -extern char *GRR_ROBOT_BLUE_SVG; -extern char *GRR_ROBOT_GREEN_SVG; -extern char *GRR_ROBOT_RED_SVG; -extern char *GRR_ROBOT_YELLOW_SVG; +void +grr_icon_destroy (grr_icon_t *icon); -extern char *GRR_TARGET_BLUE_CIRCLE_SVG; -extern char *GRR_TARGET_GREEN_CIRCLE_SVG; -extern char *GRR_TARGET_RED_CIRCLE_SVG; -extern char *GRR_TARGET_YELLOW_CIRCLE_SVG; +void +grr_icon_draw (grr_icon_t *icon, XrState *xrs); -extern char *GRR_TARGET_BLUE_OCTAGON_SVG; -extern char *GRR_TARGET_GREEN_OCTAGON_SVG; -extern char *GRR_TARGET_RED_OCTAGON_SVG; -extern char *GRR_TARGET_YELLOW_OCTAGON_SVG; +void +grr_icon_predraw (grr_icon_t *icon, XrState *xrs, int width, int height); -extern char *GRR_TARGET_BLUE_SQUARE_SVG; -extern char *GRR_TARGET_GREEN_SQUARE_SVG; -extern char *GRR_TARGET_RED_SQUARE_SVG; -extern char *GRR_TARGET_YELLOW_SQUARE_SVG; +void +grr_icon_draw_predrawn (grr_icon_t *icon, XrState *xrs); -extern char *GRR_TARGET_BLUE_TRIANGLE_SVG; -extern char *GRR_TARGET_GREEN_TRIANGLE_SVG; -extern char *GRR_TARGET_RED_TRIANGLE_SVG; -extern char *GRR_TARGET_YELLOW_TRIANGLE_SVG; +char * +grr_icon_robot_name (rr_robot_t robot); -extern char *GRR_TARGET_WHIRL_SVG; +char * +grr_icon_target_name (rr_target_t target); #endif diff --git a/src/grrobot.c b/src/grrobot.c index 1a8d665..2b6292a 100644 --- a/src/grrobot.c +++ b/src/grrobot.c @@ -287,8 +287,8 @@ grr_game_read_notices (grr_game_t *game) notice->u.number); break; case RR_NOTICE_POSITION: - rr_board_position (board, notice->u.position.robot, - notice->u.position.x, notice->u.position.y); + rr_board_position_robot (board, notice->u.position.robot, + notice->u.position.x, notice->u.position.y); gtk_widget_queue_draw (GTK_WIDGET (game->window)); break; case RR_NOTICE_TURN: diff --git a/src/svg/.cvsignore b/src/svg/.cvsignore index aacdc07..0c92ba6 100644 --- a/src/svg/.cvsignore +++ b/src/svg/.cvsignore @@ -3,4 +3,4 @@ Makefile Makefile.in bin2cstring -grr_icon_svg.h + diff --git a/src/svg/Makefile.am b/src/svg/Makefile.am index b143c9c..9a49535 100644 --- a/src/svg/Makefile.am +++ b/src/svg/Makefile.am @@ -1,9 +1,13 @@ noinst_HEADERS=grr_icon_svg.h -noinst_PROGRAMS = bin2cstring +noinst_PROGRAMS = bin2cstring deflate bin2cstring_SOURCES = bin2cstring.c +deflate_SOURCES = deflate.c + +deflate_LDADD = -lz + pkgdata_DATA = \ cell.svg \ robot_blue.svg \ @@ -30,37 +34,37 @@ target_yellow_triangle.svg \ wall.svg grr_icon_svg.h: \ -cell.svgz \ -robot_blue.svgz \ -robot_green.svgz \ -robot_red.svgz \ -robot_yellow.svgz \ -target_blue_circle.svgz \ -target_blue_octagon.svgz \ -target_blue_square.svgz \ -target_blue_triangle.svgz \ -target_green_circle.svgz \ -target_green_octagon.svgz \ -target_green_square.svgz \ -target_green_triangle.svgz \ -target_red_circle.svgz \ -target_red_octagon.svgz \ -target_red_square.svgz \ -target_red_triangle.svgz \ -target_whirl.svgz \ -target_yellow_circle.svgz \ -target_yellow_octagon.svgz \ -target_yellow_square.svgz \ -target_yellow_triangle.svgz \ -wall.svgz +cell.svg \ +robot_blue.svg \ +robot_green.svg \ +robot_red.svg \ +robot_yellow.svg \ +target_blue_circle.svg \ +target_blue_octagon.svg \ +target_blue_square.svg \ +target_blue_triangle.svg \ +target_green_circle.svg \ +target_green_octagon.svg \ +target_green_square.svg \ +target_green_triangle.svg \ +target_red_circle.svg \ +target_red_octagon.svg \ +target_red_square.svg \ +target_red_triangle.svg \ +target_whirl.svg \ +target_yellow_circle.svg \ +target_yellow_octagon.svg \ +target_yellow_square.svg \ +target_yellow_triangle.svg \ +wall.svg rm -f $@ - for svgz in $^; do \ - echo -n "char " >> $@; \ - echo -n "grr_icon_svg_$${svgz/.svgz/}[] = " | tr "a-z" "A-Z" >> $@; \ - ./bin2cstring $$svgz >> $@; \ + for svg in $^; do \ + echo -n "static char " >> $@; \ + echo -n "grr_icon_svg_$${svg/.svg/}[] = " | tr "a-z" "A-Z" >> $@; \ + ./bin2cstring $$svg >> $@; \ echo ";" >> $@; \ done -%.svgz: %.svg - gzip -c $< > $@ +%.svg.deflate: %.svg + ./deflate $< > $@ diff --git a/src/svg/bin2cstring.c b/src/svg/bin2cstring.c index 86ef541..97267b7 100644 --- a/src/svg/bin2cstring.c +++ b/src/svg/bin2cstring.c @@ -23,7 +23,7 @@ main (int argc, char *argv[]) if (c == EOF) break; - if (isprint (c) && ! isspace (c)) + if (isprint (c) && ! isspace (c) && c != '"') printf ("%c", c); else printf ("\\%03o", c); diff --git a/src/svg/grr_icon_svg.h b/src/svg/grr_icon_svg.h new file mode 100644 index 0000000..f33e575 --- /dev/null +++ b/src/svg/grr_icon_svg.h @@ -0,0 +1,23 @@ +static char GRR_ICON_SVG_CELL[] = "\012\012\012\040\040\012\012"; +static char GRR_ICON_SVG_ROBOT_BLUE[] = "\015\012\015\012\015\012\015\012\011Tux\015\012\011The\040Linux\040Penguin\040in\040SVG.\015\012\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\015\012"; +static char GRR_ICON_SVG_ROBOT_GREEN[] = "\015\012\015\012\015\012\015\012\011Tux\015\012\011The\040Linux\040Penguin\040in\040SVG.\015\012\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\015\012"; +static char GRR_ICON_SVG_ROBOT_RED[] = "\015\012\015\012\015\012\015\012\011Tux\015\012\011The\040Linux\040Penguin\040in\040SVG.\015\012\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\015\012"; +static char GRR_ICON_SVG_ROBOT_YELLOW[] = "\015\012\015\012\015\012\015\012\011Tux\015\012\011The\040Linux\040Penguin\040in\040SVG.\015\012\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\011\015\012\011\011\015\012\011\015\012\015\012"; +static char GRR_ICON_SVG_TARGET_BLUE_CIRCLE[] = "\012\012\012\040\040\012\012"; +static char GRR_ICON_SVG_TARGET_BLUE_OCTAGON[] = "\012\012\012\040\040\012\012"; +static char GRR_ICON_SVG_TARGET_BLUE_SQUARE[] = "\012\012\012\040\040\012\012"; +static char GRR_ICON_SVG_TARGET_BLUE_TRIANGLE[] = "\012\012\012\040\040\012\012"; +static char GRR_ICON_SVG_TARGET_GREEN_CIRCLE[] = "\012\012\012\040\040\012\012"; +static char GRR_ICON_SVG_TARGET_GREEN_OCTAGON[] = "\012\012\012\040\040\012\012"; +static char GRR_ICON_SVG_TARGET_GREEN_SQUARE[] = "\012\012\012\040\040\012\012"; +static char GRR_ICON_SVG_TARGET_GREEN_TRIANGLE[] = "\012\012\012\040\040\012\012"; +static char GRR_ICON_SVG_TARGET_RED_CIRCLE[] = "\012\012\012\040\040\012\012"; +static char GRR_ICON_SVG_TARGET_RED_OCTAGON[] = "\012\012\012\040\040\012\012"; +static char GRR_ICON_SVG_TARGET_RED_SQUARE[] = "\012\012\012\040\040\012\012"; +static char GRR_ICON_SVG_TARGET_RED_TRIANGLE[] = "\012\012\012\040\040\012\012"; +static char GRR_ICON_SVG_TARGET_WHIRL[] = "\012\012\012\040\040\012\040\040\012\040\040\012\040\040\012\012\012"; +static char GRR_ICON_SVG_TARGET_YELLOW_CIRCLE[] = "\012\012\012\040\040\012\012"; +static char GRR_ICON_SVG_TARGET_YELLOW_OCTAGON[] = "\012\012\012\040\040\012\012"; +static char GRR_ICON_SVG_TARGET_YELLOW_SQUARE[] = "\012\012\012\040\040\012\012"; +static char GRR_ICON_SVG_TARGET_YELLOW_TRIANGLE[] = "\012\012\012\040\040\012\012"; +static char GRR_ICON_SVG_WALL[] = "\012\012\012\040\040\012\012";