<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">It does not seem to work for all character combinations.<div class="">e.g. B&T works, C&T works, C&M works, but N&T does not work.</div><div class="">not N&M</div><div class="">Why would that be?</div><div class="">Thanks</div><div class="">.Floris</div><div class=""><br class=""></div><div class=""><img apple-inline="yes" id="BC6E92AA-D423-4E66-873D-D6942D677A56" height="248" width="240" apple-width="yes" apple-height="yes" src="cid:2B98A095-728B-4374-B2F1-7448E04C41B5@fritz.box" class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""><blockquote type="cite" class="">On 22 Sep 2018, at 11:27, Hans Hagen <<a href="mailto:j.hagen@xs4all.nl" class="">j.hagen@xs4all.nl</a>> wrote:<br class=""><br class="">On 9/22/2018 10:35 AM, Henri Menke wrote:<br class=""><blockquote type="cite" class="">Dear list,<br class="">Challanged by a very old TeX.SX question<br class=""><a href="https://tex.stackexchange.com/questions/180510" class="">https://tex.stackexchange.com/questions/180510</a><br class="">I wanted to calculate all the intersection points between two<br class="">characters.  Therefore I ripped off the \showshape macro to load the<br class="">outlines from the font and convert them to MetaPost paths.  Then I try<br class="">to find all intersections by cutting the path.<br class="">It somewhat works but for some reason, in the MWE below two intersection<br class="">points are missing.  I also have the feeling that my implementation is<br class="">extremely inefficient.  I would very much appreciate some hints by the<br class="">MetaPost experts!<br class="">Cheers, Henri<br class="">---<br class="">\startluacode<br class="">-- That's a simple reimplemetation of the showshape macro<br class="">function outlinepaths(character)<br class="">    local fontid      = font.current()<br class="">    local shapedata   = fonts.hashes.shapes[fontid] -- by index<br class="">    local chardata    = fonts.hashes.characters[fontid] -- by unicode<br class="">    local shapeglyphs = shapedata.glyphs or { }<br class="">    character = utf.byte(character)<br class="">    local c = chardata[character]<br class="">    if c then<br class="">        if not c.index then<br class="">            return {}<br class="">        end<br class="">        local glyph = shapeglyphs[c.index]<br class="">        if glyph and (glyph.segments or glyph.sequence) then<br class="">            local units  = shapedata.units or 1000<br class="">            local factor = 100/units<br class="">            local paths  = fonts.metapost.paths(glyph,factor)<br class="">            return paths<br class="">        end<br class="">    end<br class="">end<br class="">\stopluacode<br class="">\def\mpdefineoutlines#1#2{\ctxlua{<br class="">    local char = "\luaescapestring{#1}"<br class="">    local outlines = outlinepaths("#2")<br class="">    local len = \letterhash outlines<br class="">    tex.print("path " .. char .. "[];")<br class="">    tex.print(char .. "n := " .. len .. ";")<br class="">    for i, path in ipairs(outlines) do<br class="">        tex.print(char .. "[" .. i .. "] := " .. path .. ";")<br class="">    end<br class="">  }}<br class="">\starttext<br class="">\startMPpage<br class="">pair shift; shift := (1cm,-1cm);<br class="">numeric angle; angle := 5;<br class="">\mpdefineoutlines{B}{B}<br class="">\mpdefineoutlines{T}{T}<br class="">nofill B2;<br class="">nofill B3;<br class="">eofill B1 withcolor .5[blue,white];<br class="">fill T1 shifted (shift) rotated (angle) withcolor .5[red,white];<br class="">path r;<br class="">numeric n; n := 0;<br class="">for i = 1 upto Bn:<br class="">    for j = 1 upto Tn:<br class="">        r := B[i];<br class="">        forever:<br class="">            pair q;<br class="">            r := r cutbefore (T[j] shifted (shift) rotated (angle));<br class="">            exitif length cuttings = 0;<br class="">            r := subpath(epsilon, length r) of r;<br class="">            q = point 0 of r;<br class="">            n := n + 1;<br class="">            dotlabel.urt(textext("\tfx" & decimal n), q);<br class="">        endfor;<br class="">    endfor ;<br class="">endfor ;<br class="">\stopMPpage<br class="">\stoptext<br class=""></blockquote><br class="">You migh find more when you go top double mode .. anyway, these intersection calculations are not that accurate so you normally need to apply some overkill.<br class=""><br class="">- a bit cleaned up outlinepath function<br class="">- use document namespace<br class="">- add helper for defineoutline<br class="">- do 4 runs over the shapes (probably too many now)<br class="">- more neutral fill code<br class=""><br class="">It makes a nice example for the metafun (although then I'd do it slightly different). We need some rounding becaus eotherwise you get similar points (you can add a message(q) someplace).<br class=""><br class="">\startluacode<br class=""><br class="">function document.outlinepaths(character)<br class="">   local chardata  = fonts.hashes.characters[true] -- by unicode<br class="">   local shapedata = fonts.hashes.shapes[true] -- by index<br class="">   local c         = chardata[character]<br class="">   if c and c.index and shapedata then<br class="">       local shapeglyphs = shapedata.glyphs or { }<br class="">       local glyph       = shapeglyphs[c.index]<br class="">       if glyph and (glyph.segments or glyph.sequence) then<br class="">           local units  = shapedata.units or 1000<br class="">           local factor = 100/units<br class="">           return fonts.metapost.paths(glyph,factor)<br class="">       end<br class="">   end<br class="">   return { }<br class="">end<br class=""><br class="">function document.defineoutline(char,target)<br class="">   local outlines = document.outlinepaths(char)<br class="">   local nofpaths = #outlines<br class="">   context("path %s[] ;",target)<br class="">   context("numeric %sn ; %sn := %s ;",target,target,nofpaths)<br class="">   for i=1,nofpaths do<br class="">       context("%s[%i] := %s ; ",target,i,outlines[i])<br class="">   end<br class="">end<br class="">\stopluacode<br class=""><br class="">\def\mpdefineoutlines#1#2{\ctxlua{document.defineoutline(\number`#1,"#2")}}<br class=""><br class="">\starttext<br class=""><br class="">\startMPpage<br class="">pair shift ; shift := (1cm,-1cm);<br class="">numeric angle ; angle := 5;<br class=""><br class="">\mpdefineoutlines{B}{B}<br class="">\mpdefineoutlines{T}{T}<br class=""><br class="">for i=1 upto Bn - 1 : nofill B[i] ; endfor ;<br class="">eofill B[Bn] withcolor .5[blue,white] ;<br class=""><br class="">for i=1 upto Tn :<br class="">   T[i] := T[i] shifted shift rotated angle ;<br class="">endfor ;<br class=""><br class="">for i=1 upto Tn - 1 : nofill T[i] ; endfor ;<br class="">eofill T[Tn] withcolor .5[red,white] ;<br class=""><br class="">pair found[] ;<br class="">boolean isnew ;<br class="">numeric n ; n := 0 ;<br class="">pair rq ;<br class=""><br class="">def GoForIt(expr how) =<br class="">   path r ;<br class="">   for i = 1 upto Bn :<br class="">       for j = 1 upto Tn :<br class="">           r := B[i] ;<br class="">           forever:<br class="">               pair q ;<br class="">               if how = 1 :<br class="">                   r := r cutbefore T[j] ;<br class="">               elseif how = 2 :<br class="">                   r := r cutbefore reverse T[j] ;<br class="">               elseif how = 3 :<br class="">                   r := reverse r cutbefore T[j] ;<br class="">               else :<br class="">                   r := reverse r cutbefore reverse T[j] ;<br class="">               fi ;<br class="">               exitif length cuttings = 0 ;<br class="">               r := subpath(epsilon, length r) of r ;<br class="">               q = point 0 of r ;<br class="">               isnew := true ;<br class="">               rq := round(q);<br class="">               for f=1 upto n :<br class="">                   if found[f] = rq :<br class="">                       isnew := false ;<br class="">                       exitif true ;<br class="">                   fi ;<br class="">               endfor ;<br class="">               if isnew :<br class="">                   n := n + 1 ;<br class="">                   drawdot q withpen pencircle scaled 4 ;<br class="">                   draw textext("\strut\ttbf " & decimal n) ysized 3 shifted q withcolor white ;<br class="">                   found[n] := rq ;<br class="">               fi ;<br class="">           endfor;<br class="">       endfor ;<br class="">   endfor ;<br class="">enddef ;<br class=""><br class="">for i=1 upto 4 : GoForIt(i) ; endfor ;<br class=""><br class="">\stopMPpage<br class=""><br class="">\stoptext<br class=""><br class=""><br class=""><br class=""><br class="">-- <br class=""><br class="">-----------------------------------------------------------------<br class="">                                         Hans Hagen | PRAGMA ADE<br class="">             Ridderstraat 27 | 8061 GH Hasselt | The Netherlands<br class="">      tel: 038 477 53 69 | <a href="http://www.pragma-ade.nl" class="">www.pragma-ade.nl</a> | <a href="http://www.pragma-pod.nl" class="">www.pragma-pod.nl</a><br class="">-----------------------------------------------------------------<br class="">___________________________________________________________________________________<br class="">If your question is of interest to others as well, please add an entry to the Wiki!<br class=""><br class="">maillist : <a href="mailto:ntg-context@ntg.nl" class="">ntg-context@ntg.nl</a> / <a href="http://www.ntg.nl/mailman/listinfo/ntg-context" class="">http://www.ntg.nl/mailman/listinfo/ntg-context</a><br class="">webpage  : <a href="http://www.pragma-ade.nl" class="">http://www.pragma-ade.nl</a> / <a href="http://context.aanhet.net" class="">http://context.aanhet.net</a><br class="">archive  : <a href="https://bitbucket.org/phg/context-mirror/commits/" class="">https://bitbucket.org/phg/context-mirror/commits/</a><br class="">wiki     : <a href="http://contextgarden.net" class="">http://contextgarden.net</a><br class="">___________________________________________________________________________________<br class=""></blockquote><br class=""></div></body></html>