From ad2017ebe607437d95dd9daf0bda9b74d97ef2bd Mon Sep 17 00:00:00 2001 From: malc Date: Sat, 2 Oct 2010 04:00:56 +0400 Subject: [PATCH] Add "What's under the cursor" information --- KEYS | 2 ++ link.c | 59 ++++++++++++++++++++++++++++++++++++++++++----------------- main.ml | 48 +++++++++++++++++++++++++++++++++--------------- 3 files changed, 77 insertions(+), 32 deletions(-) diff --git a/KEYS b/KEYS index 4e0a99a..73b3eac 100644 --- a/KEYS +++ b/KEYS @@ -38,6 +38,8 @@ tuanbles -p - toggle preloading -v - toggle verbosity -h - toggle maxfit +-f - toggle whats under cursor identification + (only font name currently) outline mode alpha-numeric - quick search diff --git a/link.c b/link.c index 647481a..edfd3a2 100644 --- a/link.c +++ b/link.c @@ -1277,7 +1277,22 @@ CAMLprim value ml_highlightlinks (value ptr_v, value yoff_v) CAMLreturn (Val_unit); } -CAMLprim value ml_getlink (value ptr_v, value x_v, value y_v) +static void ensuretext (struct page *page) +{ + if (!page->text) { + fz_error error; + fz_device *tdev; + + page->text = fz_newtextspan (); + tdev = fz_newtextdevice (page->text); + error = pdf_runpage (state.xref, page->drawpage, tdev, + page->pagedim->ctm); + if (error) die (error); + fz_freedevice (tdev); + } +} + +CAMLprim value ml_whatsunder (value ptr_v, value x_v, value y_v) { CAMLparam3 (ptr_v, x_v, y_v); CAMLlocal2 (ret_v, tup_v); @@ -1286,13 +1301,12 @@ CAMLprim value ml_getlink (value ptr_v, value x_v, value y_v) char *s = String_val (ptr_v); ret_v = Val_int (0); - if (trylock ("ml_getlink")) { + if (trylock ("ml_whatsunder")) { ret_v = Val_int (0); goto done; } - page = parse_pointer ("ml_getlink", s); - + page = parse_pointer ("ml_whatsunder", s); link = getlink (page, Int_val (x_v), Int_val (y_v)); if (link) { switch (link->kind) { @@ -1343,7 +1357,29 @@ CAMLprim value ml_getlink (value ptr_v, value x_v, value y_v) break; } } - unlock ("ml_getlink"); + else { + int i, x, y; + fz_textspan *span; + + ensuretext (page); + x = Int_val (x_v) + page->pixmap->x; + y = Int_val (y_v) + page->pixmap->y; + + for (span = page->text; span; span = span->next) { + for (i = 0; i < span->len; ++i) { + fz_bbox *b; + b = &span->text[i].bbox; + if (x >= b->x0 && x <= b->x1 && y >= b->y0 && y <= b->y1) { + ret_v = caml_alloc_small (1, 2); + Field (ret_v, 0) = caml_copy_string (span->font->name); + goto exit; + } + } + } + + exit: (void) 0; + } + unlock ("ml_whatsunder"); done: CAMLreturn (ret_v); @@ -1364,6 +1400,7 @@ CAMLprim value ml_seltext (value ptr_v, value rect_v, value oy_v) } page = parse_pointer ("ml_seltext", s); + ensuretext (page); oy = Int_val (oy_v); x0 = Int_val (Field (rect_v, 0)); @@ -1378,18 +1415,6 @@ CAMLprim value ml_seltext (value ptr_v, value rect_v, value oy_v) glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); } - if (!page->text) { - fz_error error; - fz_device *tdev; - - page->text = fz_newtextspan (); - tdev = fz_newtextdevice (page->text); - error = pdf_runpage (state.xref, page->drawpage, tdev, - page->pagedim->ctm); - if (error) die (error); - fz_freedevice (tdev); - } - x0 += page->pixmap->x; y0 += page->pixmap->y - oy; x1 += page->pixmap->x; diff --git a/main.ml b/main.ml index ec38ae0..22cff04 100644 --- a/main.ml +++ b/main.ml @@ -1,4 +1,9 @@ -type link = | LNone | LUri of string | LGoto of (int * int);; +type under = + | Unone + | Ulinkuri of string + | Ulinkgoto of (int * int) + | Utext of facename +and facename = string;; let log fmt = Printf.kprintf prerr_endline fmt;; let dolog fmt = Printf.kprintf prerr_endline fmt;; @@ -8,9 +13,9 @@ external draw : int -> int -> int -> int -> string -> unit = "ml_draw";; external seltext : string -> (int * int * int * int) -> int -> unit = "ml_seltext";; external copysel : string -> unit = "ml_copysel";; -external getlink : string -> int -> int -> link = "ml_getlink";; external highlightlinks : string -> int -> unit = "ml_highlightlinks";; external getpagewh : int -> float array = "ml_getpagewh";; +external whatsunder : string -> int -> int -> under = "ml_whatsunder";; type mstate = Msel of ((int * int) * (int * int)) | Mnone;; @@ -90,6 +95,7 @@ type conf = ; mutable autoscroll : bool ; mutable showall : bool ; mutable hlinks : bool + ; mutable underinfo : bool } ;; @@ -152,6 +158,7 @@ let conf = ; autoscroll = false ; showall = false ; hlinks = false + ; underinfo = false } ;; @@ -774,6 +781,10 @@ let optentry text key = conf.showall <- not conf.showall; TEdone ("showall " ^ btos conf.showall) + | 'f' -> + conf.underinfo <- not conf.underinfo; + TEdone ("underinfo " ^ btos conf.underinfo) + | _ -> state.text <- Printf.sprintf "bad option %d `%c'" key c; TEstop @@ -1543,7 +1554,7 @@ let display () = Glut.swapBuffers (); ;; -let getlink x y = +let getunder x y = let rec f = function | l :: rest -> begin match getopaque l.pageno with @@ -1552,15 +1563,15 @@ let getlink x y = if y > 0 then let y = l.pagey + y in - match getlink opaque x y with - | LNone -> f rest - | link -> link + match whatsunder opaque x y with + | Unone -> f rest + | under -> under else f rest | _ -> f rest end - | [] -> LNone + | [] -> Unone in f state.layout ;; @@ -1580,21 +1591,24 @@ let mouse ~button ~bstate ~x ~y = gotoy y | Glut.LEFT_BUTTON when state.outline = None -> - let dest = if bstate = Glut.DOWN then getlink x y else LNone in + let dest = if bstate = Glut.DOWN then getunder x y else Unone in begin match dest with - | LGoto (pageno, top) -> + | Ulinkgoto (pageno, top) -> if pageno >= 0 then gotopage pageno top - | LUri s -> + | Ulinkuri s -> print_endline s - | LNone -> + | Unone when bstate = Glut.DOWN -> + Glut.setCursor Glut.CURSOR_INHERIT; + state.mstate <- Mnone + + | Unone | Utext _ -> if bstate = Glut.DOWN then ( if state.rotate mod 360 = 0 then ( - Glut.setCursor Glut.CURSOR_TEXT; state.mstate <- Msel ((x, y), (x, y)); Glut.postRedisplay () ) @@ -1639,9 +1653,13 @@ let pmotion ~x ~y = then match state.mstate with | Mnone -> - if getlink x y != LNone - then Glut.setCursor Glut.CURSOR_INFO - else Glut.setCursor Glut.CURSOR_INHERIT + begin match getunder x y with + | Unone -> Glut.setCursor Glut.CURSOR_INHERIT + | Ulinkuri _ | Ulinkgoto _ -> Glut.setCursor Glut.CURSOR_INFO + | Utext s -> + if conf.underinfo then showtext 'f' ("ont: " ^ s); + Glut.setCursor Glut.CURSOR_TEXT + end | Msel (a, _) -> () -- 2.11.4.GIT