From 1f5a6c986423b9116645f85c88ec7d4acd18c3f5 Mon Sep 17 00:00:00 2001 From: Context Git Mirror Bot Date: Sun, 21 Aug 2016 18:56:35 +0200 Subject: 2016-08-21 16:33:00 --- tex/context/base/context-version.pdf | Bin 4259 -> 4255 bytes tex/context/base/mkiv/char-ini.lua | 6 +- tex/context/base/mkiv/cont-new.mkiv | 2 +- tex/context/base/mkiv/context.mkiv | 2 +- tex/context/base/mkiv/font-chk.lua | 115 +++++++------ tex/context/base/mkiv/font-ext.lua | 185 +++++++++++++-------- tex/context/base/mkiv/font-inj.lua | 117 +++++++------ tex/context/base/mkiv/font-ota.lua | 54 +++--- tex/context/base/mkiv/font-otj.lua | 42 +++-- tex/context/base/mkiv/font-ots.lua | 28 +++- tex/context/base/mkiv/status-files.pdf | Bin 9126 -> 9129 bytes tex/context/base/mkiv/status-lua.pdf | Bin 368957 -> 369100 bytes tex/context/base/mkiv/typo-dua.lua | 4 +- tex/context/base/mkiv/typo-dub.lua | 3 +- tex/context/interface/mkiv/i-context.pdf | Bin 774457 -> 774456 bytes tex/context/interface/mkiv/i-readme.pdf | Bin 60792 -> 60792 bytes tex/context/modules/mkiv/s-fonts-missing.lua | 3 +- tex/generic/context/luatex/luatex-fonts-merged.lua | 106 +++++++----- 18 files changed, 389 insertions(+), 278 deletions(-) diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf index 372d2f1cc..2dcee03b8 100644 Binary files a/tex/context/base/context-version.pdf and b/tex/context/base/context-version.pdf differ diff --git a/tex/context/base/mkiv/char-ini.lua b/tex/context/base/mkiv/char-ini.lua index 63328a177..d9ffdb2c1 100644 --- a/tex/context/base/mkiv/char-ini.lua +++ b/tex/context/base/mkiv/char-ini.lua @@ -802,7 +802,7 @@ setmetatableindex(characters.directions,function(t,k) end end t[k] = false -- maybe 'l' - return v + return false end) characters.mirrors = { } @@ -817,7 +817,7 @@ setmetatableindex(characters.mirrors,function(t,k) end end t[k] = false - return v + return false end) characters.textclasses = { } @@ -832,7 +832,7 @@ setmetatableindex(characters.textclasses,function(t,k) end end t[k] = false - return v + return false end) --[[ldx-- diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 91d6a5598..9af40da62 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.20 13:39} +\newcontextversion{2016.08.21 16:29} %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 8e4dcf8ea..9a14d3205 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.20 13:39} +\edef\contextversion{2016.08.21 16:29} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/mkiv/font-chk.lua b/tex/context/base/mkiv/font-chk.lua index 179a9b80e..d9e88c91e 100644 --- a/tex/context/base/mkiv/font-chk.lua +++ b/tex/context/base/mkiv/font-chk.lua @@ -11,59 +11,63 @@ if not modules then modules = { } end modules ['font-chk'] = { local next = next -local formatters = string.formatters -local bpfactor = number.dimenfactors.bp -local fastcopy = table.fastcopy +local formatters = string.formatters +local bpfactor = number.dimenfactors.bp +local fastcopy = table.fastcopy -local report_fonts = logs.reporter("fonts","checking") +local report_fonts = logs.reporter("fonts","checking") -- replace -local allocate = utilities.storage.allocate +local allocate = utilities.storage.allocate -local fonts = fonts +local fonts = fonts -fonts.checkers = fonts.checkers or { } -local checkers = fonts.checkers +fonts.checkers = fonts.checkers or { } +local checkers = fonts.checkers -local fonthashes = fonts.hashes -local fontdata = fonthashes.identifiers -local fontcharacters = fonthashes.characters +local fonthashes = fonts.hashes +local fontdata = fonthashes.identifiers +local fontcharacters = fonthashes.characters -local helpers = fonts.helpers +local helpers = fonts.helpers -local addprivate = helpers.addprivate -local hasprivate = helpers.hasprivate -local getprivatenode = helpers.getprivatenode +local addprivate = helpers.addprivate +local hasprivate = helpers.hasprivate +local getprivateslot = helpers.getprivateslot +local getprivatecharornode = helpers.getprivatecharornode -local otffeatures = fonts.constructors.features.otf -local afmfeatures = fonts.constructors.features.afm +local otffeatures = fonts.constructors.features.otf +local afmfeatures = fonts.constructors.features.afm -local registerotffeature = otffeatures.register -local registerafmfeature = afmfeatures.register +local registerotffeature = otffeatures.register +local registerafmfeature = afmfeatures.register -local is_character = characters.is_character -local chardata = characters.data +local is_character = characters.is_character +local chardata = characters.data -local tasks = nodes.tasks -local enableaction = tasks.enableaction -local disableaction = tasks.disableaction +local tasks = nodes.tasks +local enableaction = tasks.enableaction +local disableaction = tasks.disableaction -local implement = interfaces.implement +local implement = interfaces.implement -local glyph_code = nodes.nodecodes.glyph +local glyph_code = nodes.nodecodes.glyph -local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode +local new_special = nodes.pool.special +local hpack_node = node.hpack -local getfont = nuts.getfont -local getchar = nuts.getchar +local nuts = nodes.nuts +local tonut = nuts.tonut +local tonode = nuts.tonode -local setfield = nuts.setfield -local setchar = nuts.setchar +local getfont = nuts.getfont +local getchar = nuts.getchar -local traverse_id = nuts.traverse_id -local remove_node = nuts.remove -local insert_node_after = nuts.insert_after +local setfield = nuts.setfield +local setchar = nuts.setchar + +local traverse_id = nuts.traverse_id +local remove_node = nuts.remove +local insert_node_after = nuts.insert_after -- maybe in fonts namespace -- deletion can be option @@ -180,11 +184,21 @@ local pdf_blob = "pdf: q %0.6F 0 0 %0.6F 0 0 cm %s %s %s rg %s %s %s RG 10 M 1 j local cache = { } -- saves some tables but not that impressive +local function missingtonode(tfmdata,character) + local commands = character.commands + local fake = hpack_node(new_special(commands[1][2])) + fake.width = character.width + fake.height = character.height + fake.depth = character.depth + return fake +end + local function addmissingsymbols(tfmdata) -- we can have an alternative with rules local characters = tfmdata.characters + local properties = tfmdata.properties local size = tfmdata.parameters.size - local privates = tfmdata.properties.privates local scale = size * bpfactor + local tonode = properties.finalized and missingtonode or nil for i=1,#variants do local v = variants[i] local tag, r, g, b = v.tag, v.r, v.g, v.b @@ -197,6 +211,7 @@ local function addmissingsymbols(tfmdata) -- we can have an alternative with rul local char = cache[hash] if not char then char = { + tonode = tonode, width = size*fake.width, height = size*fake.height, depth = size*fake.depth, @@ -226,27 +241,21 @@ fonts.loggers.category_to_placeholder = mapping function commands.getplaceholderchar(name) local id = font.current() addmissingsymbols(fontdata[id]) - context(helpers.getprivatenode(fontdata[id],name)) + context(getprivatenode(fontdata[id],name)) end +-- todo in luatex: option to add characters (just slots, no kerns etc) + local function placeholder(font,char) - local tfmdata = fontdata[font] - local properties = tfmdata.properties - local privates = properties.privates - local category = chardata[char].category - local fakechar = mapping[category] - local p = privates and privates[fakechar] - if not p then + local tfmdata = fontdata[font] + local category = chardata[char].category + local fakechar = mapping[category] + local slot = getprivateslot(font,fakechar) + if not slot then addmissingsymbols(tfmdata) - p = properties.privates[fakechar] - end - if properties.lateprivates then - -- frozen already - return "node", getprivatenode(tfmdata,fakechar) - else - -- good, we have \definefontfeature[default][default][missing=yes] - return "char", p + slot = getprivateslot(font,fakechar) end + return getprivatecharornode(tfmdata,fakechar) end checkers.placeholder = placeholder diff --git a/tex/context/base/mkiv/font-ext.lua b/tex/context/base/mkiv/font-ext.lua index 2fc85c266..16e201bd3 100644 --- a/tex/context/base/mkiv/font-ext.lua +++ b/tex/context/base/mkiv/font-ext.lua @@ -6,7 +6,9 @@ if not modules then modules = { } end modules ['font-ext'] = { license = "see context related readme files" } -local next, type, byte = next, type, string.byte +local next, type, tonumber = next, type, tonumber +local formatters = string.formatters +local byte = string.byte local utfchar = utf.char local context = context @@ -79,6 +81,8 @@ expansions.classes = classes expansions.vectors = vectors -- beware, pdftex itself uses percentages * 10 +-- +-- todo: get rid of byte() here classes.preset = { stretch = 2, shrink = 2, step = .5, factor = 1 } @@ -978,37 +982,44 @@ registerafmfeature(dimensions_specification) -- a handy helper (might change or be moved to another namespace) -local nodepool = nodes.pool +local nodepool = nodes.pool +local new_glyph = nodepool.glyph ------ new_special = nodepool.special ------ hpack_node = node.hpack -local new_glyph = nodepool.glyph +local helpers = fonts.helpers +local currentfont = font.current -local helpers = fonts.helpers -local currentfont = font.current +local currentprivate = 0xE000 +local maximumprivate = 0xEFFF -function helpers.addprivate(tfmdata,name,characterdata) - local properties = tfmdata.properties - local privates = properties.privates - local lastprivate = properties.lastprivate - if lastprivate then - lastprivate = lastprivate + 1 +-- if we run out of space we can think of another range but by sharing we can +-- use these privates for mechanisms like alignments-on-character and such + +local sharedprivates = setmetatableindex(function(t,k) + v = currentprivate + if currentprivate < maximumprivate then + currentprivate = currentprivate + 1 else - lastprivate = 0xE000 + -- reuse last slot, todo: warning end + t[k] = v + return v +end) + +function helpers.addprivate(tfmdata,name,characterdata) + local properties = tfmdata.properties + local characters = tfmdata.characters + local privates = properties.privates if not privates then privates = { } properties.privates = privates end - if name then - privates[name] = lastprivate - end - properties.lastprivate = lastprivate - tfmdata.characters[lastprivate] = characterdata - if properties.finalized then - properties.lateprivates = true + if not name then + name = formatters["anonymous_private_0x%05X"](currentprivate) end - return lastprivate + local usedprivate = sharedprivates[name] + privates[name] = usedprivate + characters[usedprivate] = characterdata + return usedprivate end local function getprivateslot(id,name) @@ -1021,69 +1032,64 @@ local function getprivateslot(id,name) return privates and privates[name] end -helpers.getprivateslot = getprivateslot - --- was originally meant for missing chars: --- --- local char = tfmdata.characters[p] --- local commands = char.commands --- if commands then --- local fake = hpack_node(new_special(commands[1][2])) --- fake.width = char.width --- fake.height = char.height --- fake.depth = char.depth --- return fake --- else - local function getprivatenode(tfmdata,name) - local id = tfmdata.properties.id - local p = getprivateslot(id,name) - if p then + if type(tfmdata) == "number" then + tfmdata = fontdata[tfmdata] + end + local properties = tfmdata.properties + local font = properties.id + local slot = getprivateslot(font,name) + if slot then -- todo: set current attribibutes - return new_glyph(id,p) + local char = tfmdata.characters[slot] + local tonode = char.tonode + if tonode then + return tonode(font,char) + else + return new_glyph(font,slot) + end end end -helpers.getprivatenode = getprivatenode - -function helpers.hasprivate(tfmdata,name) +local function getprivatecharornode(tfmdata,name) + if type(tfmdata) == "number" then + tfmdata = fontdata[tfmdata] + end local properties = tfmdata.properties - local privates = properties and properties.privates - return privates and privates[name] or false -end - -implement { - name = "getprivatechar", - arguments = "string", - actions = function(name) - local p = getprivateslot(name) - if p then - context(utfchar(p)) + local font = properties.id + local slot = getprivateslot(font,name) + if slot then + -- todo: set current attribibutes + local char = tfmdata.characters[slot] + local tonode = char.tonode + if tonode then + return "node", tonode(tfmdata,char) + else + return "char", slot end end -} +end -implement { - name = "getprivatemathchar", - arguments = "string", - actions = function(name) - local p = getprivateslot(family_font(0),name) - if p then - context(utfchar(p)) - end +helpers.getprivateslot = getprivateslot +helpers.getprivatenode = getprivatenode +helpers.getprivatecharornode = getprivatecharornode + +function helpers.getprivates(tfmdata) + if type(tfmdata) == "number" then + tfmdata = fontdata[tfmdata] end -} + local properties = tfmdata.properties + return properties and properties.privates +end -implement { - name = "getprivateslot", - arguments = "string", - actions = function(name) - local p = getprivateslot(name) - if p then - context(p) - end +function helpers.hasprivate(tfmdata,name) + if type(tfmdata) == "number" then + tfmdata = fontdata[tfmdata] end -} + local properties = tfmdata.properties + local privates = properties and properties.privates + return privates and privates[name] or false +end -- relatively new: @@ -1116,3 +1122,36 @@ do } end + +implement { + name = "getprivatechar", + arguments = "string", + actions = function(name) + local p = getprivateslot(name) + if p then + context(utfchar(p)) + end + end +} + +implement { + name = "getprivatemathchar", + arguments = "string", + actions = function(name) + local p = getprivateslot(family_font(0),name) + if p then + context(utfchar(p)) + end + end +} + +implement { + name = "getprivateslot", + arguments = "string", + actions = function(name) + local p = getprivateslot(name) + if p then + context(p) + end + end +} diff --git a/tex/context/base/mkiv/font-inj.lua b/tex/context/base/mkiv/font-inj.lua index a01496919..cb4fb7226 100644 --- a/tex/context/base/mkiv/font-inj.lua +++ b/tex/context/base/mkiv/font-inj.lua @@ -547,7 +547,7 @@ local function collect_glyphs(head,offsets) identify(n,"preinjections") end end - end + end local d = getfield(n,"post") if d then for n in traverse_id(glyph_code,d) do @@ -555,7 +555,7 @@ local function collect_glyphs(head,offsets) identify(n,"postinjections") end end - end + end local d = getfield(n,"replace") if d then for n in traverse_id(glyph_code,d) do @@ -563,9 +563,9 @@ local function collect_glyphs(head,offsets) identify(n,"replaceinjections") end end - end + end end - n = getnext(n) + n = getnext(n) end return glyphs, glyphi, nofglyphs, marks, marki, nofmarks @@ -600,11 +600,11 @@ local function inject_marks(marks,marki,nofmarks) -- kern(x) glyph(p) kern(w-x) mark(n) -- ox = px - getfield(p,"width") + pn.markx - pp.leftkern -- - -- According to Kai we don't need to handle leftkern here but I'm + -- According to Kai we don't need to handle leftkern here but I'm -- pretty sure I've run into a case where it was needed so maybe - -- some day we need something more clever here. + -- some day we need something more clever here. -- - if false then + if false then -- a mark with kerning local leftkern = pp.leftkern if leftkern then @@ -635,17 +635,16 @@ local function inject_marks(marks,marki,nofmarks) pn.rightkern = -wn/2 -- wx[n] = { 0, -wn/2, 0, -wn } end - -- so far end setfield(n,"xoffset",ox) -- local py = getfield(p,"yoffset") --- local oy = 0 --- if marks[p] then --- oy = py + pn.marky --- else --- oy = getfield(n,"yoffset") + py + pn.marky --- end + -- local oy = 0 + -- if marks[p] then + -- oy = py + pn.marky + -- else + -- oy = getfield(n,"yoffset") + py + pn.marky + -- end local oy = getfield(n,"yoffset") + py + pn.marky setfield(n,"yoffset",oy) else @@ -753,54 +752,54 @@ local function inject_kerns(head,glist,ilist,length) -- not complete ! compare w local n = glist[i] local pn = rawget(properties,n) if pn then - local dp = nil - local dr = nil + local dp = nil + local dr = nil local ni = ilist[i] local p = nil - if ni == "injections" then - p = getprev(n) - if p then - local id = getid(p) - if id == disc_code then - dp = getfield(p,"post") - dr = getfield(p,"replace") - end - end - end - if dp then - local i = rawget(pn,"postinjections") - if i then - local leftkern = i.leftkern - if leftkern and leftkern ~= 0 then - local t = find_tail(dp) - insert_node_after(dp,t,newkern(leftkern)) + if ni == "injections" then + p = getprev(n) + if p then + local id = getid(p) + if id == disc_code then + dp = getfield(p,"post") + dr = getfield(p,"replace") + end + end + end + if dp then + local i = rawget(pn,"postinjections") + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + local t = find_tail(dp) + insert_node_after(dp,t,newkern(leftkern)) setfield(p,"post",dp) -- currently we need to force a tail refresh - end - end - end - if dr then - local i = rawget(pn,"replaceinjections") - if i then - local leftkern = i.leftkern - if leftkern and leftkern ~= 0 then - local t = find_tail(dr) - insert_node_after(dr,t,newkern(leftkern)) + end + end + end + if dr then + local i = rawget(pn,"replaceinjections") + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + local t = find_tail(dr) + insert_node_after(dr,t,newkern(leftkern)) setfield(p,"replace",dr) -- currently we need to force a tail refresh - end - end - else - local i = rawget(pn,ni) - if i then - local leftkern = i.leftkern - if leftkern and leftkern ~= 0 then - insert_node_before(head,n,newkern(leftkern)) -- type 0/2 - end - local rightkern = i.rightkern - if rightkern and rightkern ~= 0 then - insert_node_after(head,n,newkern(rightkern)) -- type 0/2 - end - end - end + end + end + else + local i = rawget(pn,ni) + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + insert_node_before(head,n,newkern(leftkern)) -- type 0/2 + end + local rightkern = i.rightkern + if rightkern and rightkern ~= 0 then + insert_node_after(head,n,newkern(rightkern)) -- type 0/2 + end + end + end end end end @@ -822,7 +821,7 @@ local function inject_everything(head,where) end if nofmarks > 0 then inject_kerns(head,marks,marki,nofmarks) - end + end if keepregisteredcounts then keepregisteredcounts = false else diff --git a/tex/context/base/mkiv/font-ota.lua b/tex/context/base/mkiv/font-ota.lua index 4ddb8310a..b8944e0c0 100644 --- a/tex/context/base/mkiv/font-ota.lua +++ b/tex/context/base/mkiv/font-ota.lua @@ -262,36 +262,44 @@ local classifiers = characters.classifiers if not classifiers then - local first_arabic, last_arabic = characters.blockrange("arabic") - local first_syriac, last_syriac = characters.blockrange("syriac") - local first_mandiac, last_mandiac = characters.blockrange("mandiac") - local first_nko, last_nko = characters.blockrange("nko") + local f_arabic, l_arabic = characters.blockrange("arabic") + local f_syriac, l_syriac = characters.blockrange("syriac") + local f_mandiac, l_mandiac = characters.blockrange("mandiac") + local f_nko, l_nko = characters.blockrange("nko") + local f_ext_a, l_ext_a = characters.blockrange("arabicextendeda") classifiers = table.setmetatableindex(function(t,k) - local c = chardata[k] - local v = false - if c then - local arabic = c.arabic - if arabic then - v = mappers[arabic] - if not v then - log.report("analyze","error in mapping arabic %C",k) - -- error - v = false - end - elseif k >= first_arabic and k <= last_arabic or k >= first_syriac and k <= last_syriac or - k >= first_mandiac and k <= last_mandiac or k >= first_nko and k <= last_nko then - if categories[k] == "mn" then - v = s_mark - else - v = s_rest + if type(k) == "number" then + local c = chardata[k] + local v = false + if c then + local arabic = c.arabic + if arabic then + v = mappers[arabic] + if not v then + log.report("analyze","error in mapping arabic %C",k) + -- error + v = false + end + elseif (k >= f_arabic and k <= l_arabic) or + (k >= f_syriac and k <= l_syriac) or + (k >= f_mandiac and k <= l_mandiac) or + (k >= f_nko and k <= l_nko) or + (k >= f_ext_a and k <= l_ext_a) then + if categories[k] == "mn" then + v = s_mark + else + v = s_rest + end end end + t[k] = v + return v end - t[k] = v - return v end) + characters.classifiers = classifiers + end function methods.arab(head,font,attr) diff --git a/tex/context/base/mkiv/font-otj.lua b/tex/context/base/mkiv/font-otj.lua index 46b2ca8d4..68cf608ec 100644 --- a/tex/context/base/mkiv/font-otj.lua +++ b/tex/context/base/mkiv/font-otj.lua @@ -377,7 +377,8 @@ function injections.setkern(current,factor,rlmode,x,injection) end end -function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk) -- ba=baseanchor, ma=markanchor +function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmark) -- ba=baseanchor, ma=markanchor + local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2]) nofregisteredmarks = nofregisteredmarks + 1 if rlmode >= 0 then @@ -398,6 +399,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk) -- ba=b i.markbase = nofregisteredmarks i.markbasenode = base i.markmark = mkmk + i.checkmark = checkmark end else p.injections = { @@ -407,6 +409,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk) -- ba=b markbase = nofregisteredmarks, markbasenode = base, markmark = mkmk, + checkmark = checkmark, } end else @@ -418,6 +421,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk) -- ba=b markbase = nofregisteredmarks, markbasenode = base, markmark = mkmk, + checkmark = checkmark, }, } end @@ -1062,11 +1066,22 @@ local function inject_everything(head,where) ox = px - pn.markx -- report_injections("l2r case 3: %p",ox) -- end - local wn = getfield(n,"width") -- in arial marks have widths - if wn ~= 0 then - -- bad: we should center - pn.leftkern = -wn/2 - pn.rightkern = -wn/2 + if pn.checkmark then + local wn = getfield(n,"width") -- in arial marks have widths + if wn ~= 0 then + wn = wn/2 + if trace_injections then + report_injections("correcting non zero width mark %C",getchar(n)) + end + -- -- bad: we should center + -- pn.leftkern = -wn + -- pn.rightkern = -wn + -- -- we're too late anyway as kerns are already injected so + -- -- we do it the ugly way (no checking if the previous is + -- -- already a kern) .. maybe we should fix the font instead + insert_node_before(n,n,newkern(-wn)) + insert_node_after(n,n,newkern(-wn)) + end end end local oy = getfield(n,"yoffset") + getfield(p,"yoffset") + pn.marky @@ -1092,10 +1107,10 @@ local function inject_everything(head,where) nofmarks = nofmarks + 1 marks[nofmarks] = current else -local yoffset = i.yoffset -if yoffset and yoffset ~= 0 then - setfield(current,"yoffset",yoffset) -end + local yoffset = i.yoffset + if yoffset and yoffset ~= 0 then + setfield(current,"yoffset",yoffset) + end if hascursives then local cursivex = i.cursivex if cursivex then @@ -1148,10 +1163,6 @@ end end end -- left|glyph|right --- local yoffset = i.yoffset --- if yoffset and yoffset ~= 0 then --- setfield(current,"yoffset",yoffset) --- end local leftkern = i.leftkern if leftkern and leftkern ~= 0 then insert_node_before(head,current,newkern(leftkern)) @@ -1166,7 +1177,7 @@ end local i = p.emptyinjections if i then -- glyph|disc|glyph (special case) --- okay? + -- okay? local rightkern = i.rightkern if rightkern and rightkern ~= 0 then if next and getid(next) == disc_code then @@ -1561,6 +1572,7 @@ function injections.handler(head,where) if triggers then head = injectspaces(head) end + -- todo: marks only run too if nofregisteredmarks > 0 or nofregisteredcursives > 0 then if trace_injections then report_injections("injection variant %a","everything") diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua index 8443a383d..f2fa886b5 100644 --- a/tex/context/base/mkiv/font-ots.lua +++ b/tex/context/base/mkiv/font-ots.lua @@ -254,6 +254,7 @@ local marks = false local currentfont = false local factor = 0 local threshold = 0 +local checkmarks = false local sweepnode = nil local sweepprev = nil @@ -959,7 +960,7 @@ function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode) local ba = markanchors[1][basechar] if ba then local ma = markanchors[2] - local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar]) + local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", pref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -1015,7 +1016,7 @@ function handlers.gpos_mark2ligature(head,start,dataset,sequence,markanchors,rlm local index = getligaindex(start) ba = ba[index] if ba then - local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar]) -- index + local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) if trace_marks then logprocess("%s, anchor %s, index %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", pref(dataset,sequence),anchor,index,bound,gref(markchar),gref(basechar),index,dx,dy) @@ -1064,7 +1065,7 @@ function handlers.gpos_mark2mark(head,start,dataset,sequence,markanchors,rlmode) local ba = markanchors[1][basechar] -- slot 1 has been made copy of the class hash if ba then local ma = markanchors[2] - local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true) + local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", pref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -1532,7 +1533,7 @@ function chainprocs.gpos_mark2base(head,start,stop,dataset,sequence,currentlooku if ba then local ma = markanchors[2] if ma then - local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar]) + local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", cref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -1599,7 +1600,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,dataset,sequence,currentl local index = getligaindex(start) ba = ba[index] if ba then - local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar]) + local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", cref(dataset,sequence),anchor,a or bound,gref(markchar),gref(basechar),index,dx,dy) @@ -1652,7 +1653,7 @@ function chainprocs.gpos_mark2mark(head,start,stop,dataset,sequence,currentlooku if ba then local ma = markanchors[2] if ma then - local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true) + local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", cref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -3381,6 +3382,7 @@ local function featuresprocessor(head,font,attr) marks = tfmdata.resources.marks threshold, factor = getthreshold(font) + checkmarks = tfmdata.properties.checkmarks elseif currentfont ~= font then @@ -3822,3 +3824,17 @@ registerotffeature { node = spaceinitializer, }, } + +local function markinitializer(tfmdata,value) + local properties = tfmdata.properties + properties.checkmarks = value +end + +registerotffeature { + name = "checkmarks", + description = "check mark widths", + default = true, + initializers = { + node = markinitializer, + }, +} diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf index 860a4022a..6d479dfce 100644 Binary files a/tex/context/base/mkiv/status-files.pdf and b/tex/context/base/mkiv/status-files.pdf differ diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf index 1579c2465..d6cb56aac 100644 Binary files a/tex/context/base/mkiv/status-lua.pdf and b/tex/context/base/mkiv/status-lua.pdf differ diff --git a/tex/context/base/mkiv/typo-dua.lua b/tex/context/base/mkiv/typo-dua.lua index 728fd031b..596503dbc 100644 --- a/tex/context/base/mkiv/typo-dua.lua +++ b/tex/context/base/mkiv/typo-dua.lua @@ -153,7 +153,7 @@ local function show_list(list,size,what) result[i] = formatters["%-3s:%s %s (%i)"](direction,joiner,nodecodes[first],skip or 0) end elseif character >= 0x202A and character <= 0x202C then - result[i] = formatters["%-3s:%s %U"](direction,joiner,character) + result[i] = formatters["%-3s:%s %U"](direction,joiner,character) else result[i] = formatters["%-3s:%s %c %U"](direction,joiner,character,character) end @@ -821,7 +821,7 @@ local function process(head) report_directions("after : %s",show_list(list,size,"direction")) report_directions("result : %s",show_done(list,size)) end - head, done = apply_to_list(list,size,head,pardir) + local head, done = apply_to_list(list,size,head,pardir) return tonode(head), done end diff --git a/tex/context/base/mkiv/typo-dub.lua b/tex/context/base/mkiv/typo-dub.lua index 7946fe5b3..5a60a11e6 100644 --- a/tex/context/base/mkiv/typo-dub.lua +++ b/tex/context/base/mkiv/typo-dub.lua @@ -915,7 +915,6 @@ local function apply_to_list(list,size,head,pardir) begindir = nil done = true end - else end if begindir then local d = new_textdir(begindir) @@ -976,7 +975,7 @@ local function process(head) report_directions("after : %s",show_list(list,size,"direction")) report_directions("result : %s",show_done(list,size)) end - head, done = apply_to_list(list,size,head,pardir) + local head, done = apply_to_list(list,size,head,pardir) return tonode(head), done end diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf index 5e8c5a2aa..5f9ad492f 100644 Binary files a/tex/context/interface/mkiv/i-context.pdf and b/tex/context/interface/mkiv/i-context.pdf differ diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf index 1421fcdc0..f104d9efc 100644 Binary files a/tex/context/interface/mkiv/i-readme.pdf and b/tex/context/interface/mkiv/i-readme.pdf differ diff --git a/tex/context/modules/mkiv/s-fonts-missing.lua b/tex/context/modules/mkiv/s-fonts-missing.lua index 9a75676a9..7db5c2fb8 100644 --- a/tex/context/modules/mkiv/s-fonts-missing.lua +++ b/tex/context/modules/mkiv/s-fonts-missing.lua @@ -10,8 +10,7 @@ moduledata.fonts = moduledata.fonts or { } moduledata.fonts.missing = moduledata.fonts.missing or { } local function legend(id) - local c = fonts.hashes.identifiers[id] - local privates = c.properties.privates + local privates = fonts.helpers.getprivates(id) if privates then local categories = table.swapped(fonts.loggers.category_to_placeholder) context.starttabulate { "|c|l|" } diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 133c8ffaa..29bf21303 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/20/16 13:39:39 +-- merge date : 08/21/16 16:29:10 do -- begin closure to overcome local limits and interference @@ -16596,7 +16596,7 @@ function injections.setkern(current,factor,rlmode,x,injection) return 0,0 end end -function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk) +function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmark) local dx,dy=factor*(ba[1]-ma[1]),factor*(ba[2]-ma[2]) nofregisteredmarks=nofregisteredmarks+1 if rlmode>=0 then @@ -16614,6 +16614,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk) i.markbase=nofregisteredmarks i.markbasenode=base i.markmark=mkmk + i.checkmark=checkmark end else p.injections={ @@ -16623,6 +16624,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk) markbase=nofregisteredmarks, markbasenode=base, markmark=mkmk, + checkmark=checkmark, } end else @@ -16634,6 +16636,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk) markbase=nofregisteredmarks, markbasenode=base, markmark=mkmk, + checkmark=checkmark, }, } end @@ -17185,10 +17188,16 @@ local function inject_everything(head,where) end else ox=px-pn.markx - local wn=getfield(n,"width") - if wn~=0 then - pn.leftkern=-wn/2 - pn.rightkern=-wn/2 + if pn.checkmark then + local wn=getfield(n,"width") + if wn~=0 then + wn=wn/2 + if trace_injections then + report_injections("correcting non zero width mark %C",getchar(n)) + end + insert_node_before(n,n,newkern(-wn)) + insert_node_after(n,n,newkern(-wn)) + end end end local oy=getfield(n,"yoffset")+getfield(p,"yoffset")+pn.marky @@ -17212,10 +17221,10 @@ local function inject_everything(head,where) nofmarks=nofmarks+1 marks[nofmarks]=current else -local yoffset=i.yoffset -if yoffset and yoffset~=0 then - setfield(current,"yoffset",yoffset) -end + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setfield(current,"yoffset",yoffset) + end if hascursives then local cursivex=i.cursivex if cursivex then @@ -17856,33 +17865,40 @@ local mappers={ } local classifiers=characters.classifiers if not classifiers then - local first_arabic,last_arabic=characters.blockrange("arabic") - local first_syriac,last_syriac=characters.blockrange("syriac") - local first_mandiac,last_mandiac=characters.blockrange("mandiac") - local first_nko,last_nko=characters.blockrange("nko") + local f_arabic,l_arabic=characters.blockrange("arabic") + local f_syriac,l_syriac=characters.blockrange("syriac") + local f_mandiac,l_mandiac=characters.blockrange("mandiac") + local f_nko,l_nko=characters.blockrange("nko") + local f_ext_a,l_ext_a=characters.blockrange("arabicextendeda") classifiers=table.setmetatableindex(function(t,k) - local c=chardata[k] - local v=false - if c then - local arabic=c.arabic - if arabic then - v=mappers[arabic] - if not v then - log.report("analyze","error in mapping arabic %C",k) - v=false - end - elseif k>=first_arabic and k<=last_arabic or k>=first_syriac and k<=last_syriac or - k>=first_mandiac and k<=last_mandiac or k>=first_nko and k<=last_nko then - if categories[k]=="mn" then - v=s_mark - else - v=s_rest + if type(k)=="number" then + local c=chardata[k] + local v=false + if c then + local arabic=c.arabic + if arabic then + v=mappers[arabic] + if not v then + log.report("analyze","error in mapping arabic %C",k) + v=false + end + elseif (k>=f_arabic and k<=l_arabic) or + (k>=f_syriac and k<=l_syriac) or + (k>=f_mandiac and k<=l_mandiac) or + (k>=f_nko and k<=l_nko) or + (k>=f_ext_a and k<=l_ext_a) then + if categories[k]=="mn" then + v=s_mark + else + v=s_rest + end end end + t[k]=v + return v end - t[k]=v - return v end) + characters.classifiers=classifiers end function methods.arab(head,font,attr) local first,last=nil,nil @@ -18152,6 +18168,7 @@ local marks=false local currentfont=false local factor=0 local threshold=0 +local checkmarks=false local sweepnode=nil local sweepprev=nil local sweepnext=nil @@ -18767,7 +18784,7 @@ function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode) local ba=markanchors[1][basechar] if ba then local ma=markanchors[2] - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar]) + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", pref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -18822,7 +18839,7 @@ function handlers.gpos_mark2ligature(head,start,dataset,sequence,markanchors,rlm local index=getligaindex(start) ba=ba[index] if ba then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar]) + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) if trace_marks then logprocess("%s, anchor %s, index %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", pref(dataset,sequence),anchor,index,bound,gref(markchar),gref(basechar),index,dx,dy) @@ -18869,7 +18886,7 @@ function handlers.gpos_mark2mark(head,start,dataset,sequence,markanchors,rlmode) local ba=markanchors[1][basechar] if ba then local ma=markanchors[2] - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true) + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", pref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -19251,7 +19268,7 @@ function chainprocs.gpos_mark2base(head,start,stop,dataset,sequence,currentlooku if ba then local ma=markanchors[2] if ma then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar]) + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", cref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -19317,7 +19334,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,dataset,sequence,currentl local index=getligaindex(start) ba=ba[index] if ba then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar]) + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", cref(dataset,sequence),anchor,a or bound,gref(markchar),gref(basechar),index,dx,dy) @@ -19369,7 +19386,7 @@ function chainprocs.gpos_mark2mark(head,start,stop,dataset,sequence,currentlooku if ba then local ma=markanchors[2] if ma then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true) + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", cref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -20809,6 +20826,7 @@ local function featuresprocessor(head,font,attr) marks=tfmdata.resources.marks threshold, factor=getthreshold(font) + checkmarks=tfmdata.properties.checkmarks elseif currentfont~=font then report_warning("nested call with a different font, level %s, quitting",nesting) nesting=nesting-1 @@ -21174,6 +21192,18 @@ registerotffeature { node=spaceinitializer, }, } +local function markinitializer(tfmdata,value) + local properties=tfmdata.properties + properties.checkmarks=value +end +registerotffeature { + name="checkmarks", + description="check mark widths", + default=true, + initializers={ + node=markinitializer, + }, +} end -- closure -- cgit v1.2.3