From 66a23e616670fe19e966c833ac4c0db5edf57c7c Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Mon, 18 Jun 2018 16:55:30 +0200 Subject: Use fz_quad type in structured text and selection/highlighting. --- source/fitz/stext-device.c | 23 ++++------ source/fitz/stext-output.c | 8 +++- source/fitz/stext-search.c | 107 ++++++++++++++------------------------------- source/fitz/util.c | 6 +-- source/pdf/pdf-annot.c | 20 ++++----- source/tools/murun.c | 29 ++++++++---- 6 files changed, 80 insertions(+), 113 deletions(-) (limited to 'source') diff --git a/source/fitz/stext-device.c b/source/fitz/stext-device.c index 40b203b3..ffff886a 100644 --- a/source/fitz/stext-device.c +++ b/source/fitz/stext-device.c @@ -124,16 +124,6 @@ add_line_to_block(fz_context *ctx, fz_stext_page *page, fz_stext_block *block, c return line; } -static float min4(float a, float b, float c, float d) -{ - return fz_min(fz_min(a, b), fz_min(c, d)); -} - -static float max4(float a, float b, float c, float d) -{ - return fz_max(fz_max(a, b), fz_max(c, d)); -} - static fz_stext_char * add_char_to_line(fz_context *ctx, fz_stext_page *page, fz_stext_line *line, const fz_matrix *trm, fz_font *font, float size, int c, fz_point *p, fz_point *q) { @@ -171,10 +161,10 @@ add_char_to_line(fz_context *ctx, fz_stext_page *page, fz_stext_line *line, cons fz_transform_vector(&a, trm); fz_transform_vector(&d, trm); - ch->bbox.x0 = min4(p->x + a.x, q->x + a.x, p->x + d.x, q->x + d.x); - ch->bbox.x1 = max4(p->x + a.x, q->x + a.x, p->x + d.x, q->x + d.x); - ch->bbox.y0 = min4(p->y + a.y, q->y + a.y, p->y + d.y, q->y + d.y); - ch->bbox.y1 = max4(p->y + a.y, q->y + a.y, p->y + d.y, q->y + d.y); + ch->quad.ll = fz_make_point(p->x + d.x, p->y + d.y); + ch->quad.ul = fz_make_point(p->x + a.x, p->y + a.y); + ch->quad.lr = fz_make_point(q->x + d.x, q->y + d.y); + ch->quad.ur = fz_make_point(q->x + a.x, q->y + a.y); return ch; } @@ -648,7 +638,10 @@ fz_stext_close_device(fz_context *ctx, fz_device *dev) for (line = block->u.t.first_line; line; line = line->next) { for (ch = line->first_char; ch; ch = ch->next) - fz_union_rect(&line->bbox, &ch->bbox); + { + fz_rect bbox = fz_rect_from_quad(ch->quad); + fz_union_rect(&line->bbox, &bbox); + } fz_union_rect(&block->bbox, &line->bbox); } } diff --git a/source/fitz/stext-output.c b/source/fitz/stext-output.c index 492885cb..66433489 100644 --- a/source/fitz/stext-output.c +++ b/source/fitz/stext-output.c @@ -364,8 +364,12 @@ fz_print_stext_page_as_xml(fz_context *ctx, fz_output *out, fz_stext_page *page) name = font_full_name(ctx, font); fz_write_printf(ctx, out, "\n", name, size); } - fz_write_printf(ctx, out, "bbox.x0, ch->bbox.y0, ch->bbox.x1, ch->bbox.y1, ch->origin.x, ch->origin.y); + fz_write_printf(ctx, out, "quad.ul.x, ch->quad.ul.y, + ch->quad.ur.x, ch->quad.ur.y, + ch->quad.ll.x, ch->quad.ll.y, + ch->quad.lr.x, ch->quad.lr.y, + ch->origin.x, ch->origin.y); switch (ch->c) { case '<': fz_write_string(ctx, out, "<"); break; diff --git a/source/fitz/stext-search.c b/source/fitz/stext-search.c index b73296e3..0805d3dc 100644 --- a/source/fitz/stext-search.c +++ b/source/fitz/stext-search.c @@ -11,6 +11,20 @@ static float dist2(float a, float b) return a * a + b * b; } +static float hdist(fz_point *dir, fz_point *a, fz_point *b) +{ + float dx = b->x - a->x; + float dy = b->y - a->y; + return fz_abs(dx * dir->x + dy * dir->y); +} + +static float vdist(fz_point *dir, fz_point *a, fz_point *b) +{ + float dx = b->x - a->x; + float dy = b->y - a->y; + return fz_abs(dx * dir->y + dy * dir->x); +} + static int line_length(fz_stext_line *line) { fz_stext_char *ch; @@ -43,8 +57,8 @@ static int find_closest_in_line(fz_stext_line *line, int idx, fz_point p) for (ch = line->first_char; ch; ch = ch->next) { - float mid_x = (ch->bbox.x0 + ch->bbox.x1) / 2; - float mid_y = (ch->bbox.y0 + ch->bbox.y1) / 2; + float mid_x = (ch->quad.ul.x + ch->quad.ur.x + ch->quad.ll.x + ch->quad.lr.x) / 4; + float mid_y = (ch->quad.ul.y + ch->quad.ur.y + ch->quad.ll.y + ch->quad.lr.y) / 4; float this_dist = dist2(p.x - mid_x, p.y - mid_y); if (this_dist < closest_dist) { @@ -171,7 +185,7 @@ fz_enumerate_selection(fz_context *ctx, fz_stext_page *page, fz_point a, fz_poin struct highlight { int len, cap; - fz_rect *box; + fz_quad *box; float hfuzz, vfuzz; }; @@ -180,80 +194,23 @@ static void on_highlight_char(fz_context *ctx, void *arg, fz_stext_line *line, f struct highlight *hits = arg; float vfuzz = ch->size * hits->vfuzz; float hfuzz = ch->size * hits->hfuzz; - fz_rect bbox; - - if (line->dir.x > line->dir.y) - { - bbox.x0 = ch->bbox.x0; - bbox.x1 = ch->bbox.x1; - bbox.y0 = line->bbox.y0; - bbox.y1 = line->bbox.y1; - } - else - { - bbox.x0 = line->bbox.x0; - bbox.x1 = line->bbox.x1; - bbox.y0 = ch->bbox.y0; - bbox.y1 = ch->bbox.y1; - } if (hits->len > 0) { - fz_rect *end = &hits->box[hits->len-1]; - if (fz_abs(bbox.y0 - end->y0) < vfuzz && fz_abs(bbox.y1 - end->y1) < vfuzz) + fz_quad *end = &hits->box[hits->len-1]; + if (hdist(&line->dir, &end->lr, &ch->quad.ll) < hfuzz + && vdist(&line->dir, &end->lr, &ch->quad.ll) < vfuzz + && hdist(&line->dir, &end->ur, &ch->quad.ul) < hfuzz + && vdist(&line->dir, &end->ur, &ch->quad.ul) < vfuzz) { - if (bbox.x1 < end->x0) - { - if (end->x0 - bbox.x1 < hfuzz) - { - end->x0 = bbox.x0; - return; - } - } - else if (bbox.x0 > end->x1) - { - if (bbox.x0 - end->x1 < hfuzz) - { - end->x1 = bbox.x1; - return; - } - } - else - { - end->x0 = fz_min(bbox.x0, end->x0); - end->x1 = fz_max(bbox.x1, end->x1); - return; - } - } - if (fz_abs(bbox.x0 - end->x0) < vfuzz && fz_abs(bbox.x1 - end->x1) < vfuzz) - { - if (bbox.y1 < end->y0) - { - if (end->y0 - bbox.y1 < hfuzz) - { - end->y0 = bbox.y0; - return; - } - } - else if (bbox.y0 > end->y1) - { - if (bbox.y0 - end->y1 < hfuzz) - { - end->y1 = bbox.y1; - return; - } - } - else - { - end->y0 = fz_min(bbox.y0, end->y0); - end->y1 = fz_max(bbox.y1, end->y1); - return; - } + end->ur = ch->quad.ur; + end->lr = ch->quad.lr; + return; } } if (hits->len < hits->cap) - hits->box[hits->len++] = bbox; + hits->box[hits->len++] = ch->quad; } static void on_highlight_line(fz_context *ctx, void *arg, fz_stext_line *line) @@ -261,14 +218,14 @@ static void on_highlight_line(fz_context *ctx, void *arg, fz_stext_line *line) } int -fz_highlight_selection(fz_context *ctx, fz_stext_page *page, fz_point a, fz_point b, fz_rect *hit_bbox, int hit_max) +fz_highlight_selection(fz_context *ctx, fz_stext_page *page, fz_point a, fz_point b, fz_quad *quads, int max_quads) { struct callbacks cb; struct highlight hits; hits.len = 0; - hits.cap = hit_max; - hits.box = hit_bbox; + hits.cap = max_quads; + hits.box = quads; hits.hfuzz = 0.5f; hits.vfuzz = 0.1f; @@ -387,7 +344,7 @@ static const char *find_string(const char *s, const char *needle, const char **e } int -fz_search_stext_page(fz_context *ctx, fz_stext_page *page, const char *needle, fz_rect *hit_bbox, int hit_max) +fz_search_stext_page(fz_context *ctx, fz_stext_page *page, const char *needle, fz_quad *quads, int max_quads) { struct highlight hits; fz_stext_block *block; @@ -401,8 +358,8 @@ fz_search_stext_page(fz_context *ctx, fz_stext_page *page, const char *needle, f return 0; hits.len = 0; - hits.cap = hit_max; - hits.box = hit_bbox; + hits.cap = max_quads; + hits.box = quads; hits.hfuzz = 0.1f; hits.vfuzz = 0.1f; diff --git a/source/fitz/util.c b/source/fitz/util.c index 85ee1e45..0f935e53 100644 --- a/source/fitz/util.c +++ b/source/fitz/util.c @@ -343,7 +343,7 @@ fz_new_stext_page_from_page_number(fz_context *ctx, fz_document *doc, int number } int -fz_search_display_list(fz_context *ctx, fz_display_list *list, const char *needle, fz_rect *hit_bbox, int hit_max) +fz_search_display_list(fz_context *ctx, fz_display_list *list, const char *needle, fz_quad *hit_bbox, int hit_max) { fz_stext_page *text; int count = 0; @@ -359,7 +359,7 @@ fz_search_display_list(fz_context *ctx, fz_display_list *list, const char *needl } int -fz_search_page(fz_context *ctx, fz_page *page, const char *needle, fz_rect *hit_bbox, int hit_max) +fz_search_page(fz_context *ctx, fz_page *page, const char *needle, fz_quad *hit_bbox, int hit_max) { fz_stext_page *text; int count = 0; @@ -375,7 +375,7 @@ fz_search_page(fz_context *ctx, fz_page *page, const char *needle, fz_rect *hit_ } int -fz_search_page_number(fz_context *ctx, fz_document *doc, int number, const char *needle, fz_rect *hit_bbox, int hit_max) +fz_search_page_number(fz_context *ctx, fz_document *doc, int number, const char *needle, fz_quad *hit_bbox, int hit_max) { fz_page *page; int count = 0; diff --git a/source/pdf/pdf-annot.c b/source/pdf/pdf-annot.c index ba92b7ef..cf072c60 100644 --- a/source/pdf/pdf-annot.c +++ b/source/pdf/pdf-annot.c @@ -1058,7 +1058,7 @@ pdf_clear_annot_quad_points(fz_context *ctx, pdf_annot *annot) } void -pdf_add_annot_quad_point(fz_context *ctx, pdf_annot *annot, fz_rect bbox) +pdf_add_annot_quad_point(fz_context *ctx, pdf_annot *annot, fz_quad quad) { pdf_document *doc = annot->page->doc; fz_matrix page_ctm, inv_page_ctm; @@ -1080,15 +1080,15 @@ pdf_add_annot_quad_point(fz_context *ctx, pdf_annot *annot, fz_rect bbox) * in a counterclockwise fashion. Experiments with Adobe's implementation * indicates a cross-wise ordering is intended: ul, ur, ll, lr. */ - fz_transform_rect(&bbox, &inv_page_ctm); - pdf_array_push_real(ctx, quad_points, bbox.x0); /* ul */ - pdf_array_push_real(ctx, quad_points, bbox.y1); - pdf_array_push_real(ctx, quad_points, bbox.x1); /* ur */ - pdf_array_push_real(ctx, quad_points, bbox.y1); - pdf_array_push_real(ctx, quad_points, bbox.x0); /* ll */ - pdf_array_push_real(ctx, quad_points, bbox.y0); - pdf_array_push_real(ctx, quad_points, bbox.x1); /* lr */ - pdf_array_push_real(ctx, quad_points, bbox.y0); + fz_transform_quad(&quad, &inv_page_ctm); + pdf_array_push_real(ctx, quad_points, quad.ul.x); + pdf_array_push_real(ctx, quad_points, quad.ul.y); + pdf_array_push_real(ctx, quad_points, quad.ur.x); + pdf_array_push_real(ctx, quad_points, quad.ur.y); + pdf_array_push_real(ctx, quad_points, quad.ll.x); + pdf_array_push_real(ctx, quad_points, quad.ll.y); + pdf_array_push_real(ctx, quad_points, quad.lr.x); + pdf_array_push_real(ctx, quad_points, quad.lr.y); pdf_dirty_annot(ctx, annot); } diff --git a/source/tools/murun.c b/source/tools/murun.c index c74e4bbc..f7a890b2 100644 --- a/source/tools/murun.c +++ b/source/tools/murun.c @@ -489,6 +489,19 @@ static void ffi_pushrect(js_State *J, fz_rect rect) js_pushnumber(J, rect.y1); js_setindex(J, -2, 3); } +static void ffi_pushquad(js_State *J, fz_quad quad) +{ + js_newarray(J); + js_pushnumber(J, quad.ul.x); js_setindex(J, -2, 0); + js_pushnumber(J, quad.ul.y); js_setindex(J, -2, 1); + js_pushnumber(J, quad.ur.x); js_setindex(J, -2, 0); + js_pushnumber(J, quad.ur.y); js_setindex(J, -2, 1); + js_pushnumber(J, quad.ll.x); js_setindex(J, -2, 0); + js_pushnumber(J, quad.ll.y); js_setindex(J, -2, 1); + js_pushnumber(J, quad.lr.x); js_setindex(J, -2, 0); + js_pushnumber(J, quad.lr.y); js_setindex(J, -2, 1); +} + static fz_irect ffi_toirect(js_State *J, int idx) { fz_irect irect; @@ -1922,7 +1935,7 @@ static void ffi_Page_search(js_State *J) fz_context *ctx = js_getcontext(J); fz_page *page = ffi_topage(J, 0); const char *needle = js_tostring(J, 1); - fz_rect hits[256]; + fz_quad hits[256]; int i, n = 0; fz_try(ctx) @@ -1932,7 +1945,7 @@ static void ffi_Page_search(js_State *J) js_newarray(J); for (i = 0; i < n; ++i) { - ffi_pushrect(J, hits[i]); + ffi_pushquad(J, hits[i]); js_setindex(J, -2, i); } } @@ -2777,7 +2790,7 @@ static void ffi_DisplayList_search(js_State *J) fz_context *ctx = js_getcontext(J); fz_display_list *list = js_touserdata(J, 0, "fz_display_list"); const char *needle = js_tostring(J, 1); - fz_rect hits[256]; + fz_quad hits[256]; int i, n = 0; fz_try(ctx) @@ -2787,7 +2800,7 @@ static void ffi_DisplayList_search(js_State *J) js_newarray(J); for (i = 0; i < n; ++i) { - ffi_pushrect(J, hits[i]); + ffi_pushquad(J, hits[i]); js_setindex(J, -2, i); } } @@ -2797,7 +2810,7 @@ static void ffi_StructuredText_search(js_State *J) fz_context *ctx = js_getcontext(J); fz_stext_page *text = js_touserdata(J, 0, "fz_stext_page"); const char *needle = js_tostring(J, 1); - fz_rect hits[256]; + fz_quad hits[256]; int i, n = 0; fz_try(ctx) @@ -2807,7 +2820,7 @@ static void ffi_StructuredText_search(js_State *J) js_newarray(J); for (i = 0; i < n; ++i) { - ffi_pushrect(J, hits[i]); + ffi_pushquad(J, hits[i]); js_setindex(J, -2, i); } } @@ -2818,7 +2831,7 @@ static void ffi_StructuredText_highlight(js_State *J) fz_stext_page *text = js_touserdata(J, 0, "fz_stext_page"); fz_point a = ffi_topoint(J, 1); fz_point b = ffi_topoint(J, 2); - fz_rect hits[256]; + fz_quad hits[256]; int i, n = 0; fz_try(ctx) @@ -2828,7 +2841,7 @@ static void ffi_StructuredText_highlight(js_State *J) js_newarray(J); for (i = 0; i < n; ++i) { - ffi_pushrect(J, hits[i]); + ffi_pushquad(J, hits[i]); js_setindex(J, -2, i); } } -- cgit v1.2.3