Open davidcarlisle opened 4 years ago
It is rather under-specified whether the default centre of rotation is the left hand edge or the right hand edge (actually it is specified in several places that it is the left, but it is implicitly implying left-to-right writing direction)
If we assume that the centre should be the start of the baseline in the writing direction then \rotatebox{90}{..}
will come mostly below the baseline in a RTL context. In luatex this I think gives the desired output if we take that interpretation,
\documentclass{article}
\usepackage{graphicx}
\makeatletter
\protected\long\def\STDrotatebox#1#2{%
\leavevmode
\Grot@setangle{#1}%
\setbox\z@\hbox{{#2}}%
\ifnum\textdirection=\z@
\Grot@x\z@
\else
\Grot@x\wd\z@
\fi
\Grot@y\z@
\Grot@box}
\long\def\Grot@box@std#1#2{%
\Grot@setangle{#1}%
\setbox\z@\hbox{{#2}}%
\ifnum\textdirection=\z@
\Grot@x\z@
\else
\Grot@x\wd\z@
\fi
\Grot@y\z@
\Grot@box}
\long\def\Grot@box@kv[#1]#2#3{%
\@begin@tempboxa\hbox{#3}%
\Grot@x\width \divide\Grot@x\tw@
\Grot@y\height \advance\Grot@y-\depth \divide\Grot@y\tw@
\setkeys{Grot}{#1}%
\setbox\z@\box\@tempboxa
\Grot@setangle{#2}%
\Grot@box
\@end@tempboxa}
\def\Grot@box{%
\begingroup
\CalculateSin\Grot@angle
\CalculateCos\Grot@angle
\edef\Grot@sin{\UseSin\Grot@angle}%
\edef\Grot@cos{\UseCos\Grot@angle}%
% \GDebug{Rotate: angle \Grot@angle, sine is \Grot@sin,
% cosine is \Grot@cos}%
\Grot@r\wd\z@ \advance\Grot@r-\Grot@x
\Grot@l\z@ \advance\Grot@l-\Grot@x
\Grot@h\ht\z@ \advance\Grot@h-\Grot@y
\Grot@d-\dp\z@ \advance\Grot@d-\Grot@y
\ifdim\Grot@sin\p@>\z@
\ifdim\Grot@cos\p@>\z@
\Grot@Py\Grot@height \Grot@r\Grot@h%B
\Grot@Px\Grot@right \Grot@r\Grot@d%E
\Grot@Px\Grot@left \Grot@l\Grot@h%C
\Grot@Py\Grot@depth \Grot@l\Grot@d%D
\else
\Grot@Py\Grot@height \Grot@r\Grot@d%E
\Grot@Px\Grot@right \Grot@l\Grot@d%D
\Grot@Px\Grot@left \Grot@r\Grot@h%B
\Grot@Py\Grot@depth \Grot@l\Grot@h%C
\fi
\else
\ifdim\Grot@cos\p@<\z@
\Grot@Py\Grot@height \Grot@l\Grot@d%D
\Grot@Px\Grot@right \Grot@l\Grot@h%C
\Grot@Px\Grot@left \Grot@r\Grot@d%E
\Grot@Py\Grot@depth \Grot@r\Grot@h%B
\else
\Grot@Py\Grot@height \Grot@l\Grot@h%C
\Grot@Px\Grot@right \Grot@r\Grot@h%B
\Grot@Px\Grot@left \Grot@l\Grot@d%D
\Grot@Py\Grot@depth \Grot@r\Grot@d%E
\fi
\fi
\advance\Grot@height\Grot@y
\advance\Grot@depth\Grot@y
\Grot@Px\dimen@ \Grot@x\Grot@y
\Grot@Py\dimen@ii \Grot@x\Grot@y
\dimen@-\dimen@ \advance\dimen@-\Grot@left
\dimen@ii-\dimen@ii \advance\dimen@ii\Grot@y
% \GDebug{Rotate: (l,r,h,d)^^J%
% Original \the\Grot@l,\the\Grot@r,\the\Grot@h,\the\Grot@d,^^J%
% New..... \the\Grot@left,\the\Grot@right,%
% \the\Grot@height,\the\Grot@depth}%
\setbox\z@\hbox{%
\kern\dimen@
\raise\dimen@ii\hbox{%
\ifnum\textdirection=\z@\else
\typeout{[\the\Grot@left][\the\Grot@right][\the\dimen@]}%
\kern\dimexpr\Grot@right-\dimen@\relax
\raise-\dimen@ii\hbox
\fi
{\Grot@start\box\z@\Grot@end}}}%
\ht\z@\Grot@height
\dp\z@-\Grot@depth
\advance\Grot@right-\Grot@left\wd\z@\Grot@right
\leavevmode\box\z@
\endgroup}
\makeatother
\begin{document}
a\fbox{\rotatebox[origin=Br]{90}{abc}}
1\fbox{\rotatebox{45}{abc}}
2\fbox{\rotatebox{90}{abc}}
3\fbox{\rotatebox{-45}{abc}}
4\fbox{\rotatebox{-90}{abc}}
\ifx\textdir\undefined\else
\textdir TRT
\fi
a\fbox{\rotatebox[origin=Br]{90}{abc}}
1\fbox{\rotatebox{45}{abc}}
2\fbox{\rotatebox{90}{abc}}
3\fbox{\rotatebox{-45}{abc}}
4\fbox{\rotatebox{-90}{abc}}
\end{document}
Origin = Bl doesn't look right. And perhaps one would need origins s
and e
for start and end in writing direction (so s=l in TLT and r in TRT).
\documentclass{article}
\usepackage{graphicx}
\makeatletter
\protected\long\def\STDrotatebox#1#2{%
\leavevmode
\Grot@setangle{#1}%
\setbox\z@\hbox{{#2}}%
\ifnum\textdirection=\z@
\Grot@x\z@
\else
\Grot@x\wd\z@
\fi
\Grot@y\z@
\Grot@box}
\long\def\Grot@box@std#1#2{%
\Grot@setangle{#1}%
\setbox\z@\hbox{{#2}}%
\ifnum\textdirection=\z@
\Grot@x\z@
\else
\Grot@x\wd\z@
\fi
\Grot@y\z@
\Grot@box}
\long\def\Grot@box@kv[#1]#2#3{%
\@begin@tempboxa\hbox{#3}%
\Grot@x\width \divide\Grot@x\tw@
\Grot@y\height \advance\Grot@y-\depth \divide\Grot@y\tw@
\setkeys{Grot}{#1}%
\setbox\z@\box\@tempboxa
\Grot@setangle{#2}%
\Grot@box
\@end@tempboxa}
\def\Grot@box{%
\begingroup
\CalculateSin\Grot@angle
\CalculateCos\Grot@angle
\edef\Grot@sin{\UseSin\Grot@angle}%
\edef\Grot@cos{\UseCos\Grot@angle}%
% \GDebug{Rotate: angle \Grot@angle, sine is \Grot@sin,
% cosine is \Grot@cos}%
\Grot@r\wd\z@ \advance\Grot@r-\Grot@x
\Grot@l\z@ \advance\Grot@l-\Grot@x
\Grot@h\ht\z@ \advance\Grot@h-\Grot@y
\Grot@d-\dp\z@ \advance\Grot@d-\Grot@y
\ifdim\Grot@sin\p@>\z@
\ifdim\Grot@cos\p@>\z@
\Grot@Py\Grot@height \Grot@r\Grot@h%B
\Grot@Px\Grot@right \Grot@r\Grot@d%E
\Grot@Px\Grot@left \Grot@l\Grot@h%C
\Grot@Py\Grot@depth \Grot@l\Grot@d%D
\else
\Grot@Py\Grot@height \Grot@r\Grot@d%E
\Grot@Px\Grot@right \Grot@l\Grot@d%D
\Grot@Px\Grot@left \Grot@r\Grot@h%B
\Grot@Py\Grot@depth \Grot@l\Grot@h%C
\fi
\else
\ifdim\Grot@cos\p@<\z@
\Grot@Py\Grot@height \Grot@l\Grot@d%D
\Grot@Px\Grot@right \Grot@l\Grot@h%C
\Grot@Px\Grot@left \Grot@r\Grot@d%E
\Grot@Py\Grot@depth \Grot@r\Grot@h%B
\else
\Grot@Py\Grot@height \Grot@l\Grot@h%C
\Grot@Px\Grot@right \Grot@r\Grot@h%B
\Grot@Px\Grot@left \Grot@l\Grot@d%D
\Grot@Py\Grot@depth \Grot@r\Grot@d%E
\fi
\fi
\advance\Grot@height\Grot@y
\advance\Grot@depth\Grot@y
\Grot@Px\dimen@ \Grot@x\Grot@y
\Grot@Py\dimen@ii \Grot@x\Grot@y
\dimen@-\dimen@ \advance\dimen@-\Grot@left
\dimen@ii-\dimen@ii \advance\dimen@ii\Grot@y
% \GDebug{Rotate: (l,r,h,d)^^J%
% Original \the\Grot@l,\the\Grot@r,\the\Grot@h,\the\Grot@d,^^J%
% New..... \the\Grot@left,\the\Grot@right,%
% \the\Grot@height,\the\Grot@depth}%
\setbox\z@\hbox{%
\kern\dimen@
\raise\dimen@ii\hbox{%
\ifnum\textdirection=\z@\else
\typeout{[\the\Grot@left][\the\Grot@right][\the\dimen@]}%
\kern\dimexpr\Grot@right-\dimen@\relax
\raise-\dimen@ii\hbox
\fi
{\Grot@start\box\z@\Grot@end}}}%
\ht\z@\Grot@height
\dp\z@-\Grot@depth
\advance\Grot@right-\Grot@left\wd\z@\Grot@right
\leavevmode\box\z@
\endgroup}
\makeatother
\begin{document}
a\fbox{abc}\fbox{\rotatebox[origin=Br]{90}{abcrr}}\fbox{\rotatebox[origin=Bl]{90}{abcll}}
\ifx\textdir\undefined\else
\textdir TRT
\fi
a\fbox{abc}\fbox{\rotatebox[origin=Br]{90}{abcrrr}}\fbox{\rotatebox[origin=Bl]{90}{abclll}}
\end{document}
yes I hadn't really checked the interpretation of all the origin options, just forced that example to work to see if that is the expected answer rather than rotating from the left edge.
Another thing to resolve: since TRT is a reflection of TLT, should the meaning of a ‘positive rotation value’ also get reflected to mean ‘clockwise’ (assuming Hebrew clocks look like (most) English clocks).
It’s all relative:-).
Why not rotate about the centre of the box? I recall ‘discussing’ this with Sebastian, who maintained volubly that it was ‘completely obvious’ what a rotation is, so no need to specify the centre!
should the meaning of a ‘positive rotation value’ also get reflected to mean ‘clockwise’
Unless there is strong push from native speakers that that is the convention I think it would be pretty confusing to change the direction.
Why not rotate about the centre of the box?
I don't think we can change the behaviour of LTR documents. The centre is the default value of the origin key so \rotatebox[]{90}{1234}
rotates around the centre, as does \rotatebox[origin=c]{90}{1234}
We also need to coordinate with the patches done for xetex by the bidi package.
\documentclass{article}
\usepackage{graphicx,bidi}
\TeXXeTstate=1
\begin{document}
a\fbox{\rotatebox[origin=Br]{90}{abc}}
1\fbox{\rotatebox{45}{abc}}
2\fbox{\rotatebox{90}{abc}}
3\fbox{\rotatebox{-45}{abc}}
4\fbox{\rotatebox{-90}{abc}}
\setRTL
a\fbox{\rotatebox[origin=Br]{90}{abc}}
1\fbox{\rotatebox{45}{abc}}
2\fbox{\rotatebox{90}{abc}}
3\fbox{\rotatebox{-45}{abc}}
4\fbox{\rotatebox{-90}{abc}}
\end{document}
@davidcarlisle
Unless there is strong push from native speakers that that is the convention I think it would be pretty confusing to change the direction.
If it is of any help, I am a native speaker of Arabic (A Right to left language), however, I do not have much experience regarding the programming aspect you are discussing, I am not used to modifying packages.
A use-case for rotating text (the only generic one I can immediately think of):
Typesetting column headings in a table, if they are long one often rotates them through 90deg (or 45deg for easier reading). Now think about an RTL document. My intuition is that the “equivalent layout” of a table in RTL is obtained by a reflection. For such headings is thus obtained by rotating the text through the opposite angle.
I think that considering the centre of rotation is not helpful in practical use-cases.
It is better to think as follows: first rotate the box (about any centre); then decide where
on the page you want the reference of the “new box” to be.
Note: “new box” needs interpretation, it could be the rotated box itself, or the bounding box of the rotated box.
@vinoruto Did you follow my use-case regarding rotated text in column-headings? Your input on this would be useful.
@davidcarlisle or @u-fischer Any chance of producing the two possibilities for such a table? Preferably using 45deg rotation as this makes the distinction very clear.
This is not entirely a question of programming although I can see arguments (at least from non-tech types) for not changing the meaning of a “positive rotation”. But therefore there is probably a need to be able to specify (at document level) the direction of a rotation that is relative to the current text direction, rather than absolutely (relatively to the page co-ordinate system].
@car222222
Did you follow my use-case regarding rotated text in column-headings? Your input on this would be useful
It is more appropriate for me if there is a worked example, I can provide sample text if you need so.
I asked if @davidcarlisle or @u-fischer can make up, or find, examples of my use-case.
But they are very busy people. Maybe I shall loook for something I can adapt.
Surely @khaledhosny can provide some authoritative opinion on the rotation convention?
@car222222 , if it is not of any annoyance to you, can you give me a little bit more detail of what you would like to do since this issue caused me to suspend an ongoing typsetting process of a certain publication of mine. A simplified know how or an example which I can follow to generate your query in Arabic (RTL language) since I am not experienced at Latex Hacking.
@car222222 I think you mean an example like this? (made with xetex and bidi package
\documentclass{article}
\usepackage{graphicx}
\usepackage{bidi}
\begin{document}
\begin{tabular}{ll}
\rotatebox{45}{head1}&
\rotatebox{45}{head2}\\
\hline
aaa&bbb
\end{tabular}
\setRTL
\begin{tabular}{ll}
\rotatebox{45}{head1}&
\rotatebox{45}{head2}\\
\hline
aaa&bbb
\end{tabular}
\begin{tabular}{ll}
\rotatebox{-45}{head1}&
\rotatebox{-45}{head2}\\
\hline
aaa&bbb
\end{tabular}
\end{document}
@vinoruto the main question is what you would expect that a \rotatebox{45}{...} does in a RTL context. Here a few possibilities:
I would argue against changing the direction of rotation.
CSS for example which has much more embedded support for bidirectional text than we do always takes positive rotation to be in the same direction (which it takes as clockwise actually, but it's not dependent on the text direction)
https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotate
It would also be confusing in diagrams and other vector drawing contexts if the rotation direction depended on the text direction of the outer context.
I would argue against changing the direction of rotation.
That was my first reaction too, I'm rather confident that 45 rotates everywhere in the same direction (anti-clockwise) .
Makes sense to me too. So do we think Ulrike's third example above is probably the most sensible outcome?
Thanks for the examples, David. Yes, I think they shows the correct things but using aaa and bbb does not help thinking about writing directions:-). My claim is that the lower one in the RTL column is the "visual equivalent" of the LTR one, for the angle of the text goes. BUT the text inside both the RTL boxes is not set in RTL is it? (Impossible to tell whether the aaa and bbb have changed diretcion!)
My suggestion is to provide an extra command that rotates in the "expcted direction" relative to the writing direction.
If rotation is specified using angles, then it should be direction-independent; rotating 45 degrees should do the same thing regardless of the text directions (clockwise is the same if you are speaking Arabic or Greek, Arabic clocks don’t rotate in a different direction).
It is also desirable to have direction-neutral layouts that produce the right output for a given document or text direction, but these should then use relating not absolute terms. A good example is CSS text-align: left
that always aligns to the left, and text-align: start
that aligns to the left or to the right depending on the direction.
Makes sense to me too. So do we think Ulrike's third example above is probably the most sensible outcome?
Well it depends on if you think about the mathematics or typesetting. For e.g. table headers you don't want to rotate by 45 degrees around the left corner but probably "go up by an angle of 45 in writing direction". Which for LTR means \rotatebox{45} but for RTL \rotatebox[origin=Br]{-45}. And the question is if one needs a syntax for this.
\documentclass{article}
\usepackage{graphicx}
\usepackage{bidi}
\begin{document}
\begin{tabular}{ll}
x\rotatebox{60}{xxxx}x&
x\rotatebox{60}{xxxx}x\\
\hline
aaa&bbb
\end{tabular}
\setRTL
\begin{tabular}{ll}
x\rotatebox[origin=Br]{-60}{xxxx}x&
x\rotatebox[origin=Br]{-60}{xxxx}x\\
\hline
aaa&bbb
\end{tabular}
\end{document}
Yes, Ulrike is saying much the same as I meant.
In practice, at least for this use-case, after the rotation you will always need to translate the box to get it to 'look right', so the exact location of the rotation centre is not vital.
But please use unsymmetric letters and words so that we can see all the details of what is really going on!
But please use unsymmetric letters and words so that we can see all the details of what is really going on!
I used symmmetric letters and words on purpose to avoid confusing due to missing direction changes inside the box (and tabular cells when using lualatex).
@u-fischer - @car222222 , I modified the code to use lualatex + Babel, and used simple obvious arabic words, I tested it out and all is working fine, If you may check it out
\documentclass{article}
\usepackage{graphicx}
\usepackage[bidi=basic,layout=lists.tabular]{babel}
\babelprovide[import=en,maparabic,main]{english}
\babelprovide[import=ar,language=Default]{arabic}
\babelfont{rm}{Latin Modern Roman}
\babelfont[arabic]{rm}{Simplified Arabic} % Can use "Amiri" instead of simplified arabic
\babelfont[english]{rm}{Times New Roman}
\begin{document}
\begin{tabular}{ll}
x\rotatebox{60}{\foreignlanguage{arabic}{ذهب}}x&
x\rotatebox{60}{\foreignlanguage{arabic}{فهم}}x\\
\hline
\foreignlanguage{arabic}{نام}
&
\foreignlanguage{arabic}{ريم}\\
\hline
Rome & Dome
\end{tabular}
\begin{tabular}{ll}
x\rotatebox[origin=Br]{-60}{\foreignlanguage{arabic}{ذهب}}x&
x\rotatebox[origin=Br]{-60}{\foreignlanguage{arabic}{فهم}}x\\
\hline
\foreignlanguage{arabic}{نام}
&
\foreignlanguage{arabic}{ريم}\\
\hline
Rome & Dome
\end{tabular}
\end{document}
Hey dudes, isn't there anyway to resolve this issue, it causing me some truly annoying technical difficulties.
I made a testfile for lualatex and checked the rotation for the various origins and a few angles. Imho the rotation and the bounding box is always fine. The only thing wrong is the vertical shift: for 0-180 is should go up, for 180-360 down by an unknown amount.
\documentclass{article}
\usepackage{graphicx}
\usepackage{tikz}
\newcommand\baseline[2][red]{\tikz[overlay]\draw[#1](0,0)--++(#2,0);\ignorespaces}
\newcommand\testtext[1]{\fboxsep=0pt \fbox{#1yytt\rule[-10pt]{1pt}{20pt}}}
\newcommand\testangle{90}
\newcommand\testrotate[1]{%
\fbox{\rotatebox[origin=#1]{\testangle}
{\baseline[green]{\ifnum\textdirection=0 1\else -1 \fi}\testtext{#1}}}}
\newcommand\testsuite[1]{%
\renewcommand\testangle{#1}
\ifnum\textdirection=0
\baseline{20}%
\else
\baseline{-20}%
\fi
a\fbox{\testtext{NN}}
\testrotate{Br}
\testrotate{Bl}
\testrotate{lb}
\testrotate{rb}
\testrotate{lt}
\testrotate{rt}
\testrotate{c}
}%
\begin{document}
\testsuite{90}
\testsuite{-90}
\testsuite{50}
\testsuite{-50}
\testsuite{180}
\newpage
\textdir TRT \pardir TRT
\testsuite{90}
\testsuite{-90}
\testsuite{50}
\testsuite{-50}
\testsuite{180}
\end{document}
This issue has been automatically marked as stale because it has not had recent activity.
Brief outline of the bug
this is essentially a copy of
https://github.com/latex3/babel/issues/42
but restricted to the core rotation issues.
In luatex you get
in xetex you get
and in pdftex you get