From 1f787e13a6c75cf12a09fc44d590ba9169c52a71 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Tue, 26 Jun 2018 14:45:15 +0200 Subject: Add fz_snap_selection function to snap selection to chars/words/lines. Updates the input point coordinates, and also returns a quad with appropriate UI handles. --- include/mupdf/fitz/structured-text.h | 9 +++++ platform/gl/gl-main.c | 5 +++ source/fitz/stext-search.c | 67 ++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) diff --git a/include/mupdf/fitz/structured-text.h b/include/mupdf/fitz/structured-text.h index 44219f4d..2adfa73a 100644 --- a/include/mupdf/fitz/structured-text.h +++ b/include/mupdf/fitz/structured-text.h @@ -152,6 +152,15 @@ int fz_search_stext_page(fz_context *ctx, fz_stext_page *text, const char *needl */ int fz_highlight_selection(fz_context *ctx, fz_stext_page *page, fz_point a, fz_point b, fz_quad *quads, int max_quads); +enum +{ + FZ_SELECT_CHARS, + FZ_SELECT_WORDS, + FZ_SELECT_LINES, +}; + +fz_quad fz_snap_selection(fz_context *ctx, fz_stext_page *page, fz_point *ap, fz_point *bp, int mode); + /* fz_copy_selection: Return a newly allocated UTF-8 string with the text for a given selection. diff --git a/platform/gl/gl-main.c b/platform/gl/gl-main.c index 726de1c0..ee182cdd 100644 --- a/platform/gl/gl-main.c +++ b/platform/gl/gl-main.c @@ -489,6 +489,11 @@ static void do_page_selection(void) fz_transform_point(&page_a, &view_page_inv_ctm); fz_transform_point(&page_b, &view_page_inv_ctm); + if (ui.mod == GLUT_ACTIVE_CTRL) + fz_snap_selection(ctx, page_text, &page_a, &page_b, FZ_SELECT_WORDS); + else if (ui.mod == GLUT_ACTIVE_CTRL + GLUT_ACTIVE_SHIFT) + fz_snap_selection(ctx, page_text, &page_a, &page_b, FZ_SELECT_LINES); + n = fz_highlight_selection(ctx, page_text, page_a, page_b, hits, nelem(hits)); glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); /* invert destination color */ diff --git a/source/fitz/stext-search.c b/source/fitz/stext-search.c index 0805d3dc..14aa002e 100644 --- a/source/fitz/stext-search.c +++ b/source/fitz/stext-search.c @@ -180,6 +180,73 @@ fz_enumerate_selection(fz_context *ctx, fz_stext_page *page, fz_point a, fz_poin } } +fz_quad +fz_snap_selection(fz_context *ctx, fz_stext_page *page, fz_point *a, fz_point *b, int mode) +{ + fz_stext_block *block; + fz_stext_line *line; + fz_stext_char *ch; + fz_quad handles; + int idx, start, end; + int pc; + + start = find_closest_in_page(page, *a); + end = find_closest_in_page(page, *b); + + if (start > end) + idx = start, start = end, end = idx; + + handles.ll = handles.ul = *a; + handles.lr = handles.ur = *b; + + idx = 0; + for (block = page->first_block; block; block = block->next) + { + if (block->type != FZ_STEXT_BLOCK_TEXT) + continue; + for (line = block->u.t.first_line; line; line = line->next) + { + pc = '\n'; + for (ch = line->first_char; ch; ch = ch->next) + { + if (idx <= start) + { + if (mode == FZ_SELECT_CHARS + || (mode == FZ_SELECT_WORDS && (pc == ' ' || pc == '\n')) + || (mode == FZ_SELECT_LINES && (pc == '\n'))) + { + handles.ll = ch->quad.ll; + handles.ul = ch->quad.ul; + *a = ch->origin; + } + } + if (idx >= end) + { + if (mode == FZ_SELECT_CHARS + || (mode == FZ_SELECT_WORDS && (ch->c == ' '))) + { + handles.lr = ch->quad.ll; + handles.ur = ch->quad.ul; + *b = ch->origin; + return handles; + } + if (!ch->next) + { + handles.lr = ch->quad.lr; + handles.ur = ch->quad.ur; + *b = ch->quad.lr; + return handles; + } + } + pc = ch->c; + ++idx; + } + } + } + + return handles; +} + /* Highlight selection */ struct highlight -- cgit v1.2.3