update of packages
This commit is contained in:
@@ -11,47 +11,54 @@
|
||||
|
||||
The ~pdf-tools~ Wiki is maintained at https://pdftools.wiki. Head to the site if you find it easier to navigate a website for reading a manual. All the topics on the site are listed at https://pdftools.wiki/impulse.
|
||||
|
||||
* Table of Contents :noexport:TOC_3_org:
|
||||
- [[About PDF Tools][About PDF Tools]]
|
||||
- [[Installing pdf-tools][Installing pdf-tools]]
|
||||
- [[Installing the epdfinfo server][Installing the epdfinfo server]]
|
||||
- [[Installing the epdfinfo server from package managers][Installing the epdfinfo server from package managers]]
|
||||
- [[Installing the epdfinfo server from source on Windows (+ Gotchas)][Installing the epdfinfo server from source on Windows (+ Gotchas)]]
|
||||
- [[Installing the epdfinfo server from source on macOS (+ Gotchas)][Installing the epdfinfo server from source on macOS (+ Gotchas)]]
|
||||
- [[Common installation gotchas][Common installation gotchas]]
|
||||
- [[Installing optional features][Installing optional features]]
|
||||
- [[Installing pdf-tools elisp code][Installing pdf-tools elisp code]]
|
||||
- [[Updating pdf-tools][Updating pdf-tools]]
|
||||
- [[Features][Features]]
|
||||
- [[View and Navigate PDFs][View and Navigate PDFs]]
|
||||
- [[Keybindings for navigating PDF documents][Keybindings for navigating PDF documents]]
|
||||
- [[Keybindings for manipulating display of PDF][Keybindings for manipulating display of PDF]]
|
||||
- [[Annotations][Annotations]]
|
||||
- [[Keybindings for working with Annotations][Keybindings for working with Annotations]]
|
||||
- [[Working with AUCTeX][Working with AUCTeX]]
|
||||
- [[Keybindings for working with AUCTeX][Keybindings for working with AUCTeX]]
|
||||
- [[Miscellaneous features][Miscellaneous features]]
|
||||
- [[Keybindings for miscellaneous features in PDF tools][Keybindings for miscellaneous features in PDF tools]]
|
||||
- [[Easy Help for PDF Tools features][Easy Help for PDF Tools features]]
|
||||
- [[Configuring PDF Tools features][Configuring PDF Tools features]]
|
||||
- [[Known problems][Known problems]]
|
||||
- [[linum-mode][linum-mode]]
|
||||
- [[display-line-numbers-mode][display-line-numbers-mode]]
|
||||
- [[auto-revert][auto-revert]]
|
||||
- [[sublimity][sublimity]]
|
||||
- [[Text selection is not transparent in PDFs OCRed with Tesseract][Text selection is not transparent in PDFs OCRed with Tesseract]]
|
||||
- [[Key-bindings in PDF Tools][Key-bindings in PDF Tools]]
|
||||
- [[Tips and Tricks for Developers][Tips and Tricks for Developers]]
|
||||
- [[Turn on debug mode][Turn on debug mode]]
|
||||
- [[Run Emacs lisp tests locally][Run Emacs lisp tests locally]]
|
||||
- [[Run server compilation tests locally][Run server compilation tests locally]]
|
||||
- [[Add a Dockerfile to automate server compilation testing][Add a Dockerfile to automate server compilation testing]]
|
||||
- [[FAQs][FAQs]]
|
||||
- [[PDFs are not rendering well!][PDFs are not rendering well!]]
|
||||
- [[What Emacs versions does pdf-tools support?][What Emacs versions does pdf-tools support?]]
|
||||
- [[I want to add support for pdf-tools on "My Fav OS". How do I do that?][I want to add support for pdf-tools on "My Fav OS". How do I do that?]]
|
||||
- [[I am on a Macbook M1 and pdf-tools installation fails with a stack-trace][I am on a Macbook M1 and pdf-tools installation fails with a stack-trace]]
|
||||
- [[I am a developer, making changes to the pdf-tools source code][I am a developer, making changes to the pdf-tools source code]]
|
||||
* Table of Contents :noexport:TOC_3_gh:
|
||||
- [[#about-pdf-tools][About PDF Tools]]
|
||||
- [[#installing-pdf-tools][Installing pdf-tools]]
|
||||
- [[#installing-the-epdfinfo-server][Installing the epdfinfo server]]
|
||||
- [[#installing-the-epdfinfo-server-from-package-managers][Installing the epdfinfo server from package managers]]
|
||||
- [[#installing-the-epdfinfo-server-from-source-on-windows--gotchas][Installing the epdfinfo server from source on Windows (+ Gotchas)]]
|
||||
- [[#installing-the-epdfinfo-server-from-source-on-macos--gotchas][Installing the epdfinfo server from source on macOS (+ Gotchas)]]
|
||||
- [[#common-installation-gotchas][Common installation gotchas]]
|
||||
- [[#installing-optional-features][Installing optional features]]
|
||||
- [[#installing-pdf-tools-elisp-code][Installing pdf-tools elisp code]]
|
||||
- [[#updating-pdf-tools][Updating pdf-tools]]
|
||||
- [[#features][Features]]
|
||||
- [[#view-and-navigate-pdfs][View and Navigate PDFs]]
|
||||
- [[#keybindings-for-navigating-pdf-documents][Keybindings for navigating PDF documents]]
|
||||
- [[#keybindings-for-manipulating-display-of-pdf][Keybindings for manipulating display of PDF]]
|
||||
- [[#annotations][Annotations]]
|
||||
- [[#keybindings-for-working-with-annotations][Keybindings for working with Annotations]]
|
||||
- [[#working-with-auctex][Working with AUCTeX]]
|
||||
- [[#keybindings-for-working-with-auctex][Keybindings for working with AUCTeX]]
|
||||
- [[#miscellaneous-features][Miscellaneous features]]
|
||||
- [[#keybindings-for-miscellaneous-features-in-pdf-tools][Keybindings for miscellaneous features in PDF tools]]
|
||||
- [[#easy-help-for-pdf-tools-features][Easy Help for PDF Tools features]]
|
||||
- [[#configuring-pdf-tools-features][Configuring PDF Tools features]]
|
||||
- [[#known-problems][Known problems]]
|
||||
- [[#linum-mode][linum-mode]]
|
||||
- [[#display-line-numbers-mode][display-line-numbers-mode]]
|
||||
- [[#auto-revert][auto-revert]]
|
||||
- [[#sublimity][sublimity]]
|
||||
- [[#text-selection-is-not-transparent-in-pdfs-ocred-with-tesseract][Text selection is not transparent in PDFs OCRed with Tesseract]]
|
||||
- [[#key-bindings-in-pdf-tools][Key-bindings in PDF Tools]]
|
||||
- [[#tips-and-tricks-for-developers][Tips and Tricks for Developers]]
|
||||
- [[#turn-on-debug-mode][Turn on debug mode]]
|
||||
- [[#run-emacs-lisp-tests-locally][Run Emacs lisp tests locally]]
|
||||
- [[#run-server-compilation-tests-locally][Run server compilation tests locally]]
|
||||
- [[#add-a-dockerfile-to-automate-server-compilation-testing][Add a Dockerfile to automate server compilation testing]]
|
||||
- [[#issue-template-for-bug-reports][Issue Template for Bug Reports]]
|
||||
- [[#describe-the-bug][Describe the bug]]
|
||||
- [[#steps-to-reproduce-the-behaviour][Steps To Reproduce the behaviour:]]
|
||||
- [[#what-is-the-expected-behaviour][What is the expected behaviour?]]
|
||||
- [[#desktop][Desktop]]
|
||||
- [[#your-pdf-tools-install][Your pdf-tools install]]
|
||||
- [[#additional-context][Additional context]]
|
||||
- [[#faqs][FAQs]]
|
||||
- [[#pdfs-are-not-rendering-well][PDFs are not rendering well!]]
|
||||
- [[#what-emacs-versions-does-pdf-tools-support][What Emacs versions does pdf-tools support?]]
|
||||
- [[#i-want-to-add-support-for-pdf-tools-on-my-fav-os-how-do-i-do-that][I want to add support for pdf-tools on "My Fav OS". How do I do that?]]
|
||||
- [[#i-am-on-a-macbook-m1-and-pdf-tools-installation-fails-with-a-stack-trace][I am on a Macbook M1 and pdf-tools installation fails with a stack-trace]]
|
||||
- [[#i-am-a-developer-making-changes-to-the-pdf-tools-source-code][I am a developer, making changes to the pdf-tools source code]]
|
||||
|
||||
* About PDF Tools
|
||||
:PROPERTIES:
|
||||
@@ -218,7 +225,7 @@ This also applies when updating via MELPA / NonGNU ELPA (except for running the
|
||||
+ Follow :: Click on highlighted links, moving to some part of a different page, some external file, a website or any other URI. Links may also be followed by keyboard commands.
|
||||
+ Annotations :: Display and list text and markup annotations (like underline), edit their contents and attributes (e.g. color), move them around, delete them or create new ones and then save the modifications back to the PDF file. [[id:5fff6471-a933-46d7-8ae9-b2fa4a9de952][More information here]].
|
||||
+ Attachments :: Save files attached to the PDF-file or list them in a dired buffer.
|
||||
+ Outline :: Use ~imenu~ or a special buffer (~M-x pdf-outline~) to examine and navigate the PDF's outline.
|
||||
+ Outline :: Use ~imenu~ or a special buffer (=M-x pdf-outline=) to examine and navigate the PDF's outline.
|
||||
+ SyncTeX :: Jump from a position on a page directly to the TeX source and vice versa.
|
||||
+ Virtual :: Use a collection of documents as if it were one, big single PDF.
|
||||
+ Misc ::
|
||||
@@ -288,6 +295,8 @@ Note that ~pdf-tools~ renders the PDF as images inside Emacs. This means that al
|
||||
| Trim Margins (set slice to bounding box) | ~s b~ |
|
||||
| Reset Margins | ~s r~ |
|
||||
| Reset Zoom | ~0~ |
|
||||
| Rotate Page | ~R~ |
|
||||
|------------------------------------------+-----------------|
|
||||
|
||||
** Annotations
|
||||
:PROPERTIES:
|
||||
@@ -300,27 +309,30 @@ Note that ~pdf-tools~ renders the PDF as images inside Emacs. This means that al
|
||||
:CREATED: [2021-12-30 Thu 17:08]
|
||||
:ID: 243b3843-b912-430b-884a-641304755b92
|
||||
:END:
|
||||
| Annotations | |
|
||||
|--------------------------------------+---------------------------------------------------|
|
||||
| List Annotations | ~C-c C-a l~ |
|
||||
| Jump to Annotations from List | ~SPACE~ |
|
||||
| Mark Annotation for Deletion | ~d~ |
|
||||
| Delete Marked Annotations | ~x~ |
|
||||
| Unmark Annotations | ~u~ |
|
||||
| Close Annotation List | ~q~ |
|
||||
| Enable/Disable Following Annotations | ~C-c C-f~ |
|
||||
|--------------------------------------+---------------------------------------------------|
|
||||
| Add and Edit Annotations | Select region via Mouse selection. |
|
||||
| | Then left-click context menu OR keybindings below |
|
||||
|--------------------------------------+---------------------------------------------------|
|
||||
| Add a Markup Annotation | ~C-c C-a m~ |
|
||||
| Add a Highlight Markup Annotation | ~C-c C-a h~ |
|
||||
| Add a Strikeout Markup Annotation | ~C-c C-a o~ |
|
||||
| Add a Squiggly Markup Annotation | ~C-c C-a s~ |
|
||||
| Add an Underline Markup Annotation | ~C-c C-a u~ |
|
||||
| Add a Text Annotation | ~C-c C-a t~ |
|
||||
|--------------------------------------+---------------------------------------------------|
|
||||
| | |
|
||||
| Annotations | |
|
||||
|--------------------------------------+----------------------------------------------------|
|
||||
| List Annotations | ~C-c C-a l~ |
|
||||
| Jump to Annotations from List | ~SPACE~ |
|
||||
| Mark Annotation for Deletion | ~d~ |
|
||||
| Delete Marked Annotations | ~x~ |
|
||||
| Unmark Annotations | ~u~ |
|
||||
| Close Annotation List | ~q~ |
|
||||
| Enable/Disable Following Annotations | ~C-c C-f~ |
|
||||
|--------------------------------------+----------------------------------------------------|
|
||||
| Add and Edit Annotations | Select region via Mouse selection. |
|
||||
| | Then left-click context menu OR keybindings below |
|
||||
|--------------------------------------+----------------------------------------------------|
|
||||
| Add a Markup Annotation | ~C-c C-a m~ |
|
||||
| Add a Highlight Markup Annotation | ~C-c C-a h~ |
|
||||
| Add a Strikeout Markup Annotation | ~C-c C-a o~ |
|
||||
| Add a Squiggly Markup Annotation | ~C-c C-a s~ |
|
||||
| Add an Underline Markup Annotation | ~C-c C-a u~ |
|
||||
| Add a Text Annotation | ~C-c C-a t~ |
|
||||
|--------------------------------------+----------------------------------------------------|
|
||||
| Highlight an arbitrary region | Section region with Mouse Drag (Hold down Meta and |
|
||||
| | drag). Then ~C-c C-a h~ to highlight that region. |
|
||||
|--------------------------------------+----------------------------------------------------|
|
||||
| | |
|
||||
|
||||
** Working with AUCTeX
|
||||
:PROPERTIES:
|
||||
@@ -361,7 +373,7 @@ Note that ~pdf-tools~ renders the PDF as images inside Emacs. This means that al
|
||||
M-x pdf-tools-help RET
|
||||
#+end_src
|
||||
|
||||
Run ~M-x pdf-tools-help~ inside Emacs, as shown above. It will list all the features provided by ~pdf-tools~ as well as the key-bindings for these features.
|
||||
Run =M-x pdf-tools-help= inside Emacs, as shown above. It will list all the features provided by ~pdf-tools~ as well as the key-bindings for these features.
|
||||
|
||||
** Configuring PDF Tools features
|
||||
:PROPERTIES:
|
||||
@@ -520,12 +532,12 @@ A clear and concise description of what you expected to happen.
|
||||
Please complete the following information:
|
||||
|
||||
- OS: [eg: MacOS Catalina]
|
||||
- Emacs Version: [This should be the output of ~M-x emacs-version~ ]
|
||||
- Emacs Version: [This should be the output of =M-x emacs-version= ]
|
||||
- Poppler Version: [eg: output of ~brew info poppler~ and similarly for other OSs]
|
||||
|
||||
*** Your pdf-tools install
|
||||
Please complete the following information:
|
||||
- ~pdf-tools~ Version: [ ~M-x package-list-packages~ -> Search for ~pdf-tools~ -> Hit Enter and copy all the details that pop up in the Help buffer]
|
||||
- ~pdf-tools~ Version: [ =M-x package-list-packages= -> Search for ~pdf-tools~ -> Hit Enter and copy all the details that pop up in the Help buffer]
|
||||
- ~pdf-tools~ customization / configuration that you use:
|
||||
|
||||
*** Additional context
|
||||
@@ -539,6 +551,13 @@ Please complete the following information:
|
||||
:CREATED: [2021-12-30 Thu 22:04]
|
||||
:ID: 3be6abe7-163e-4c3e-a7df-28e8470fe37f
|
||||
:END:
|
||||
** Epdfinfo has stopped working!
|
||||
:PROPERTIES:
|
||||
:CREATED: [2023-06-10 Sat 23:25]
|
||||
:ID: 9B5F797F-9BB3-45D9-B364-D4E5F13222BF
|
||||
:END:
|
||||
Have you upgraded ~poppler~ recently? This can cause ~epdfinfo~ to stop working, since it was compiled with the previous version of ~poppler~. Just run =M-x pdf-tools-install= and this should be fixed.
|
||||
|
||||
** PDFs are not rendering well!
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-30 Thu 22:04]
|
||||
@@ -558,6 +577,7 @@ to scale the images correctly when rendering them.
|
||||
:ID: f44c66e6-402d-4154-b806-6bb4180a0a5b
|
||||
:END:
|
||||
~pdf-tools~ supports the 3 latest versions of Emacs major releases. At the moment of this writing, this means that the minimum supported Emacs version is ~26.3~.
|
||||
|
||||
** I want to add support for pdf-tools on "My Fav OS". How do I do that?
|
||||
:PROPERTIES:
|
||||
:CREATED: [2022-04-25 Mon 21:50]
|
||||
@@ -581,7 +601,7 @@ When you make your changes, please be sure to test [[id:1CBE7325-A5A1-479B-9A98-
|
||||
:CREATED: [2022-05-09 Mon 20:29]
|
||||
:ID: 96D389D8-DD23-4FB0-996C-2D6F70A76BB2
|
||||
:END:
|
||||
There have been a number of issues around ~pdf-tools~ installation problems on M1. ~M-x pdf-tools-install~ throws the following stack trace:
|
||||
There have been a number of issues around ~pdf-tools~ installation problems on M1. =M-x pdf-tools-install= throws the following stack trace:
|
||||
#+begin_example
|
||||
1 warning generated.
|
||||
ld: warning: ignoring file /opt/homebrew/opt/gettext/lib/libintl.dylib, building for macOS-x86_64 but attempting to link with file built for macOS-arm64
|
||||
|
||||
@@ -434,7 +434,8 @@ os_void() {
|
||||
poppler-glib-devel
|
||||
zlib-devel
|
||||
make
|
||||
pkgconf"
|
||||
pkgconf
|
||||
cairo-devel"
|
||||
PKGCMD=xbps-install
|
||||
PKGARGS="-Sy"
|
||||
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:/usr/lib/pkgconfig"
|
||||
|
||||
@@ -370,17 +370,122 @@ mktempfile()
|
||||
return filename;
|
||||
}
|
||||
|
||||
/* Holds RGB, HSL, HSV, Lab, or Lch... but note that the order in memory for HSL
|
||||
* and HSV are actually VSH and LSH. */
|
||||
struct color
|
||||
{
|
||||
union
|
||||
{
|
||||
double r, v, l;
|
||||
};
|
||||
union
|
||||
{
|
||||
double g, s, a;
|
||||
};
|
||||
union
|
||||
{
|
||||
double b, h;
|
||||
};
|
||||
};
|
||||
|
||||
#define struct_color(x) (*((struct color *) x))
|
||||
#define vec_color(x) ((double *) &x)
|
||||
|
||||
// Using values reported at https://bottosson.github.io/posts/oklab/#converting-from-linear-srgb-to-oklab
|
||||
// instead of going through xyz. This ensures any whitepoint is ignored
|
||||
static struct color
|
||||
rgb2oklab(struct color rgb)
|
||||
{
|
||||
struct color srgb;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
double val = vec_color(rgb)[i];
|
||||
vec_color(srgb)[i] = ((val > 0.04045)
|
||||
? pow((val + 0.055) / 1.055, 2.4)
|
||||
: (val / 12.92));
|
||||
}
|
||||
|
||||
double l = 0.4121656120 * srgb.r + 0.5362752080 * srgb.g + 0.0514575653 * srgb.b;
|
||||
double m = 0.2118591070 * srgb.r + 0.6807189584 * srgb.g + 0.1074065790 * srgb.b;
|
||||
double s = 0.0883097947 * srgb.r + 0.2818474174 * srgb.g + 0.6302613616 * srgb.b;
|
||||
|
||||
l = cbrt(l);
|
||||
m = cbrt(m);
|
||||
s = cbrt(s);
|
||||
|
||||
return (struct color) {
|
||||
.l = 0.2104542553 * l + 0.7936177850 * m - 0.0040720468 * s,
|
||||
.a = 1.9779984951 * l - 2.4285922050 * m + 0.4505937099 * s,
|
||||
.b = 0.0259040371 * l + 0.7827717662 * m - 0.8086757660 * s
|
||||
};
|
||||
}
|
||||
|
||||
static double clamp(double x, double low, double high)
|
||||
{
|
||||
return ((x < low)
|
||||
? low
|
||||
: ((x > high) ? high : x));
|
||||
}
|
||||
|
||||
static struct color
|
||||
oklab2rgb(struct color lab)
|
||||
{
|
||||
double l = lab.l + 0.3963377774 * lab.a + 0.2158037573 * lab.b;
|
||||
double m = lab.l - 0.1055613458 * lab.a - 0.0638541728 * lab.b;
|
||||
double s = lab.l - 0.0894841775 * lab.a - 1.2914855480 * lab.b;
|
||||
|
||||
l = l * l * l;
|
||||
m = m * m * m;
|
||||
s = s * s * s;
|
||||
|
||||
struct color srgb = {
|
||||
.r = 4.0767245293 * l - 3.3072168827 * m + 0.2307590544 * s,
|
||||
.g = -1.2681437731 * l + 2.6093323231 * m - 0.3411344290 * s,
|
||||
.b = -0.0041119885 * l - 0.7034763098 * m + 1.7068625689 * s
|
||||
};
|
||||
|
||||
struct color rgb;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
double val = vec_color(srgb)[i];
|
||||
val = ((val > 0.0031308)
|
||||
? (1.055 * pow(val, 1 / 2.4) - 0.055)
|
||||
: (12.92 * val));
|
||||
|
||||
vec_color(rgb)[i] = clamp(val, 0.0, 1.0);
|
||||
}
|
||||
|
||||
return rgb;
|
||||
}
|
||||
|
||||
#undef struct_color
|
||||
#undef vec_color
|
||||
|
||||
static inline gboolean color_equal(struct color a, struct color b)
|
||||
{
|
||||
return (a.r == b.r && a.g == b.g && a.b == b.b);
|
||||
}
|
||||
|
||||
static void
|
||||
image_recolor (cairo_surface_t * surface, const PopplerColor * fg,
|
||||
const PopplerColor * bg)
|
||||
const PopplerColor * bg, int usecolors)
|
||||
{
|
||||
/* uses a representation of a rgb color as follows:
|
||||
- a lightness scalar (between 0,1), which is a weighted average of r, g, b,
|
||||
- a hue vector, which indicates a radian direction from the grey axis,
|
||||
inside the equal lightness plane.
|
||||
- a saturation scalar between 0,1. It is 0 when grey, 1 when the color is
|
||||
in the boundary of the rgb cube.
|
||||
*/
|
||||
/* Performs one of two kinds of image recoloring depending on the value of usecolors:
|
||||
|
||||
1 -> Bg-Fg Interpolation: maps source document colors to colors
|
||||
interpolated between the background and foreground values in
|
||||
pdf-view-midnight-colors via the lightness of the source color. This
|
||||
discards hue information but allows you to fit your color theme
|
||||
perfectly.
|
||||
|
||||
2 -> Hue-Preserving interpolation: same as above, similar to above, but
|
||||
attempts to preserve hue while still respecting the background and
|
||||
foreground colors. This is done by matching source document white and
|
||||
black to the specified background and foreground as above, but mixes
|
||||
hue/saturation with the background color. This preserves hue but is
|
||||
more expensive.
|
||||
*/
|
||||
|
||||
const unsigned int page_width = cairo_image_surface_get_width (surface);
|
||||
const unsigned int page_height = cairo_image_surface_get_height (surface);
|
||||
@@ -391,46 +496,131 @@ image_recolor (cairo_surface_t * surface, const PopplerColor * fg,
|
||||
static const double a[] = { 0.30, 0.59, 0.11 };
|
||||
|
||||
const double f = 65535.;
|
||||
const double rgb_fg[] = {
|
||||
fg->red / f, fg->green / f, fg->blue / f
|
||||
const struct color rgb_fg = {
|
||||
.r = fg->red / f,
|
||||
.g = fg->green / f,
|
||||
.b = fg->blue / f
|
||||
};
|
||||
const double rgb_bg[] = {
|
||||
bg->red / f, bg->green / f, bg->blue / f
|
||||
const struct color rgb_bg = {
|
||||
.r = bg->red / f,
|
||||
.g = bg->green / f,
|
||||
.b = bg->blue / f
|
||||
};
|
||||
|
||||
const double rgb_diff[] = {
|
||||
rgb_bg[0] - rgb_fg[0],
|
||||
rgb_bg[1] - rgb_fg[1],
|
||||
rgb_bg[2] - rgb_fg[2]
|
||||
const struct color rgb_diff = {
|
||||
.r = rgb_bg.r - rgb_fg.r,
|
||||
.g = rgb_bg.g - rgb_fg.g,
|
||||
.b = rgb_bg.b - rgb_fg.b
|
||||
};
|
||||
|
||||
unsigned int y;
|
||||
for (y = 0; y < page_height * rowstride; y += rowstride)
|
||||
switch (usecolors)
|
||||
{
|
||||
unsigned char *data = image + y;
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
unsigned int y;
|
||||
for (y = 0; y < page_height * rowstride; y += rowstride)
|
||||
{
|
||||
unsigned char *data = image + y;
|
||||
|
||||
unsigned int x;
|
||||
for (x = 0; x < page_width; x++, data += 4)
|
||||
{
|
||||
/* Careful. data color components blue, green, red. */
|
||||
const double rgb[3] = {
|
||||
(double) data[2] / 256.,
|
||||
(double) data[1] / 256.,
|
||||
(double) data[0] / 256.
|
||||
};
|
||||
unsigned int x;
|
||||
for (x = 0; x < page_width; x++, data += 4)
|
||||
{
|
||||
/* Careful. data color components blue, green, red. */
|
||||
struct color rgb = {
|
||||
.r = (double) data[2] / 256.,
|
||||
.g = (double) data[1] / 256.,
|
||||
.b = (double) data[0] / 256.
|
||||
};
|
||||
|
||||
/* compute h, s, l data */
|
||||
double l = a[0] * rgb[0] + a[1] * rgb[1] + a[2] * rgb[2];
|
||||
/* Linear interpolation between bg and fg based on the
|
||||
perceptual lightness measure l */
|
||||
/* compute h, s, l data */
|
||||
double l = a[0] * rgb.r + a[1] * rgb.g + a[2] * rgb.b;
|
||||
|
||||
/* linear interpolation between dark and light with color ligtness as
|
||||
* a parameter */
|
||||
data[2] =
|
||||
(unsigned char) round (255. * (l * rgb_diff[0] + rgb_fg[0]));
|
||||
data[1] =
|
||||
(unsigned char) round (255. * (l * rgb_diff[1] + rgb_fg[1]));
|
||||
data[0] =
|
||||
(unsigned char) round (255. * (l * rgb_diff[2] + rgb_fg[2]));
|
||||
}
|
||||
/* linear interpolation between dark and light with color
|
||||
lightness as a parameter */
|
||||
data[2] =
|
||||
(unsigned char) round (255. * (l * rgb_diff.r + rgb_fg.r));
|
||||
data[1] =
|
||||
(unsigned char) round (255. * (l * rgb_diff.g + rgb_fg.g));
|
||||
data[0] =
|
||||
(unsigned char) round (255. * (l * rgb_diff.b + rgb_fg.b));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
/* If using the Oklab transform, it is relatively expensive. Precompute
|
||||
white->background and black->foreground and have a single entry cache to
|
||||
speed up computation */
|
||||
const struct color white = {.r = 1.0, .g = 1.0, .b = 1.0};
|
||||
struct color precomputed_rgb = white;
|
||||
struct color precomputed_inv_rgb = rgb_bg;
|
||||
|
||||
/* Must match the transformation of colors below. */
|
||||
struct color oklab_fg = rgb2oklab(rgb_fg);
|
||||
struct color oklab_bg = rgb2oklab(rgb_bg);
|
||||
|
||||
const double oklab_diff_l = oklab_fg.l - oklab_bg.l;
|
||||
|
||||
unsigned int y;
|
||||
for (y = 0; y < page_height * rowstride; y += rowstride)
|
||||
{
|
||||
unsigned char *data = image + y;
|
||||
|
||||
unsigned int x;
|
||||
for (x = 0; x < page_width; x++, data += 4)
|
||||
{
|
||||
/* Careful. data color components blue, green, red. */
|
||||
struct color rgb = {
|
||||
.r = (double) data[2] / 256.,
|
||||
.g = (double) data[1] / 256.,
|
||||
.b = (double) data[0] / 256.
|
||||
};
|
||||
|
||||
/* Convert to Oklab coordinates, invert perceived lightness,
|
||||
convert back to RGB. */
|
||||
if (color_equal(white, rgb))
|
||||
{
|
||||
rgb = rgb_bg;
|
||||
}
|
||||
else if (color_equal(precomputed_rgb, rgb))
|
||||
{
|
||||
rgb = precomputed_inv_rgb;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct color oklab = rgb2oklab(rgb);
|
||||
precomputed_rgb = rgb;
|
||||
|
||||
/* Invert the perceived lightness, and scales it */
|
||||
double l = oklab.l;
|
||||
double inv_l = 1.0 - l;
|
||||
oklab.l = oklab_bg.l + oklab_diff_l * inv_l;
|
||||
|
||||
/* Have a and b parameters (which encode hue and saturation)
|
||||
start at the background value and interpolate up to
|
||||
foreground */
|
||||
oklab.a = (oklab.a + oklab_bg.a * l + oklab_fg.a * inv_l);
|
||||
oklab.b = (oklab.b + oklab_bg.b * l + oklab_fg.b * inv_l);
|
||||
|
||||
rgb = oklab2rgb(oklab);
|
||||
|
||||
precomputed_inv_rgb = rgb;
|
||||
}
|
||||
|
||||
data[2] = (unsigned char) round(255. * rgb.r);
|
||||
data[1] = (unsigned char) round(255. * rgb.g);
|
||||
data[0] = (unsigned char) round(255. * rgb.b);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
internal_error ("image_recolor switch fell through");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -501,8 +691,8 @@ image_render_page(PopplerDocument *pdf, PopplerPage *page,
|
||||
|
||||
cairo_paint (cr);
|
||||
|
||||
if (options && options->usecolors)
|
||||
image_recolor (surface, &options->fg, &options->bg);
|
||||
if (options && (options->usecolors))
|
||||
image_recolor (surface, &options->fg, &options->bg, options->usecolors);
|
||||
|
||||
cairo_destroy (cr);
|
||||
|
||||
@@ -760,6 +950,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)
|
||||
@@ -1347,12 +1557,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;
|
||||
@@ -1360,7 +1573,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);
|
||||
@@ -1389,6 +1602,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
|
||||
@@ -1396,8 +1610,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;
|
||||
@@ -1420,6 +1635,21 @@ annotation_new (const epdfinfo_t *ctx, document_t *doc, PopplerPage *page,
|
||||
#ifdef HAVE_POPPLER_ANNOT_MARKUP
|
||||
garray = g_array_new (FALSE, FALSE, sizeof (PopplerQuadrilateral));
|
||||
poppler_page_get_size (page, &width, &height);
|
||||
if (nargs == 0)
|
||||
{
|
||||
PopplerQuadrilateral q;
|
||||
|
||||
q.p1.x = r->x1;
|
||||
q.p1.y = r->y1;
|
||||
q.p2.x = r->x2;
|
||||
q.p2.y = r->y1;
|
||||
q.p4.x = r->x2;
|
||||
q.p4.y = r->y2;
|
||||
q.p3.x = r->x1;
|
||||
q.p3.y = r->y2;
|
||||
|
||||
g_array_append_val (garray, q);
|
||||
}
|
||||
for (i = 0; i < nargs; ++i)
|
||||
{
|
||||
PopplerRectangle *rr = &carg.value.rectangle;
|
||||
@@ -1428,7 +1658,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");
|
||||
@@ -2319,14 +2549,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);
|
||||
@@ -2368,7 +2591,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 */
|
||||
};
|
||||
|
||||
@@ -2384,14 +2607,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);
|
||||
@@ -2644,6 +2860,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 */
|
||||
};
|
||||
@@ -2655,7 +2872,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;
|
||||
@@ -2667,6 +2885,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);
|
||||
@@ -2680,7 +2899,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 ();
|
||||
@@ -3074,6 +3294,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;
|
||||
|
||||
@@ -3202,10 +3423,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);
|
||||
}
|
||||
@@ -3420,7 +3649,7 @@ cmd_charlayout(const epdfinfo_t *ctx, const command_arg_t *args)
|
||||
|
||||
const document_option_t document_options [] =
|
||||
{
|
||||
DEC_DOPT (":render/usecolors", ARG_BOOL, render.usecolors),
|
||||
DEC_DOPT (":render/usecolors", ARG_NATNUM, render.usecolors),
|
||||
DEC_DOPT (":render/printed", ARG_BOOL, render.printed),
|
||||
DEC_DOPT (":render/foreground", ARG_COLOR, render.fg),
|
||||
DEC_DOPT (":render/background", ARG_COLOR, render.bg),
|
||||
|
||||
@@ -1052,19 +1052,24 @@ 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)
|
||||
(non-markup (pcase type
|
||||
('text t)
|
||||
('highlight pdf-view--have-rectangle-region)))
|
||||
(a (apply #'pdf-info-addannot
|
||||
page
|
||||
(if (eq type 'text)
|
||||
(if non-markup
|
||||
(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)))
|
||||
(unless non-markup edges)))
|
||||
(id (pdf-annot-get-id a)))
|
||||
(when property-alist
|
||||
(condition-case err
|
||||
@@ -1445,15 +1450,16 @@ annotation's contents and otherwise `org-mode'."
|
||||
(set-keymap-parent kmap text-mode-map)
|
||||
(define-key kmap (kbd "C-c C-c") #'pdf-annot-edit-contents-commit)
|
||||
(define-key kmap (kbd "C-c C-q") #'pdf-annot-edit-contents-abort)
|
||||
(define-key kmap (kbd "C-c C-k") #'pdf-annot-edit-contents-abort)
|
||||
kmap))
|
||||
|
||||
(define-minor-mode pdf-annot-edit-contents-minor-mode
|
||||
"Active when editing the contents of annotations."
|
||||
:group 'pdf-annot
|
||||
(when pdf-annot-edit-contents-minor-mode
|
||||
(message "%s"
|
||||
(substitute-command-keys
|
||||
"Press \\[pdf-annot-edit-contents-commit] to commit your changes, \\[pdf-annot-edit-contents-abort] to abandon them."))))
|
||||
(setq-local header-line-format
|
||||
(substitute-command-keys "\
|
||||
Press \\[pdf-annot-edit-contents-commit] to commit your changes, \\[pdf-annot-edit-contents-abort] to abandon them."))))
|
||||
|
||||
(put 'pdf-annot-edit-contents-minor-mode 'permanent-local t)
|
||||
|
||||
@@ -1508,11 +1514,8 @@ At any given point of time, only one annotation can be in edit mode."
|
||||
(pdf-annot-edit-contents-finalize 'ask)))
|
||||
(unless (buffer-live-p pdf-annot-edit-contents--buffer)
|
||||
(setq pdf-annot-edit-contents--buffer
|
||||
(with-current-buffer (get-buffer-create
|
||||
(format "*Edit Annotation %s*"
|
||||
(buffer-name)))
|
||||
(pdf-annot-edit-contents-minor-mode 1)
|
||||
(current-buffer))))
|
||||
(get-buffer-create
|
||||
(format "*Edit Annotation %s*" (buffer-name)))))
|
||||
(with-current-buffer pdf-annot-edit-contents--buffer
|
||||
(let ((inhibit-read-only t))
|
||||
(erase-buffer)
|
||||
@@ -1520,6 +1523,7 @@ At any given point of time, only one annotation can be in edit mode."
|
||||
(set-buffer-modified-p nil))
|
||||
(setq pdf-annot-edit-contents--annotation a)
|
||||
(funcall pdf-annot-edit-contents-setup-function a)
|
||||
(pdf-annot-edit-contents-minor-mode 1)
|
||||
(current-buffer))))
|
||||
|
||||
(defun pdf-annot-edit-contents (a)
|
||||
@@ -1718,16 +1722,19 @@ pretty-printed output."
|
||||
\\{pdf-annot-list-mode-map}"
|
||||
(interactive)
|
||||
(pdf-util-assert-pdf-buffer)
|
||||
(let ((buffer (current-buffer)))
|
||||
(with-current-buffer (get-buffer-create
|
||||
(format "*%s's annots*"
|
||||
(file-name-sans-extension
|
||||
(buffer-name))))
|
||||
(let* ((buffer (current-buffer))
|
||||
(name (format "*%s's annots*"
|
||||
(file-name-sans-extension
|
||||
(buffer-name))))
|
||||
(annots-existed (and (get-buffer name)
|
||||
pdf-annot-list-buffer)))
|
||||
(with-current-buffer (get-buffer-create name)
|
||||
(delay-mode-hooks
|
||||
(unless (derived-mode-p 'pdf-annot-list-mode)
|
||||
(pdf-annot-list-mode))
|
||||
(setq pdf-annot-list-document-buffer buffer)
|
||||
(tabulated-list-print)
|
||||
(unless annots-existed
|
||||
(tabulated-list-print))
|
||||
(setq tablist-context-window-function
|
||||
(lambda (id) (pdf-annot-list-context-function id buffer))
|
||||
tablist-operations-function #'pdf-annot-list-operation-function)
|
||||
|
||||
@@ -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)))))
|
||||
|
||||
|
||||
@@ -570,8 +570,14 @@ interrupted."
|
||||
(let ((key (intern (car key-value)))
|
||||
(value (cadr key-value)))
|
||||
(cl-case key
|
||||
((:render/printed :render/usecolors)
|
||||
(setq value (equal value "1"))))
|
||||
((:render/printed)
|
||||
(setq value (equal value "1")))
|
||||
((:render/usecolors)
|
||||
(setq value (ignore-errors
|
||||
(let ((int-val (cl-parse-integer value)))
|
||||
(if (> 3 int-val 0)
|
||||
int-val
|
||||
0))))))
|
||||
(push value options)
|
||||
(push key options)))
|
||||
options))
|
||||
@@ -1247,6 +1253,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 +1280,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))))
|
||||
(pdf-info--selection-style selection-style)))
|
||||
|
||||
(defun pdf-info-getselection (page edges &optional selection-style
|
||||
file-or-buffer)
|
||||
(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 +1427,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 +1446,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 +1621,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 +1631,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 +1655,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)
|
||||
@@ -1718,8 +1732,16 @@ Returns a list \(LEFT TOP RIGHT BOT\)."
|
||||
((:render/foreground :render/background)
|
||||
(push (pdf-util-hexcolor value)
|
||||
soptions))
|
||||
((:render/usecolors :render/printed)
|
||||
((:render/printed)
|
||||
(push (if value 1 0) soptions))
|
||||
((:render/usecolors)
|
||||
;; 0 -> original color
|
||||
;; 1 -> recolor document to grayscale mapping black to
|
||||
;; :render/foreground and white to :render/background
|
||||
;; 2 -> recolor document by inverting the perceived lightness
|
||||
;; preserving hue
|
||||
(push (if (and (integerp value) (> 3 value 0)) value 0)
|
||||
soptions))
|
||||
(t (push value soptions)))
|
||||
(push key soptions)))
|
||||
soptions)))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -143,6 +143,19 @@
|
||||
["Copy region" pdf-view-kill-ring-save
|
||||
:keys "\\[kill-ring-save]"
|
||||
:active (pdf-view-active-region-p)]
|
||||
("Selection style"
|
||||
["Glyph" (pdf-view-set-selection-style 'glyph)
|
||||
:style radio
|
||||
:selected (eq pdf-view-selection-style 'glyph)
|
||||
:help "When dragging the mouse, select individual characters."]
|
||||
["Word" (pdf-view-set-selection-style 'word)
|
||||
:style radio
|
||||
:selected (eq pdf-view-selection-style 'word)
|
||||
:help "When dragging the mouse, select entire words."]
|
||||
["Line" (pdf-view-set-selection-style 'line)
|
||||
:style radio
|
||||
:selected (eq pdf-view-selection-style 'line)
|
||||
:help "When dragging the mouse, select entire lines."])
|
||||
"--"
|
||||
["Isearch document" isearch-forward
|
||||
:visible (bound-and-true-p pdf-isearch-minor-mode)]
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
(define-package "pdf-tools" "20221202.1104" "Support library for PDF documents"
|
||||
(define-package "pdf-tools" "20230611.239" "Support library for PDF documents"
|
||||
'((emacs "26.3")
|
||||
(tablist "1.0")
|
||||
(let-alist "1.0.4"))
|
||||
:commit "b8079e4ebc2936f9772657332d50936350a65825" :authors
|
||||
:commit "c69e7656a4678fe25afbd29f3503dd19ee7f9896" :authors
|
||||
'(("Andreas Politz" . "mail@andreas-politz.de"))
|
||||
:maintainers
|
||||
'(("Vedang Manerikar" . "vedang.manerikar@gmail.com"))
|
||||
:maintainer
|
||||
'("Vedang Manerikar" . "vedang.manerikar@gmail.com")
|
||||
:keywords
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
;; URL: http://github.com/vedang/pdf-tools/
|
||||
;; Keywords: files, multimedia
|
||||
;; Package: pdf-tools
|
||||
;; Version: 1.0.0
|
||||
;; Version: 1.1.0
|
||||
;; Package-Requires: ((emacs "26.3") (tablist "1.0") (let-alist "1.0.4"))
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
@@ -145,9 +145,7 @@ In order to customize dark and light colors use
|
||||
pdf-sync-minor-mode
|
||||
pdf-misc-context-menu-minor-mode
|
||||
pdf-cache-prefetch-minor-mode
|
||||
pdf-occur-global-minor-mode
|
||||
;; pdf-virtual-global-minor-mode
|
||||
)
|
||||
pdf-occur-global-minor-mode)
|
||||
"A list of automatically enabled minor-modes.
|
||||
|
||||
PDF Tools is build as a series of minor-modes. This variable and
|
||||
|
||||
@@ -118,6 +118,20 @@ This should be a cons \(FOREGROUND . BACKGROUND\) of colors."
|
||||
:type '(cons (color :tag "Foreground")
|
||||
(color :tag "Background")))
|
||||
|
||||
(defcustom pdf-view-midnight-invert t
|
||||
"In midnight mode invert the image color lightness maintaining hue.
|
||||
|
||||
This is particularly useful if you are viewing documents with
|
||||
color coded data in plots. This will maintain the colors such
|
||||
that blue and red will remain these colors in the inverted
|
||||
rendering. This inversion is non-trivial. This makes use of the
|
||||
OKLab color space which is well calibrated to have equal
|
||||
perceptual brightness across hue, but not all colors are within
|
||||
the RGB gamut after inversion, causing some colors to saturate.
|
||||
Nevertheless, this seems to work well in most cases."
|
||||
:group 'pdf-view
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom pdf-view-change-page-hook nil
|
||||
"Hook run after changing to another page, but before displaying it.
|
||||
|
||||
@@ -181,13 +195,23 @@ loaded."
|
||||
|
||||
(defcustom pdf-view-incompatible-modes
|
||||
'(linum-mode linum-relative-mode helm-linum-relative-mode
|
||||
nlinum-mode nlinum-hl-mode nlinum-relative-mode yalinum-mode)
|
||||
nlinum-mode nlinum-hl-mode nlinum-relative-mode yalinum-mode
|
||||
display-line-numbers-mode)
|
||||
"A list of modes incompatible with `pdf-view-mode'.
|
||||
|
||||
Issue a warning, if one of them is active in a PDF buffer."
|
||||
:group 'pdf-view
|
||||
:type '(repeat symbol))
|
||||
|
||||
(defcustom pdf-view-selection-style 'word
|
||||
"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
|
||||
@@ -217,6 +241,9 @@ regarding display of the region in the later function.")
|
||||
(defvar-local pdf-view--hotspot-functions nil
|
||||
"Alist of hotspot functions.")
|
||||
|
||||
(defvar-local pdf-view--current-rotation nil
|
||||
"Current rotation of the page.")
|
||||
|
||||
(defvar-local pdf-view-register-alist nil
|
||||
"Local, dedicated register for PDF positions.")
|
||||
|
||||
@@ -281,6 +308,8 @@ regarding display of the region in the later function.")
|
||||
(define-key map (kbd "s m") 'pdf-view-set-slice-using-mouse)
|
||||
(define-key map (kbd "s b") 'pdf-view-set-slice-from-bounding-box)
|
||||
(define-key map (kbd "s r") 'pdf-view-reset-slice)
|
||||
;; Rotation.
|
||||
(define-key map (kbd "R") #'pdf-view-rotate)
|
||||
;; Reconvert
|
||||
(define-key map (kbd "C-c C-c") 'doc-view-mode)
|
||||
(define-key map (kbd "g") 'revert-buffer)
|
||||
@@ -304,6 +333,7 @@ regarding display of the region in the later function.")
|
||||
map)
|
||||
"Keymap used by `pdf-view-mode' when displaying a doc as a set of images.")
|
||||
|
||||
(defvar pdf-tools-enabled-modes)
|
||||
(define-derived-mode pdf-view-mode special-mode "PDFView"
|
||||
"Major mode in PDF buffers.
|
||||
|
||||
@@ -337,6 +367,17 @@ PNG images in Emacs buffers."
|
||||
;; Disable pixel-scroll-precision-mode locally if enabled
|
||||
(if (bound-and-true-p pixel-scroll-precision-mode)
|
||||
(set (make-local-variable 'pixel-scroll-precision-mode) nil))
|
||||
(if (boundp 'mwheel-coalesce-scroll-events)
|
||||
(setq-local mwheel-coalesce-scroll-events t))
|
||||
|
||||
;; If the Emacs theme is dark, add `pdf-view-dark-minor-mode' to the
|
||||
;; list of `pdf-tools-enabled-modes'. See an interesting discussion
|
||||
;; at: https://github.com/vedang/pdf-tools/issues/166 about how this
|
||||
;; avoids a segfault crash in MacOS Ventura. IF you know why this
|
||||
;; happens, please get in touch via the linked issue.
|
||||
|
||||
(when (eq 'dark (frame-parameter nil 'background-mode))
|
||||
(add-to-list 'pdf-tools-enabled-modes 'pdf-view-dark-minor-mode))
|
||||
|
||||
;; Clearing overlays
|
||||
(add-hook 'change-major-mode-hook
|
||||
@@ -461,7 +502,10 @@ operating on a local copy of a remote file."
|
||||
;; in the process), it may be immediately reopened due to
|
||||
;; redisplay happening inside the pdf-info-close function
|
||||
;; (while waiting for a response from the process.).
|
||||
(copy-file tempfile (buffer-file-name) t)
|
||||
(copy-file tempfile (or (buffer-file-name)
|
||||
(read-file-name
|
||||
"File name to save PDF to: "))
|
||||
t)
|
||||
(pdf-info-close pdf-view--server-file-name)
|
||||
|
||||
(when pdf-view--buffer-file-name
|
||||
@@ -574,6 +618,21 @@ For example, (pdf-view-shrink 1.25) decreases size by 20%."
|
||||
(setq pdf-view-display-size 1.0)
|
||||
(pdf-view-redisplay t))
|
||||
|
||||
|
||||
;; * ================================================================== *
|
||||
;; * Rotation
|
||||
;; * ================================================================== *
|
||||
(defun pdf-view-rotate (angle)
|
||||
"Rotate the current page by ANGLE degrees clockwise.
|
||||
When called interactively, angle defaults to 90. Moreover, if
|
||||
called interactively with a prefix argument, then rotate
|
||||
anti-clockwise."
|
||||
(interactive (list (if current-prefix-arg -90 90)))
|
||||
(setq-local pdf-view--current-rotation
|
||||
(mod (+ (or pdf-view--current-rotation 0)
|
||||
angle)
|
||||
360))
|
||||
(pdf-view-redisplay t))
|
||||
|
||||
|
||||
;; * ================================================================== *
|
||||
@@ -962,6 +1021,7 @@ See also `pdf-view-use-imagemagick'."
|
||||
window page size)))
|
||||
(pdf-view-create-image data
|
||||
:width (car size)
|
||||
:rotation (or pdf-view--current-rotation 0)
|
||||
:map hotspots
|
||||
:pointer 'arrow)))
|
||||
|
||||
@@ -1210,7 +1270,16 @@ The colors are determined by the variable
|
||||
(pdf-info-setoptions
|
||||
:render/foreground (or (car pdf-view-midnight-colors) "black")
|
||||
:render/background (or (cdr pdf-view-midnight-colors) "white")
|
||||
:render/usecolors t))))
|
||||
:render/usecolors
|
||||
(if pdf-view-midnight-invert
|
||||
;; If midnight invert is enabled, pass "2" indicating
|
||||
;; that :render/foreground and :render/background should
|
||||
;; be ignored and to instead invert the PDF (preserving
|
||||
;; hue)
|
||||
2
|
||||
;; If invert is not enabled, pass "1" indictating that
|
||||
;; :render/foreground and :render/background should be used
|
||||
1)))))
|
||||
(cond
|
||||
(pdf-view-midnight-minor-mode
|
||||
(add-hook 'after-save-hook enable nil t)
|
||||
@@ -1219,10 +1288,20 @@ The colors are determined by the variable
|
||||
(t
|
||||
(remove-hook 'after-save-hook enable t)
|
||||
(remove-hook 'after-revert-hook enable t)
|
||||
(pdf-info-setoptions :render/usecolors nil))))
|
||||
(pdf-info-setoptions
|
||||
;; Value "0" indicates that colors should remain unchanged
|
||||
:render/usecolors 0))))
|
||||
(pdf-cache-clear-images)
|
||||
(pdf-view-redisplay t))
|
||||
|
||||
(defun pdf-view-set-theme-background ()
|
||||
"Set the buffer's color filter to correspond to the current Emacs theme."
|
||||
(pdf-util-assert-pdf-buffer)
|
||||
(pdf-info-setoptions
|
||||
:render/foreground (face-foreground 'default nil)
|
||||
:render/background (face-background 'default nil)
|
||||
:render/usecolors 1))
|
||||
|
||||
(defun pdf-view-refresh-themed-buffer (&optional get-theme)
|
||||
"Refresh the current buffer to activate applied colors.
|
||||
|
||||
@@ -1234,14 +1313,6 @@ current theme's colors."
|
||||
(pdf-view-set-theme-background))
|
||||
(pdf-view-redisplay t))
|
||||
|
||||
(defun pdf-view-set-theme-background ()
|
||||
"Set the buffer's color filter to correspond to the current Emacs theme."
|
||||
(pdf-util-assert-pdf-buffer)
|
||||
(pdf-info-setoptions
|
||||
:render/foreground (face-foreground 'default nil)
|
||||
:render/background (face-background 'default nil)
|
||||
:render/usecolors t))
|
||||
|
||||
(define-minor-mode pdf-view-themed-minor-mode
|
||||
"Synchronize color filter with the present Emacs theme.
|
||||
|
||||
@@ -1257,7 +1328,7 @@ The colors are determined by the `face-foreground' and
|
||||
(t
|
||||
(remove-hook 'after-save-hook #'pdf-view-set-theme-background t)
|
||||
(remove-hook 'after-revert-hook #'pdf-view-set-theme-background t)
|
||||
(pdf-info-setoptions :render/usecolors nil)))
|
||||
(pdf-info-setoptions :render/usecolors 0)))
|
||||
(pdf-view-refresh-themed-buffer pdf-view-themed-minor-mode))
|
||||
|
||||
(when pdf-view-use-unicode-ligther
|
||||
@@ -1338,13 +1409,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 +1441,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 +1494,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 +1518,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 +1535,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 +1560,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
|
||||
@@ -1554,6 +1635,20 @@ the `convert' program is used."
|
||||
(dolist (f (cons result images))
|
||||
(when (file-exists-p f)
|
||||
(delete-file f))))))
|
||||
|
||||
(defun pdf-view-set-selection-style (&optional style)
|
||||
"Set `pdf-view-selection-style' to STYLE in the current buffer.
|
||||
|
||||
When called interactively or without an argument, cycle between
|
||||
the selection styles."
|
||||
(interactive)
|
||||
(unless style
|
||||
(setq style (or (cadr (memq pdf-view-selection-style '(glyph word line)))
|
||||
'glyph))
|
||||
(message "Setting selection style to `%s'." style))
|
||||
(pdf-view-deactivate-region)
|
||||
(setq-local pdf-view-selection-style style))
|
||||
|
||||
|
||||
;; * ================================================================== *
|
||||
;; * Bookmark + Register Integration
|
||||
|
||||
Reference in New Issue
Block a user