Bounding box for each letter
A LuaTeX solution. Should work in all situations that I am aware of:
\documentclass{article}
\usepackage{luacode,luatexbase}
\begin{document}
\begin{luacode*}
local GLYPH_ID = node.id("glyph")
local number_sp_in_a_pdf_point = 65782
function math.round(num)
return math.floor(num * 1000 + 0.5) / 1000
end
-- width/height/depth of a glyph and the whatsit node
local wd,ht,dp,w
-- head is a linked list (next/prev entries pointing to the next node)
function showcharbox(head)
while head do
if head.id == 0 or head.id == 1 then
-- a hbox/vbox
showcharbox(head.list)
elseif head.id == GLYPH_ID then
-- Create a pdf_literal node to draw a box with the dimensions
-- of the glyph
w = node.new("whatsit","pdf_literal")
wd = math.round(head.width / number_sp_in_a_pdf_point)
ht = math.round(head.height / number_sp_in_a_pdf_point)
dp = math.round(head.depth / number_sp_in_a_pdf_point)
-- draw a dashed line if depth not zero
if dp ~= 0 then
w.data = string.format("q 0.2 G 0.1 w 0 %g %g %g re S f [0.2] 0 d 0 0 m %g 0 l S Q",-dp,-wd,dp + ht,-wd)
else
w.data = string.format("q 0.2 G 0.1 w 0 %g %g %g re S f Q",-dp,-wd,dp + ht,-wd)
end
-- insert this new node after the current glyph and move pointer (head) to
-- the new whatsit node
w.next = head.next
w.prev = head
head.next = w
head = w
end
head = head.next
end
return true
end
luatexbase.add_to_callback("post_linebreak_filter",showcharbox,"showcharbox")
\end{luacode*}
A \emph{wonderful} serenity has taken {\large possession} of my entire soul, like these
\textsl{sweet}
\textbf{mornings} of spring which I enjoy with my whole heart. I am alone, and feel the
charm of existence in this spot, \textbf{which} was created for the bliss of souls like
mine. I am so happy, my dear friend, so absorbed in the exquisite sense of
mere tranquil existence, that I neglect my talents. I should be incapable of
drawing a single stroke at the present moment; and yet I feel that I never was
a greater artist than now.
\end{document}
which yields:
(detail)
Bonus: it draws the base line if the depth of the glyph is not 0.
Here is a solution that replaces the glyphs by black rectangles (rules):
\documentclass{article}
\usepackage{luacode,luatexbase,microtype}
\begin{document}
\begin{luacode*}
local GLYPH_ID = node.id("glyph")
-- head is a linked list (next/prev entries pointing to the next node)
-- parent it the surrounding h/vbox
function showcharbox(head,parent)
while head do
if head.id == 0 or head.id == 1 then
-- a hbox/vbox
showcharbox(head.list,head)
elseif head.id == GLYPH_ID then
r = node.new("rule")
r.width = head.width
r.height = head.height
r.depth = head.depth
-- replace the glyph by
-- the rule by changing the
-- pointers of the next/prev
-- entries of the rule node
if not head.prev then
-- first glyph in a list
parent.list = r
else
head.prev.next = r
end
if head.next then
head.next.prev = r
end
r.prev = head.prev
r.next = head.next
-- now the glyph points to
-- nowhere and we should remove
-- it from the memory
node.free(head)
head = r
end
head = head.next
end
return true
end
luatexbase.add_to_callback("post_linebreak_filter",showcharbox,"showcharbox")
\end{luacode*}
\hsize6cm
A wonderful serenity has taken possession of my entire soul, like these sweet
mornings of spring which I enjoy with my whole heart. I am alone, and feel the
charm of existence in this spot, which was created for the bliss of souls like
mine. I am so happy, my dear friend, so absorbed in the exquisite sense of
mere tranquil existence, that I neglect my talents. I should be incapable of
drawing a single stroke at the present moment; and yet I feel that I never was
a greater artist than now.
\end{document}
Here is a solution that respects kerning (but not ligatures):
\documentclass{article}
\usepackage{xcolor}
\makeatletter
\def\showboxes#1{%
\begingroup\fboxrule=.1pt \fboxsep=-\fboxrule
\@showboxes#1\@showboxes\@empty
\endgroup}
\def\@showboxes#1#2{%
\ifx#2\@showboxes
\fbox{\color{gray}#1}\expandafter\@gobble
\else
\setbox0=\hbox{#1\kern0pt#2}\setbox2=\hbox{#1#2}%
\dimen0=\wd0 \advance\dimen0 -\wd2 % \dimen0 contains the kern between the two chars
\fbox{\color{gray}#1}\kern-\dimen0
\expandafter\@showboxes
\fi#2}
\begin{document}
\showboxes{AVov}
\end{document}
For doing more words just add
\usepackage{xparse}
\def\showboxesaux#1{\showboxes{#1} }
\NewDocumentCommand\Showboxes{>{\SplitList{ }}m}
{\ProcessList{#1}\showboxesaux\unskip}
and use
\Showboxes{The quick brown fox jumped over the lazy dog.}
but hyphenation won't be taken care of.
Probably the best is the code from the TeXbook and this I will leave up to you. Another alternative is to study the code from the soul
package and use the scanners provided.
Here is an adaptation:
\documentclass{article}
\usepackage{soul,graphicx,xcolor}
\fboxrule=0.1pt
\fboxsep=-\fboxrule
\begin{document}
\makeatletter
\def\SOUL@soeverytoken{%
\fbox{\color{gray}\the\SOUL@token}}
\makeatother
\scalebox{7}{\color{purple}\so{ailbcdefgh}}
\end{document}
Change the gray color to white to have the letters disappear.
You will need to change the \fbox
to basic TeX primitives, if you need to compensate for the 0.1pt rule or use the suggestion of egreg in the comments, which I have incorporated.