olsak / OpTeX

OpTeX - LuaTeX format with extended Plain TeX macros
http://petr.olsak.net/optex/
35 stars 13 forks source link

Colors and \pdfrestore #82

Closed gromadan closed 2 years ago

gromadan commented 2 years ago

It seems that the colors in OpTeX do not work well with \pdfsave and \pdfrestore. Consider the following code

\pdfsave\pdfrotate{90}\Red A\pdfrestore

\Red B

\bye

The letter B is black although it should be red.

(If I remember correctly, it was possible to turn off the color stacking in the earlier versions of OpTeX, which might help here. But I did not find this possibility in the current documentation.)

vlasakm commented 2 years ago

It's true that with OpTeX v1.03 and earlier you would get red A and red B. However, with OpTeX v1.04 there is a new color behavior - colors always respect TeX groups.

There is still (as in earlier versions) a \nolocalcolor mode, which now just makes the color settings be \global. Though it's not that would help in this case, since your program doesn't have any groups. That's actually why the second \Red doesn't do anything - in the top level group level the color didn't ever change after the first \Red.

The problem here is, that in #57 we decided to make color implemention simpler, by requiring the users to "balance" their use of colors in weird situations, such as leaders, PDF literals, PDF stores and restores.

Here in your example you set the color to red inside a \pdfsave/\pdfrestore block. While that worked fine previously (when there was no postprocessing, and the color implementation was more "direct"), now it confuses the color system - because there is no group end it still thinks that the color is red, although \pdfrestore resetted it in the PDF state!

Maybe the decision to ignore \pdfsave/\pdfrestore was wrong, as partly demonstrated by #73, where it turns out that maybe we still need to detect them somewhere. But I think that with the "TeX grouping" mindset however, this particular behavior makes sense (and as a matter of fact #74 doesn't change it).

So what can be done with the document at hand? Well the use of colors in \pdfsave/\pdfrestore pairs should be balanced, so you can just enclose it in a group - \pdfsave\pdfrotate{90}{\Red A}\pdfrestore.

While that solves the presented issue, there are still a few problems left with the example you provided:

The easiest thing to do is to just use \transformbox or even \rotbox in this case. But note that this creates box thats gets inserted according to the current mode! And you should decide whether you want it to be stacked with paragraphs vertically, or with letters in lines horizontally. I think you probably need the second one, so also need \quitvmode to switch to horizontal mode.

\fontfam[lm]

%\quitvmode\transformbox{\pdfrotate{90}}{\Red A}
\quitvmode\rotbox{90}{\Red A}

\Red B

\bye

2021-11-29-202521

I know that this example is most likely a MWE you put together just to show the color problem, so the horizontal / vertical mode problem maybe didn't hit your use, since you already were in the right mode, but as you see, sometimes one needs to be careful.

gromadan commented 2 years ago

Thanks for your extensive answer, but

\pdfsave\pdfrotate{90}{\Red A}\pdfrestore

\Red B

does not work for me either. Did you try it yourself? Maybe I am doing something wrong. I actually thought before that the grouping might be important, but nothing was really working

gromadan commented 2 years ago

And your suggestion works neither. Maybe there is some problem with my installation.

vlasakm commented 2 years ago

Hm, indeed you are right, sorry. I was testing with #74 already applied. My apologies.

Why it doesn't work without #74 is because of an optimization in the color switching - to save bytes in the PDF, color is changed only when needed, without #74 \pdfrestores are not seen as color needing, so there is in fact nothing nonred between red A and red B, which means that the code thinks that red is still active when it gets to B. This is exactly what issue #73 is about and #74 is trying to solve.

@olsak Did you decide about #74? I think this is more evidence that it is probably right way to go.

olsak commented 2 years ago

I accepted #74. Thank you.