summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/font-txt.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/font-txt.lua')
-rw-r--r--tex/context/base/mkiv/font-txt.lua532
1 files changed, 268 insertions, 264 deletions
diff --git a/tex/context/base/mkiv/font-txt.lua b/tex/context/base/mkiv/font-txt.lua
index 20f290ddb..c52878ca7 100644
--- a/tex/context/base/mkiv/font-txt.lua
+++ b/tex/context/base/mkiv/font-txt.lua
@@ -247,303 +247,307 @@ end
-- users do that. On the other hand, we do support longer glyph runs in both modes
-- so there we gain a bit.
-local function texthandler(head,font,attr,rlmode,handler,startspacing,stopspacing,nesting)
- if not head then
- return
- end
- if startspacing == nil then
- startspacing = false
- end
- if stopspacing == nil then
- stopspacing = false
- end
+do
- if getid(head) == par_code and start_of_par(head) then
- rlmode = pardirstate(head)
- elseif rlmode == righttoleft_code then
- rlmode = -1
- else
- rlmode = 0
- end
-
- local dirstack = { }
- local rlparmode = 0
- local topstack = 0
- local text = { }
- local size = 0
- local current = head
- local start = nil
- local stop = nil
- local startrlmode = rlmode
+ local function texthandler(head,font,dynamic,rlmode,handler,startspacing,stopspacing,nesting)
+ if not head then
+ return
+ end
+ if startspacing == nil then
+ startspacing = false
+ end
+ if stopspacing == nil then
+ stopspacing = false
+ end
- local function handle(leading,trailing) -- what gets passed can become configureable: e.g. utf 8
- local stop = current or start -- hm, what with outer stop
- if getid(stop) ~= glyph_code then
- stop = getprev(stop)
+ if getid(head) == par_code and start_of_par(head) then
+ rlmode = pardirstate(head)
+ elseif rlmode == righttoleft_code then
+ rlmode = -1
+ else
+ rlmode = 0
end
- head = handler(head,font,attr,rlmode,start,stop,text,leading,trailing) -- handler can adapt text
- size = 0
- text = { }
- start = nil
- end
- while current do
- local char, id = ischar(current,font)
- if char then
- if not start then
- start = current
- startrlmode = rlmode
- end
- local char = getchar(current)
- size = size + 1
- text[size] = char
- current = getnext(current)
- elseif char == false then
- -- so a mixed font
- if start and size > 0 then
- handle(startspacing,false)
+ local dirstack = { }
+ local rlparmode = 0
+ local topstack = 0
+ local text = { }
+ local size = 0
+ local current = head
+ local start = nil
+ local stop = nil
+ local startrlmode = rlmode
+
+ local function handle(leading,trailing) -- what gets passed can become configureable: e.g. utf 8
+ local stop = current or start -- hm, what with outer stop
+ if getid(stop) ~= glyph_code then
+ stop = getprev(stop)
end
- startspacing = false
- current = getnext(current)
- elseif id == glue_code then
- -- making this branch optional i.e. always use the else doesn't really
- -- make a difference in performance (in hb) .. tricky anyway as we can
- local width = getwidth(current)
- if width > 0 then
- if start and size > 0 then
- handle(startspacing,true)
+ head = handler(head,font,dynamic,rlmode,start,stop,text,leading,trailing) -- handler can adapt text
+ size = 0
+ text = { }
+ start = nil
+ end
+
+ while current do
+ local char, id = ischar(current,font)
+ if char then
+ if not start then
+ start = current
+ startrlmode = rlmode
end
- startspacing = true
- stopspacing = false
- else
+ local char = getchar(current)
+ size = size + 1
+ text[size] = char
+ current = getnext(current)
+ elseif char == false then
+ -- so a mixed font
if start and size > 0 then
- head = handle(startspacing)
+ handle(startspacing,false)
end
startspacing = false
- stopspacing = false
- end
- current = getnext(current)
- elseif id == disc_code and usesfont(current,font) then -- foo|-|bar : has hbox
- -- This looks much like the original code but I don't see a need to optimize
- -- for e.g. deva or r2l fonts. If there are no disc nodes then we won't see
- -- this branch anyway and if there are, we should just deal with them.
- --
- -- There is still some weird code here ... start/stop and such. When I'm in
- -- the mood (or see a need) I'll rewrite this bit.
+ current = getnext(current)
+ elseif id == glue_code then
+ -- making this branch optional i.e. always use the else doesn't really
+ -- make a difference in performance (in hb) .. tricky anyway as we can
+ local width = getwidth(current)
+ if width > 0 then
+ if start and size > 0 then
+ handle(startspacing,true)
+ end
+ startspacing = true
+ stopspacing = false
+ else
+ if start and size > 0 then
+ head = handle(startspacing)
+ end
+ startspacing = false
+ stopspacing = false
+ end
+ current = getnext(current)
+ elseif id == disc_code and usesfont(current,font) then -- foo|-|bar : has hbox
+ -- This looks much like the original code but I don't see a need to optimize
+ -- for e.g. deva or r2l fonts. If there are no disc nodes then we won't see
+ -- this branch anyway and if there are, we should just deal with them.
+ --
+ -- There is still some weird code here ... start/stop and such. When I'm in
+ -- the mood (or see a need) I'll rewrite this bit.
- -- bug: disc in last word moves to end (in practice not an issue as one
- -- doesn't want a break there)
+ -- bug: disc in last word moves to end (in practice not an issue as one
+ -- doesn't want a break there)
- local pre = nil
- local post = nil
- local currentnext = getnext(current)
- local current_pre, current_post, current_replace = getdisc(current)
- setdisc(current) -- why, we set it later
- if start then
- pre = copy_node_list(start,current)
- stop = getprev(current)
- -- why also current and not:
- -- pre = copy_node_list(start,stop)
- if start == head then
- head = current
+ local pre = nil
+ local post = nil
+ local currentnext = getnext(current)
+ local current_pre, current_post, current_replace = getdisc(current)
+ setdisc(current) -- why, we set it later
+ if start then
+ pre = copy_node_list(start,current)
+ stop = getprev(current)
+ -- why also current and not:
+ -- pre = copy_node_list(start,stop)
+ if start == head then
+ head = current
+ end
+ setlink(getprev(start),current)
+ setlink(stop,current_pre)
+ current_pre = start
+ setprev(current_pre)
+ start = nil
+ stop = nil
+ startrlmode = rlmode
end
- setlink(getprev(start),current)
- setlink(stop,current_pre)
- current_pre = start
- setprev(current_pre)
- start = nil
- stop = nil
- startrlmode = rlmode
- end
- while currentnext do
- local char, id = ischar(currentnext,font)
- if char or id == disc_code then
- stop = currentnext
- currentnext = getnext(currentnext)
- elseif id == glue_code then
- local width = getwidth(currentnext)
- if width and width > 0 then
- stopspacing = true
+ while currentnext do
+ local char, id = ischar(currentnext,font)
+ if char or id == disc_code then
+ stop = currentnext
+ currentnext = getnext(currentnext)
+ elseif id == glue_code then
+ local width = getwidth(currentnext)
+ if width and width > 0 then
+ stopspacing = true
+ else
+ stopspacing = false
+ end
+ break
else
- stopspacing = false
+ break
end
- break
- else
- break
end
- end
- if stop then
- local currentnext = getnext(current)
- local stopnext = getnext(stop)
- post = copy_node_list(currentnext,stopnext)
- if current_post then
- setlink(find_node_tail(current_post),currentnext)
- else
- setprev(currentnext)
- current_post = currentnext
+ if stop then
+ local currentnext = getnext(current)
+ local stopnext = getnext(stop)
+ post = copy_node_list(currentnext,stopnext)
+ if current_post then
+ setlink(find_node_tail(current_post),currentnext)
+ else
+ setprev(currentnext)
+ current_post = currentnext
+ end
+ setlink(current,stopnext)
+ setnext(stop)
+ stop = nil
end
- setlink(current,stopnext)
- setnext(stop)
- stop = nil
- end
- if pre then
- setlink(find_node_tail(pre),current_replace)
- current_replace = pre
- pre = nil
- end
- if post then
- if current_replace then
- setlink(find_node_tail(current_replace),post)
- else
- current_replace = post
+ if pre then
+ setlink(find_node_tail(pre),current_replace)
+ current_replace = pre
+ pre = nil
end
- post = nil
- end
- size = 0 -- hm, ok, start is also nil now
- text = { }
- if current_pre then
- current_pre = texthandler(current_pre,font,attr,rlmode,handler,startspacing,false,"pre")
- end
- if current_post then
- current_post = texthandler(current_post,font,attr,rlmode,handler,false,stopspacing,"post")
- end
- if current_replace then
- current_replace = texthandler(current_replace,font,attr,rlmode,handler,startspacing,stopspacing,"replace")
- end
- startspacing = false
- stopspacing = false
- local cpost = current_post and find_node_tail(current_post)
- local creplace = current_replace and find_node_tail(current_replace)
- local cpostnew = nil
- local creplacenew = nil
- local newcurrent = nil
- while cpost and equalnode(cpost,creplace) do
- cpostnew = cpost
- creplacenew = creplace
- if creplace then
- creplace = getprev(creplace)
+ if post then
+ if current_replace then
+ setlink(find_node_tail(current_replace),post)
+ else
+ current_replace = post
+ end
+ post = nil
end
- cpost = getprev(cpost)
- end
- if cpostnew then
- if cpostnew == current_post then
- current_post = nil
- else
- setnext(getprev(cpostnew))
+ size = 0 -- hm, ok, start is also nil now
+ text = { }
+ if current_pre then
+ current_pre = texthandler(current_pre,font,dynamic,rlmode,handler,startspacing,false,"pre")
end
- flush_list(cpostnew)
- if creplacenew == current_replace then
- current_replace = nil
- else
- setnext(getprev(creplacenew))
+ if current_post then
+ current_post = texthandler(current_post,font,dynamic,rlmode,handler,false,stopspacing,"post")
end
- local c = getnext(current)
- setlink(current,creplacenew)
- local creplacenewtail = find_node_tail(creplacenew)
- setlink(creplacenewtail,c)
- newcurrent = creplacenewtail
- end
- current_post = current_post and deletedisc(current_post)
- current_replace = current_replace and deletedisc(current_replace)
- local cpre = current_pre
- local creplace = current_replace
- local cprenew = nil
- local creplacenew = nil
- while cpre and equalnode(cpre, creplace) do
- cprenew = cpre
- creplacenew = creplace
- if creplace then
- creplace = getnext(creplace)
+ if current_replace then
+ current_replace = texthandler(current_replace,font,dynamic,rlmode,handler,startspacing,stopspacing,"replace")
end
- cpre = getnext(cpre)
- end
- if cprenew then
- cpre = current_pre
- current_pre = getnext(cprenew)
- if current_pre then
- setprev(current_pre)
+ startspacing = false
+ stopspacing = false
+ local cpost = current_post and find_node_tail(current_post)
+ local creplace = current_replace and find_node_tail(current_replace)
+ local cpostnew = nil
+ local creplacenew = nil
+ local newcurrent = nil
+ while cpost and equalnode(cpost,creplace) do
+ cpostnew = cpost
+ creplacenew = creplace
+ if creplace then
+ creplace = getprev(creplace)
+ end
+ cpost = getprev(cpost)
end
- setnext(cprenew)
- flush_list(cpre)
- creplace = current_replace
- current_replace = getnext(creplacenew)
- if current_replace then
- setprev(current_replace)
+ if cpostnew then
+ if cpostnew == current_post then
+ current_post = nil
+ else
+ setnext(getprev(cpostnew))
+ end
+ flush_list(cpostnew)
+ if creplacenew == current_replace then
+ current_replace = nil
+ else
+ setnext(getprev(creplacenew))
+ end
+ local c = getnext(current)
+ setlink(current,creplacenew)
+ local creplacenewtail = find_node_tail(creplacenew)
+ setlink(creplacenewtail,c)
+ newcurrent = creplacenewtail
end
- setlink(getprev(current),creplace)
- if current == head then
- head = creplace
+ current_post = current_post and deletedisc(current_post)
+ current_replace = current_replace and deletedisc(current_replace)
+ local cpre = current_pre
+ local creplace = current_replace
+ local cprenew = nil
+ local creplacenew = nil
+ while cpre and equalnode(cpre, creplace) do
+ cprenew = cpre
+ creplacenew = creplace
+ if creplace then
+ creplace = getnext(creplace)
+ end
+ cpre = getnext(cpre)
end
- setlink(creplacenew,current)
- end
- setdisc(current,current_pre,current_post,current_replace)
- current = currentnext
- else
- if start and size > 0 then
- handle(startspacing,stopspacing)
- end
- startspacing = false
- stopspacing = false
- if id == math_code then
- current = getnext(end_of_math(current))
- elseif id == dir_code then
- startspacing = false
- topstack, rlmode = txtdirstate(current,dirstack,topstack,rlparmode)
- current = getnext(current)
- -- elseif id == par_code and start_of_par(current) then
- -- startspacing = false
- -- rlparmode, rlmode = pardirstate(current)
- -- current = getnext(current)
+ if cprenew then
+ cpre = current_pre
+ current_pre = getnext(cprenew)
+ if current_pre then
+ setprev(current_pre)
+ end
+ setnext(cprenew)
+ flush_list(cpre)
+ creplace = current_replace
+ current_replace = getnext(creplacenew)
+ if current_replace then
+ setprev(current_replace)
+ end
+ setlink(getprev(current),creplace)
+ if current == head then
+ head = creplace
+ end
+ setlink(creplacenew,current)
+ end
+ setdisc(current,current_pre,current_post,current_replace)
+ current = currentnext
else
- current = getnext(current)
+ if start and size > 0 then
+ handle(startspacing,stopspacing)
+ end
+ startspacing = false
+ stopspacing = false
+ if id == math_code then
+ current = getnext(end_of_math(current))
+ elseif id == dir_code then
+ startspacing = false
+ topstack, rlmode = txtdirstate(current,dirstack,topstack,rlparmode)
+ current = getnext(current)
+ -- elseif id == par_code and start_of_par(current) then
+ -- startspacing = false
+ -- rlparmode, rlmode = pardirstate(current)
+ -- current = getnext(current)
+ else
+ current = getnext(current)
+ end
end
end
+ if start and size > 0 then
+ handle(startspacing,stopspacing)
+ end
+ return head, true
end
- if start and size > 0 then
- handle(startspacing,stopspacing)
- end
- return head, true
-end
-function fonts.handlers.otf.texthandler(head,font,attr,direction,action)
- if action then
- return texthandler(head,font,attr,direction == righttoleft_code and -1 or 0,action)
- else
- return head, false
+ function fonts.handlers.otf.texthandler(head,font,dynamic,direction,action)
+ if action then
+ return texthandler(head,font,dynamic,direction == righttoleft_code and -1 or 0,action)
+ else
+ return head, false
+ end
end
-end
--- Next comes a tracer plug into context.
+ -- Next comes a tracer plug into context.
-local texthandler = fonts.handlers.otf.texthandler
-local report_text = logs.reporter("otf plugin","text")
-local nofruns = 0
-local nofsnippets = 0
-local f_unicode = string.formatters["%U"]
+ ----- texthandler = fonts.handlers.otf.texthandler
+ local report_text = logs.reporter("otf plugin","text")
+ local nofruns = 0
+ local nofsnippets = 0
+ local f_unicode = string.formatters["%U"]
-local function showtext(head,font,attr,rlmode,start,stop,list,before,after)
- if list then
- nofsnippets = nofsnippets + 1
- local plus = { }
- for i=1,#list do
- local u = list[i]
- list[i] = utfchar(u)
- plus[i] = f_unicode(u)
+ local function showtext(head,font,dynamic,rlmode,start,stop,list,before,after)
+ if list then
+ nofsnippets = nofsnippets + 1
+ local plus = { }
+ for i=1,#list do
+ local u = list[i]
+ list[i] = utfchar(u)
+ plus[i] = f_unicode(u)
+ end
+ report_text("%03i : [%s] %t [%s]-> % t", nofsnippets, before and "+" or "-", list, after and "+" or "-", plus)
+ else
+ report_text()
+ report_text("invalid list")
+ report_text()
end
- report_text("%03i : [%s] %t [%s]-> % t", nofsnippets, before and "+" or "-", list, after and "+" or "-", plus)
- else
- report_text()
- report_text("invalid list")
- report_text()
+ return head, false
end
- return head, false
-end
-fonts.handlers.otf.registerplugin("text",function(head,font,attr,direction)
- nofruns = nofruns + 1
- nofsnippets = 0
- report_text("start run %i",nofruns)
- local h, d = texthandler(head,font,attr,direction,showtext)
- report_text("stop run %i",nofruns)
- return h, d
-end)
+ fonts.handlers.otf.registerplugin("text",function(head,font,dynamic,direction)
+ nofruns = nofruns + 1
+ nofsnippets = 0
+ report_text("start run %i",nofruns)
+ local h, d = texthandler(head,font,dynamic,direction,showtext)
+ report_text("stop run %i",nofruns)
+ return h, d
+ end)
+
+end