2007-06-21 19:52:03 +00:00
|
|
|
#include "draw.h"
|
|
|
|
#include "level.h"
|
2007-06-23 19:00:05 +00:00
|
|
|
#include "geometry.h"
|
2007-06-24 00:35:04 +00:00
|
|
|
#include <math.h>
|
2007-06-21 19:52:03 +00:00
|
|
|
#include <gtk/gtk.h>
|
2007-06-24 17:33:00 +00:00
|
|
|
#include <glib/gprintf.h>
|
2007-06-21 19:52:03 +00:00
|
|
|
#include <cairo/cairo.h>
|
|
|
|
|
|
|
|
|
|
|
|
static double scale = 100.0;
|
|
|
|
static double xTranslate = 0.0, yTranslate = 0.0;
|
|
|
|
|
2007-06-23 19:00:05 +00:00
|
|
|
|
2007-06-24 00:35:04 +00:00
|
|
|
static void drawGrid(cairo_t *cr, const RECTANGLE *rect) {
|
|
|
|
double depth = log10(scale)-0.75;
|
|
|
|
double depth2 = floor(depth);
|
|
|
|
double step = pow(0.1, depth2);
|
2007-06-24 17:33:00 +00:00
|
|
|
double d;
|
2007-06-24 00:35:04 +00:00
|
|
|
int i;
|
2007-06-24 17:33:00 +00:00
|
|
|
gchar buffer[10];
|
2007-06-24 00:35:04 +00:00
|
|
|
|
|
|
|
|
2007-06-24 17:33:00 +00:00
|
|
|
cairo_set_font_size(cr, 10.0/scale);
|
|
|
|
|
|
|
|
for(i = 0; 0.2*(depth-depth2+i-1) < 0.3; i++) {
|
|
|
|
d = MIN(0.2*(depth-depth2+i), 0.3);
|
|
|
|
cairo_set_source_rgb(cr, d, d, d);
|
|
|
|
|
|
|
|
for(d = rect->x - fmod(rect->x, step) - step; d <= rect->x+rect->width; d+=step) {
|
|
|
|
cairo_move_to(cr, d, rect->y);
|
|
|
|
cairo_line_to(cr, d, rect->y+rect->height);
|
2007-06-24 00:35:04 +00:00
|
|
|
|
|
|
|
cairo_stroke(cr);
|
2007-06-24 17:33:00 +00:00
|
|
|
|
|
|
|
if(step > 0.2)
|
|
|
|
g_snprintf(buffer, sizeof(buffer), "%i", (int)rint(d));
|
|
|
|
else
|
|
|
|
g_snprintf(buffer, sizeof(buffer), "%.*f", -(int)floor(log10(step*1.1)), d+step/10);
|
|
|
|
buffer[sizeof(buffer)-1] = '\0';
|
|
|
|
cairo_move_to(cr, d+1/scale, rect->y+11/scale);
|
|
|
|
cairo_show_text(cr, buffer);
|
2007-06-24 00:35:04 +00:00
|
|
|
}
|
|
|
|
|
2007-06-24 17:33:00 +00:00
|
|
|
for(d = rect->y - fmod(rect->y, step) - step; d <= rect->y+rect->height; d+=step) {
|
|
|
|
cairo_move_to(cr, rect->x, d);
|
|
|
|
cairo_line_to(cr, rect->x+rect->width, d);
|
2007-06-24 00:35:04 +00:00
|
|
|
|
|
|
|
cairo_stroke(cr);
|
2007-06-24 17:33:00 +00:00
|
|
|
|
|
|
|
if(step > 0.5)
|
|
|
|
g_snprintf(buffer, sizeof(buffer), "%i", (int)rint(d));
|
|
|
|
else
|
|
|
|
g_snprintf(buffer, sizeof(buffer), "%.*f", -(int)floor(log10(step*1.1)), d+step/10);
|
|
|
|
buffer[sizeof(buffer)-1] = '\0';
|
|
|
|
cairo_move_to(cr, rect->x+3/scale, d+11/scale);
|
|
|
|
cairo_show_text(cr, buffer);
|
2007-06-24 00:35:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
step *= 10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void room2path(cairo_t *cr, const ROOM *room, const RECTANGLE *rect) {
|
2007-06-21 19:52:03 +00:00
|
|
|
int i;
|
2007-06-23 19:00:05 +00:00
|
|
|
ROOM room2 = {0, NULL};
|
2007-06-21 19:52:03 +00:00
|
|
|
|
2007-06-23 19:00:05 +00:00
|
|
|
// no vertices
|
2007-06-21 19:52:03 +00:00
|
|
|
if(room->nVertices == 0) return;
|
|
|
|
|
2007-06-23 19:00:05 +00:00
|
|
|
if(rect)
|
|
|
|
simplifyPolygon(room, rect, &room2);
|
|
|
|
else
|
|
|
|
room2 = *room;
|
|
|
|
|
|
|
|
if(room2.nVertices == 0) return;
|
2007-06-21 19:52:03 +00:00
|
|
|
|
2007-06-23 19:00:05 +00:00
|
|
|
cairo_new_sub_path(cr);
|
|
|
|
|
|
|
|
for(i = 0; i < room2.nVertices; i++) {
|
|
|
|
cairo_line_to(cr, room2.vertices[i].x, room2.vertices[i].y);
|
|
|
|
}
|
2007-06-21 19:52:03 +00:00
|
|
|
|
|
|
|
cairo_close_path(cr);
|
2007-06-23 19:00:05 +00:00
|
|
|
|
|
|
|
if(rect && room2.vertices)
|
|
|
|
free(room2.vertices);
|
2007-06-21 19:52:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
|
|
|
|
VERTEX vertices[4] = {{-1,-1}, {-1,1}, {1,1}, {1,-1}};
|
|
|
|
ROOM room = {sizeof(vertices)/sizeof(vertices[0]), vertices};
|
|
|
|
LEVEL lvl = {1, &room};
|
|
|
|
cairo_t *cr;
|
2007-06-24 17:33:00 +00:00
|
|
|
RECTANGLE rect = {-1, -1, widget->allocation.width+2, widget->allocation.height+2};
|
2007-06-21 19:52:03 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
|
|
cr = gdk_cairo_create(widget->window);
|
|
|
|
|
2007-06-23 19:00:05 +00:00
|
|
|
gdk_cairo_region(cr, event->region);
|
2007-06-21 19:52:03 +00:00
|
|
|
cairo_clip(cr);
|
|
|
|
|
|
|
|
cairo_translate(cr, getImageWidth()/2-xTranslate, getImageHeight()/2-yTranslate);
|
|
|
|
cairo_scale(cr, scale, scale);
|
|
|
|
|
2007-06-23 19:00:05 +00:00
|
|
|
cairo_device_to_user(cr, &rect.x, &rect.y);
|
|
|
|
cairo_device_to_user_distance(cr, &rect.width, &rect.height);
|
|
|
|
|
2007-06-21 19:52:03 +00:00
|
|
|
cairo_set_line_width(cr, 1.0/scale);
|
2007-06-23 19:00:05 +00:00
|
|
|
cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER);
|
2007-06-21 19:52:03 +00:00
|
|
|
|
2007-06-24 00:35:04 +00:00
|
|
|
drawGrid(cr, &rect);
|
|
|
|
|
2007-06-21 19:52:03 +00:00
|
|
|
for(i = 0; i < lvl.nRooms; i++)
|
2007-06-23 19:00:05 +00:00
|
|
|
room2path(cr, &lvl.rooms[i], &rect);
|
2007-06-21 19:52:03 +00:00
|
|
|
|
|
|
|
cairo_set_source_rgba(cr, 0.0, 0.7, 1.0, 0.3);
|
|
|
|
cairo_fill_preserve(cr);
|
|
|
|
|
|
|
|
cairo_set_source_rgba(cr, 0.0, 0.7, 1.0, 0.7);
|
|
|
|
cairo_stroke(cr);
|
|
|
|
|
|
|
|
cairo_destroy (cr);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
double getScale() {
|
|
|
|
return scale;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setScale(double s) {
|
|
|
|
scale = s;
|
|
|
|
}
|
|
|
|
|
|
|
|
double getImageWidth() {
|
|
|
|
return 5*scale;
|
|
|
|
}
|
|
|
|
|
|
|
|
double getImageHeight() {
|
|
|
|
return 5*scale;
|
|
|
|
}
|
|
|
|
|
|
|
|
double getXTranslate() {
|
|
|
|
return xTranslate;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setXTranslate(double x) {
|
|
|
|
xTranslate = x;
|
|
|
|
}
|
|
|
|
|
|
|
|
double getYTranslate() {
|
|
|
|
return yTranslate;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setYTranslate(double y) {
|
|
|
|
yTranslate = y;
|
|
|
|
}
|