summaryrefslogtreecommitdiff
path: root/tex/context/base/mkxl/driv-shp.lmt
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkxl/driv-shp.lmt')
-rw-r--r--tex/context/base/mkxl/driv-shp.lmt172
1 files changed, 116 insertions, 56 deletions
diff --git a/tex/context/base/mkxl/driv-shp.lmt b/tex/context/base/mkxl/driv-shp.lmt
index cd117f326..2be1fd105 100644
--- a/tex/context/base/mkxl/driv-shp.lmt
+++ b/tex/context/base/mkxl/driv-shp.lmt
@@ -164,10 +164,22 @@ local flush_character do
-- todo: cache streams
- local default = 16384 * number.dimenfactors.bp -- 65536 // 4
+ local default = 16384 -- * number.dimenfactors.bp -- 65536 // 4
local vfinjectors = fonts.helpers.vfinjectors
+ local function flushchar(current,font,char,fnt,chr,f,e)
+ if fnt then
+ local nest = char ~= chr or font ~= fnt
+ if fnt == 0 then
+ fnt = main
+ end
+ return flush_character(current,fnt,chr,factor,nest,pos_h,pos_v,pos_r,f,e)
+ else
+ return 0
+ end
+ end
+
local function flush_vf_packet(current,pos_h,pos_v,pos_r,font,char,data,factor,vfcommands,sx,sy)
if nesting > 100 then
@@ -188,23 +200,20 @@ local flush_character do
local fonts = data.fonts
local siz = (data.parameters.factor or 1)/65536
- local function flushchar(font,char,fnt,chr,f,e)
- if fnt then
- local nest = char ~= chr or font ~= fnt
- if fnt == 0 then
- fnt = main
- end
- return flush_character(current,fnt,chr,factor,nest,pos_h,pos_v,pos_r,f,e)
- else
- return 0
- end
- end
+ -- An alternative where we (here) locally define handlers like this:
+ --
+ -- if not vfinjectors then
+ -- function vfinjectors.char(hpos,vpos,packet)
+ -- -- .... access: font, char, factor, sx, xy
+ -- end
+ -- end
+ --
+ -- doesn't work because accessing the parameters passed to the outer function doesn't
+ -- work as expected (so we end up in a nesting loop). I remember hitting this somewhat
+ -- unexpected feature before.
-- we assume resolved fonts: id mandate but maybe also size
- -- we could map left, right, up, down -> offset
- -- we could map char, font, slot to -> slot
-
for i=1,#vfcommands do
local packet = vfcommands[i]
local command = packet[1]
@@ -212,24 +221,24 @@ local flush_character do
local chr = packet[2]
local f = packet[3]
local e = packet[4]
- pos_h = pos_h + flushchar(font,char,fnt,chr,f,e)
+ pos_h = pos_h + flushchar(current,font,char,fnt,chr,f,e)
elseif command == "slot" then
local index = packet[2]
local chr = packet[3]
local f = packet[4]
local e = packet[5]
if index == 0 then
- pos_h = pos_h + flushchar(font,char,font,chr,f,e)
+ pos_h = pos_h + flushchar(current,font,char,font,chr,f,e)
else
local okay = fonts and fonts[index]
if okay then
local fnt = okay.id
if fnt then
- pos_h = pos_h + flushchar(font,char,fnt,chr,f,e)
+ pos_h = pos_h + flushchar(current,font,char,fnt,chr,f,e)
end
else
-- safeguard, we assume the font itself (often index 1)
- pos_h = pos_h + flushchar(font,char,font,chr,f,e)
+ pos_h = pos_h + flushchar(current,font,char,font,chr,f,e)
end
end
elseif command == "use" then
@@ -300,7 +309,7 @@ local flush_character do
pos_v = pos_v + v * sy
end
if c then
- flushchar(font,char,fnt,c)
+ flushchar(current,font,char,fnt,c)
pos_h = ph
pos_v = pv
end
@@ -320,7 +329,7 @@ local flush_character do
pos_v = pos_v + v * sy
end
if c then
- flushchar(font,char,fnt,c)
+ flushchar(current,font,char,fnt,c)
pos_h = ph
pos_v = pv
end
@@ -336,6 +345,62 @@ local flush_character do
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 / 1000
+ 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
+ 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]
@@ -350,37 +415,27 @@ local flush_character do
pos_h = pos_h + size_h
end
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]
- if width > 0 then
- local height = packet[3] or 0
- local depth = packet[4] or 0
- local total = height + depth
- if total > 0 then
- if factor ~= 0 then
- width = width + width * factor / 1000
+ 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 / 1000
+ 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
- if width > 0 then
- local line = packet[5] or default
- local outline = not packet[6]
- local advance = not packet[7]
- 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
+ flushsimplerule(pos_h,pos_v-dp,pos_r,wd,ht+dp)
+ if color then
+ vfinjectors.stopcolor()
end
+ pos_h = pos_h + wd
end
end
elseif command == "font" then
@@ -399,20 +454,25 @@ local flush_character do
if kind == "function" then
code(font,char,pos_h,pos_v,sx,sy)
end
- elseif command == "node" then -- obsolete
+ 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)
end
end
- -- image : not needed, maybe some day
- -- pdfmode : not used
- -- special : makes no sense
- -- nop : the official ignore
- -- scale : not supported
end
pos_h = saved_h