42 GdkEventButton *event, gpointer user_data);
44 GdkEventExpose *event, gpointer user_data);
58 int w = size.width / scaled_size + 1;
59 int h = size.height / scaled_size + 1;
87 static gulong map_button_handler = 0;
103 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
114 LOG(
LOG_ERROR,
"map_init",
"Invalid faceset size from server");
140 cairo_set_source_surface(cr, pixmap->
map_image, dest_x, dest_y);
145 const int sx,
const int sy,
const int dx,
const int dy) {
150 cairo_set_source_surface(cr, pixmap->
map_image, dest_x - src_x, dest_y - src_y);
169 static void drawsmooth(cairo_t *cr,
int mx,
int my,
int layer,
int picx,
int picy) {
170 static int dx[8]= {0,1,1,1,0,-1,-1,-1};
171 static int dy[8]= {-1,-1,0,1,1,1,0,-1};
172 static int bweights[8]= {2,0,4,0,8,0,1,0};
173 static int cweights[8]= {0,2,0,4,0,8,0,1};
174 static int bc_exclude[8]= {
184 int partdone[8]= {0,0,0,0,0,0,0,0};
187 int i,weight,weightC;
191 for (i=0; i<=layer; i++) {
197 for (i=0; i<8; i++) {
218 for (i=0; i<8; i++) {
219 if ( (slevels[i]>0) && (!partdone[i]) &&
220 ((lowest<0) || (slevels[i]<slevels[lowest]))
240 for (i=0; i<8; i++) {
241 if ( (slevels[i]==slevels[lowest]) &&
242 (sfaces[i]==sfaces[lowest])) {
244 weight=weight+bweights[i];
245 weightC&=~bc_exclude[i];
248 weightC&=~cweights[i];
252 if (sfaces[lowest]<=0) {
255 smoothface=sfaces[lowest];
264 if ( (!
pixmaps[smoothface]->map_image) ||
282 static void map_draw_layer(cairo_t *cr,
int layer,
int mx_start,
int nx,
int my_start,
int ny) {
283 for (
int x = 0; x <= nx; x++) {
284 for (
int y = 0; y <= ny; y++) {
286 const int mx = mx_start + x;
287 const int my = my_start + y;
296 if (face > 0 &&
pixmaps[face]->map_image != NULL) {
308 static void map_draw_labels(cairo_t *cr,
int mx_start,
int nx,
int my_start,
int ny) {
309 cairo_font_face_t *font = cairo_toy_font_face_create(
"", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
310 cairo_set_font_face(cr, font);
311 for (
int x = 0; x <= nx; x++) {
312 for (
int y = 0; y <= ny; y++) {
314 const int mx = mx_start + x;
315 const int my = my_start + y;
319 while (
next != NULL) {
321 cairo_text_extents_t extents;
322 cairo_text_extents(cr,
next->
label, &extents);
329 double lineheight = extents.height+2*bx;
330 cairo_set_source_rgba(cr, 0.3, 0.3, 0.3, 0.5);
331 cairo_rectangle(cr, sx - bx, sy-extents.height-bx, extents.width+2*bx, lineheight);
335 cairo_move_to(cr, sx, sy);
338 cairo_set_source_rgb(cr, 1, 0, 0);
341 cairo_set_source_rgb(cr, 177.0/255, 225.0/255, 255.0/255);
344 cairo_set_source_rgb(cr, 1, 1, 1);
353 cairo_font_face_destroy(font);
364 static void draw_darkness(cairo_t *cr,
int nx,
int ny,
int mx_start,
int my_start) {
369 cairo_surface_t *cst_lm = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, nx+2, ny+2);
370 cairo_t *cr_lm = cairo_create(cst_lm);
371 for (
int x = -1; x <= nx+1; x++) {
372 for (
int y = -1; y <= ny+1; y++) {
373 const int dx =
MIN(MAX(0, x), nx);
374 const int dy =
MIN(MAX(0, y), ny);
377 const int mx = mx_start + dx;
378 const int my = my_start + dy;
381 const int ax = x + 1;
382 const int ay = y + 1;
384 cairo_rectangle(cr_lm, ax, ay, 1, 1);
389 cairo_destroy(cr_lm);
393 cairo_translate(cr, -1, -1);
394 cairo_set_source_surface(cr, cst_lm, 0, 0);
397 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
400 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_GOOD);
403 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_BEST);
407 cairo_surface_destroy(cst_lm);
414 int x = mx - mx_start;
415 int y = my - my_start;
421 cairo_set_source_rgb(cr, 1, 0, 0);
423 cairo_set_source_rgb(cr, 1, 1, 0);
425 cairo_set_line_width(cr, 2);
428 cairo_set_source_rgb(cr, 0, 0, 0);
429 cairo_set_line_width(cr, 1);
447 const double ew = size.width / scale;
448 const double eh = size.height / scale;
461 const int mx_start = (nx > vw) ?
pl_pos.
x - (nx - vw)/2 :
pl_pos.
x;
462 const int my_start = (ny > vh) ?
pl_pos.
y - (ny - vh)/2 :
pl_pos.
y;
465 cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ew, eh);
466 cairo_t *cr = cairo_create(cst);
469 cairo_set_source_rgb(cr, 0, 0, 0);
470 cairo_rectangle(cr, 0, 0, ew, eh);
491 cairo_t *map_cr = gdk_cairo_create(gtk_widget_get_window(
map_drawing_area));
493 cairo_scale(map_cr, scale, scale);
495 cairo_set_source_surface(map_cr, cst, 0, 0);
497 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
500 cairo_destroy(map_cr);
502 cairo_surface_destroy(cst);
526 gint64 t_start, t_end;
527 t_start = g_get_monotonic_time();
532 t_end = g_get_monotonic_time();
533 gint64 elapsed = t_end - t_start;
535 printf(
"profile/redraw,%"G_GINT64_FORMAT
"\n", elapsed);
538 const unsigned int target_redraw = 100000;
539 const int no_resize_above = 100;
542 LOG(
LOG_DEBUG,
"draw_map",
"Increasing mapscale to %d to reduce draw time below %u us",
549 gpointer user_data) {
561 if (dx == 0 && dy == 0) {
563 }
else if (dx == 0 && dy < 0) {
565 }
else if (dx > 0 && dy < 0) {
567 }
else if (dx > 0 && dy == 0) {
569 }
else if (dx > 0 && dy > 0) {
571 }
else if (dx == 0 && dy > 0) {
573 }
else if (dx < 0 && dy > 0) {
575 }
else if (dx < 0 && dy == 0) {
577 }
else if (dx < 0 && dy < 0) {
580 g_assert_not_reached();
593 int mx = x / tile_size;
594 int my = y / tile_size;
602 const double ew = size.width / scale;
603 const double eh = size.height / scale;
635 GdkEventButton *event, gpointer user_data) {
640 switch (event->button) {
642 if (event->type == GDK_BUTTON_PRESS) {
647 if (event->type == GDK_BUTTON_RELEASE) {
654 if (event->type == GDK_BUTTON_PRESS) {