The problem is related with the sidebearings.
The following code in lualatex shows the effect, turning the switch \dropsidebearings
on and off. Courtesy of Marcel Krüger.
The references of the original Q&A are in the comments.
sidebearings and precision left/right alignment
Perfect alignment, LuaTex and sidebearings. Part II
A solution of the problem using xelatex is also shown in the first referenced question.
% !TeX TS-program = lualatex
\documentclass[11pt, a5paper]{article}
\usepackage[showframe]{geometry}
\RequirePackage{luacode}
\newcount\dropsidebearings
\begin{luacode*}
------------------------drop_sidebearing------------------------
--https://tex.stackexchange.com/questions/427068/sidebearings-and-precision-left-right-alignment?noredirect=1&lq=1
--In LuaTeX, you can use the post_linebreak_filter to intercept the broken lines and
-- add some offsets. The sidebearings can be extracted from rawdata saved by luaotfload.
-- After adding the offsets, the hboxes have to be repacked to determine the new glue settings.
---updated for 1.09
--https://tex.stackexchange.com/questions/470276/perfect-alignment-luatex-and-sidebearings-part-ii
------------------------drop_sidebearing------------------------
local function drop_sidebearing(head, groupcode)
if tex.count['dropsidebearings'] == 0 then
return true
end
for n in node.traverse_id(node.id'hlist', head) do
local char = node.has_glyph(n.head)
if char then
local f = font.getfont(char.font)
if f.shared then
local kern = node.new(node.id'kern')
kern.kern = - f.shared.rawdata.descriptions[char.char].boundingbox[1]*f.size/1000
n.head = node.insert_before(n.head, char, kern)
end
end
for ch in node.traverse_id(node.id'glyph', n.head) do
char = ch
end
if char then
local f = font.getfont(char.font)
if f.shared then
local desc = f.shared.rawdata.descriptions[char.char]
local kern = node.new(node.id'kern')
kern.kern = - (desc.width-desc.boundingbox[3])*f.size/1000
node.insert_after(n.head, char, kern)
end
end
local new_list = node.hpack(n.head, n.width, 'exactly')
new_list.head = nil
n.glue_order = new_list.glue_order
n.glue_set = new_list.glue_set
n.glue_sign = new_list.glue_sign
node.free(new_list)
end
return true
end
luatexbase.add_to_callback('post_linebreak_filter', drop_sidebearing, 'Drop sidebearings after linebreaking')
\end{luacode*}
\begin{document}
\dropsidebearings=1
\noindent dropsidebearing =1
\noindent\textbf{.}
\noindent \textbf{Some example text.}
\dropsidebearings=0
\noindent dropsidebearing =0
\noindent\textbf{.}
\noindent \textbf{Some example text.}
\end{document}
\makebox[0.5\width]{\textbf{.}}
achieve what you want? You can increase the 0.5 factor to get it where you desire.