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

Add support for midnight mode with color #69

Closed
wants to merge 2 commits into from

Conversation

smithzvk
Copy link
Contributor

Not sure if the other PDF-Tools repo is dead on not so reposting here (originally at politza/pdf-tools#698)

This inversion method attempts to maintain the color hue and saturation but inverts the lightness using the OKLab color space.

About the OKLab color space: https://bottosson.github.io/posts/oklab/

This addresses feature request #608 (in politza's repo)

Original image:

image

Image in midnight mode with pdf-tools-midnight-invert set to true (hues maintained but lightness inverted):

image

@vedang
Copy link
Owner

vedang commented Jan 11, 2022

Thank you for this work. Please rebase it on top of the latest master so that CI tests will run correctly. I will review and test it over the weekend

@vedang vedang added ux Improving the User Experience of the library pending review Maintainer needs to review the changes labels Jan 11, 2022
@vedang vedang added this to the v1.1.0 milestone Jan 11, 2022
This inversion method attempts to maintain the color hue and saturation but
inverts the lightness using the OKLab color space.
@smithzvk
Copy link
Contributor Author

Got it passing the CI except appveyor, but that seems to have been broken for other commits recently so I suspect that isn't my change.

@vedang
Copy link
Owner

vedang commented Jan 13, 2022 via email

@smithzvk
Copy link
Contributor Author

smithzvk commented Feb 5, 2022

Just bumping to see if there are any concerns and to say that if there is an issue or just a dislike, let me know and maybe I can find a way to make this work within your desires for the project.

@vedang
Copy link
Owner

vedang commented Feb 7, 2022

I haven't had time to review thoroughly and test on my own yet @smithzvk . There is no action item on you, just on me to make the time to merge this in / get back .

Sorry for the delay, I'll get this done as soon as possible.

Copy link
Owner

@vedang vedang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @smithzvk ,

Thank you for this work and sorry for the delay in the review. I've added a few comments. Can you please make the requested changes and push new commits?

Thanks,
Vedang

lisp/pdf-info.el Outdated Show resolved Hide resolved
lisp/pdf-info.el Outdated Show resolved Hide resolved
lisp/pdf-view.el Outdated
@@ -1177,7 +1191,7 @@ 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 2 1)))))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since :render/usecolors is no longer a boolean, there needs to be an explanation of what the three supported values indicate, as a comment for future devs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know if more is desired here.

server/epdfinfo.c Outdated Show resolved Hide resolved
server/epdfinfo.c Show resolved Hide resolved
server/epdfinfo.c Outdated Show resolved Hide resolved
(double) data[0] / 256.
};

if (usecolors == 2)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid values for usecolors are now 0, 1 and 2 (not just boolean). These need to be explained in the code. Perhaps a switch-case with comments and a default case to throw errors would be great.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used internal_error() here. Let me know if this is not the right method for throwing an error. No return value here to pass errors back up the stack.

server/epdfinfo.c Show resolved Hide resolved
server/epdfinfo.c Show resolved Hide resolved
last_rgb = struct_color(rgb);

oklab.l = pow(oklab.l, 1.8);
oklab.l = 1.0 - oklab.l;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't understand why this is not part of the rgb2oklab function itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comments for clarity. The inversion isn't part of the color space conversion and should be separate.

The gamma correction on the other hand... I don't understand the need for it at all given that the lightness should be a linear w.r.t how we perceive the lightness (the entire point of the color conversion), but I perceive that with the correction yields better results.

As a blanket statement here, I tried a lot of different methods to achieve this affect but this yielded the best results to date and, save for that gamma correction, at least seems to theoretically be the right thing to do.

@vedang vedang added pending changes Author needs to make changes as requested and removed pending review Maintainer needs to review the changes labels Feb 13, 2022
@vedang
Copy link
Owner

vedang commented Feb 18, 2022

Hi @smithzvk ,

Not sure if you got a notification for the review comments I left above. No rush on making the actual fixes, but do let me know a tentative timeline by when you'll be able to address the comments

@smithzvk
Copy link
Contributor Author

I did get a notification. I'm looking through them this morning and try to update on an expected ETA.

@smithzvk
Copy link
Contributor Author

I've been using this pretty much exclusively lately. I think it is pretty good, but I will note that there are instances where colors turn out less than ideal. In particular, some journal articles use a blue for the links which, for whatever reason, isn't very highly legible in the inverted recolored image, but the standard midnight mode works well. In addition, this can be a bit slow for older machines... incorporating a SIMD path would likely resolve this slight slowness.

I feel like this is a 90% solution right now. If you think we should hold off, I can attempt to resolve as time permits.

Also, let me know if you would like me to rebase to master or combine commits etc, or of course feel free to do so yourself. I'm picky about repo history, so respect if you have similar pet peeves.

@smithzvk smithzvk requested a review from vedang February 19, 2022 21:39
@vedang
Copy link
Owner

vedang commented Feb 21, 2022

Took a quick look at the changes and they look good to me! Thanks!

Will review them in some more detail when time permits, test a bit over the next weekend and then merge the changes in.

I'll do a rebase and fixup the commits into a single commit.

@vedang
Copy link
Owner

vedang commented May 17, 2022

I want to set expectations here: The change looks good to me, and I've planned to merge it into the 1.1.0 milestone release of pdf-tools. This means that I will merge the changes into master after I cut a 1.0.0 release, which I have planned for sometime this month (pending testing across all the changes).

No code change is expected here, thank you for your patience :). I will post updates on the ticket as soon as I start merging the changes in.

Copy link
Owner

@vedang vedang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good to me. Thank you!

@vedang vedang removed the pending changes Author needs to make changes as requested label May 17, 2022
@bhankas
Copy link

bhankas commented Sep 24, 2022

Hello, anything keeping these changes from being merged?

@vedang
Copy link
Owner

vedang commented Oct 11, 2022 via email

@vedang vedang closed this in fdb1874 Jan 17, 2023
vedang added a commit that referenced this pull request Jan 17, 2023
This commit enables @smithzvk's work in #69 as the default in
`pdf-tools`. It works well for all the PDFs I have tested with.

The previous behaviour can be enabled by setting
`pdf-view-midnight-invert` to `nil`, if required.
@vedang
Copy link
Owner

vedang commented Jan 17, 2023

I have finally merged this change in, and it is now the default behavior of pdf-view-midnight-minor-mode. Thank you!

@smithzvk
Copy link
Contributor Author

smithzvk commented Jan 17, 2023 via email

@Atreyagaurav
Copy link
Contributor

I have a problem that the values of pdf-view-midnight-colors are being ignored in the pdf, I feel like this is due to this thing. It was fine, and I hadn't updated my packages for a while, when I updated this and the ignoring of the midnight color coincides, and looking at this and seeing the code made me feel like this is related. Can you test it and confirm it?

It's really great to see the color brightness inversion, I had always wondered if that was possible and would be a good way to invert things. I really love this.

@smithzvk
Copy link
Contributor Author

smithzvk commented Feb 28, 2023

Yes, you are right. When pdf-view-midnight-invert is enabled, the values in pdf-view-midnight-colors are ignored as the colors are based on the original PDF content. Unfortunately, at least until someone comes up with something very clever, you will need to choose between the invert behavior and the original behavior which allows you to match your color theme.

With the latest change to make the invert mode the default, this is going to impact people who have been relying on the original behavior. But all you need to do right now is set pdf-view-midnight-invert to nil to restore the original behavior.

@Atreyagaurav
Copy link
Contributor

I like the new behavior in the color stuffs, it's really great. It's life-changing lol.

The high contrast for fg and bg color is the problem, One idea I can think of is to make the original pdf-view-midnight-colors's lightness as thresholds (min and max) for new lightness calculated by the oklab method, theoretically it should work for reducing the contrast for all colors not just black and white. Someone who's implemented it might have an easier job integrating it. Otherwise, I can look it up to see if I can do that when I have time.

@fw623
Copy link

fw623 commented Mar 1, 2023

The changes proposed in #169 respect the pdf-view-midnight-colors (at the time I didn't know that the changes in #69 don't), so feel free to use the changes there directly or as inspiration, if you're interested in implementing this.

oklab.l = pow(oklab.l, 1.8);

/* Invert the perceived lightness */
oklab.l = 1.0 - oklab.l;
Copy link
Contributor

@Atreyagaurav Atreyagaurav Mar 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can add a line to make sure oklab.l is between the l value of fg and bg here, what do you think? And add in documentations that pdf-view-midnight-colors will be used to determine the lightness in this case, but those colors will be used as it is in the other case. This should help with not letting the contrast be too high, but I'm not sure about the ramification of that. I thought about changing the precomputed white and black that way, but that might not work with colors that are close to them, so I think this implementation should be better.

@smithzvk
Copy link
Contributor Author

smithzvk commented Mar 1, 2023 via email

@Atreyagaurav
Copy link
Contributor

Atreyagaurav commented Mar 3, 2023

This seems to work for me:

--- a/epdfinfo.c
+++ b/epdfinfo-new.c
@@ -502,6 +502,9 @@ image_recolor (cairo_surface_t * surface, const PopplerColor * fg,
     .g = bg->green / f,
     .b = bg->blue / f
   };
+  const double fg_l = a[0] * rgb_fg.r + a[1] * rgb_fg.g + a[2] * rgb_fg.b;
+  const double bg_l = a[0] * rgb_bg.r + a[1] * rgb_bg.g + a[2] * rgb_bg.b;
+  const double diff_l = fg_l - bg_l;
 
   const struct color rgb_diff = {
     .r = rgb_bg.r - rgb_fg.r,
@@ -576,9 +579,9 @@ image_recolor (cairo_surface_t * surface, const PopplerColor * fg,
                      * 'feel' too dark and fonts too thin otherwise. */
                     oklab.l = pow(oklab.l, 1.8);
 
-                    /* Invert the perceived lightness */
-                    oklab.l = 1.0 - oklab.l;
-
+                    /* Invert the perceived lightness, and scales it */
+                    oklab.l = bg_l + diff_l * (1.0 - oklab.l);
+                   
                     rgb = oklab2rgb(oklab);
 
                     precomputed_inv_rgb = rgb;

Here, the bottom part of the image is when I have inverted the PDF.

This is on: (setq pdf-view-midnight-colors '("gray70" . "gray25")), it works normally if you have (setq pdf-view-midnight-colors '("white" . "black"))

image

If you think just this much is fine, I can make a pull request, but if you want to test it on other cases to see if it's the correct way, then feel free to use the part from the patch. This should at least act as a band-aid for the sudden change to high contrast rendering that doesn't respect user configurations.

Atreyagaurav added a commit to Atreyagaurav/pdf-tools that referenced this pull request Mar 3, 2023
Uses the Lightness values from the `pdf-view-midnight-colors` `fg` and `bg` to scale the inverted color's lightness.
Band-aid till better method is found.

Related to: vedang#69
aikrahguzar pushed a commit to aikrahguzar/pdf-tools that referenced this pull request Apr 25, 2023
This inversion method attempts to maintain the color hue and saturation but
inverts the lightness using the OKLab color space[^1].

[^1]: https://bottosson.github.io/posts/oklab/

* server/epdfinfo.c (image-recolor): Add feature to support the OKLab
inversion method functionality

* lisp/pdf-view.el (pdf-view-midnight-invert): Add new variable to
invert the image color lightness while maintaining hue.

(pdf-view-midnight-minor-mode): Account for above.

* lisp/pdf-info.el (pdf-info-query--parse-response): Handle changes to
:render/usecolors command

Closes: vedang#69
Closes: vedang#169
Closes: politza/pdf-tools#698
Closes: politza/pdf-tools#608
aikrahguzar pushed a commit to aikrahguzar/pdf-tools that referenced this pull request Apr 25, 2023
This commit enables @smithzvk's work in vedang#69 as the default in
`pdf-tools`. It works well for all the PDFs I have tested with.

The previous behaviour can be enabled by setting
`pdf-view-midnight-invert` to `nil`, if required.
aikrahguzar pushed a commit to aikrahguzar/pdf-tools that referenced this pull request Apr 25, 2023
This inversion method attempts to maintain the color hue and saturation but
inverts the lightness using the OKLab color space[^1].

[^1]: https://bottosson.github.io/posts/oklab/

* server/epdfinfo.c (image-recolor): Add feature to support the OKLab
inversion method functionality

* lisp/pdf-view.el (pdf-view-midnight-invert): Add new variable to
invert the image color lightness while maintaining hue.

(pdf-view-midnight-minor-mode): Account for above.

* lisp/pdf-info.el (pdf-info-query--parse-response): Handle changes to
:render/usecolors command

Closes: vedang#69
Closes: vedang#169
Closes: politza/pdf-tools#698
Closes: politza/pdf-tools#608
aikrahguzar pushed a commit to aikrahguzar/pdf-tools that referenced this pull request Apr 25, 2023
This commit enables @smithzvk's work in vedang#69 as the default in
`pdf-tools`. It works well for all the PDFs I have tested with.

The previous behaviour can be enabled by setting
`pdf-view-midnight-invert` to `nil`, if required.
vedang pushed a commit that referenced this pull request Jun 10, 2023
Uses the Lightness values from the `pdf-view-midnight-colors` `fg` and
`bg` to scale the inverted color's lightness. Band-aid till better
method is found.

Relates to: #69
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ux Improving the User Experience of the library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants