42 GdkEventButton *event, gpointer user_data);
44 GdkEventExpose *event, gpointer user_data);
47 static cairo_font_face_t *
font;
61 int w = size.width / scaled_size + 1;
62 int h = size.height / scaled_size + 1;
89 font = cairo_toy_font_face_create(
"", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
92 const char *test_text =
"TEST TEXT";
93 cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 10, 10);
94 cairo_t *cr = cairo_create(cst);
95 cairo_set_font_face(cr,
font);
96 cairo_text_extents_t extents;
97 cairo_text_extents(cr, test_text, &extents);
98 cairo_show_text(cr, test_text);
100 cairo_surface_destroy(cst);
109 static gulong map_button_handler = 0;
125 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
136 LOG(
LOG_ERROR,
"map_init",
"Invalid faceset size from server");
162 cairo_set_source_surface(cr, pixmap->
map_image, dest_x, dest_y);
167 const int sx,
const int sy,
const int dx,
const int dy) {
172 cairo_set_source_surface(cr, pixmap->
map_image, dest_x - src_x, dest_y - src_y);
191 static void drawsmooth(cairo_t *cr,
int mx,
int my,
int layer,
int picx,
int picy) {
192 static int dx[8]= {0,1,1,1,0,-1,-1,-1};
193 static int dy[8]= {-1,-1,0,1,1,1,0,-1};
194 static int bweights[8]= {2,0,4,0,8,0,1,0};
195 static int cweights[8]= {0,2,0,4,0,8,0,1};
196 static int bc_exclude[8]= {
206 int partdone[8]= {0,0,0,0,0,0,0,0};
209 int i,weight,weightC;
213 for (i=0; i<=layer; i++) {
219 for (i=0; i<8; i++) {
240 for (i=0; i<8; i++) {
241 if ( (slevels[i]>0) && (!partdone[i]) &&
242 ((lowest<0) || (slevels[i]<slevels[lowest]))
262 for (i=0; i<8; i++) {
263 if ( (slevels[i]==slevels[lowest]) &&
264 (sfaces[i]==sfaces[lowest])) {
266 weight=weight+bweights[i];
267 weightC&=~bc_exclude[i];
270 weightC&=~cweights[i];
274 if (sfaces[lowest]<=0) {
277 smoothface=sfaces[lowest];
286 if ( (!
pixmaps[smoothface]->map_image) ||
304 static void map_draw_layer(cairo_t *cr,
int layer,
int mx_start,
int nx,
int my_start,
int ny) {
305 for (
int x = 0; x <= nx; x++) {
306 for (
int y = 0; y <= ny; y++) {
308 const int mx = mx_start + x;
309 const int my = my_start + y;
318 if (face > 0 &&
pixmaps[face]->map_image != NULL) {
330 static void map_draw_labels(cairo_t *cr,
int mx_start,
int nx,
int my_start,
int ny) {
331 cairo_set_font_face(cr,
font);
332 for (
int x = 0; x <= nx; x++) {
333 for (
int y = 0; y <= ny; y++) {
335 const int mx = mx_start + x;
336 const int my = my_start + y;
340 while (
next != NULL) {
342 cairo_text_extents_t extents;
343 cairo_text_extents(cr,
next->
label, &extents);
350 double lineheight = extents.height+2*bx;
351 cairo_set_source_rgba(cr, 0.3, 0.3, 0.3, 0.5);
352 cairo_rectangle(cr, sx - bx, sy-extents.height-bx, extents.width+2*bx, lineheight);
356 cairo_move_to(cr, sx, sy);
359 cairo_set_source_rgb(cr, 1, 0, 0);
362 cairo_set_source_rgb(cr, 177.0/255, 225.0/255, 255.0/255);
365 cairo_set_source_rgb(cr, 1, 1, 1);
384 static void draw_darkness(cairo_t *cr,
int nx,
int ny,
int mx_start,
int my_start) {
389 cairo_surface_t *cst_lm = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, nx+2, ny+2);
390 cairo_t *cr_lm = cairo_create(cst_lm);
391 for (
int x = -1; x <= nx+1; x++) {
392 for (
int y = -1; y <= ny+1; y++) {
393 const int dx =
MIN(MAX(0, x), nx);
394 const int dy =
MIN(MAX(0, y), ny);
397 const int mx = mx_start + dx;
398 const int my = my_start + dy;
401 const int ax = x + 1;
402 const int ay = y + 1;
404 cairo_rectangle(cr_lm, ax, ay, 1, 1);
409 cairo_destroy(cr_lm);
413 cairo_translate(cr, -1, -1);
414 cairo_set_source_surface(cr, cst_lm, 0, 0);
417 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
420 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_GOOD);
423 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_BEST);
427 cairo_surface_destroy(cst_lm);
434 int x = mx - mx_start;
435 int y = my - my_start;
441 cairo_set_source_rgb(cr, 1, 0, 0);
443 cairo_set_source_rgb(cr, 1, 1, 0);
445 cairo_set_line_width(cr, 2);
448 cairo_set_source_rgb(cr, 0, 0, 0);
449 cairo_set_line_width(cr, 1);
467 const double ew = size.width / scale;
468 const double eh = size.height / scale;
481 const int mx_start = (nx > vw) ?
pl_pos.
x - (nx - vw)/2 :
pl_pos.
x;
482 const int my_start = (ny > vh) ?
pl_pos.
y - (ny - vh)/2 :
pl_pos.
y;
485 cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ew, eh);
486 cairo_t *cr = cairo_create(cst);
489 cairo_set_source_rgb(cr, 0, 0, 0);
490 cairo_rectangle(cr, 0, 0, ew, eh);
511 cairo_t *map_cr = gdk_cairo_create(gtk_widget_get_window(
map_drawing_area));
513 cairo_scale(map_cr, scale, scale);
515 cairo_set_source_surface(map_cr, cst, 0, 0);
517 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
520 cairo_destroy(map_cr);
522 cairo_surface_destroy(cst);
546 gint64 t_start, t_end;
547 t_start = g_get_monotonic_time();
552 t_end = g_get_monotonic_time();
553 gint64 elapsed = t_end - t_start;
555 printf(
"profile/redraw,%"G_GINT64_FORMAT
"\n", elapsed);
558 const unsigned int target_redraw = 100000;
559 const int no_resize_above = 100;
562 LOG(
LOG_DEBUG,
"draw_map",
"Increasing mapscale to %d to reduce draw time below %u us",
569 gpointer user_data) {
581 if (dx == 0 && dy == 0) {
583 }
else if (dx == 0 && dy < 0) {
585 }
else if (dx > 0 && dy < 0) {
587 }
else if (dx > 0 && dy == 0) {
589 }
else if (dx > 0 && dy > 0) {
591 }
else if (dx == 0 && dy > 0) {
593 }
else if (dx < 0 && dy > 0) {
595 }
else if (dx < 0 && dy == 0) {
597 }
else if (dx < 0 && dy < 0) {
600 g_assert_not_reached();
613 int mx = x / tile_size;
614 int my = y / tile_size;
622 const double ew = size.width / scale;
623 const double eh = size.height / scale;
655 GdkEventButton *event, gpointer user_data) {
660 switch (event->button) {
662 if (event->type == GDK_BUTTON_PRESS) {
667 if (event->type == GDK_BUTTON_RELEASE) {
674 if (event->type == GDK_BUTTON_PRESS) {