summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2018-06-26 14:45:15 +0200
committerTor Andersson <tor.andersson@artifex.com>2018-07-04 17:23:21 +0200
commit1f787e13a6c75cf12a09fc44d590ba9169c52a71 (patch)
treee22d92e99290f40600044137ecd494e335352cda
parentb064110f9640e19e7c582ad7aa227ea03ac07fe7 (diff)
downloadmupdf-1f787e13a6c75cf12a09fc44d590ba9169c52a71.tar.xz
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.
-rw-r--r--include/mupdf/fitz/structured-text.h9
-rw-r--r--platform/gl/gl-main.c5
-rw-r--r--source/fitz/stext-search.c67
3 files changed, 81 insertions, 0 deletions
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