Update adds a patch of LaTeX's \selectfont
to modify its way of defining \strutbox
as per OP's request in a comment. To be further adapted to one's needs. When \set@fontsize
is called, the new font isn't yet loaded, thus, I ended up adding some extra code at the very end of \selectfont
rather than patching \set@fontsize
.
TeX
has a mechanism for setting lines \baselineskip
apart which most of the time works fine. As explained in @DavidCarlisle's answer, the \strutbox
is defined with an ad hoc .7:.3:1
rule for height:depth:baselineskip
. Unfortunately this means that adding a \strut
to a situation where things were otherwise well aligned will sometimes cause misalignments. Here below is an example where the depth coming from the strut plus the height coming from an accented character on the next line will have a total exceeding the baselineskip, because the .7\baselineskip
falls short of the height of the accented character.
\documentclass[12pt]{article}
\usepackage [utf8]{inputenc}
\usepackage [T1]{fontenc}
\usepackage {multicol}
\begin{document}\pagestyle{empty}\thispagestyle{empty}
Without struts:
\begin{multicols}{2}
Etat de droit Etat de droit Etat de droit Etat de droit Etat de droit
Etat de droit Etat de droit Etat de droit\par
\columnbreak
\'Etat de droit \'Etat de droit \'Etat de droit \'Etat de droit \'Etat
de droit \'Etat de droit \'Etat de droit\par
\end{multicols}
With two added struts (the one on the left does no harm), the
alignment is off!:
\begin{multicols}{2}
\strut Etat de droit Etat de droit Etat de droit Etat de droit Etat de droit
Etat de droit Etat de droit Etat de droit\par
\columnbreak
\strut État de droit État de droit État de droit État de droit État
de droit État de droit État de droit\par
\end{multicols}
\end{document}
produces

This was discussed in a thread on a French newsgroup, the situation is worse with lmodern
:
\documentclass[12pt]{article}
\usepackage [utf8]{inputenc}
\usepackage [T1]{fontenc}
\usepackage {multicol}
\usepackage{lmodern}
\begin{document}\pagestyle{empty}\thispagestyle{empty}
Without struts:
\begin{multicols}{2}
Etat de droit Etat de droit Etat de droit Etat de droit Etat de droit
Etat de droit Etat de droit Etat de droit\par
\columnbreak
\'Etat de droit \'Etat de droit \'Etat de droit \'Etat de droit \'Etat
de droit \'Etat de droit \'Etat de droit\par
\end{multicols}
With two added struts (the one on the left does no harm), the
alignment is off!:
\begin{multicols}{2}
\strut Etat de droit Etat de droit Etat de droit Etat de droit Etat de droit
Etat de droit Etat de droit Etat de droit\par
\columnbreak
\strut État de droit État de droit État de droit État de droit État
de droit État de droit État de droit\par
\end{multicols}
With more struts at the right, alignment even more off:
\begin{multicols}{2}
\strut Etat de droit Etat de droit Etat de droit Etat de droit Etat de droit
Etat de droit Etat de droit Etat de droit\par
\columnbreak
\strut État de droit État de droit État de droit \strut État de droit État
de droit État de droit État de droit\par
\end{multicols}
\end{document}

Code for patching \selectfont
.
\documentclass[12pt]{article}
\usepackage [utf8]{inputenc}
\usepackage [T1]{fontenc}
\usepackage {multicol}
\usepackage{lmodern}
% patch \selectfont
\makeatletter
\newbox\igor@tempbox
% or \@tempboxa but perhaps some code calls \selectfont
% not expecting \@tempboxa to be modified
\def\igor@fixstrutbox{\setbox\igor@tempbox\hbox{ÉÈÙÀĂÅ}%
% first we reset the \strutbox to not inherit a situation which
% could go through unmodified but would depend upon the sequence
% of earlier font changes, if you didn't make the change now.
%
\setbox\strutbox\hbox{\vrule
\@height.7\baselineskip
\@depth.3\baselineskip
\@width\z@}%
\ifdim\ht\igor@tempbox>\ht\strutbox
% comment out these two lines in real use cases
\typeout{IGOR: MODIFYING DEFAULT STRUTBOX\on@line.}%
\typeout{IGOR: old=\the\ht\strutbox, new=\the\ht\igor@tempbox}%
\setbox\strutbox\hbox{\vrule
\@height\ht\igor@tempbox % add some extra?
\@depth\dimexpr\baselineskip-\ht\igor@tempbox\relax
\@width\z@}\fi }%
\expandafter\def
\csname selectfont \expandafter\expandafter\expandafter
\endcsname
\expandafter\expandafter\expandafter
{\csname selectfont \endcsname\igor@fixstrutbox}%
\makeatother
\begin{document}\pagestyle{empty}\thispagestyle{empty}
Without struts (no problems):
\begin{multicols}{2}
Etat de droit Etat de droit Etat de droit Etat de droit Etat de droit
Etat de droit Etat de droit Etat de droit\par
\columnbreak
État de droit État de droit État de droit État de droit État
de droit État de droit État de droit\par
\end{multicols}
With struts: (careful to put a strut also on left first line.)
\begin{multicols}{2}
\strut Etat de droit Etat de droit Etat de droit Etat de droit Etat de droit
Etat de droit Etat de droit Etat de droit\par
\columnbreak
\strut État de droit État de droit État de droit État de droit État
de droit État de droit État de droit\par
\end{multicols}
\Large
Changed size.
\begin{multicols}{2}
\strut Etat de droit Etat de droit Etat de droit Etat de droit Etat de droit
Etat de droit Etat de droit Etat\par\hrule
\columnbreak
\strut État de droit État de droit État de droit \strut État de droit État
de droit État de droit État de droit\par\hrule
\end{multicols}
\sffamily
Other font.
\begin{multicols}{2}
\strut Etat de droit Etat de droit Etat de droit Etat de droit Etat de droit
Etat de droit Etat de droit Etat de droit\par\hrule
\columnbreak
\strut État de droit État de droit État de droit \strut État de droit État
de droit État de droit État de droit\par\hrule
\end{multicols}
\end{document}

Log (with \igor@fixstrutbox
containing only É
, and that was with an earlier version of the code):
(/usr/local/texlive/2015/texmf-dist/tex/latex/lm/t1lmr.fd
File: t1lmr.fd 2009/10/30 v1.6 Font defs for Latin Modern
)
IGOR: MODIFYING DEFAULT STRUTBOX on input line 30.
IGOR: old=10.14995pt, new=11.004pt
IGOR: MODIFYING DEFAULT STRUTBOX on input line 51.
IGOR: old=15.39993pt, new=15.68199pt
LaTeX Font Info: Try loading font information for T1+lmss on input line 62.
(/usr/local/texlive/2015/texmf-dist/tex/latex/lm/t1lmss.fd
File: t1lmss.fd 2009/10/30 v1.6 Font defs for Latin Modern
)
IGOR: MODIFYING DEFAULT STRUTBOX on input line 73.
IGOR: old=10.14995pt, new=11.004pt
Switch to sans serif
caused no adjustment, but if \igor@fixstrutbox
is set-up with \hbox{ĂÉÈÅ}
rather, one gets (again with earlier code, not re-compiled).
IGOR: MODIFYING DEFAULT STRUTBOX on input line 30.
IGOR: old=10.14995pt, new=11.004pt
IGOR: MODIFYING DEFAULT STRUTBOX on input line 51.
IGOR: old=15.39993pt, new=15.68199pt
LaTeX Font Info: Try loading font information for T1+lmss on input line 62.
(/usr/local/texlive/2015/texmf-dist/tex/latex/lm/t1lmss.fd
File: t1lmss.fd 2009/10/30 v1.6 Font defs for Latin Modern
)
IGOR: MODIFYING DEFAULT STRUTBOX on input line 62.
IGOR: old=15.68199pt, new=15.97498pt
IGOR: MODIFYING DEFAULT STRUTBOX on input line 73.
IGOR: old=10.14995pt, new=11.004pt
The same with only \hbox{Ă}
showing that this character is taller in sans serif than É
at least in \Large
font size.
I have edited the \igor@fixstrutbox
to always reset first the \strutbox
to the default LaTeX definition, because if not the decision to keep the \strutbox
or modify it would depend on the history of earlier font changes, as LaTeX calls only in certain circumstances \set@fontsize
which gives non \relax
meaning to \size@update
(executed by \selectfont
). I have not updated the image and logs above after that change.
$x_2$
so in some cases you may need a depth of more than 2.5 but so be it