\documentclass{article}
\usepackage{fontspec}
\usepackage{tikz}
\usepackage{luacode}
\begin{luacode*}
local concat = table.concat
local function f_moveto(...)
return string.format("\\pgfsyssoftpath@movetotoken{
end
local function f_lineto(...)
return string.format("\\pgfsyssoftpath@linetotoken{
end
local function f_curveto(...)
return string.format(
"\\pgfsyssoftpath@curvetosupportatoken{
"\\pgfsyssoftpath@curvetosupportbtoken{
"\\pgfsyssoftpath@curvetotoken{
end
local s_cycle = "\\pgfsyssoftpath@closepath"
-- from font-mps.lua
local function glyph_to_paths(d,xfactor,yfactor)
local sequence = d.sequence
local segments = d.segments
local list = { }
local path = { } -- recycled
local size = 0
local xfactor = xfactor or 1
local yfactor = yfactor or xfactor
if sequence then
local i = 1
local n = #sequence
while i < n do
local operator = sequence[i]
if operator == "m" then -- "moveto"
if size > 0 then
size = size + 1
path[size] = s_cycle
list[#list+1] = concat(path,"",1,size)
size = 1
else
size = size + 1
end
path[size] = f_moveto(xfactor*sequence[i+1],yfactor*sequence[i+2])
i = i + 3
elseif operator == "l" then -- "lineto"
size = size + 1
path[size] = f_lineto(xfactor*sequence[i+1],yfactor*sequence[i+2])
i = i + 3
elseif operator == "c" then -- "curveto"
size = size + 1
path[size] = f_curveto(xfactor*sequence[i+1],yfactor*sequence[i+2],xfactor*sequence[i+3],yfactor*sequence[i+4],xfactor*sequence[i+5],yfactor*sequence[i+6])
i = i + 7
elseif operator =="q" then -- "quadraticto"
size = size + 1
-- first is always a moveto
local l_x = xfactor*sequence[i-2]
local l_y = yfactor*sequence[i-1]
local m_x = xfactor*sequence[i+1]
local m_y = yfactor*sequence[i+2]
local r_x = xfactor*sequence[i+3]
local r_y = yfactor*sequence[i+4]
path[size] = f_curveto (
l_x + 2/3 * (m_x-l_x),
l_y + 2/3 * (m_y-l_y),
r_x + 2/3 * (m_x-r_x),
r_y + 2/3 * (m_y-r_y),
r_x, r_y
)
i = i + 5
else
-- weird
i = i + 1
end
end
elseif segments then
for i=1,#segments do
local segment = segments[i]
local operator = segment[#segment]
if operator == "m" then -- "moveto"
if size > 0 then
size = size + 1
path[size] = s_cycle
list[#list+1] = concat(path,"",1,size)
size = 1
else
size = size + 1
end
path[size] = f_moveto(xfactor*segment[1],yfactor*segment[2])
elseif operator == "l" then -- "lineto"
size = size + 1
path[size] = f_lineto(xfactor*segment[1],yfactor*segment[2])
elseif operator == "c" then -- "curveto"
size = size + 1
path[size] = f_curveto(xfactor*segment[1],yfactor*segment[2],xfactor*segment[3],yfactor*segment[4],xfactor*segment[5],yfactor*segment[6])
elseif operator =="q" then -- "quadraticto"
size = size + 1
-- first is always a moveto
local prev = segments[i-1]
local l_x = xfactor*prev[#prev-2]
local l_y = yfactor*prev[#prev-1]
local m_x = xfactor*segment[1]
local m_y = yfactor*segment[2]
local r_x = xfactor*segment[3]
local r_y = yfactor*segment[4]
path[size] = f_curveto (
l_x + 2/3 * (m_x-l_x),
l_y + 2/3 * (m_y-l_y),
r_x + 2/3 * (m_x-r_x),
r_y + 2/3 * (m_y-r_y),
r_x, r_y
)
else
-- weird
end
end
else
return
end
if size > 0 then
size = size + 1
path[size] = s_cycle
list[#list+1] = concat(path,"",1,size)
end
return list
end
-- from meta-imp-outlines.mkiv
-- That's a simple reimplemetation of ConTeXt's \showshape macro
function outlinepaths(character)
local fontid = font.current()
local shapedata = fonts.hashes.shapes[fontid] -- by index
local chardata = fonts.hashes.characters[fontid] -- by unicode
local shapeglyphs = shapedata.glyphs or { }
character = utf.byte(character)
local c = chardata[character]
if c then
if not c.index then
return {}
end
local glyph = shapeglyphs[c.index]
if glyph and (glyph.segments or glyph.sequence) then
local units = shapedata.units or 1000
local factor = 100/units
local paths = glyph_to_paths(glyph,factor)
return paths
end
end
end
\end{luacode*}
\begin{document}
\makeatletter
\directlua{
for i, path in ipairs(outlinepaths("A")) do
token.set_macro("path" .. string.char(string.byte("A") + i - 1), path)
end
}
\makeatother
\begin{tikzpicture}
\draw[use path=\pathA];
\draw[use path=\pathB];
\end{tikzpicture}
\end{document}