#include "gtkgl.h"
#include "grits-marker.h"
-static void render_all(GritsMarker *marker);
-static void render_point(GritsMarker *marker);
-static void render_label(GritsMarker *marker);
-static void render_icon(GritsMarker *marker);
+/* Texture setup functions */
+static void render_point(GritsMarker *marker)
+{
+ /* Draw outline */
+ cairo_set_source_rgba(marker->cairo, 0, 0, 0, 1);
+ cairo_set_line_width(marker->cairo, marker->outline*2);
+
+ cairo_arc(marker->cairo, marker->xoff, marker->yoff, marker->radius,
+ 0, 2*G_PI);
+ cairo_stroke(marker->cairo);
+
+ /* Draw filler */
+ cairo_set_source_rgba(marker->cairo, 1, 1, 1, 1);
+
+ cairo_arc(marker->cairo, marker->xoff, marker->yoff, marker->radius,
+ 0, 2*G_PI);
+ cairo_fill(marker->cairo);
+}
+
+static void render_label(GritsMarker *marker)
+{
+ g_assert(marker->label);
+
+ cairo_set_source_rgba(marker->cairo, 0, 0, 0, 1);
+ cairo_select_font_face(marker->cairo, "sans-serif",
+ CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+ cairo_set_font_size(marker->cairo, 13);
+ cairo_move_to(marker->cairo, marker->xoff + (marker->icon_width / 2),
+ marker->yoff - (marker->icon_height / 2));
+ cairo_text_path(marker->cairo, marker->label);
+ cairo_stroke(marker->cairo);
+
+ /* Draw filler */
+ cairo_set_source_rgba(marker->cairo, 1, 1, 1, 1);
+ cairo_move_to(marker->cairo, marker->xoff + (marker->icon_width / 2),
+ marker->yoff - (marker->icon_height / 2));
+ cairo_show_text(marker->cairo, marker->label);
+}
+
+static void render_icon(GritsMarker *marker)
+{
+ g_assert(marker->icon_img != NULL);
+ /* This code assumes the icon is an image pointing toward 0 degrees
+ * (ie. north/up). If marker->flip is set, then it will rotate the
+ * icon appropriately then reflect it across the vertical axis so
+ * it's never upside down. */
+ gdouble flip = 1.0;
+ gdouble angle = marker->angle % 360;
+ if (marker->flip && (angle < 360 && angle > 180)) {
+ /* if icon rotates to the left half it will be upside down */
+ flip = -1.0; /* flip horizontally */
+ }
+
+ cairo_save(marker->cairo);
+
+ /* move to marker location */
+ cairo_translate(marker->cairo, marker->xoff, marker->yoff);
+
+ /* perform rotation and flip in one transformation */
+ gdouble C = cos(angle*(M_PI/180.0));
+ gdouble S = sin(angle*(M_PI/180.0));
+ gdouble fx = flip;
+ gdouble fy = 1.0;
+ gdouble tx = 0.0;
+ gdouble ty = 0.0;
+ cairo_matrix_t matrix;
+ cairo_matrix_init(&matrix,
+ fx*C, fx*S,
+ -S*fy, C*fy,
+ C*tx*(1-fx)-S*ty*(fy-1)+tx-C*tx+S*ty,
+ S*tx*(1-fx)+C*ty*(fy-1)+ty-S*tx-C*ty);
+ cairo_transform(marker->cairo, &matrix);
+
+ /* center image */
+ cairo_translate(marker->cairo, -marker->icon_width/2,
+ -marker->icon_height/2);
+
+ cairo_set_source_surface(marker->cairo, marker->icon_img, 0, 0);
+
+ cairo_paint(marker->cairo);
+ cairo_restore(marker->cairo);
+}
+
+static void render_all(GritsMarker *marker)
+{
+ g_assert(marker);
+ if (marker->display_mask & MARKER_DMASK_ICON)
+ render_icon(marker);
+
+ if (marker->display_mask & MARKER_DMASK_POINT)
+ render_point(marker);
+
+ if (marker->display_mask & MARKER_DMASK_LABEL)
+ render_label(marker);
+
+ /* Load GL texture */
+ glEnable(GL_TEXTURE_2D);
+ glGenTextures(1, &marker->tex);
+ glBindTexture(GL_TEXTURE_2D, marker->tex);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glPixelStorei(GL_PACK_ALIGNMENT, 1);
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, marker->width, marker->height,
+ 0, GL_BGRA, GL_UNSIGNED_BYTE,
+ cairo_image_surface_get_data(cairo_get_target(marker->cairo)));
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+}
+
+
+/* Constructors */
/**
* grits_marker_new:
* @label: a short description of the marker
return marker;
}
-/*
+/**
+ * grits_marker_icon_new:
+ * @label: The label to display if MARKER_DMASK_LABEL is set
+ * @filename: The filename of the icon
+ * @angle: The angle to rotate the icon (0 is north)
+ * @flip: Whether to flip the image so that it's never upside down.
+ * Useful for non-symmetric icons which have an "up".
+ * @display_mask: A bitmask which specifies which items to display.
+ *
* Create a new marker with a label, point, icon (png), or any
* combination of the above.
- * label: The label to display if MARKER_DMASK_LABEL is set
- * filename: The filename of the icon
- * angle: The angle to rotate the icon (0 is north)
- * flip: Whether to flip the image so that it's never upside down.
- * Useful for non-symmetric icons which have an "up".
- * display_mask: A bitmask which specifies which items to display.
+ *
+ * Returns: the new #GritsMarker
*/
GritsMarker *grits_marker_icon_new(const gchar *label, const gchar *filename,
guint angle, gboolean flip, guint display_mask)
render_all(marker);
- if (marker->icon_img) {
+ if (marker->icon_img)
cairo_surface_destroy(marker->icon_img);
- }
return marker;
}
-static void render_all(GritsMarker *marker)
-{
- g_assert(marker);
- if (marker->display_mask & MARKER_DMASK_ICON) {
- render_icon(marker);
- }
- if (marker->display_mask & MARKER_DMASK_POINT) {
- render_point(marker);
- }
- if (marker->display_mask & MARKER_DMASK_LABEL) {
- render_label(marker);
- }
-
- /* Load GL texture */
- glEnable(GL_TEXTURE_2D);
- glGenTextures(1, &marker->tex);
- glBindTexture(GL_TEXTURE_2D, marker->tex);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
- glTexImage2D(GL_TEXTURE_2D, 0, 4, marker->width, marker->height,
- 0, GL_BGRA, GL_UNSIGNED_BYTE,
- cairo_image_surface_get_data(cairo_get_target(marker->cairo)));
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-}
-
-
-static void render_point(GritsMarker *marker)
-{
- /* Draw outline */
- cairo_set_source_rgba(marker->cairo, 0, 0, 0, 1);
- cairo_set_line_width(marker->cairo, marker->outline*2);
-
- cairo_arc(marker->cairo, marker->xoff, marker->yoff, marker->radius,
- 0, 2*G_PI);
- cairo_stroke(marker->cairo);
-
- /* Draw filler */
- cairo_set_source_rgba(marker->cairo, 1, 1, 1, 1);
-
- cairo_arc(marker->cairo, marker->xoff, marker->yoff, marker->radius,
- 0, 2*G_PI);
- cairo_fill(marker->cairo);
-}
-
-static void render_label(GritsMarker *marker)
-{
- g_assert(marker->label);
-
- cairo_set_source_rgba(marker->cairo, 0, 0, 0, 1);
- cairo_select_font_face(marker->cairo, "sans-serif",
- CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
- cairo_set_font_size(marker->cairo, 13);
- cairo_move_to(marker->cairo, marker->xoff + (marker->icon_width / 2),
- marker->yoff - (marker->icon_height / 2));
- cairo_text_path(marker->cairo, marker->label);
- cairo_stroke(marker->cairo);
-
- /* Draw filler */
- cairo_set_source_rgba(marker->cairo, 1, 1, 1, 1);
- cairo_move_to(marker->cairo, marker->xoff + (marker->icon_width / 2),
- marker->yoff - (marker->icon_height / 2));
- cairo_show_text(marker->cairo, marker->label);
-}
-
-static void render_icon(GritsMarker *marker)
-{
- g_assert(marker->icon_img != NULL);
-
- /* This code assumes the icon is an image pointing toward 0 degrees
- * (ie. north/up). If marker->flip is set, then it will rotate the
- * icon appropriately then reflect it across the vertical axis so
- * it's never upside down.
- */
- gdouble flip = 1.0;
- gdouble angle = marker->angle % 360;
- if (marker->flip && (angle < 360 && angle > 180)) {
- /* if icon rotates to the left half it will be upside down */
- flip = -1.0; /* flip horizontally */
- }
-
- cairo_save(marker->cairo);
-
- /* move to marker location */
- cairo_translate(marker->cairo, marker->xoff, marker->yoff);
-
- /* perform rotation and flip in one transformation */
- gdouble C = cos(angle*(M_PI/180.0));
- gdouble S = sin(angle*(M_PI/180.0));
- gdouble fx = flip;
- gdouble fy = 1.0;
- gdouble tx = 0.0;
- gdouble ty = 0.0;
- cairo_matrix_t matrix;
- cairo_matrix_init(&matrix,
- fx*C, fx*S,
- -S*fy, C*fy,
- C*tx*(1-fx)-S*ty*(fy-1)+tx-C*tx+S*ty,
- S*tx*(1-fx)+C*ty*(fy-1)+ty-S*tx-C*ty);
- cairo_transform(marker->cairo, &matrix);
-
- /* center image */
- cairo_translate(marker->cairo, -marker->icon_width/2,
- -marker->icon_height/2);
-
- cairo_set_source_surface(marker->cairo, marker->icon_img, 0, 0);
-
- cairo_paint(marker->cairo);
- cairo_restore(marker->cairo);
-}
/* Drawing */
static void grits_marker_draw(GritsObject *_marker, GritsOpenGL *opengl)