summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2020-12-31 21:51:56 +0000
committerKarl Berry <karl@freefriends.org>2020-12-31 21:51:56 +0000
commit0d3cb8095777faa6f0790ce9f2a73c08882b775e (patch)
tree11ece030bd8bdf6557675f8e58ce847552035e84 /Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua
parent0cbf90fb1d02a12129a697341cdc3dcf1ca63789 (diff)
luaotfload (31dec20)
git-svn-id: svn://tug.org/texlive/trunk@57274 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua')
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua311
1 files changed, 172 insertions, 139 deletions
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua
index 490f28de699..1f4806ee257 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua
@@ -13,7 +13,7 @@ with plain <l n='tex'/> it has to be so. This module is part of <l n='context'/>
and discussion about improvements and functionality mostly happens on the
<l n='context'/> mailing list.</p>
-<p>The specification of OpenType is (or at least a decade ago was) kind of vague.
+<p>The specification of OpenType is (or at least decades ago was) kind of vague.
Apart from a lack of a proper free specifications there's also the problem that
Microsoft and Adobe may have their own interpretation of how and in what order to
apply features. In general the Microsoft website has more detailed specifications
@@ -218,6 +218,7 @@ local copy_only_glyphs = nuts.copy_only_glyphs
local count_components = nuts.count_components
local set_components = nuts.set_components
local get_components = nuts.get_components
+local flush_components = nuts.flush_components
---------------------------------------------------------------------------------------
@@ -251,7 +252,7 @@ local glue_code = nodecodes.glue
local disc_code = nodecodes.disc
local math_code = nodecodes.math
local dir_code = nodecodes.dir
-local localpar_code = nodecodes.localpar
+local par_code = nodecodes.par
local lefttoright_code = nodes.dirvalues.lefttoright
local righttoleft_code = nodes.dirvalues.righttoleft
@@ -488,6 +489,7 @@ local function markstoligature(head,start,stop,char)
setsubtype(base,ligatureglyph_code)
set_components(base,start)
setlink(prev,base,next)
+ flush_components(start)
return head, base
end
end
@@ -500,9 +502,25 @@ end
-- in the not discfound branch then. We now have skiphash too so we can be more
-- selective if needed (todo).
+-- we can have more granularity here but for now we only do a simple check
+
+local no_left_ligature_code = 1
+local no_right_ligature_code = 2
+local no_left_kern_code = 4
+local no_right_kern_code = 8
+
+local has_glyph_option = node.direct.has_glyph_option or function(n,c)
+ if c == no_left_ligature_code or c == no_right_ligature_code then
+ return getattr(n,a_noligature) == 1
+ else
+ return false
+ end
+end
+
+-- in lmtx we need to check the components and can be slightly more clever
+
local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks) -- brr head
- if getattr(start,a_noligature) == 1 then
- -- so we can do: e\noligature{ff}e e\noligature{f}fie (we only look at the first)
+ if has_glyph_option(start,no_right_ligature_code) then
return head, start
end
if start == stop and getchar(start) == char then
@@ -572,6 +590,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
break
end
end
+ flush_components(components)
else
-- discfound ... forget about marks .. probably no scripts that hyphenate and have marks
local discprev, discnext = getboth(discfound)
@@ -902,81 +921,89 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
end
function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection)
- local startchar = getchar(start)
- local format = step.format
- if format == "single" or type(kerns) == "table" then -- the table check can go
- local dx, dy, w, h = setposition(0,start,factor,rlmode,kerns,injection)
- if trace_kerns then
- logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
- end
+ if has_glyph_option(start,no_right_kern_code) then
+ return head, start, false
else
- local k = (format == "move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
- if trace_kerns then
- logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k)
+ local startchar = getchar(start)
+ local format = step.format
+ if format == "single" or type(kerns) == "table" then -- the table check can go
+ local dx, dy, w, h = setposition(0,start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
+ end
+ else
+ local k = (format == "move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k)
+ end
end
+ return head, start, true
end
- return head, start, true
end
function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection)
- local snext = getnext(start)
- if not snext then
+ if has_glyph_option(start,no_right_kern_code) then
return head, start, false
else
- local prev = start
- while snext do
- local nextchar = ischar(snext,currentfont)
- if nextchar then
- if skiphash and skiphash[nextchar] then -- includes marks too when flag
- prev = snext
- snext = getnext(snext)
- else
- local krn = kerns[nextchar]
- if not krn then
- break
- end
- local format = step.format
- if format == "pair" then
- local a = krn[1]
- local b = krn[2]
- if a == true then
- -- zero
- elseif a then -- #a > 0
- local x, y, w, h = setposition(1,start,factor,rlmode,a,injection)
- if trace_kerns then
- local startchar = getchar(start)
- logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
- end
+ local snext = getnext(start)
+ if not snext then
+ return head, start, false
+ else
+ local prev = start
+ while snext do
+ local nextchar = ischar(snext,currentfont)
+ if nextchar then
+ if skiphash and skiphash[nextchar] then -- includes marks too when flag
+ prev = snext
+ snext = getnext(snext)
+ else
+ local krn = kerns[nextchar]
+ if not krn then
+ break
end
- if b == true then
- -- zero
- start = snext -- cf spec
- elseif b then -- #b > 0
- local x, y, w, h = setposition(2,snext,factor,rlmode,b,injection)
+ local format = step.format
+ if format == "pair" then
+ local a = krn[1]
+ local b = krn[2]
+ if a == true then
+ -- zero
+ elseif a then -- #a > 0
+ local x, y, w, h = setposition(1,start,factor,rlmode,a,injection)
+ if trace_kerns then
+ local startchar = getchar(start)
+ logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ end
+ end
+ if b == true then
+ -- zero
+ start = snext -- cf spec
+ elseif b then -- #b > 0
+ local x, y, w, h = setposition(2,snext,factor,rlmode,b,injection)
+ if trace_kerns then
+ local startchar = getchar(start)
+ logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ end
+ start = snext -- cf spec
+ elseif forcepairadvance then
+ start = snext -- for testing, not cf spec
+ end
+ return head, start, true
+ elseif krn ~= 0 then
+ local k = (format == "move" and setmove or setkern)(snext,factor,rlmode,krn,injection)
if trace_kerns then
- local startchar = getchar(start)
- logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections")
end
- start = snext -- cf spec
- elseif forcepairadvance then
- start = snext -- for testing, not cf spec
- end
- return head, start, true
- elseif krn ~= 0 then
- local k = (format == "move" and setmove or setkern)(snext,factor,rlmode,krn,injection)
- if trace_kerns then
- logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections")
+ return head, start, true
+ else -- can't happen
+ break
end
- return head, start, true
- else -- can't happen
- break
end
+ else
+ break
end
- else
- break
end
+ return head, start, false
end
- return head, start, false
end
end
@@ -1505,92 +1532,98 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup
end
function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
- local mapping = currentlookup.mapping
- if mapping == nil then
- mapping = getmapping(dataset,sequence,currentlookup)
- end
- if mapping then
- local startchar = getchar(start)
- local kerns = mapping[startchar]
- if kerns then
- local format = currentlookup.format
- if format == "single" then
- local dx, dy, w, h = setposition(0,start,factor,rlmode,kerns) -- currentlookup.flags ?
- if trace_kerns then
- logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
- end
- else -- needs checking .. maybe no kerns format for single
- local k = (format == "move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
- if trace_kerns then
- logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k)
+ -- we actually should check no_left_kern_code with next
+ if not has_glyph_option(start,no_right_kern_code) then
+ local mapping = currentlookup.mapping
+ if mapping == nil then
+ mapping = getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar = getchar(start)
+ local kerns = mapping[startchar]
+ if kerns then
+ local format = currentlookup.format
+ if format == "single" then
+ local dx, dy, w, h = setposition(0,start,factor,rlmode,kerns) -- currentlookup.flags ?
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
+ end
+ else -- needs checking .. maybe no kerns format for single
+ local k = (format == "move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k)
+ end
end
+ return head, start, true
end
- return head, start, true
end
end
return head, start, false
end
function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) -- todo: injections ?
- local mapping = currentlookup.mapping
- if mapping == nil then
- mapping = getmapping(dataset,sequence,currentlookup)
- end
- if mapping then
- local snext = getnext(start)
- if snext then
- local startchar = getchar(start)
- local kerns = mapping[startchar] -- always 1 step
- if kerns then
- local prev = start
- while snext do
- local nextchar = ischar(snext,currentfont)
- if not nextchar then
- break
- end
- if skiphash and skiphash[nextchar] then
- prev = snext
- snext = getnext(snext)
- else
- local krn = kerns[nextchar]
- if not krn then
+ -- we actually should check no_left_kern_code with next
+ if not has_glyph_option(start,no_right_kern_code) then
+ local mapping = currentlookup.mapping
+ if mapping == nil then
+ mapping = getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local snext = getnext(start)
+ if snext then
+ local startchar = getchar(start)
+ local kerns = mapping[startchar] -- always 1 step
+ if kerns then
+ local prev = start
+ while snext do
+ local nextchar = ischar(snext,currentfont)
+ if not nextchar then
break
end
- local format = currentlookup.format
- if format == "pair" then
- local a = krn[1]
- local b = krn[2]
- if a == true then
- -- zero
- elseif a then
- local x, y, w, h = setposition(1,start,factor,rlmode,a,"injections") -- currentlookups flags?
- if trace_kerns then
- local startchar = getchar(start)
- logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
- end
+ if skiphash and skiphash[nextchar] then
+ prev = snext
+ snext = getnext(snext)
+ else
+ local krn = kerns[nextchar]
+ if not krn then
+ break
end
- if b == true then
- -- zero
- start = snext -- cf spec
- elseif b then -- #b > 0
- local x, y, w, h = setposition(2,snext,factor,rlmode,b,"injections")
+ local format = currentlookup.format
+ if format == "pair" then
+ local a = krn[1]
+ local b = krn[2]
+ if a == true then
+ -- zero
+ elseif a then
+ local x, y, w, h = setposition(1,start,factor,rlmode,a,"injections") -- currentlookups flags?
+ if trace_kerns then
+ local startchar = getchar(start)
+ logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ end
+ if b == true then
+ -- zero
+ start = snext -- cf spec
+ elseif b then -- #b > 0
+ local x, y, w, h = setposition(2,snext,factor,rlmode,b,"injections")
+ if trace_kerns then
+ local startchar = getchar(start)
+ logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ start = snext -- cf spec
+ elseif forcepairadvance then
+ start = snext -- for testing, not cf spec
+ end
+ return head, start, true
+ elseif krn ~= 0 then
+ local k = (format == "move" and setmove or setkern)(snext,factor,rlmode,krn)
if trace_kerns then
- local startchar = getchar(start)
- logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
+ logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar))
end
- start = snext -- cf spec
- elseif forcepairadvance then
- start = snext -- for testing, not cf spec
- end
- return head, start, true
- elseif krn ~= 0 then
- local k = (format == "move" and setmove or setkern)(snext,factor,rlmode,krn)
- if trace_kerns then
- logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar))
+ return head, start, true
+ else
+ break
end
- return head, start, true
- else
- break
end
end
end
@@ -3759,7 +3792,7 @@ do
local initialrl = 0
- if getid(head) == localpar_code and start_of_par(head) then
+ if getid(head) == par_code and start_of_par(head) then
initialrl = pardirstate(head)
elseif direction == righttoleft_code then
initialrl = -1
@@ -3913,7 +3946,7 @@ do
elseif id == dir_code then
topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode)
start = getnext(start)
- -- elseif id == localpar_code and start_of_par(start) then
+ -- elseif id == par_code and start_of_par(start) then
-- rlparmode, rlmode = pardirstate(start)
-- start = getnext(start)
else
@@ -3997,7 +4030,7 @@ do
elseif id == dir_code then
topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode)
start = getnext(start)
- -- elseif id == localpar_code and start_of_par(start) then
+ -- elseif id == par_code and start_of_par(start) then
-- rlparmode, rlmode = pardirstate(start)
-- start = getnext(start)
else
@@ -4108,7 +4141,7 @@ do
elseif id == dir_code then
topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode)
start = getnext(start)
- -- elseif id == localpar_code and start_of_par(start) then
+ -- elseif id == par_code and start_of_par(start) then
-- rlparmode, rlmode = pardirstate(start)
-- start = getnext(start)
else