# How to scale a line of text to an exact width

I'd like to scale some lines of text so that they line up perfect on both the left and thee right. Using resizebox* I have something that almost works, but there's a tiny bit of whitespace at the edges. The larger the font size, the larger the whitespace.

\documentclass{article}
\usepackage{graphicx}
\setkeys{Gin}{keepaspectratio} % to maintain aspect ratio of content inside resizebox
\setlength{\fboxsep}{0cm} % So that we can see the exact box around some text

\begin{document}%
\setlength{\parindent}{0cm}
\fbox{\resizebox*{12cm}{2cm}{OOOOOOOOOOOOOOOOOOOOOO}}\\%
\fbox{\resizebox*{12cm}{2cm}{OOOOOOOOOOOOOO}}\\%
\fbox{\resizebox*{12cm}{2cm}{OOOOOO}}\\%
\end{document}


It produces output like this:

• So, basically, do you want to lop off the left-hand sidebearing of the first letter on the left and the right-hand sidebearing of the last letter of the right of each box? – Mico Apr 19 '17 at 13:16
• to tex, each character is a rectangle, it has no information about which parts of that rectangle are black and which are white, so in your image there is no space between the O, the gaps are just "part of the O" (the side bearings) and similarly the gaps at the ends. So you can add negative space by eye to negate the sidebearings at each end, but tex has no information to allow it to do that automatically. – David Carlisle Apr 19 '17 at 14:02
• – John Kormylo Apr 19 '17 at 15:30
• In some cases, using the \linebreak command helps. You can also use the \adjustwidth environment. These are not necessarily better than your own technique with \resizebox but they are a different way of doing it. – user103221 Apr 19 '17 at 18:26

If you are willing to use XeLaTeX, you can do it without guessing.

\documentclass{article}
\usepackage{fontspec}
\usepackage{graphicx}

\newcommand{\removeleft}[1]{%
\leavevmode\kern-\XeTeXglyphbounds1 \the\XeTeXcharglyph#1\relax
#1%
}
\newcommand{\removeright}[1]{%
#1%
\kern-\XeTeXglyphbounds3 \the\XeTeXcharglyph#1\relax
}

\setlength{\parindent}{0pt}
\setlength{\fboxsep}{0pt}

\begin{document}

\fbox{\resizebox{12cm}{!}{\removeleft{O}OOOOOOOOOOOOOOOOOOOO\removeright{O}}}

\fbox{\resizebox{12cm}{!}{\removeleft{O}OOOOOOOOOOOO\removeright{O}}}

\fbox{\resizebox{12cm}{!}{\removeleft{O}OOOO\removeright{O}}}

\end{document}


The trick is explained in the documentation for XeTeX. First we get the glyph number of the first character, then measure its left sidebearing. Similarly for the last.

With some expl3 trickery, we can avoid separating the first and last letter:

\documentclass{article}
\usepackage{fontspec}
\usepackage{graphicx}

\newcommand{\remove}[2]{%
\leavevmode\kern-\XeTeXglyphbounds#2\space\the\XeTeXcharglyph#1\relax
}

\ExplSyntaxOn
\cs_set_eq:NN \tobyone_remove_sb:nn \remove
\cs_generate_variant:Nn \tobyone_remove_sb:nn { fn }

\NewDocumentCommand{\removesidebearings}{m}
{
\tobyone_remove_sb:fn { \tl_head:n { #1 } } { 1 }% left
#1
\tobyone_remove_sb:fn { \tl_head:f { \tl_reverse:n { #1 } } } { 3 }
}
\ExplSyntaxOff

\setlength{\parindent}{0pt}
\setlength{\fboxsep}{0pt}

\begin{document}

\fbox{\resizebox{12cm}{!}{\removesidebearings{OOOOOOOOOOOOOOOOOOOOOO}}}

\fbox{\resizebox{12cm}{!}{\removesidebearings{OOOOOOOOOOOOOO}}}

\fbox{\resizebox{12cm}{!}{\removesidebearings{OOOOOO}}}

\end{document}


If you also need TeX's special characters, add definitions as follows and use the “symbolic names”.

\documentclass{article}
\usepackage{fontspec}
\usepackage{graphicx}

\newcommand{\remove}[2]{%
\leavevmode\kern-\XeTeXglyphbounds#2\space\the\XeTeXcharglyph#1\relax
}

\ExplSyntaxOn
\cs_set_eq:NN \tobyone_remove_sb:nn \remove
\cs_generate_variant:Nn \tobyone_remove_sb:nn { fn }

\NewDocumentCommand{\removesidebearings}{m}
{
\tobyone_remove_sb:fn { \tl_head:n { #1 } } { 1 }% left
#1
\tobyone_remove_sb:fn { \tl_head:f { \tl_reverse:n { #1 } } } { 3 }
}

\cs_set_eq:NN \ampersandchar  \c_ampersand_str
\cs_set_eq:NN \backslashchar  \c_backslash_str
\cs_set_eq:NN \leftbracechar  \c_left_brace_str
\cs_set_eq:NN \rightbracechar \c_right_brace_str
\cs_set_eq:NN \circumflexchar \c_circumflex_str
\cs_set_eq:NN \dollarchar     \c_dollar_str
\cs_set_eq:NN \hashchar       \c_hash_str
\cs_set_eq:NN \percentchar    \c_percent_str
\cs_set_eq:NN \tildechar      \c_tilde_str
\cs_set_eq:NN \underscorechar \c_underscore_str
\ExplSyntaxOff

\setlength{\parindent}{0pt}
\setlength{\fboxsep}{0pt}

\begin{document}

\fbox{\resizebox{12cm}{!}{\removesidebearings{\dollarchar abc\rightbracechar}}}

\fbox{\resizebox{12cm}{!}{\dollarchar abc\rightbracechar}}

\end{document}


• Works great thank you! For future readers: the graphicx package isn't necessary, it's just there because I accidentally included it in my example code in my question. – toby-one Apr 20 '17 at 18:53
• When certain characters are at the beginning or end of a line I get an error "Improper alphabetic constant". The characters that cause problems are $, ^, _, ~, {, }, \, generated using \$, \^{}, \_, \~{}, {, }, \textbackslash{} respectively. Any idea how to make \removesidebearings with these characters, or else skip at least skip them and not cause an error? – toby-one May 4 '17 at 11:07
• @toby-one \textbackslash is not a character, but the instructions for printing it. I added a workaround. – egreg May 4 '17 at 11:34
• When I compile I get an error: "Undefined control sequence ...bearings{\dollarchar abc\rightbracechar}}}". Full log file here: textuploader.com/d9smq – toby-one May 8 '17 at 8:57
• @toby-one Update your TeX distribution. You have an older version of expl3. – egreg May 8 '17 at 9:00

This works, but it's based on trial and error (no clean solution):

\documentclass{article}
\usepackage{graphicx}
\setkeys{Gin}{keepaspectratio} % to maintain aspect ratio of content inside resizebox
\setlength{\fboxsep}{0cm} % So that we can see the exact box around some text

\newlength\mycor
\mycor=-0.555428pt

\begin{document}%
\setlength{\parindent}{0cm}
\fbox{\resizebox*{12cm}{2cm}{\hspace*{\mycor}OOOOOOOOOOOOOOOOOOOOOO}\hspace*{\mycor}}\\%
\fbox{\resizebox*{12cm}{2cm}{\hspace*{\mycor}OOOOOOOOOOOOOO\hspace*{\mycor}}}\\%
\fbox{\resizebox*{12cm}{2cm}{\hspace*{\mycor}OOOOOO\hspace*{\mycor}}}\\%
\end{document}