summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/typo-lin.lmt
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/typo-lin.lmt')
-rw-r--r--tex/context/base/mkiv/typo-lin.lmt475
1 files changed, 0 insertions, 475 deletions
diff --git a/tex/context/base/mkiv/typo-lin.lmt b/tex/context/base/mkiv/typo-lin.lmt
deleted file mode 100644
index e49f13b60..000000000
--- a/tex/context/base/mkiv/typo-lin.lmt
+++ /dev/null
@@ -1,475 +0,0 @@
-if not modules then modules = { } end modules ['typo-lin'] = {
- version = 1.001,
- comment = "companion to typo-lin.mkiv",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- This is experimental code. The idea is to create an anchor point in a line but there are
--- some considerations:
---
--- * if we normalize in order to have more easy access later on, we need to normalize all
--- lines and we cannot catch all without losing efficiency
---
--- * if we normalize too soon, we might have issues with changed properties later on
---
--- * if we normalize too late, we have no knowledge of the current hsize
---
--- * if we always create an anchor we also create unwanted overhead if it is not used later
--- on (more nodes)
---
--- The question is: do we mind of at the first access an anchor is created? As we cannot know
--- that now, I choose some middle ground but this might change. if we don't assume direct
--- access but only helpers, we can decide later.
---
--- Because of right2left mess it makes sense to use helpers so that we only need to deal with
--- this mess once, in helpers. The more abstraction there the better. And so, after a week of
--- experimenting, yet another abstraction was introduced.
---
--- The danger of adding the anchor later is that we adapt the head and so the caller needs to
--- check that ... real messy. On the other hand, we soldom traverse the line. And other
--- mechanisms can push stuff in front too. Actually that alone can mess up analysis when we
--- delay too much. So in the end we need to accept the slow down.
---
--- We only need to normalize the left side because when we mess around we keep the page stream
--- order (and adding content to the right of the line is a no-go for tagged etc. For the same
--- reason we don't use two left anchors (each side fo leftskip) because there can be stretch.
--- But, maybe there are good reasons for having just that anchor (mostly for educational purposes
--- I guess.)
---
--- At this stage the par node is no longer of any use so we remove it (each line has the
--- direction attached). We might at some point also strip the disc nodes as they no longer serve
--- a purpose but that can better be a helper. Anchoring left has advantage of keeping page
--- stream.
---
--- This looks a bit messy but we want to keep the box as it is so \showboxes still visualizes as
--- expected. Normally left and rightskips end up in the line while hangindents become shifts and
--- hsize corrections. We could normalize this to a line with
-
--- indent : hlist type 3
--- hangindent : shift and width
-
-local type = type
-
-local trace_anchors = false trackers.register("paragraphs.anchors", function(v) trace_anchors = v end)
-
-local report = logs.reporter("anchors")
-
-local nuts = nodes.nuts
-local nodecodes = nodes.nodecodes
-local gluecodes = nodes.gluecodes
-local listcodes = nodes.listcodes
-
-local hlist_code = nodecodes.hlist
-local glue_code = nodecodes.glue
-local kern_code = nodecodes.kern
-local linelist_code = listcodes.line
------ par_code = nodecodes.par
-local leftskip_code = gluecodes.leftskip
-local rightskip_code = gluecodes.rightskip
-local parfillskip_code = gluecodes.parfillskip
-
-local tonut = nodes.tonut
-local tonode = nodes.tonode
-
-local nexthlist = nuts.traversers.hlist
-local insert_before = nuts.insert_before
-local insert_after = nuts.insert_after
-local find_tail = nuts.tail
-local rehpack = nuts.rehpack
------ remove_node = nuts.remove
-
-local getsubtype = nuts.getsubtype
-local getlist = nuts.getlist
-local setlist = nuts.setlist
-local getid = nuts.getid
-local getnext = nuts.getnext
-local getprev = nuts.getprev
-local getboth = nuts.getboth
-local setlink = nuts.setlink
-local setkern = nuts.setkern
-local getkern = nuts.getkern
-local getdirection = nuts.getdirection
-local getshift = nuts.getshift
-local setshift = nuts.setshift
-local getwidth = nuts.getwidth
-local setwidth = nuts.setwidth
-
-local setprop = nuts.setprop
-local getprop = nuts.rawprop -- getprop
-
-local effectiveglue = nuts.effective_glue
-
-local nodepool = nuts.pool
-local new_kern = nodepool.kern
-local new_leftskip = nodepool.leftskip
-local new_rightskip = nodepool.rightskip
-local new_hlist = nodepool.hlist
-local new_rule = nodepool.rule
-local new_glue = nodepool.glue
-
-local righttoleft_code = nodes.dirvalues.righttoleft
-
-local texgetcount = tex.getcount
-local texgetglue = tex.getglue
-local setmetatableindex = table.setmetatableindex
-local formatters = string.formatters
-
-local jobpositions = job.positions
-local getposition = jobpositions.get
-local getreserved = jobpositions.getreserved
-
-local paragraphs = { }
-typesetters.paragraphs = paragraphs
-
-local addskips = false -- todo: use engine normalizer
-local noflines = 0
-
--- This is the third version, a mix between immediate (prestine lines) and delayed
--- as we don't want anchors that are not used.
-
--- I will make a better variant once lmtx is stable i.e. less clutter.
-
-local function finalize(prop,key) -- delayed calculations
- local line = prop.line
- local hsize = prop.hsize
- local width = prop.width
- local shift = getshift(line) -- dangerous as it can be vertical as well
- local reverse = getdirection(line) == righttoleft_code or false
- local pack = new_hlist()
- local head = getlist(line)
- local delta = 0
- if reverse then
- delta = - shift + (hsize - width)
- else
- delta = shift
- end
- local kern1 = new_kern(delta)
- local kern2 = new_kern(-delta)
- head = insert_before(head,head,kern1)
- head = insert_before(head,head,pack)
- head = insert_before(head,head,kern2)
- setlist(line,head)
- local where = {
- pack = pack,
- head = nil,
- tail = nil,
- }
- prop.where = where
- prop.reverse = reverse
- prop.shift = shift
- setmetatableindex(prop,nil)
- return prop[key]
-end
-
-local function normalize(line,islocal) -- assumes prestine lines, nothing pre/appended
- local oldhead = getlist(line)
- local head = oldhead
- local leftskip = nil
- local rightskip = nil
- local width = getwidth(line)
- local hsize = islocal and width or tex.hsize
- local lskip = 0
- local rskip = 0
- local pskip = 0
- local current = head
- local id = getid(current)
- if id == glue_code then
- local subtype = getsubtype(head)
- if subtype == leftskip_code then
- leftskip = head
- lskip = getwidth(head) or 0
- end
- current = getnext(head)
- id = getid(current)
- end
- -- no:
- -- if id == par_code then
- -- head = remove_node(head,head,true)
- -- end
- local tail = find_tail(head)
- local current = tail
- local id = getid(current)
- if id == glue_code then
- if getsubtype(current) == rightskip_code then
- rightskip = tail
- rskip = getwidth(current) or 0
- current = getprev(tail)
- id = getid(current)
- end
- if id == glue_code then
- if getsubtype(current) == parfillskip_code then
- pskip = effectiveglue(current,line)
- end
- end
- end
- if addskips then
- if rightskip and not leftskip then
- leftskip = new_leftskip(lskip)
- head = insert_before(head,head,leftskip)
- end
- if leftskip and not rightskip then
- rightskip = new_rightskip(0)
- head, tail = insert_after(head,tail,rightskip)
- end
- end
- if head ~= oldhead then
- setlist(line,head)
- end
- noflines = noflines + 1
- local prop = {
- width = width,
- hsize = hsize,
- leftskip = lskip,
- rightskip = rskip,
- parfillskip = pskip,
- line = line,
- number = noflines,
- }
- setprop(line,"line",prop)
- setmetatableindex(prop,finalize)
- return prop
-end
-
-function paragraphs.checkline(n)
- return getprop(n,"line") or normalize(n,true)
-end
-
--- do we still need this:
-
-function paragraphs.normalize(head,islocal)
- if texgetcount("pagebodymode") > 0 then
- -- can be an option, maybe we need a proper state in lua itself ... is this check still needed?
- return head, false
- end
- -- normalizer : todo, get the data, no need to normalize
- for line, subtype in nexthlist, head do
- if subtype == linelist_code and not getprop(line,"line") then
- normalize(line)
- end
- end
- return head, true -- true is obsolete
-end
-
--- print(nodes.idstostring(head))
-
--- We do only basic positioning and leave compensation for directions and distances
--- to the caller as that one knows the circumstances better.
-
--- todo: only in mvl or explicitly, e.g. framed or so, not in all lines
-
-local function addtoline(n,list,option)
- local line = getprop(n,"line")
- if not line then
- line = normalize(n,true)
- end
- if line then
- if trace_anchors and not line.traced then
- line.traced = true
- local rule = new_rule(2*65536,2*65536,1*65536)
- local list = insert_before(rule,rule,new_kern(-1*65536))
- addtoline(n,list)
- local rule = new_rule(2*65536,6*65536,-3*65536)
- local list = insert_before(rule,rule,new_kern(-1*65536))
- addtoline(n,list,"internal")
- else
- line.traced = true
- end
- local list = tonut(list)
- local where = line.where
- local head = where.head
- local tail = where.tail
- local blob = new_hlist(list)
- local delta = 0
- if option == "internal" then
- if line.reverse then
- delta = line.shift - line.leftskip - (line.hsize - line.width)
- else
- delta = line.shift + line.leftskip
- end
- end
- -- always kerns, also when 0 so that we can adapt but we can optimize if needed
- -- by keeping a hash as long as we use the shiftinline helper .. no need to
- -- optimize now .. we can also decide to put each blob in a hlist
- local kern = new_kern(delta)
- if tail then
- head, tail = insert_after(head,tail,kern)
- else
- head, tail = kern, kern
- setlist(where.pack,head)
- end
- head, tail = insert_after(head,tail,blob)
- local kern = new_kern(-delta)
- head, tail = insert_after(head,tail,kern)
- --
- where.head = head
- where.tail = tail
- return line, blob
- else
- -- report("unknown anchor")
- end
-end
-
-local function addanchortoline(n,anchor)
- local line = type(n) ~= "table" and getprop(n,"line") or n
- if not line then
- line = normalize(n,true)
- end
- if line then
- local anchor = tonut(anchor)
- local where = line.where
- if trace_anchors then
- anchor = new_hlist(setlink(
- anchor,
- new_kern(-65536/4),
- new_rule(65536/2,4*65536,4*65536),
- new_kern(-65536/4-4*65536),
- new_rule(8*65536,65536/4,65536/4)
- ))
- setwidth(anchor,0)
- end
- if where.tail then
- local head = where.head
- insert_before(head,head,anchor)
- else
- where.tail = anchor
- end
- setlist(where.pack,anchor)
- where.head = anchor
- return line
- end
-end
-
-paragraphs.addtoline = addtoline
-paragraphs.addanchortoline = addanchortoline
-
-function paragraphs.moveinline(n,blob,dx,dy)
- if not blob then
- return
- end
- if not dx then
- dx = 0
- end
- if not dy then
- dy = 0
- end
- if dx ~= 0 or dy ~= 0 then
- local line = type(n) ~= "table" and getprop(n,"line") or n
- if line then
- if dx ~= 0 then
- local prev, next = getboth(blob)
- if prev and getid(prev) == kern_code then
- setkern(prev,getkern(prev) + dx)
- end
- if next and getid(next) == kern_code then
- setkern(next,getkern(next) - dx)
- end
- end
- if dy ~= 0 then
- if getid(blob) == hlist_code then
- setshift(blob,getshift(blob) + dy)
- end
- end
- else
--- report("no line")
- end
- end
-end
-
-local latelua = nodepool.latelua
-local setposition = jobpositions.setspec
-
-local function setanchor(h_anchor)
- return latelua {
- action = setposition,
- name = "md:h",
- index = h_anchor,
- value = { x = true, c = true },
- }
-end
-
-function paragraphs.calculatedelta(n,width,delta,atleft,islocal,followshape,area)
- local line = type(n) ~= "table" and getprop(n,"line") or n
- if not line then
- line = normalize(n,true)
- end
- local hmove = 0
- if line then
- local reverse = line.reverse
- -- basic hsize based anchoring
- if atleft then
- if reverse then
- -- delta = delta
- else
- delta = - delta - width
- end
- else
- if reverse then
- delta = - delta - width - line.hsize
- else
- delta = delta + line.hsize
- end
- end
- if islocal then
- -- relative to hsize with leftskip / rightskip compensation
- if atleft then
- if reverse then
- delta = delta - line.leftskip
- else
- delta = delta + line.leftskip
- end
- else
- if reverse then
- delta = delta + line.rightskip
- else
- delta = delta - line.rightskip
- end
- end
- if followshape then
- -- shape compensation
- if atleft then
- if reverse then
- delta = delta + line.shift - line.hsize + line.width
- else
- delta = delta + line.shift
- end
- else
- if reverse then
- delta = delta + line.shift + line.parfillskip
- else
- delta = delta + line.shift - line.hsize + line.width - line.parfillskip
- end
- end
- end
- end
- if area then
- local number = line.number
- if not line.hanchor then
- addanchortoline(line,setanchor(number))
- line.hanchor = true
- end
- local blob = getposition(s_anchor,number)
- if blob then
- local reference = getreserved(area,blob.c)
- if reference then
- hmove = (reference.x or 0) - (blob.x or 0)
- if atleft then
- if reverse then
- hmove = hmove + (reference.w or 0)
- else
- -- hmove = hmove
- end
- else
- if reverse then
- hmove = hmove + line.hsize
- else
- hmove = hmove + (reference.w or 0) - line.hsize
- end
- end
- end
- end
- end
- end
- return delta, hmove
-end