# Font and spacing issue in expl3 macro using ooalign

So I was looking at underline omitting the descenders and wanted a version where I could control the underline thickness. Using the basic idea from the answers there, I came up with a method that has a couple of issues that I don't understand.

1. If I underline a single word the spacing seems to be fine, however if I underline a longer sentence it seems that the text is getting shifted to the right (ie. the underline ends before the sentence does)
2. Things become a mess if I change the font (uncomment \usepackage{tgheros})
3. Things become an even larger mess if I use \usepackage[T1]{fontenc} when I get pixelated text.

Can anyone point out where I've gone wrong? I would include the output but I'm not sure how to enlarge it enough to show the problem clearly without it looking terrible.

\documentclass{article}
%\usepackage{tgheros}
%\usepackage[T1]{fontenc}
\renewcommand*\familydefault{\sfdefault}
\usepackage{xcolor}
\usepackage{xparse}
\ExplSyntaxOn

\box_new:N \text_box
\fp_new:N \l_tmpa_fp

%1st optional is width of gap, 2nd is thickness of rule, 3rd is vertical height of rule
\NewDocumentCommand \gapul {O{10} D<>{.05} D(){.2} m}
{
\tl_gset:Nn \g_tmpa_tl {#4}
\hbox_set:Nn \text_box {#4}
{
\ooalign{
\rule[-#3ex]{\box_wd:N \text_box}{#2ex}\cr
\prg_stepwise_function:nnnN {1}{1}{#1}\write_white_text:n
\box_use:N \text_box\cr}
}
}

\cs_new:Npn \write_white_text:n #1
{
\fp_set:Nn \l_tmpa_fp {.05}
\fp_mul:Nn \l_tmpa_fp {#1}
\hspace{\fp_to_dim:N \l_tmpa_fp}\textcolor{white}{\g_tmpa_tl}\cr
\hspace{-\fp_to_dim:N \l_tmpa_fp}\textcolor{white}{\g_tmpa_tl}\cr
}
\ExplSyntaxOff

\begin{document}
\gapul{japan}
\gapul{japan giddy quid japan}
\end{document}


Edit: Can anyone explain what is happening when write_white_text is changed to the following:

\cs_new:Npn \write_white_text:n #1
{
\fp_set:Nn \l_tmpa_fp {.05}
\fp_mul:Nn \l_tmpa_fp {#1}
\hspace{\fp_to_dim:N \l_tmpa_fp}\textcolor{red}{\g_tmpa_tl}\cr
%\hspace{-\fp_to_dim:N \l_tmpa_fp}\textcolor{white}{\g_tmpa_tl}\cr
}


Although the \hspace is positive (??) the words at the start are getting shifted in both a positive and negative direction and the shift in the negative direction diminishes across words. Boxing the text causes the shift to be consistent across words.

-
Feel free to suggest an improvement or alternate method of achieving the thickness requirement, this is just my (poor) attempt. –  Scott H. Jun 13 '12 at 4:23

You have to do the cancellation in one step.

\documentclass{article}
%\usepackage{tgheros}
%\usepackage[T1]{fontenc}
\renewcommand*\familydefault{\sfdefault}
\usepackage{xcolor}
\usepackage{xparse}
\ExplSyntaxOn

\box_new:N \l_gapul_text_box
\fp_new:N \l_gapul_gap_fp
\tl_new:N \l_gapul_text_tl
%1st optional is width of gap, 2nd is thickness of rule, 3rd is vertical height of rule
\NewDocumentCommand \gapul {O{10} D<>{.05} D(){.2} m}
{
\gapul_make:nnnn { #1 } { #2 } { #3 } { #4 }
}

\cs_new_protected:Npn \gapul_make:nnnn #1 #2 #3 #4
{
\tl_set:Nn \l_gapul_text_tl {#4}
\hbox_set:Nn \l_gapul_text_box {#4}
\group_begin:
\fp_set:Nn \l_gapul_gap_fp {.05}
\fp_mul:Nn \l_gapul_gap_fp {#1}
\leavevmode\vphantom{\l_gapul_text_tl} % so TeX knows the real height and depth
\ooalign{
\rule[-#3ex]{\box_wd:N \l_gapul_text_box}{#2ex}\cr
\gapul_cancel:nn { + } { - }
\hspace{-\box_wd:N \l_gapul_text_box}
\gapul_cancel:nn { - } { + }
\cr
\box_use:N \l_gapul_text_box\cr
}
\group_end:
}
\cs_new_protected:Npn \gapul_cancel:nn #1 #2
{
\hspace{#1\fp_to_dim:N \l_gapul_gap_fp}
\textcolor{white}{\l_gapul_text_tl}
\hspace{#2\fp_to_dim:N \l_gapul_gap_fp}
}
\ExplSyntaxOff

\begin{document}
\gapul{japan}

\gapul{j} \gapul{n}

\gapul{abcde}

\gapul{japan giddy quid japan}
\end{document}


The apparent overshoot is caused by what TeX thinks about the bounding box of the characters.

I tried also to fix the usage of LaTeX3 names.

-
Hi egreg, the reason for the \prg_stepwise in my attempt was because in the default font (comment out \renewcommand*\familydefault{\sfdefault}) the y has a very narrow descender and rather than producing a continuous space around the descender, I was getting gaps to either side of it. That still occurs here, although I suppose that I shouldn't want a gap larger than the width of the narrowest descender anyway. If your solution were to be modified to take this into account, where should that iteration take place? I tried in the aux function, but wasn't able to make it work. –  Scott H. Jun 14 '12 at 18:47
@ScottH. I tried in several ways, but it seems that printing the white text all in the same line is the only way out. –  egreg Jun 14 '12 at 19:27
Thanks for the solution, I guess going about it in this way was bound to lead to some problems. I'll wait a day or so to see if there's any other input and otherwise accept this as the definitive answer. –  Scott H. Jun 14 '12 at 21:37
@ScottH. To tell you the complete truth, I would never use something so awful. ;-) –  egreg Jun 14 '12 at 21:42