emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/pdf-tools 8ddf4c7098 2/3: Make selection style configurabl


From: ELPA Syncer
Subject: [nongnu] elpa/pdf-tools 8ddf4c7098 2/3: Make selection style configurable by introducing a new variable
Date: Mon, 16 Jan 2023 13:59:54 -0500 (EST)

branch: elpa/pdf-tools
commit 8ddf4c709829ea0225771891a7b404900768d9f1
Author: lennonhill <@>
Commit: Vedang Manerikar <ved.manerikar@gmail.com>

    Make selection style configurable by introducing a new variable
    
    Make selection-style configurable via `pdf-view-selection-style`. A
    default value of `word` might be desirable, as selection is usually
    intended to select entire words is perceptually faster than
    glyph-based selection.
    
    This affects selections and highlights, but not search.
    
    Limitation:
    The selection type is fixed for all currently selected regions.
    Selecting multiple regions with different selection styles at the same
    time would require storing the selection style for every region and
    replacing the protocol for `cmd_addannot` with a more flexible one,
    e.g. the keyword-based one used by `cmd_renderpage`.
    
    Closes: #73
---
 lisp/pdf-annot.el     |  6 ++++--
 lisp/pdf-cache.el     |  4 ++--
 lisp/pdf-info.el      | 42 +++++++++++++++++++++++++-----------------
 lisp/pdf-isearch.el   |  2 +-
 lisp/pdf-view.el      | 29 ++++++++++++++++++++++++-----
 server/epdfinfo.c     | 40 +++++++++++++++++++++++++++++-----------
 test/pdf-info-test.el |  9 +++++----
 7 files changed, 90 insertions(+), 42 deletions(-)

diff --git a/lisp/pdf-annot.el b/lisp/pdf-annot.el
index 7140e9ae14..3b6359342e 100644
--- a/lisp/pdf-annot.el
+++ b/lisp/pdf-annot.el
@@ -1052,7 +1052,8 @@ Return the new annotation."
   (when (and (eq type 'text)
              (> (length edges) 1))
     (error "Edges argument should be a single edge-list for text annotations"))
-  (let* ((a (apply #'pdf-info-addannot
+  (let* ((selection-style pdf-view-selection-style)
+         (a (apply #'pdf-info-addannot
                    page
                    (if (eq type 'text)
                        (car edges)
@@ -1060,9 +1061,10 @@ Return the new annotation."
                             (apply #'append
                                    (mapcar
                                     (lambda (e)
-                                      (pdf-info-getselection page e))
+                                      (pdf-info-getselection page e 
selection-style))
                                     edges))))
                    type
+                   selection-style
                    nil
                    (if (not (eq type 'text)) edges)))
          (id (pdf-annot-get-id a)))
diff --git a/lisp/pdf-cache.el b/lisp/pdf-cache.el
index 650ff36acc..9c25e07d04 100644
--- a/lisp/pdf-cache.el
+++ b/lisp/pdf-cache.el
@@ -332,13 +332,13 @@ See also `pdf-info-renderpage-text-regions' and
 `pdf-cache-renderpage'."
   (if pdf-cache-image-inihibit
       (apply #'pdf-info-renderpage-text-regions
-             page width single-line-p nil selection)
+             page width single-line-p nil nil selection)
     (let ((hash (sxhash
                  (format "%S" (cons 'renderpage-text-regions
                                     (cons single-line-p selection))))))
       (or (pdf-cache-get-image page width width hash)
           (let ((data (apply #'pdf-info-renderpage-text-regions
-                             page width single-line-p nil selection)))
+                             page width single-line-p nil nil selection)))
             (pdf-cache-put-image page width data hash)
             data)))))
 
diff --git a/lisp/pdf-info.el b/lisp/pdf-info.el
index 40dfc3d17f..d3e17bf07d 100644
--- a/lisp/pdf-info.el
+++ b/lisp/pdf-info.el
@@ -1247,6 +1247,17 @@ of this element in the tree."
    'outline
    (pdf-info--normalize-file-or-buffer file-or-buffer)))
 
+(defun pdf-info--selection-style (selection-style)
+  "SELECTION-STYLE is the smallest unit of the selected region.
+
+It must be one of glyph, word or line. If it is none of these, we
+fallback to glyph."
+  (cl-case selection-style
+    (glyph 0)
+    (word 1)
+    (line 2)
+    (t 0)))
+
 (defun pdf-info-gettext (page edges &optional selection-style
                               file-or-buffer)
   "Get text on PAGE according to EDGES.
@@ -1263,30 +1274,21 @@ Return the text contained in the selection."
    (pdf-info--normalize-file-or-buffer file-or-buffer)
    page
    (mapconcat #'number-to-string edges " ")
-   (cl-case selection-style
-     (glyph 0)
-     (word 1)
-     (line 2)
-     (t 0))))
-
-(defun pdf-info-getselection (page edges &optional selection-style
-                                   file-or-buffer)
+   (pdf-info--selection-style selection-style)))
+
+(defun pdf-info-getselection (page edges
+                                   &optional selection-style file-or-buffer)
   "Return the edges of the selection EDGES on PAGE.
 
 Arguments are the same as for `pdf-info-gettext'.  Return a list
 of edges corresponding to the text that would be returned by the
 aforementioned function, when called with the same arguments."
-
   (pdf-info-query
    'getselection
    (pdf-info--normalize-file-or-buffer file-or-buffer)
    page
    (mapconcat #'number-to-string edges " ")
-   (cl-case selection-style
-     (glyph 0)
-     (word 1)
-     (line 2)
-     (t 0))))
+   (pdf-info--selection-style selection-style)))
 
 (defun pdf-info-textregions (page &optional file-or-buffer)
   "Return a list of edges describing PAGE's text-layout."
@@ -1419,7 +1421,9 @@ function."
    (pdf-info--normalize-file-or-buffer file-or-buffer)
    id))
 
-(defun pdf-info-addannot (page edges type &optional file-or-buffer &rest 
markup-edges)
+(defun pdf-info-addannot (page edges type
+                               &optional selection-style file-or-buffer
+                               &rest markup-edges)
   "Add a new annotation to PAGE with EDGES of TYPE.
 
 FIXME: TYPE may be one of `text', `markup-highlight', ... .
@@ -1436,6 +1440,7 @@ returns."
    (pdf-info--normalize-file-or-buffer file-or-buffer)
    page
    type
+   (pdf-info--selection-style selection-style)
    (mapconcat 'number-to-string edges " ")
    (mapcar (lambda (me)
              (mapconcat 'number-to-string me " "))
@@ -1610,6 +1615,8 @@ Return the data of the corresponding PNG image."
                    (pdf-util-hexcolor value))
                   (:alpha
                    (number-to-string value))
+                  (:selection-style
+                   (number-to-string (pdf-info--selection-style value)))
                   (otherwise value)))
           (push kw transformed)
           (push value transformed)))
@@ -1618,14 +1625,14 @@ Return the data of the corresponding PNG image."
       (nreverse transformed))))
 
 (defun pdf-info-renderpage-text-regions (page width single-line-p
-                                              &optional file-or-buffer
+                                              &optional selection-style 
file-or-buffer
                                               &rest regions)
   "Highlight text on PAGE with width WIDTH using REGIONS.
 
 REGIONS is a list determining foreground and background color and
 the regions to render. So each element should look like \(FG BG
 \(LEFT TOP RIGHT BOT\) \(LEFT TOP RIGHT BOT\) ... \) . The
-rendering is text-aware.
+rendering is text-aware and is controlled by SELECTION-STYLE.
 
 If SINGLE-LINE-P is non-nil, the edges in REGIONS are each
 supposed to be limited to a single line in the document.  Setting
@@ -1642,6 +1649,7 @@ Return the data of the corresponding PNG image."
   (apply #'pdf-info-renderpage
     page width file-or-buffer
     (apply #'append
+      `(:selection-style ,selection-style)
       (mapcar (lambda (elt)
                 `(:foreground ,(pop elt)
                   :background ,(pop elt)
diff --git a/lisp/pdf-isearch.el b/lisp/pdf-isearch.el
index 4d87a2e435..f5468eb56a 100644
--- a/lisp/pdf-isearch.el
+++ b/lisp/pdf-isearch.el
@@ -745,7 +745,7 @@ MATCH-BG LAZY-FG LAZY-BG\)."
                     (pdf-view-display-image
                      (pdf-view-create-image data :width width))))))))
       (pdf-info-renderpage-text-regions
-       page width t nil
+       page width t nil nil
        `(,fg1 ,bg1 ,@(pdf-util-scale-pixel-to-relative
                       current))
        `(,fg2 ,bg2 ,@(pdf-util-scale-pixel-to-relative
diff --git a/lisp/pdf-view.el b/lisp/pdf-view.el
index 849be6a713..5cf7ac7daf 100644
--- a/lisp/pdf-view.el
+++ b/lisp/pdf-view.el
@@ -188,6 +188,15 @@ Issue a warning, if one of them is active in a PDF buffer."
   :group 'pdf-view
   :type '(repeat symbol))
 
+(defcustom pdf-view-selection-style 'glyph
+  "The current default selection style.
+
+Must be one of `glyph', `word', or `line'."
+  :group 'pdf-view
+  :type '(choice (const glyph)
+                 (const word)
+                 (const line)))
+
 
 ;; * ================================================================== *
 ;; * Internal variables and macros
@@ -1338,13 +1347,17 @@ Deactivate the region if DEACTIVATE-P is non-nil."
     (pdf-view-redisplay t)))
 
 (defun pdf-view-mouse-set-region (event &optional allow-extend-p
-                                        rectangle-p)
+                                        rectangle-p
+                                        selection-style)
   "Select a region of text using the mouse with mouse event EVENT.
 
 Allow for stacking of regions, if ALLOW-EXTEND-P is non-nil.
 
 Create a rectangular region, if RECTANGLE-P is non-nil.
 
+Overwrite `pdf-view-selection-style' with SELECTION-STYLE,
+which is one of `glyph', `word', or `line'.
+
 Stores the region in `pdf-view-active-region'."
   (interactive "@e")
   (setq pdf-view--have-rectangle-region rectangle-p)
@@ -1366,6 +1379,7 @@ Stores the region in `pdf-view-active-region'."
                   (setq begin-inside-image-p nil)
                   (posn-x-y pos)))
          (abs-begin (posn-x-y pos))
+         (selection-style (or selection-style pdf-view-selection-style))
          pdf-view-continuous
          region)
     (when (pdf-util-track-mouse-dragging (event 0.05)
@@ -1418,7 +1432,8 @@ Stores the region in `pdf-view-active-region'."
                         (pdf-util-scale-pixel-to-relative iregion))
                   (pdf-view-display-region
                    (cons region pdf-view-active-region)
-                   rectangle-p)
+                   rectangle-p
+                   selection-style)
                   (pdf-util-scroll-to-edges iregion)))))
       (setq pdf-view-active-region
             (append pdf-view-active-region
@@ -1441,7 +1456,7 @@ This is more useful for commands like
   (interactive "@e")
   (pdf-view-mouse-set-region event nil t))
 
-(defun pdf-view-display-region (&optional region rectangle-p)
+(defun pdf-view-display-region (&optional region rectangle-p selection-style)
   ;; TODO: write documentation!
   (unless region
     (pdf-view-assert-active-region)
@@ -1458,7 +1473,7 @@ This is more useful for commands like
               page width nil
               `(,(car colors) ,(cdr colors) 0.35 ,@region))
            (pdf-info-renderpage-text-regions
-            page width nil nil
+            page width nil selection-style nil
             `(,(car colors) ,(cdr colors) ,@region)))
        :width width))))
 
@@ -1483,7 +1498,11 @@ This is more useful for commands like
   "Return the text of the active region as a list of strings."
   (pdf-view-assert-active-region)
   (mapcar
-   (apply-partially 'pdf-info-gettext (pdf-view-current-page))
+   (lambda (edges)
+     (pdf-info-gettext
+      (pdf-view-current-page)
+      edges
+      pdf-view-selection-style))
    pdf-view-active-region))
 
 (defun pdf-view-extract-region-image (regions &optional page size
diff --git a/server/epdfinfo.c b/server/epdfinfo.c
index a5c1359e00..32898fa9fc 100644
--- a/server/epdfinfo.c
+++ b/server/epdfinfo.c
@@ -1367,12 +1367,15 @@ annotation_markup_get_text_regions (PopplerPage *page, 
PopplerAnnotTextMarkup *a
  *
  * @param page The page of the annotation.  This is used to get the
  *             text regions and pagesize.
+ * @param selection_style The selection style.
  * @param region The region to add.
  * @param garray[in,out] An array of PopplerQuadrilateral, where the
  *              new quadrilaterals will be appended.
  */
 static void
-annotation_markup_append_text_region (PopplerPage *page, PopplerRectangle 
*region,
+annotation_markup_append_text_region (PopplerPage *page,
+                                     PopplerSelectionStyle selection_style,
+                                     PopplerRectangle *region,
                                       GArray *garray)
 {
   gdouble height;
@@ -1380,7 +1383,7 @@ annotation_markup_append_text_region (PopplerPage *page, 
PopplerRectangle *regio
      replacement.  (poppler_page_get_selected_region returns a union
      of rectangles.) */
   GList *regions =
-    poppler_page_get_selection_region (page, 1.0, POPPLER_SELECTION_GLYPH, 
region);
+    poppler_page_get_selection_region (page, 1.0, selection_style, region);
   GList *item;
 
   poppler_page_get_size (page, NULL, &height);
@@ -1409,6 +1412,7 @@ annotation_markup_append_text_region (PopplerPage *page, 
PopplerRectangle *regio
  *
  * @param doc The document for which to create it.
  * @param type The type of the annotation.
+ * @param selection_style The selection style.
  * @param r The rectangle where annotation will end up on the page.
  *
  * @return The new annotation, or NULL, if the annotation type is
@@ -1416,8 +1420,9 @@ annotation_markup_append_text_region (PopplerPage *page, 
PopplerRectangle *regio
  */
 static PopplerAnnot*
 annotation_new (const epdfinfo_t *ctx, document_t *doc, PopplerPage *page,
-                const char *type, PopplerRectangle *r,
-                const command_arg_t *rest, char **error_msg)
+                const char *type, PopplerSelectionStyle selection_style,
+                PopplerRectangle *r, const command_arg_t *rest,
+                char **error_msg)
 {
 
   PopplerAnnot *a = NULL;
@@ -1448,7 +1453,7 @@ annotation_new (const epdfinfo_t *ctx, document_t *doc, 
PopplerPage *page,
                                            ARG_EDGES, error_msg));
       rr->x1 *= width; rr->x2 *= width;
       rr->y1 *= height; rr->y2 *= height;
-      annotation_markup_append_text_region (page, rr, garray);
+      annotation_markup_append_text_region (page, selection_style, rr, garray);
     }
   cerror_if_not (garray->len > 0, error_msg, "%s",
                  "Unable to create empty markup annotation");
@@ -2339,7 +2344,7 @@ cmd_gettext(const epdfinfo_t *ctx, const command_arg_t 
*args)
   double width, height;
   gchar *text = NULL;
 
-  selection_style = xpoppler_validate_selection_style(selection_style);
+  selection_style = xpoppler_validate_selection_style (selection_style);
   page = poppler_document_get_page (doc, pn - 1);
   perror_if_not (page, "No such page %d", pn);
   poppler_page_get_size (page, &width, &height);
@@ -2381,7 +2386,7 @@ const command_arg_type_t cmd_getselection_spec[] =
   {
     ARG_DOC,
     ARG_NATNUM,                 /* page number */
-    ARG_EDGES,       /* selection */
+    ARG_EDGES,                  /* selection */
     ARG_NATNUM                  /* selection-style */
   };
 
@@ -2397,7 +2402,7 @@ cmd_getselection (const epdfinfo_t *ctx, const 
command_arg_t *args)
   PopplerPage *page = NULL;
   int i;
 
-  selection_style = xpoppler_validate_selection_style(selection_style);
+  selection_style = xpoppler_validate_selection_style (selection_style);
   page = poppler_document_get_page (doc, pn - 1);
   perror_if_not (page, "No such page %d", pn);
   poppler_page_get_size (page, &width, &height);
@@ -2650,6 +2655,7 @@ const command_arg_type_t cmd_addannot_spec[] =
     ARG_DOC,
     ARG_NATNUM,                 /* page number */
     ARG_STRING,                 /* type */
+    ARG_NATNUM,                 /* selection-style */
     ARG_EDGES_OR_POSITION,      /* edges or position (uses default size) */
     ARG_REST,                  /* markup regions */
   };
@@ -2661,7 +2667,8 @@ cmd_addannot (const epdfinfo_t *ctx, const command_arg_t 
*args)
   document_t *doc = args->value.doc;
   gint pn = args[1].value.natnum;
   const char *type_string = args[2].value.string;
-  PopplerRectangle r = args[3].value.rectangle;
+  int selection_style = args[3].value.natnum;
+  PopplerRectangle r = args[4].value.rectangle;
   int i;
   PopplerPage *page = NULL;
   double width, height;
@@ -2673,6 +2680,7 @@ cmd_addannot (const epdfinfo_t *ctx, const command_arg_t 
*args)
   gdouble y2;
   char *error_msg = NULL;
 
+  selection_style = xpoppler_validate_selection_style (selection_style);
   page = poppler_document_get_page (doc->pdf, pn - 1);
   perror_if_not (page, "Unable to get page %d", pn);
   poppler_page_get_size (page, &width, &height);
@@ -2686,7 +2694,8 @@ cmd_addannot (const epdfinfo_t *ctx, const command_arg_t 
*args)
   r.y2 = height - r.y1;
   r.y1 = height - y2;
 
-  pa = annotation_new (ctx, doc, page, type_string, &r, &args[4], &error_msg);
+  pa = annotation_new (ctx, doc, page, type_string, selection_style, &r, 
&args[5],
+                       &error_msg);
   perror_if_not (pa, "Creating annotation failed: %s",
                  error_msg ? error_msg : "Reason unknown");
   amap = poppler_annot_mapping_new ();
@@ -3080,6 +3089,7 @@ cmd_renderpage (const epdfinfo_t *ctx, const 
command_arg_t *args)
   PopplerColor bg = { 65535, 0, 0 };
   double alpha = 1.0;
   double line_width = 1.5;
+  PopplerSelectionStyle selection_style = POPPLER_SELECTION_GLYPH;
   PopplerRectangle cb = {0.0, 0.0, 1.0, 1.0};
   int i = 0;
 
@@ -3208,10 +3218,18 @@ cmd_renderpage (const epdfinfo_t *ctx, const 
command_arg_t *args)
                     }
 
                   poppler_page_render_selection (page, cr, r, NULL,
-                                                 POPPLER_SELECTION_GLYPH, &fg, 
&bg);
+                                                 selection_style, &fg, &bg);
                 }
             }
         }
+      else if (! strcmp (keyword, ":selection-style"))
+        {
+          perror_if_not (command_arg_parse_arg (ctx, rest_args[i], &rest_arg,
+                                                ARG_NATNUM, &error_msg),
+                         "%s", error_msg);
+          ++i;
+         selection_style = xpoppler_validate_selection_style 
(rest_arg.value.natnum);
+        }
       else
         perror_if_not (0, "Unknown render command: %s", keyword);
     }
diff --git a/test/pdf-info-test.el b/test/pdf-info-test.el
index a8f9de9042..bdf807413d 100644
--- a/test/pdf-info-test.el
+++ b/test/pdf-info-test.el
@@ -164,10 +164,11 @@
             annots)
       (when (memq 'markup-annotations
                   (pdf-info-features))
-        (push (pdf-info-addannot 1 '(0 0 1 1) 'squiggly '(0 0 1 1)) annots)
-        (push (pdf-info-addannot 1 '(0 0 1 1) 'highlight '(0 0 1 1)) annots)
-        (push (pdf-info-addannot 1 '(0 0 1 1) 'underline '(0 0 1 1)) annots)
-        (push (pdf-info-addannot 1 '(0 0 1 1) 'strike-out '(0 0 1 1)) annots))
+
+         (push (pdf-info-addannot 1 '(0 0 1 1) 'squiggly nil nil '(0 0 1 1)) 
annots)
+         (push (pdf-info-addannot 1 '(0 0 1 1) 'highlight 'word nil '(0 0 1 
1)) annots)
+         (push (pdf-info-addannot 1 '(0 0 1 1) 'underline 'line nil '(0 0 1 
1)) annots)
+        (push (pdf-info-addannot 1 '(0 0 1 1) 'strike-out 'glyph nil '(0 0 1 
1)) annots))
       (dolist (a annots)
         (pdf-info-delannot (cdr (assq 'id a))))
       (should (= nannots (length (pdf-info-getannots)))))))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]