From b1cfe634348a2505554b227c8ae97e07964abd5f Mon Sep 17 00:00:00 2001 From: malc Date: Sun, 13 Jun 2010 11:56:15 +0400 Subject: [PATCH] Fine link positioning --- link.c | 65 +++++++++++++++++++++++++++++++++++++++------------ main.ml | 83 +++++++++++++++++++++++++++++++++++++++-------------------------- 2 files changed, 100 insertions(+), 48 deletions(-) diff --git a/link.c b/link.c index f7636e9..846490f 100644 --- a/link.c +++ b/link.c @@ -881,37 +881,72 @@ CAMLprim value ml_draw (value dispy_v, value w_v, value h_v, CAMLreturn (Val_unit); } -CAMLprim value ml_checklink (value ptr_v, value x_v, value y_v) +static pdf_link *getlink (struct page *page, int x, int y) { - CAMLparam3 (ptr_v, x_v, y_v); fz_point p; fz_matrix ctm; pdf_link *link; - int pageno = -1; - struct page *page; - char *s = String_val (ptr_v); - p.x = Int_val (x_v); - p.y = Int_val (y_v); - - page = parse_pointer ("ml_checklink", s); + p.x = x; + p.y = y; ctm = fz_invertmatrix (page->pagedim->ctm); p = fz_transformpoint (ctm, p); for (link = page->drawpage->links; link; link = link->next) { - if (p.x >= link->rect.x0 && p.x <= link->rect.x1) + if (p.x >= link->rect.x0 && p.x <= link->rect.x1) { if (p.y >= link->rect.y0 && p.y <= link->rect.y1) { if (link->kind == PDF_LGOTO) { - pageno = pdf_findpageobject (state.xref, - fz_arrayget (link->dest, 0)) - 1; - /* link->dest); */ + return link; } - break; } + } + } + return NULL; +} + +CAMLprim value ml_checklink (value ptr_v, value x_v, value y_v) +{ + CAMLparam3 (ptr_v, x_v, y_v); + char *s = String_val (ptr_v); + + CAMLreturn (Val_bool (NULL != getlink (parse_pointer ("ml_checklink", s), + Int_val (x_v), Int_val (y_v)))); +} + +CAMLprim value ml_getlink (value ptr_v, value x_v, value y_v) +{ + CAMLparam3 (ptr_v, x_v, y_v); + CAMLlocal2 (ret_v, tup_v); + pdf_link *link; + struct page *page; + char *s = String_val (ptr_v); + + page = parse_pointer ("ml_getlink", s); + + link = getlink (page, Int_val (x_v), Int_val (y_v)); + if (link) { + int pageno; + fz_point p; + + pageno = pdf_findpageobject (state.xref, + fz_arrayget (link->dest, 0)) - 1; + + p.x = fz_toint (fz_arrayget (link->dest, 2)); + p.y = fz_toint (fz_arrayget (link->dest, 3)); + p = fz_transformpoint (page->pagedim->ctm, p); + + tup_v = caml_alloc_tuple (2); + ret_v = caml_alloc_small (1, 1); + Field (tup_v, 0) = Val_int (pageno); + Field (tup_v, 1) = Val_int (p.y); + Field (ret_v, 0) = tup_v; + } + else { + ret_v = Val_int (0); } - CAMLreturn (Val_int (pageno)); + CAMLreturn (ret_v); } CAMLprim value ml_gettext (value ptr_v, value rect_v, value oy_v, value rectsel_v) diff --git a/main.ml b/main.ml index 6e7f74c..3ab6c13 100644 --- a/main.ml +++ b/main.ml @@ -8,7 +8,8 @@ external draw : int -> int -> int -> int -> string -> unit = "ml_draw";; external preload : string -> unit = "ml_preload";; external gettext : string -> (int * int * int * int) -> int -> bool -> unit = "ml_gettext";; -external checklink : string -> int -> int -> int = "ml_checklink";; +external checklink : string -> int -> int -> bool = "ml_checklink";; +external getlink : string -> int -> int -> (int * int) option = "ml_getlink";; type mstate = Msel of ((int * int) * (int * int)) | Mnone;; @@ -952,27 +953,44 @@ let getlink x y = if y > 0 then let y = l.pagey + y in - let destpage = checklink opaque x y in - if destpage < 0 - then - f rest - else - destpage + match getlink opaque x y with + | None -> f rest + | some -> some else f rest | _ -> f rest end - | [] -> -1 + | [] -> None in f state.layout ;; -let gotopage n = +let checklink x y = + let rec f = function + | l :: rest -> + begin match getopaque l.pageno with + | Some opaque when validopaque opaque -> + let y = y - l.pagedispy in + if y > 0 + then + let y = l.pagey + y in + if checklink opaque x y then true else f rest + else + f rest + | _ -> + f rest + end + | [] -> false + in + f state.layout +;; + +let gotopage n top = let y = getpagey n in addnav (); - state.y <- y; - gotoy y; + state.y <- y + top; + gotoy state.y; ;; let mouse ~button ~bstate ~x ~y = @@ -990,22 +1008,23 @@ let mouse ~button ~bstate ~x ~y = gotoy y | Glut.LEFT_BUTTON -> - let destpage = if bstate = Glut.DOWN then getlink x y else - 1 in - if destpage >= 0 - then - gotopage destpage - else ( - if bstate = Glut.DOWN - then ( - Glut.setCursor Glut.CURSOR_CROSSHAIR; - state.mstate <- Msel ((x, y), (x, y)); - Glut.postRedisplay () - ) - else ( - Glut.setCursor Glut.CURSOR_RIGHT_ARROW; - state.mstate <- Mnone; - ) - ) + let dest = if bstate = Glut.DOWN then getlink x y else None in + begin match dest with + | Some (pageno, top) -> + gotopage pageno top + + | None -> + if bstate = Glut.DOWN + then ( + Glut.setCursor Glut.CURSOR_CROSSHAIR; + state.mstate <- Msel ((x, y), (x, y)); + Glut.postRedisplay () + ) + else ( + Glut.setCursor Glut.CURSOR_RIGHT_ARROW; + state.mstate <- Mnone; + ) + end | _ -> () @@ -1022,13 +1041,11 @@ let motion ~x ~y = let pmotion ~x ~y = match state.mstate with + | Mnone when (checklink x y) -> + Glut.setCursor Glut.CURSOR_INFO + | Mnone -> - let pageno = getlink x y in - if pageno = -1 - then - Glut.setCursor Glut.CURSOR_RIGHT_ARROW - else - Glut.setCursor Glut.CURSOR_INFO + Glut.setCursor Glut.CURSOR_RIGHT_ARROW | Msel (a, _) -> () -- 2.11.4.GIT