%D \module
%D   [      file=s-fnt-23,
%D        version=2009.03.04,
%D          title=\CONTEXT\ Style File,
%D       subtitle=Tracing Feature Application (3),
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

% last_data was written wrong so it needs checking

\startluacode
    local last_data = nil
    local format = string.format
    function fonts.otf.show_shape(n)
        local tfmdata = fonts.identifiers[font.current()]
        last_data = tfmdata
        local charnum = tonumber(n)
        if not charnum then
            charnum = tfmdata.unicodes[n]
        end
        local c = tfmdata.characters[charnum]
        local d = tfmdata.descriptions[charnum]
        if d then
            local factor = (tfmdata.size/tfmdata.units)*((7200/7227)/65536)
            local llx, lly, urx, ury = unpack(d.boundingbox)
            llx, lly, urx, ury = llx*factor, lly*factor, urx*factor, ury*factor
            local width, italic = (d.width or 0)*factor, (d.italic or 0)*factor
            local top_accent, bot_accent = (d.top_accent or 0)*factor, (d.bot_accent or 0)*factor
            local anchors, math = d.anchors, d.math
            context.startMPcode()
            context("pickup pencircle scaled .25bp ; ")
            context('picture p ; p := image(draw textext.drt("\\gray\\char%s");); draw p ;',charnum)
            context('draw (%s,%s)--(%s,%s)--(%s,%s)--(%s,%s)--cycle withcolor green ;',llx,lly,urx,lly,urx,ury,llx,ury)
            context('draw (%s,%s)--(%s,%s) withcolor green ;',llx,0,urx,0)
            context('draw boundingbox p withcolor .2white withpen pencircle scaled .065bp ;')
            context("defaultscale := 0.05 ; ")
            -- inefficient but non critical
            local function slant_1(v,dx,dy,txt,xsign,ysign,loc,labloc)
                if #v > 0 then
                    local l = { }
                    for kk, vv in ipairs(v) do
                        local h, k = vv.height, vv.kern
                        if h and k then
                            l[#l+1] = format("((%s,%s) shifted (%s,%s))",xsign*k*factor,ysign*h*factor,dx,dy)
                        end
                    end
                    context("draw ((%s,%s) shifted (%s,%s))--%s dashed (evenly scaled .25) withcolor .5white;", xsign*v[1].kern*factor,lly,dx,dy,l[1])
                    context("draw laddered (%s) withcolor .5white ;",table.concat(l,".."))
                    context("draw ((%s,%s) shifted (%s,%s))--%s dashed (evenly scaled .25) withcolor .5white;", xsign*v[#v].kern*factor,ury,dx,dy,l[#l])
                    for k, v in ipairs(l) do
                        context("draw %s withcolor blue  withpen pencircle scaled 1bp;",v)
                    end
                end
            end
            local function slant_2(v,dx,dy,txt,xsign,ysign,loc,labloc)
                if #v > 0 then
                    local l = { }
                    for kk, vv in ipairs(v) do
                        local h, k = vv.height, vv.kern
                        if h and k then
                            l[#l+1] = format("((%s,%s) shifted (%s,%s))",xsign*k*factor,ysign*h*factor,dx,dy)
                        end
                    end
                    if loc == "top" then
                        context('label.%s("\\type{%s}",%s shifted (0,-1bp)) ;',loc,txt,l[#l])
                    else
                        context('label.%s("\\type{%s}",%s shifted (0,2bp)) ;',loc,txt,l[1])
                    end
                    for kk, vv in ipairs(v) do
                        local h, k = vv.height, vv.kern
                        if h and k then
                            context('label.top("(%s,%s)",%s shifted (0,-2bp));',k,h,l[kk])
                        end
                    end
                end
            end
            if math then
                local kerns = math.kerns
                if kerns then
                    for _, slant in ipairs { slant_1, slant_2 } do
                        for k,v in pairs(kerns) do
                            if k == "top_right" then
                                slant(v,width+italic,0,k,1,1,"top","ulft")
                            elseif k == "bottom_right" then
                                slant(v,width,0,k,1,1,"bot","lrt")
                            elseif k == "top_left" then
                                slant(v,0,0,k,-1,1,"top","ulft")
                            elseif k == "bottom_left" then
                                slant(v,0,0,k,-1,1,"bot","lrt")
                            end
                        end
                    end
                end
            end
            local function show(x,y,txt)
                local xx, yy = x*factor, y*factor
                context("draw (%s,%s) withcolor blue withpen pencircle scaled 1bp;",xx,yy)
                context('label.top("\\type{%s}",(%s,%s-2bp)) ;',txt,xx,yy)
                context('label.bot("(%s,%s)",(%s,%s+2bp)) ;',x,y,xx,yy)
            end
            if anchors then
                local a = anchors.baselig
                if a then
                    for k, v in pairs(a) do
                        for kk, vv in ipairs(v) do
                            show(vv[1],vv[2],k .. ":" .. kk)
                        end
                    end
                end
                local a = anchors.mark
                if a then
                    for k, v in pairs(a) do
                        show(v[1],v[2],k)
                    end
                end
                local a = anchors.basechar
                if a then
                    for k, v in pairs(a) do
                        show(v[1],v[2],k)
                    end
                end
                local ba = anchors.centry
                if a then
                    for k, v in pairs(a) do
                        show(v[1],v[2],k)
                    end
                end
                local a = anchors.cexit
                if a then
                    for k, v in pairs(a) do
                        show(v[1],v[2],k)
                    end
                end
            end
            if italic ~= 0 then
                context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue;',width,ury,width,ury)
                context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue;',width+italic,ury,width+italic,ury)
                context('draw (%s,%s-1bp)--(%s,%s-1bp) withcolor blue;',width,ury,width+italic,ury)
                context('label.lft("\\type{%s}",(%s+2bp,%s-1bp));',"italic",width,ury)
                context('label.rt("%s",(%s-2bp,%s-1bp));',d.italic,width+italic,ury)
            end
            if top_accent ~= 0 then
                context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',top_accent,ury,top_accent,ury)
                context('label.bot("\\type{%s}",(%s,%s+1bp));',"top_accent",top_accent,ury)
                context('label.top("%s",(%s,%s-1bp));',d.top_accent,top_accent,ury)
            end
            if bot_accent ~= 0 then
                context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',bot_accent,lly,bot_accent,lly)
                context('label.top("\\type{%s}",(%s,%s-1bp));',"bot_accent",top_accent,ury)
                context('label.bot("%s",(%s,%s+1bp));',d.bot_accent,bot_accent,lly)
            end
            context('draw origin withcolor red withpen pencircle scaled 1bp;')
            context("setbounds currentpicture to boundingbox currentpicture enlarged 1bp ;")
            context("currentpicture := currentpicture scaled 8 ;")
            context.stopMPcode()
        elseif c then
            local factor = (7200/7227)/65536
            context.startMPcode()
            context("pickup pencircle scaled .25bp ; ")
            context('picture p ; p := image(draw textext.drt("\\gray\\char%s");); draw p ;',charnum)
            context('draw boundingbox p withcolor .2white withpen pencircle scaled .065bp ;')
            context("defaultscale := 0.05 ; ")
            local italic, top_accent, bot_accent = (c.italic or 0)*factor, (c.top_accent or 0)*factor, (c.bot_accent or 0)*factor
            local width, height, depth = (c.width or 0)*factor, (c.height or 0)*factor, (c.depth or 0)*factor
            local ury = height
            if italic ~= 0 then
                context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue;',width,ury,width,ury)
                context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue;',width+italic,ury,width+italic,ury)
                context('draw (%s,%s-1bp)--(%s,%s-1bp) withcolor blue;',width,ury,width+italic,height)
                context('label.lft("\\type{%s}",(%s+2bp,%s-1bp));',"italic",width,height)
                context('label.rt("%6.3f bp",(%s-2bp,%s-1bp));',italic,width+italic,height)
            end
            if top_accent ~= 0 then
                context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',top_accent,ury,top_accent,height)
                context('label.bot("\\type{%s}",(%s,%s+1bp));',"top_accent",top_accent,height)
                context('label.top("%6.3f bp",(%s,%s-1bp));',top_accent,top_accent,height)
            end
            if bot_accent ~= 0 then
                context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',bot_accent,lly,bot_accent,height)
                context('label.top("\\type{%s}",(%s,%s-1bp));',"bot_accent",top_accent,height)
                context('label.bot("%6.3f bp",(%s,%s+1bp));',bot_accent,bot_accent,height)
            end
            context('draw origin withcolor red withpen pencircle scaled 1bp;')
            context("setbounds currentpicture to boundingbox currentpicture enlarged 1bp ;")
            context("currentpicture := currentpicture scaled 8 ;")
            context.stopMPcode()
        else
            context("no such shape: %s",n)
        end
    end
    function fonts.otf.show_all_shapes(start,stop)
        local tfmdata = fonts.identifiers[font.current()]
        last_data = tfmdata
        start, stop = start or "\\startTEXpage\\gobbleoneargument", stop or "\\stopTEXpage"
        local unicodes, indices, descriptions = tfmdata.unicodes, tfmdata.indices, tfmdata.descriptions
        for _, unicode in next, table.sortedkeys(descriptions) do
            local d = descriptions[unicode]
            local name = d.name
            context("%s{%s}%%",start,unicode)
            context("\\writestatus{glyph}{U+%04X -> %s}%%",unicode,name)
            fonts.otf.show_shape(unicode)
            context(stop)
        end
    end
    function fonts.otf.show_shape_field(unicode,name)
        local tfmdata = last_data or fonts.identifiers[font.current()]
        local d = tfmdata.descriptions[unicode]
        if d then
            if name == "unicode" then
                context("U+%04X",unicode)
            else
                d = d[name]
                if d then
                    context(d)
                end
            end
        end
    end
\stopluacode

\setupcolors
  [state=start]

\def\GetGlyphField#1#2%
  {\ctxlua{fonts.otf.show_shape_field(#1,"#2")}}

\def\StartShowGlyphShape#1%
  {\startTEXpage
   \nonknuthmode
   \def\GlyphUnicode{#1}}

\def\StopShowGlyphShape
  {\par
   \midaligned{\tttf\setstrut\strut\GetGlyphField\GlyphUnicode{unicode}: \GetGlyphField\GlyphUnicode{name}}%
   \stopTEXpage}

\def\ShowGlyphShape#1#2#3% name size glyph
  {\begingroup
   \definedfont[#1 at #2]%
   \obeyMPboxdepth
   \ctxlua{fonts.otf.show_shape("#3")}%
   \endgroup}

\def\ShowAllGlyphShapes#1#2% name size
  {\begingroup
   \nonknuthmode
   \definedfont[#1 at #2]%
   \ctxlua{fonts.otf.show_all_shapes("\\StartShowGlyphShape","\\StopShowGlyphShape")}%
   \endgroup}

\setupcolors
  [state=start]

\doifnotmode{demo}{\endinput}

\starttext

\startTEXpage \ShowGlyphShape{simplenaskhi}{100bp}{0x62A}       \stopTEXpage
\startTEXpage \ShowGlyphShape{simplenaskhi}{100bp}{0x2004}      \stopTEXpage
\startTEXpage \ShowGlyphShape{simplenaskhi}{100bp}{0xF0299}     \stopTEXpage
\startTEXpage \ShowGlyphShape{simplenaskhi}{100bp}{NameMe.1190} \stopTEXpage

\ShowAllGlyphShapes{simplenaskhi}{100bp}
% \ShowAllGlyphShapes{xits}{100bp}

\stoptext
