From 78d506538016cd295d9a84ac62e3e036f23feffc Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Sun, 15 Nov 2009 17:10:27 +0200 Subject: updating to latest (beta 2009.11.13) ConTeXt code --- luaotfload.dtx | 10 ++-- otfl-data-con.lua | 2 +- otfl-font-def.lua | 128 +++++++++++++++++++++++++++++++-------------- otfl-font-dum.lua | 5 +- otfl-font-ini.lua | 24 ++++++++- otfl-font-map.lua | 13 +++-- otfl-font-ota.lua | 3 +- otfl-font-otb.lua | 8 +-- otfl-font-otc.lua | 4 +- otfl-font-otd.lua | 2 +- otfl-font-otf.lua | 63 +++++++++++++++++----- otfl-font-oti.lua | 2 +- otfl-font-otn.lua | 152 +++++++++++++++++++++++++++++++++--------------------- otfl-font-ott.lua | 3 +- otfl-font-tfm.lua | 17 ++++-- otfl-font-xtx.lua | 2 +- otfl-luat-dum.lua | 14 +++-- otfl-node-fnt.lua | 3 +- otfl-node-ini.lua | 2 +- otfl-node-inj.lua | 132 ++++++++++++++++++++++++++++++++--------------- otfl-node-res.lua | 29 ++++++++++- 21 files changed, 432 insertions(+), 186 deletions(-) diff --git a/luaotfload.dtx b/luaotfload.dtx index 45768d7..2ef3370 100644 --- a/luaotfload.dtx +++ b/luaotfload.dtx @@ -34,7 +34,7 @@ \input docstrip.tex \Msg{************************************************************************} \Msg{* Installation} -\Msg{* Package: luaotfload 2009/09/22 v1.04 ConTeXt font loading system} +\Msg{* Package: luaotfload 2009/11/15 v1.05 ConTeXt font loading system} \Msg{************************************************************************} \keepsilent @@ -100,7 +100,7 @@ and the derived files %<*driver> \NeedsTeXFormat{LaTeX2e} \ProvidesFile{luaminimalotf.drv}% - [2009/09/22 v1.04 ConTeXt font loading system]% + [2009/11/15 v1.05 ConTeXt font loading system]% \documentclass{ltxdoc} \EnableCrossrefs \CodelineIndex @@ -131,7 +131,7 @@ and the derived files % \GetFileInfo{luaotfload.drv} % % \title{The \textsf{luaotfload} package} -% \date{2009/09/22 v1.04} +% \date{2009/11/15 v1.05} % \author{Elie Roux \\ \texttt{elie.roux@telecom-bretagne.eu}} % % \maketitle @@ -225,7 +225,7 @@ luaotfload = { } luaotfload.module = { name = "luaotfload", version = 1.04, - date = "2009/09/22", + date = "2009/11/15", description = "ConTeXt font loading system.", author = "Elie Roux & Hans Hagen", copyright = "Elie Roux", @@ -475,7 +475,7 @@ end \else \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{luaotfload}% - [2009/09/22 v1.04 ConTeXt font loading system] + [2009/11/15 v1.05 ConTeXt font loading system] \RequirePackage{luatextra} \fi diff --git a/otfl-data-con.lua b/otfl-data-con.lua index 02ee9ee..d35bc7a 100644 --- a/otfl-data-con.lua +++ b/otfl-data-con.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['data-con'] = { version = 1.001, - comment = "companion to luat-lib.tex", + comment = "companion to luat-lib.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" diff --git a/otfl-font-def.lua b/otfl-font-def.lua index 3301c39..65c74d4 100644 --- a/otfl-font-def.lua +++ b/otfl-font-def.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['font-def'] = { version = 1.001, - comment = "companion to font-ini.tex", + 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" @@ -9,7 +9,8 @@ if not modules then modules = { } end modules ['font-def'] = { local format, concat, gmatch, match, find, lower = string.format, table.concat, string.gmatch, string.match, string.find, string.lower local tostring, next = tostring, next -local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) +local trace_defining = false trackers .register("fonts.defining", function(v) trace_defining = v end) +local directive_embedall = false directives.register("fonts.embedall", function(v) directive_embedall = v end) trackers.register("fonts.loading", "fonts.defining", "otf.loading", "afm.loading", "tfm.loading") trackers.register("fonts.all", "fonts.*", "otf.*", "afm.*", "tfm.*") @@ -77,20 +78,35 @@ and prepares a table that will move along as we proceed.

local splitter, specifiers = nil, "" +local P, C, S, Cc = lpeg.P, lpeg.C, lpeg.S, lpeg.Cc + +local left = P("(") +local right = P(")") +local colon = P(":") +local space = P(" ") + +define.defaultlookup = "file" + +local prefixpattern = P(false) + function define.add_specifier(symbol) specifiers = specifiers .. symbol - local left = lpeg.P("(") - local right = lpeg.P(")") - local colon = lpeg.P(":") - local method = lpeg.S(specifiers) - local lookup = lpeg.C(lpeg.P("file")+lpeg.P("name")) * colon -- hard test, else problems with : method - local sub = left * lpeg.C(lpeg.P(1-left-right-method)^1) * right ---~ local specification = lpeg.C(method) * lpeg.C(lpeg.P(1-method)^1) - local specification = lpeg.C(method) * lpeg.C(lpeg.P(1)^1) - local name = lpeg.C((1-sub-specification)^1) - splitter = lpeg.P((lookup + lpeg.Cc("")) * name * (sub + lpeg.Cc("")) * (specification + lpeg.Cc(""))) + local method = S(specifiers) + local lookup = C(prefixpattern) * colon + local sub = left * C(P(1-left-right-method)^1) * right + local specification = C(method) * C(P(1)^1) + local name = C((1-sub-specification)^1) + splitter = P((lookup + Cc("")) * name * (sub + Cc("")) * (specification + Cc(""))) +end + +function define.add_lookup(str,default) + prefixpattern = prefixpattern + P(str) end +define.add_lookup("file") +define.add_lookup("name") +define.add_lookup("spec") + function define.get_specification(str) return splitter:match(str) end @@ -111,8 +127,8 @@ function define.makespecification(specification, lookup, name, sub, method, deta --~ lookup = specification.lookup -- can come from xetex [] syntax --~ specification.lookup = nil --~ end - if lookup ~= 'name' then -- for the moment only two lookups, maybe some day also system: - lookup = 'file' + if not lookup or lookup == "" then + lookup = define.defaultlookup end local t = { lookup = lookup, -- forced type @@ -132,7 +148,7 @@ end function define.analyze(specification, size) -- can be optimized with locals local lookup, name, sub, method, detail = define.get_specification(specification or "") - return define.makespecification(specification,lookup, name, sub, method, detail, size) + return define.makespecification(specification, lookup, name, sub, method, detail, size) end --[[ldx-- @@ -214,17 +230,44 @@ end

We can resolve the filename using the next function:

--ldx]]-- +define.resolvers = resolvers + +function define.resolvers.file(specification) + specification.forced = file.extname(specification.name) + specification.name = file.removesuffix(specification.name) +end + +function define.resolvers.name(specification) + local resolve = fonts.names.resolve + if resolve then + specification.resolved, specification.sub = fonts.names.resolve(specification.name,specification.sub) + if specification.resolved then + specification.forced = file.extname(specification.resolved) + specification.name = file.removesuffix(specification.resolved) + end + else + define.resolvers.file(specification) + end +end + +function define.resolvers.spec(specification) + local resolvespec = fonts.names.resolvespec + if resolvespec then + specification.resolved, specification.sub = fonts.names.resolvespec(specification.name,specification.sub) + if specification.resolved then + specification.forced = file.extname(specification.resolved) + specification.name = file.removesuffix(specification.resolved) + end + else + define.resolvers.name(specification) + end +end + function define.resolve(specification) if not specification.resolved or specification.resolved == "" then -- resolved itself not per se in mapping hash - if specification.lookup == 'name' then - specification.resolved, specification.sub = fonts.names.resolve(specification.name,specification.sub) - if specification.resolved then - specification.forced = file.extname(specification.resolved) - specification.name = file.removesuffix(specification.resolved) - end - elseif specification.lookup == 'file' then - specification.forced = file.extname(specification.name) - specification.name = file.removesuffix(specification.name) + local r = define.resolvers[specification.lookup] + if r then + r(specification) end end if specification.forced == "" then @@ -232,7 +275,6 @@ function define.resolve(specification) else specification.forced = specification.forced end ---~ specification.hash = specification.name .. ' @ ' .. tfm.hash_features(specification) specification.hash = lower(specification.name .. ' @ ' .. tfm.hash_features(specification)) if specification.sub and specification.sub ~= "" then specification.hash = specification.sub .. ' @ ' .. specification.hash @@ -271,15 +313,21 @@ function tfm.read(specification) local reader = sequence[s] if readers[reader] then -- not really needed if trace_defining then - logs.report("define font","trying type %s for %s with file %s",reader,specification.name,specification.filename or "unknown") + logs.report("define font","trying (sequence driven) type %s for %s with file %s",reader,specification.name,specification.filename or "unknown") end tfmtable = readers[reader](specification) - if tfmtable then break end + if tfmtable then + break + else + specification.filename = nil + end end end end if tfmtable then - if tfmtable.filename and fonts.dontembed[tfmtable.filename] then + if directive_embedall then + tfmtable.embedding = "full" + elseif tfmtable.filename and fonts.dontembed[tfmtable.filename] then tfmtable.embedding = "no" else tfmtable.embedding = "subset" @@ -402,16 +450,22 @@ function readers.afm(specification,method) return tfmtable end -local function check_otf(specification,suffix,what) - local fullname, tfmtable = resolvers.findbinfile(specification.name,suffix) or "", nil +-- maybe some day a set of names + +local function check_otf(forced,specification,suffix,what) + local name = specification.name + if forced then + name = file.addsuffix(name,suffix) + end + local fullname, tfmtable = resolvers.findbinfile(name,suffix) or "", nil -- one shot if fullname == "" then - local fb = fonts.names.old_to_new[specification.name] + local fb = fonts.names.old_to_new[name] if fb then fullname = resolvers.findbinfile(fb,suffix) or "" end end if fullname == "" then - local fb = fonts.names.new_to_old[specification.name] + local fb = fonts.names.new_to_old[name] if fb then fullname = resolvers.findbinfile(fb,suffix) or "" end @@ -426,13 +480,11 @@ end function readers.opentype(specification,suffix,what) local forced = specification.forced or "" if forced == "otf" then - return check_otf(specification,forced,"opentype") - elseif forced == "ttf" then - return check_otf(specification,forced,"truetype") - elseif forced == "ttf" then - return check_otf(specification,forced,"truetype") + return check_otf(true,specification,forced,"opentype") + elseif forced == "ttf" or forced == "ttc" or forced == "dfont" then + return check_otf(true,specification,forced,"truetype") else - return check_otf(specification,suffix,what) + return check_otf(false,specification,suffix,what) end end diff --git a/otfl-font-dum.lua b/otfl-font-dum.lua index ef267a4..c585c18 100644 --- a/otfl-font-dum.lua +++ b/otfl-font-dum.lua @@ -42,6 +42,7 @@ end fonts.names = fonts.names or { } +fonts.names.version = 1.014 fonts.names.basename = "luatex-fonts-names.lua" fonts.names.new_to_old = { } fonts.names.old_to_new = { } @@ -72,7 +73,7 @@ function fonts.names.resolve(name,sub) end loaded = true end - if type(data) == "table" and data.version == 1.08 then + if type(data) == "table" and data.version == fonts.names.version then local condensed = string.gsub(string.lower(name),"[^%a%d]","") local found = data.mapping and data.mapping[condensed] if found then @@ -85,6 +86,8 @@ function fonts.names.resolve(name,sub) end end +fonts.names.resolvespec = fonts.names.resolve -- only supported in mkiv + -- For the moment we put this (adapted) pseudo feature here. table.insert(fonts.triggers,"itlc") diff --git a/otfl-font-ini.lua b/otfl-font-ini.lua index 4005726..5cff227 100644 --- a/otfl-font-ini.lua +++ b/otfl-font-ini.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['font-ini'] = { version = 1.001, - comment = "companion to font-ini.tex", + 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" @@ -11,6 +11,8 @@ if not modules then modules = { } end modules ['font-ini'] = { --ldx]]-- local utf = unicode.utf8 +local format, serialize = string.format, table.serialize +local write_nl = texio.write_nl if not fontloader then fontloader = fontforge end @@ -30,6 +32,7 @@ fonts.verbose = false -- more verbose cache tables fonts.ids[0] = { -- nullfont characters = { }, descriptions = { }, + name = "nullfont", } fonts.methods = fonts.methods or { @@ -91,7 +94,24 @@ function fonts.show_char_data(n) end local chr = tfmdata.characters[n] if chr then - texio.write_nl(table.serialize(chr,string.format("U_%04X",n))) + write_nl(format("%s @ %s => U%04X => %s => ",tfmdata.fullname,tfmdata.size,n,utf.char(n)) .. serialize(chr,false)) + end + end +end + +function fonts.show_font_parameters() + local tfmdata = fonts.ids[font.current()] + if tfmdata then + local parameters, mathconstants = tfmdata.parameters, tfmdata.MathConstants + local hasparameters, hasmathconstants = parameters and next(parameters), mathconstants and next(mathconstants) + if hasparameters then + write_nl(format("%s @ %s => parameters => ",tfmdata.fullname,tfmdata.size) .. serialize(parameters,false)) + end + if hasmathconstants then + write_nl(format("%s @ %s => math constants => ",tfmdata.fullname,tfmdata.size) .. serialize(mathconstants,false)) + end + if not hasparameters and not hasmathconstants then + write_nl(format("%s @ %s => no parameters and/or mathconstants",tfmdata.fullname,tfmdata.size)) end end end diff --git a/otfl-font-map.lua b/otfl-font-map.lua index c597d48..0dc4eca 100644 --- a/otfl-font-map.lua +++ b/otfl-font-map.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['font-map'] = { version = 1.001, - comment = "companion to font-ini.tex", + 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" @@ -10,7 +10,7 @@ local match, format, find, concat = string.match, string.format, string.find, ta local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end) -local ctxcatcodes = tex.ctxcatcodes +local ctxcatcodes = tex and tex.ctxcatcodes --[[ldx--

Eventually this code will disappear because map files are kind @@ -141,13 +141,15 @@ end local hex = lpeg.R("AF","09") local hexfour = (hex*hex*hex*hex) / function(s) return tonumber(s,16) end -local dec = (lpeg.R("09")^1) / tonumber +local hexsix = (hex^1) / function(s) return tonumber(s,16) end +local dec = (lpeg.R("09")^1) / tonumber local period = lpeg.P(".") local unicode = lpeg.P("uni") * (hexfour * (period + lpeg.P(-1)) * lpeg.Cc(false) + lpeg.Ct(hexfour^1) * lpeg.Cc(true)) +local ucode = lpeg.P("u") * (hexsix * (period + lpeg.P(-1)) * lpeg.Cc(false) + lpeg.Ct(hexsix ^1) * lpeg.Cc(true)) local index = lpeg.P("index") * dec * lpeg.Cc(false) -local parser = unicode + index +local parser = unicode + ucode + index local parsers = { } @@ -165,10 +167,13 @@ function fonts.map.make_name_parser(str) end --~ local parser = fonts.map.make_name_parser("Japan1") +--~ local parser = fonts.map.make_name_parser() --~ local function test(str) --~ local b, a = parser:match(str) --~ print((a and table.serialize(b)) or b) --~ end +--~ test("a.sc") +--~ test("a") --~ test("uni1234") --~ test("uni1234.xx") --~ test("uni12349876") diff --git a/otfl-font-ota.lua b/otfl-font-ota.lua index 72e7414..e2fa3f2 100644 --- a/otfl-font-ota.lua +++ b/otfl-font-ota.lua @@ -131,7 +131,8 @@ local isol_fina = { [0x06D3] = true, [0x06D5] = true, [0x06EE] = true, [0x06EF] = true, [0x0759] = true, [0x075A] = true, [0x075B] = true, [0x076B] = true, [0x076C] = true, [0x0771] = true, [0x0773] = true, [0x0774] = true, - [0x0778] = true, [0x0779] = true, + [0x0778] = true, [0x0779] = true, [0xFEF5] = true, [0xFEF7] = true, + [0xFEF9] = true, [0xFEFB] = true, } local isol_fina_medi_init = { diff --git a/otfl-font-otb.lua b/otfl-font-otb.lua index 5ef44a0..127d4c2 100644 --- a/otfl-font-otb.lua +++ b/otfl-font-otb.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['font-otb'] = { version = 1.001, - comment = "companion to font-ini.tex", + 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" @@ -309,7 +309,7 @@ local supported_gsub = { 'zero', 'smcp','cpsp','c2sc','ornm','aalt', 'hwid','fwid', - 'ssty', -- math + 'ssty', 'rtlm', -- math } local supported_gpos = { @@ -361,8 +361,8 @@ function fonts.initializers.base.otf.features(tfmdata,value) -- eventually (and subset later on). If needed we can use a more -- verbose name as long as we don't use <()<>[]{}/%> and the length -- is < 128. - tfmdata.fullname = tfmdata.fullname .. "-" .. base ---~ logs.report("otf define","fullname base hash: '%s', featureset '%s'",tfmdata.fullname,hash) + tfmdata.fullname = tfmdata.fullname .. "-" .. base -- tfmdata.psname is the original + --~ logs.report("otf define","fullname base hash: '%s', featureset '%s'",tfmdata.fullname,hash) end if trace_preparing then logs.report("otf define","preparation time is %0.3f seconds for %s",os.clock()-t,tfmdata.fullname or "?") diff --git a/otfl-font-otc.lua b/otfl-font-otc.lua index f75da39..1fc1f22 100644 --- a/otfl-font-otc.lua +++ b/otfl-font-otc.lua @@ -219,7 +219,9 @@ function otf.name_to_slot(name) -- todo: afm en tfm if tfmdata and tfmdata.shared then local otfdata = tfmdata.shared.otfdata local unicode = otfdata.luatex.unicodes[name] - if type(unicode) == "number" then + if not unicode then + return string.byte("?") -- nil + elseif type(unicode) == "number" then return unicode else return unicode[1] diff --git a/otfl-font-otd.lua b/otfl-font-otd.lua index 78a8281..41e8853 100644 --- a/otfl-font-otd.lua +++ b/otfl-font-otd.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['font-otd'] = { version = 1.001, - comment = "companion to font-ini.tex", + 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" diff --git a/otfl-font-otf.lua b/otfl-font-otf.lua index f3b3f54..b5f7cb4 100644 --- a/otfl-font-otf.lua +++ b/otfl-font-otf.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['font-otf'] = { version = 1.001, - comment = "companion to font-ini.tex", + 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" @@ -19,6 +19,7 @@ local trace_dynamics = false trackers.register("otf.dynamics", function(v local trace_sequences = false trackers.register("otf.sequences", function(v) trace_sequences = v end) local trace_math = false trackers.register("otf.math", function(v) trace_math = v end) local trace_unimapping = false trackers.register("otf.unimapping", function(v) trace_unimapping = v end) +local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) --~ trackers.enable("otf.loading") @@ -82,7 +83,7 @@ otf.features.default = otf.features.default or { } otf.enhancers = otf.enhancers or { } otf.glists = { "gsub", "gpos" } -otf.version = 2.628 -- beware: also sync font-mis.lua +otf.version = 2.635 -- beware: also sync font-mis.lua otf.pack = true -- beware: also sync font-mis.lua otf.syncspace = true otf.notdef = false @@ -104,6 +105,7 @@ otf.tables.global_fields = table.tohash { "names", "unicodes", "names", +--~ "math", "anchor_classes", "kern_classes", "gpos", @@ -202,6 +204,7 @@ local enhancers = { "patch bugs", "merge cid fonts", "prepare unicode", "cleanup ttf tables", "compact glyphs", "reverse coverage", "cleanup aat", "enrich with features", "add some missing characters", + "reorganize mark classes", "reorganize kerns", -- moved here "flatten glyph lookups", "flatten anchor tables", "flatten feature tables", "prepare luatex tables", @@ -227,7 +230,7 @@ function otf.load(filename,format,sub,featurefile) local data = containers.read(otf.cache(), hash) local size = lfs.attributes(filename,"size") or 0 if not data or data.verbose ~= fonts.verbose or data.size ~= size then - logs.report("load otf","loading: %s",filename) + logs.report("load otf","loading: %s (hash: %s)",filename,hash) local ff, messages if sub then ff, messages = fontloader.open(filename,sub) @@ -267,6 +270,9 @@ function otf.load(filename,format,sub,featurefile) end end if data then + if trace_defining then + logs.report("define font","loading from cache: %s",hash) + end otf.enhance("unpack",data,filename,false) -- no message here otf.add_dimensions(data) if trace_sequences then @@ -354,6 +360,29 @@ end -- todo: normalize, design_size => designsize +otf.enhancers["reorganize mark classes"] = function(data,filename) + if data.mark_classes then + local unicodes = data.luatex.unicodes + local reverse = { } + for name, class in next, data.mark_classes do + local t = { } + for s in gmatch(class,"[^ ]+") do + local us = unicodes[s] + if type(us) == "table" then + for u=1,#us do + t[us[u]] = true + end + else + t[us] = true + end + end + reverse[name] = t + end + data.luatex.markclasses = reverse + data.mark_classes = nil + end +end + otf.enhancers["prepare luatex tables"] = function(data,filename) data.luatex = data.luatex or { } local luatex = data.luatex @@ -500,6 +529,7 @@ otf.enhancers["analyse unicodes"] = function(data,filename) cidcodes = usedmap.unicodes end uparser = fonts.map.make_name_parser() + local aglmap = fonts.map and fonts.map.agl_to_unicode for index, glyph in next, data.glyphs do local name, unic = glyph.name, glyph.unicode or -1 -- play safe if unic == -1 or unic >= private or (unic >= 0xE000 and unic <= 0xF8FF) or unic == 0xFFFE or unic == 0xFFFF then @@ -509,7 +539,7 @@ otf.enhancers["analyse unicodes"] = function(data,filename) end -- cidmap heuristics, beware, there is no guarantee for a match unless -- the chain resolves - if not unicode and usedmap then + if (not unicode) and usedmap then local foundindex = oparser:match(name) if foundindex then unicode = cidcodes[foundindex] -- name to number @@ -544,7 +574,8 @@ otf.enhancers["analyse unicodes"] = function(data,filename) if nplit == 0 then -- skip elseif nplit == 1 then - unicode = unicodes[split[1]] + local base = split[1] + unicode = unicodes[base] or (agl and agl[base]) if unicode then if type(unicode) == "table" then unicode = unicode[1] @@ -552,20 +583,20 @@ otf.enhancers["analyse unicodes"] = function(data,filename) originals[index], tounicode[index], ns = unicode, tounicode16(unicode), ns + 1 end else - local done = true + local t = { } for l=1,nplit do - local u = unicodes[split[l]] + local base = split[l] + local u = unicodes[base] or (agl and agl[base]) if not u then - done = false break elseif type(u) == "table" then - split[l] = u[1] + t[#t+1] = u[1] else - split[l] = u + t[#t+1] = u end end - if done then - originals[index], tounicode[index], nl, unicode = split, tounicode16sequence(split), nl + 1, true + if #t > 0 then -- done then + originals[index], tounicode[index], nl, unicode = t, tounicode16sequence(t), nl + 1, true end end end @@ -658,8 +689,11 @@ otf.enhancers["analyse subtables"] = function(data,filename) (flags.ignorecombiningmarks and "mark") or false, (flags.ignoreligatures and "ligature") or false, (flags.ignorebaseglyphs and "base") or false, - flags.r2l or false + flags.r2l or false, } + if flags.mark_class then + gk.markclass = luatex.markclasses[flags.mark_class] + end end end end @@ -756,7 +790,7 @@ otf.enhancers["prepare unicode"] = function(data,filename) end end end - -- beware: the indeces table is used to initialize the tfm table + -- beware: the indices table is used to initialize the tfm table for unicode, index in next, mapmap do if not internals[index] then local name = glyphs[index].name @@ -1464,6 +1498,7 @@ function otf.copy_to_tfm(data,cache_id) -- we can save a copy when we reorder th -- we need a runtime lookup because of running from cdrom or zip, brrr tfm.filename = resolvers.findbinfile(luatex.filename,"") or luatex.filename tfm.fullname = metadata.fontname or metadata.fullname + tfm.psname = tfm.fullname tfm.encodingbytes = 2 tfm.cidinfo = data.cidinfo tfm.cidinfo.registry = tfm.cidinfo.registry or "" diff --git a/otfl-font-oti.lua b/otfl-font-oti.lua index cbac6d3..4cb2706 100644 --- a/otfl-font-oti.lua +++ b/otfl-font-oti.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['font-oti'] = { version = 1.001, - comment = "companion to font-ini.tex", + 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" diff --git a/otfl-font-otn.lua b/otfl-font-otn.lua index 3c11b84..77d67d4 100644 --- a/otfl-font-otn.lua +++ b/otfl-font-otn.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['font-otn'] = { version = 1.001, - comment = "companion to font-ini.tex", + 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" @@ -10,6 +10,8 @@ if not modules then modules = { } end modules ['font-otn'] = { -- much functionality could only be implemented thanks to the husayni font -- of Idris Samawi Hamid to who we dedicate this module. +-- some day when we can jit this, we can use more functions + -- we can use more lpegs when lpeg is extended with function args and so -- resolving to unicode does not gain much @@ -136,6 +138,7 @@ local trace_bugs = false trackers.register("otf.bugs", function local trace_details = false trackers.register("otf.details", function(v) trace_details = v end) local trace_applied = false trackers.register("otf.applied", function(v) trace_applied = v end) local trace_steps = false trackers.register("otf.steps", function(v) trace_steps = v end) +local trace_skips = false trackers.register("otf.skips", function(v) trace_skips = v end) trackers.register("otf.verbose_chain", function(v) otf.setcontextchain(v and "verbose") end) trackers.register("otf.normal_chain", function(v) otf.setcontextchain(v and "normal") end) @@ -301,16 +304,29 @@ end local function toligature(kind,lookupname,start,stop,char,markflag,discfound) -- brr head if start ~= stop then +--~ if discfound then +--~ local lignode = copy_node(start) +--~ lignode.font = start.font +--~ lignode.char = char +--~ lignode.subtype = 2 +--~ start = node.do_ligature_n(start, stop, lignode) +--~ if start.id == disc then +--~ local prev = start.prev +--~ start = start.next +--~ end if discfound then + -- print("start->stop",nodes.tosequence(start,stop)) local lignode = copy_node(start) - lignode.font = start.font - lignode.char = char - lignode.subtype = 2 - start = node.do_ligature_n(start, stop, lignode) - if start.id == disc then - local prev = start.prev - start = start.next + lignode.font, lignode.char, lignode.subtype = start.font, char, 2 + local next, prev = stop.next, start.prev + stop.next = nil + lignode = node.do_ligature_n(start, stop, lignode) + prev.next = lignode + if next then + next.prev = lignode end + lignode.next, lignode.prev = next, prev + -- print("start->end",nodes.tosequence(start)) else -- start is the ligature local deletemarks = markflag ~= "mark" local n = copy_node(start) @@ -385,16 +401,19 @@ local function alternative_glyph(start,alternatives,kind,chainname,chainlookupna value, choice = format("first, choice %s",1), alternatives[1] elseif value == "last" then value, choice = format("last, choice %s",n), alternatives[n] - elseif type(value) ~= "number" then - value, choice = "default, choice 1", alternatives[1] - elseif value > n then - value, choice = format("no %s variants, taking %s",value,n), alternatives[n] - elseif value == 0 then - value, choice = format("choice %s (no change)",value), start.char - elseif value < 1 then - value, choice = format("no %s variants, taking %s",value,1), alternatives[1] else - value, choice = format("choice %s",value), alternatives[value] + value = tonumber(value) + if type(value) ~= "number" then + value, choice = "default, choice 1", alternatives[1] + elseif value > n then + value, choice = format("no %s variants, taking %s",value,n), alternatives[n] + elseif value == 0 then + value, choice = format("choice %s (no change)",value), start.char + elseif value < 1 then + value, choice = format("no %s variants, taking %s",value,1), alternatives[1] + else + value, choice = format("choice %s",value), alternatives[value] + end end if not choice then logwarning("%s: no variant %s for %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(start.char)) @@ -752,9 +771,9 @@ end function handlers.gpos_single(start,kind,lookupname,kerns,sequence) local startchar = start.char - local dx, dy = set_pair(start,tfmdata.factor,rlmode,kerns,characters[startchar]) + local dx, dy, w, h = set_pair(start,tfmdata.factor,rlmode,sequence.flags[4],kerns,characters[startchar]) if trace_kerns then - logprocess("%s: shifting single %s by (%s,%s)",pref(kind,lookupname),gref(startchar),dx,dy) + logprocess("%s: shifting single %s by (%s,%s) and correction (%s,%s)",pref(kind,lookupname),gref(startchar),dx,dy,w,h) end return start, false end @@ -783,14 +802,14 @@ local krn = kerns[nextchar] local a, b = krn[3], krn[4] if a and #a > 0 then local startchar = start.char - local x, y, w, h = set_pair(start,factor,rlmode,a,characters[startchar]) + local x, y, w, h = set_pair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) if trace_kerns then logprocess("%s: shifting first of pair %s and %s by (%s,%s) and correction (%s,%s)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) end end if b and #b > 0 then local startchar = start.char - local x, y, w, h = set_pair(snext,factor,rlmode,b,characters[nextchar]) + local x, y, w, h = set_pair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) if trace_kerns then logprocess("%s: shifting second of pair %s and %s by (%s,%s) and correction (%s,%s)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) end @@ -1404,7 +1423,7 @@ function chainprocs.gpos_cursive(start,stop,kind,chainname,currentcontext,cache, return start, false end -function chainprocs.gpos_single(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname) +function chainprocs.gpos_single(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,chainindex,sequence) -- untested local startchar = start.char local subtables = currentlookup.subtables @@ -1413,9 +1432,9 @@ function chainprocs.gpos_single(start,stop,kind,chainname,currentcontext,cache,c if kerns then kerns = kerns[startchar] if kerns then - local dx, dy = set_pair(start,tfmdata.factor,rlmode,kerns,characters[startchar]) + local dx, dy, w, h = set_pair(start,tfmdata.factor,rlmode,sequence.flags[4],kerns,characters[startchar]) if trace_kerns then - logprocess("%s: shifting single %s by (%s,%s)",cref(kind,chainname,chainlookupname),gref(startchar),dx,dy) + logprocess("%s: shifting single %s by (%s,%s) and correction (%s,%s)",cref(kind,chainname,chainlookupname),gref(startchar),dx,dy,w,h) end end end @@ -1424,7 +1443,7 @@ end -- when machines become faster i will make a shared function -function chainprocs.gpos_pair(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname) +function chainprocs.gpos_pair(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,chainindex,sequence) -- logwarning("%s: gpos_pair not yet supported",cref(kind,chainname,chainlookupname)) local snext = start.next if snext then @@ -1439,12 +1458,11 @@ function chainprocs.gpos_pair(start,stop,kind,chainname,currentcontext,cache,cur local factor = tfmdata.factor while snext and snext.id == glyph and snext.subtype<256 and snext.font == currentfont do local nextchar = snext.char -local krn = kerns[nextchar] + local krn = kerns[nextchar] if not krn and marks[nextchar] then prev = snext snext = snext.next else ---~ local krn = kerns[nextchar] if not krn then -- skip elseif type(krn) == "table" then @@ -1452,14 +1470,14 @@ local krn = kerns[nextchar] local a, b = krn[3], krn[4] if a and #a > 0 then local startchar = start.char - local x, y, w, h = set_pair(start,factor,rlmode,a,characters[startchar]) + local x, y, w, h = set_pair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) if trace_kerns then logprocess("%s: shifting first of pair %s and %s by (%s,%s) and correction (%s,%s)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) end end if b and #b > 0 then local startchar = start.char - local x, y, w, h = set_pair(snext,factor,rlmode,b,characters[nextchar]) + local x, y, w, h = set_pair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) if trace_kerns then logprocess("%s: shifting second of pair %s and %s by (%s,%s) and correction (%s,%s)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) end @@ -1503,19 +1521,29 @@ end -- we don't need to pass the currentcontext, saves a bit -- make a slow variant then can be activated but with more tracing +local function show_skip(kind,chainname,char,ck,class) + if ck[9] then + logwarning("%s: skipping char %s (%s) in rule %s, lookuptype %s (%s=>%s)",cref(kind,chainname),gref(char),class,ck[1],ck[2],ck[9],ck[10]) + else + logwarning("%s: skipping char %s (%s) in rule %s, lookuptype %s",cref(kind,chainname),gref(char),class,ck[1],ck[2]) + end +end + local function normal_handle_contextchain(start,kind,chainname,contexts,sequence,cache) -- local rule, lookuptype, sequence, f, l, lookups = ck[1], ck[2] ,ck[3], ck[4], ck[5], ck[6] local flags, done = sequence.flags, false local skipmark, skipligature, skipbase = flags[1], flags[2], flags[3] local someskip = skipmark or skipligature or skipbase -- could be stored in flags for a fast test (hm, flags could be false !) + local markclass = sequence.markclass -- todo, first we need a proper test for k=1,#contexts do local match, current, last = true, start, start local ck = contexts[k] - local sequence = ck[3] - local s = #sequence + local seq = ck[3] + local s = #seq + -- f..l = mid string if s == 1 then -- never happens - match = current.id == glyph and current.subtype<256 and current.font == currentfont and sequence[1][current.char] + match = current.id == glyph and current.subtype<256 and current.font == currentfont and seq[1][current.char] else -- todo: better space check (maybe check for glue) local f, l = ck[4], ck[5] @@ -1529,7 +1557,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence -- we cannot optimize for n=2 because there can be disc nodes -- if not someskip and n == l then -- -- n=2 and no skips then faster loop - -- match = last and last.id == glyph and last.subtype<256 and last.font == currentfont and sequence[n][last.char] + -- match = last and last.id == glyph and last.subtype<256 and last.font == currentfont and seq[n][last.char] -- else while n <= l do if last then @@ -1540,11 +1568,12 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence local ccd = descriptions[char] if ccd then local class = ccd.class - if class == skipmark or class == skipligature or class == skipbase then ---~ if someskip and class == skipmark or class == skipligature or class == skipbase then - -- skip 'm + if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then + if trace_skips then + show_skip(kind,chainname,char,ck,class) + end last = last.next - elseif sequence[n][char] then + elseif seq[n][char] then if n < l then last = last.next end @@ -1570,6 +1599,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence -- end end if match and f > 1 then + -- before local prev = start.prev if prev then local n = f-1 @@ -1582,10 +1612,11 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence local ccd = descriptions[char] if ccd then local class = ccd.class - if class == skipmark or class == skipligature or class == skipbase then ---~ if someskip and class == skipmark or class == skipligature or class == skipbase then - -- skip 'm - elseif sequence[n][char] then + if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then + if trace_skips then + show_skip(kind,chainname,char,ck,class) + end + elseif seq[n][char] then n = n -1 else match = false break @@ -1598,32 +1629,33 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence end elseif id == disc then -- skip 'm - elseif sequence[n][32] then + elseif seq[n][32] then n = n -1 else match = false break end prev = prev.prev - elseif sequence[n][32] then + elseif seq[n][32] then n = n -1 else match = false break end end elseif f == 2 then - match = sequence[1][32] + match = seq[1][32] else for n=f-1,1 do - if not sequence[n][32] then + if not seq[n][32] then match = false break end end end end if match and s > l then + -- after local current = last.next if current then - -- removed optimiziation for s-l == 1, we have to deal with marks anyway + -- removed optimization for s-l == 1, we have to deal with marks anyway local n = l + 1 while n <= s do if current then @@ -1634,10 +1666,11 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence local ccd = descriptions[char] if ccd then local class = ccd.class - if class == skipmark or class == skipligature or class == skipbase then ---~ if someskip and class == skipmark or class == skipligature or class == skipbase then - -- skip 'm - elseif sequence[n][char] then + if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then + if trace_skips then + show_skip(kind,chainname,char,ck,class) + end + elseif seq[n][char] then n = n + 1 else match = false break @@ -1650,23 +1683,23 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence end elseif id == disc then -- skip 'm - elseif sequence[n][32] then -- brrr + elseif seq[n][32] then -- brrr n = n + 1 else match = false break end current = current.next - elseif sequence[n][32] then + elseif seq[n][32] then n = n + 1 else match = false break end end elseif s-l == 1 then - match = sequence[s][32] + match = seq[s][32] else for n=l+1,s do - if not sequence[n][32] then + if not seq[n][32] then match = false break end end @@ -1676,7 +1709,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence if match then -- ck == currentcontext if trace_contexts then - local rule, lookuptype, sequence, f, l = ck[1], ck[2] ,ck[3], ck[4], ck[5] + local rule, lookuptype, f, l = ck[1], ck[2], ck[4], ck[5] local char = start.char if ck[9] then logwarning("%s: rule %s matches at char %s for (%s,%s,%s) chars, lookuptype %s (%s=>%s)",cref(kind,chainname),rule,gref(char),f-1,l-f+1,s-l,lookuptype,ck[9],ck[10]) @@ -1693,7 +1726,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence local chainlookup = lookuptable[chainlookupname] local cp = chainprocs[chainlookup.type] if cp then - start, done = cp(start,last,kind,chainname,ck,cache,chainlookup,chainlookupname) + start, done = cp(start,last,kind,chainname,ck,cache,chainlookup,chainlookupname,nil,sequence) else logprocess("%s: %s is not yet supported",cref(kind,chainname,chainlookupname),chainlookup.type) end @@ -1706,7 +1739,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence local cp = chainmores[chainlookup.type] if cp then local ok, n - start, ok, n = cp(start,last,kind,chainname,ck,cache,chainlookup,chainlookupname,i) + start, ok, n = cp(start,last,kind,chainname,ck,cache,chainlookup,chainlookupname,i,sequence) -- messy since last can be changed ! if ok then done = true @@ -1725,7 +1758,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence else local replacements = ck[7] if replacements then - start, done = chainprocs.reversesub(start,last,kind,chainname,ck,cache,replacements) + start, done = chainprocs.reversesub(start,last,kind,chainname,ck,cache,replacements) -- sequence else done = true -- can be meant to be skipped if trace_contexts then @@ -1797,6 +1830,8 @@ end local resolved = { } -- we only resolve a font,script,language pair once +-- todo: pass all these 'locals' in a table + function fonts.methods.node.otf.features(head,font,attr) if trace_steps then checkstep(head) @@ -1956,6 +1991,7 @@ function fonts.methods.node.otf.features(head,font,attr) -- sequence kan weg local ok start, ok = handler(start,r[4],lookupname,lookupmatch,sequence,featuredata,1) +--~ texio.write_nl(tostring(lookupname),tostring(lookupmatch),tostring(ok)) if ok then success = true end diff --git a/otfl-font-ott.lua b/otfl-font-ott.lua index 47c2e0e..55cb734 100644 --- a/otfl-font-ott.lua +++ b/otfl-font-ott.lua @@ -87,7 +87,7 @@ otf.tables.scripts = { ['ugar'] = 'Ugaritic Cuneiform', ['xpeo'] = 'Old Persian Cuneiform', ['xsux'] = 'Sumero-Akkadian Cuneiform', - ['yi' ] = 'Yi' + ['yi' ] = 'Yi', } otf.tables.languages = { @@ -569,6 +569,7 @@ otf.tables.features = { ['rphf'] = 'Reph Form', ['rtbd'] = 'Right Bounds', ['rtla'] = 'Right-To-Left Alternates', + ['rtlm'] = 'Right To Left Math', -- math ['ruby'] = 'Ruby Notation Forms', ['salt'] = 'Stylistic Alternates', ['sinf'] = 'Scientific Inferiors', diff --git a/otfl-font-tfm.lua b/otfl-font-tfm.lua index 8b799df..5768293 100644 --- a/otfl-font-tfm.lua +++ b/otfl-font-tfm.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['font-tfm'] = { version = 1.001, - comment = "companion to font-ini.tex", + 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" @@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['font-tfm'] = { local utf = unicode.utf8 -local next, format, match, lower = next, string.format, string.match, string.lower +local next, format, match, lower, gsub = next, string.format, string.match, string.lower, string.gsub local concat, sortedkeys, utfbyte, serialize = table.concat, table.sortedkeys, utf.byte, table.serialize local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) @@ -225,7 +225,7 @@ end local charactercache = { } -- The scaler is only used for otf and afm and virtual fonts. If --- a virtual font has italic correction make sur eto set the +-- a virtual font has italic correction make sure to set the -- has_italic flag. Some more flags will be added in the future. function tfm.do_scale(tfmtable, scaledpoints) @@ -258,6 +258,9 @@ function tfm.do_scale(tfmtable, scaledpoints) t.unicodes = tfmtable.unicodes t.indices = tfmtable.indices t.marks = tfmtable.marks +t.goodies = tfmtable.goodies +t.colorscheme = tfmtable.colorscheme +--~ t.embedding = tfmtable.embedding t.descriptions = descriptions if tfmtable.fonts then t.fonts = table.fastcopy(tfmtable.fonts) -- hm also at the end @@ -362,6 +365,7 @@ local private = fonts.private end end if hasquality then + -- we could move these calculations elsewhere (saves calculations) local ve = v.expansion_factor if ve then chr.expansion_factor = ve*1000 -- expansionfactor, hm, can happen elsewhere @@ -553,6 +557,13 @@ end end t.nomath, t.MathConstants = true, nil end + -- fullname is used in the subsetting + if not t.psname then + t.psname = t.fullname -- else bad luck + end + if trace_defining then + logs.report("define font","used for subsetting: %s ",t.fullname or "nofullname") + end return t, delta end diff --git a/otfl-font-xtx.lua b/otfl-font-xtx.lua index 7b3f1ec..8aecae8 100644 --- a/otfl-font-xtx.lua +++ b/otfl-font-xtx.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['font-xtx'] = { version = 1.001, - comment = "companion to font-ini.tex", + 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" diff --git a/otfl-luat-dum.lua b/otfl-luat-dum.lua index f2ff505..dd5ade7 100644 --- a/otfl-luat-dum.lua +++ b/otfl-luat-dum.lua @@ -13,6 +13,11 @@ statistics = { starttiming = dummyfunction, stoptiming = dummyfunction, } +directives = { + register = dummyfunction, + enable = dummyfunction, + disable = dummyfunction, +} trackers = { register = dummyfunction, enable = dummyfunction, @@ -40,10 +45,11 @@ texconfig.kpse_init = true resolvers = resolvers or { } -- no fancy file helpers used local remapper = { - otf = "opentype fonts", - ttf = "truetype fonts", - ttc = "truetype fonts", - cid = "other text files", -- will become "cid files" + otf = "opentype fonts", + ttf = "truetype fonts", + ttc = "truetype fonts", + dfont = "truetype dictionary", + cid = "other text files", -- will become "cid files" } function resolvers.find_file(name,kind) diff --git a/otfl-node-fnt.lua b/otfl-node-fnt.lua index 3ad9060..72bb140 100644 --- a/otfl-node-fnt.lua +++ b/otfl-node-fnt.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['node-fnt'] = { version = 1.001, - comment = "companion to font-ini.tex", + 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" @@ -178,7 +178,6 @@ else do -- X000 1100 = 12 = 0x1C = leftghost -- X001 0100 = 20 = 0x14 = rightghost - function nodes.protect_glyphs(head) local done = false for g in traverse_id(glyph,head) do diff --git a/otfl-node-ini.lua b/otfl-node-ini.lua index 3ff73c6..741e53d 100644 --- a/otfl-node-ini.lua +++ b/otfl-node-ini.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['node-ini'] = { version = 1.001, - comment = "companion to node-ini.tex", + comment = "companion to node-ini.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" diff --git a/otfl-node-inj.lua b/otfl-node-inj.lua index dc676a4..4c58409 100644 --- a/otfl-node-inj.lua +++ b/otfl-node-inj.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['node-inj'] = { version = 1.001, - comment = "companion to node-ini.tex", + comment = "companion to node-ini.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" @@ -10,7 +10,8 @@ if not modules then modules = { } end modules ['node-inj'] = { -- This is very experimental (this will change when we have luatex > .50 and -- a few pending thingies are available. Also, Idris needs to make a few more --- test fonts. +-- test fonts. Btw, future versions of luatex will have extended glyph properties +-- that can be of help. local next = next @@ -50,6 +51,8 @@ local kerns = { } -- explicitly i will provide an alternative; also, we can share -- tables +-- for the moment we pass the r2l key ... volt/arabtype tests + function nodes.set_cursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext) local dx, dy = factor*(exit[1]-entry[1]), factor*(exit[2]-entry[2]) local ws, wn = tfmstart.width, tfmnext.width @@ -60,7 +63,7 @@ function nodes.set_cursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext) return dx, dy, bound end -function nodes.set_pair(current,factor,rlmode,spec,tfmchr) +function nodes.set_pair(current,factor,rlmode,r2lflag,spec,tfmchr) local x, y, w, h = factor*spec[1], factor*spec[2], factor*spec[3], factor*spec[4] -- dy = y - h if x ~= 0 or w ~= 0 or y ~= 0 or h ~= 0 then @@ -71,7 +74,7 @@ function nodes.set_pair(current,factor,rlmode,spec,tfmchr) else bound = #kerns + 1 set_attribute(current,kernpair,bound) - kerns[bound] = { rlmode, x, y, w, h } + kerns[bound] = { rlmode, x, y, w, h, r2lflag, tfmchr.width } end return x, y, w, h, bound end @@ -171,6 +174,7 @@ end function nodes.inject_kerns(head,where,keep) local has_marks, has_cursives, has_kerns = next(marks), next(cursives), next(kerns) if has_marks or has_cursives then +--~ if has_marks or has_cursives or has_kerns then if trace_injections then nodes.trace_injection(head) end @@ -190,7 +194,7 @@ function nodes.inject_kerns(head,where,keep) if k then local kk = kerns[k] if kk then - local x, y, w, h = kk[2], kk[3], kk[4], kk[5] + local x, y, w, h = kk[2] or 0, kk[3] or 0, kk[4] or 0, kk[5] or 0 local dy = y - h if dy ~= 0 then ky[n] = dy @@ -305,14 +309,15 @@ function nodes.inject_kerns(head,where,keep) local d = mrks[index] if d then -- local rlmode = d[3] -- not used - -- if rlmode and rlmode < 0 then - -- n.xoffset = p.xoffset + d[1] + -- if rlmode and rlmode > 0 then + -- todo -- else - n.xoffset = p.xoffset - d[1] ---~ local k = wx[p] ---~ if k then ---~ wx[n] = k ---~ end + local k = wx[p] + if k then + n.xoffset = p.xoffset - d[1] - k[2] + else + n.xoffset = p.xoffset - d[1] + end -- end if mk[p] then n.yoffset = p.yoffset + d[2] @@ -334,23 +339,41 @@ function nodes.inject_kerns(head,where,keep) if next(wx) then for n, k in next, wx do -- only w can be nil, can be sped up when w == nil - local rl, x, w = k[1], k[2] or 0, k[4] or 0 + local rl, x, w, r2l = k[1], k[2] or 0, k[4] or 0, k[6] local wx = w - x - if rl < 0 then - if wx ~= 0 then - insert_node_before(head,n,newkern(wx)) - end - if x ~= 0 then - insert_node_after (head,n,newkern(x)) - end - else - -- if wx ~= 0 then - -- insert_node_after(head,n,newkern(wx)) - -- end - if x ~= 0 then - insert_node_before(head,n,newkern(x)) +--~ if rl < 0 then +--~ if r2l then +--~ if wx ~= 0 then +--~ insert_node_before(head,n,newkern(wx)) +--~ end +--~ if x ~= 0 then +--~ insert_node_after (head,n,newkern(x)) +--~ end +--~ else +--~ if x ~= 0 then +--~ insert_node_before(head,n,newkern(x)) +--~ end +--~ if wx ~= 0 then +--~ insert_node_after(head,n,newkern(wx)) +--~ end +--~ end +--~ else + if r2l then + if wx ~= 0 then + insert_node_before(head,n,newkern(wx)) + end + if x ~= 0 then + insert_node_after (head,n,newkern(x)) + end + else + if x ~= 0 then + insert_node_before(head,n,newkern(x)) + end + if wx ~= 0 then + insert_node_after(head,n,newkern(wx)) + end end - end +--~ end end end if next(cx) then @@ -376,29 +399,54 @@ function nodes.inject_kerns(head,where,keep) if trace_injections then nodes.trace_injection(head) end - -- we assume done is true because there are kerns for n in traverse_id(glyph,head) do local k = has_attribute(n,kernpair) if k then local kk = kerns[k] if kk then - -- only w can be nil, can be sped up when w == nil - local rl, x, y, w = kk[1], kk[2] or 0, kk[3] or 0, kk[4] or 0 - if y ~= 0 then + local rl, x, y, w = kk[1], kk[2] or 0, kk[3], kk[4] + if y and y ~= 0 then n.yoffset = y -- todo: h ? end - local wx = w - x - if rl < 0 then - if wx ~= 0 then - insert_node_before(head,n,newkern(wx)) - end - if x ~= 0 then - insert_node_after (head,n,newkern(x)) - end + if w then + -- copied from above + local r2l = kk[6] + local wx = w - x +--~ if rl < 0 then +--~ if r2l then +--~ if x ~= 0 then +--~ insert_node_before(head,n,newkern(x)) +--~ end +--~ if wx ~= 0 then +--~ insert_node_after(head,n,newkern(wx)) +--~ end +--~ else +--~ if wx ~= 0 then +--~ insert_node_before(head,n,newkern(wx)) +--~ end +--~ if x ~= 0 then +--~ insert_node_after (head,n,newkern(x)) +--~ end +--~ end +--~ else + if r2l then + if wx ~= 0 then + insert_node_before(head,n,newkern(wx)) + end + if x ~= 0 then + insert_node_after (head,n,newkern(x)) + end + else + if x ~= 0 then + insert_node_before(head,n,newkern(x)) + end + if wx ~= 0 then + insert_node_after(head,n,newkern(wx)) + end + end +--~ end else - -- if wx ~= 0 then - -- insert_node_after(head,n,newkern(wx)) - -- end + -- simple (e.g. kernclass kerns) if x ~= 0 then insert_node_before(head,n,newkern(x)) end diff --git a/otfl-node-res.lua b/otfl-node-res.lua index 4f2cf5a..f147981 100644 --- a/otfl-node-res.lua +++ b/otfl-node-res.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['node-res'] = { version = 1.001, - comment = "companion to node-ini.tex", + comment = "companion to node-ini.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" @@ -60,6 +60,8 @@ local glyph = nodes.register(new_node("glyph",0)) local textdir = nodes.register(new_node("whatsit",7)) local rule = nodes.register(new_node("rule")) local latelua = nodes.register(new_node("whatsit",35)) +--~ local user = nodes.register(new_node("user_defined")) +local user = nodes.register(new_node(44)) function nodes.glyph(fnt,chr) local n = copy_node(glyph) @@ -109,6 +111,31 @@ function nodes.latelua(code) return n end +function nodes.usernumber(num) + local n = copy_node(user) + n.type = 100 + if num then n.value = num end + return n +end +function nodes.userstring(str) + local n = copy_node(user) + n.type = 115 + if str then n.value = str end + return n +end +function nodes.userlist(list) + local n = copy_node(user) + n.type = 110 + if list then n.value = list end + return n +end +function nodes.usertokens(tokens) + local n = copy_node(user) + n.type = 116 + if tokens then n.value = tokens end + return n +end + statistics.register("cleaned up reserved nodes", function() return format("%s nodes, %s lists of %s", nodes.cleanup_reserved(tex.count["lastallocatedbox"])) end) -- \topofboxstack -- cgit v1.2.3