fix synctex rectangles overlapping

This commit is contained in:
Lucas Franceschino 2020-03-11 17:22:12 +01:00
parent eab2479172
commit 9a7d1d1c47
3 changed files with 124 additions and 1 deletions

View file

@ -202,7 +202,10 @@ synctex_rectangles_from_position(const char* filename, const char* input_file,
girara_list_free(other_rects);
}
return hitlist;
girara_list_t* hitlist_flat = flatten_rectangles(hitlist);
/* girara_list_free(hitlist); */
return hitlist_flat;
}
#else
bool

View file

@ -310,3 +310,121 @@ running_under_wsl(void)
free(content);
return result;
}
typedef struct zathura_point_s
{
double x;
double y;
} zathura_point_t;
int cmp_point(const zathura_point_t* a, const zathura_point_t* b){
return a->x == b->x && a->y == b->y ? 0 : -1;
}
int cmp_double(const double* x, const double* y){
return *x == *y ? 0 : (*x > *y ? 1 : -1);
}
int cmp_rectangle(const zathura_rectangle_t* r1, const zathura_rectangle_t* r2){
return
(r1->x1 == r2->x1 &&
r1->x2 == r2->x2 &&
r1->y1 == r2->y1 &&
r1->y2 == r2->y2
) ? 0 : -1;
}
girara_compare_function_t gcmp_double = (girara_compare_function_t)cmp_double;
girara_compare_function_t gcmp_point = (girara_compare_function_t)cmp_point;
girara_compare_function_t gcmp_rectangle = (girara_compare_function_t)cmp_rectangle;
bool girara_list_append_unique(girara_list_t* l, girara_compare_function_t cmp, void* item){
if(girara_list_find(l, cmp, item))
return false;
girara_list_append(l, item);
return true;
}
void rectangle_to_points(const zathura_rectangle_t* rect, girara_list_t* list){
zathura_point_t* p1 = g_try_malloc0(sizeof(zathura_point_t));
zathura_point_t* p2 = g_try_malloc0(sizeof(zathura_point_t));
zathura_point_t* p3 = g_try_malloc0(sizeof(zathura_point_t));
zathura_point_t* p4 = g_try_malloc0(sizeof(zathura_point_t));
if(p1==NULL || p2==NULL || p3==NULL || p4==NULL)
return;
*p1 = (zathura_point_t) { rect->x1, rect->y1 };
*p2 = (zathura_point_t) { rect->x1, rect->y2 };
*p3 = (zathura_point_t) { rect->x2, rect->y1 };
*p4 = (zathura_point_t) { rect->x2, rect->y2 };
if(!girara_list_append_unique(list, gcmp_point, (void*) p1))
g_free(p1);
if(!girara_list_append_unique(list, gcmp_point, (void*) p2))
g_free(p2);
if(!girara_list_append_unique(list, gcmp_point, (void*) p3))
g_free(p3);
if(!girara_list_append_unique(list, gcmp_point, (void*) p4))
g_free(p4);
}
// transform a rectangle into multiple new ones according a grid of points
void cut_rectangle(const zathura_rectangle_t* rect, girara_list_t* points,
girara_list_t* rectangles){
// Lists of ordred relevant points
girara_list_t* xs = girara_sorted_list_new2(gcmp_double, g_free);
girara_list_t* ys = girara_sorted_list_new2(gcmp_double, g_free);
double* rX2 = g_try_malloc(sizeof(double));
double* rY2 = g_try_malloc(sizeof(double));
if(rX2 == NULL || rY2 == NULL)
return;
*rX2 = (double)rect->x2;
*rY2 = (double)rect->y2;
girara_list_append(xs, rX2);
girara_list_append(ys, rY2);
GIRARA_LIST_FOREACH(points, zathura_point_t*, i_pt, pt)
if(pt->x > rect->x1 && pt->x < rect->x2){
double* v = g_try_malloc(sizeof(double));
if(v == NULL) return;
*v = (double) pt->x;
if(!girara_list_append_unique(xs, gcmp_double, v))
g_free(v);
}
if(pt->y > rect->y1 && pt->y < rect->y2){
double* v = g_try_malloc(sizeof(double));
if(v == NULL) return;
*v = (double) pt->y;
if(!girara_list_append_unique(ys, gcmp_double, v))
g_free(v);
}
GIRARA_LIST_FOREACH_END(points, zathura_point_t*, i_pt, pt);
double x = rect->x1;
GIRARA_LIST_FOREACH(xs, double*, ix, cx)
double y = rect->y1;
GIRARA_LIST_FOREACH(ys, double*, iy, cy)
zathura_rectangle_t* r = g_try_malloc(sizeof(zathura_rectangle_t));
*r = (zathura_rectangle_t) {x, y, *cx, *cy};
y = *cy;
girara_list_append_unique(rectangles, gcmp_rectangle, r);
GIRARA_LIST_FOREACH_END(ys, double*, iy, cy);
x = *cx;
GIRARA_LIST_FOREACH_END(xs, double*, ix, cx);
girara_list_free(xs);
girara_list_free(ys);
}
girara_list_t* flatten_rectangles(girara_list_t* rectangles){
girara_list_t* new_rectangles = girara_list_new2(g_free);
girara_list_t* points = girara_list_new2(g_free);
girara_list_foreach(rectangles, (girara_list_callback_t) rectangle_to_points, points);
GIRARA_LIST_FOREACH(rectangles, zathura_rectangle_t*, i, r)
cut_rectangle(r, points, new_rectangles);
GIRARA_LIST_FOREACH_END(rectangles, zathura_rectangle_t*, i, r);
girara_list_free(points);
return new_rectangles;
}

View file

@ -138,3 +138,5 @@ bool parse_color(GdkRGBA* color, const char* str);
bool running_under_wsl(void);
#endif // UTILS_H
girara_list_t* flatten_rectangles(girara_list_t* rectangles);