summaryrefslogtreecommitdiff
path: root/tex/context/base/mkxl/typo-cap.lmt
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkxl/typo-cap.lmt')
-rw-r--r--tex/context/base/mkxl/typo-cap.lmt272
1 files changed, 135 insertions, 137 deletions
diff --git a/tex/context/base/mkxl/typo-cap.lmt b/tex/context/base/mkxl/typo-cap.lmt
index c5c91243e..fe7406e76 100644
--- a/tex/context/base/mkxl/typo-cap.lmt
+++ b/tex/context/base/mkxl/typo-cap.lmt
@@ -19,83 +19,85 @@ local report_casing = logs.reporter("typesetting","casing")
local nodes, node = nodes, node
-local nuts = nodes.nuts
+local nuts = nodes.nuts
-local getnext = nuts.getnext
-local getid = nuts.getid
-local takeattr = nuts.takeattr
-local getfont = nuts.getfont
-local getsubtype = nuts.getsubtype
-local getchar = nuts.getchar
-local isglyph = nuts.isglyph
-local getdisc = nuts.getdisc
+local getnext = nuts.getnext
+local getid = nuts.getid
+local getattr = nuts.getattr
+local getfont = nuts.getfont
+local getsubtype = nuts.getsubtype
+local getchar = nuts.getchar
+local isglyph = nuts.isglyph
+local getdisc = nuts.getdisc
-local setchar = nuts.setchar
-local setfont = nuts.setfont
+local setchar = nuts.setchar
+local setfont = nuts.setfont
-local copy_node = nuts.copy
-local end_of_math = nuts.end_of_math
-local insert_after = nuts.insert_after
-local find_attribute = nuts.find_attribute
+local copy_node = nuts.copy
+local end_of_math = nuts.end_of_math
+local insert_after = nuts.insert_after
+local find_attribute = nuts.find_attribute
+local unset_attributes = nuts.unset_attributes
-local nextglyph = nuts.traversers.glyph
+local nextglyph = nuts.traversers.glyph
-local nodecodes = nodes.nodecodes
-local kerncodes = nodes.kerncodes
+local nodecodes = nodes.nodecodes
+local kerncodes = nodes.kerncodes
-local glyph_code = nodecodes.glyph
-local kern_code = nodecodes.kern
-local disc_code = nodecodes.disc
-local math_code = nodecodes.math
+local glyph_code = nodecodes.glyph
+local kern_code = nodecodes.kern
+local disc_code = nodecodes.disc
+local math_code = nodecodes.math
-local fontkern_code = kerncodes.fontkern
+local fontkern_code = kerncodes.fontkern
-local enableaction = nodes.tasks.enableaction
+local enableaction = nodes.tasks.enableaction
-local newkern = nuts.pool.kern
+local newkern = nuts.pool.kern
-local fonthashes = fonts.hashes
-local fontdata = fonthashes.identifiers
-local fontchar = fonthashes.characters
+local fonthashes = fonts.hashes
+local fontdata = fonthashes.identifiers
+local fontchar = fonthashes.characters
-local currentfont = font.current
+local currentfont = font.current
-local variables = interfaces.variables
-local v_reset = variables.reset
+local variables = interfaces.variables
+local v_reset = variables.reset
-local texsetattribute = tex.setattribute
-local unsetvalue = attributes.unsetvalue
+local texsetattribute = tex.setattribute
+local unsetvalue = attributes.unsetvalue
-typesetters = typesetters or { }
-local typesetters = typesetters
+typesetters = typesetters or { }
+local typesetters = typesetters
-typesetters.cases = typesetters.cases or { }
-local cases = typesetters.cases
+typesetters.cases = typesetters.cases or { }
+local cases = typesetters.cases
-cases.actions = { }
-local actions = cases.actions
-local a_cases = attributes.private("case")
+cases.actions = { }
+local actions = cases.actions
+local a_cases = attributes.private("case")
-local extract = bit32.extract
-local run = 0 -- a trick to make neighbouring ranges work
-local blocked = { }
+local run = 0 -- a trick to make neighbouring ranges work
+local blocked = { }
local function set(tag,font)
- if run == 0x40 then -- 2^6
- run = 1
- else
+ if run < 0x7F then
run = run + 1
+ else
+ run = 1
end
- local a = font * 0x10000 + tag * 0x100 + run
+ local a = (font << 16)
+ + (tag << 8)
+ + (run << 0)
blocked[a] = false
return a
end
local function get(a)
return
- extract(a, 8, 8), -- tag
- extract(a,16,12), -- font
- extract(a, 0, 8) -- run
+ (a >> 8) & 0x00FF, -- tag
+ (a >> 16) & 0xFFFF, -- font
+ (a >> 0) & 0x00FF -- run
end
-- a previous implementation used char(0) as placeholder for the larger font, so we needed
@@ -279,106 +281,103 @@ register(variables.camel, camel) -- 10
register(variables.cap, variables.capital) -- clone
register(variables.Cap, variables.Capital) -- clone
--- This can be more clever: when we unset we can actually use the same attr ref if
--- needed. Using properties to block further usage is not faster.
-
-function cases.handler(head) -- not real fast but also not used on much data
- local start = head
- local lastfont = { }
- local lastattr = nil
- local count = 0
- local previd = nil
- local prev = nil
- while start do -- while because start can jump ahead
- local id = getid(start)
- if id == glyph_code then
- local attr = takeattr(start,a_cases)
- if attr and attr > 0 and not blocked[attr] then
- if attr ~= lastattr then
- lastattr = attr
- count = 1
- else
- count = count + 1
- end
- local n, id, m = get(attr)
- if lastfont[n] == nil then
- lastfont[n] = id
- end
- local action = actions[n] -- map back to low number
- if action then
- local quit
- start, quit = action(start,attr,lastfont,n,count)
- if trace_casing then
- report_casing("case trigger %a, instance %a, fontid %a, result %a",n,m,id,quit and "-" or "+")
+function cases.handler(head)
+ local _, start = find_attribute(head, a_cases)
+ if start then
+ local lastfont = { }
+ local lastattr = nil
+ local count = 0
+ local done = false
+ while start do -- while because start can jump ahead
+ local id = getid(start)
+ if id == glyph_code then
+ local attr = getattr(start,a_cases)
+ if attr and attr > 0 and not blocked[attr] then
+ if attr ~= lastattr then
+ lastattr = attr
+ count = 1
+ else
+ count = count + 1
end
- elseif trace_casing then
- report_casing("unknown case trigger %a",n)
- end
- end
- elseif id == disc_code then
- local attr = takeattr(start,a_cases)
- if attr and attr > 0 and not blocked[attr] then
- if attr ~= lastattr then
- lastattr = attr
- count = 0
- end
- local n, id, m = get(attr)
- if lastfont[n] == nil then
- lastfont[n] = id
+ local n, id, m = get(attr)
+ if lastfont[n] == nil then
+ lastfont[n] = id
+ end
+ local action = actions[n] -- map back to low number
+ if action then
+ local quit
+ start, quit = action(start,attr,lastfont,n,count)
+ if trace_casing then
+ report_casing("case trigger %a, instance %a, fontid %a, result %a",n,m,id,quit and "-" or "+")
+ end
+ elseif trace_casing then
+ report_casing("unknown case trigger %a",n)
+ end
+ done = true
end
- local action = actions[n] -- map back to low number
- if action then
- local pre, post, replace = getdisc(start)
- if replace then
- local cnt = count
- for g in nextglyph, replace do
- cnt = cnt + 1
- takeattr(g,a_cases)
- local h, quit = action(start,attr,lastfont,n,cnt,"replace",g)
- if quit then
- break
+ elseif id == disc_code then
+ local attr = getattr(start,a_cases)
+ if attr and attr > 0 and not blocked[attr] then
+ if attr ~= lastattr then
+ lastattr = attr
+ count = 0
+ end
+ local n, id, m = get(attr)
+ if lastfont[n] == nil then
+ lastfont[n] = id
+ end
+ local action = actions[n] -- map back to low number
+ if action then
+ local pre, post, replace = getdisc(start)
+ if replace then
+ local cnt = count
+ for g in nextglyph, replace do
+ cnt = cnt + 1
+ getattr(g,a_cases)
+ local h, quit = action(start,attr,lastfont,n,cnt,"replace",g)
+ if quit then
+ break
+ end
end
end
- end
- if pre then
- local cnt = count
- for g in nextglyph, pre do
- cnt = cnt + 1
- takeattr(g,a_cases)
- local h, quit = action(start,attr,lastfont,n,cnt,"pre",g)
- if quit then
- break
+ if pre then
+ local cnt = count
+ for g in nextglyph, pre do
+ cnt = cnt + 1
+ getattr(g,a_cases)
+ local h, quit = action(start,attr,lastfont,n,cnt,"pre",g)
+ if quit then
+ break
+ end
end
end
- end
- if post then
- local cnt = count
- for g in nextglyph, post do
- cnt = cnt + 1
- takeattr(g,a_cases)
- local h, quit = action(start,attr,lastfont,n,cnt,"post",g)
- if quit then
- break
+ if post then
+ local cnt = count
+ for g in nextglyph, post do
+ cnt = cnt + 1
+ getattr(g,a_cases)
+ local h, quit = action(start,attr,lastfont,n,cnt,"post",g)
+ if quit then
+ break
+ end
end
end
end
+ count = count + 1
+ done = true
end
- count = count + 1
- end
- elseif id == math_code then
- start = end_of_math(start)
- count = 0
- elseif count > 0 then
- if prev_id == kern_code and getsubtype(prev) == fontkern_code then
- -- still inside a word ...normally kerns are added later
else
+ if id == math_code then
+ start = end_of_math(start)
+ end
count = 0
end
+ if start then
+ start = getnext(start)
+ end
end
- if start then
- prev = start
- previd = id
- start = getnext(start)
+ if done then
+ -- unset_attributes(a_cases,head)
end
end
return head
@@ -415,6 +414,5 @@ interfaces.implement {
-- public = true,
-- protected = true,
actions = cases.set,
--- arguments = { "string" }
arguments = { "argument" }
}