diff options
17 files changed, 1035 insertions, 188 deletions
diff --git a/context/data/scite/context/lexers/data/scite-context-data-metafun.lua b/context/data/scite/context/lexers/data/scite-context-data-metafun.lua index b8aa47b38..39bd1e22b 100644 --- a/context/data/scite/context/lexers/data/scite-context-data-metafun.lua +++ b/context/data/scite/context/lexers/data/scite-context-data-metafun.lua @@ -1,4 +1,4 @@ return { - ["commands"]={ "transparency", "sqr", "log", "ln", "exp", "inv", "pow", "pi", "radian", "tand", "cotd", "sin", "cos", "tan", "cot", "atan", "asin", "acos", "invsin", "invcos", "invtan", "acosh", "asinh", "sinh", "cosh", "zmod", "paired", "tripled", "unitcircle", "fulldiamond", "unitdiamond", "fullsquare", "llcircle", "lrcircle", "urcircle", "ulcircle", "tcircle", "bcircle", "lcircle", "rcircle", "lltriangle", "lrtriangle", "urtriangle", "ultriangle", "uptriangle", "downtriangle", "lefttriangle", "righttriangle", "triangle", "smoothed", "cornered", "superellipsed", "randomized", "squeezed", "enlonged", "shortened", "punked", "curved", "unspiked", "simplified", "blownup", "stretched", "enlarged", "leftenlarged", "topenlarged", "rightenlarged", "bottomenlarged", "crossed", "laddered", "randomshifted", "interpolated", "paralleled", "cutends", "peepholed", "llenlarged", "lrenlarged", "urenlarged", "ulenlarged", "llmoved", "lrmoved", "urmoved", "ulmoved", "rightarrow", "leftarrow", "centerarrow", "boundingbox", "innerboundingbox", "outerboundingbox", "pushboundingbox", "popboundingbox", "bottomboundary", "leftboundary", "topboundary", "rightboundary", "xsized", "ysized", "xysized", "sized", "xyscaled", "intersection_point", "intersection_found", "penpoint", "bbwidth", "bbheight", "withshade", "withcircularshade", "withlinearshade", "defineshade", "shaded", "shadedinto", "withshadecolors", "withshadedomain", "withshademethod", "withshadefactor", "withshadevector", "withshadecenter", "withshadedirection", "withshadestep", "withshadefraction", "cmyk", "spotcolor", "multitonecolor", "namedcolor", "drawfill", "undrawfill", "inverted", "uncolored", "softened", "grayed", "greyed", "onlayer", "along", "graphictext", "loadfigure", "externalfigure", "figure", "register", "outlinetext", "checkedbounds", "checkbounds", "strut", "rule", "withmask", "bitmapimage", "colordecimals", "ddecimal", "dddecimal", "ddddecimal", "textext", "thetextext", "rawtextext", "textextoffset", "texbox", "thetexbox", "rawtexbox", "verbatim", "thelabel", "label", "autoalign", "transparent", "withtransparency", "property", "properties", "withproperties", "asgroup", "infont", "space", "crlf", "dquote", "percent", "SPACE", "CRLF", "DQUOTE", "PERCENT", "grayscale", "greyscale", "withgray", "withgrey", "colorpart", "readfile", "clearxy", "unitvector", "center", "epsed", "anchored", "originpath", "infinite", "break", "xstretched", "ystretched", "snapped", "pathconnectors", "function", "constructedfunction", "constructedpath", "constructedpairs", "straightfunction", "straightpath", "straightpairs", "curvedfunction", "curvedpath", "curvedpairs", "evenly", "oddly", "condition", "pushcurrentpicture", "popcurrentpicture", "arrowpath", "tensecircle", "roundedsquare", "colortype", "whitecolor", "blackcolor", "basiccolors", "complementary", "complemented", "resolvedcolor", "normalfill", "normaldraw", "visualizepaths", "detailpaths", "naturalizepaths", "drawboundary", "drawwholepath", "drawpathonly", "visualizeddraw", "visualizedfill", "detaileddraw", "draworigin", "drawboundingbox", "drawpath", "drawpoint", "drawpoints", "drawcontrolpoints", "drawcontrollines", "drawpointlabels", "drawlineoptions", "drawpointoptions", "drawcontroloptions", "drawlabeloptions", "draworiginoptions", "drawboundoptions", "drawpathoptions", "resetdrawoptions", "undashed", "decorated", "redecorated", "undecorated", "passvariable", "passarrayvariable", "tostring", "format", "formatted", "startpassingvariable", "stoppassingvariable", "eofill", "eoclip", "nofill", "fillup", "eofillup", "area", "addbackground", "shadedup", "shadeddown", "shadedleft", "shadedright" }, + ["commands"]={ "transparency", "sqr", "log", "ln", "exp", "inv", "pow", "pi", "radian", "tand", "cotd", "sin", "cos", "tan", "cot", "atan", "asin", "acos", "invsin", "invcos", "invtan", "acosh", "asinh", "sinh", "cosh", "zmod", "paired", "tripled", "unitcircle", "fulldiamond", "unitdiamond", "fullsquare", "llcircle", "lrcircle", "urcircle", "ulcircle", "tcircle", "bcircle", "lcircle", "rcircle", "lltriangle", "lrtriangle", "urtriangle", "ultriangle", "uptriangle", "downtriangle", "lefttriangle", "righttriangle", "triangle", "smoothed", "cornered", "superellipsed", "randomized", "randomizedcontrols", "squeezed", "enlonged", "shortened", "punked", "curved", "unspiked", "simplified", "blownup", "stretched", "enlarged", "leftenlarged", "topenlarged", "rightenlarged", "bottomenlarged", "crossed", "laddered", "randomshifted", "interpolated", "paralleled", "cutends", "peepholed", "llenlarged", "lrenlarged", "urenlarged", "ulenlarged", "llmoved", "lrmoved", "urmoved", "ulmoved", "rightarrow", "leftarrow", "centerarrow", "boundingbox", "innerboundingbox", "outerboundingbox", "pushboundingbox", "popboundingbox", "bottomboundary", "leftboundary", "topboundary", "rightboundary", "xsized", "ysized", "xysized", "sized", "xyscaled", "intersection_point", "intersection_found", "penpoint", "bbwidth", "bbheight", "withshade", "withcircularshade", "withlinearshade", "defineshade", "shaded", "shadedinto", "withshadecolors", "withshadedomain", "withshademethod", "withshadefactor", "withshadevector", "withshadecenter", "withshadedirection", "withshadestep", "withshadefraction", "cmyk", "spotcolor", "multitonecolor", "namedcolor", "drawfill", "undrawfill", "inverted", "uncolored", "softened", "grayed", "greyed", "onlayer", "along", "graphictext", "loadfigure", "externalfigure", "figure", "register", "outlinetext", "checkedbounds", "checkbounds", "strut", "rule", "withmask", "bitmapimage", "colordecimals", "ddecimal", "dddecimal", "ddddecimal", "textext", "thetextext", "rawtextext", "textextoffset", "texbox", "thetexbox", "rawtexbox", "verbatim", "thelabel", "label", "autoalign", "transparent", "withtransparency", "property", "properties", "withproperties", "asgroup", "infont", "space", "crlf", "dquote", "percent", "SPACE", "CRLF", "DQUOTE", "PERCENT", "grayscale", "greyscale", "withgray", "withgrey", "colorpart", "readfile", "clearxy", "unitvector", "center", "epsed", "anchored", "originpath", "infinite", "break", "xstretched", "ystretched", "snapped", "pathconnectors", "function", "constructedfunction", "constructedpath", "constructedpairs", "straightfunction", "straightpath", "straightpairs", "curvedfunction", "curvedpath", "curvedpairs", "evenly", "oddly", "condition", "pushcurrentpicture", "popcurrentpicture", "arrowpath", "tensecircle", "roundedsquare", "colortype", "whitecolor", "blackcolor", "basiccolors", "complementary", "complemented", "resolvedcolor", "normalfill", "normaldraw", "visualizepaths", "detailpaths", "naturalizepaths", "drawboundary", "drawwholepath", "drawpathonly", "visualizeddraw", "visualizedfill", "detaileddraw", "draworigin", "drawboundingbox", "drawpath", "drawpoint", "drawpoints", "drawcontrolpoints", "drawcontrollines", "drawpointlabels", "drawlineoptions", "drawpointoptions", "drawcontroloptions", "drawlabeloptions", "draworiginoptions", "drawboundoptions", "drawpathoptions", "resetdrawoptions", "undashed", "decorated", "redecorated", "undecorated", "passvariable", "passarrayvariable", "tostring", "format", "formatted", "startpassingvariable", "stoppassingvariable", "eofill", "eoclip", "nofill", "fillup", "eofillup", "area", "addbackground", "shadedup", "shadeddown", "shadedleft", "shadedright" }, ["internals"]={ "nocolormodel", "greycolormodel", "graycolormodel", "rgbcolormodel", "cmykcolormodel", "shadefactor", "textextoffset", "normaltransparent", "multiplytransparent", "screentransparent", "overlaytransparent", "softlighttransparent", "hardlighttransparent", "colordodgetransparent", "colorburntransparent", "darkentransparent", "lightentransparent", "differencetransparent", "exclusiontransparent", "huetransparent", "saturationtransparent", "colortransparent", "luminositytransparent", "ahvariant", "ahdimple", "ahfactor", "metapostversion", "maxdimensions", "drawoptionsfactor" }, }
\ No newline at end of file diff --git a/context/data/scite/context/scite-context-data-metafun.properties b/context/data/scite/context/scite-context-data-metafun.properties index b5d277dc7..578b5c6d0 100644 --- a/context/data/scite/context/scite-context-data-metafun.properties +++ b/context/data/scite/context/scite-context-data-metafun.properties @@ -9,50 +9,50 @@ fulldiamond unitdiamond fullsquare llcircle lrcircle \ urcircle ulcircle tcircle bcircle lcircle \ rcircle lltriangle lrtriangle urtriangle ultriangle \ uptriangle downtriangle lefttriangle righttriangle triangle \ -smoothed cornered superellipsed randomized squeezed \ -enlonged shortened punked curved unspiked \ -simplified blownup stretched enlarged leftenlarged \ -topenlarged rightenlarged bottomenlarged crossed laddered \ -randomshifted interpolated paralleled cutends peepholed \ -llenlarged lrenlarged urenlarged ulenlarged llmoved \ -lrmoved urmoved ulmoved rightarrow leftarrow \ -centerarrow boundingbox innerboundingbox outerboundingbox pushboundingbox \ -popboundingbox bottomboundary leftboundary topboundary rightboundary \ -xsized ysized xysized sized xyscaled \ -intersection_point intersection_found penpoint bbwidth bbheight \ -withshade withcircularshade withlinearshade defineshade shaded \ -shadedinto withshadecolors withshadedomain withshademethod withshadefactor \ -withshadevector withshadecenter withshadedirection withshadestep withshadefraction \ -cmyk spotcolor multitonecolor namedcolor drawfill \ -undrawfill inverted uncolored softened grayed \ -greyed onlayer along graphictext loadfigure \ -externalfigure figure register outlinetext checkedbounds \ -checkbounds strut rule withmask bitmapimage \ -colordecimals ddecimal dddecimal ddddecimal textext \ -thetextext rawtextext textextoffset texbox thetexbox \ -rawtexbox verbatim thelabel label autoalign \ -transparent withtransparency property properties withproperties \ -asgroup infont space crlf dquote \ -percent SPACE CRLF DQUOTE PERCENT \ -grayscale greyscale withgray withgrey colorpart \ -readfile clearxy unitvector center epsed \ -anchored originpath infinite break xstretched \ -ystretched snapped pathconnectors function constructedfunction \ -constructedpath constructedpairs straightfunction straightpath straightpairs \ -curvedfunction curvedpath curvedpairs evenly oddly \ -condition pushcurrentpicture popcurrentpicture arrowpath tensecircle \ -roundedsquare colortype whitecolor blackcolor basiccolors \ -complementary complemented resolvedcolor normalfill normaldraw \ -visualizepaths detailpaths naturalizepaths drawboundary drawwholepath \ -drawpathonly visualizeddraw visualizedfill detaileddraw draworigin \ -drawboundingbox drawpath drawpoint drawpoints drawcontrolpoints \ -drawcontrollines drawpointlabels drawlineoptions drawpointoptions drawcontroloptions \ -drawlabeloptions draworiginoptions drawboundoptions drawpathoptions resetdrawoptions \ -undashed decorated redecorated undecorated passvariable \ -passarrayvariable tostring format formatted startpassingvariable \ -stoppassingvariable eofill eoclip nofill fillup \ -eofillup area addbackground shadedup shadeddown \ -shadedleft shadedright +smoothed cornered superellipsed randomized randomizedcontrols \ +squeezed enlonged shortened punked curved \ +unspiked simplified blownup stretched enlarged \ +leftenlarged topenlarged rightenlarged bottomenlarged crossed \ +laddered randomshifted interpolated paralleled cutends \ +peepholed llenlarged lrenlarged urenlarged ulenlarged \ +llmoved lrmoved urmoved ulmoved rightarrow \ +leftarrow centerarrow boundingbox innerboundingbox outerboundingbox \ +pushboundingbox popboundingbox bottomboundary leftboundary topboundary \ +rightboundary xsized ysized xysized sized \ +xyscaled intersection_point intersection_found penpoint bbwidth \ +bbheight withshade withcircularshade withlinearshade defineshade \ +shaded shadedinto withshadecolors withshadedomain withshademethod \ +withshadefactor withshadevector withshadecenter withshadedirection withshadestep \ +withshadefraction cmyk spotcolor multitonecolor namedcolor \ +drawfill undrawfill inverted uncolored softened \ +grayed greyed onlayer along graphictext \ +loadfigure externalfigure figure register outlinetext \ +checkedbounds checkbounds strut rule withmask \ +bitmapimage colordecimals ddecimal dddecimal ddddecimal \ +textext thetextext rawtextext textextoffset texbox \ +thetexbox rawtexbox verbatim thelabel label \ +autoalign transparent withtransparency property properties \ +withproperties asgroup infont space crlf \ +dquote percent SPACE CRLF DQUOTE \ +PERCENT grayscale greyscale withgray withgrey \ +colorpart readfile clearxy unitvector center \ +epsed anchored originpath infinite break \ +xstretched ystretched snapped pathconnectors function \ +constructedfunction constructedpath constructedpairs straightfunction straightpath \ +straightpairs curvedfunction curvedpath curvedpairs evenly \ +oddly condition pushcurrentpicture popcurrentpicture arrowpath \ +tensecircle roundedsquare colortype whitecolor blackcolor \ +basiccolors complementary complemented resolvedcolor normalfill \ +normaldraw visualizepaths detailpaths naturalizepaths drawboundary \ +drawwholepath drawpathonly visualizeddraw visualizedfill detaileddraw \ +draworigin drawboundingbox drawpath drawpoint drawpoints \ +drawcontrolpoints drawcontrollines drawpointlabels drawlineoptions drawpointoptions \ +drawcontroloptions drawlabeloptions draworiginoptions drawboundoptions drawpathoptions \ +resetdrawoptions undashed decorated redecorated undecorated \ +passvariable passarrayvariable tostring format formatted \ +startpassingvariable stoppassingvariable eofill eoclip nofill \ +fillup eofillup area addbackground shadedup \ +shadeddown shadedleft shadedright keywordclass.metafun.internals=\ nocolormodel greycolormodel graycolormodel rgbcolormodel \ diff --git a/metapost/context/base/mpiv/mp-mlib.mpiv b/metapost/context/base/mpiv/mp-mlib.mpiv index 4c9f6442a..a4541ae2d 100644 --- a/metapost/context/base/mpiv/mp-mlib.mpiv +++ b/metapost/context/base/mpiv/mp-mlib.mpiv @@ -909,6 +909,10 @@ vardef mfun_do_outline_text_flush (expr kind, n, x, y) (text t) = fi ; enddef ; +vardef mfun_do_outline_rule_flush (expr kind, x, y, w, h) = + mfun_do_outline_text_flush (kind, 1, x, y) (fullsquare xyscaled(w,h)) +enddef ; + numeric mfun_do_outline_n ; mfun_do_outline_n := 0 ; vardef mfun_do_outline_text_f (expr n, x, y) (text t) = @@ -1009,6 +1013,9 @@ def mfun_do_outline_options_r = enddef ; vardef outlinetext@# (expr t) text rest = save kind ; string kind ; kind := str @# ; currentoutlinetext := currentoutlinetext + 1 ; + def mfun_do_outline_options_d = enddef ; + def mfun_do_outline_options_f = enddef ; + def mfun_do_outline_options_r = enddef ; image ( normaldraw image ( if mfun_trial_run : % lua.mp.report("set outline text",currentoutlinetext); diff --git a/metapost/context/base/mpiv/mp-tool.mpiv b/metapost/context/base/mpiv/mp-tool.mpiv index 9e086f0df..ae2ce3435 100644 --- a/metapost/context/base/mpiv/mp-tool.mpiv +++ b/metapost/context/base/mpiv/mp-tool.mpiv @@ -996,6 +996,56 @@ primarydef p randomshifted s = endgroup enddef ; +vardef mfun_randomized_path(expr p,s) = + for i=0 upto length(p)-1 : + (point i of p) .. controls + ((postcontrol i of p) randomshifted s) and + ((precontrol (i+1) of p) randomshifted s) .. + endfor + if cycle p : + cycle + else : + (point length(p) of p) + fi +enddef; + +vardef mfun_randomized_picture(expr p,s)(text rnd) = + save currentpicture ; + picture currentpicture ; + currentpicture := nullpicture ; + for i within p : + addto currentpicture + if stroked i : + doublepath pathpart i rnd s + dashed dashpart i + withpen penpart i + withcolor colorpart i + withprescript prescriptpart i + withpostscript postscriptpart i + elseif filled i : + contour pathpart i rnd s + withpen penpart i + withcolor colorpart i + withprescript prescriptpart i + withpostscript postscriptpart i + else : + also i + fi + ; + endfor ; + currentpicture +enddef ; + +primarydef p randomizedcontrols s = ( + if path p : + mfun_randomized_path(p,s) + elseif picture p : + mfun_randomized_picture(p,s)(randomizedcontrols) + else : + p randomized s + fi +) enddef ; + primarydef p randomized s = ( if path p : for i=0 upto length(p)-1 : @@ -1041,6 +1091,8 @@ primarydef p randomized s = ( fi elseif string p : (resolvedcolor(p)) randomized s + elseif picture p : + mfun_randomized_picture(p,s)(randomized) else : p + uniformdeviate s fi @@ -1943,7 +1995,7 @@ def reprocess suffix p = p := repathed (22,p) enddef ; % no attributes vardef repathed (expr mode, p) text t = begingroup ; if mode = 0 : - save withcolor ; + save normalwithcolor ; remapcolors ; fi ; save _p_, _pp_, _ppp_, _f_, _b_, _t_ ; diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf Binary files differindex f97738e16..0c4892500 100644 --- a/tex/context/base/context-version.pdf +++ b/tex/context/base/context-version.pdf diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 5e4e0bb15..4c8aa9228 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2016.07.30 00:26} +\newcontextversion{2016.08.01 10:49} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 6b102e801..d0d438996 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -39,7 +39,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2016.07.30 00:26} +\edef\contextversion{2016.08.01 10:49} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/mkiv/font-mps.lua b/tex/context/base/mkiv/font-mps.lua index 42e8e704b..d56c25731 100644 --- a/tex/context/base/mkiv/font-mps.lua +++ b/tex/context/base/mkiv/font-mps.lua @@ -21,8 +21,6 @@ fonts = fonts or { } local metapost = fonts.metapost or { } fonts.metapost = metapost -local trace_skips = false trackers.register("metapost.outlines.skips",function(v) trace_skips = v end) - local f_moveto = formatters["(%F,%F)"] local f_lineto = formatters["--(%F,%F)"] local f_curveto = formatters["..controls(%F,%F)and(%F,%F)..(%F,%F)"] @@ -238,38 +236,46 @@ function metapost.maxbounds(data,index,factor) ) end ------ formatters = string.formatters ------ concat = table.concat +-- This is a nice example of tex, metapost and lua working in tandem. Each kicks in at the +-- right time. It's probably why I like watching https://www.youtube.com/watch?v=c5FqpddnJmc +-- so much: precisely (and perfectly) timed too. + +local nodecodes = nodes.nodecodes -- no nuts yet -local nodecodes = nodes.nodecodes -- no nuts yet +local glyph_code = nodecodes.glyph +local disc_code = nodecodes.disc +local kern_code = nodecodes.kern +local glue_code = nodecodes.glue +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local rule_code = nodecodes.rule -local glyph_code = nodecodes.glyph -local disc_code = nodecodes.disc -local kern_code = nodecodes.kern -local glue_code = nodecodes.glue -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local rule_code = nodecodes.rule +local normal_rule = nodes.rulecodes.normal -local find_tail = nodes.tail +local nuts = nodes.nuts +local getnext = nuts.getnext +local getid = nuts.getid +local getlist = nuts.getlist +local getchar = nuts.getchar +local getfont = nuts.getfont +local getsubtype = nuts.getsubtype +local getfield = nuts.getfield +local getbox = nuts.getbox ------ metapost = fonts.glyphs.metapost +local effective_glue = nuts.effective_glue -local characters = fonts.hashes.characters -local parameters = fonts.hashes.parameters -local shapes = fonts.hashes.shapes -local topaths = metapost.paths +local characters = fonts.hashes.characters +local parameters = fonts.hashes.parameters +local shapes = fonts.hashes.shapes +local topaths = metapost.paths -local f_code = formatters["mfun_do_outline_text_flush(%q,%i,%F,%F)(%,t);"] -local s_nothing = "(origin scaled 10)" -local f_trace_rule = formatters["draw rule(%F,%F,%F) shifted (%F,%F) withcolor .5white;"] -local f_strut = formatters["strut(%F,%F);"] -local f_hrule = formatters["draw rule(%F,%F,%F);"] -local f_vrule = formatters["draw rule(%F,%F,%F) shifted (%F,%F);"] -local f_bounds = formatters["checkbounds(%F,%F,%F,%F);"] +local f_code = formatters["mfun_do_outline_text_flush(%q,%i,%F,%F)(%,t);"] +local f_rule = formatters["mfun_do_outline_rule_flush(%q,%F,%F,%F,%F);"] +local f_bounds = formatters["checkbounds(%F,%F,%F,%F);"] +local s_nothing = "(origin scaled 10)" -local sc = 10 -local fc = number.dimenfactors.bp * sc / 10 +local sc = 10 +local fc = number.dimenfactors.bp * sc / 10 -- todo: make the next more efficient: @@ -284,8 +290,7 @@ function metapost.output(kind,font,char,advance,shift,ex) local glyf = glyphs[index] if glyf then local units = shapedata.units or 1000 - local yfactor = sc/units -yfactor = yfactor * parameters[font].factor / 655.36 + local yfactor = (sc/units) * parameters[font].factor / 655.36 local xfactor = yfactor local shift = shift or 0 local advance = advance or 0 @@ -317,131 +322,114 @@ function fonts.metapost.boxtomp(n,kind) local llx, lly, urx, ury = 0, 0, 0, 0 - local boxtomp + local horizontal, vertical - local function horizontal(current,shift,glue_sign,glue_set,glue_order,ht,dp) - shift = shift or 0 + horizontal = function(parent,current,xoffset,yoffset) + local dx = 0 while current do - local id = current.id + local id = getid(current) if id == glyph_code then - local code, width = metapost.output(kind,current.font,current.char,advance,-shift*fc,current.expansion_factor) + local code, width = metapost.output(kind,getfont(current),getchar(current),xoffset+dx,yoffset,getfield(current,"expansion_factor")) result[#result+1] = code - advance = advance + width + dx = dx + width elseif id == disc_code then - local replace = current.replace + local replace = getfield(current,"replace") if replace then - horizontal(replace,shift,glue_sign,glue_set,glue_order,ht,dp) + dx = dx + horizontal(parent,replace,xoffset+dx,yoffset) end elseif id == kern_code then - local kern = current.kern * fc - if trace_skips then - result[#result+1] = f_trace_rule(kern,0.8*ht*fc,0.8*dp*fc,advance,-shift*fc) - end - advance = advance + kern + dx = dx + getfield(current,"kern") * fc elseif id == glue_code then - local width = current.width - if glue_sign == 1 then - if current.stretch_order == glue_order then - width = (width + current.stretch * glue_set) * fc - else - width = width * fc - end - elseif glue_sign == 2 then - if current.shrink_order == glue_order then - width = (width - current.shrink * glue_set) * fc - else - width = width * fc - end - else - width = width * fc - end - if trace_skips then - result[#result+1] = f_trace_rule(width,0.1*ht*fc,0.1*dp*fc,advance,-shift*fc) - end - advance = advance + width + dx = dx + effective_glue(current,parent) * fc elseif id == hlist_code then - local a = advance - boxtomp(current,shift+current.shift,current.glue_sign,current.glue_set,current.glue_order) - advance = a + current.width * fc + local list = getlist(current) + if list then + horizontal(current,list,xoffset+dx,yoffset-getfield(current,"shift")*fc) + end + dx = dx + getfield(current,"width") * fc elseif id == vlist_code then - boxtomp(current) -- ,distance + shift,current.glue_set*current.glue_sign) - advance = advance + current.width * fc + local list = getlist(current) + if list then + vertical(current,list,xoffset+dx,yoffset-getfield(current,"shift")*fc) + end + dx = dx + getfield(current,"width") * fc elseif id == rule_code then - local wd = current.width - local ht = current.height - local dp = current.depth - if not (ht == signal or dp == signal or wd == signal) then - ht = ht - shift - dp = dp - shift - if wd == 0 then - result[#result+1] = f_strut(ht*fc,-dp*fc) - else - result[#result+1] = f_hrule(wd*fc,ht*fc,-dp*fc) + local wd = getfield(current,"width") * fc + if wd ~= 0 then + local ht = getfield(current,"height") + local dp = getfield(current,"depth") + if ht == signal then + ht = getfield(parent,"height") end - end - if wd ~= signal then - advance = advance + wd * fc + if dp == signal then + dp = getfield(parent,"depth") + end + local hd = (ht + dp) * fc + if hd ~= 0 and getsubtype(current) == normal_rule then + result[#result+1] = f_rule(kind,xoffset+dx+wd/2,yoffset+hd/2,wd,hd) + end + dx = dx + wd end end - current = current.next + current = getnext(current) end + return dx end - local function vertical(current,shift) - shift = shift or 0 - current = find_tail(current) -- otherwise bad bbox + vertical = function(parent,current,xoffset,yoffset) + local dy = getfield(parent,"height") * fc while current do - local id = current.id + local id = getid(current) if id == hlist_code then - distance = distance - current.depth - boxtomp(current,distance + shift,current.glue_set*current.glue_sign) - distance = distance - current.height + dy = dy - getfield(current,"height") * fc + local list = getlist(current) + if list then + horizontal(current,list,xoffset+getfield(current,"shift")*fc,yoffset+dy) + end + dy = dy - getfield(current,"depth") * fc elseif id == vlist_code then - print("vertical >>>") - vertical(current.list,0) + dy = dy - getfield(current,"height") * fc + local list = getlist(current) + if list then + vertical(current,list,xoffset+getfield(current,"shift")*fc,yoffset+dy) + end + dy = dy - getfield(current,"depth") * fc elseif id == kern_code then - distance = distance - current.kern - advance = 0 + dy = dy - getfield(current,"kern") * fc elseif id == glue_code then - distance = distance - current.width - advance = 0 + dy = dy - effective_glue(current,parent) * fc elseif id == rule_code then - local wd = current.width - local ht = current.height - local dp = current.depth - if not (ht == signal or dp == signal or wd == signal) then - distance = distance - dp - if wd == 0 then - result[#result+1] = f_strut(ht*fc,-dp*fc) + local ht = getfield(current,"height") + local dp = getfield(current,"depth") + local hd = (ht + dp) * fc + if hd ~= 0 then + local wd = getfield(current,"width") + if wd == signal then + wd = getfield(parent,"width") * fc else - result[#result+1] = f_vrule(wd*fc,ht*fc,-dp*fc,0,distance+shift) + wd = wd * fc end - distance = distance - ht + dy = dy - ht * fc + if wd ~= 0 and getsubtype(current) == 0 then + result[#result+1] = f_rule(kind,xoffset+wd/2,yoffset+dy+hd/2,wd,hd) + end + dy = dy - dp * fc end end - current = current.prev + current = getnext(current) end + return dy end - boxtomp = function(list,shift) - local current = list.list - if current then - if list.id == hlist_code then - horizontal(current,shift,list.glue_sign,list.glue_set,list.glue_order,list.height,list.depth) - else - vertical(current,shift) - end - end + local box = getbox(n) + local list = box and getlist(box) + if list then + (getid(box) == hlist_code and horizontal or vertical)(box,list,0,0) end - local box = tex.box[n] - - boxtomp(box,box.shift,box.glue_sign,box.glue_set,box.glue_order) - - local wd = box.width - local ht = box.height - local dp = box.depth - local sh = box.shift + local wd = getfield(box,"width") + local ht = getfield(box,"height") + local dp = getfield(box,"depth") result[#result+1] = f_bounds(0,-dp*fc,wd*fc,ht*fc) diff --git a/tex/context/base/mkiv/grph-con.lua b/tex/context/base/mkiv/grph-con.lua index 7cff26d10..380f56b14 100644 --- a/tex/context/base/mkiv/grph-con.lua +++ b/tex/context/base/mkiv/grph-con.lua @@ -173,14 +173,15 @@ do -- svg local svgconverter = converters.svg converters.svgz = svgconverter - -- inkscape on windows only works with complete paths .. did the command line arguments change again? + -- inkscape on windows only works with complete paths .. did the command line + -- arguments change again? Ok, it's weirder, with -A then it's a name only when + -- not . (current) programs.inkscape = { command = "inkscape", pdfargument = longtostring [[ "%oldname%" --export-dpi=600 - -A --export-pdf="%newname%" ]], pngargument = longtostring [[ diff --git a/tex/context/base/mkiv/meta-imp-outlines.mkiv b/tex/context/base/mkiv/meta-imp-outlines.mkiv index 7d7495037..ab6fcdd3d 100644 --- a/tex/context/base/mkiv/meta-imp-outlines.mkiv +++ b/tex/context/base/mkiv/meta-imp-outlines.mkiv @@ -18,8 +18,8 @@ local formatters = string.formatters local validstring = string.valid local f_setbounds = formatters["setbounds currentpicture to (%s) enlarged %.4G;"] -local f_index = formatters['draw anchored.bot(textext("\\tttf\\setstrut\\strut index %i") ysized 2bp ,.5[llcorner currentpicture,lrcorner currentpicture] shifted (0,%.4G));'] -local f_unicode = formatters['draw anchored.bot(textext("\\tttf\\setstrut\\strut unicode %05X") ysized 2bp ,.5[llcorner currentpicture,lrcorner currentpicture] shifted (0,%.4G));'] +local f_index = formatters['draw anchored.bot(textext("\\tttf\\setstrut\\strut index %i") ysized 10bp ,.5[llcorner currentpicture,lrcorner currentpicture] shifted (0,%.4G));'] +local f_unicode = formatters['draw anchored.bot(textext("\\tttf\\setstrut\\strut unicode %05X") ysized 10bp ,.5[llcorner currentpicture,lrcorner currentpicture] shifted (0,%.4G));'] local f_in_red = formatters["draw %s withpen pencircle scaled .15 withcolor .5red;"] local f_in_green = formatters["draw %s withpen pencircle scaled .15 withcolor .5green;"] @@ -43,6 +43,12 @@ local v_all = variables.all local v_page = variables.page local v_text = variables.text local v_command = variables.command +local v_box = variables.box +local v_width = variables.width +local v_min = variables.min +local v_max = variables.max +local v_comment = variables.comment +local v_simple = variables.simple function metapost.showglyph(specification) local fontid = font.current() @@ -53,7 +59,8 @@ function metapost.showglyph(specification) local index = validstring(specification.index) local alternative = validstring(specification.alternative) local command = validstring(specification.command) - + local options = utilities.parsers.settings_to_set(specification.option) + local all = not next(options) and not options[v_simple] or options[v_all] local function shape(index,what,f_comment) if not index then return @@ -63,15 +70,15 @@ function metapost.showglyph(specification) local units = data.fontheader and data.fontheader.emsize or 1000 local factor = 100/units local paths = metapost.paths(glyph,factor) - if #paths > 0 then + if #paths > 0 and glyph.boundingbox and glyph.width then local graphic = f_glyph(concat{ - f_in_gray(metapost.fill(paths)), - metapost.draw(paths,true), -- true triggers trace - f_in_red(metapost.boundingbox(glyph,factor)), - f_in_green(metapost.widthline(glyph,factor)), - f_in_blue(metapost.zeroline(glyph,factor)), - f_setbounds(metapost.maxbounds(data,index,factor),offset or 1), - f_comment(what,1) + f_in_gray (metapost.fill(paths)), + metapost.draw(paths,true), -- true triggers trace + (all or options[v_box]) and f_in_red (metapost.boundingbox(glyph,factor)) or "", + (all or options[v_width]) and f_in_green (metapost.widthline(glyph,factor)) or "", + (all or options[v_min]) and f_in_blue (metapost.zeroline(glyph,factor)) or "", + (all or options[v_max]) and f_setbounds(metapost.maxbounds(data,index,factor),offset or 1) or "", + (all or options[v_comment]) and f_comment (what,1) or "", }) if alternative == v_page then context.startMPpage() @@ -110,7 +117,7 @@ function metapost.showglyph(specification) end local first, last if type(index) == "string" then - first, last = string.match(index,"^(.-):(.*)$") + first, last = string.split(index,":") if first and last then first = tonumber(first) last = tonumber(last) @@ -137,17 +144,25 @@ end \unprotect +% option: box|width|min|max|comment + \unexpanded\def\showshape {\dosingleargument\meta_shapes_show} \def\meta_shapes_show[#1]% {\begingroup - \getdummyparameters[\c!alternative=\v!text,#1]% + \letdummyparameter\c!index\empty + \letdummyparameter\c!character\empty + \letdummyparameter\c!alternative\v!text + \letdummyparameter\c!command\empty + \letdummyparameter\c!option\v!all + \getdummyparameters[#1]% \ctxlua{fonts.metapost.showglyph{ character = "\dummyparameter\c!character", index = "\dummyparameter\c!index", alternative = "\dummyparameter\c!alternative", command = "\dummyparameter\c!command", + option = "\dummyparameter\c!option", }}% \endgroup} @@ -164,8 +179,19 @@ end % \setupbodyfont[pagella] % \showshape[character=all,alternative=page] -\setupbodyfont[dejavu] -\showshape[character=P,alternative=text] +\usemodule[art-01] + +\startcombination[3*1] + {\ruledhbox{\startMPcode draw textext("\showshape[character=a]") ; \stopMPcode}} {} + {\ruledhbox{\startMPcode draw textext("\showshape[character=x]") ; \stopMPcode}} {} + {\ruledhbox{\showshape[character=P,alternative=text]}} {} +\stopcombination + +\startcombination[3*1] + {\ruledhbox{\startMPcode draw textext("\showshape[character=a,option={simple}]") ; \stopMPcode}} {} + {\ruledhbox{\startMPcode draw textext("\showshape[character=x,option={simple}]") ; \stopMPcode}} {} + {\ruledhbox{\showshape[character=P,alternative=text,option=simple]}} {} +\stopcombination % \definedfont[almfixed] % \showshape[character=all,alternative=page] diff --git a/tex/context/base/mkiv/mult-fun.lua b/tex/context/base/mkiv/mult-fun.lua index 1a083e366..c6d321949 100644 --- a/tex/context/base/mkiv/mult-fun.lua +++ b/tex/context/base/mkiv/mult-fun.lua @@ -30,7 +30,7 @@ return { "tcircle", "bcircle", "lcircle", "rcircle", "lltriangle", "lrtriangle", "urtriangle", "ultriangle", "uptriangle", "downtriangle", "lefttriangle", "righttriangle", "triangle", - "smoothed", "cornered", "superellipsed", "randomized", "squeezed", "enlonged", "shortened", + "smoothed", "cornered", "superellipsed", "randomized", "randomizedcontrols", "squeezed", "enlonged", "shortened", "punked", "curved", "unspiked", "simplified", "blownup", "stretched", "enlarged", "leftenlarged", "topenlarged", "rightenlarged", "bottomenlarged", "crossed", "laddered", "randomshifted", "interpolated", "paralleled", "cutends", "peepholed", diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex 88085d831..6df820770 100644 --- a/tex/context/base/mkiv/status-files.pdf +++ b/tex/context/base/mkiv/status-files.pdf diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf Binary files differindex a5db281ed..879c87379 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf Binary files differindex 73add297a..9b63690fc 100644 --- a/tex/context/interface/mkiv/i-context.pdf +++ b/tex/context/interface/mkiv/i-context.pdf diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf Binary files differindex a3c7158cb..c08e5822a 100644 --- a/tex/context/interface/mkiv/i-readme.pdf +++ b/tex/context/interface/mkiv/i-readme.pdf diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 4cefe9a5e..5683fb2f2 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 07/30/16 00:26:47 +-- merge date : 08/01/16 10:49:41 do -- begin closure to overcome local limits and interference @@ -23430,6 +23430,777 @@ end -- closure do -- begin closure to overcome local limits and interference +if not modules then modules={} end modules ['font-otc']={ + version=1.001, + comment="companion to font-otf.lua (context)", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local format,insert,sortedkeys,tohash=string.format,table.insert,table.sortedkeys,table.tohash +local type,next=type,next +local lpegmatch=lpeg.match +local utfbyte,utflen=utf.byte,utf.len +local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) +local report_otf=logs.reporter("fonts","otf loading") +local fonts=fonts +local otf=fonts.handlers.otf +local registerotffeature=otf.features.register +local setmetatableindex=table.setmetatableindex +local normalized={ + substitution="substitution", + single="substitution", + ligature="ligature", + alternate="alternate", + multiple="multiple", + kern="kern", + pair="pair", + chainsubstitution="chainsubstitution", + chainposition="chainposition", +} +local types={ + substitution="gsub_single", + ligature="gsub_ligature", + alternate="gsub_alternate", + multiple="gsub_multiple", + kern="gpos_pair", + pair="gpos_pair", + chainsubstitution="gsub_contextchain", + chainposition="gpos_contextchain", +} +local names={ + gsub_single="gsub", + gsub_multiple="gsub", + gsub_alternate="gsub", + gsub_ligature="gsub", + gsub_context="gsub", + gsub_contextchain="gsub", + gsub_reversecontextchain="gsub", + gpos_single="gpos", + gpos_pair="gpos", + gpos_cursive="gpos", + gpos_mark2base="gpos", + gpos_mark2ligature="gpos", + gpos_mark2mark="gpos", + gpos_context="gpos", + gpos_contextchain="gpos", +} +setmetatableindex(types,function(t,k) t[k]=k return k end) +local everywhere={ ["*"]={ ["*"]=true } } +local noflags={ false,false,false,false } +local function getrange(sequences,category) + local count=#sequences + local first=nil + local last=nil + for i=1,count do + local t=sequences[i].type + if t and names[t]==category then + if not first then + first=i + end + last=i + end + end + return first or 1,last or count +end +local function validspecification(specification,name) + local dataset=specification.dataset + if dataset then + elseif specification[1] then + dataset=specification + specification={ dataset=dataset } + else + dataset={ { data=specification.data } } + specification.data=nil + specification.dataset=dataset + end + local first=dataset[1] + if first then + first=first.data + end + if not first then + report_otf("invalid feature specification, no dataset") + return + end + if type(name)~="string" then + name=specification.name or first.name + end + if type(name)~="string" then + report_otf("invalid feature specification, no name") + return + end + local n=#dataset + if n>0 then + for i=1,n do + setmetatableindex(dataset[i],specification) + end + return specification,name + end +end +local function addfeature(data,feature,specifications) + if not specifications then + report_otf("missing specification") + return + end + local descriptions=data.descriptions + local resources=data.resources + local features=resources.features + local sequences=resources.sequences + if not features or not sequences then + report_otf("missing specification") + return + end + local alreadydone=resources.alreadydone + if not alreadydone then + alreadydone={} + resources.alreadydone=alreadydone + end + if alreadydone[specifications] then + return + else + alreadydone[specifications]=true + end + local fontfeatures=resources.features or everywhere + local unicodes=resources.unicodes + local splitter=lpeg.splitter(" ",unicodes) + local done=0 + local skip=0 + local aglunicodes=false + local specifications=validspecification(specifications,feature) + if not specifications then + return + end + local function tounicode(code) + if not code then + return + end + if type(code)=="number" then + return code + end + local u=unicodes[code] + if u then + return u + end + if utflen(code)==1 then + u=utfbyte(code) + if u then + return u + end + end + if not aglunicodes then + aglunicodes=fonts.encodings.agl.unicodes + end + return aglunicodes[code] + end + local coverup=otf.coverup + local coveractions=coverup.actions + local stepkey=coverup.stepkey + local register=coverup.register + local function prepare_substitution(list,featuretype) + local coverage={} + local cover=coveractions[featuretype] + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if description then + if type(replacement)=="table" then + replacement=replacement[1] + end + replacement=tounicode(replacement) + if replacement and descriptions[replacement] then + cover(coverage,unicode,replacement) + done=done+1 + else + skip=skip+1 + end + else + skip=skip+1 + end + end + return coverage + end + local function prepare_alternate(list,featuretype) + local coverage={} + local cover=coveractions[featuretype] + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if not description then + skip=skip+1 + elseif type(replacement)=="table" then + local r={} + for i=1,#replacement do + local u=tounicode(replacement[i]) + r[i]=descriptions[u] and u or unicode + end + cover(coverage,unicode,r) + done=done+1 + else + local u=tounicode(replacement) + if u then + cover(coverage,unicode,{ u }) + done=done+1 + else + skip=skip+1 + end + end + end + return coverage + end + local function prepare_multiple(list,featuretype) + local coverage={} + local cover=coveractions[featuretype] + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if not description then + skip=skip+1 + elseif type(replacement)=="table" then + local r,n={},0 + for i=1,#replacement do + local u=tounicode(replacement[i]) + if descriptions[u] then + n=n+1 + r[n]=u + end + end + if n>0 then + cover(coverage,unicode,r) + done=done+1 + else + skip=skip+1 + end + else + local u=tounicode(replacement) + if u then + cover(coverage,unicode,{ u }) + done=done+1 + else + skip=skip+1 + end + end + end + return coverage + end + local function prepare_ligature(list,featuretype) + local coverage={} + local cover=coveractions[featuretype] + for code,ligature in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if description then + if type(ligature)=="string" then + ligature={ lpegmatch(splitter,ligature) } + end + local present=true + for i=1,#ligature do + local l=ligature[i] + local u=tounicode(l) + if descriptions[u] then + ligature[i]=u + else + present=false + break + end + end + if present then + cover(coverage,unicode,ligature) + done=done+1 + else + skip=skip+1 + end + else + skip=skip+1 + end + end + return coverage + end + local function prepare_kern(list,featuretype) + local coverage={} + local cover=coveractions[featuretype] + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if description and type(replacement)=="table" then + local r={} + for k,v in next,replacement do + local u=tounicode(k) + if u then + r[u]=v + end + end + if next(r) then + cover(coverage,unicode,r) + done=done+1 + else + skip=skip+1 + end + else + skip=skip+1 + end + end + return coverage + end + local function prepare_pair(list,featuretype) + local coverage={} + local cover=coveractions[featuretype] + if cover then + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if description and type(replacement)=="table" then + local r={} + for k,v in next,replacement do + local u=tounicode(k) + if u then + r[u]=v + end + end + if next(r) then + cover(coverage,unicode,r) + done=done+1 + else + skip=skip+1 + end + else + skip=skip+1 + end + end + else + report_otf("unknown cover type %a",featuretype) + end + return coverage + end + local function prepare_chain(list,featuretype,sublookups) + local rules=list.rules + local coverage={} + if rules then + local rulehash={} + local rulesize=0 + local sequence={} + local nofsequences=0 + local lookuptype=types[featuretype] + for nofrules=1,#rules do + local rule=rules[nofrules] + local current=rule.current + local before=rule.before + local after=rule.after + local replacements=rule.replacements or false + local sequence={} + local nofsequences=0 + if before then + for n=1,#before do + nofsequences=nofsequences+1 + sequence[nofsequences]=before[n] + end + end + local start=nofsequences+1 + for n=1,#current do + nofsequences=nofsequences+1 + sequence[nofsequences]=current[n] + end + local stop=nofsequences + if after then + for n=1,#after do + nofsequences=nofsequences+1 + sequence[nofsequences]=after[n] + end + end + local lookups=rule.lookups or false + local subtype=nil + if lookups and sublookups then + for k,v in next,lookups do + local lookup=sublookups[v] + if lookup then + lookups[k]=lookup + if not subtype then + subtype=lookup.type + end + else + end + end + end + if nofsequences>0 then + local hashed={} + for i=1,nofsequences do + local t={} + local s=sequence[i] + for i=1,#s do + local u=tounicode(s[i]) + if u then + t[u]=true + end + end + hashed[i]=t + end + sequence=hashed + rulesize=rulesize+1 + rulehash[rulesize]={ + nofrules, + lookuptype, + sequence, + start, + stop, + lookups, + replacements, + subtype, + } + for unic in next,sequence[start] do + local cu=coverage[unic] + if not cu then + coverage[unic]=rulehash + end + end + end + end + end + return coverage + end + local dataset=specifications.dataset + local function report(name,category,position,first,last,sequences) + report_otf("injecting name %a of category %a at position %i in [%i,%i] of [%i,%i]", + name,category,position,first,last,1,#sequences) + end + local function inject(specification,sequences,sequence,first,last,category,name) + local position=specification.position or false + if not position then + position=specification.prepend + if position==true then + if trace_loading then + report(name,category,first,first,last,sequences) + end + insert(sequences,first,sequence) + return + end + end + if not position then + position=specification.append + if position==true then + if trace_loading then + report(name,category,last+1,first,last,sequences) + end + insert(sequences,last+1,sequence) + return + end + end + local kind=type(position) + if kind=="string" then + local index=false + for i=first,last do + local s=sequences[i] + local f=s.features + if f then + for k in next,f do + if k==position then + index=i + break + end + end + if index then + break + end + end + end + if index then + position=index + else + position=last+1 + end + elseif kind=="number" then + if position<0 then + position=last-position+1 + end + if position>last then + position=last+1 + elseif position<first then + position=first + end + else + position=last+1 + end + if trace_loading then + report(name,category,position,first,last,sequences) + end + insert(sequences,position,sequence) + end + for s=1,#dataset do + local specification=dataset[s] + local valid=specification.valid + local feature=specification.name or feature + if not feature or feature=="" then + report_otf("no valid name given for extra feature") + elseif not valid or valid(data,specification,feature) then + local initialize=specification.initialize + if initialize then + specification.initialize=initialize(specification,data) and initialize or nil + end + local askedfeatures=specification.features or everywhere + local askedsteps=specification.steps or specification.subtables or { specification.data } or {} + local featuretype=normalized[specification.type or "substitution"] or "substitution" + local featureflags=specification.flags or noflags + local featureorder=specification.order or { feature } + local featurechain=(featuretype=="chainsubstitution" or featuretype=="chainposition") and 1 or 0 + local nofsteps=0 + local steps={} + local sublookups=specification.lookups + local category=nil + if sublookups then + local s={} + for i=1,#sublookups do + local specification=sublookups[i] + local askedsteps=specification.steps or specification.subtables or { specification.data } or {} + local featuretype=normalized[specification.type or "substitution"] or "substitution" + local featureflags=specification.flags or noflags + local nofsteps=0 + local steps={} + for i=1,#askedsteps do + local list=askedsteps[i] + local coverage=nil + local format=nil + if featuretype=="substitution" then + coverage=prepare_substitution(list,featuretype) + elseif featuretype=="ligature" then + coverage=prepare_ligature(list,featuretype) + elseif featuretype=="alternate" then + coverage=prepare_alternate(list,featuretype) + elseif featuretype=="multiple" then + coverage=prepare_multiple(list,featuretype) + elseif featuretype=="kern" then + format="kern" + coverage=prepare_kern(list,featuretype) + elseif featuretype=="pair" then + format="pair" + coverage=prepare_pair(list,featuretype) + end + if coverage and next(coverage) then + nofsteps=nofsteps+1 + steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources) + end + end + s[i]={ + [stepkey]=steps, + nofsteps=nofsteps, + type=types[featuretype], + } + end + sublookups=s + end + for i=1,#askedsteps do + local list=askedsteps[i] + local coverage=nil + local format=nil + if featuretype=="substitution" then + category="gsub" + coverage=prepare_substitution(list,featuretype) + elseif featuretype=="ligature" then + category="gsub" + coverage=prepare_ligature(list,featuretype) + elseif featuretype=="alternate" then + category="gsub" + coverage=prepare_alternate(list,featuretype) + elseif featuretype=="multiple" then + category="gsub" + coverage=prepare_multiple(list,featuretype) + elseif featuretype=="kern" then + category="gpos" + format="kern" + coverage=prepare_kern(list,featuretype) + elseif featuretype=="pair" then + category="gpos" + format="pair" + coverage=prepare_pair(list,featuretype) + elseif featuretype=="chainsubstitution" then + category="gsub" + coverage=prepare_chain(list,featuretype,sublookups) + elseif featuretype=="chainposition" then + category="gpos" + coverage=prepare_chain(list,featuretype,sublookups) + else + report_otf("not registering feature %a, unknown category",feature) + return + end + if coverage and next(coverage) then + nofsteps=nofsteps+1 + steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources) + end + end + if nofsteps>0 then + for k,v in next,askedfeatures do + if v[1] then + askedfeatures[k]=tohash(v) + end + end + if featureflags[1] then featureflags[1]="mark" end + if featureflags[2] then featureflags[2]="ligature" end + if featureflags[3] then featureflags[3]="base" end + local steptype=types[featuretype] + local sequence={ + chain=featurechain, + features={ [feature]=askedfeatures }, + flags=featureflags, + name=feature, + order=featureorder, + [stepkey]=steps, + nofsteps=nofsteps, + type=steptype, + } + local first,last=getrange(sequences,category) + inject(specification,sequences,sequence,first,last,category,feature) + local features=fontfeatures[category] + if not features then + features={} + fontfeatures[category]=features + end + local k=features[feature] + if not k then + k={} + features[feature]=k + end + for script,languages in next,askedfeatures do + local kk=k[script] + if not kk then + kk={} + k[script]=kk + end + for language,value in next,languages do + kk[language]=value + end + end + end + end + end + if trace_loading then + report_otf("registering feature %a, affected glyphs %a, skipped glyphs %a",feature,done,skip) + end +end +otf.enhancers.addfeature=addfeature +local extrafeatures={} +local knownfeatures={} +function otf.addfeature(name,specification) + if type(name)=="table" then + specification=name + end + if type(specification)~="table" then + report_otf("invalid feature specification, no valid table") + return + end + specification,name=validspecification(specification,name) + if name and specification then + local slot=knownfeatures[name] + if slot then + else + slot=#extrafeatures+1 + knownfeatures[name]=slot + end + specification.name=name + extrafeatures[slot]=specification + end +end +local function enhance(data,filename,raw) + for slot=1,#extrafeatures do + local specification=extrafeatures[slot] + addfeature(data,specification.name,specification) + end +end +otf.enhancers.enhance=enhance +otf.enhancers.register("check extra features",enhance) +local tlig={ + [0x2013]={ 0x002D,0x002D }, + [0x2014]={ 0x002D,0x002D,0x002D }, +} +local tlig_specification={ + type="ligature", + features=everywhere, + data=tlig, + order={ "tlig" }, + flags=noflags, + prepend=true, +} +otf.addfeature("tlig",tlig_specification) +registerotffeature { + name='tlig', + description='tex ligatures', +} +local trep={ + [0x0027]=0x2019, +} +local trep_specification={ + type="substitution", + features=everywhere, + data=trep, + order={ "trep" }, + flags=noflags, + prepend=true, +} +otf.addfeature("trep",trep_specification) +registerotffeature { + name='trep', + description='tex replacements', +} +local anum_arabic={ + [0x0030]=0x0660, + [0x0031]=0x0661, + [0x0032]=0x0662, + [0x0033]=0x0663, + [0x0034]=0x0664, + [0x0035]=0x0665, + [0x0036]=0x0666, + [0x0037]=0x0667, + [0x0038]=0x0668, + [0x0039]=0x0669, +} +local anum_persian={ + [0x0030]=0x06F0, + [0x0031]=0x06F1, + [0x0032]=0x06F2, + [0x0033]=0x06F3, + [0x0034]=0x06F4, + [0x0035]=0x06F5, + [0x0036]=0x06F6, + [0x0037]=0x06F7, + [0x0038]=0x06F8, + [0x0039]=0x06F9, +} +local function valid(data) + local features=data.resources.features + if features then + for k,v in next,features do + for k,v in next,v do + if v.arab then + return true + end + end + end + end +end +local anum_specification={ + { + type="substitution", + features={ arab={ urd=true,dflt=true } }, + order={ "anum" }, + data=anum_arabic, + flags=noflags, + valid=valid, + }, + { + type="substitution", + features={ arab={ urd=true } }, + order={ "anum" }, + data=anum_persian, + flags=noflags, + valid=valid, + }, +} +otf.addfeature("anum",anum_specification) +registerotffeature { + name='anum', + description='arabic digits', +} + +end -- closure + +do -- begin closure to overcome local limits and interference + if not modules then modules={} end modules ['font-onr']={ version=1.001, comment="companion to font-ini.mkiv", diff --git a/tex/generic/context/luatex/luatex-fonts.lua b/tex/generic/context/luatex/luatex-fonts.lua index 41b95d98c..c21389c71 100644 --- a/tex/generic/context/luatex/luatex-fonts.lua +++ b/tex/generic/context/luatex/luatex-fonts.lua @@ -259,6 +259,8 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then loadmodule('font-osd.lua') loadmodule('font-ocl.lua') -- svg needs 0.97 (for fix in memstreams) + loadmodule('font-otc.lua') + -- type one code loadmodule('font-onr.lua') -- was font-afm.lua |