summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2015-08-13 14:06:36 +0200
committerTor Andersson <tor.andersson@artifex.com>2015-10-06 11:21:23 +0200
commit22cfd27af25ee0167111410572ab5f63271fdba8 (patch)
tree69ab2f4315e6724f439ba5782358fa43ba282328
parentcb6b1b6bba0a9197ded761ce8d9a1d3c8737368c (diff)
downloadmupdf-22cfd27af25ee0167111410572ab5f63271fdba8.tar.xz
glut: Select rectangle with right mouse and extract text.
-rw-r--r--platform/glut/glut-main.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/platform/glut/glut-main.c b/platform/glut/glut-main.c
index 3fa401ae..2a4dbc3b 100644
--- a/platform/glut/glut-main.c
+++ b/platform/glut/glut-main.c
@@ -316,6 +316,80 @@ void do_search_page(int number, char *needle, fz_cookie *cookie)
fz_drop_page(ctx, page);
}
+static void do_copy_region(fz_rect *sel, int xofs, int yofs, float zoom, float rotate)
+{
+ fz_rect hitbox;
+ fz_matrix ctm;
+ int c, i, p, need_newline;
+ int block_num;
+
+ int x0 = sel->x0 - xofs;
+ int y0 = sel->y0 - yofs;
+ int x1 = sel->x1 - xofs;
+ int y1 = sel->y1 - yofs;
+
+ fz_page *page = fz_load_page(ctx, doc, currentpage);
+ fz_text_sheet *sheet = fz_new_text_sheet(ctx);
+ fz_text_page *text = fz_new_text_page(ctx);
+ fz_device *dev = fz_new_text_device(ctx, sheet, text);
+ fz_run_page(ctx, page, dev, &fz_identity, NULL);
+ fz_drop_device(ctx, dev);
+
+ fz_scale(&ctm, zoom / 72, zoom / 72);
+ fz_pre_rotate(&ctm, -rotate);
+
+ p = 0;
+ need_newline = 0;
+
+ for (block_num = 0; block_num < text->len; block_num++)
+ {
+ fz_text_line *line;
+ fz_text_block *block;
+ fz_text_span *span;
+
+ if (text->blocks[block_num].type != FZ_PAGE_BLOCK_TEXT)
+ continue;
+ block = text->blocks[block_num].u.text;
+
+ for (line = block->lines; line < block->lines + block->len; line++)
+ {
+ int saw_text = 0;
+ for (span = line->first_span; span; span = span->next)
+ {
+ for (i = 0; i < span->len; i++)
+ {
+ fz_text_char_bbox(ctx, &hitbox, span, i);
+ fz_transform_rect(&hitbox, &ctm);
+ c = span->text[i].c;
+ if (c < 32)
+ c = '?';
+ if (hitbox.x1 >= x0 && hitbox.x0 <= x1 && hitbox.y1 >= y0 && hitbox.y0 <= y1)
+ {
+ saw_text = 1;
+ if (need_newline)
+ {
+#if defined(_WIN32) || defined(_WIN64)
+ putchar('\r');
+#endif
+ putchar('\n');
+ need_newline = 0;
+ }
+ putchar(c);
+ }
+ }
+ }
+
+ if (saw_text)
+ need_newline = 1;
+ }
+ }
+
+ fz_drop_text_page(ctx, text);
+ fz_drop_text_sheet(ctx, sheet);
+ fz_drop_page(ctx, page);
+}
+
+
static void draw_string(float x, float y, const char *s)
{
int c;
@@ -807,6 +881,44 @@ static void draw_links(fz_link *link, int xofs, int yofs, float zoom, float rota
glDisable(GL_BLEND);
}
+static void draw_page_selection(int x0, int y0, int x1, int y1, float zoom, float rotate)
+{
+ static fz_rect sel;
+
+ if (ui.x >= x0 && ui.x < x1 && ui.y >= y0 && ui.y < y1)
+ {
+ ui.hot = &sel;
+ if (!ui.active && ui.right)
+ {
+ ui.active = &sel;
+ sel.x0 = sel.x1 = ui.x;
+ sel.y0 = sel.y1 = ui.y;
+ }
+ }
+
+ if (ui.active == &sel)
+ {
+ sel.x1 = ui.x;
+ sel.y1 = ui.y;
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); /* invert destination color */
+
+ glColor4f(1, 1, 1, 1);
+ glRectf(sel.x0, sel.y0, sel.x1 + 1, sel.y1 + 1);
+
+ glDisable(GL_BLEND);
+ }
+
+ if (ui.active == &sel && !ui.right)
+ {
+ printf("--- copy to clipboard ---\n");
+ do_copy_region(&sel, x0, y0, zoom, rotate);
+ printf("\n---\n");
+ glutPostRedisplay();
+ }
+}
+
static void draw_search_hits(int xofs, int yofs, float zoom, float rotate)
{
fz_matrix ctm;
@@ -1079,6 +1191,7 @@ static void display(void)
draw_image(page_tex, &r);
draw_links(links, x, y, currentzoom, currentrotate);
+ draw_page_selection(x, y, x+page_w, y+page_h, currentzoom, currentrotate);
if (search_hit_page == currentpage && search_hit_count > 0)
draw_search_hits(x, y, currentzoom, currentrotate);