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

Support currentColor foreground #214

Closed
tecosaur opened this issue Jan 11, 2023 · 11 comments
Closed

Support currentColor foreground #214

tecosaur opened this issue Jan 11, 2023 · 11 comments
Assignees
Labels
feature feature request
Milestone

Comments

@tecosaur
Copy link

SVGs support the wonderful color value currentColor. This is particularly useful in some situations, such as the LaTeX previews via dvisvgm functionality I am currently working on, where I want the images to dynamically adapt to theme changes.

theme-changing-currentColor.mp4

For this use case, having a transparent background and currentColor foreground is ideal.

Currently, I achieve this result by taking the result of dvisvgm, finding the first color in the SVG file, and replacing all instances of that color with currentColor. This is an imperfect solution though (with issues like #212 complicating the process), and I imagine this isn't the only use case that would benefit from currentColor support.

With this in mind, it would be rather nice if dvisvgm supported a --currentcolor flag (or similar) to get an SVG where currentColor is used for the foreground OOTB.

@mgieseki mgieseki self-assigned this Jan 11, 2023
@mgieseki mgieseki added the feature feature request label Jan 11, 2023
@mgieseki
Copy link
Owner

Could you elaborate a bit on what you consider the foreground color? When converting a simple DVI file that doesn't change colors, the SVG doesn't contain any color attributes either. The fill color defaults to black then and there's no stroke color set, i.e. outlines are not drawn. In this case it's easy to add a fill="currentColor" to the g element enclosing the page content, for example.

However, if there are color values present in the SVG, these colors were explicitly set in the input file. A fill attribute in the enclosing group will only affect the elements with no direct or inherited color attributes. Is this sufficient? What about the explicitly colored elements? Are they supposed to keep their fill and/or stroke colors or do you want them all to be replaced so that multicolored graphics get monochrome?

At the moment, I'm not sure about the intended semantics of --currentcolor and how consistently they could be applied to arbitrary input files.

@tecosaur
Copy link
Author

By the "foreground color" I mean the dominant color used for text, stroke, etc.

When using the result of blocks like this:

% Using preview.sty
\begin{preview} % p1
  \color{XYZ}
  ...content...
\end{preview}

\begin{preview} % p2
  ...more content...
\end{preview}

Looking at the generated SVGs, the first <g> element seems to have the fill set to the result of \color{XYZ} in all the cases I've seen, and so I'm currently using that as a heuristic for finding the foreground color. Then, I look for all instances of that color in the file and replace it with currentColor.

Here's a sample SVG from an earlier issue: org-tex-pojDTY-000000001, post-processing: org-tex-pojDTY-000000001

@mgieseki
Copy link
Owner

Hm, these are quite specific prerequisites. I can't see a reliable way to determine the "dominant color" because the DVI file can contain several subsequent and nested color specials that might affect none or different parts of the document. Only in case of simple input files it's easy to detect it.
I guess it would be better to introduce a dedicated special to replace the currently active color with currentColor, e.g.

\special{dvisvgm:currentcolor}

@tecosaur
Copy link
Author

tecosaur commented Jan 20, 2023

That approach sounds potentially promising. I'm imagining that when \special{dvisvgm:currentcolor} is seen the current foreground color will be recorded and future instances of that colour will be replaced with currentColor, is this what you are thinking?

@mgieseki
Copy link
Owner

Yes, \special{dvisvgm:currentcolor} will simply replace the current active color by currentColor without affecting the color stack. As long as no further color special or PS/PDF color operator is processed, all fill and/or stroke attributes get value currentColor. I need to think about this in more detail, but I'm confident it will work.

@tecosaur
Copy link
Author

tecosaur commented Feb 7, 2023

It would be good to hear more on this being implemented 😉. That sounds like it should work well to me, I've just got two questions:

Would the design you're thinking of work if hypothetically the colour was changed and a second \special{dvisvgm:currentcolor} was emitted?

If no colour is set (i.e. it's the default black), could just the --currentcolor flag be enough, or would \special{dvisvgm:currentcolor} be needed too?

@mgieseki
Copy link
Owner

mgieseki commented Feb 7, 2023

I'm still playing around with several semantics of the special statement to find out the most plausible variant. Unfortunately, it's more complicated than I first thought. currentColor can't be a dedicated color value for several reasons but must be a global state that overrides the current color as long as it's active. \special{dvisvgm:currentcolor} would activate it and any following regular color change could deactivate it again. Of course, this mechanism may be used as often as necessary and at different locations of the TeX file.
Maybe it's also useful to have something like \special{dvisvgm:currentcolor lock} and \special{dvisvgm:currentcolor unlock} to keep currentColor active until it's explicitly released, regardless any intermediate color changes.

I don't think option --currentcolor would be a really useful addition, as its functionality is too limited and specialized compared to the various sources of color changes and their nesting that would interfere with it.

Anyway, I'm currently preparing to move to a different city alongside my job and therefore don't have much time to work on dvisvgm. So please don't expect this to be implemented in the next few weeks.

@mgieseki mgieseki added this to the 3.1 milestone Jul 6, 2023
@mgieseki
Copy link
Owner

mgieseki commented Jul 6, 2023

I finally found some time to add a first implementation which is also part of the latest release 3.1.

  • Command-line option --currentcolor can be used to explicitly set a color that gets replaced with currentColor.
  • \special command dvisvgm:currentcolor can be used to replace the currently active color with currentColor or to disable the functionality.

@mgieseki mgieseki closed this as completed Jul 7, 2023
@tecosaur
Copy link
Author

tecosaur commented Jan 5, 2024

It's been a while, but I just wanted to come back and say this has been working brilliantly. Thanks for adding this functionality!

@mgieseki
Copy link
Owner

mgieseki commented Jan 5, 2024

That's great to hear. Thank you for the feedback!

@karthink
Copy link

karthink commented Jan 6, 2024

Thank you for this! We're seeing significant improvements in Emacs' preview rendering experience, since we don't have to reopen each svg and replace colors manually.

|----------------------+---------------+---------------+-------------|
| Document with...     | dvisvgm 3.0.3 | dvisvgm 3.1.2 | Improvement |
|----------------------+---------------+---------------+-------------|
| 503 LaTeX fragments  |               |               |             |
| Rendering time (s)   | 1.67  ± 0.22  | 1.047 ± 0.20  |         37% |
|----------------------+---------------+---------------+-------------|
| 1200 LaTeX fragments |               |               |             |
| Rendering time (s)   | 4.60  ± 0.3   | 3.60   ± 0.1  |         22% |
|----------------------+---------------+---------------+-------------|

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature feature request
Projects
None yet
Development

No branches or pull requests

3 participants