summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/page-flt.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/page-flt.lua')
-rw-r--r--tex/context/base/mkiv/page-flt.lua105
1 files changed, 77 insertions, 28 deletions
diff --git a/tex/context/base/mkiv/page-flt.lua b/tex/context/base/mkiv/page-flt.lua
index 53780e420..41a35d47b 100644
--- a/tex/context/base/mkiv/page-flt.lua
+++ b/tex/context/base/mkiv/page-flt.lua
@@ -9,12 +9,17 @@ if not modules then modules = { } end modules ['page-flt'] = {
-- floats -> managers.floats
-- some functions are a tex/lua mix so we need a separation
+local next = next
+local tostring = tostring
local insert, remove = table.insert, table.remove
local find = string.find
+local abs = math.abs
-local trace_floats = false trackers.register("graphics.floats", function(v) trace_floats = v end) -- name might change
+local trace_floats = false trackers.register("floats.caching", function(v) trace_floats = v end)
+local trace_collecting = false trackers.register("floats.collecting", function(v) trace_collecting = v end)
-local report_floats = logs.reporter("structure","floats")
+local report_floats = logs.reporter("floats","caching")
+local report_collecting = logs.reporter("floats","collecting")
local C, S, P, lpegmatch = lpeg.C, lpeg.S, lpeg.P, lpeg.match
@@ -22,6 +27,7 @@ local C, S, P, lpegmatch = lpeg.C, lpeg.S, lpeg.P, lpeg.match
-- text page leftpage rightpage (todo: top, bottom, margin, order)
local setdimen = tex.setdimen
+local getdimen = tex.getdimen
local setcount = tex.setcount
local texsetbox = tex.setbox
local textakebox = nodes.takebox
@@ -78,14 +84,25 @@ function floats.pop()
end
end
-local function setdimensions(b)
- local w, h, d = 0, 0, 0
+local function setdimensions(t,b)
+ local bw, bh, bd = 0, 0, 0
+ local nw, nh, nd = 0, 0, 0
if b then
- w, h, d = b.width, b.height, b.depth
+ bw = b.width
+ bh = b.height
+ bd = b.depth
end
- setdimen("global","floatwidth", w)
- setdimen("global","floatheight", h+d)
- return w, h, d
+ if t then
+ nw = t.width or bw
+ nh = t.height or bh
+ nd = t.depth or bd
+ end
+ setdimen("global","floatwidth", bw)
+ setdimen("global","floatheight", bh+bd)
+ setdimen("global","naturalfloatwd", nw)
+ setdimen("global","naturalfloatht", nh)
+ setdimen("global","naturalfloatdp", nd)
+ return bw, bh, bd, nw, nh, dp
end
local function get(stack,n,bylabel)
@@ -115,9 +132,12 @@ function floats.save(which,data)
local stack = stacks[which]
noffloats = noffloats + 1
local t = {
- n = noffloats,
- data = data or { },
- box = b,
+ n = noffloats,
+ data = data or { },
+ width = getdimen("naturalfloatwd"),
+ height = getdimen("naturalfloatht"),
+ depth = getdimen("naturalfloatdp"),
+ box = b,
}
insert(stack,t)
-- inspect(stacks)
@@ -138,9 +158,11 @@ function floats.resave(which)
which = which or default
local stack = stacks[which]
local b = textakebox("floatbox")
+ if not b then
+ report_floats("resaved float is empty")
+ end
last.box = b
insert(stack,1,last)
--- inspect(stacks)
setcount("global","savednoffloats",#stacks[default])
if trace_floats then
report_floats("%s, category %a, number %a, slot %a width %p, height %p, depth %p","resaving",
@@ -155,15 +177,14 @@ end
function floats.flush(which,n,bylabel)
which = which or default
--- inspect(stacks)
local stack = stacks[which]
local t, b, n = get(stack,n or 1,bylabel)
if t then
if not b then
showmessage("floatblocks",1,t.n)
end
+ local w, h, d = setdimensions(t,b)
if trace_floats then
- local w, h, d = setdimensions(b) -- ?
report_floats("%s, category %a, number %a, slot %a width %p, height %p, depth %p","flushing",
which,t.n,n,w,h,d)
else
@@ -172,7 +193,7 @@ function floats.flush(which,n,bylabel)
texsetbox("floatbox",b)
last = remove(stack,n)
last.box = nil
- setcount("global","savednoffloats",#stacks[default]) -- default?
+ setcount("global","savednoffloats",#stacks[which]) -- default?
else
setdimensions()
end
@@ -183,7 +204,7 @@ function floats.consult(which,n)
local stack = stacks[which]
local t, b, n = get(stack,n)
if t then
- local w, h, d = setdimensions(b)
+ local w, h, d = setdimensions(t,b)
if trace_floats then
report_floats("%s, category %a, number %a, slot %a width %p, height %p, depth %p","consulting",
which,t.n,n,w,h,d)
@@ -198,16 +219,46 @@ function floats.consult(which,n)
end
function floats.collect(which,maxwidth,distance)
- which = which or default
- local stack = stacks[which]
- local n, m = #stack, 0
- for i=1,n do
+ local usedwhich = which or default
+ local stack = stacks[usedwhich]
+ local stacksize = #stack
+ local collected = 0
+ local maxheight = 0
+ local maxdepth = 0
+
+ local function register()
+ collected = collected + 1
+ maxwidth = rest
+ if h > maxheight then
+ maxheight = h
+ end
+ if d > maxdepth then
+ maxdepth = d
+ end
+ end
+
+ for i=1,stacksize do
local t, b, n = get(stack,i)
if t then
- local w, h, d = setdimensions(b)
- if w + distance < maxwidth then
- m = m + 1
- maxwidth = maxwidth - w - distance
+ local w, h, d, nw = setdimensions(t,b)
+ -- we use the real width
+ w = nw
+ -- which could be an option
+ local rest = maxwidth - w - (1 == 1 and 0 or distance)
+ local fits = rest > -10
+ if trace_collecting then
+ report_collecting("%s, category %a, number %a, slot %a width %p, rest %p, fit %a","collecting",
+ usedwhich,t.n,n,w,rest,fits)
+ end
+ if fits then
+ collected = collected + 1
+ maxwidth = rest
+ if h > maxheight then
+ maxheight = h
+ end
+ if d > maxdepth then
+ maxdepth = d
+ end
else
break
end
@@ -215,10 +266,8 @@ function floats.collect(which,maxwidth,distance)
break
end
end
- if m == 0 then
- m = 1
- end
- setcount("global","nofcollectedfloats",m)
+ setcount("global","nofcollectedfloats",collected)
+ setdimen("global","maxcollectedfloatstotal",maxheight+maxdepth)
end
function floats.getvariable(name,default)