diff options
author | Karl Berry <karl@freefriends.org> | 2017-08-21 20:51:34 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2017-08-21 20:51:34 +0000 |
commit | 506029f1ed5e0d0047159a091f3bba2856c3aa0d (patch) | |
tree | 9396e8b58ec76cbefe4f5348515203bfeaefe3a2 /Master/texmf-dist/doc | |
parent | 94a3ec7f333b2bc7b4d29565c2b4a57ae04c5180 (diff) |
fontloader-luaotfload (21aug17)
git-svn-id: svn://tug.org/texlive/trunk@45090 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/doc')
11 files changed, 1048 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/luatex/fontloader-luaotfload/README.md b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/README.md new file mode 100644 index 00000000000..71784a59734 --- /dev/null +++ b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/README.md @@ -0,0 +1,25 @@ +# The fontloader-luaotfload package + +Additional fontloaders for luaotfload + +Version 1.0 Ulrike Fischer 2017- + + +## License + +LATEX Project Public License 1.3c. + +## Contents + +- Readme.md (this file) +- various fontloader-XXXX.lua files +- luaotfload-letterspace.luaX -- and alternative version of luaotfload-letterspace.lua, needed for some of the fontloaders +- luaotfload.confX -- an example configuration file, rename to luaotfload.conf to use it. +- fontloader-luaotfload.tex, fontloader-luaotfload.pdf (the docu and example) +- A number of test-XXX-files + + +## Use and Installation + +Read the documentation. + diff --git a/Master/texmf-dist/doc/luatex/fontloader-luaotfload/fontloader-luaotfload.pdf b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/fontloader-luaotfload.pdf Binary files differnew file mode 100644 index 00000000000..ee54df89a1e --- /dev/null +++ b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/fontloader-luaotfload.pdf diff --git a/Master/texmf-dist/doc/luatex/fontloader-luaotfload/fontloader-luaotfload.tex b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/fontloader-luaotfload.tex new file mode 100644 index 00000000000..07cc8016f79 --- /dev/null +++ b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/fontloader-luaotfload.tex @@ -0,0 +1,164 @@ +% !Mode:: "TeX:DE:UTF-8:Main" +\RequirePackage{luatex85} +\documentclass[parskip=half-,egregdoesnotlikesansseriftitles]{scrartcl} +\usepackage{ydoc-code,ydoc-desc} +\usepackage{fontspec} +\usepackage[english]{babel} +\usepackage{csquotes} +\usepackage{xcolor,listings,enumitem} + +\title{The \texttt{fontloader-luaotfload} package} +\author{Ulrike Fischer\thanks{fischer@troubleshooting-tex.de}} +\newcommand\package[1]{\texttt{#1}} + + +\begin{document} +\maketitle + +\section{Requirements} + +Use a current tex system! The files has been tried with texlive 2017. + +\section{Introduction} +The luatex engine can use open type fonts but -- unlike xetex which has the harfbuzz library built-in -- it doesn't work with the bare binary but needs additional (lua)-code. + +In \LaTeX\ this lua-code is provided by the package \package{luaotfload}. In newer \LaTeX-versions the lua-code of \package{luaotfload} is loaded by the format. So you don't need to load it manually. Even a minimal hello-world-example should show in the log-file + +\verb+Lua module: luaotfload-main 2017/01/29 2.80001 OpenType layout system.+ + + + + +\package{luaotfload} consist of two parts: + +\begin{itemize} +\item The core of the package is the \emph{fontloader} -- the current is \texttt{fontloader-2017-02-11.lua}. The fontloader has been created from a subset of the fontloader code of the Con\TeX{}t format. + +\item Around this fontloader \package{luaotfload} contains a number of lua-file needed for the creation of the font name database, the font cache, and some adaptions of the fontloader to the needs of \LaTeX. +\end{itemize} + +\package{luaotfload} has made quite an effort to separate the two parts and since some time it is possible to replace the core fontloader with another (newer) version with the help of a configuration file. This makes it possible e.\,g. to test new features which have been added to Con\TeX{}t. + +This package provides a number of such alternative fontloaders. + +\emph{Please read the complete documentation before trying to use the fontloaders -- at least read the section \ref{sec:problem} about incompabilities.} + + +\section{Installation} + +The package contains + +\begin{itemize} +\item a number of \texttt{fontloader-XXX.lua} files. This files should be in a texmf-tree in \texttt{../tex/luatex/fontloader-luaotfload} -- probably your tex system installed them there already. + +\item all the other files are either examples or documentation and should go in the \texttt{doc}-folder. +\end{itemize} + +\section{Using the fontloader(s)} + +To use one of the alternative fontloader you must create a \texttt{luaotfload.conf} file. This file should be in the normal search path, e.g. in the folder of your document or in some texmf-tree, there at best in the branch \texttt{tex/luatex}. + +Such a \texttt{luaotfload.conf} looks e.\,g. like this: + +\lstinputlisting[columns=flexible,basicstyle=\ttfamily]{luaotfload.conf} + +\begin{itemize} +\item The fontloader section starts with \texttt[run]. +\item The semicolon starts a comment. So in the example \texttt{fontloader-reference-2017-07-28.lua} is the active fontloader. If you comment all fontloaders \package{luaotfload} will use its default loader. +\item The shortcuts \texttt{default} loads the default fontloader of \package{luaotfload} and \texttt{reference} its reference version (see below for an explanation about the reference fontloader). +\item The last active entry wins! +\item It is possible to use absolute pathes, but how exactly is rather system dependant, so you will have to try. +\end{itemize} + +\section{General description of the fontloaders} + +Fontloaders come in two flavors: I will call them \emph{reference type} and \emph{luaotfload type}. + +The \emph{reference type} is a copy from a \texttt{luatex-fonts-merged.lua} from a context installation. This file is -- as the name indicates -- a merge of the generic part of the context fontloader files. It is normally present in a context minimals installation, or can be created by running in the folder which contains \texttt{luatex-fonts.lua} the command: + +\begin{lstlisting} +mtxrun --script package --merge ./luatex-fonts.lua +\end{lstlisting} + +The \emph{luaotfload type} is created by a script call \texttt{mkimport} which you can find on the github site of \package{luaotfload}. It also uses the context files but ignores some that are present in the lualibs packages and it also does some other adaptions. + +The original \package{luaotfload} already contains both types of fontloaders, the reference type is \texttt{fontloader-reference.lua} -- it can be chosen in the configuration file with the keyword \texttt{reference} -- and the luaotfload type is \texttt{fontloader-2017-02-11-lua}. + +I have no idea about the pros and cons of both types. On the whole I would have preferred to build luaotfload type fontloaders as they are nearer to the current default fontloader. But sadly it didn't work: I could adapt the pathes in \texttt{mkimport} to my system and build a fontloader but it wasn't usable. +The \emph{reference type} are perhaps slower and there is the possibility that they contain code which could clash with some lua libraries loaded by other \LaTeX packages. But until now they seemed to work. + +For both types there is the danger that fontloaders created with files from a newer context version clash with the older wrapper code of luaotfload -- and actually this already happened, see the following section. + + + +\section{Incompabilities with the \package{luaotfload} \enquote{wrapper} files}\label{sec:problem} + +As mentioned in the previous section it is always possible that newer versions of the core fontloader are no longer compatible to the wrapper files from \package{luaotfload}. If you try out \texttt{fontloader-reference-2017-07-28.lua} you will get a lua error: + +\begin{verbatim} +luaotfload | load : FATAL ERROR +luaotfload | load : Failed to load module "luaotfload-letterspace.lua". +luaotfload | load : Error message: +luaotfload | load : "...mf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua:73: + attempt to index local 'nodepool' (a nil value)". +\end{verbatim} + +The reason is that \texttt{luaotfload-letterspace.lua} tries to access a table value that no longer exists. Imho it is not possible to solve this problem without changing the original file. This is absolutly not to my liking but as I don't see another way I offer a patched version. If you want to use the newer fontloader versions you will have to do this: + +In the documentation folder of this package there is a file \texttt{luaotfload-letterspace.luax}. Change the extension to \texttt{lua} and copy the file to your document folder or in a \emph{local} texmf tree to \texttt{tex/luatex/luaotfload} -- in the second case don't forget to update your file name database (FNDB): in miktex with \texttt{initexmf -u} and in texlive with \texttt{mktexlsr}. + +Try out a small lualatex document. If the log-file tells you + +\verb+ !!!!! UF: Using CHANGED luaotfload-letterspace 2017-07-14 !!!!!+ + +then the new \texttt{lua}-file is used. \textbf{Don't forget that this patched file is in your system! When luaotfload is updated you should remove it.} + +\section{The list of new fontloaders} + +Currently there are only three fontloaders. But I plan to add more if some changes are made to the context files. + +Fontloaders with * before their name need the adapted \texttt{luaotfload-letterspace.lua} as described in the last section. + +\begin{description}[font=\texttt] + \item[fontloader-2017-02-11-stix.lua] This fontloader is the original luaotfload-type fontloader where one section -- from \texttt{font-oto.lua} -- has been replaced to get around a bug in the stix fonts with wrong parenthese sizes. See \texttt{test-fontloader-2017-02-11-stix.tex}. + + \item[*fontloader-reference-2017-07-28.lua] This is a reference-type fontloader which has been created on 2017-07-28. It adds the capability to add ligatures with \enquote{word boundaries}. See \texttt{test-fontloader-2017-07-28.tex}. + + \item[*fontloader-reference-2017-08-18.lua] This is a reference-type fontloader which I added when I tried out to color the cow fonts: See \url{https://tex.stackexchange.com/a/387069/2388} and + \texttt{test-fontloader-2017-08-18.tex}. + +\end{description} + + +\section{Using newer luatex versions} + +As mentioned in the tex.stackexchange answer about the colored cow fonts, the solution needs a newer luatex. While \texttt{fontloader-reference-2017-08-18.lua} in itself seems to work fine with the luatex of TeXlive 2017, trying to use the \texttt{colr} font feature, leads to the error + + \verb+! error: (vf command): unknown packet command+ + +So here a description how I did setup my windows system to allow tests with a newer luatex without disturbing my standard system: + +\begin{enumerate} +\item I created a folder \texttt{.../texlive/2017/bin-dev} beside the standard \texttt{bin}-folder. +\item In this \texttt{bin-dev}-folder I copied the whole \texttt{win32} from the \texttt{bin}-folder. +\item I got \texttt{luatex-dev-w32.tar.xz} from \texttt{http://w32tex.org/} and copied the included \texttt{luatex.dll} and \texttt{lua52.dll} to the \texttt{bin-dev/win32}-folder. + +\item In the \texttt{bin-dev/win32}-folder I created a \texttt{texmf.cnf}-file with the line + + \verb+ TEXMFSYSVAR = $TEXMFROOT/texmf-var-dev+ + +\item Then I changed the windows \texttt{PATH}-variable and added the path to \texttt{.../bin-dev/win32;} at the begin. + +\item As a last step I called on a command \verb+fmtutil-sys --all+. This creates the formats in a new \texttt{texmf-var-dev} tree beside the standard \texttt{texmf-var}. +\end{enumerate} + +With this installation it is possible to switch between the normal texlive and the one with the development luatex simply by changing the windows PATH variable. + + + + + +\end{document} + + + diff --git a/Master/texmf-dist/doc/luatex/fontloader-luaotfload/luaotfload-letterspace.luax b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/luaotfload-letterspace.luax new file mode 100644 index 00000000000..df93dbe1b70 --- /dev/null +++ b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/luaotfload-letterspace.luax @@ -0,0 +1,683 @@ +if not modules then modules = { } end modules ['letterspace'] = { + version = "2.8", + comment = "companion to luaotfload-main.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL; adapted by Philipp Gesang", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--- This code diverged quite a bit from its origin in Context. Please +--- do *not* report bugs on the Context list. + +local log = luaotfload.log +local logreport = log.report + +-- UF +texio.write_nl ("------------------") +texio.write_nl ("!!!!! UF: Using CHANGED luaotfload-letterspace 2017-07-14 !!!!!") +texio.write_nl ("------------------") +-- /UF + +local getmetatable = getmetatable +local require = require +local setmetatable = setmetatable +local tonumber = tonumber + +local next = next +local nodes, node, fonts = nodes, node, fonts + +local nodedirect = nodes.nuts + +local getfield = nodedirect.getfield +local setfield = nodedirect.setfield + +local field_setter = function (name) return function (n, ...) setfield (n, name, ...) end end +local field_getter = function (name) return function (n, ...) getfield (n, name, ...) end end + +local getfont = nodedirect.getfont +local getid = nodedirect.getid + +local getnext = nodedirect.getnext or field_getter "next" +local setnext = nodedirect.setnext or field_setter "next" + +local getprev = nodedirect.getprev or field_getter "prev" +local setprev = nodedirect.setprev or field_setter "prev" + +--- since r5336 +local getboth = nodedirect.getboth or function (n) + return getprev (n), getnext (n) +end + +local setlink = nodedirect.setlink or function (a, b) + setnext (a, b) + setprev (b, a) +end + +local getdisc = nodedirect.getdisc or field_getter "disc" +local setdisc = nodedirect.setdisc or field_setter "disc" + +local getsubtype = nodedirect.getsubtype or field_getter "subtype" +local setsubtype = nodedirect.setsubtype or field_setter "subtype" + +local getchar = nodedirect.getchar or field_getter "subtype" +local setchar = nodedirect.setchar or field_setter "subtype" + +local find_node_tail = nodedirect.tail +local todirect = nodedirect.tonut +local tonode = nodedirect.tonode + +local insert_node_before = nodedirect.insert_before +local free_node = nodedirect.free -- may cause double free +local free_node = function (n) + logreport ("term", 5, "letterspace", "not calling free_node(%d)", n) + -- free_node (n) +end +local copy_node = nodedirect.copy +local new_node = nodedirect.new + +local nodepool = nodedirect.pool +-- local new_kern = nodepool.kern -- UF removed 2017-07-14 + +local nodecodes = nodes.nodecodes + +local glyph_code = nodecodes.glyph +local kern_code = nodecodes.kern +local disc_code = nodecodes.disc +local math_code = nodecodes.math +local glue_code = nodecodes.glue + +local fonthashes = fonts.hashes +local chardata = fonthashes.characters +local quaddata = fonthashes.quads +local otffeatures = fonts.constructors.newfeatures "otf" + +--[[doc-- + + Since the letterspacing method was derived initially from Context’s + typo-krn.lua we keep the sub-namespace “letterspace” inside the + “luaotfload” table. + +--doc]]-- + +luaotfload.letterspace = luaotfload.letterspace or { } +local letterspace = luaotfload.letterspace + +letterspace.keepligature = false +letterspace.keeptogether = false + +---=================================================================--- +--- preliminary definitions +---=================================================================--- +-- We set up a layer emulating some Context internals that are needed +-- for the letterspacing callback. +----------------------------------------------------------------------- +--- node-ini +----------------------------------------------------------------------- + +local bothways = function (t) return table.swapped (t, t) end +local kerncodes = bothways { [0] = "fontkern" + , [1] = "userkern" + , [2] = "accentkern" + } +local skipcodes = bothways { [0] = "userskip" + , [13] = "spaceskip" + , [14] = "xspaceskip" + } + +kerncodes.kerning = kerncodes.fontkern --- idiosyncrasy +local kerning_code = kerncodes.kerning +local userkern_code = kerncodes.userkern +local userskip_code = skipcodes.userskip +local spaceskip_code = skipcodes.spaceskip +local xspaceskip_code = skipcodes.xspaceskip + +----------------------------------------------------------------------- +--- node-res +----------------------------------------------------------------------- + +local glue_spec = new_node "glue_spec" + +local new_gluespec = function (width, + stretch, shrink, + stretch_order, shrink_order) + local spec = copy_node(glue_spec) + if width then setfield(spec, "width" , width ) end + if stretch then setfield(spec, "stretch" , stretch ) end + if shrink then setfield(spec, "shrink" , shrink ) end + if stretch_order then setfield(spec, "stretch_order", stretch_order) end + if shrink_order then setfield(spec, "shrink_order" , shrink_order ) end + return spec +end + +local new_glue = function (width, stretch, shrink, + stretch_order, shrink_order) + local n = new_node "glue" + if not width then return n end + -- no spec + if width == false then + local width = tonumber(width) + if width then + setfield(n, "spec", + new_gluespec(width, stretch, shrink, + stretch_order, shrink_order)) + end + else + -- shared + setfield(n, "spec", copy_node(width)) + end + return n +end + +----------------------------------------------------------------------- +--- font-hsh +----------------------------------------------------------------------- +--- some initialization resembling font-hsh +local fonthashes = fonts.hashes +local identifiers = fonthashes.identifiers --- was: fontdata +local chardata = fonthashes.characters +local quaddata = fonthashes.quads +local parameters = fonthashes.parameters + +--- ('a, 'a) hash -> (('a, 'a) hash -> 'a -> 'a) -> ('a, 'a) hash +local setmetatableindex = function (t, f) + local mt = getmetatable(t) + if mt then + mt.__index = f + else + setmetatable(t, { __index = f }) + end + return t +end + +if not parameters then + parameters = { } + setmetatableindex(parameters, function(t, k) + if k == true then + return parameters[currentfont()] + else + local parameters = identifiers[k].parameters + t[k] = parameters + return parameters + end + end) + --fonthashes.parameters = parameters +end + +if not chardata then + chardata = { } + setmetatableindex(chardata, function(t, k) + if k == true then + return chardata[currentfont()] + else + local tfmdata = identifiers[k] + if not tfmdata then --- unsafe + tfmdata = font.fonts[k] + end + if tfmdata then + local characters = tfmdata.characters + t[k] = characters + return characters + end + end + end) + fonthashes.characters = chardata +end + +if not quaddata then + quaddata = { } + setmetatableindex(quaddata, function(t, k) + if k == true then + return quads[currentfont()] + else + local parameters = parameters[k] + local quad = parameters and parameters.quad or 0 + t[k] = quad + return quad + end + end) + --fonthashes.quads = quaddata +end + +---=================================================================--- +--- character kerning functionality +---=================================================================--- + +-- UF changed 2017-07-14 +local newUF = node.direct.new + +local kern_injector = function (fillup, kern) + if fillup then + local g = newUF("glue") + setfield(g, "stretch", kern) + setfield(g, "stretch_order", 1) + return g + end + local g = newUF("kern") + setfield(g,"kern",kern) + return g +end +-- /UF + +local kernable_skip = function (n) + local st = getsubtype (n) + return st == userskip_code + or st == spaceskip_code + or st == xspaceskip_code +end + +local function spec_injector (fillup, width, stretch, shrink) + if fillup then + local spec = new_gluespec(width, 2 * stretch, 2 * shrink) + setfield(spec, "stretch_order", 1) + return spec + end + return new_gluespec(width,stretch,shrink) +end + +--[[doc-- + + Caveat lector. + This is an adaptation of the Context character kerning mechanism + that emulates XeTeX-style fontwise letterspacing. Note that in its + present state it is far inferior to the original, which is + attribute-based and ignores font-boundaries. Nevertheless, due to + popular demand the following callback has been added. + +--doc]]-- + +local kernfactors = { } --- fontid -> factor + +local kerncharacters +kerncharacters = function (head) + local start = head + local lastfont = nil + local keepligature = letterspace.keepligature --- function + local keeptogether = letterspace.keeptogether --- function + local fillup = false + + local identifiers = fonthashes.identifiers + local kernfactors = kernfactors + local firstkern = true + + while start do + local id = getid(start) + if id == glyph_code then + --- 1) look up kern factor (slow, but cached rudimentarily) + local krn + local fontid = getfont(start) + do + krn = kernfactors[fontid] + if not krn then + local tfmdata = identifiers[fontid] + if not tfmdata then -- unsafe + tfmdata = font.fonts[fontid] + end + if tfmdata then + fontproperties = tfmdata.properties + if fontproperties then + krn = fontproperties.kerncharacters + end + end + kernfactors[fontid] = krn + end + if not krn or krn == 0 then + firstkern = true + goto nextnode + elseif firstkern then + firstkern = false + if (id ~= disc_code) and (not getfield(start, "components")) then + --- not a ligature, skip node + goto nextnode + end + end + end + + if krn == "max" then + krn = .25 + fillup = true + else + fillup = false + end + + lastfont = fontid + + --- 2) resolve ligatures + local c = getfield(start, "components") + + if c then + if keepligature and keepligature(start) then + -- keep 'm + c = nil + else + while c do + local s = start + local p, n = getboth (s) + if p then + setlink (p, c) + else + head = c + end + if n then + local tail = find_node_tail(c) + setlink (tail, n) + end + start = c + setfield(s, "components", nil) + free_node(s) --> double free with multipart components + c = getfield (start, "components") + end + end + end -- kern ligature + + --- 3) apply the extra kerning + local prev = getprev(start) + if prev then + local pid = getid(prev) + + if not pid then + -- nothing + + elseif pid == glue_code and kernable_skip(prev) then + local spec = getfield(prev, "spec") + local wd = getfield(spec, "width") + if wd > 0 then + --- formula taken from Context + --- existing_width extended by four times the + --- width times the font’s kernfactor + local newwd = wd + --[[two en to a quad]] 4 * wd * krn + local stretched = (getfield(spec,"stretch") * newwd) / wd + local shrunk = (getfield(spec,"shrink") * newwd) / wd + setfield(prev, "spec", + spec_injector(fillup, newwd, stretched, shrunk)) + end + + elseif pid == kern_code then + local prev_subtype = getsubtype(prev) + if prev_subtype == kerning_code --- context does this by means of an + or prev_subtype == userkern_code --- attribute; we may need a test + then + + local pprev = getprev(prev) + local pprev_id = getid(pprev) + + if keeptogether + and pprev_id == glyph_code + and keeptogether(pprev, start) + then + -- keep + else + setsubtype (prev, userkern_code) + local prev_kern = getfield(prev, "kern") + prev_kern = prev_kern + quaddata[lastfont] * krn + setfield (prev, "kern", prev_kern) + end + end + + elseif pid == glyph_code then + if getfont(prev) == lastfont then + local prevchar = getchar(prev) + local lastchar = getchar(start) + if keeptogether and keeptogether(prev, start) then + -- keep 'm + elseif identifiers[lastfont] then + local lastfontchars = chardata[lastfont] + if lastfontchars then + local prevchardata = lastfontchars[prevchar] + if not prevchardata then + --- font doesn’t contain the glyph + else + local kern = 0 + local kerns = prevchardata.kerns + if kerns then kern = kerns[lastchar] or kern end + krn = kern + quaddata[lastfont]*krn -- here + insert_node_before(head,start,kern_injector(fillup,krn)) + end + end + end + else + krn = quaddata[lastfont]*krn -- here + insert_node_before(head,start,kern_injector(fillup,krn)) + end + + elseif pid == disc_code then + local disc = prev -- disc + local pre, post, replace = getdisc (disc) + local prv = getprev(disc) + local nxt = getnext(disc) + + if pre and prv then -- must pair with start.prev + -- this one happens in most cases + local before = copy_node(prv) + setprev(pre, before) + setnext(before, pre) + setprev(before, nil) + pre = kerncharacters (before) + pre = getnext(pre) + setprev(pre, nil) + setfield(disc, "pre", pre) + free_node(before) + end + + if post and nxt then -- must pair with start + local after = copy_node(nxt) + local tail = find_node_tail(post) + setnext(tail, after) + setprev(after, tail) + setnext(after, nil) + post = kerncharacters (post) + setnext(tail, nil) + setfield(disc, "post", post) + free_node(after) + end + + if replace and prv and nxt then -- must pair with start and start.prev + local before = copy_node(prv) + local after = copy_node(nxt) + local tail = find_node_tail(replace) + setprev(replace, before) + setnext(before, replace) + setprev(before, nil) + setnext(tail, after) + setprev(after, tail) + setnext(after, nil) + replace = kerncharacters (before) + replace = getnext(replace) + setprev(replace, nil) + setnext(getprev(after), nil) + setfield(disc, "replace", replace) + free_node(after) + free_node(before) + + elseif identifiers[lastfont] then + if prv + and getid(prv) == glyph_code + and getfont(prv) == lastfont + then + local kern = 0 + local prevchar = getchar(prv) + local lastchar = getchar(start) + local lastfontchars = chardata[lastfont] + if lastfontchars then + local prevchardata = lastfontchars[prevchar] + if not prevchardata then + --- font doesn’t contain the glyph + else + local kerns = prevchardata.kerns + if kerns then kern = kerns[lastchar] or kern end + end + end + krn = kern + quaddata[lastfont]*krn -- here + else + krn = quaddata[lastfont]*krn -- here + end + setfield(disc, "replace", kern_injector(false, krn)) + end --[[if replace and prv and nxt]] + end --[[if not pid]] + end --[[if prev]] + end --[[if id == glyph_code]] + + ::nextnode:: + if start then + start = getnext(start) + end + end + return head +end + +---=================================================================--- +--- integration +---=================================================================--- + +--- · callback: kerncharacters +--- · enabler: enablefontkerning +--- · disabler: disablefontkerning + +--- callback wrappers + +--- (node_t -> node_t) -> string -> string list -> bool +local registered_as = { } --- procname -> callbacks +local add_processor = function (processor, name, ...) + local callbacks = { ... } + for i=1, #callbacks do + luatexbase.add_to_callback(callbacks[i], processor, name) + end + registered_as[name] = callbacks --- for removal + return true +end + +--- string -> bool +local remove_processor = function (name) + local callbacks = registered_as[name] + if callbacks then + for i=1, #callbacks do + luatexbase.remove_from_callback(callbacks[i], name) + end + return true + end + return false --> unregistered +end + +--- When font kerning is requested, usually by defining a font with the +--- ``letterspace`` parameter, we inject a wrapper for the +--- ``kerncharacters()`` node processor in the relevant callbacks. This +--- wrapper initially converts the received head node into its “direct” +--- counterpart. Likewise, the callback result is converted back to an +--- ordinary node prior to returning. Internally, ``kerncharacters()`` +--- performs all node operations on direct nodes. + +--- unit -> bool +local enablefontkerning = function ( ) + + local handler = function (hd) + local direct_hd = todirect (hd) + logreport ("term", 5, "letterspace", + "kerncharacters() invoked with node.direct interface \z + (``%s`` -> ``%s``)", tostring (hd), tostring (direct_hd)) + local direct_hd = kerncharacters (direct_hd) + if not direct_hd then --- bad + logreport ("both", 0, "letterspace", + "kerncharacters() failed to return a valid new head") + end + return tonode (direct_hd) + end + + return add_processor( handler + , "luaotfload.letterspace" + , "pre_linebreak_filter" + , "hpack_filter") +end + +--- unit -> bool +---al disablefontkerning = function ( ) +---eturn remove_processor "luaotfload.letterspace" +--- + +--[[doc-- + + Fontwise kerning is enabled via the “kernfactor” option at font + definition time. Unlike the Context implementation which relies on + Luatex attributes, it uses a font property for passing along the + letterspacing factor of a node. + + The callback is activated the first time a letterspaced font is + requested and stays active until the end of the run. Since the font + is a property of individual glyphs, every glyph in the entire + document must be checked for the kern property. This is quite + inefficient compared to Context’s attribute based approach, but Xetex + compatibility reduces our options significantly. + +--doc]]-- + + +local fontkerning_enabled = false --- callback state + +--- fontobj -> float -> unit +local initializefontkerning = function (tfmdata, factor) + if factor ~= "max" then + factor = tonumber (factor) or 0 + end + if factor == "max" or factor ~= 0 then + local fontproperties = tfmdata.properties + if fontproperties then + --- hopefully this field stays unused otherwise + fontproperties.kerncharacters = factor + end + if not fontkerning_enabled then + fontkerning_enabled = enablefontkerning () + end + end +end + +--- like the font colorization, fontwise kerning is hooked into the +--- feature mechanism + +otffeatures.register { + name = "kernfactor", + description = "kernfactor", + initializers = { + base = initializefontkerning, + node = initializefontkerning, + } +} + +--[[doc-- + + The “letterspace” feature is essentially identical with the above + “kernfactor” method, but scales the factor to percentages to match + Xetex’s behavior. (See the Xetex reference, page 5, section 1.2.2.) + + Since Xetex doesn’t appear to have a (documented) “max” keyword, we + assume all input values are numeric. + +--doc]]-- + +local initializecompatfontkerning = function (tfmdata, percentage) + local factor = tonumber (percentage) + if not factor then + logreport ("both", 0, "letterspace", + "Invalid argument to letterspace: %s (type %q), " .. + "was expecting percentage as Lua number instead.", + percentage, type (percentage)) + return + end + return initializefontkerning (tfmdata, factor * 0.01) +end + +otffeatures.register { + name = "letterspace", + description = "letterspace", + initializers = { + base = initializecompatfontkerning, + node = initializecompatfontkerning, + } +} + +--[[example-- + +See https://bitbucket.org/phg/lua-la-tex-tests/src/tip/pln-letterspace-8-compare.tex +for an example. + +--example]]-- + +--- vim:sw=2:ts=2:expandtab:tw=71 + diff --git a/Master/texmf-dist/doc/luatex/fontloader-luaotfload/luaotfload.confx b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/luaotfload.confx new file mode 100644 index 00000000000..4cf5302ce6e --- /dev/null +++ b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/luaotfload.confx @@ -0,0 +1,8 @@ +[run] +;fontloader = reference; +;fontloader = default; +;fontloader = context; +;fontloader = fontloader-reference-2017-07-28.lua; +fontloader = fontloader-reference-2017-08-18.lua; +;fontloader = fontloader-2017-02-11-stix.lua; + diff --git a/Master/texmf-dist/doc/luatex/fontloader-luaotfload/test-fontloader-2017-02-11-stix.pdf b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/test-fontloader-2017-02-11-stix.pdf Binary files differnew file mode 100644 index 00000000000..6df2feb9855 --- /dev/null +++ b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/test-fontloader-2017-02-11-stix.pdf diff --git a/Master/texmf-dist/doc/luatex/fontloader-luaotfload/test-fontloader-2017-02-11-stix.tex b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/test-fontloader-2017-02-11-stix.tex new file mode 100644 index 00000000000..6b41d21fab6 --- /dev/null +++ b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/test-fontloader-2017-02-11-stix.tex @@ -0,0 +1,15 @@ +% !Mode:: "TeX:UTF-8:Main" +% to avoid the bug: use fontloader 2017-02-11-stix or later + +\documentclass{article} + +\usepackage{unicode-math} +\setmathfont{STIX2Math.otf} + +\begin{document} +$\left(\frac{\frac{a}{b}}{\frac{a}{b}}\right)$ +\qquad +$a^{\left(\frac{\frac{a}{b}}{\frac{a}{b}}\right)}$ %wrong size of parentheses + + +\end{document} diff --git a/Master/texmf-dist/doc/luatex/fontloader-luaotfload/test-fontloader-2017-07-28.pdf b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/test-fontloader-2017-07-28.pdf Binary files differnew file mode 100644 index 00000000000..2129efe108a --- /dev/null +++ b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/test-fontloader-2017-07-28.pdf diff --git a/Master/texmf-dist/doc/luatex/fontloader-luaotfload/test-fontloader-2017-07-28.tex b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/test-fontloader-2017-07-28.tex new file mode 100644 index 00000000000..5750fa345c7 --- /dev/null +++ b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/test-fontloader-2017-07-28.tex @@ -0,0 +1,127 @@ +% !Mode:: "TeX:UTF-8:Main" +%needs a fontloader 2017-07-28 or later +%substitutions at word boundaries + +\documentclass{article} + +\usepackage{luacode,fontspec} +\begin{luacode*} + fonts.handlers.otf.addfeature { + name = "test-a", + type = "chainsubstitution", + lookups = { + { + type = "substitution", + data = { + ["a"] = "A", + ["b"] = "B", + ["c"] = "C", + ["d"] = "D", + }, + }, + { + type = "ligature", + data = { + ['1'] = { "a", "b" }, + ['2'] = { "c", "d" }, + }, + }, + }, + data = { + rules = { + { + before = { { " ", 0xFFFC } }, + current = { { "a" }, { "b" } }, + lookups = { 2 }, + }, + { + current = { { "c" }, { "d" } }, + after = { { 0xFFFC, " " } }, + lookups = { 2 }, + }, + { + current = { { "a" } }, + after = { { "b" } }, + lookups = { 1 }, + }, + { + current = { { "c" } }, + after = { { "d" } }, + lookups = { 1 }, + }, + }, + }, + } + + fonts.handlers.otf.addfeature { + name = "test-b", + type = "chainsubstitution", + lookups = { + { + type = "ligature", + data = { + ['1'] = { "a", "b" }, + ['2'] = { "c", "d" }, + }, + }, + }, + data = { + rules = { + { + -- the space is redundant as 0xFFFC contains it + before = { { " ", 0xFFFC } }, + current = { { "a" }, { "b" } }, + lookups = { 1 }, + }, + { + current = { { "c" }, { "d" } }, + -- the space is redundant as 0xFFFC contains it + after = { { 0xFFFC, " " } }, + lookups = { 1 }, + }, + }, + }, + } + + fonts.handlers.otf.addfeature { + name = "test-c", + type = "chainsubstitution", + lookups = { + { + type = "ligature", + data = { + ['1'] = { "a", "b" }, + ['2'] = { "c", "d" }, + }, + }, + }, + data = { + rules = { + { + before = { { " " } }, + current = { { "a" }, { "b" } }, + lookups = { 1 }, + }, + { + current = { { "c" }, { "d" } }, + after = { { " " } }, + lookups = { 1 }, + }, + }, + }, + } +\end{luacode*} + + +\setmainfont{Arial}[RawFeature=+test-a;] + +\begin{document} +Substitutions at word boundaries (spaces): + +ab ab abxcd abxcdcdcd + +expected output: + +1 1 1x2 1xCdCd2 + +\end{document}
\ No newline at end of file diff --git a/Master/texmf-dist/doc/luatex/fontloader-luaotfload/test-fontloader-2017-08-18.pdf b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/test-fontloader-2017-08-18.pdf Binary files differnew file mode 100644 index 00000000000..3492594cabf --- /dev/null +++ b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/test-fontloader-2017-08-18.pdf diff --git a/Master/texmf-dist/doc/luatex/fontloader-luaotfload/test-fontloader-2017-08-18.tex b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/test-fontloader-2017-08-18.tex new file mode 100644 index 00000000000..1cdb8eeb5ec --- /dev/null +++ b/Master/texmf-dist/doc/luatex/fontloader-luaotfload/test-fontloader-2017-08-18.tex @@ -0,0 +1,26 @@ +% !Mode:: "TeX:UTF-8:Main" +%needs a fontloader 2017-08-18 or later **and** a luatex 1.06!!! + +\documentclass{article} + + +\directlua{fonts.handlers.otf.registerpalette("demo", { + { g = 0 }, + { g = 0.5, b=0, r=1 }, + { r = 1 }, + { r = 0, b= 1, g= 0}, + } + )} + + +\begin{document} +\font\Emoj={file:seguiemj.ttf:mode=node;colr=yes;} + \Emoj \char"2661 \char"1F34D \char"1F986 + +\font\Emoj={file:seguiemj.ttf:mode=node;colr=demo;} + \Emoj \char"2661 \char"1F34D \char"1F986 + +\font\cow={file:koeielettersot.ttf:mode=node;colr=demo;} at 30pt + \cow ABC + +\end{document}
\ No newline at end of file |