diff options
Diffstat (limited to 'platform/gl/gl-main.c')
-rw-r--r-- | platform/gl/gl-main.c | 568 |
1 files changed, 359 insertions, 209 deletions
diff --git a/platform/gl/gl-main.c b/platform/gl/gl-main.c index 67f69f16..c6aadc0b 100644 --- a/platform/gl/gl-main.c +++ b/platform/gl/gl-main.c @@ -1,9 +1,14 @@ #include "gl-app.h" +#include <limits.h> #include <string.h> #include <stdlib.h> #include <stdio.h> +#ifndef PATH_MAX +#define PATH_MAX 2048 +#endif + #ifndef _WIN32 #include <unistd.h> /* for fork and exec */ #endif @@ -11,9 +16,12 @@ fz_context *ctx = NULL; pdf_document *pdf = NULL; pdf_page *page = NULL; -int page_x_ofs = 0; -int page_y_ofs = 0; -fz_matrix page_ctm, page_inv_ctm; +pdf_annot *selected_annot = NULL; +fz_stext_page *page_text = NULL; +fz_matrix draw_page_ctm, view_page_ctm, view_page_inv_ctm; +fz_rect page_bounds, draw_page_bounds, view_page_bounds; +fz_irect view_page_area; +char filename[PATH_MAX]; enum { @@ -74,7 +82,6 @@ static int zoom_out(int oldres) #define MAXRES (zoom_list[nelem(zoom_list)-1]) #define DEFRES 96 -static char filename[2048]; static char *password = ""; static char *anchor = NULL; static float layout_w = DEFAULT_LAYOUT_W; @@ -83,10 +90,8 @@ static float layout_em = DEFAULT_LAYOUT_EM; static char *layout_css = NULL; static int layout_use_doc_css = 1; -static const char *title = "MuPDF/GL"; static fz_document *doc = NULL; static fz_page *fzpage = NULL; -static fz_stext_page *text = NULL; static fz_outline *outline = NULL; static fz_link *links = NULL; @@ -98,6 +103,7 @@ static int canvas_x = 0, canvas_w = 100; static int canvas_y = 0, canvas_h = 100; static int outline_w = 260; +static int annotate_w = 220; static int oldinvert = 0, currentinvert = 0; static int oldpage = 0, currentpage = 0; @@ -106,6 +112,7 @@ static float oldrotate = 0, currentrotate = 0; static int isfullscreen = 0; static int showoutline = 0; +static int showannotate = 0; static int showlinks = 0; static int showsearch = 0; static int showinfo = 0; @@ -132,29 +139,79 @@ static int search_hit_page = -1; static int search_hit_count = 0; static fz_rect search_hit_bbox[5000]; -static void update_title(void) +static char error_message[256]; +static void error_dialog(void) +{ + ui_dialog_begin(500, (ui.gridsize+4)*3); + ui_layout(T, NONE, NW, 2, 2); + ui_label("%C %s", 0x1f4a3, error_message); /* BOMB */ + ui_layout(B, NONE, S, 2, 2); + if (ui_button("Quit") || ui.key == KEY_ENTER || ui.key == KEY_ESCAPE || ui.key == 'q') + exit(1); + ui_dialog_end(); +} +void ui_show_error_dialog(const char *message) +{ + fz_strlcpy(error_message, message, sizeof error_message); + ui.dialog = error_dialog; +} + +static char warning_message[256]; +static void warning_dialog(void) { - static char buf[256]; - size_t n = strlen(title); + ui_dialog_begin(500, (ui.gridsize+4)*3); + ui_layout(T, NONE, NW, 2, 2); + ui_label("%C %s", 0x26a0, warning_message); /* WARNING SIGN */ + ui_layout(B, NONE, S, 2, 2); + if (ui_button("Okay") || ui.key == KEY_ENTER || ui.key == KEY_ESCAPE) + ui.dialog = NULL; + ui_dialog_end(); +} +void ui_show_warning_dialog(const char *message) +{ + fz_strlcpy(warning_message, message, sizeof warning_message); + ui.dialog = warning_dialog; +} + +void update_title(void) +{ + char buf[256]; + char *title = "MuPDF/GL"; + char *extra = ""; + size_t n; + + title = strrchr(filename, '/'); + if (!title) + title = strrchr(filename, '\\'); + if (title) + ++title; + else + title = filename; + + if (pdf && pdf->dirty) + extra = "*"; + + n = strlen(title); if (n > 50) - sprintf(buf, "...%s - %d / %d", title + n - 50, currentpage + 1, fz_count_pages(ctx, doc)); + sprintf(buf, "...%s%s - %d / %d", title + n - 50, extra, currentpage + 1, fz_count_pages(ctx, doc)); else - sprintf(buf, "%s - %d / %d", title, currentpage + 1, fz_count_pages(ctx, doc)); + sprintf(buf, "%s%s - %d / %d", title, extra, currentpage + 1, fz_count_pages(ctx, doc)); glutSetWindowTitle(buf); glutSetIconTitle(buf); } void load_page(void) { - fz_rect rect; - fz_irect irect; + fz_irect area; - fz_scale(&page_ctm, currentzoom / 72, currentzoom / 72); - fz_pre_rotate(&page_ctm, -currentrotate); - fz_invert_matrix(&page_inv_ctm, &page_ctm); + fz_scale(&draw_page_ctm, currentzoom / 72, currentzoom / 72); + fz_pre_rotate(&draw_page_ctm, -currentrotate); - fz_drop_stext_page(ctx, text); - text = NULL; + /* clear all editor selections */ + selected_annot = NULL; + + fz_drop_stext_page(ctx, page_text); + page_text = NULL; fz_drop_link(ctx, links); links = NULL; fz_drop_page(ctx, fzpage); @@ -165,26 +222,25 @@ void load_page(void) page = (pdf_page*)fzpage; links = fz_load_links(ctx, fzpage); - text = fz_new_stext_page_from_page(ctx, fzpage, NULL); - + page_text = fz_new_stext_page_from_page(ctx, fzpage, NULL); /* compute bounds here for initial window size */ - fz_bound_page(ctx, fzpage, &rect); - fz_transform_rect(&rect, &page_ctm); - fz_irect_from_rect(&irect, &rect); - page_tex.w = irect.x1 - irect.x0; - page_tex.h = irect.y1 - irect.y0; + fz_bound_page(ctx, fzpage, &page_bounds); + draw_page_bounds = page_bounds; + fz_transform_rect(&draw_page_bounds, &draw_page_ctm); + fz_irect_from_rect(&area, &draw_page_bounds); + page_tex.w = area.x1 - area.x0; + page_tex.h = area.y1 - area.y0; } void render_page(void) { fz_pixmap *pix; - fz_scale(&page_ctm, currentzoom / 72, currentzoom / 72); - fz_pre_rotate(&page_ctm, -currentrotate); - fz_invert_matrix(&page_inv_ctm, &page_ctm); + fz_scale(&draw_page_ctm, currentzoom / 72, currentzoom / 72); + fz_pre_rotate(&draw_page_ctm, -currentrotate); - pix = fz_new_pixmap_from_page(ctx, fzpage, &page_ctm, fz_device_rgb(ctx), 0); + pix = fz_new_pixmap_from_page(ctx, fzpage, &draw_page_ctm, fz_device_rgb(ctx), 0); if (currentinvert) { fz_invert_pixmap(ctx, pix); @@ -201,14 +257,14 @@ static struct mark save_mark() mark.page = currentpage; mark.scroll.x = scroll_x; mark.scroll.y = scroll_y; - fz_transform_point(&mark.scroll, &page_inv_ctm); + fz_transform_point(&mark.scroll, &view_page_inv_ctm); return mark; } static void restore_mark(struct mark mark) { currentpage = mark.page; - fz_transform_point(&mark.scroll, &page_ctm); + fz_transform_point(&mark.scroll, &draw_page_ctm); scroll_x = mark.scroll.x; scroll_y = mark.scroll.y; } @@ -257,7 +313,7 @@ static void jump_to_page_xy(int newpage, float x, float y) { fz_point p = { x, y }; newpage = fz_clampi(newpage, 0, fz_count_pages(ctx, doc) - 1); - fz_transform_point(&p, &page_ctm); + fz_transform_point(&p, &draw_page_ctm); clear_future(); push_history(); currentpage = newpage; @@ -313,7 +369,7 @@ static void do_outline_imp(struct list *list, int end, fz_outline *node, int dep n = node->next->page; selected = (currentpage == p || (currentpage > p && currentpage < n)); - if (ui_list_item(list, node, depth * ui.lineheight, node->title, selected)) + if (ui_list_item_x(list, node, depth * ui.lineheight, node->title, selected)) jump_to_page_xy(p, node->x, node->y); if (node->down) @@ -325,11 +381,12 @@ static void do_outline_imp(struct list *list, int end, fz_outline *node, int dep static void do_outline(fz_outline *node) { - static struct list list = {}; + static struct list list; ui_layout(L, BOTH, NW, 0, 0); ui_list_begin(&list, count_outline(node), outline_w, 0); do_outline_imp(&list, fz_count_pages(ctx, doc), node, 1); ui_list_end(&list); + ui_splitter(&outline_w, 150, 500, R); } static void do_links(fz_link *link) @@ -344,9 +401,8 @@ static void do_links(fz_link *link) while (link) { bounds = link->rect; - fz_transform_rect(&bounds, &page_ctm); + fz_transform_rect(&bounds, &view_page_ctm); fz_irect_from_rect(&area, &bounds); - fz_translate_irect(&area, page_x_ofs, page_y_ofs); if (ui_mouse_inside(&area)) { @@ -389,13 +445,13 @@ static void do_links(fz_link *link) glDisable(GL_BLEND); } -static void do_page_selection(int x0, int y0, int x1, int y1) +static void do_page_selection(void) { static fz_point pt = { 0, 0 }; fz_rect hits[1000]; int i, n; - if (ui.x >= x0 && ui.x < x1 && ui.y >= y0 && ui.y < y1) + if (ui_mouse_inside(&view_page_area)) { ui.hot = &pt; if (!ui.active && ui.right) @@ -408,16 +464,13 @@ static void do_page_selection(int x0, int y0, int x1, int y1) if (ui.active == &pt) { - int xofs = x0 - page_tex.x; - int yofs = y0 - page_tex.y; - - fz_point page_a = { pt.x - xofs, pt.y - yofs }; - fz_point page_b = { ui.x - xofs, ui.y - yofs }; + fz_point page_a = { pt.x, pt.y }; + fz_point page_b = { ui.x, ui.y }; - fz_transform_point(&page_a, &page_inv_ctm); - fz_transform_point(&page_b, &page_inv_ctm); + fz_transform_point(&page_a, &view_page_inv_ctm); + fz_transform_point(&page_b, &view_page_inv_ctm); - n = fz_highlight_selection(ctx, text, page_a, page_b, hits, nelem(hits)); + 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 */ glEnable(GL_BLEND); @@ -425,8 +478,8 @@ static void do_page_selection(int x0, int y0, int x1, int y1) glColor4f(1, 1, 1, 1); for (i = 0; i < n; ++i) { - fz_transform_rect(&hits[i], &page_ctm); - glRectf(hits[i].x0+xofs, hits[i].y0+yofs, hits[i].x1 + 1 + xofs, hits[i].y1 + 1 + yofs); + fz_transform_rect(&hits[i], &view_page_ctm); + glRectf(hits[i].x0, hits[i].y0, hits[i].x1 + 1, hits[i].y1 + 1); } glDisable(GL_BLEND); @@ -435,9 +488,9 @@ static void do_page_selection(int x0, int y0, int x1, int y1) { char *s; #ifdef _WIN32 - s = fz_copy_selection(ctx, text, page_a, page_b, 1); + s = fz_copy_selection(ctx, page_text, page_a, page_b, 1); #else - s = fz_copy_selection(ctx, text, page_a, page_b, 0); + s = fz_copy_selection(ctx, page_text, page_a, page_b, 0); #endif ui_set_clipboard(s); fz_free(ctx, s); @@ -457,9 +510,8 @@ static void do_search_hits(void) for (i = 0; i < search_hit_count; ++i) { bounds = search_hit_bbox[i]; - fz_transform_rect(&bounds, &page_ctm); + fz_transform_rect(&bounds, &view_page_ctm); fz_irect_from_rect(&area, &bounds); - fz_translate_irect(&area, page_x_ofs, page_y_ofs); glColor4f(1, 0, 0, 0.4f); glRectf(area.x0, area.y0, area.x1, area.y1); @@ -477,9 +529,9 @@ static void do_forms(void) if (!pdf || search_active) return; - p.x = page_x_ofs + ui.x; - p.y = page_y_ofs + ui.y; - fz_transform_point(&p, &page_inv_ctm); + p.x = ui.x; + p.y = ui.y; + fz_transform_point(&p, &view_page_inv_ctm); if (ui.down && !ui.active) { @@ -533,7 +585,7 @@ static void shrinkwrap(void) { int screen_w = glutGet(GLUT_SCREEN_WIDTH) - SCREEN_FURNITURE_W; int screen_h = glutGet(GLUT_SCREEN_HEIGHT) - SCREEN_FURNITURE_H; - int w = page_tex.w + (showoutline ? outline_w : 0); + int w = page_tex.w + (showoutline ? outline_w + 4 : 0) + (showannotate ? annotate_w : 0); int h = page_tex.h; if (screen_w > 0 && w > screen_w) w = screen_w; @@ -544,6 +596,36 @@ static void shrinkwrap(void) glutReshapeWindow(w, h); } +static struct input input_password; +static void password_dialog(void) +{ + int is; + ui_dialog_begin(400, (ui.gridsize+4)*3); + { + ui_layout(T, X, NW, 2, 2); + ui_label("Password:"); + is = ui_input(&input_password, 200); + + ui_layout(B, X, NW, 2, 2); + ui_panel_begin(0, ui.gridsize, 0, 0, 0); + { + ui_layout(R, NONE, S, 0, 0); + if (ui_button("Cancel")) + exit(1); + ui_spacer(); + if (ui_button("Okay") || is == UI_INPUT_ACCEPT) + { + password = input_password.text; + ui.dialog = NULL; + reload(); + shrinkwrap(); + } + } + ui_panel_end(); + } + ui_dialog_end(); +} + static void load_document(void) { fz_drop_outline(ctx, outline); @@ -554,8 +636,13 @@ static void load_document(void) { if (!fz_authenticate_password(ctx, doc, password)) { + fz_drop_document(ctx, doc); + doc = NULL; fprintf(stderr, "Invalid password.\n"); - exit(1); + ui_input_init(&input_password, ""); + ui.focus = &input_password; + ui.dialog = password_dialog; + return; } } @@ -583,12 +670,15 @@ static void load_document(void) currentpage = fz_clampi(currentpage, 0, fz_count_pages(ctx, doc) - 1); } -static void reload(void) +void reload(void) { load_document(); - load_page(); - render_page(); - update_title(); + if (doc) + { + load_page(); + render_page(); + update_title(); + } } static void toggle_outline(void) @@ -601,6 +691,16 @@ static void toggle_outline(void) } } +static void toggle_annotate(void) +{ + if (pdf) + { + showannotate = !showannotate; + if (canvas_w == page_tex.w && canvas_h == page_tex.h) + shrinkwrap(); + } +} + static void set_zoom(int z, int cx, int cy) { z = fz_clamp(z, MINRES, MAXRES); @@ -681,6 +781,7 @@ static void smart_move_forward(void) static void clear_search(void) { + showsearch = 0; search_hit_page = -1; search_hit_count = 0; } @@ -697,8 +798,9 @@ static void do_app(void) { switch (ui.key) { - case KEY_ESCAPE: clear_search(); break; + case KEY_ESCAPE: clear_search(); selected_annot = NULL; break; case KEY_F1: showhelp = !showhelp; break; + case 'a': toggle_annotate(); break; case 'o': toggle_outline(); break; case 'L': showlinks = !showlinks; break; case 'i': showinfo = !showinfo; break; @@ -817,51 +919,27 @@ static void do_app(void) } } -static int do_info_line(int x, int y, char *label, char *text) -{ - char buf[512]; - fz_snprintf(buf, sizeof buf, "%s: %s", label, text); - ui_draw_string(x, y, buf); - return y + ui.lineheight; -} - static void do_info(void) { - char buf[256]; - - int x = canvas_x + 4 * ui.lineheight; - int y = canvas_y + 4 * ui.lineheight; - int w = canvas_w - 8 * ui.lineheight; - int h = 9 * ui.lineheight; - - glBegin(GL_TRIANGLE_STRIP); - { - glColor4f(0.9f, 0.9f, 0.9f, 1.0f); - glVertex2f(x, y); - glVertex2f(x, y + h); - glVertex2f(x + w, y); - glVertex2f(x + w, y + h); - } - glEnd(); + char buf[100]; - x += ui.lineheight; - y += ui.lineheight + ui.baseline; + ui_dialog_begin(500, 10 * ui.lineheight); + ui_layout(T, X, W, 0, 0); - glColor4f(0, 0, 0, 1); if (fz_lookup_metadata(ctx, doc, FZ_META_INFO_TITLE, buf, sizeof buf) > 0) - y = do_info_line(x, y, "Title", buf); + ui_label("Title: %s", buf); if (fz_lookup_metadata(ctx, doc, FZ_META_INFO_AUTHOR, buf, sizeof buf) > 0) - y = do_info_line(x, y, "Author", buf); + ui_label("Author: %s", buf); if (fz_lookup_metadata(ctx, doc, FZ_META_FORMAT, buf, sizeof buf) > 0) - y = do_info_line(x, y, "Format", buf); + ui_label("Format: %s", buf); if (fz_lookup_metadata(ctx, doc, FZ_META_ENCRYPTION, buf, sizeof buf) > 0) - y = do_info_line(x, y, "Encryption", buf); + ui_label("Encryption: %s", buf); if (pdf_specifics(ctx, doc)) { if (fz_lookup_metadata(ctx, doc, "info:Creator", buf, sizeof buf) > 0) - y = do_info_line(x, y, "PDF Creator", buf); + ui_label("PDF Creator: %s", buf); if (fz_lookup_metadata(ctx, doc, "info:Producer", buf, sizeof buf) > 0) - y = do_info_line(x, y, "PDF Producer", buf); + ui_label("PDF Producer: %s", buf); buf[0] = 0; if (fz_has_permission(ctx, doc, FZ_PERMISSION_PRINT)) fz_strlcat(buf, "print, ", sizeof buf); @@ -875,74 +953,74 @@ static void do_info(void) buf[strlen(buf)-2] = 0; else fz_strlcat(buf, "none", sizeof buf); - y = do_info_line(x, y, "Permissions", buf); + ui_label("Permissions: %s", buf); } + + ui_dialog_end(); } -static int do_help_line(int x, int y, char *label, char *text) +static void do_help_line(char *label, char *text) { - ui_draw_string(x, y, label); - ui_draw_string(x+100, y, text); - return y + ui.lineheight; + ui_panel_begin(0, ui.lineheight, 0, 0, 0); + { + ui_layout(L, NONE, W, 0, 0); + ui_panel_begin(100, ui.lineheight, 0, 0, 0); + ui_layout(R, NONE, W, 20, 0); + ui_label("%s", label); + ui_panel_end(); + + ui_layout(ALL, X, W, 0, 0); + ui_panel_begin(0, ui.lineheight, 0, 0, 0); + ui_label("%s", text); + ui_panel_end(); + } + ui_panel_end(); } static void do_help(void) { - int x = canvas_x + 4 * ui.lineheight; - int y = canvas_y + 4 * ui.lineheight; - int w = canvas_w - 8 * ui.lineheight; - int h = 38 * ui.lineheight; - - glBegin(GL_TRIANGLE_STRIP); - { - glColor4f(0.9f, 0.9f, 0.9f, 1.0f); - glVertex2f(x, y); - glVertex2f(x, y + h); - glVertex2f(x + w, y); - glVertex2f(x + w, y + h); - } - glEnd(); - - x += ui.lineheight; - y += ui.lineheight + ui.baseline; - - glColor4f(0, 0, 0, 1); - y = do_help_line(x, y, "MuPDF", FZ_VERSION); - y += ui.lineheight; - y = do_help_line(x, y, "F1", "show this message"); - y = do_help_line(x, y, "i", "show document information"); - y = do_help_line(x, y, "o", "show/hide outline"); - y = do_help_line(x, y, "L", "show/hide links"); - y = do_help_line(x, y, "r", "reload file"); - y = do_help_line(x, y, "q", "quit"); - y += ui.lineheight; - y = do_help_line(x, y, "I", "toggle inverted color mode"); - y = do_help_line(x, y, "f", "fullscreen window"); - y = do_help_line(x, y, "w", "shrink wrap window"); - y = do_help_line(x, y, "W or H", "fit to width or height"); - y = do_help_line(x, y, "Z", "fit to page"); - y = do_help_line(x, y, "z", "reset zoom"); - y = do_help_line(x, y, "N z", "set zoom to N"); - y = do_help_line(x, y, "+ or -", "zoom in or out"); - y = do_help_line(x, y, "[ or ]", "rotate left or right"); - y = do_help_line(x, y, "arrow keys", "pan in small increments"); - y += ui.lineheight; - y = do_help_line(x, y, "b", "smart move backward"); - y = do_help_line(x, y, "Space", "smart move forward"); - y = do_help_line(x, y, ", or PgUp", "go backward"); - y = do_help_line(x, y, ". or PgDn", "go forward"); - y = do_help_line(x, y, "<", "go backward 10 pages"); - y = do_help_line(x, y, ">", "go forward 10 pages"); - y = do_help_line(x, y, "N g", "go to page N"); - y = do_help_line(x, y, "G", "go to last page"); - y += ui.lineheight; - y = do_help_line(x, y, "t", "go backward in history"); - y = do_help_line(x, y, "T", "go forward in history"); - y = do_help_line(x, y, "N m", "save location in bookmark N"); - y = do_help_line(x, y, "N t", "go to bookmark N"); - y += ui.lineheight; - y = do_help_line(x, y, "/ or ?", "search for text"); - y = do_help_line(x, y, "n or N", "repeat search"); + ui_dialog_begin(500, 35 * ui.lineheight); + ui_layout(T, X, W, 0, 0); + + do_help_line("MuPDF", FZ_VERSION); + ui_spacer(); + do_help_line("F1", "show this message"); + do_help_line("i", "show document information"); + do_help_line("o", "show/hide outline"); + do_help_line("a", "show/hide annotation editor"); + do_help_line("L", "show/hide links"); + do_help_line("r", "reload file"); + do_help_line("q", "quit"); + ui_spacer(); + do_help_line("I", "toggle inverted color mode"); + do_help_line("f", "fullscreen window"); + do_help_line("w", "shrink wrap window"); + do_help_line("W or H", "fit to width or height"); + do_help_line("Z", "fit to page"); + do_help_line("z", "reset zoom"); + do_help_line("N z", "set zoom to N"); + do_help_line("+ or -", "zoom in or out"); + do_help_line("[ or ]", "rotate left or right"); + do_help_line("arrow keys", "pan in small increments"); + ui_spacer(); + do_help_line("b", "smart move backward"); + do_help_line("Space", "smart move forward"); + do_help_line(", or PgUp", "go backward"); + do_help_line(". or PgDn", "go forward"); + do_help_line("<", "go backward 10 pages"); + do_help_line(">", "go forward 10 pages"); + do_help_line("N g", "go to page N"); + do_help_line("G", "go to last page"); + ui_spacer(); + do_help_line("t", "go backward in history"); + do_help_line("T", "go forward in history"); + do_help_line("N m", "save location in bookmark N"); + do_help_line("N t", "go to bookmark N"); + ui_spacer(); + do_help_line("/ or ?", "search for text"); + do_help_line("n or N", "repeat search"); + + ui_dialog_end(); } static void do_canvas(void) @@ -952,7 +1030,7 @@ static void do_canvas(void) static int saved_ui_x = 0; static int saved_ui_y = 0; fz_irect area; - int state; + int page_x, page_y; ui_layout(ALL, BOTH, NW, 0, 0); ui_pack_push(area = ui_pack(0, 0)); @@ -992,39 +1070,55 @@ static void do_canvas(void) if (page_tex.w <= canvas_w) { scroll_x = 0; - page_x_ofs = canvas_x + (canvas_w - page_tex.w) / 2; + page_x = canvas_x + (canvas_w - page_tex.w) / 2; } else { scroll_x = fz_clamp(scroll_x, 0, page_tex.w - canvas_w); - page_x_ofs = canvas_x - scroll_x; + page_x = canvas_x - scroll_x; } if (page_tex.h <= canvas_h) { scroll_y = 0; - page_y_ofs = canvas_y + (canvas_h - page_tex.h) / 2; + page_y = canvas_y + (canvas_h - page_tex.h) / 2; } else { scroll_y = fz_clamp(scroll_y, 0, page_tex.h - canvas_h); - page_y_ofs = canvas_y - scroll_y; + page_y = canvas_y - scroll_y; } - page_x_ofs -= page_tex.x; - page_y_ofs -= page_tex.y; - ui_draw_image(&page_tex, page_x_ofs, page_y_ofs); + view_page_ctm = draw_page_ctm; + view_page_ctm.e += page_x; + view_page_ctm.f += page_y; + fz_invert_matrix(&view_page_inv_ctm, &view_page_ctm); + view_page_bounds = page_bounds; + fz_transform_rect(&view_page_bounds, &view_page_ctm); + fz_irect_from_rect(&view_page_area, &view_page_bounds); + + ui_draw_image(&page_tex, page_x, page_y); if (search_active) { - ui_layout(T, X, NW, 2, 2); + ui_layout(T, X, NW, 0, 0); + ui_panel_begin(0, ui.gridsize+8, 4, 4, 1); + ui_layout(L, NONE, W, 2, 0); ui_label("Searching page %d of %d.", search_page + 1, fz_count_pages(ctx, doc)); + ui_panel_end(); } else { - do_forms(); - do_links(links); - do_page_selection(page_x_ofs, page_y_ofs, page_x_ofs+page_tex.w, page_y_ofs+page_tex.h); + if (showannotate) + { + do_annotate_canvas(area); + } + else + { + do_forms(); + do_links(links); + do_page_selection(); + } if (search_hit_page == currentpage && search_hit_count > 0) do_search_hits(); @@ -1033,12 +1127,11 @@ static void do_canvas(void) if (showsearch) { ui_layout(T, X, NW, 0, 0); - state = ui_input(&search_input, 0); - if (state == UI_INPUT_CANCEL) - { - showsearch = 0; - } - else if (state == UI_INPUT_ACCEPT) + ui_panel_begin(0, ui.gridsize+8, 4, 4, 1); + ui_layout(L, NONE, W, 2, 0); + ui_label("Search:"); + ui_layout(ALL, X, E, 2, 0); + if (ui_input(&search_input, 0) == UI_INPUT_ACCEPT) { showsearch = 0; search_page = -1; @@ -1054,16 +1147,17 @@ static void do_canvas(void) search_page = currentpage; } } + if (ui.focus != &search_input) + showsearch = 0; + ui_panel_end(); } ui_pack_pop(); glDisable(GL_SCISSOR_TEST); } -void run_main_loop(void) +void do_main(void) { - ui_begin(); - if (search_active) { int start_time = glutGet(GLUT_ELAPSED_TIME); @@ -1121,13 +1215,34 @@ void run_main_loop(void) if (showoutline) do_outline(outline); + if (showannotate) + { + ui_layout(R, BOTH, NW, 0, 0); + ui_panel_begin(annotate_w, 0, 4, 4, 1); + do_annotate_panel(); + ui_panel_end(); + } + do_canvas(); if (showinfo) do_info(); else if (showhelp) do_help(); +} +void run_main_loop(void) +{ + ui_begin(); + fz_try(ctx) + { + if (ui.dialog) + ui.dialog(); + else + do_main(); + } + fz_catch(ctx) + ui_show_error_dialog(fz_caught_message(ctx)); ui_end(); } @@ -1146,6 +1261,29 @@ static void usage(const char *argv0) exit(1); } +static int document_filter(const char *filename) +{ + return !!fz_recognize_document(ctx, filename); +} + +static void do_open_document_dialog(void) +{ + if (ui_open_file(filename)) + { + ui.dialog = NULL; + if (filename[0] == 0) + exit(0); + load_document(); + if (doc) + { + load_page(); + render_page(); + shrinkwrap(); + update_title(); + } + } +} + #ifdef _MSC_VER int main_utf8(int argc, char **argv) #else @@ -1171,32 +1309,6 @@ int main(int argc, char **argv) } } - if (fz_optind < argc) - { - fz_strlcpy(filename, argv[fz_optind++], sizeof filename); - } - else - { -#ifdef _WIN32 - win_install(); - if (!win_open_file(filename, sizeof filename)) - exit(0); -#else - usage(argv[0]); -#endif - } - - if (fz_optind < argc) - anchor = argv[fz_optind++]; - - title = strrchr(filename, '/'); - if (!title) - title = strrchr(filename, '\\'); - if (title) - ++title; - else - title = filename; - ctx = fz_new_context(NULL, NULL, 0); fz_register_document_handlers(ctx); if (layout_css) @@ -1207,14 +1319,52 @@ int main(int argc, char **argv) } fz_set_use_document_css(ctx, layout_use_doc_css); - load_document(); - load_page(); + if (fz_optind < argc) + { + fz_strlcpy(filename, argv[fz_optind++], sizeof filename); + if (fz_optind < argc) + anchor = argv[fz_optind++]; - ui_init(page_tex.w, page_tex.h, title); - ui_input_init(&search_input, ""); + fz_try(ctx) + { + page_tex.w = 600; + page_tex.h = 700; + load_document(); + if (doc) load_page(); + } + fz_always(ctx) + { + ui_init(page_tex.w, page_tex.h, "MuPDF: Loading..."); + ui_input_init(&search_input, ""); + } + fz_catch(ctx) + { + ui_show_error_dialog(fz_caught_message(ctx)); + } - render_page(); - update_title(); + fz_try(ctx) + { + if (doc) + { + render_page(); + update_title(); + } + } + fz_catch(ctx) + { + ui_show_error_dialog(fz_caught_message(ctx)); + } + } + else + { +#ifdef _WIN32 + win_install(); +#endif + ui_init(640, 700, "MuPDF: Open document"); + ui_input_init(&search_input, ""); + ui_init_open_file(".", document_filter); + ui.dialog = do_open_document_dialog; + } glutMainLoop(); @@ -1225,7 +1375,7 @@ int main(int argc, char **argv) fz_debug_store(ctx); #endif - fz_drop_stext_page(ctx, text); + fz_drop_stext_page(ctx, page_text); fz_drop_link(ctx, links); fz_drop_page(ctx, fzpage); fz_drop_outline(ctx, outline); |