<div dir="ltr"><div><br></div><div><br></div>Scaling by small values in xetex/xdvipdfmx<br>==============================<wbr>============<br><br><br>Short Version<br>=============<br><br>Would it be possible for (x)dvipdfm(x) when giving this warning<br><br>WARN("Transformation matrix not invertible.");<br><br>to anyway scale by the specified transform, or to scale by the<br>smallest invertible transformation that it can handle.<br>Or failing that could it use some more numerically stable<br>test than calculating the determinant.<br><br>The overwhelmingly most common transform is a scale factor<br>which is invertible if the x and y scale are non zero but<br>calculating the determinant squares the scale factor and<br>so gets very small and hits the test det < 1.e-8 used by the driver.<br><br>Currently small scale factors that trigger this warning leave the text<br>unscaled.<br><br><br>Long version<br>============<br><br><br>(x)dvipdfm(x) unlike dvips or pdftex or luatex gives an error on<br>transformation matrices that are close to being non-invertible and<br>does not apply the transformation.<br><br>This is especially noticeable in xetex where by default the  warnings<br>from xdvipdfmx are obscured, but the end result is that text fails to<br>scale.<br><br>In this test file with xelatex only 1234 is scaled, ABCDEFG and WXYZ<br>stay at their normal size using xetex if using the xetex.def from<br><br><a href="https://github.com/latex3/graphics-def" target="_blank">https://github.com/latex3/<wbr>graphics-def</a><br><br>If you use the current version of xetex.def from texlive then all<br>three scale. The difference is<br><br><a href="https://github.com/latex3/graphics-def/commit/02e549d7fd34b76cf8df1c5cdda3997f12473959" target="_blank">https://github.com/latex3/<wbr>graphics-def/commit/<wbr>02e549d7fd34b76cf8df1c5cdda399<wbr>7f12473959</a><br><br><br>The texlive 2016 version of xetex.def uses a pdfliteral to implement<br>scaling<br><br>pdf:literal \Gscale@x\space 0 0 \Gscale@y\space 0 0 cm<br><br>specifically to avoid this dvipdfm driver warning.<br><br>However this has been reverted to use the<br><br>\special{x:gsave}\special{x:<wbr>scale \Gscale@x\space\Gscale@y}<br><br><br>specials as used in texlive 2014 as otherwise nested links from using<br>the bann special do not use the transformed coordinate system so the<br><div>link annotation appears in the wrong place.</div><div><br></div><div>The test file has local definitions of the scale code so should show the same</div><div>issue whichever version of xetex.def is used.<br></div><br>%%%%%%%%%%%%%%%%%%%%%%%%%%%%<br><div><br></div><div>\documentclass{article}<br><br>\usepackage{graphics,hyperref,parskip}<br><br>\begin{document}<br><br>\textbf{x:scale: wrong small scaling, but good link area}<br><br>\makeatletter<br>\def\Gscale@start{%<br>  \special{x:gsave}%<br>  \special{x:scale \Gscale@x\space\Gscale@y}<br>  }<br><br>\makeatother<br><br>[\scalebox{0.00001}{ABCDEFG}]<br><br>[\scalebox{0.000001}[0.001]{WXYZ}]<br><br>[\scalebox{0.000001}[0.01]{1234}]<br><br>\scalebox{2}{\href{abc}{abc}}<br><br>\bigskip<br>\textbf{pdf:literal: correct small scaling, but bad link area}<br><br>\makeatletter<br>\def\Gscale@start{%<br>  \special{x:gsave}%<br>  \special{pdf:literal \Gscale@x\space 0 0 \Gscale@y\space 0 0 cm}<br>  }<br>\makeatother<br>[\scalebox{0.00001}{ABCDEFG}]<br><br>[\scalebox{0.000001}[0.001]{WXYZ}]<br><br>[\scalebox{0.000001}[0.01]{1234}]<br><br>\scalebox{2}{\href{abc}{abc}}<br>\end{document}<br></div><br>%%%%%%%%%%%%%%%%%%%%%%%%%%%%<br><br><br>xdvipdfmx warns:<br><br>xdvipdfmx:warning: Transformation matrix not invertible.<br>xdvipdfmx:warning: --- M = [1e-05 0 0 1e-05 79.4811 -62.764]<br>xdvipdfmx:warning: Transformation matrix not invertible.<br>xdvipdfmx:warning: --- M = [1e-06 0 0 0.001 79.4819 -74.6451]<br><br>despite the fact that both those matrices are clearly invertible.<br><br>The xdvipdfmx sources (pdfdraw.c) have<br><br><br>  if (fabs(detP(M)) < 1.e-8) {<br>    WARN("Transformation matrix not invertible.");<br>    WARN("--- M = [%g %g %g %g %g %g]",<br>         M->a, M->b, M->c, M->d, M->e, M->f);<br>    return -1;<br><br><br>As noted above this will give the zero determinant warning<br><br><br>Even if the transform really is non-invertible for example<br><br>\scalebox{0}{oops}<br><br>It would probably be less surprising if the text was scaled to nothing<br>(with a warning) rather than not scaled at all.<br><br>The PDF Reference manual observes that such transformations are not<br>illegal in PDF but may not work as expected:<br><br>> Note: <br>> <br>> When rendering graphics objects, it is sometimes necessary for an<br>> application to perform the inverse of a transformation—that is, to<br>> find the user space coordinates that correspond to a given pair of<br>> device space coordinates.  Not all transformations are invertible,<br>> however. For example, if a matrix contains a, b, c, and d elements<br>> that are all zero, all user coordinates map to the same device<br>> coordinates and there is no unique inverse transformation. Such<br>> noninvertible transformations are not very useful and generally arise<br>> from unintended operations, such as scaling by 0. Use of a<br>> noninvertible matrix when painting graphics objects can result in<br>> un-predictable behavior.<br><br><br>See these two stackexchange questions<br><br>Example of small scaling that fails in xetex<br><br><a href="https://tex.stackexchange.com/questions/328825" target="_blank">https://tex.stackexchange.com/<wbr>questions/328825</a><br><br>Example of mis-placed link annotations with xetex<br><br><a href="https://tex.stackexchange.com/a/368385" target="_blank">https://tex.stackexchange.com/<wbr>a/368385</a></div>