Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make selection-style configurable #73

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions lisp/pdf-annot.el
Original file line number Diff line number Diff line change
Expand Up @@ -1053,17 +1053,19 @@ 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)
(apply #'pdf-util-edges-union
(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)))
Expand Down
4 changes: 2 additions & 2 deletions lisp/pdf-cache.el
Original file line number Diff line number Diff line change
Expand Up @@ -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)))))

Expand Down
19 changes: 16 additions & 3 deletions lisp/pdf-info.el
Original file line number Diff line number Diff line change
Expand Up @@ -1413,7 +1413,7 @@ 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', ... .
Expand All @@ -1430,6 +1430,11 @@ returns."
(pdf-info--normalize-file-or-buffer file-or-buffer)
page
type
(cl-case selection-style
(glyph 0)
(word 1)
(line 2)
(t 0))
(mapconcat 'number-to-string edges " ")
(mapcar (lambda (me)
(mapconcat 'number-to-string me " "))
Expand Down Expand Up @@ -1604,6 +1609,12 @@ Return the data of the corresponding PNG image."
(pdf-util-hexcolor value))
(:alpha
(number-to-string value))
(:selection-style
(number-to-string (cl-case value
(glyph 0)
(word 1)
(line 2)
(t 0))))
(otherwise value)))
(push kw transformed)
(push value transformed)))
Expand All @@ -1612,14 +1623,15 @@ 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
Expand All @@ -1636,6 +1648,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)
Expand Down
2 changes: 1 addition & 1 deletion lisp/pdf-isearch.el
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
28 changes: 23 additions & 5 deletions lisp/pdf-view.el
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1305,13 +1314,16 @@ 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)
Expand All @@ -1333,6 +1345,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)
Expand Down Expand Up @@ -1385,7 +1398,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
Expand All @@ -1408,7 +1422,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)
Expand All @@ -1425,7 +1439,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))))

Expand All @@ -1450,7 +1464,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
Expand Down
69 changes: 45 additions & 24 deletions server/epdfinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,26 @@ xpoppler_annot_text_state_string (PopplerAnnotTextState state)
}
};

/**
* Validate a PopplerSelectionStyle by replacing invalid styles
* with a default of POPPLER_SELECTION_GLYPH.
*
* @param selection_style The selection style.
*
* @return selection_style for valid styles, otherwise POPPLER_SELECTION_GLYPH.
*/
static PopplerSelectionStyle
xpoppler_validate_selection_style (int selection_style)
{
switch (selection_style) {
case POPPLER_SELECTION_GLYPH:
case POPPLER_SELECTION_WORD:
case POPPLER_SELECTION_LINE:
return selection_style;
}
return POPPLER_SELECTION_GLYPH;
}

static document_t*
document_open (const epdfinfo_t *ctx, const char *filename,
const char *passwd, GError **gerror)
Expand Down Expand Up @@ -1367,20 +1387,22 @@ 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,
GArray *garray)
annotation_markup_append_text_region (PopplerPage *page,
PopplerSelectionStyle selection_style,
PopplerRectangle *region, GArray *garray)
{
gdouble height;
/* poppler_page_get_selection_region is deprecated w/o a
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);
Expand Down Expand Up @@ -1410,14 +1432,15 @@ 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
* not available.
*/
static PopplerAnnot*
annotation_new (const epdfinfo_t *ctx, document_t *doc, PopplerPage *page,
const char *type, PopplerRectangle *r,
const char *type, PopplerSelectionStyle selection_style, PopplerRectangle *r,
const command_arg_t *rest, char **error_msg)
{

Expand Down Expand Up @@ -1449,7 +1472,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");
Expand Down Expand Up @@ -2337,14 +2360,7 @@ cmd_gettext(const epdfinfo_t *ctx, const command_arg_t *args)
double width, height;
gchar *text = NULL;

switch (selection_style)
{
case POPPLER_SELECTION_GLYPH: break;
case POPPLER_SELECTION_LINE: break;
case POPPLER_SELECTION_WORD: break;
default: selection_style = POPPLER_SELECTION_GLYPH;
}

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);
Expand Down Expand Up @@ -2402,14 +2418,7 @@ cmd_getselection (const epdfinfo_t *ctx, const command_arg_t *args)
PopplerPage *page = NULL;
int i;

switch (selection_style)
{
case POPPLER_SELECTION_GLYPH: break;
case POPPLER_SELECTION_LINE: break;
case POPPLER_SELECTION_WORD: break;
default: selection_style = POPPLER_SELECTION_GLYPH;
}

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);
Expand Down Expand Up @@ -2662,6 +2671,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 */
};
Expand All @@ -2673,7 +2683,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;
Expand All @@ -2685,6 +2696,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);
Expand All @@ -2698,7 +2710,7 @@ 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 ();
Expand Down Expand Up @@ -3092,6 +3104,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;

Expand Down Expand Up @@ -3220,10 +3233,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);
}
Expand Down
9 changes: 5 additions & 4 deletions test/pdf-info-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -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)))))))
Expand Down