# [tex-live] Small scaling values in xetex / (x)dvipdfm(x)

David Carlisle d.p.carlisle at gmail.com
Mon May 8 13:54:27 CEST 2017

Scaling by small values in xetex/xdvipdfmx
==========================================

Short Version
=============

Would it be possible for (x)dvipdfm(x) when giving this warning

WARN("Transformation matrix not invertible.");

to anyway scale by the specified transform, or to scale by the
smallest invertible transformation that it can handle.
Or failing that could it use some more numerically stable
test than calculating the determinant.

The overwhelmingly most common transform is a scale factor
which is invertible if the x and y scale are non zero but
calculating the determinant squares the scale factor and
so gets very small and hits the test det < 1.e-8 used by the driver.

Currently small scale factors that trigger this warning leave the text
unscaled.

Long version
============

(x)dvipdfm(x) unlike dvips or pdftex or luatex gives an error on
transformation matrices that are close to being non-invertible and
does not apply the transformation.

This is especially noticeable in xetex where by default the  warnings
from xdvipdfmx are obscured, but the end result is that text fails to
scale.

In this test file with xelatex only 1234 is scaled, ABCDEFG and WXYZ
stay at their normal size using xetex if using the xetex.def from

https://github.com/latex3/graphics-def

If you use the current version of xetex.def from texlive then all
three scale. The difference is

https://github.com/latex3/graphics-def/commit/02e549d7fd34b76cf8df1c5cdda399
7f12473959

The texlive 2016 version of xetex.def uses a pdfliteral to implement
scaling

pdf:literal \Gscale at x\space 0 0 \Gscale at y\space 0 0 cm

specifically to avoid this dvipdfm driver warning.

However this has been reverted to use the

\special{x:gsave}\special{x:scale \Gscale at x\space\Gscale at y}

specials as used in texlive 2014 as otherwise nested links from using
the bann special do not use the transformed coordinate system so the
link annotation appears in the wrong place.

The test file has local definitions of the scale code so should show the
same
issue whichever version of xetex.def is used.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\documentclass{article}

\usepackage{graphics,hyperref,parskip}

\begin{document}

\textbf{x:scale: wrong small scaling, but good link area}

\makeatletter
\def\Gscale at start{%
\special{x:gsave}%
\special{x:scale \Gscale at x\space\Gscale at y}
}

\makeatother

[\scalebox{0.00001}{ABCDEFG}]

[\scalebox{0.000001}[0.001]{WXYZ}]

[\scalebox{0.000001}[0.01]{1234}]

\scalebox{2}{\href{abc}{abc}}

\bigskip
\textbf{pdf:literal: correct small scaling, but bad link area}

\makeatletter
\def\Gscale at start{%
\special{x:gsave}%
\special{pdf:literal \Gscale at x\space 0 0 \Gscale at y\space 0 0 cm}
}
\makeatother
[\scalebox{0.00001}{ABCDEFG}]

[\scalebox{0.000001}[0.001]{WXYZ}]

[\scalebox{0.000001}[0.01]{1234}]

\scalebox{2}{\href{abc}{abc}}
\end{document}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%

xdvipdfmx warns:

xdvipdfmx:warning: Transformation matrix not invertible.
xdvipdfmx:warning: --- M = [1e-05 0 0 1e-05 79.4811 -62.764]
xdvipdfmx:warning: Transformation matrix not invertible.
xdvipdfmx:warning: --- M = [1e-06 0 0 0.001 79.4819 -74.6451]

despite the fact that both those matrices are clearly invertible.

The xdvipdfmx sources (pdfdraw.c) have

if (fabs(detP(M)) < 1.e-8) {
WARN("Transformation matrix not invertible.");
WARN("--- M = [%g %g %g %g %g %g]",
M->a, M->b, M->c, M->d, M->e, M->f);
return -1;

As noted above this will give the zero determinant warning

Even if the transform really is non-invertible for example

\scalebox{0}{oops}

It would probably be less surprising if the text was scaled to nothing
(with a warning) rather than not scaled at all.

The PDF Reference manual observes that such transformations are not
illegal in PDF but may not work as expected:

> Note:
>
> When rendering graphics objects, it is sometimes necessary for an
> application to perform the inverse of a transformation—that is, to
> find the user space coordinates that correspond to a given pair of
> device space coordinates.  Not all transformations are invertible,
> however. For example, if a matrix contains a, b, c, and d elements
> that are all zero, all user coordinates map to the same device
> coordinates and there is no unique inverse transformation. Such
> noninvertible transformations are not very useful and generally arise
> from unintended operations, such as scaling by 0. Use of a
> noninvertible matrix when painting graphics objects can result in
> un-predictable behavior.

See these two stackexchange questions

Example of small scaling that fails in xetex

https://tex.stackexchange.com/questions/328825

Example of mis-placed link annotations with xetex

https://tex.stackexchange.com/a/368385
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://tug.org/pipermail/tex-live/attachments/20170508/78180a60/attachment.html>