diff options
Diffstat (limited to 'tex/context/base/mkxl/driv-shp.lmt')
-rw-r--r-- | tex/context/base/mkxl/driv-shp.lmt | 513 |
1 files changed, 280 insertions, 233 deletions
diff --git a/tex/context/base/mkxl/driv-shp.lmt b/tex/context/base/mkxl/driv-shp.lmt index 2a2b14850..73e7085b2 100644 --- a/tex/context/base/mkxl/driv-shp.lmt +++ b/tex/context/base/mkxl/driv-shp.lmt @@ -143,6 +143,10 @@ function drivers.getvpos() return round(pos_v) end -- characters +-- experiment (smaller page stream but might be fragile) + +local tospace = false directives.register("backends.spaces", function(v) tospace = v end) + local flush_character do local stack = setmetatableindex("table") @@ -150,30 +154,65 @@ local flush_character do local nesting = 0 local main = 0 - -- experiment (smaller page stream but might be fragile) - - local tospace = false directives.register("backends.spaces", function(v) tospace = v end) - -- todo: cache streams - local default = 16384 -- * number.dimenfactors.bp -- 65536 // 4 + local default = 16384 -- * number.dimenfactors.bp -- 65536 // 4 + local refactored = 1000000 -- expansion related local vfinjectors = fonts.helpers.vfinjectors -- current can go + -- local alternative = false -- more local, can be an option: vf.commands.local + local function flush_vf_packet(current,pos_h,pos_v,pos_r,font,char,data,csx,csy,factor,sx,sy,vfcommands) if nesting > 100 then return elseif nesting == 0 then main = font + -- if alternative then + -- local s = stack[0] + -- s[1] = pos_h + -- s[2] = pos_v + -- s[3] = pos_r + -- end + else + -- if alternative then + -- local s = stack[0] + -- pos_h = s[1] + -- pos_v = s[2] + -- pos_r = s[3] + -- end end nesting = nesting + 1 + local savedlevel = level + + local function push() + level = level + 1 + local s = stack[level] + s[1] = pos_h + s[2] = pos_v + s[3] = pos_r + end + + local function pop() + if level > 0 then + local s = stack[level] + pos_h = s[1] + pos_v = s[2] + pos_r = s[3] + level = level - 1 + end + end + + -- push() -- or: + local saved_h = pos_h local saved_v = pos_v local saved_r = pos_r + pos_r = lefttoright_code local fdata = fontdata[font] -- offsets etc @@ -250,96 +289,118 @@ local flush_character do end end - local refactored = 1000000 for i=1,#vfcommands do - local packet = vfcommands[i] - local command = packet[1] - if command == "char" then - local chr = packet[2] - local csx = packet[3] - local csy = packet[4] or csx - pos_h = pos_h + flushchar(fnt,chr,csx,csy) - elseif command == "slot" then - local index = packet[2] - local chr = packet[3] - local csx = packet[4] - local csy = packet[5] or csx - if index == 0 then - pos_h = pos_h + flushchar(font,chr,csx,csy) - else - local okay = fonts and fonts[index] - if okay then - local fnt = okay.id - if fnt then - pos_h = pos_h + flushchar(fnt,chr,csx,csy) - end - else - -- safeguard, we assume the font itself (often index 1) - pos_h = pos_h + flushchar(font,chr,csx,csy) - end - end - elseif command == "use" then - local index = packet[2] - if index then - local fnt + local packet = vfcommands[i] + if packet then + local command = packet[1] + if command == "char" then + local chr = packet[2] + local csx = packet[3] + local csy = packet[4] or csx + pos_h = pos_h + flushchar(fnt,chr,csx,csy) + elseif command == "slot" then + local index = packet[2] + local chr = packet[3] + local csx = packet[4] + local csy = packet[5] or csx if index == 0 then - fnt = font + pos_h = pos_h + flushchar(font,chr,csx,csy) else local okay = fonts and fonts[index] if okay then - fnt = okay.id + local fnt = okay.id + if fnt then + if fnt == 0 then + fnt = font + end + pos_h = pos_h + flushchar(fnt,chr,csx,csy) + end + else + -- safeguard, we assume the font itself (often index 1) + pos_h = pos_h + flushchar(font,chr,csx,csy) end end - if fnt then - -- not efficient but ok for now as experiment - local d = characters[fnt] - if d then - for i=3,#packet do - local chr = packet[i] - local dat = d[chr] - if dat then - flushfontchar(fnt,chr,dat) + elseif command == "use" then + local index = packet[2] + if index then + local fnt + if index == 0 then + fnt = font + else + local okay = fonts and fonts[index] + if okay then + fnt = okay.id + end + end + if fnt then + -- not efficient but ok for now as experiment + local d = characters[fnt] + if d then + for i=3,#packet do + local chr = packet[i] + local dat = d[chr] + if dat then + flushfontchar(fnt,chr,dat) + end end end end end - end - elseif command == "right" then - local h = packet[2] -- already scaled - if h ~= 0 then - if factor ~= 0 then - h = h + h * factor / refactored -- expansion + elseif command == "right" then + local h = packet[2] -- already scaled + if h ~= 0 then + if factor ~= 0 then + h = h + h * factor / refactored -- expansion + end + pos_h = pos_h + h * sx end - pos_h = pos_h + h * sx - end - elseif command == "left" then - local h = packet[2] -- already scaled - if h ~= 0 then - if factor ~= 0 then - h = h + h * factor / refactored -- expansion + elseif command == "left" then + local h = packet[2] -- already scaled + if h ~= 0 then + if factor ~= 0 then + h = h + h * factor / refactored -- expansion + end + pos_h = pos_h - h * sx end - pos_h = pos_h - h * sx - end - elseif command == "down" then - local v = packet[2] -- already scaled - if v and v ~= 0 then - pos_v = pos_v - v * sy - end - elseif command == "up" then - local v = packet[2] -- already scaled - if v and v ~= 0 then - pos_v = pos_v + v * sy - end - elseif command == "offset" then - local c = packet[4] - if c then - local ph = pos_h - local pv = pos_v - local csx = packet[5] - local csy = packet[6] or csx - local h = packet[2] - local v = packet[3] - if h and h ~= 0 then + elseif command == "down" then + local v = packet[2] -- already scaled + if v and v ~= 0 then + pos_v = pos_v - v * sy + end + elseif command == "up" then + local v = packet[2] -- already scaled + if v and v ~= 0 then + pos_v = pos_v + v * sy + end + elseif command == "offset" then + local c = packet[4] + if c then + local ph = pos_h + local pv = pos_v + local csx = packet[5] + local csy = packet[6] or csx + local h = packet[2] + local v = packet[3] + if h and h ~= 0 then + if factor ~= 0 then + h = h + h * factor / refactored -- expansion + end + pos_h = pos_h + h * sx + end + if v and v ~= 0 then + pos_v = pos_v + v * sy + end + flushchar(fnt,c,csx,csy) + pos_h = ph + pos_v = pv + end + elseif command == "compose" then -- for now idem + local ph = pos_h + local pv = pos_v + local h = packet[2] or 0 + local v = packet[3] or 0 + local c = packet[4] + if h ~= 0 then if factor ~= 0 then h = h + h * factor / refactored -- expansion end @@ -348,179 +409,165 @@ local flush_character do if v and v ~= 0 then pos_v = pos_v + v * sy end - flushchar(fnt,c,csx,csy) - pos_h = ph - pos_v = pv - end - elseif command == "compose" then -- for now idem - local ph = pos_h - local pv = pos_v - local h = packet[2] or 0 - local v = packet[3] or 0 - local c = packet[4] - if h ~= 0 then - if factor ~= 0 then - h = h + h * factor / refactored -- expansion + if c then + flushchar(fnt,c) + pos_h = ph + pos_v = pv end - pos_h = pos_h + h * sx - end - if v and v ~= 0 then - pos_v = pos_v + v * sy - end - if c then - flushchar(fnt,c) - pos_h = ph - pos_v = pv - end - elseif command == "push" then - level = level + 1 - local s = stack[level] - s[1] = pos_h - s[2] = pos_v - elseif command == "pop" then - if level > 0 then - local s = stack[level] - pos_h = s[1] - pos_v = s[2] - level = level - 1 - end - elseif command == "frame" then - -- d:width d:height d:depth d:rulethickness b:outline b:advance b:baseline s:color - local width = packet[2] - local height = packet[3] - local depth = packet[4] - local wd, ht, dp - if width == true or height == true or depth == true then - wd, ht, dp = getwhd(current,true) - end - if width == true then - width = wd - elseif not width then - width = 0 - end - if height == true then - height = ht - elseif not height then - height = 0 - end - if depth == true then - depth = dp - elseif not depth then - depth = 0 - end - local total = height + depth - if width > 0 and total > 0 then - if factor ~= 0 then - width = width + width * factor / refactored + elseif command == "push" then + push() + elseif command == "pop" then + pop() + elseif command == "frame" then + -- d:width d:height d:depth d:rulethickness b:outline b:advance b:baseline s:color + local width = packet[2] + local height = packet[3] + local depth = packet[4] + local wd, ht, dp + if width == true or height == true or depth == true then + wd, ht, dp = getwhd(current,true) end - if width > 0 then - local line = packet[5] or default - local outline = packet[6] - local advance = packet[7] - if outline == nil then - outline = true + if width == true then + width = wd + elseif not width then + width = 0 + end + if height == true then + height = ht + elseif not height then + height = 0 + end + if depth == true then + depth = dp + elseif not depth then + depth = 0 + end + local total = height + depth + if width > 0 and total > 0 then + if factor ~= 0 then + width = width + width * factor / refactored end - if advance == nil then - advance = true + if width > 0 then + local line = packet[5] or default + local outline = packet[6] + local advance = packet[7] + if outline == nil then + outline = true + end + if advance == nil then + advance = true + end + local baseline = outline and packet[8] + local color = packet[9] -- no longer needed probably + if color then + vfinjectors.startcolor(pos_h,pos_v,color) -- takes packet or string + end + width = width * sx + height = height * sy + depth = depth * sy + flushspecialrule(pos_h,pos_v,pos_r,width,height,depth,line,outline,baseline) + if color then + vfinjectors.stopcolor() + end + if advance then + pos_h = pos_h + width + end + end + end + elseif command == "rule" then + local size_v = packet[2] + local size_h = packet[3] + if size_h > 0 and size_v > 0 then + if factor ~= 0 then + size_h = size_h + size_h * factor / refactored end - local baseline = outline and packet[8] - local color = packet[9] -- no longer needed probably - if color then - vfinjectors.startcolor(pos_h,pos_v,color) -- takes packet or string + if size_h > 0 then + size_h = size_h * sx + size_v = size_v * sy + flushsimplerule(pos_h,pos_v,pos_r,size_h,size_v) + pos_h = pos_h + size_h end - width = width * sx - height = height * sy - depth = depth * sy - flushspecialrule(pos_h,pos_v,pos_r,width,height,depth,line,outline,baseline) - if color then - vfinjectors.stopcolor() + end + elseif command == "line" then + local wd = packet[2] or 0 + local ht = packet[3] or 0 + local dp = packet[4] or 0 + if wd > 0 and ht ~= 0 and dp ~= 0 then + if factor ~= 0 then + wd = wd + wd * factor / refactored end - if advance then - pos_h = pos_h + width + if wd > 0 then + wd = wd * sx + ht = ht * sy + dp = dp * sy + local color = packet[5] -- no longer needed probably + if color then + vfinjectors.startcolor(pos_h,pos_v,color) -- takes packet or string + end + flushsimplerule(pos_h,pos_v-dp,pos_r,wd,ht+dp) + if color then + vfinjectors.stopcolor() + end + pos_h = pos_h + wd end end - end - elseif command == "rule" then - local size_v = packet[2] - local size_h = packet[3] - if size_h > 0 and size_v > 0 then - if factor ~= 0 then - size_h = size_h + size_h * factor / refactored + elseif command == "font" then + local index = packet[2] + local okay = fonts and fonts[index] + if okay then + fnt = okay.id or fnt -- or maybe just return end - if size_h > 0 then - size_h = size_h * sx - size_v = size_v * sy - flushsimplerule(pos_h,pos_v,pos_r,size_h,size_v) - pos_h = pos_h + size_h + elseif command == "lua" then + local code = packet[2] + local kind = type(code) + if kind ~= "function" then + code = loadstring(code) + kind = type(code) end - end - elseif command == "line" then - local wd = packet[2] or 0 - local ht = packet[3] or 0 - local dp = packet[4] or 0 - if wd > 0 and ht ~= 0 and dp ~= 0 then - if factor ~= 0 then - wd = wd + wd * factor / refactored + if kind == "function" then + code(font,char,pos_h,pos_v,sx,sy) -- maybe also packet end - if wd > 0 then - wd = wd * sx - ht = ht * sy - dp = dp * sy - local color = packet[5] -- no longer needed probably - if color then - vfinjectors.startcolor(pos_h,pos_v,color) -- takes packet or string - end - flushsimplerule(pos_h,pos_v-dp,pos_r,wd,ht+dp) - if color then - vfinjectors.stopcolor() - end - pos_h = pos_h + wd + elseif command == "node" then + local h = packet[2] + hlist_out(h,getlist(h)) + -- elseif command == "pdf" then + -- unsupported + -- elseif command == "pdfmode" then + -- unsupported + -- elseif command == "special" then + -- unsupported + -- elseif command == "nop" then + -- just ignored + -- elseif command == "image" then + -- unsupported, use "node" + elseif command == "inspect" then + inspect(vfcommands) + elseif command == "trace" then + report("virtual state: h=%p v=%p d=%i",pos_h,pos_v,pos_r) + else + local injector = vfinjectors[command] + if injector then + injector(pos_h,pos_v,packet) -- maybe also sx, sy but then we need to check usage end end - elseif command == "font" then - local index = packet[2] - local okay = fonts and fonts[index] - if okay then - fnt = okay.id or fnt -- or maybe just return - end - elseif command == "lua" then - local code = packet[2] - local kind = type(code) - if kind ~= "function" then - code = loadstring(code) - kind = type(code) - end - if kind == "function" then - code(font,char,pos_h,pos_v,sx,sy) -- maybe also packet - end - elseif command == "node" then - local h = packet[2] - hlist_out(h,getlist(h)) - -- elseif command == "pdf" then - -- unsupported - -- elseif command == "pdfmode" then - -- unsupported - -- elseif command == "special" then - -- unsupported - -- elseif command == "nop" then - -- just ignored - -- elseif command == "image" then - -- unsupported, use "node" - else - local injector = vfinjectors[command] - if injector then - injector(pos_h,pos_v,packet) -- maybe also sx, sy but then we need to check usage - end end end - -- hm, never seen outside here + -- pop() -- or: pos_h = saved_h pos_v = saved_v pos_r = saved_r + if savedlevel ~= level then + report("") + report("virtual state: stack is corrupt") + report("") + end + level = savedlevel + nesting = nesting - 1 + end local onetimemessage -- could be defined later (todo: make plug for this) |