* Author: Carl Worth <carl@theworths.org>
*/
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
#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) },
+
+ { 0, "cell1",
+ GRR_ICON_SVG_CELL1, sizeof (GRR_ICON_SVG_CELL1) },
+ { 0, "cell2",
+ GRR_ICON_SVG_CELL2, sizeof (GRR_ICON_SVG_CELL2) }
};
+#define NUM_BUILTINS (sizeof (builtins) / sizeof (builtins[0]))
+
+static char *
+_grr_icon_builtin_name (int type);
+
+static rr_status_t
+_grr_icon_init (grr_icon_t *icon, char *name);
+
+static char *
+_grr_icon_find_file (char *name);
-typedef struct grr_icon {
- xsvg_t *xsvg;
-} grr_icon_t;
+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)
static rr_status_t
_grr_icon_init (grr_icon_t *icon, char *name)
{
- xsvg_status_t status;
+ svg_cairo_status_t status;
char *file, *buf;
+ int buflen;
+
+ icon->surface = NULL;
+ icon->surface_width = 0;
+ icon->surface_height = 0;
- status = xsvg_create (&icon->xsvg);
+ status = svg_cairo_create (&icon->svg_cairo);
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);
- if (status == XSVG_STATUS_SUCCESS) {
+ status = svg_cairo_parse (icon->svg_cairo, file);
+ if (status == SVG_CAIRO_STATUS_SUCCESS) {
free (file);
return RR_STATUS_SUCCESS;
}
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 = svg_cairo_parse_buffer (icon->svg_cairo, buf, buflen);
if (status) {
fprintf (stderr, "Error parsing built-in SVG icon for: %s\n", name);
return RR_STATUS_PARSE_ERROR;
}
-
return RR_STATUS_SUCCESS;
}
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, cairo_t *xrs)
+{
+ svg_cairo_status_t status;
+
+ status = svg_cairo_render (icon->svg_cairo, xrs);
+ if (status) {
+ fprintf (stderr, "svg_cairo_render error\n");
+ return;
+ }
+}
+
+void
+grr_icon_predraw (grr_icon_t *icon, cairo_t *xrs, int width, int height)
+{
+ cairo_t *xrs2;
+ cairo_matrix_t ctm;
+
+ if (icon->surface_width != width || icon->surface_height != height) {
+ if (icon->surface)
+ cairo_surface_destroy (icon->surface);
+ icon->surface_width = width;
+ icon->surface_height = height;
+ icon->surface = cairo_surface_create_similar (cairo_get_target (xrs),
+ CAIRO_FORMAT_ARGB32,
+ width, height);
+ }
+
+ /* Need to copy the CTM from the original cairo_t to the new one */
+ xrs2 = cairo_create (icon->surface);
+ cairo_get_matrix (xrs, &ctm);
+ cairo_set_matrix (xrs2, &ctm);
+ grr_icon_draw (icon, xrs2);
+ cairo_destroy (xrs2);
+}
+
+void
+grr_icon_draw_predrawn (grr_icon_t *icon, cairo_t *xrs, double alpha)
+{
+ if (icon->surface) {
+ cairo_set_source_surface (xrs, icon->surface, 0.0, 0.0);
+ cairo_paint_with_alpha (xrs, alpha);
+ }
}