[tex-k] dvips: 'fun' with translation combined with scaling/rotation

Joseph Wright joseph.wright at morningstar2.co.uk
Mon Mar 5 08:14:26 CET 2018


On 04/03/2018 15:39, Joseph Wright wrote:
> On 04/03/2018 15:25, Joseph Wright wrote:
>> Hello all,
>>
>> I've run into an oddity with dvips: this might well be 'user error' 
>> but I'd appreciate any insight.
>>
>> What I'm trying to do is set up box transformations inside a 'drawing' 
>> environment. The aim is to avoid using a completely raw special (ps:: 
>> <matrix> concat) as that is opaque to the driver and means it looses 
>> hyperlinks and the like. I can get it all working *provided* I don't 
>> have any translation applied.
>>
>> In the following example, you only get the result I was expecting if 
>> you set \shiftmatrixtrue and \rotateandscalefalse, i.e. do everything 
>> in one matrix operation. If you split the shift of the box out then an 
>> 'extra' displacement pops up. It seems that the transformation (either 
>> rotation/scaling or matrix-based) is applied to the kern which is 
>> *before* the operations. You see the same effect if you add a y-shift 
>> (moving the box up/down), and with a pure scaling (so no rotation at 
>> all).
>>
>> The same general approach works as-expected with (x)dvipdfmx, where 
>> again we have scaling/rotation but no driver-tracked transformation 
>> (cf. pdfTeX), so I don't think I have the kern in the obviously-wrong 
>> place.
>>
>> I suspect I'm missing a save/restore or similar: any ideas?
>>
>> Joseph
>>
>>      \newif\ifshiftmatrix
>>      \shiftmatrixtrue
>>      \newif\ifrotateandscale
>>      \rotateandscalefalse
>>
>>      \setbox0=\hbox{%
>>        \special{ps::[begin]}% Line up with TeX current point
>>        \special{ps::/ox currentpoint /oy exch def def}% Save the origin
>>        \special{ps::@beginspecial}% Get scale and axis 'into line'
>>        \special{ps::0 0 moveto}%              (0cm,0cm)
>>        \special{ps::85.04045 0 lineto}%       (3cm,0cm)
>>        \special{ps::28.3468 0 moveto}%        (1cm,0cm}
>>        \special{ps::28.3468 56.69363 lineto}% (1cm,2cm)
>>        \special{ps::stroke}%
>>        \special{ps::newpath}%
>>        \hbox to 0pt{%
>>          \ifshiftmatrix\else\kern 1cm \fi
>>          \special{ps::save}%
>>          \ifrotateandscale
>>            % Singular value decomposition of [1 2 1 1]
>>            \special{ps::58.28253 rotate}%
>>            \special{ps::2.61803 -0.38197 scale}%
>>            \special{ps::-31.71747 rotate}%
>>          \else
>>            \ifshiftmatrix
>>              \special{ps::[1 2 1 1 28.3468 0] concat}%
>>            \else
>>              \special{ps::[1 2 1 1 0 0] concat}%
>>            \fi
>>          \fi
>>        % The next three lines get us 'back' to the TeX origin
>>          \special{ps::72 Resolution div 72 VResolution div neg scale}%
>>          \special{ps::magscale {1 DVImag div dup scale} if}%
>>          \special{ps::ox neg oy neg translate}%
>>          \special{ps::[end]}%
>>          \hbox to 0pt{Hello\hss}%
>>          \special{ps::[begin]}%
>>          \special{ps::restore}%
>>          \hss
>>        }%
>>        \special{ps::@endspecial}% Tidy up
>>        \special{ps::[end]}%
>>      }%
>>      \wd0=3cm %
>>      \ht0=2cm %
>>      \box0 %
>>
>>      world
>>
>>      \bye
> 
> Oh, I should add that the "world" at the end deals with a second oddity: 
> depending on the exact set up of scaling/rotation, something goes odd 
> and the entire page is landscape.
> 
> Joseph

It occurs to me that the dvipdfmx comparison is likely misleading: in 
the latter, rotation and scaling is covered by driver-specific specials, 
but for dvips only 'raw' PostScipt is available.

However, the core question remains: what is it that leads the 
transformation to apply to kerns/box shifts *before* it is inserted? 
(And indeed, what exactly determines the scope of the transformation.) 
If the answer is 'it just is', I can adjust by working out the requested 
shifts allowing for the subsequent transformation. But I'd like to be 
sure it's entirely predictable, at least.

Joseph


More information about the tex-k mailing list