[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