diff options
41 files changed, 1328 insertions, 694 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 39bd1e22b..581d6e905 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", "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" }, + ["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", "unittriangle", "fulltriangle", "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", "withshaderadius", "withshadetransform", "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 578b5c6d0..9797c5395 100644 --- a/context/data/scite/context/scite-context-data-metafun.properties +++ b/context/data/scite/context/scite-context-data-metafun.properties @@ -5,54 +5,55 @@ 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 +fulldiamond unitdiamond fullsquare unittriangle fulltriangle \ +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 withshaderadius withshadetransform 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/doc/context/documents/general/manuals/luatex.pdf b/doc/context/documents/general/manuals/luatex.pdf Binary files differindex 8c20ea3ca..c7a492ea8 100644 --- a/doc/context/documents/general/manuals/luatex.pdf +++ b/doc/context/documents/general/manuals/luatex.pdf diff --git a/doc/context/documents/general/manuals/xml-mkiv.pdf b/doc/context/documents/general/manuals/xml-mkiv.pdf Binary files differindex 932b4cbaf..c21944c72 100644 --- a/doc/context/documents/general/manuals/xml-mkiv.pdf +++ b/doc/context/documents/general/manuals/xml-mkiv.pdf diff --git a/doc/context/sources/general/manuals/luatex/luatex-math.tex b/doc/context/sources/general/manuals/luatex/luatex-math.tex index cb8d198b1..91d2420f5 100644 --- a/doc/context/sources/general/manuals/luatex/luatex-math.tex +++ b/doc/context/sources/general/manuals/luatex/luatex-math.tex @@ -603,7 +603,7 @@ correction takes place. Possible locations are \type {top}, \type {bottom}, \type {both} and \type {center}. When no location is given \type {top} is assumed. An additional parameter \type {fraction} can be specified followed by a number; a value of for -instance 1200 means that the criterium is 1.2 times the width of the nuclues. The +instance 1200 means that the criterium is 1.2 times the width of the nucleus. The fraction only applies to the stepwise selected shapes and is mostly meant for the \type {overlay} location. It also works for the other locations but then it concerns the width. diff --git a/doc/context/sources/general/manuals/luatex/luatex-nodes.tex b/doc/context/sources/general/manuals/luatex/luatex-nodes.tex index 8d32ab287..7d19d7713 100644 --- a/doc/context/sources/general/manuals/luatex/luatex-nodes.tex +++ b/doc/context/sources/general/manuals/luatex/luatex-nodes.tex @@ -532,6 +532,7 @@ into a single node type with separate subtypes for differentiation. \NC sup \NC kernel node \NC superscript \NC \NR \NC accent \NC kernel node \NC top accent \NC \NR \NC bot_accent \NC kernel node \NC bottom accent \NC \NR +\NC fraction \NC number \NC larger step criterium (divided by 1000) \NC \NR \stoptabulate \subsubsubsection{style nodes} @@ -556,9 +557,9 @@ a trailing \type {'} to signify \quote {cramped} styles. \NC scriptscript \NC node \NC list of scriptscriptsize alternatives \NC \NR \stoptabulate -A warning: never assign a node list to the display, text, script, or -scriptscript field unless you are sure its internal link structure is -correct, otherwise an error may be result. +Warning: never assign a node list to the \type {display}, \type {text}, \type +{script}, or \type {scriptscript} field unless you are sure its internal link +structure is correct, otherwise an error may be result. \subsubsubsection{radical nodes} @@ -571,11 +572,13 @@ correct, otherwise an error may be result. \NC sup \NC kernel node \NC superscript \NC \NR \NC left \NC delimiter node \NC \NC \NR \NC degree \NC kernel node \NC only set by \type {\Uroot} \NC \NR +\NC width \NC number \NC required width \NC \NR +\NC options \NC number \NC bitset of rendering options \NC \NR \stoptabulate -A warning: never assign a node list to the nucleus, sub, sup, left, or degree -field unless you are sure its internal link structure is correct, otherwise an -error may be result. +Warning: never assign a node list to the \type {nucleus}, \type {sub}, \type +{sup}, \type {left}, or \type {degree} field unless you are sure its internal +link structure is correct, otherwise an error may be result. \subsubsubsection{fraction nodes} @@ -586,11 +589,14 @@ error may be result. \NC num \NC kernel node \NC numerator \NC \NR \NC denom \NC kernel node \NC denominator \NC \NR \NC left \NC delimiter node \NC left side symbol \NC \NR -\NC right \NC delimiter node \NC right side symbol\NC \NR +\NC right \NC delimiter node \NC right side symbol \NC \NR +\NC middle \NC delimiter node \NC middle symbol \NC \NR +\NC options \NC number \NC bitset of rendering options \NC \NR \stoptabulate -A warning: never assign a node list to the num, or denom field unless you are -sure its internal link structure is correct, otherwise an error may be result. +Warning: never assign a node list to the \type {num}, or \type {denom} field +unless you are sure its internal link structure is correct, otherwise an error +may be result. \subsubsubsection{fence nodes} @@ -599,8 +605,16 @@ sure its internal link structure is correct, otherwise an error may be result. \NC subtype \NC number \NC \showsubtypes{fence} \NC \NR \NC attr \NC node \NC list of attributes \NC \NR \NC delim \NC delimiter node \NC delimiter specification \NC \NR +\NC italic \NC number \NC italic correction \NC \NR +\NC height \NC number \NC required height \NC \NR +\NC depth \NC number \NC required depth \NC \NR +\NC options \NC number \NC bitset of rendering options \NC \NR +\NC class \NC number \NC spacing related class \NC \NR \stoptabulate +Warning: some of these fields are used by the renderer and might get adapted in +the process. + \subsection{whatsit nodes} Whatsit nodes come in many subtypes that you can ask for by running diff --git a/doc/context/sources/general/manuals/luatex/luatex.tex b/doc/context/sources/general/manuals/luatex/luatex.tex index cd67f07f2..7fd436666 100644 --- a/doc/context/sources/general/manuals/luatex/luatex.tex +++ b/doc/context/sources/general/manuals/luatex/luatex.tex @@ -12,8 +12,8 @@ \dontcomplain \startdocument - [version=0.98.0, - status=Pre-release] + [version=0.98.2, + status=pre-release] \component luatex-titlepage diff --git a/doc/context/sources/general/manuals/xml/xml-mkiv.tex b/doc/context/sources/general/manuals/xml/xml-mkiv.tex index 3933c0063..caeff0ceb 100644 --- a/doc/context/sources/general/manuals/xml/xml-mkiv.tex +++ b/doc/context/sources/general/manuals/xml/xml-mkiv.tex @@ -3805,6 +3805,109 @@ typesetting often takes relatively more time than the lookup. \stopsection +\startsection[title=Finalizers] + +The \XML\ parser is also available outside \TEX. Here is an example of its usage. +We pipe the result to \TEX\ but you can do with \type {t} whatever you like. + +\startbuffer +local x = xml.load("manual-demo-1.xml") +local t = { } + +for c in xml.collected(x,"//*") do + if not c.special and not t[c.tg] then + t[c.tg] = true + end +end + +context.tocontext(table.sortedkeys(t)) +\stopbuffer + +\typebuffer + +This returns: + +\ctxluabuffer + +We can wrap this in a finalizer: + +\startbuffer +xml.finalizers.taglist = function(collected) + local t = { } + for i=1,#collected do + local c = collected[i] + if not c.special then + local tg = c.tg + if tg and not t[tg] then + t[tg] = true + end + end + end + return table.sortedkeys(t) +end +\stopbuffer + +\typebuffer + +Or in a more extensive one: + +\startbuffer +xml.finalizers.taglist = function(collected,parenttoo) + local t = { } + for i=1,#collected do + local c = collected[i] + if not c.special then + local tg = c.tg + if tg and not t[tg] then + t[tg] = true + end + if parenttoo then + local p = c.__p__ + if p and not p.special then + local tg = p.tg .. ":" .. tg + if tg and not t[tg] then + t[tg] = true + end + end + end + end + end + return table.sortedkeys(t) +end +\stopbuffer + +\typebuffer \ctxluabuffer + +Usage is as follows: + +\startbuffer +local x = xml.load("manual-demo-1.xml") +local t = xml.applylpath(x,"//*/taglist()") + +context.tocontext(t) +\stopbuffer + +\typebuffer + +And indeed we get: + +\ctxluabuffer + +But we can also say: + +\startbuffer +local x = xml.load("manual-demo-1.xml") +local t = xml.applylpath(x,"//*/taglist(true)") + +context.tocontext(t) +\stopbuffer + +\typebuffer + +Now we get: + +\ctxluabuffer + \stopchapter \stopbodymatter diff --git a/metapost/context/base/mpiv/mp-luas.mpiv b/metapost/context/base/mpiv/mp-luas.mpiv index c30798247..c7c97228e 100644 --- a/metapost/context/base/mpiv/mp-luas.mpiv +++ b/metapost/context/base/mpiv/mp-luas.mpiv @@ -97,3 +97,5 @@ enddef ; vardef MP@#(text t) = mlib_luas_lualist("MP." & str @#,t) enddef ; + +def message = lua.mp.report enddef ; diff --git a/metapost/context/base/mpiv/mp-mlib.mpiv b/metapost/context/base/mpiv/mp-mlib.mpiv index a4541ae2d..ea148d0c1 100644 --- a/metapost/context/base/mpiv/mp-mlib.mpiv +++ b/metapost/context/base/mpiv/mp-mlib.mpiv @@ -585,6 +585,7 @@ primarydef p withshademethod m = hide(mfun_with_shade_method_analyze(p)) p withprescript "sh_domain=0 1" + withprescript "sh_transform=yes" withprescript "sh_color=into" withprescript "sh_color_a=" & colordecimals white withprescript "sh_color_b=" & colordecimals black @@ -611,6 +612,16 @@ primarydef p withshademethod m = fi enddef ; +def withshaderadius expr a = + withprescript "sh_radius_a=" & decimal (xpart a) + withprescript "sh_radius_b=" & decimal (ypart a) +enddef ; + +def withshadeorigin expr a = + withprescript "sh_center_a=" & ddecimal a + withprescript "sh_center_b=" & ddecimal a +enddef ; + def withshadevector expr a = withprescript "sh_center_a=" & ddecimal (point xpart a of mfun_shade_path) withprescript "sh_center_b=" & ddecimal (point ypart a of mfun_shade_path) @@ -621,6 +632,10 @@ def withshadedirection expr a = withprescript "sh_center_b=" & ddecimal (point ypart a of boundingbox(mfun_shade_path)) enddef ; +def withshadetransform expr a = % yes | no + withprescript "sh_transform=" & a +enddef ; + pair shadedup ; shadedup := (0.5,2.5) ; pair shadeddown ; shadeddown := (2.5,0.5) ; pair shadedleft ; shadedleft := (1.5,3.5) ; @@ -690,10 +705,47 @@ def shaded text s = s enddef ; +% For me. + +primarydef p shownshadevector v = + image ( + drawarrow (point xpart v of p) -- (point ypart v of p) ; + fill fullcircle scaled 2 shifted point xpart v of p ; + setbounds currentpicture to center currentpicture -- cycle ; + ) +enddef ; + +primarydef p shownshadedirection v = + image ( + drawarrow (point xpart v of boundingbox p) -- (point ypart v of boundingbox p) ; + fill fullcircle scaled 2 shifted (point xpart v of boundingbox p) ; + setbounds currentpicture to center currentpicture -- cycle ; + ) +enddef ; + +primarydef p shownshadecenter v = + image ( + fill fullcircle scaled 2 + shifted center p shifted ( + xpart v * bbwidth (p)/2, + ypart v * bbheight(p)/2 + ) ; + setbounds currentpicture to center currentpicture -- cycle ; + ) +enddef ; + +primarydef p shownshadeorigin v = + image ( + fill fullcircle scaled 2 shifted v ; + setbounds currentpicture to center currentpicture -- cycle ; + ) +enddef ; + % Old macros: def withcircularshade (expr a, b, ra, rb, ca, cb) = withprescript "sh_type=circular" + withprescript "sh_transform=yes" withprescript "sh_domain=0 1" withprescript "sh_factor=1" withprescript "sh_color_a=" & colordecimals ca @@ -706,6 +758,7 @@ enddef ; def withlinearshade (expr a, b, ca, cb) = withprescript "sh_type=linear" + withprescript "sh_transform=yes" withprescript "sh_domain=0 1" withprescript "sh_factor=1" withprescript "sh_color_a=" & colordecimals ca @@ -1530,6 +1583,9 @@ vardef formatted(expr f, x) = textext(varfmt(f, x)) enddef ; % def strfmt = format enddef ; % old % def varfmt = formatted enddef ; % old + +def fmttext = lua.mp.formatted enddef ; + % new def fillup text t = draw t withpostscript "both" enddef ; % we use draw because we need the proper boundingbox diff --git a/metapost/context/base/mpiv/mp-tool.mpiv b/metapost/context/base/mpiv/mp-tool.mpiv index 4922d5075..220a7b6a9 100644 --- a/metapost/context/base/mpiv/mp-tool.mpiv +++ b/metapost/context/base/mpiv/mp-tool.mpiv @@ -1246,6 +1246,15 @@ vardef arrowheadonpath (expr p, s) = arrowhead p if s < 1 : cutafter (point (s*arclength(p) + (ahlength/2)) on p) fi enddef ; +def resetarrows = + hide ( + ahlength := 4 ; + ahangle := 45 ; + ahvariant := 0 ; + ahdimple := 1/5 ; + ) +enddef ; + %D Points. def drawpoint expr c = @@ -2811,4 +2820,17 @@ enddef; extra_endfig := extra_endfig & "mfun_apply_max_dimensions ;" ; +%D Bonus shapes (need along): + +path unittriangle, fulltriangle ; % not really units but circle based + +unittriangle := point 0 along unitcircle + -- point 1/3 along unitcircle + -- point 2/3 along unitcircle + -- cycle ; +fulltriangle := point 0 along fullcircle + -- point 1/3 along fullcircle + -- point 2/3 along fullcircle + -- cycle ; + let dump = relax ; diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua index 2d5ebefd2..52a1e2ca6 100644 --- a/scripts/context/lua/mtxrun.lua +++ b/scripts/context/lua/mtxrun.lua @@ -8828,7 +8828,7 @@ do -- create closure to overcome 200 locals limit package.loaded["trac-inf"] = package.loaded["trac-inf"] or true --- original size: 6996, stripped down to: 5510 +-- original size: 7055, stripped down to: 5524 if not modules then modules={} end modules ['trac-inf']={ version=1.001, @@ -8878,12 +8878,13 @@ local function stoptiming(instance) timer.timing=it-1 else local starttime=timer.starttime - if starttime then + if starttime and starttime>0 then local stoptime=clock() local loadtime=stoptime-starttime timer.stoptime=stoptime timer.loadtime=timer.loadtime+loadtime timer.timing=0 + timer.starttime=0 return loadtime end end @@ -8982,7 +8983,6 @@ function statistics.formatruntime(runtime) end function statistics.runtime() stoptiming(statistics) - stoptiming(statistics) return statistics.formatruntime(elapsedtime(statistics)) end local report=logs.reporter("system") @@ -18824,8 +18824,8 @@ end -- of closure -- used libraries : l-lua.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-mrg.lua util-tpl.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua -- skipped libraries : - --- original bytes : 799977 --- stripped bytes : 290115 +-- original bytes : 800036 +-- stripped bytes : 290160 -- end library merge diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua index 2d5ebefd2..52a1e2ca6 100644 --- a/scripts/context/stubs/mswin/mtxrun.lua +++ b/scripts/context/stubs/mswin/mtxrun.lua @@ -8828,7 +8828,7 @@ do -- create closure to overcome 200 locals limit package.loaded["trac-inf"] = package.loaded["trac-inf"] or true --- original size: 6996, stripped down to: 5510 +-- original size: 7055, stripped down to: 5524 if not modules then modules={} end modules ['trac-inf']={ version=1.001, @@ -8878,12 +8878,13 @@ local function stoptiming(instance) timer.timing=it-1 else local starttime=timer.starttime - if starttime then + if starttime and starttime>0 then local stoptime=clock() local loadtime=stoptime-starttime timer.stoptime=stoptime timer.loadtime=timer.loadtime+loadtime timer.timing=0 + timer.starttime=0 return loadtime end end @@ -8982,7 +8983,6 @@ function statistics.formatruntime(runtime) end function statistics.runtime() stoptiming(statistics) - stoptiming(statistics) return statistics.formatruntime(elapsedtime(statistics)) end local report=logs.reporter("system") @@ -18824,8 +18824,8 @@ end -- of closure -- used libraries : l-lua.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-mrg.lua util-tpl.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua -- skipped libraries : - --- original bytes : 799977 --- stripped bytes : 290115 +-- original bytes : 800036 +-- stripped bytes : 290160 -- end library merge diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun index 2d5ebefd2..52a1e2ca6 100644 --- a/scripts/context/stubs/unix/mtxrun +++ b/scripts/context/stubs/unix/mtxrun @@ -8828,7 +8828,7 @@ do -- create closure to overcome 200 locals limit package.loaded["trac-inf"] = package.loaded["trac-inf"] or true --- original size: 6996, stripped down to: 5510 +-- original size: 7055, stripped down to: 5524 if not modules then modules={} end modules ['trac-inf']={ version=1.001, @@ -8878,12 +8878,13 @@ local function stoptiming(instance) timer.timing=it-1 else local starttime=timer.starttime - if starttime then + if starttime and starttime>0 then local stoptime=clock() local loadtime=stoptime-starttime timer.stoptime=stoptime timer.loadtime=timer.loadtime+loadtime timer.timing=0 + timer.starttime=0 return loadtime end end @@ -8982,7 +8983,6 @@ function statistics.formatruntime(runtime) end function statistics.runtime() stoptiming(statistics) - stoptiming(statistics) return statistics.formatruntime(elapsedtime(statistics)) end local report=logs.reporter("system") @@ -18824,8 +18824,8 @@ end -- of closure -- used libraries : l-lua.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-mrg.lua util-tpl.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua -- skipped libraries : - --- original bytes : 799977 --- stripped bytes : 290115 +-- original bytes : 800036 +-- stripped bytes : 290160 -- end library merge diff --git a/scripts/context/stubs/win64/mtxrun.lua b/scripts/context/stubs/win64/mtxrun.lua index 2d5ebefd2..52a1e2ca6 100644 --- a/scripts/context/stubs/win64/mtxrun.lua +++ b/scripts/context/stubs/win64/mtxrun.lua @@ -8828,7 +8828,7 @@ do -- create closure to overcome 200 locals limit package.loaded["trac-inf"] = package.loaded["trac-inf"] or true --- original size: 6996, stripped down to: 5510 +-- original size: 7055, stripped down to: 5524 if not modules then modules={} end modules ['trac-inf']={ version=1.001, @@ -8878,12 +8878,13 @@ local function stoptiming(instance) timer.timing=it-1 else local starttime=timer.starttime - if starttime then + if starttime and starttime>0 then local stoptime=clock() local loadtime=stoptime-starttime timer.stoptime=stoptime timer.loadtime=timer.loadtime+loadtime timer.timing=0 + timer.starttime=0 return loadtime end end @@ -8982,7 +8983,6 @@ function statistics.formatruntime(runtime) end function statistics.runtime() stoptiming(statistics) - stoptiming(statistics) return statistics.formatruntime(elapsedtime(statistics)) end local report=logs.reporter("system") @@ -18824,8 +18824,8 @@ end -- of closure -- used libraries : l-lua.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-mrg.lua util-tpl.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua -- skipped libraries : - --- original bytes : 799977 --- stripped bytes : 290115 +-- original bytes : 800036 +-- stripped bytes : 290160 -- end library merge diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf Binary files differindex 56b86067d..c59466f1d 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 eab508e59..11508c4c1 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.08.11 13:56} +\newcontextversion{2016.08.15 22:40} %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 dd2143252..fc4b3427a 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.08.11 13:56} +\edef\contextversion{2016.08.15 22:40} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/mkiv/font-cff.lua b/tex/context/base/mkiv/font-cff.lua index 8c57b473e..8f33c76c4 100644 --- a/tex/context/base/mkiv/font-cff.lua +++ b/tex/context/base/mkiv/font-cff.lua @@ -26,6 +26,7 @@ local concat, remove = table.concat, table.remove local floor, abs, round, ceil = math.floor, math.abs, math.round, math.ceil local P, C, R, S, C, Cs, Ct = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Ct local lpegmatch = lpeg.match +local formatters = string.formatters local readers = fonts.handlers.otf.readers local streamreader = readers.streamreader @@ -594,6 +595,7 @@ do local ymax = 0 local checked = false local keepcurve = false + local version = 2 local function showstate(where) report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top) @@ -1052,13 +1054,114 @@ do end end - local function unsupported() + local function unsupported(t) if trace_charstrings then - showstate("unsupported") + showstate("unsupported " .. t) end top = 0 end + local function unsupportedsub(t) + if trace_charstrings then + showstate("unsupported sub " .. t) + end + top = 0 + end + + -- type 1 (not used in type 2) + + local function getstem3() + if trace_charstrings then + showstate("stem3") + end + top = 0 + end + + local function divide() + if version == 1 then + local d = stack[top] + top = top - 1 + stack[top] = stack[top] / d + end + end + + local function closepath() + if version == 1 then + if trace_charstrings then + showstate("closepath") + end + end + top = 0 + end + + local function hsbw() + if version == 1 then + if trace_charstrings then + showstate("dotsection") + end + width = stack[top] + end + top = 0 + end + + local function seac() + if version == 1 then + if trace_charstrings then + showstate("seac") + end + end + top = 0 + end + + local function sbw() + if version == 1 then + if trace_charstrings then + showstate("sbw") + end + width = stack[top-1] + end + top = 0 + end + + -- these are probably used for special cases i.e. call out to postscript + + local function callothersubr() + if version == 1 then + -- we don't support this (ok, we could mimick these othersubs) + if trace_charstrings then + showstate("callothersubr (unsupported)") + end + end + top = 0 + end + + local function pop() + if version == 1 then + -- we don't support this + if trace_charstrings then + showstate("pop (unsupported)") + end + top = top + 1 + stack[top] = 0 -- a dummy + else + top = 0 + end + end + + local function setcurrentpoint() + if version == 1 then + -- we don't support this + if trace_charstrings then + showstate("pop (unsupported)") + end + x = x + stack[top-1] + y = y + stack[top] + end + top = 0 + end + + -- so far for unsupported postscript + -- Bah, we cannot use a fast lpeg because a hint has an unknown size and a -- runtime capture cannot handle that well. @@ -1076,7 +1179,7 @@ do unsupported, -- 10 -- calllocal, unsupported, -- 11 -- callreturn, unsupported, -- 12 -- elsewhere - unsupported, -- 13 -- hsbw + hsbw, -- 13 -- hsbw (type 1 cff) unsupported, -- 14 -- endchar, unsupported, -- 15 unsupported, -- 16 @@ -1098,6 +1201,17 @@ do } local subactions = { + -- cff 1 + [000] = dotsection, + [001] = getstem3, + [002] = getstem3, + [006] = seac, + [007] = sbw, + [012] = divide, + [016] = callothersubr, + [017] = pop, + [033] = setcurrentpoint, + -- cff 2 [034] = hflex, [035] = flex, [036] = hflex1, @@ -1107,23 +1221,29 @@ do local p_bytes = Ct((P(1)/byte)^0) local function call(scope,list,bias,process) - local index = stack[top] + bias - top = top - 1 - if trace_charstrings then - showvalue(scope,index,true) - end - local str = list[index] - if str then - if type(str) == "string" then - str = lpegmatch(p_bytes,str) - list[index] = str - end - depth = depth + 1 - process(str) - depth = depth - 1 + depth = depth + 1 + if top == 0 then + showstate(formatters["unknown %s call"](scope)) + top = 0 else - report("unknown %s %i",scope,index) + local index = stack[top] + bias + top = top - 1 + if trace_charstrings then + showvalue(scope,index,true) + end + local tab = list[index] + if tab then + if type(tab) == "string" then + tab = lpegmatch(p_bytes,tab) + list[index] = tab + end + process(tab) + else + showstate(formatters["unknown %s call %i"](scope,index)) + top = 0 + end end + depth = depth - 1 end local function process(tab) @@ -1131,7 +1251,7 @@ do local n = #tab while i <= n do local t = tab[i] - if t >= 32 and t<=246 then + if t >= 32 and t <= 246 then -- -107 .. +107 top = top + 1 stack[top] = t - 139 @@ -1196,7 +1316,7 @@ do local t = tab[i] local a = subactions[t] if a then - a() + a(t) else if trace_charstrings then showvalue("<subaction>",t) @@ -1207,7 +1327,7 @@ do else local a = actions[t] if a then - local s = a() + local s = a(t) if s then i = i + s end @@ -1260,27 +1380,44 @@ do -- end -- end - parsecharstrings = function(data,glyphs,doshapes) + local function setbias(globals,locals) + if version == 1 then + return + false, + false + else + local g, l = #globals, #locals + return + ((g < 1240 and 107) or (g < 33900 and 1131) or 32768) + 1, + ((l < 1240 and 107) or (l < 33900 and 1131) or 32768) + 1 + end + end + + parsecharstrings = function(data,glyphs,doshapes,tversion) -- for all charstrings local dictionary = data.dictionaries[1] local charstrings = dictionary.charstrings local charset = dictionary.charset + local private = dictionary.private or { data = { } } + keepcurve = doshapes + version = tversion stack = { } glyphs = glyphs or { } strings = data.strings - locals = dictionary.subroutines - globals = data.routines - globalbias = #globals - localbias = #locals - globalbias = ((globalbias < 1240 and 107) or (globalbias < 33900 and 1131) or 32768) + 1 - localbias = ((localbias < 1240 and 107) or (localbias < 33900 and 1131) or 32768) + 1 - local nominalwidth = dictionary.private.data.nominalwidthx or 0 - local defaultwidth = dictionary.private.data.defaultwidthx or 0 + globals = data.routines or { } + locals = dictionary.subroutines or { } + + globalbias, localbias = setbias(globals,locals,version) + + local nominalwidth = private.data.nominalwidthx or 0 + local defaultwidth = private.data.defaultwidthx or 0 for i=1,#charstrings do - local str = charstrings[i] - local tab = lpegmatch(p_bytes,str) + local tab = charstrings[i] + if type(tab) == "string" then + tab = lpegmatch(p_bytes,tab) + end local index = i - 1 x = 0 y = 0 @@ -1341,20 +1478,22 @@ do return glyphs end - parsecharstring = function(data,dictionary,charstring,glyphs,index,doshapes) + parsecharstring = function(data,dictionary,tab,glyphs,index,doshapes,version) local private = dictionary.private keepcurve = doshapes strings = data.strings -- or in dict? locals = dictionary.subroutines or { } globals = data.routines or { } - globalbias = #globals - localbias = #locals - globalbias = ((globalbias < 1240 and 107) or (globalbias < 33900 and 1131) or 32768) + 1 - localbias = ((localbias < 1240 and 107) or (localbias < 33900 and 1131) or 32768) + 1 + + globalbias = setbias(globals,locals) + local nominalwidth = private and private.data.nominalwidthx or 0 local defaultwidth = private and private.data.defaultwidthx or 0 -- - local tab = lpegmatch(p_bytes,charstring) + if type(tab) == "string" then + tab = lpegmatch(p_bytes,tab) + end + -- x = 0 y = 0 width = false @@ -1384,7 +1523,8 @@ do width = nominalwidth + width end -- -index = index - 1 + index = index - 1 + -- local glyph = glyphs[index] -- can be autodefined in otr if not glyph then glyphs[index] = { @@ -1410,8 +1550,6 @@ index = index - 1 report("width: %s",tostring(width)) report("boundingbox: % t",boundingbox) end - -- - return charstring end resetcharstrings = function() @@ -1542,7 +1680,7 @@ local function readcidprivates(f,data) parseprivates(data,dictionaries) end -local function readnoselect(f,data,glyphs,doshapes) +local function readnoselect(f,data,glyphs,doshapes,version) local dictionaries = data.dictionaries local dictionary = dictionaries[1] readglobals(f,data) @@ -1552,11 +1690,13 @@ local function readnoselect(f,data,glyphs,doshapes) readprivates(f,data) parseprivates(data,data.dictionaries) readlocals(f,data,dictionary) - parsecharstrings(data,glyphs,doshapes) + parsecharstrings(data,glyphs,doshapes,version) resetcharstrings() end -local function readfdselect(f,data,glyphs,doshapes) +readers.parsecharstrings = parsecharstrings + +local function readfdselect(f,data,glyphs,doshapes,version) local header = data.header local dictionaries = data.dictionaries local dictionary = dictionaries[1] @@ -1615,7 +1755,7 @@ local function readfdselect(f,data,glyphs,doshapes) readlocals(f,data,dictionaries[i]) end for i=1,#charstrings do - parsecharstring(data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes) + parsecharstring(data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version) end resetcharstrings() end diff --git a/tex/context/base/mkiv/font-lib.mkvi b/tex/context/base/mkiv/font-lib.mkvi index 6b891542c..ed7d896c5 100644 --- a/tex/context/base/mkiv/font-lib.mkvi +++ b/tex/context/base/mkiv/font-lib.mkvi @@ -61,6 +61,10 @@ %registerctxluafile{font-afm}{1.001} \registerctxluafile{font-afk}{1.001} +% shapes + +\registerctxluafile{font-shp}{1.001} + % tfm \registerctxluafile{font-tfm}{1.001} diff --git a/tex/context/base/mkiv/font-onr.lua b/tex/context/base/mkiv/font-onr.lua index dcf7445e5..6c33b24c6 100644 --- a/tex/context/base/mkiv/font-onr.lua +++ b/tex/context/base/mkiv/font-onr.lua @@ -50,31 +50,41 @@ and <l n='otf'/> reader.</p> and new vectors (we actually had one bad vector with the old loader).</p> --ldx]]-- -local get_indexes +local get_indexes, get_shapes do - local n, m + local decrypt - local progress = function(str,position,name,size) - local forward = position + tonumber(size) + 3 + 2 - n = n + 1 - if n >= m then - return #str, name - elseif forward < #str then - return forward, name - else - return #str, name + do + + local r, c1, c2, n = 0, 0, 0, 0 + + local function step(c) + local cipher = byte(c) + local plain = bxor(cipher,rshift(r,8)) + r = ((cipher + r) * c1 + c2) % 65536 + return char(plain) end - end - local initialize = function(str,position,size) - n = 0 - m = size -- % tonumber(size) - return position + 1 + decrypt = function(binary,initial,seed) + r, c1, c2, n = initial, 52845, 22719, seed + binary = gsub(binary,".",step) + return sub(binary,n+1) + end + + -- local pattern = Cs((P(1) / step)^1) + -- + -- decrypt = function(binary,initial,seed) + -- r, c1, c2, n = initial, 52845, 22719, seed + -- binary = lpegmatch(pattern,binary) + -- return sub(binary,n+1) + -- end + end local charstrings = P("/CharStrings") + local subroutines = P("/Subrs") local encoding = P("/Encoding") local dup = P("dup") local put = P("put") @@ -85,9 +95,64 @@ do local spaces = P(" ")^1 local spacing = patterns.whitespace^0 + local routines, vector, chars, n, m + + local initialize = function(str,position,size) + n = 0 + m = size -- % tonumber(size) + return position + 1 + end + + local setroutine = function(str,position,index,size) + local forward = position + tonumber(size) + local stream = sub(str,position+1,forward) + routines[index] = decrypt(stream,4330,4) + return forward + end + + local setvector = function(str,position,name,size) + local forward = position + tonumber(size) + if n >= m then + return #str + elseif forward < #str then + vector[n] = name + n = n + 1 -- we compensate for notdef at the cff loader end + return forward + else + return #str + end + end + + local setshapes = function(str,position,name,size) + local forward = position + tonumber(size) + local stream = sub(str,position+1,forward) + if n > m then + return #str + elseif forward < #str then + vector[n] = name + n = n + 1 + chars [n] = decrypt(stream,4330,4) + return forward + else + return #str + end + end + + local p_rd = spacing * (P("RD") + P("-|")) + local p_np = spacing * (P("NP") + P( "|")) + local p_nd = spacing * (P("ND") + P( "|")) + + local p_filterroutines = -- dup <i> <n> RD or -| <n encrypted bytes> NP or | + (1-subroutines)^0 * subroutines * spaces * Cmt(cardinal,initialize) + * (Cmt(cardinal * spaces * cardinal * p_rd, setroutine) * p_np + P(1))^1 + + local p_filtershapes = -- /foo <n> RD <n encrypted bytes> ND + (1-charstrings)^0 * charstrings * spaces * Cmt(cardinal,initialize) + * (Cmt(name * spaces * cardinal * p_rd, setshapes) * p_nd + P(1))^1 + local p_filternames = Ct ( (1-charstrings)^0 * charstrings * spaces * Cmt(cardinal,initialize) - * (Cmt(name * spaces * cardinal, progress) + P(1))^1 + * (Cmt(name * spaces * cardinal, setvector) + P(1))^1 ) -- /Encoding 256 array @@ -102,36 +167,7 @@ do -- if one of first 4 not 0-9A-F then binary else hex - local decrypt - - do - - local r, c1, c2, n = 0, 0, 0, 0 - - local function step(c) - local cipher = byte(c) - local plain = bxor(cipher,rshift(r,8)) - r = ((cipher + r) * c1 + c2) % 65536 - return char(plain) - end - - decrypt = function(binary) - r, c1, c2, n = 55665, 52845, 22719, 4 - binary = gsub(binary,".",step) - return sub(binary,n+1) - end - - -- local pattern = Cs((P(1) / step)^1) - -- - -- decrypt = function(binary) - -- r, c1, c2, n = 55665, 52845, 22719, 4 - -- binary = lpegmatch(pattern,binary) - -- return sub(binary,n+1) - -- end - - end - - local function loadpfbvector(filename) + local function loadpfbvector(filename,shapestoo) -- for the moment limited to encoding only local data = io.loaddata(resolvers.findfile(filename)) @@ -153,28 +189,36 @@ do return end - binary = decrypt(binary,4) + binary = decrypt(binary,55665,4) - local vector = lpegmatch(p_filternames,binary) - --- if vector[1] == ".notdef" then --- -- tricky --- vector[0] = table.remove(vector,1) --- end - - for i=1,#vector do - vector[i-1] = vector[i] + local names = { } + local encoding = lpegmatch(p_filterencoding,ascii) + local glyphs = { } + + routines, vector, chars = { }, { }, { } + + if shapestoo then + lpegmatch(p_filterroutines,binary) + lpegmatch(p_filtershapes,binary) + local data = { + dictionaries = { + { + charstrings = chars, + charset = vector, + subroutines = routines, + } + }, + } + fonts.handlers.otf.readers.parsecharstrings(data,glyphs,true,true) + else + lpegmatch(p_filternames,binary) end - vector[#vector] = nil - if not vector then - report_pfb("no vector in %a",filename) - return - end + names = vector - local encoding = lpegmatch(p_filterencoding,ascii) + routines, vector, chars = nil, nil, nil - return vector, encoding + return names, encoding, glyphs end @@ -202,6 +246,11 @@ do end end + get_shapes = function(pfbname) + local vector, encoding, glyphs = loadpfbvector(pfbname,true) + return glyphs + end + end --[[ldx-- @@ -428,6 +477,26 @@ function readers.loadfont(afmname,pfbname) end end +-- for now, todo: n and check with otf (no afm needed here) + +function readers.loadshapes(filename) + local fullname = resolvers.findfile(filename) or "" + if fullname == "" then + return { + filename = "not found: " .. filename, + glyphs = { } + } + else + return { + filename = fullname, + format = "opentype", + glyphs = get_shapes(fullname) or { }, + units = 1000, + } + end +end + + function readers.getinfo(filename) local data = read(resolvers.findfile(filename),infoparser) if data then diff --git a/tex/context/base/mkiv/font-otr.lua b/tex/context/base/mkiv/font-otr.lua index 7c81285c1..9cdbc3df0 100644 --- a/tex/context/base/mkiv/font-otr.lua +++ b/tex/context/base/mkiv/font-otr.lua @@ -1747,118 +1747,6 @@ function readers.math(f,fontdata,specification) end end --- Goodie. A sequence instead of segments costs a bit more memory, some 300K on a --- dejavu serif and about the same on a pagella regular. - -local function packoutlines(data,makesequence) - local subfonts = data.subfonts - if subfonts then - for i=1,#subfonts do - packoutlines(subfonts[i],makesequence) - end - return - end - local common = data.segments - if common then - return - end - local glyphs = data.glyphs - if not glyphs then - return - end - if makesequence then - for index=1,#glyphs do - local glyph = glyphs[index] - local segments = glyph.segments - if segments then - local sequence = { } - local nofsequence = 0 - for i=1,#segments do - local segment = segments[i] - local nofsegment = #segment - nofsequence = nofsequence + 1 - sequence[nofsequence] = segment[nofsegment] - for i=1,nofsegment-1 do - nofsequence = nofsequence + 1 - sequence[nofsequence] = segment[i] - end - end - glyph.sequence = sequence - glyph.segments = nil - end - end - else - local hash = { } - local common = { } - local reverse = { } - local last = 0 - for index=1,#glyphs do - local segments = glyphs[index].segments - if segments then - for i=1,#segments do - local h = concat(segments[i]," ") - hash[h] = (hash[h] or 0) + 1 - end - end - end - for index=1,#glyphs do - local segments = glyphs[index].segments - if segments then - for i=1,#segments do - local segment = segments[i] - local h = concat(segment," ") - if hash[h] > 1 then -- minimal one shared in order to hash - local idx = reverse[h] - if not idx then - last = last + 1 - reverse[h] = last - common[last] = segment - idx = last - end - segments[i] = idx - end - end - end - end - if last > 0 then - data.segments = common - end - end -end - -local function unpackoutlines(data) - local subfonts = data.subfonts - if subfonts then - for i=1,#subfonts do - unpackoutlines(subfonts[i]) - end - return - end - local common = data.segments - if not common then - return - end - local glyphs = data.glyphs - if not glyphs then - return - end - for index=1,#glyphs do - local segments = glyphs[index].segments - if segments then - for i=1,#segments do - local c = common[segments[i]] - if c then - segments[i] = c - end - end - end - end - data.segments = nil -end - -otf.packoutlines = packoutlines -otf.unpackoutlines = unpackoutlines - -- Now comes the loader. The order of reading these matters as we need to know -- some properties in order to read following tables. When details is true we also -- initialize the glyphs data. @@ -2152,6 +2040,15 @@ function readers.loadshapes(filename,n) shapes = true, subfont = n, } + if fontdata then + -- easier on luajit but still we can hit the 64 K stack constants issue + for k, v in next, fontdata.glyphs do + v.class = nil + v.index = nil + v.math = nil + -- v.name = nil + end + end return fontdata and { -- version = 0.123 -- todo filename = filename, @@ -2302,63 +2199,3 @@ function readers.extend(fontdata) end end end - --- for now .. this will move to a context specific file - -if fonts.hashes then - - local identifiers = fonts.hashes.identifiers - local loadshapes = readers.loadshapes - - readers.version = 0.006 - readers.cache = containers.define("fonts", "shapes", readers.version, true) - - -- todo: loaders per format - - local function load(filename,sub) - local base = file.basename(filename) - local name = file.removesuffix(base) - local kind = file.suffix(filename) - local attr = lfs.attributes(filename) - local size = attr and attr.size or 0 - local time = attr and attr.modification or 0 - local sub = tonumber(sub) - if size > 0 and (kind == "otf" or kind == "ttf" or kind == "tcc") then - local hash = containers.cleanname(base) -- including suffix - if sub then - hash = hash .. "-" .. sub - end - data = containers.read(readers.cache,hash) - if not data or data.time ~= time or data.size ~= size then - data = loadshapes(filename,sub) - if data then - data.size = size - data.format = data.format or (kind == "otf" and "opentype") or "truetype" - data.time = time - packoutlines(data) - containers.write(readers.cache,hash,data) - data = containers.read(readers.cache,hash) -- frees old mem - end - end - unpackoutlines(data) - else - data = { - filename = filename, - size = 0, - time = time, - format = "unknown", - units = 1000, - glyphs = { } - } - end - return data - end - - fonts.hashes.shapes = table.setmetatableindex(function(t,k) - local d = identifiers[k] - local v = load(d.properties.filename,d.subindex) - t[k] = v - return v - end) - -end diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua index d37115603..8443a383d 100644 --- a/tex/context/base/mkiv/font-ots.lua +++ b/tex/context/base/mkiv/font-ots.lua @@ -3665,7 +3665,7 @@ if fontfeatures then function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr) local features = fontfeatures[font] - local enabled = features.spacekern == true and features.kern == true + local enabled = features and features.spacekern and features.kern if enabled then setspacekerns(font,sequence) end @@ -3677,7 +3677,7 @@ else -- generic (no hashes) function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr) local shared = fontdata[font].shared local features = shared and shared.features - local enabled = features and features.spacekern == true and features.kern == true + local enabled = features and features.spacekern and features.kern if enabled then setspacekerns(font,sequence) end @@ -3739,7 +3739,7 @@ local function spaceinitializer(tfmdata,value) -- attr if kern then if feat then for script, languages in next, kern do - local f = feat[k] + local f = feat[script] if f then for l in next, languages do f[l] = true @@ -3759,7 +3759,7 @@ local function spaceinitializer(tfmdata,value) -- attr if kerns then for k, v in next, kerns do if type(v) == "table" then - right[k] = v[3] -- needs checking + right[k] = v[1][3] else right[k] = v end @@ -3769,7 +3769,7 @@ local function spaceinitializer(tfmdata,value) -- attr local kern = v[32] if kern then if type(kern) == "table" then - left[k] = kern[3] -- needs checking + left[k] = kern[1][3] else left[k] = kern end diff --git a/tex/context/base/mkiv/font-shp.lua b/tex/context/base/mkiv/font-shp.lua new file mode 100644 index 000000000..92ff70127 --- /dev/null +++ b/tex/context/base/mkiv/font-shp.lua @@ -0,0 +1,193 @@ +if not modules then modules = { } end modules ['font-shp'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local concat = table.concat +local load, tonumber = load, tonumber + +local otf = fonts.handlers.otf +local afm = fonts.handlers.afm + +local hashes = fonts.hashes +local identifiers = hashes.identifiers + +local version = 0.006 +local cache = containers.define("fonts", "shapes", version, true) + +-- shapes (can be come a separate file at some point) + +local function packoutlines(data,makesequence) + local subfonts = data.subfonts + if subfonts then + for i=1,#subfonts do + packoutlines(subfonts[i],makesequence) + end + return + end + local common = data.segments + if common then + return + end + local glyphs = data.glyphs + if not glyphs then + return + end + if makesequence then + for index=1,#glyphs do + local glyph = glyphs[index] + local segments = glyph.segments + if segments then + local sequence = { } + local nofsequence = 0 + for i=1,#segments do + local segment = segments[i] + local nofsegment = #segment + nofsequence = nofsequence + 1 + sequence[nofsequence] = segment[nofsegment] + for i=1,nofsegment-1 do + nofsequence = nofsequence + 1 + sequence[nofsequence] = segment[i] + end + end + glyph.sequence = sequence + glyph.segments = nil + end + end + else + local hash = { } + local common = { } + local reverse = { } + local last = 0 + for index=1,#glyphs do + local segments = glyphs[index].segments + if segments then + for i=1,#segments do + local h = concat(segments[i]," ") + hash[h] = (hash[h] or 0) + 1 + end + end + end + for index=1,#glyphs do + local segments = glyphs[index].segments + if segments then + for i=1,#segments do + local segment = segments[i] + local h = concat(segment," ") + if hash[h] > 1 then -- minimal one shared in order to hash + local idx = reverse[h] + if not idx then + last = last + 1 + reverse[h] = last + common[last] = segment + idx = last + end + segments[i] = idx + end + end + end + end + if last > 0 then + data.segments = common + end + end +end + +local function unpackoutlines(data) + local subfonts = data.subfonts + if subfonts then + for i=1,#subfonts do + unpackoutlines(subfonts[i]) + end + return + end + local common = data.segments + if not common then + return + end + local glyphs = data.glyphs + if not glyphs then + return + end + for index=1,#glyphs do + local segments = glyphs[index].segments + if segments then + for i=1,#segments do + local c = common[segments[i]] + if c then + segments[i] = c + end + end + end + end + data.segments = nil +end + +-- todo: loaders per format + +local function load(filename,sub) + local base = file.basename(filename) + local name = file.removesuffix(base) + local kind = file.suffix(filename) + local attr = lfs.attributes(filename) + local size = attr and attr.size or 0 + local time = attr and attr.modification or 0 + local sub = tonumber(sub) + + -- fonts.formats + + if size > 0 and (kind == "otf" or kind == "ttf" or kind == "tcc") then + local hash = containers.cleanname(base) -- including suffix + if sub then + hash = hash .. "-" .. sub + end + data = containers.read(cache,hash) + if not data or data.time ~= time or data.size ~= size then + data = otf.readers.loadshapes(filename,sub) + if data then + data.size = size + data.format = data.format or (kind == "otf" and "opentype") or "truetype" + data.time = time + packoutlines(data) + containers.write(cache,hash,data) + data = containers.read(cache,hash) -- frees old mem + end + end + unpackoutlines(data) + elseif size > 0 and (kind == "pfb") then + local hash = containers.cleanname(base) -- including suffix + data = containers.read(cache,hash) + if not data or data.time ~= time or data.size ~= size then + data = afm.readers.loadshapes(filename) + if data then + data.size = size + data.format = "type1" + data.time = time + packoutlines(data) + containers.write(cache,hash,data) + data = containers.read(cache,hash) -- frees old mem + end + end + unpackoutlines(data) + else + data = { + filename = filename, + size = 0, + time = time, + format = "unknown", + units = 1000, + glyphs = { } + } + end + return data +end + +hashes.shapes = table.setmetatableindex(function(t,k) + local d = identifiers[k] + local v = load(d.properties.filename,d.subindex) + t[k] = v + return v +end) diff --git a/tex/context/base/mkiv/luat-mac.lua b/tex/context/base/mkiv/luat-mac.lua index 4274fe9f9..3f1fe6751 100644 --- a/tex/context/base/mkiv/luat-mac.lua +++ b/tex/context/base/mkiv/luat-mac.lua @@ -145,9 +145,8 @@ local grammar = { "converter", * stopcode * poplocal, texbody = ( -leadingcomment -- new per 2015-03-03 (ugly) -+ - V("definition") + leadingcomment -- new per 2015-03-03 (ugly) + + V("definition") + identifier + V("braced") + (1 - stopcode) diff --git a/tex/context/base/mkiv/math-map.lua b/tex/context/base/mkiv/math-map.lua index 4eb76ac8c..cf9353e95 100644 --- a/tex/context/base/mkiv/math-map.lua +++ b/tex/context/base/mkiv/math-map.lua @@ -34,7 +34,7 @@ if not modules then modules = { } end modules ['math-map'] = { local type, next = type, next local floor, div = math.floor, math.div -local merged = table.merged +local merged, sortedhash = table.merged, table.sortedhash local extract = bit32.extract local allocate = utilities.storage.allocate @@ -557,10 +557,10 @@ mathematics.mapremap = mathremap local boldmap = allocate { } mathematics.boldmap = boldmap --- all math (a bit of redundancy here) +-- all math (a bit of redundancy here) (sorted for tracing) -for alphabet, styles in next, alphabets do -- per 9/6/2011 we also have attr for missing - for style, data in next, styles do +for alphabet, styles in sortedhash(alphabets) do -- per 9/6/2011 we also have attr for missing + for style, data in sortedhash(styles) do -- let's keep the long names (for tracing) local n = #mathremap + 1 local d = { diff --git a/tex/context/base/mkiv/meta-imp-outlines.mkiv b/tex/context/base/mkiv/meta-imp-outlines.mkiv index ab6fcdd3d..199dadb32 100644 --- a/tex/context/base/mkiv/meta-imp-outlines.mkiv +++ b/tex/context/base/mkiv/meta-imp-outlines.mkiv @@ -54,7 +54,7 @@ function metapost.showglyph(specification) local fontid = font.current() local shapedata = fonts.hashes.shapes[fontid] -- by index local chardata = fonts.hashes.characters[fontid] -- by unicode - local shapeglyphs = shapedata.glyphs + local shapeglyphs = shapedata.glyphs or { } local character = validstring(specification.character) local index = validstring(specification.index) local alternative = validstring(specification.alternative) @@ -181,6 +181,8 @@ end \usemodule[art-01] +% \definedfont[lt55476.afm] + \startcombination[3*1] {\ruledhbox{\startMPcode draw textext("\showshape[character=a]") ; \stopMPcode}} {} {\ruledhbox{\startMPcode draw textext("\showshape[character=x]") ; \stopMPcode}} {} diff --git a/tex/context/base/mkiv/meta-tex.lua b/tex/context/base/mkiv/meta-tex.lua index 1008e45c0..9c5a2186d 100644 --- a/tex/context/base/mkiv/meta-tex.lua +++ b/tex/context/base/mkiv/meta-tex.lua @@ -187,9 +187,9 @@ function mp.format(fmt,str) mpprint(f_textext(formatters[fmt](metapost.untagvariable(str,false)))) end -function mp.formatted(fmt,num) -- svformat +function mp.formatted(fmt,...) -- svformat fmt = lpegmatch(cleaner,fmt) - mpprint(f_textext(formatters[fmt](tonumber(num) or num))) + mpprint(f_textext(formatters[fmt](...))) end function mp.graphformat(fmt,num) -- nvformat diff --git a/tex/context/base/mkiv/mlib-lua.lua b/tex/context/base/mkiv/mlib-lua.lua index 7b2c67220..93ae74244 100644 --- a/tex/context/base/mkiv/mlib-lua.lua +++ b/tex/context/base/mkiv/mlib-lua.lua @@ -412,7 +412,6 @@ function mp.tb_dimensions(category,name) mptriplet(w/factor,h/factor,d/factor) end - function mp.report(a,b) if b then report_message("%s : %s",a,b) diff --git a/tex/context/base/mkiv/mlib-pps.lua b/tex/context/base/mkiv/mlib-pps.lua index f72061372..8d200ac63 100644 --- a/tex/context/base/mkiv/mlib-pps.lua +++ b/tex/context/base/mkiv/mlib-pps.lua @@ -1160,16 +1160,17 @@ local function sh_process(object,prescript,before,after) local sh_type = prescript.sh_type if sh_type then nofshades = nofshades + 1 - local domain = lpegmatch(domainsplitter,prescript.sh_domain or "0 1") - local centera = lpegmatch(centersplitter,prescript.sh_center_a or "0 0") - local centerb = lpegmatch(centersplitter,prescript.sh_center_b or "0 0") + local domain = lpegmatch(domainsplitter,prescript.sh_domain or "0 1") + local centera = lpegmatch(centersplitter,prescript.sh_center_a or "0 0") + local centerb = lpegmatch(centersplitter,prescript.sh_center_b or "0 0") + local transform = toboolean(prescript.sh_transform or "yes",true) -- compensation for scaling local sx = 1 local sy = 1 local sr = 1 local dx = 0 local dy = 0 - if true then + if transform then local first = lpegmatch(coordinatesplitter,prescript.sh_first or "0 0") local setx = lpegmatch(coordinatesplitter,prescript.sh_set_x or "0 0") local sety = lpegmatch(coordinatesplitter,prescript.sh_set_y or "0 0") diff --git a/tex/context/base/mkiv/mtx-context-xml.tex b/tex/context/base/mkiv/mtx-context-xml.tex index 8e4d229f5..f8bfeef3a 100644 --- a/tex/context/base/mkiv/mtx-context-xml.tex +++ b/tex/context/base/mkiv/mtx-context-xml.tex @@ -18,12 +18,14 @@ % usage: context --extra=xml [options] list-of-files % % --analyze : show elements and characters +% --template : also export template % --topspace=dimension : distance above first line % --backspace=dimension : distance before left margin % --bodyfont=list : additional bodyfont settings % --paperformat=spec : paper*print or paperxprint % % context --extra=xml --analyze path::i-context.xml +% context --extra=xml --analyze --template path::i-context.xml % context --extra=xml --analyze selfautoparent:texmf-context/tex/context/interface/mkiv/i-*.xml % end help @@ -52,8 +54,10 @@ \starttext \startluacode - local files = document.files - local pattern = document.arguments.pattern or (#files == 1 and files[1]) + local files = document.files + local pattern = document.arguments.pattern or (#files == 1 and files[1]) + local analyze = document.arguments.analyze + local template = document.arguments.template if pattern then files = dir.glob(pattern) @@ -63,12 +67,15 @@ end if #files > 0 then - if document.arguments.analyze then - moduledata.xml.analyzers.structure (files) + if analyze then + moduledata.xml.analyzers.structure(files) context.page() moduledata.xml.analyzers.characters(files) context.page() moduledata.xml.analyzers.entities(files) + if template then + moduledata.xml.analyzers.allsetups(files,type(template) == "string" and template or nil) + end else context("no action given") end diff --git a/tex/context/base/mkiv/mult-fun.lua b/tex/context/base/mkiv/mult-fun.lua index c6d321949..5996b9ac6 100644 --- a/tex/context/base/mkiv/mult-fun.lua +++ b/tex/context/base/mkiv/mult-fun.lua @@ -24,7 +24,7 @@ return { "invsin", "invcos", "invtan", "acosh", "asinh", "sinh", "cosh", "zmod", "paired", "tripled", - "unitcircle", "fulldiamond", "unitdiamond", "fullsquare", + "unitcircle", "fulldiamond", "unitdiamond", "fullsquare", "unittriangle", "fulltriangle", -- "halfcircle", "quartercircle", "llcircle", "lrcircle", "urcircle", "ulcircle", "tcircle", "bcircle", "lcircle", "rcircle", @@ -45,8 +45,10 @@ return { "withshade", "withcircularshade", "withlinearshade", -- old but kept "defineshade", "shaded", -- "withshading", "withlinearshading", "withcircularshading", "withfromshadecolor", "withtoshadecolor", - "shadedinto", "withshadecolors", "withshadedomain", "withshademethod", "withshadefactor", "withshadevector", - "withshadecenter", "withshadedirection", "withshadestep", "withshadefraction", + "shadedinto", "withshadecolors", + "withshadedomain", "withshademethod", "withshadefactor", "withshadevector", + "withshadecenter", "withshadedirection", "withshaderadius", "withshadetransform", + "withshadestep", "withshadefraction", "cmyk", "spotcolor", "multitonecolor", "namedcolor", "drawfill", "undrawfill", "inverted", "uncolored", "softened", "grayed", "greyed", diff --git a/tex/context/base/mkiv/node-ini.lua b/tex/context/base/mkiv/node-ini.lua index f8720f717..1a9d141f4 100644 --- a/tex/context/base/mkiv/node-ini.lua +++ b/tex/context/base/mkiv/node-ini.lua @@ -248,6 +248,7 @@ local accentcodes = mark(getsubtypes("accent")) -- [1] = "left", -- [2] = "middle", -- [3] = "right", +-- [4] = "no", -- } local fencecodes = mark(getsubtypes("fence")) @@ -274,6 +275,18 @@ local usercodes = allocate { [116] = "tokens" -- t } +local noadoptions = allocate { + set = 0x08, + unused_1 = 0x00 + 0x08, + unused_2 = 0x01 + 0x08, + axis = 0x02 + 0x08, + no_axis = 0x04 + 0x08, + exact = 0x10 + 0x08, + left = 0x11 + 0x08, + middle = 0x12 + 0x08, + right = 0x14 + 0x08, +} + skipcodes = allocate(swapped(skipcodes,skipcodes)) boundarycodes = allocate(swapped(boundarycodes,boundarycodes)) noadcodes = allocate(swapped(noadcodes,noadcodes)) @@ -293,6 +306,7 @@ fencecodes = allocate(swapped(fencecodes,fencecodes)) rulecodes = allocate(swapped(rulecodes,rulecodes)) leadercodes = allocate(swapped(leadercodes,leadercodes)) usercodes = allocate(swapped(usercodes,usercodes)) +noadoptions = allocate(swapped(noadoptions,noadoptions)) nodes.skipcodes = skipcodes nodes.boundarycodes = boundarycodes @@ -313,6 +327,7 @@ nodes.fencecodes = fencecodes nodes.rulecodes = rulecodes nodes.leadercodes = leadercodes nodes.usercodes = usercodes +nodes.noadoptions = noadoptions nodes.gluecodes = skipcodes -- more official nodes.whatsitcodes = whatcodes -- more official @@ -327,25 +342,38 @@ kerncodes.kerning = kerncodes.fontkern kerncodes.italiccorrection = kerncodes.italiccorrection or 1 -- new nodes.codes = allocate { -- mostly for listing - glue = skipcodes, - boundary = boundarycodes, - noad = noadcodes, - node = nodecodes, - hlist = listcodes, - vlist = listcodes, - glyph = glyphcodes, - kern = kerncodes, - penalty = penaltycodes, - math = mathnodes, - fill = fillcodes, - margin = margincodes, - disc = disccodes, - whatsit = whatcodes, - accent = accentcodes, - fence = fencecodes, - rule = rulecodes, - leader = leadercodes, - user = usercodes, + glue = skipcodes, + boundary = boundarycodes, + noad = noadcodes, + node = nodecodes, + hlist = listcodes, + vlist = listcodes, + glyph = glyphcodes, + kern = kerncodes, + penalty = penaltycodes, + math = mathnodes, + fill = fillcodes, + margin = margincodes, + disc = disccodes, + whatsit = whatcodes, + accent = accentcodes, + fence = fencecodes, + rule = rulecodes, + leader = leadercodes, + user = usercodes, + noadoptions = noadoptions, +} + +nodes.noadoptions = { + set = 0x08, + unused_1 = 0x00 + 0x08, + unused_2 = 0x01 + 0x08, + axis = 0x02 + 0x08, + no_axis = 0x04 + 0x08, + exact = 0x10 + 0x08, + left = 0x11 + 0x08, + middle = 0x12 + 0x08, + right = 0x14 + 0x08, } local report_codes = logs.reporter("nodes","codes") diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex 3192f32d8..10ad1bcfd 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 4dc611165..05f1666a9 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/base/mkiv/trac-inf.lua b/tex/context/base/mkiv/trac-inf.lua index a1d7fb0a0..12a4f646f 100644 --- a/tex/context/base/mkiv/trac-inf.lua +++ b/tex/context/base/mkiv/trac-inf.lua @@ -61,12 +61,13 @@ local function stoptiming(instance) timer.timing = it - 1 else local starttime = timer.starttime - if starttime then - local stoptime = clock() - local loadtime = stoptime - starttime - timer.stoptime = stoptime - timer.loadtime = timer.loadtime + loadtime - timer.timing = 0 + if starttime and starttime > 0 then + local stoptime = clock() + local loadtime = stoptime - starttime + timer.stoptime = stoptime + timer.loadtime = timer.loadtime + loadtime + timer.timing = 0 + timer.starttime = 0 return loadtime end end @@ -183,7 +184,7 @@ end function statistics.runtime() stoptiming(statistics) - stoptiming(statistics) -- somehow we can start the timer twice, but where + -- stoptiming(statistics) -- somehow we can start the timer twice, but where return statistics.formatruntime(elapsedtime(statistics)) end diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf Binary files differindex 7a04caa92..6f9fc8a56 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 21a81dd2a..621a2513b 100644 --- a/tex/context/interface/mkiv/i-readme.pdf +++ b/tex/context/interface/mkiv/i-readme.pdf diff --git a/tex/context/modules/mkiv/s-xml-analyzers.lua b/tex/context/modules/mkiv/s-xml-analyzers.lua index 99f6a1cdf..6e7f7f2ba 100644 --- a/tex/context/modules/mkiv/s-xml-analyzers.lua +++ b/tex/context/modules/mkiv/s-xml-analyzers.lua @@ -11,6 +11,8 @@ moduledata.xml.analyzers = moduledata.xml.analyzers or { } local next, type = next, type local utfvalues = string.utfvalues +local formatters = string.formatters +local setmetatableindex = table.setmetatableindex local context = context local NC, NR, HL, FL, LL, SL, TB = context.NC, context.NR, context.HL, context.TB, context.FL, context.LL, context.SL local sortedhash, sortedkeys, concat, sequenced = table.sortedhash, table.sortedkeys, table.concat, table.sequenced @@ -43,28 +45,29 @@ local function analyze(filename) attr = { } ents = { } - table.setmetatableindex(tags,function(t,k) + local function att(t,k) + local v = setmetatableindex("number") + t[k] = v + return v + end + + local function add(t,k) local v = { n = 0, - attributes = { }, - children = { }, + attributes = setmetatableindex(att), + children = setmetatableindex(add), } t[k] = v return v - end) + end - table.setmetatableindex(char,function(t,k) - t[k] = 0 - return 0 - end) + setmetatableindex(tags,add) - table.setmetatableindex(attr,function(t,k) - char[k] = char[k] or 0 - t[k] = 0 - return 0 - end) + setmetatableindex(ents,"number") + setmetatableindex(char,"number") - table.setmetatableindex(ents,function(t,k) + setmetatableindex(attr,function(t,k) + char[k] = char[k] or 0 t[k] = 0 return 0 end) @@ -85,24 +88,25 @@ local function analyze(filename) local tg = e.tg local tag = tags[tg] tag.n = tag.n + 1 + local children = parent and tags[parent].children[tg] + local childatt = children and children.attributes + if children then + children.n = children.n + 1 + end if at then local attributes = tag.attributes for k, v in next, at do local a = attributes[k] - if a then - a[v] = (a[v] or 0) + 1 - else - attributes[k] = { [v] = 1 } + a[v] = a[v] + 1 + if childatt then + local a = childatt[k] + a[v] = a[v] + 1 end for s in utfvalues(v) do attr[s] = attr[s] + 1 end end end - if parent then - local children = tags[parent].children - children[tg] = (children[tg] or 0) + 1 - end if dt then for i=1,#dt do local d = dt[i] @@ -132,10 +136,10 @@ local function analyze(filename) end end - table.setmetatableindex(tags,nil) - table.setmetatableindex(char,nil) - table.setmetatableindex(attr,nil) - table.setmetatableindex(ents,nil) + setmetatableindex(tags,nil) + setmetatableindex(char,nil) + setmetatableindex(attr,nil) + setmetatableindex(ents,nil) end @@ -157,7 +161,11 @@ function moduledata.xml.analyzers.structure(filename) NC() context.bold("element") NC() context.darkred(name) NC() NR() NC() context.bold("frequency") NC() context(data.n) NC() NR() if next(children) then - NC() context.bold("children") NC() context.puretext(sequenced(children)) NC() NR() + local t = { } + for k, v in next, children do + t[k] = v.n + end + NC() context.bold("children") NC() context.puretext(sequenced(t)) NC() NR() end if next(attributes) then NC() context.bold("attributes") NC() context.puretext.darkgreen(concat(sortedkeys(attributes)," ")) NC() NR() @@ -198,3 +206,122 @@ function moduledata.xml.analyzers.entities(filename) end context.stoptabulate() end + +local f_parent_s = formatters["xml:%s"] +local f_parent_n = formatters["\\startxmlsetups xml:%s\n \\xmlflush{#1}\n\\stopxmlsetups"] +local f_parent_a = formatters["\\startxmlsetups xml:%s\n %% @ % t\n \\xmlflush{#1}\n\\stopxmlsetups"] +local f_child_s = formatters["xml:%s:%s"] +local f_child_n = formatters["\\startxmlsetups xml:%s:%s\n \\xmlflush{#1}\n\\stopxmlsetups"] +local f_child_a = formatters["\\startxmlsetups xml:%s:%s\n %% @ % t\n \\xmlflush{#1}\n\\stopxmlsetups"] + +local f_template = formatters [ [[ +%% file: %s + +%% Beware, these are all (first level) setups. If you have a complex document +%% it often makes sense to use \\xmlfilter or similar local filter options. + +%% presets + +\startxmlsetup xml:presets:all + \xmlsetsetups {#1} { + %s + } +\stopxmlsetups + +%% setups + +%s +]] ] + +function moduledata.xml.analyzers.allsetups(filename,usedname) + analyze(filename) + local result = { } + local setups = { } + for name, data in table.sortedhash(tags) do + local children = data.children + local attributes = data.attributes + if next(attributes) then + result[#result+1] = f_parent_a(name,sortedkeys(attributes)) + else + result[#result+1] = f_parent_n(name) + end + setups[#setups+1] = f_parent_s(name) + if next(children) then + for k, v in sortedhash(children) do + local attributes = v.attributes + if next(attributes) then + result[#result+1] = f_child_a(name,k,sortedkeys(attributes)) + else + result[#result+1] = f_child_n(name,k) + end + setups[#setups+1] = f_child_s(name,k) + end + end + end + table.sort(setups) + -- + if type(filename) == "table" then + filename = concat(filename," | ") + end + -- + usedname = usedname or "xml-analyze-template.tex" + -- + io.savedata(usedname,f_template(filename,concat(setups,"|\n "),concat(result,"\n\n"))) + logs.report("xml analyze","presets saved in: %s",usedname) +end + +-- example: + +-- local t = { } +-- local x = xml.load("music-collection.xml") +-- for c in xml.collected(x,"//*") do +-- if not c.special and not t[c.tg] then +-- t[c.tg] = true +-- end +-- end +-- inspect(table.sortedkeys(t)) + +-- xml.finalizers.taglist = function(collected) +-- local t = { } +-- for i=1,#collected do +-- local c = collected[i] +-- if not c.special then +-- local tg = c.tg +-- if tg and not t[tg] then +-- t[tg] = true +-- end +-- end +-- end +-- return t +-- end +-- local x = xml.load("music-collection.xml") +-- inspect(table.sortedkeys(xml.applylpath(x,"//*/taglist()"))) + +-- xml.finalizers.taglist = function(collected,parenttoo) +-- local t = { } +-- for i=1,#collected do +-- local c = collected[i] +-- if not c.special then +-- local tg = c.tg +-- if tg and not t[tg] then +-- t[tg] = true +-- end +-- if parenttoo then +-- local p = c.__p__ +-- if p and not p.special then +-- local tg = p.tg .. ":" .. tg +-- if tg and not t[tg] then +-- t[tg] = true +-- end +-- end +-- end +-- end +-- end +-- return t +-- end + +-- local x = xml.load("music-collection.xml") +-- inspect(table.sortedkeys(xml.applylpath(x,"//*/taglist()"))) + +-- local x = xml.load("music-collection.xml") +-- inspect(table.sortedkeys(xml.applylpath(x,"//*/taglist(true)"))) diff --git a/tex/context/modules/mkiv/s-xml-analyzers.mkiv b/tex/context/modules/mkiv/s-xml-analyzers.mkiv index af11fc984..4104f023a 100644 --- a/tex/context/modules/mkiv/s-xml-analyzers.mkiv +++ b/tex/context/modules/mkiv/s-xml-analyzers.mkiv @@ -18,6 +18,7 @@ \installmodulecommandluasingle \showxmlstructure {moduledata.xml.analyzers.structure} \installmodulecommandluasingle \showxmlcharacters {moduledata.xml.analyzers.characters} \installmodulecommandluasingle \showxmlentities {moduledata.xml.analyzers.entities} +\installmodulecommandluasingle \showxmlallsetups {moduledata.xml.analyzers.allsetups} \stopmodule @@ -33,6 +34,9 @@ \starttext - \showxmlcharacters[\FileName] + \showxmlstructure [\FileName] \page + \showxmlentities [\FileName] \page + \showxmlcharacters[\FileName] \page + \showxmlallsetups [\FileName] \page \stoptext diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 6ef9430b3..bbd2117a8 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 : 08/11/16 13:56:03 +-- merge date : 08/15/16 22:40:19 do -- begin closure to overcome local limits and interference @@ -8845,112 +8845,6 @@ function readers.math(f,fontdata,specification) reportskippedtable("math") end end -local function packoutlines(data,makesequence) - local subfonts=data.subfonts - if subfonts then - for i=1,#subfonts do - packoutlines(subfonts[i],makesequence) - end - return - end - local common=data.segments - if common then - return - end - local glyphs=data.glyphs - if not glyphs then - return - end - if makesequence then - for index=1,#glyphs do - local glyph=glyphs[index] - local segments=glyph.segments - if segments then - local sequence={} - local nofsequence=0 - for i=1,#segments do - local segment=segments[i] - local nofsegment=#segment - nofsequence=nofsequence+1 - sequence[nofsequence]=segment[nofsegment] - for i=1,nofsegment-1 do - nofsequence=nofsequence+1 - sequence[nofsequence]=segment[i] - end - end - glyph.sequence=sequence - glyph.segments=nil - end - end - else - local hash={} - local common={} - local reverse={} - local last=0 - for index=1,#glyphs do - local segments=glyphs[index].segments - if segments then - for i=1,#segments do - local h=concat(segments[i]," ") - hash[h]=(hash[h] or 0)+1 - end - end - end - for index=1,#glyphs do - local segments=glyphs[index].segments - if segments then - for i=1,#segments do - local segment=segments[i] - local h=concat(segment," ") - if hash[h]>1 then - local idx=reverse[h] - if not idx then - last=last+1 - reverse[h]=last - common[last]=segment - idx=last - end - segments[i]=idx - end - end - end - end - if last>0 then - data.segments=common - end - end -end -local function unpackoutlines(data) - local subfonts=data.subfonts - if subfonts then - for i=1,#subfonts do - unpackoutlines(subfonts[i]) - end - return - end - local common=data.segments - if not common then - return - end - local glyphs=data.glyphs - if not glyphs then - return - end - for index=1,#glyphs do - local segments=glyphs[index].segments - if segments then - for i=1,#segments do - local c=common[segments[i]] - if c then - segments[i]=c - end - end - end - end - data.segments=nil -end -otf.packoutlines=packoutlines -otf.unpackoutlines=unpackoutlines local function getinfo(maindata,sub,platformnames,rawfamilynames) local fontdata=sub and maindata.subfonts and maindata.subfonts[sub] or maindata local names=fontdata.names @@ -9218,6 +9112,13 @@ function readers.loadshapes(filename,n) shapes=true, subfont=n, } + if fontdata then + for k,v in next,fontdata.glyphs do + v.class=nil + v.index=nil + v.math=nil + end + end return fontdata and { filename=filename, format=fontdata.format, @@ -9347,56 +9248,6 @@ function readers.extend(fontdata) end end end -if fonts.hashes then - local identifiers=fonts.hashes.identifiers - local loadshapes=readers.loadshapes - readers.version=0.006 - readers.cache=containers.define("fonts","shapes",readers.version,true) - local function load(filename,sub) - local base=file.basename(filename) - local name=file.removesuffix(base) - local kind=file.suffix(filename) - local attr=lfs.attributes(filename) - local size=attr and attr.size or 0 - local time=attr and attr.modification or 0 - local sub=tonumber(sub) - if size>0 and (kind=="otf" or kind=="ttf" or kind=="tcc") then - local hash=containers.cleanname(base) - if sub then - hash=hash.."-"..sub - end - data=containers.read(readers.cache,hash) - if not data or data.time~=time or data.size~=size then - data=loadshapes(filename,sub) - if data then - data.size=size - data.format=data.format or (kind=="otf" and "opentype") or "truetype" - data.time=time - packoutlines(data) - containers.write(readers.cache,hash,data) - data=containers.read(readers.cache,hash) - end - end - unpackoutlines(data) - else - data={ - filename=filename, - size=0, - time=time, - format="unknown", - units=1000, - glyphs={} - } - end - return data - end - fonts.hashes.shapes=table.setmetatableindex(function(t,k) - local d=identifiers[k] - local v=load(d.properties.filename,d.subindex) - t[k]=v - return v - end) -end end -- closure @@ -9415,6 +9266,7 @@ local concat,remove=table.concat,table.remove local floor,abs,round,ceil=math.floor,math.abs,math.round,math.ceil local P,C,R,S,C,Cs,Ct=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Ct local lpegmatch=lpeg.match +local formatters=string.formatters local readers=fonts.handlers.otf.readers local streamreader=readers.streamreader local readbytes=streamreader.readbytes @@ -9815,6 +9667,7 @@ do local ymax=0 local checked=false local keepcurve=false + local version=2 local function showstate(where) report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top) end @@ -10237,9 +10090,91 @@ do return floor((stems+7)/8) end end - local function unsupported() + local function unsupported(t) if trace_charstrings then - showstate("unsupported") + showstate("unsupported "..t) + end + top=0 + end + local function unsupportedsub(t) + if trace_charstrings then + showstate("unsupported sub "..t) + end + top=0 + end + local function getstem3() + if trace_charstrings then + showstate("stem3") + end + top=0 + end + local function divide() + if version==1 then + local d=stack[top] + top=top-1 + stack[top]=stack[top]/d + end + end + local function closepath() + if version==1 then + if trace_charstrings then + showstate("closepath") + end + end + top=0 + end + local function hsbw() + if version==1 then + if trace_charstrings then + showstate("dotsection") + end + width=stack[top] + end + top=0 + end + local function seac() + if version==1 then + if trace_charstrings then + showstate("seac") + end + end + top=0 + end + local function sbw() + if version==1 then + if trace_charstrings then + showstate("sbw") + end + width=stack[top-1] + end + top=0 + end + local function callothersubr() + if version==1 then + if trace_charstrings then + showstate("callothersubr (unsupported)") + end + end + top=0 + end + local function pop() + if version==1 then + if trace_charstrings then + showstate("pop (unsupported)") + end + top=top+1 + stack[top]=0 + else + top=0 + end + end + local function setcurrentpoint() + if version==1 then + if trace_charstrings then + showstate("pop (unsupported)") + end + x=x+stack[top-1] + y=y+stack[top] end top=0 end @@ -10256,7 +10191,7 @@ do unsupported, unsupported, unsupported, - unsupported, + hsbw, unsupported, unsupported, unsupported, @@ -10277,6 +10212,15 @@ do hvcurveto, } local subactions={ + [000]=dotsection, + [001]=getstem3, + [002]=getstem3, + [006]=seac, + [007]=sbw, + [012]=divide, + [016]=callothersubr, + [017]=pop, + [033]=setcurrentpoint, [034]=hflex, [035]=flex, [036]=hflex1, @@ -10284,23 +10228,29 @@ do } local p_bytes=Ct((P(1)/byte)^0) local function call(scope,list,bias,process) - local index=stack[top]+bias - top=top-1 - if trace_charstrings then - showvalue(scope,index,true) - end - local str=list[index] - if str then - if type(str)=="string" then - str=lpegmatch(p_bytes,str) - list[index]=str - end - depth=depth+1 - process(str) - depth=depth-1 + depth=depth+1 + if top==0 then + showstate(formatters["unknown %s call"](scope)) + top=0 else - report("unknown %s %i",scope,index) + local index=stack[top]+bias + top=top-1 + if trace_charstrings then + showvalue(scope,index,true) + end + local tab=list[index] + if tab then + if type(tab)=="string" then + tab=lpegmatch(p_bytes,tab) + list[index]=tab + end + process(tab) + else + showstate(formatters["unknown %s call %i"](scope,index)) + top=0 + end end + depth=depth-1 end local function process(tab) local i=1 @@ -10367,7 +10317,7 @@ do local t=tab[i] local a=subactions[t] if a then - a() + a(t) else if trace_charstrings then showvalue("<subaction>",t) @@ -10378,7 +10328,7 @@ do else local a=actions[t] if a then - local s=a() + local s=a(t) if s then i=i+s end @@ -10392,25 +10342,38 @@ do end end end - parsecharstrings=function(data,glyphs,doshapes) + local function setbias(globals,locals) + if version==1 then + return + false, + false + else + local g,l=#globals,#locals + return + ((g<1240 and 107) or (g<33900 and 1131) or 32768)+1, + ((l<1240 and 107) or (l<33900 and 1131) or 32768)+1 + end + end + parsecharstrings=function(data,glyphs,doshapes,tversion) local dictionary=data.dictionaries[1] local charstrings=dictionary.charstrings local charset=dictionary.charset + local private=dictionary.private or { data={} } keepcurve=doshapes + version=tversion stack={} glyphs=glyphs or {} strings=data.strings - locals=dictionary.subroutines - globals=data.routines - globalbias=#globals - localbias=#locals - globalbias=((globalbias<1240 and 107) or (globalbias<33900 and 1131) or 32768)+1 - localbias=((localbias<1240 and 107) or (localbias<33900 and 1131) or 32768)+1 - local nominalwidth=dictionary.private.data.nominalwidthx or 0 - local defaultwidth=dictionary.private.data.defaultwidthx or 0 + globals=data.routines or {} + locals=dictionary.subroutines or {} + globalbias,localbias=setbias(globals,locals,version) + local nominalwidth=private.data.nominalwidthx or 0 + local defaultwidth=private.data.defaultwidthx or 0 for i=1,#charstrings do - local str=charstrings[i] - local tab=lpegmatch(p_bytes,str) + local tab=charstrings[i] + if type(tab)=="string" then + tab=lpegmatch(p_bytes,tab) + end local index=i-1 x=0 y=0 @@ -10461,19 +10424,18 @@ do end return glyphs end - parsecharstring=function(data,dictionary,charstring,glyphs,index,doshapes) + parsecharstring=function(data,dictionary,tab,glyphs,index,doshapes,version) local private=dictionary.private keepcurve=doshapes strings=data.strings locals=dictionary.subroutines or {} globals=data.routines or {} - globalbias=#globals - localbias=#locals - globalbias=((globalbias<1240 and 107) or (globalbias<33900 and 1131) or 32768)+1 - localbias=((localbias<1240 and 107) or (localbias<33900 and 1131) or 32768)+1 + globalbias=setbias(globals,locals) local nominalwidth=private and private.data.nominalwidthx or 0 local defaultwidth=private and private.data.defaultwidthx or 0 - local tab=lpegmatch(p_bytes,charstring) + if type(tab)=="string" then + tab=lpegmatch(p_bytes,tab) + end x=0 y=0 width=false @@ -10497,7 +10459,7 @@ do else width=nominalwidth+width end -index=index-1 + index=index-1 local glyph=glyphs[index] if not glyph then glyphs[index]={ @@ -10520,7 +10482,6 @@ index=index-1 report("width: %s",tostring(width)) report("boundingbox: % t",boundingbox) end - return charstring end resetcharstrings=function() result={} @@ -10634,7 +10595,7 @@ local function readcidprivates(f,data) end parseprivates(data,dictionaries) end -local function readnoselect(f,data,glyphs,doshapes) +local function readnoselect(f,data,glyphs,doshapes,version) local dictionaries=data.dictionaries local dictionary=dictionaries[1] readglobals(f,data) @@ -10644,10 +10605,11 @@ local function readnoselect(f,data,glyphs,doshapes) readprivates(f,data) parseprivates(data,data.dictionaries) readlocals(f,data,dictionary) - parsecharstrings(data,glyphs,doshapes) + parsecharstrings(data,glyphs,doshapes,version) resetcharstrings() end -local function readfdselect(f,data,glyphs,doshapes) +readers.parsecharstrings=parsecharstrings +local function readfdselect(f,data,glyphs,doshapes,version) local header=data.header local dictionaries=data.dictionaries local dictionary=dictionaries[1] @@ -10705,7 +10667,7 @@ local function readfdselect(f,data,glyphs,doshapes) readlocals(f,data,dictionaries[i]) end for i=1,#charstrings do - parsecharstring(data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes) + parsecharstring(data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version) end resetcharstrings() end @@ -21057,7 +21019,7 @@ local setspacekerns=nodes.injections.setspacekerns if not setspacekerns then os. if fontfeatures then function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr) local features=fontfeatures[font] - local enabled=features.spacekern==true and features.kern==true + local enabled=features and features.spacekern and features.kern if enabled then setspacekerns(font,sequence) end @@ -21067,7 +21029,7 @@ else function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr) local shared=fontdata[font].shared local features=shared and shared.features - local enabled=features and features.spacekern==true and features.kern==true + local enabled=features and features.spacekern and features.kern if enabled then setspacekerns(font,sequence) end @@ -21122,7 +21084,7 @@ local function spaceinitializer(tfmdata,value) if kern then if feat then for script,languages in next,kern do - local f=feat[k] + local f=feat[script] if f then for l in next,languages do f[l]=true @@ -21142,7 +21104,7 @@ local function spaceinitializer(tfmdata,value) if kerns then for k,v in next,kerns do if type(v)=="table" then - right[k]=v[3] + right[k]=v[1][3] else right[k]=v end @@ -21152,7 +21114,7 @@ local function spaceinitializer(tfmdata,value) local kern=v[32] if kern then if type(kern)=="table" then - left[k]=kern[3] + left[k]=kern[1][3] else left[k]=kern end @@ -24226,26 +24188,25 @@ handlers.afm=afm local readers=afm.readers or {} afm.readers=readers afm.version=1.512 -local get_indexes +local get_indexes,get_shapes do - local n,m - local progress=function(str,position,name,size) - local forward=position+tonumber(size)+3+2 - n=n+1 - if n>=m then - return #str,name - elseif forward<#str then - return forward,name - else - return #str,name + local decrypt + do + local r,c1,c2,n=0,0,0,0 + local function step(c) + local cipher=byte(c) + local plain=bxor(cipher,rshift(r,8)) + r=((cipher+r)*c1+c2)%65536 + return char(plain) + end + decrypt=function(binary,initial,seed) + r,c1,c2,n=initial,52845,22719,seed + binary=gsub(binary,".",step) + return sub(binary,n+1) end - end - local initialize=function(str,position,size) - n=0 - m=size - return position+1 end local charstrings=P("/CharStrings") + local subroutines=P("/Subrs") local encoding=P("/Encoding") local dup=P("dup") local put=P("put") @@ -24255,28 +24216,58 @@ do local cardinal=digits/tonumber local spaces=P(" ")^1 local spacing=patterns.whitespace^0 + local routines,vector,chars,n,m + local initialize=function(str,position,size) + n=0 + m=size + return position+1 + end + local setroutine=function(str,position,index,size) + local forward=position+tonumber(size) + local stream=sub(str,position+1,forward) + routines[index]=decrypt(stream,4330,4) + return forward + end + local setvector=function(str,position,name,size) + local forward=position+tonumber(size) + if n>=m then + return #str + elseif forward<#str then + vector[n]=name + n=n+1 + return forward + else + return #str + end + end + local setshapes=function(str,position,name,size) + local forward=position+tonumber(size) + local stream=sub(str,position+1,forward) + if n>m then + return #str + elseif forward<#str then + vector[n]=name + n=n+1 + chars [n]=decrypt(stream,4330,4) + return forward + else + return #str + end + end + local p_rd=spacing*(P("RD")+P("-|")) + local p_np=spacing*(P("NP")+P("|")) + local p_nd=spacing*(P("ND")+P("|")) + local p_filterroutines= + (1-subroutines)^0*subroutines*spaces*Cmt(cardinal,initialize)*(Cmt(cardinal*spaces*cardinal*p_rd,setroutine)*p_np+P(1))^1 + local p_filtershapes= + (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*p_rd,setshapes)*p_nd+P(1))^1 local p_filternames=Ct ( - (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal,progress)+P(1))^1 + (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal,setvector)+P(1))^1 ) local p_filterencoding=(1-encoding)^0*encoding*spaces*digits*spaces*array*(1-dup)^0*Cf( Ct("")*Cg(spacing*dup*spaces*cardinal*spaces*name*spaces*put)^1 ,rawset) - local decrypt - do - local r,c1,c2,n=0,0,0,0 - local function step(c) - local cipher=byte(c) - local plain=bxor(cipher,rshift(r,8)) - r=((cipher+r)*c1+c2)%65536 - return char(plain) - end - decrypt=function(binary) - r,c1,c2,n=55665,52845,22719,4 - binary=gsub(binary,".",step) - return sub(binary,n+1) - end - end - local function loadpfbvector(filename) + local function loadpfbvector(filename,shapestoo) local data=io.loaddata(resolvers.findfile(filename)) if not data then report_pfb("no data in %a",filename) @@ -24291,18 +24282,30 @@ do report_pfb("no binary data in %a",filename) return end - binary=decrypt(binary,4) - local vector=lpegmatch(p_filternames,binary) - for i=1,#vector do - vector[i-1]=vector[i] - end - vector[#vector]=nil - if not vector then - report_pfb("no vector in %a",filename) - return - end + binary=decrypt(binary,55665,4) + local names={} local encoding=lpegmatch(p_filterencoding,ascii) - return vector,encoding + local glyphs={} + routines,vector,chars={},{},{} + if shapestoo then + lpegmatch(p_filterroutines,binary) + lpegmatch(p_filtershapes,binary) + local data={ + dictionaries={ + { + charstrings=chars, + charset=vector, + subroutines=routines, + } + }, + } + fonts.handlers.otf.readers.parsecharstrings(data,glyphs,true,true) + else + lpegmatch(p_filternames,binary) + end + names=vector + routines,vector,chars=nil,nil,nil + return names,encoding,glyphs end local pfb=handlers.pfb or {} handlers.pfb=pfb @@ -24326,6 +24329,10 @@ do end end end + get_shapes=function(pfbname) + local vector,encoding,glyphs=loadpfbvector(pfbname,true) + return glyphs + end end local spacer=patterns.spacer local whitespace=patterns.whitespace @@ -24474,6 +24481,22 @@ function readers.loadfont(afmname,pfbname) return data end end +function readers.loadshapes(filename) + local fullname=resolvers.findfile(filename) or "" + if fullname=="" then + return { + filename="not found: "..filename, + glyphs={} + } + else + return { + filename=fullname, + format="opentype", + glyphs=get_shapes(fullname) or {}, + units=1000, + } + end +end function readers.getinfo(filename) local data=read(resolvers.findfile(filename),infoparser) if data then |