pgf-tikz / pgf

A Portable Graphic Format for TeX
https://pgf-tikz.github.io/
1.13k stars 108 forks source link

Support for blend group option on dvisvgm #1031

Open HyunggyuJang opened 3 years ago

HyunggyuJang commented 3 years ago

Brief outline of the bug

Compiling tikz picture including a scope with blend group option doesn’t render as expeceted when it comes to a process involving dvisvgm, whereas pdflatex works properly.

Minimal working example (MWE)

\documentclass[dvisvgm,tikz]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[scale=2]
\clip (-.2,-.2) rectangle (1.2,1.2);
\begin{scope}[blend group=darken]
  \fill[blue!40] (-1, 5) -- (-1,1/2) -- (3, 1/2) -- (3, 5);
  \fill[green!40] (5, -1) -- (1/2,-1) -- (1/2, 3) -- (5, 3);
\end{scope}
  \draw[fill] (0,0) circle [radius=1pt];
  \draw[fill] (1,0) circle [radius=1pt];
  \draw[fill] (0,1) circle [radius=1pt];
\end{tikzpicture}
\end{document}

should render

test (this was generated by pdflatex)

but, via dvisvgm, only get

test

I've used compile process of

latex test.tex
dvisvgm test.dvi

Thanks for your interest! And also for this superb package!

muzimuzhi commented 3 years ago

Bad news: pgf's driver for dvisvgm does not support blend mode. (More specifically, it doesn't redefine \pgfsys@blend@mode.) A warning is expected to be found in the log:

Package pgf Warning: Your graphic driver pgfsys-dvisvgm.def does not support bl
end mode. This warning is given only once on input line 6.

Good news: It seems the driver for dvips also works for dvisvgm, so you can just remove the dvisvgm document class option, and still use latex test.tex followed by dvisvgm test.dvi to get the svg output.

hmenke commented 3 years ago

mix-blend-mode is a CSS feature and not intrinsic to SVG. I'm not sure whether we want to support it for dvisvgm.

@muzimuzhi Keep in mind that by using dvips you lose many features of the dvisvgm driver, most importantly animations.

hmenke commented 3 years ago

Unfortunately the naïve implementation doesn't even work.

diff --git a/tex/generic/pgf/systemlayer/pgfsys-common-svg.def b/tex/generic/pgf/systemlayer/pgfsys-common-svg.def
index f1d27290..c1824a73 100644
--- a/tex/generic/pgf/systemlayer/pgfsys-common-svg.def
+++ b/tex/generic/pgf/systemlayer/pgfsys-common-svg.def
@@ -141,6 +141,24 @@
   }%
 }

+\def\pgfsys@blend@mode#1{\pgf@sys@svg@gs{style="mix-blend-mode: \csname pgf@sys@svg@blend@mode@map@#1\endcsname;"}}
+\expandafter\def\csname pgf@sys@svg@blend@mode@map@normal\endcsname{normal}
+\expandafter\def\csname pgf@sys@svg@blend@mode@map@multiply\endcsname{multiply}
+\expandafter\def\csname pgf@sys@svg@blend@mode@map@screen\endcsname{screen}
+\expandafter\def\csname pgf@sys@svg@blend@mode@map@overlay\endcsname{overlay}
+\expandafter\def\csname pgf@sys@svg@blend@mode@map@darken\endcsname{darken}
+\expandafter\def\csname pgf@sys@svg@blend@mode@map@lighten\endcsname{lighten}
+\expandafter\def\csname pgf@sys@svg@blend@mode@map@color dodge\endcsname{color-dodge}
+\expandafter\def\csname pgf@sys@svg@blend@mode@map@color burn\endcsname{color-burn}
+\expandafter\def\csname pgf@sys@svg@blend@mode@map@hard light\endcsname{hard-light}
+\expandafter\def\csname pgf@sys@svg@blend@mode@map@soft light\endcsname{soft-light}
+\expandafter\def\csname pgf@sys@svg@blend@mode@map@difference\endcsname{difference}
+\expandafter\def\csname pgf@sys@svg@blend@mode@map@exclusion\endcsname{exclusion}
+\expandafter\def\csname pgf@sys@svg@blend@mode@map@saturation\endcsname{saturation}
+\expandafter\def\csname pgf@sys@svg@blend@mode@map@color\endcsname{color}
+\expandafter\def\csname pgf@sys@svg@blend@mode@map@hue\endcsname{hue}
+\expandafter\def\csname pgf@sys@svg@blend@mode@map@luminosity\endcsname{luminosity}
+
 % Transformation:
 \def\pgfsys@transformcm#1#2#3#4#5#6{%
   {\pgf@x=#5\pgf@y=#6%
hmenke commented 3 years ago

Acutally browser support for this feature is also a bit spotty, in particular for Apple devices. https://caniuse.com/css-mixblendmode

muzimuzhi commented 3 years ago

mix-blend-mode is a CSS feature and not intrinsic to SVG. I'm not sure whether we want to support it for dvisvgm.

SVG has a <feBlend ... mode="blend_mode"/> filter. MDN pages for <feBlend> filter and mode attribute.

HyunggyuJang commented 3 years ago

Thanks for your quick, detailed response @muzimuzhi, @hmenke.

mix-blend-mode is a CSS feature and not intrinsic to SVG. I’m not sure whether we want to support it for dvisvgm.

First of all, sorry that I have little knowledge about internals of latex, wasn’t aware of the fact that PDF can also integrate CSS specifications. Extra point why I should learn seriously about web programming! Thanks!

Bad news: pgf’s driver for dvisvgm does not support blend mode. (More specifically, it doesn’t redefine \pgfsys@blend@mode.) A warning is expected to be found in the log:

I should have checked or searched through based on that warning message, but frankly, realized there was a warning message after your kind notification. Thanks, but to me, thought if pdflatex can do, why not dvisvgm?

Good news: It seems the driver for dvips also works for dvisvgm, so you can just remove the dvisvgm document class option, and still use latex test.tex followed by dvisvgm test.dvi to get the svg output.

Think, for my use case — to use a latex fragment preview embedded in org mode of emacs — indeed, it is more than sufficient! Thanks for your advice. It solves my initial concern.

@muzimuzhi Keep in mind that by using dvips you lose many features of the dvisvgm driver, most importantly animations.

As for Emacs, animations isn’t critical, since even though Emacs can natively render svg, seems like doesn’t support svg animation. But, yes, also think the most killer feature of tikz in dvisvgm is animation, hope someday blend mode also supported in dvisvgm backend, although, as you indicated, there are some difficulties around that.

From your sincere advice, I could solve my problem at hand. I’d like to let this issue open, however, since, as far as I know, there was no relevant space to track what features are available in dvisvgm backend, think this would be the place for blend group option. But feel free to close if you think unnecessary.

Again, much appreciate your effort, and willingness to cope with any issues in such enthusiastic manner.

P.S. Tried to recompile all the existing embedded latex fragment with

\documentclass[dvips]{standalone}

causes an error when it comes to

\begin{tikzpicture}
\shade (0,0) rectangle (2,1) (3,0.5) circle (.5cm);
\end{tikzpicture}

which is from TikZ manual. Hence, think better stick with dvisvgm option, or selectively use dvips for the ones I need.

hmenke commented 3 years ago

I've converted this into a feature request and changed the title accordingly.

HyunggyuJang commented 3 years ago

I've converted this into a feature request and changed the title accordingly.

Thanks! Now it matches to contents! 👍