summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2017-03-01 13:51:17 +0100
committerContext Git Mirror Bot <phg42.2a@gmail.com>2017-03-01 13:51:17 +0100
commit0da55392b876cef55845157c4bfb8244d84c6450 (patch)
treea050eef10e2790e286b94dcfeae1aacc657b025b /tex
parenta616b343d8dfe81008c9e8aee253cf31f088f35b (diff)
downloadcontext-0da55392b876cef55845157c4bfb8244d84c6450.tar.gz
2017-03-01 13:47:00
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/font-cff.lua370
-rw-r--r--tex/context/base/mkiv/font-dsp.lua110
-rw-r--r--tex/context/base/mkiv/font-ext.lua66
-rw-r--r--tex/context/base/mkiv/font-onr.lua4
-rw-r--r--tex/context/base/mkiv/font-otr.lua71
-rw-r--r--tex/context/base/mkiv/font-ots.lua14
-rw-r--r--tex/context/base/mkiv/l-io.lua264
-rw-r--r--tex/context/base/mkiv/l-os.lua6
-rw-r--r--tex/context/base/mkiv/lxml-lpt.lua6
-rw-r--r--tex/context/base/mkiv/lxml-tab.lua8
-rw-r--r--tex/context/base/mkiv/node-fnt.lua10
-rw-r--r--tex/context/base/mkiv/page-ins.mkiv1
-rw-r--r--tex/context/base/mkiv/page-one.mkiv5
-rw-r--r--tex/context/base/mkiv/spac-ver.lua2
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin25630 -> 25656 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin419694 -> 420944 bytes
-rw-r--r--tex/context/base/mkiv/strc-not.mkvi20
-rw-r--r--tex/context/base/mkiv/trac-deb.lua32
-rw-r--r--tex/context/base/mkiv/trac-vis.lua4
-rw-r--r--tex/context/base/mkiv/typo-sus.lua1
-rw-r--r--tex/context/base/mkiv/util-deb.lua145
-rw-r--r--tex/context/base/mkiv/util-fil.lua76
-rw-r--r--tex/context/base/mkiv/util-lib.lua22
-rw-r--r--tex/context/base/mkiv/util-sac.lua19
-rw-r--r--tex/context/fonts/mkiv/xits-math.lfg5
-rw-r--r--tex/context/interface/mkiv/i-context.pdfbin804624 -> 804051 bytes
-rw-r--r--tex/context/interface/mkiv/i-readme.pdfbin60772 -> 60771 bytes
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua715
32 files changed, 1209 insertions, 775 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index ed4567e86..ffee0b4d9 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2017.02.25 16:24}
+\newcontextversion{2017.03.01 13:40}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index bc277e721..55f420e79 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2017.02.25 16:24}
+\edef\contextversion{2017.03.01 13:40}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index d931309da..8578cd188 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2017.02.25 16:24}
+\newcontextversion{2017.03.01 13:40}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 5b3bba8da..bd4fbb462 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -39,7 +39,7 @@
%D up and the dependencies are more consistent.
\edef\contextformat {\jobname}
-\edef\contextversion{2017.02.25 16:24}
+\edef\contextversion{2017.03.01 13:40}
\edef\contextkind {beta}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/font-cff.lua b/tex/context/base/mkiv/font-cff.lua
index 1c6bd56fd..e6f47e40b 100644
--- a/tex/context/base/mkiv/font-cff.lua
+++ b/tex/context/base/mkiv/font-cff.lua
@@ -23,7 +23,7 @@ if not modules then modules = { } end modules ['font-cff'] = {
local next, type, tonumber = next, type, tonumber
local byte = string.byte
local concat, remove = table.concat, table.remove
-local floor, abs, round, ceil = math.floor, math.abs, math.round, math.ceil
+local floor, abs, round, ceil, min, max = math.floor, math.abs, math.round, math.ceil, math.min, math.max
local P, C, R, S, C, Cs, Ct = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Ct
local lpegmatch = lpeg.match
local formatters = string.formatters
@@ -31,14 +31,14 @@ local formatters = string.formatters
local readers = fonts.handlers.otf.readers
local streamreader = readers.streamreader
-local readbytes = streamreader.readbytes
local readstring = streamreader.readstring
local readbyte = streamreader.readcardinal1 -- 8-bit unsigned integer
local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer
local readuint = streamreader.readcardinal3 -- 24-bit unsigned integer
-local readulong = streamreader.readcardinal4 -- 24-bit unsigned integer
+local readulong = streamreader.readcardinal4 -- 32-bit unsigned integer
local setposition = streamreader.setposition
local getposition = streamreader.getposition
+local readbytetable = streamreader.readbytetable
local setmetatableindex = table.setmetatableindex
@@ -611,16 +611,17 @@ do
-- All these indirect calls make this run slower but it's cleaner this way
-- and we cache the result. As we moved the boundingbox code inline we gain
- -- some back.
+ -- some back. I inlined some of then and a bit speed can be gained by more
+ -- inlining but not that much.
- local function moveto(x,y)
+ local function moveto()
if keepcurve then
r = r + 1
result[r] = { x, y, "m" }
end
if checked then
- if x < xmin then xmin = x elseif x > xmax then xmax = x end
- if y < ymin then ymin = y elseif y > ymax then ymax = y end
+ if x > xmax then xmax = x elseif x < xmin then xmin = x end
+ if y > ymax then ymax = y elseif y < ymin then ymin = y end
else
xmin = x
ymin = y
@@ -630,14 +631,50 @@ do
end
end
- local function lineto(x,y)
+ local function xmoveto() -- slight speedup
+ if keepcurve then
+ r = r + 1
+ result[r] = { x, y, "m" }
+ end
+ if not checked then
+ xmin = x
+ ymin = y
+ xmax = x
+ ymax = y
+ checked = true
+ elseif x > xmax then
+ xmax = x
+ elseif x < xmin then
+ xmin = x
+ end
+ end
+
+ local function ymoveto() -- slight speedup
+ if keepcurve then
+ r = r + 1
+ result[r] = { x, y, "m" }
+ end
+ if not checked then
+ xmin = x
+ ymin = y
+ xmax = x
+ ymax = y
+ checked = true
+ elseif y > ymax then
+ ymax = y
+ elseif y < ymin then
+ ymin = y
+ end
+ end
+
+ local function lineto() -- we could inline
if keepcurve then
r = r + 1
result[r] = { x, y, "l" }
end
if checked then
- if x < xmin then xmin = x elseif x > xmax then xmax = x end
- if y < ymin then ymin = y elseif y > ymax then ymax = y end
+ if x > xmax then xmax = x elseif x < xmin then xmin = x end
+ if y > ymax then ymax = y elseif y < ymin then ymin = y end
else
xmin = x
ymin = y
@@ -647,14 +684,50 @@ do
end
end
+ local function xlineto() -- slight speedup
+ if keepcurve then
+ r = r + 1
+ result[r] = { x, y, "l" }
+ end
+ if not checked then
+ xmin = x
+ ymin = y
+ xmax = x
+ ymax = y
+ checked = true
+ elseif x > xmax then
+ xmax = x
+ elseif x < xmin then
+ xmin = x
+ end
+ end
+
+ local function ylineto() -- slight speedup
+ if keepcurve then
+ r = r + 1
+ result[r] = { x, y, "l" }
+ end
+ if not checked then
+ xmin = x
+ ymin = y
+ xmax = x
+ ymax = y
+ checked = true
+ elseif y > ymax then
+ ymax = y
+ elseif y < ymin then
+ ymin = y
+ end
+ end
+
local function curveto(x1,y1,x2,y2,x3,y3)
if keepcurve then
r = r + 1
result[r] = { x1, y1, x2, y2, x3, y3, "c" }
end
if checked then
- if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end
- if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end
+ if x1 > xmax then xmax = x1 elseif x1 < xmin then xmin = x1 end
+ if y1 > ymax then ymax = y1 elseif y1 < ymin then ymin = y1 end
else
xmin = x1
ymin = y1
@@ -662,22 +735,22 @@ do
ymax = y1
checked = true
end
- if x2 < xmin then xmin = x2 elseif x2 > xmax then xmax = x2 end
- if y2 < ymin then ymin = y2 elseif y2 > ymax then ymax = y2 end
- if x3 < xmin then xmin = x3 elseif x3 > xmax then xmax = x3 end
- if y3 < ymin then ymin = y3 elseif y3 > ymax then ymax = y3 end
+ if x2 > xmax then xmax = x2 elseif x2 < xmin then xmin = x2 end
+ if y2 > ymax then ymax = y2 elseif y2 < ymin then ymin = y2 end
+ if x3 > xmax then xmax = x3 elseif x3 < xmin then xmin = x3 end
+ if y3 > ymax then ymax = y3 elseif y3 < ymin then ymin = y3 end
end
local function rmoveto()
- if top > 2 then
- if not width then
+ if not width then
+ if top > 2 then
width = stack[1]
if trace_charstrings then
showvalue("width",width)
end
+ else
+ width = true
end
- elseif not width then
- width = true
end
if trace_charstrings then
showstate("rmoveto")
@@ -685,45 +758,45 @@ do
x = x + stack[top-1] -- dx1
y = y + stack[top] -- dy1
top = 0
- moveto(x,y)
+ moveto()
end
local function hmoveto()
- if top > 1 then
- if not width then
+ if not width then
+ if top > 1 then
width = stack[1]
if trace_charstrings then
showvalue("width",width)
end
+ else
+ width = true
end
- elseif not width then
- width = true
end
if trace_charstrings then
showstate("hmoveto")
end
x = x + stack[top] -- dx1
top = 0
- moveto(x,y)
+ xmoveto()
end
local function vmoveto()
- if top > 1 then
- if not width then
+ if not width then
+ if top > 1 then
width = stack[1]
if trace_charstrings then
showvalue("width",width)
end
+ else
+ width = true
end
- elseif not width then
- width = true
end
if trace_charstrings then
showstate("vmoveto")
end
y = y + stack[top] -- dy1
top = 0
- moveto(x,y)
+ ymoveto()
end
local function rlineto()
@@ -733,21 +806,7 @@ do
for i=1,top,2 do
x = x + stack[i] -- dxa
y = y + stack[i+1] -- dya
- lineto(x,y)
- end
- top = 0
- end
-
- local function xlineto(swap) -- x (y,x)+ | (x,y)+
- for i=1,top do
- if swap then
- x = x + stack[i]
- swap = false
- else
- y = y + stack[i]
- swap = true
- end
- lineto(x,y)
+ lineto()
end
top = 0
end
@@ -756,14 +815,48 @@ do
if trace_charstrings then
showstate("hlineto")
end
- xlineto(true)
+ if top == 1 then
+ x = x + stack[1]
+ xlineto()
+ else
+ local swap = true
+ for i=1,top do
+ if swap then
+ x = x + stack[i]
+ xlineto()
+ swap = false
+ else
+ y = y + stack[i]
+ ylineto()
+ swap = true
+ end
+ end
+ end
+ top = 0
end
local function vlineto() -- y (x,y)+ | (y,x)+
if trace_charstrings then
showstate("vlineto")
end
- xlineto(false)
+ if top == 1 then
+ y = y + stack[1]
+ ylineto()
+ else
+ local swap = false
+ for i=1,top do
+ if swap then
+ x = x + stack[i]
+ xlineto()
+ swap = false
+ else
+ y = y + stack[i]
+ ylineto()
+ swap = true
+ end
+ end
+ end
+ top = 0
end
local function rrcurveto()
@@ -775,8 +868,8 @@ do
local ay = y + stack[i+1] -- dya
local bx = ax + stack[i+2] -- dxb
local by = ay + stack[i+3] -- dyb
- x = bx + stack[i+4] -- dxc
- y = by + stack[i+5] -- dyc
+ x = bx + stack[i+4] -- dxc
+ y = by + stack[i+5] -- dyc
curveto(ax,ay,bx,by,x,y)
end
top = 0
@@ -788,15 +881,15 @@ do
end
local s = 1
if top % 2 ~= 0 then
- y = y + stack[1] -- dy1
+ y = y + stack[1] -- dy1
s = 2
end
for i=s,top,4 do
- local ax = x + stack[i] -- dxa
+ local ax = x + stack[i] -- dxa
local ay = y
local bx = ax + stack[i+1] -- dxb
local by = ay + stack[i+2] -- dyb
- x = bx + stack[i+3] -- dxc
+ x = bx + stack[i+3] -- dxc
y = by
curveto(ax,ay,bx,by,x,y)
end
@@ -810,16 +903,16 @@ do
local s = 1
local d = 0
if top % 2 ~= 0 then
- d = stack[1] -- dx1
+ d = stack[1] -- dx1
s = 2
end
for i=s,top,4 do
local ax = x + d
- local ay = y + stack[i] -- dya
+ local ay = y + stack[i] -- dya
local bx = ax + stack[i+1] -- dxb
local by = ay + stack[i+2] -- dyb
x = bx
- y = by + stack[i+3] -- dyc
+ y = by + stack[i+3] -- dyc
curveto(ax,ay,bx,by,x,y)
d = 0
end
@@ -831,7 +924,6 @@ do
if last then
top = top - 1
end
- local sw = swap
for i=1,top,4 do
local ax, ay, bx, by
if swap then
@@ -893,7 +985,7 @@ do
end
x = x + stack[top-1] -- dxc
y = y + stack[top] -- dyc
- lineto(x,y)
+ lineto()
top = 0
end
@@ -905,7 +997,7 @@ do
for i=1,top-6,2 do
x = x + stack[i]
y = y + stack[i+1]
- lineto(x,y)
+ lineto()
end
end
local ax = x + stack[top-5]
@@ -945,7 +1037,7 @@ do
if trace_charstrings then
showstate("hflex")
end
- local ax = x + stack[1] -- dx1
+ local ax = x + stack[1] -- dx1
local ay = y
local bx = ax + stack[2] -- dx2
local by = ay + stack[3] -- dy2
@@ -956,7 +1048,7 @@ do
local dy = by
local ex = dx + stack[6] -- dx5
local ey = y
- x = ex + stack[7] -- dx6
+ x = ex + stack[7] -- dx6
curveto(dx,dy,ex,ey,x,y)
top = 0
end
@@ -976,7 +1068,7 @@ do
local dy = by
local ex = dx + stack[7] -- dx5
local ey = dy + stack[8] -- dy5
- x = ex + stack[9] -- dx6
+ x = ex + stack[9] -- dx6
curveto(dx,dy,ex,ey,x,y)
top = 0
end
@@ -1218,9 +1310,9 @@ do
[037] = flex1,
}
- local p_bytes = Ct((P(1)/byte)^0)
+ local process
- local function call(scope,list,bias,process)
+ local function call(scope,list,bias) -- ,process)
depth = depth + 1
if top == 0 then
showstate(formatters["unknown %s call"](scope))
@@ -1233,10 +1325,10 @@ do
end
local tab = list[index]
if tab then
- if type(tab) == "string" then
- tab = lpegmatch(p_bytes,tab)
- list[index] = tab
- end
+-- if type(tab) == "string" then
+-- tab = { byte(tab,1,#tab) }
+-- list[index] = tab
+-- end
process(tab)
else
showstate(formatters["unknown %s call %i"](scope,index))
@@ -1246,54 +1338,64 @@ do
depth = depth - 1
end
- local function process(tab)
+ -- precompiling and reuse is much slower than redoing the calls
+
+ process = function(tab)
local i = 1
local n = #tab
while i <= n do
local t = tab[i]
- if t >= 32 and t <= 246 then
- -- -107 .. +107
- top = top + 1
- stack[top] = t - 139
- i = i + 1
- elseif t >= 247 and t <= 250 then
- -- +108 .. +1131
- top = top + 1
- stack[top] = (t-247)*256 + tab[i+1] + 108
- i = i + 2
- elseif t >= 251 and t <= 254 then
- -- -1131 .. -108
- top = top + 1
- stack[top] = -(t-251)*256 - tab[i+1] - 108
- i = i + 2
+ if t >= 32 then
+ if t <= 246 then
+ -- -107 .. +107
+ top = top + 1
+ stack[top] = t - 139
+ i = i + 1
+ elseif t <= 250 then
+ -- +108 .. +1131
+ top = top + 1
+ -- stack[top] = (t-247)*256 + tab[i+1] + 108
+ -- stack[top] = t*256 - 247*256 + tab[i+1] + 108
+ stack[top] = t*256 - 63124 + tab[i+1]
+ i = i + 2
+ elseif t <= 254 then
+ -- -1131 .. -108
+ top = top + 1
+ -- stack[top] = -(t-251)*256 - tab[i+1] - 108
+ -- stack[top] = -t*256 + 251*256 - tab[i+1] - 108
+ stack[top] = -t*256 + 64148 - tab[i+1]
+ i = i + 2
+ else
+ local n = 0x100 * tab[i+1] + tab[i+2]
+ top = top + 1
+ if n >= 0x8000 then
+ -- stack[top] = n - 0xFFFF - 1 + (0x100 * tab[i+3] + tab[i+4])/0xFFFF
+ stack[top] = n - 0x10000 + (0x100 * tab[i+3] + tab[i+4])/0xFFFF
+ else
+ stack[top] = n + (0x100 * tab[i+3] + tab[i+4])/0xFFFF
+ end
+ i = i + 5
+ end
elseif t == 28 then
-- -32768 .. +32767 : b1<<8 | b2
top = top + 1
local n = 0x100 * tab[i+1] + tab[i+2]
if n >= 0x8000 then
- stack[top] = n - 0xFFFF - 1
+ -- stack[top] = n - 0xFFFF - 1
+ stack[top] = n - 0x10000
else
stack[top] = n
end
i = i + 3
- elseif t == 255 then
- local n = 0x100 * tab[i+1] + tab[i+2]
- top = top + 1
- if n >= 0x8000 then
- stack[top] = n - 0xFFFF - 1 + (0x100 * tab[i+3] + tab[i+4])/0xFFFF
- else
- stack[top] = n + (0x100 * tab[i+3] + tab[i+4])/0xFFFF
- end
- i = i + 5
- elseif t == 11 then
+ elseif t == 11 then
if trace_charstrings then
showstate("return")
end
return
elseif t == 10 then
- call("local",locals,localbias,process)
+ call("local",locals,localbias) -- ,process)
i = i + 1
- elseif t == 14 then -- endchar
+ elseif t == 14 then -- endchar
if width then
-- okay
elseif top > 0 then
@@ -1309,7 +1411,7 @@ do
end
return
elseif t == 29 then
- call("global",globals,globalbias,process)
+ call("global",globals,globalbias) -- ,process)
i = i + 1
elseif t == 12 then
i = i + 1
@@ -1356,7 +1458,7 @@ do
-- if y < ymin then ymin = y end
-- if y > ymax then ymax = y end
-- -- we now have a reasonable start so we could
- -- -- simplyfy the next checks
+ -- -- simplify the next checks
-- for i=1,nofsegments do
-- local s = segments[i]
-- local x = s[1]
@@ -1415,9 +1517,9 @@ do
for i=1,#charstrings do
local tab = charstrings[i]
- if type(tab) == "string" then
- tab = lpegmatch(p_bytes,tab)
- end
+-- if type(tab) == "string" then -- no real need as wel nil charstrings[i] at the end
+ tab = { byte(tab,1,#tab) }
+-- end
local index = i - 1
x = 0
y = 0
@@ -1425,7 +1527,7 @@ do
r = 0
top = 0
stems = 0
- result = { }
+ result = { } -- we could reuse it when only boundingbox calculations are needed
--
xmin = 0
xmax = 0
@@ -1450,15 +1552,7 @@ do
--
-- trace_charstrings = index == 3078 -- todo: make tracker
local glyph = glyphs[index] -- can be autodefined in otr
- if not glyph then
- glyphs[index] = {
- segments = doshapes ~= false and result or nil, -- optional
- boundingbox = boundingbox,
- width = width,
- name = charset[index],
- -- sidebearing = 0,
- }
- else
+ if glyph then
glyph.segments = doshapes ~= false and result or nil
glyph.boundingbox = boundingbox
if not glyph.width then
@@ -1468,12 +1562,26 @@ do
glyph.name = charset[index]
end
-- glyph.sidebearing = 0 -- todo
+ elseif doshapes then
+ glyphs[index] = {
+ segments = result,
+ boundingbox = boundingbox,
+ width = width,
+ name = charset[index],
+ -- sidebearing = 0,
+ }
+ else
+ glyphs[index] = {
+ boundingbox = boundingbox,
+ width = width,
+ name = charset[index],
+ }
end
if trace_charstrings then
report("width: %s",tostring(width))
report("boundingbox: % t",boundingbox)
end
- charstrings[i] = nil -- free memory
+ charstrings[i] = nil -- free memory (what if used more often?)
end
return glyphs
end
@@ -1491,9 +1599,10 @@ do
local nominalwidth = private and private.data.nominalwidthx or 0
local defaultwidth = private and private.data.defaultwidthx or 0
--
- if type(tab) == "string" then
- tab = lpegmatch(p_bytes,tab)
- end
+-- if type(tab) == "string" then
+ -- a helper is not much faster but might be nicer for the stack
+ tab = { byte(tab,1,#tab) }
+-- end
--
x = 0
y = 0
@@ -1527,15 +1636,7 @@ do
index = index - 1
--
local glyph = glyphs[index] -- can be autodefined in otr
- if not glyph then
- glyphs[index] = {
- segments = doshapes ~= false and result or nil, -- optional
- boundingbox = boundingbox,
- width = width,
- name = charset[index],
- -- sidebearing = 0,
- }
- else
+ if glyph then
glyph.segments = doshapes ~= false and result or nil
glyph.boundingbox = boundingbox
if not glyph.width then
@@ -1545,6 +1646,20 @@ do
glyph.name = charset[index]
end
-- glyph.sidebearing = 0 -- todo
+ elseif doshapes then
+ glyphs[index] = {
+ segments = result,
+ boundingbox = boundingbox,
+ width = width,
+ name = charset[index],
+ -- sidebearing = 0,
+ }
+ else
+ glyphs[index] = {
+ boundingbox = boundingbox,
+ width = width,
+ name = charset[index],
+ }
end
--
if trace_charstrings then
@@ -1564,7 +1679,7 @@ end
local function readglobals(f,data)
local routines = readlengths(f)
for i=1,#routines do
- routines[i] = readstring(f,routines[i])
+ routines[i] = readbytetable(f,routines[i])
end
data.routines = routines
end
@@ -1627,7 +1742,7 @@ local function readlocals(f,data,dictionary)
setposition(f,header.offset+private.offset+subroutineoffset)
local subroutines = readlengths(f)
for i=1,#subroutines do
- subroutines[i] = readstring(f,subroutines[i])
+ subroutines[i] = readbytetable(f,subroutines[i])
end
dictionary.subroutines = subroutines
private.data.subroutines = nil
@@ -1757,6 +1872,7 @@ local function readfdselect(f,data,glyphs,doshapes,version)
end
for i=1,#charstrings do
parsecharstring(data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version)
+charstrings[i] = nil
end
resetcharstrings()
end
diff --git a/tex/context/base/mkiv/font-dsp.lua b/tex/context/base/mkiv/font-dsp.lua
index a5a1ae7c0..c336441e3 100644
--- a/tex/context/base/mkiv/font-dsp.lua
+++ b/tex/context/base/mkiv/font-dsp.lua
@@ -71,18 +71,18 @@ local streamreader = readers.streamreader
local setposition = streamreader.setposition
local getposition = streamreader.getposition
-local skipshort = streamreader.skipshort
-local skipbytes = streamreader.skip
local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer
local readulong = streamreader.readcardinal4 -- 24-bit unsigned integer
+local readinteger = streamreader.readinteger1
local readshort = streamreader.readinteger2 -- 16-bit signed integer
-local readfword = readshort
local readstring = streamreader.readstring
local readtag = streamreader.readtag
local readbytes = streamreader.readbytes
local readfixed = streamreader.readfixed4
local read2dot14 = streamreader.read2dot14
-local readinteger = streamreader.readinteger1
+local skipshort = streamreader.skipshort
+local skipbytes = streamreader.skip
+local readfword = readshort
local gsubhandlers = { }
local gposhandlers = { }
@@ -1820,61 +1820,65 @@ do
report("ignoring global kern table using gpos kern feature")
return
end
- report("adding global kern table as gpos feature %a",name)
setposition(f,datatable.offset)
local version = readushort(f)
local noftables = readushort(f)
- local kerns = setmetatableindex("table")
- for i=1,noftables do
- local version = readushort(f)
- local length = readushort(f)
- local coverage = readushort(f)
- -- bit 8-15 of coverage: format 0 or 2
- local format = bit32.rshift(coverage,8) -- is this ok?
- if format == 0 then
- local nofpairs = readushort(f)
- local searchrange = readushort(f)
- local entryselector = readushort(f)
- local rangeshift = readushort(f)
- for i=1,nofpairs do
- kerns[readushort(f)][readushort(f)] = readfword(f)
+ if noftables > 1 then
+ report("adding global kern table as gpos feature %a",name)
+ local kerns = setmetatableindex("table")
+ for i=1,noftables do
+ local version = readushort(f)
+ local length = readushort(f)
+ local coverage = readushort(f)
+ -- bit 8-15 of coverage: format 0 or 2
+ local format = bit32.rshift(coverage,8) -- is this ok?
+ if format == 0 then
+ local nofpairs = readushort(f)
+ local searchrange = readushort(f)
+ local entryselector = readushort(f)
+ local rangeshift = readushort(f)
+ for i=1,nofpairs do
+ kerns[readushort(f)][readushort(f)] = readfword(f)
+ end
+ elseif format == 2 then
+ -- apple specific so let's ignore it
+ else
+ -- not supported by ms
end
- elseif format == 2 then
- -- apple specific so let's ignore it
- else
- -- not supported by ms
end
- end
- local feature = { dflt = { dflt = true } }
- if not features then
- fontdata.features = { gpos = { [name] = feature } }
- elseif not gposfeatures then
- fontdata.features.gpos = { [name] = feature }
- else
- gposfeatures[name] = feature
- end
- local sequences = fontdata.sequences
- if not sequences then
- sequences = { }
- fontdata.sequences = sequences
- end
- local nofsequences = #sequences + 1
- sequences[nofsequences] = {
- index = nofsequences,
- name = name,
- steps = {
- {
- coverage = kerns,
- format = "kern",
+ local feature = { dflt = { dflt = true } }
+ if not features then
+ fontdata.features = { gpos = { [name] = feature } }
+ elseif not gposfeatures then
+ fontdata.features.gpos = { [name] = feature }
+ else
+ gposfeatures[name] = feature
+ end
+ local sequences = fontdata.sequences
+ if not sequences then
+ sequences = { }
+ fontdata.sequences = sequences
+ end
+ local nofsequences = #sequences + 1
+ sequences[nofsequences] = {
+ index = nofsequences,
+ name = name,
+ steps = {
+ {
+ coverage = kerns,
+ format = "kern",
+ },
},
- },
- nofsteps = 1,
- type = "gpos_pair",
- -- type = "gpos_single", -- maybe better
- flags = { false, false, false, false },
- order = { name },
- features = { [name] = feature },
- }
+ nofsteps = 1,
+ type = "gpos_pair",
+ -- type = "gpos_single", -- maybe better
+ flags = { false, false, false, false },
+ order = { name },
+ features = { [name] = feature },
+ }
+ else
+ report("ignoring empty kern table of feature %a",name)
+ end
end
function readers.gsub(f,fontdata,specification)
diff --git a/tex/context/base/mkiv/font-ext.lua b/tex/context/base/mkiv/font-ext.lua
index 0b2bfd44f..6edfe7025 100644
--- a/tex/context/base/mkiv/font-ext.lua
+++ b/tex/context/base/mkiv/font-ext.lua
@@ -292,12 +292,11 @@ vectors['quality'] = table.merged(
vectors['alpha']
)
--- As this is experimental code, users should not depend on it. The
--- implications are still discussed on the ConTeXt Dev List and we're
--- not sure yet what exactly the spec is (the next code is tested with
--- a gyre font patched by / fea file made by Khaled Hosny). The double
--- trick should not be needed it proper hanging punctuation is used in
--- which case values < 1 can be used.
+-- As this is experimental code, users should not depend on it. The implications are still
+-- discussed on the ConTeXt Dev List and we're not sure yet what exactly the spec is (the
+-- next code is tested with a gyre font patched by / fea file made by Khaled Hosny). The
+-- double trick should not be needed it proper hanging punctuation is used in which case
+-- values < 1 can be used.
--
-- preferred (in context, usine vectors):
--
@@ -345,17 +344,23 @@ local function map_opbd_onto_protrusion(tfmdata,value,opbd)
if validlookups then
for i=1,#lookuplist do
local lookup = lookuplist[i]
- local data = lookuphash[lookup]
- if data then
+ local steps = lookup.steps
+ if steps then
if trace_protrusion then
- report_protrusions("setting left using lfbd lookup %a",lookuptags[lookup])
+ report_protrusions("setting left using lfbd")
end
- for k, v in next, data do
- -- local p = - v[3] / descriptions[k].width-- or 1 ~= 0 too but the same
- local p = - (v[1] / 1000) * factor * left
- characters[k].left_protruding = p
- if trace_protrusion then
- report_protrusions("lfbd -> %s -> %C -> %0.03f (% t)",lookuptags[lookup],k,p,v)
+ for i=1,#steps do
+ local step = steps[i]
+ local coverage = step.coverage
+ if coverage then
+ for k, v in next, coverage do
+ -- local p = - v[3] / descriptions[k].width-- or 1 ~= 0 too but the same
+ local p = - (v[1] / 1000) * factor * left
+ characters[k].left_protruding = p
+ if trace_protrusion then
+ report_protrusions("lfbd -> %C -> %p",k,p)
+ end
+ end
end
end
done = true
@@ -368,17 +373,23 @@ local function map_opbd_onto_protrusion(tfmdata,value,opbd)
if validlookups then
for i=1,#lookuplist do
local lookup = lookuplist[i]
- local data = lookuphash[lookup]
- if data then
+ local steps = lookup.steps
+ if steps then
if trace_protrusion then
- report_protrusions("setting right using rtbd lookup %a",lookuptags[lookup])
+ report_protrusions("setting right using rtbd")
end
- for k, v in next, data do
- -- local p = v[3] / descriptions[k].width -- or 3
- local p = (v[1] / 1000) * factor * right
- characters[k].right_protruding = p
- if trace_protrusion then
- report_protrusions("rtbd -> %s -> %C -> %0.03f (% t)",lookuptags[lookup],k,p,v)
+ for i=1,#steps do
+ local step = steps[i]
+ local coverage = step.coverage
+ if coverage then
+ for k, v in next, coverage do
+ -- local p = v[3] / descriptions[k].width -- or 3
+ local p = (v[1] / 1000) * factor * right
+ characters[k].right_protruding = p
+ if trace_protrusion then
+ report_protrusions("rtbd -> %C -> %p",k,p)
+ end
+ end
end
end
end
@@ -397,10 +408,9 @@ local function map_opbd_onto_protrusion(tfmdata,value,opbd)
end
end
--- The opbd test is just there because it was discussed on the
--- context development list. However, the mentioned fxlbi.otf font
--- only has some kerns for digits. So, consider this feature not
--- supported till we have a proper test font.
+-- The opbd test is just there because it was discussed on the context development list. However,
+-- the mentioned fxlbi.otf font only has some kerns for digits. So, consider this feature not supported
+-- till we have a proper test font.
local function initializeprotrusion(tfmdata,value)
if value then
diff --git a/tex/context/base/mkiv/font-onr.lua b/tex/context/base/mkiv/font-onr.lua
index 6c33b24c6..d986a0ddc 100644
--- a/tex/context/base/mkiv/font-onr.lua
+++ b/tex/context/base/mkiv/font-onr.lua
@@ -105,8 +105,8 @@ do
local setroutine = function(str,position,index,size)
local forward = position + tonumber(size)
- local stream = sub(str,position+1,forward)
- routines[index] = decrypt(stream,4330,4)
+ local stream = decrypt(sub(str,position+1,forward),4330,4)
+ routines[index] = { byte(stream,1,#stream) }
return forward
end
diff --git a/tex/context/base/mkiv/font-otr.lua b/tex/context/base/mkiv/font-otr.lua
index c5c5d8f32..5d3609b35 100644
--- a/tex/context/base/mkiv/font-otr.lua
+++ b/tex/context/base/mkiv/font-otr.lua
@@ -107,15 +107,15 @@ local readstring = streamreader.readstring
local readbyte = streamreader.readcardinal1 -- 8-bit unsigned integer
local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer
local readuint = streamreader.readcardinal3 -- 24-bit unsigned integer
-local readulong = streamreader.readcardinal4 -- 24-bit unsigned integer
+local readulong = streamreader.readcardinal4 -- 32-bit unsigned integer
----- readchar = streamreader.readinteger1 -- 8-bit signed integer
local readshort = streamreader.readinteger2 -- 16-bit signed integer
-local readlong = streamreader.readinteger4 -- 24-bit unsigned integer
+local readlong = streamreader.readinteger4 -- 32-bit unsigned integer
local readfixed = streamreader.readfixed4
+local read2dot14 = streamreader.read2dot14 -- 16-bit signed fixed number with the low 14 bits of fraction (2.14) (F2DOT14)
local readfword = readshort -- 16-bit signed integer that describes a quantity in FUnits
local readufword = readushort -- 16-bit unsigned integer that describes a quantity in FUnits
local readoffset = readushort
-local read2dot14 = streamreader.read2dot14 -- 16-bit signed fixed number with the low 14 bits of fraction (2.14) (F2DOT14)
function streamreader.readtag(f)
return lower(stripstring(readstring(f,4)))
@@ -1996,13 +1996,22 @@ local function prepareglyps(fontdata)
fontdata.mapping = { }
end
+local function readtable(tag,f,fontdata,specification)
+ local reader = readers[tag]
+ if reader then
+ -- local t = os.clock()
+ reader(f,fontdata,specification)
+ -- report("reading table %a took %0.4f seconds",tag,os.clock()-t)
+ end
+end
+
local function readdata(f,offset,specification)
local fontdata = loadtables(f,specification,offset)
if specification.glyphs then
prepareglyps(fontdata)
end
--
- readers["name"](f,fontdata,specification)
+ readtable("name",f,fontdata,specification)
--
local askedname = specification.askedname
if askedname then
@@ -2014,33 +2023,35 @@ local function readdata(f,offset,specification)
end
end
--
- readers["os/2"](f,fontdata,specification)
- readers["head"](f,fontdata,specification)
- readers["maxp"](f,fontdata,specification)
- readers["hhea"](f,fontdata,specification)
- readers["vhea"](f,fontdata,specification)
- readers["hmtx"](f,fontdata,specification)
- readers["vmtx"](f,fontdata,specification)
- readers["vorg"](f,fontdata,specification)
- readers["post"](f,fontdata,specification)
- readers["cff" ](f,fontdata,specification)
- readers["cmap"](f,fontdata,specification)
- readers["loca"](f,fontdata,specification)
- readers["glyf"](f,fontdata,specification)
- readers["colr"](f,fontdata,specification)
- readers["cpal"](f,fontdata,specification)
- readers["svg" ](f,fontdata,specification)
- readers["kern"](f,fontdata,specification)
- readers["gdef"](f,fontdata,specification)
- readers["gsub"](f,fontdata,specification)
- readers["gpos"](f,fontdata,specification)
- readers["math"](f,fontdata,specification)
+ readtable("os/2",f,fontdata,specification)
+ readtable("head",f,fontdata,specification)
+ readtable("maxp",f,fontdata,specification)
+ readtable("hhea",f,fontdata,specification)
+ readtable("vhea",f,fontdata,specification)
+ readtable("hmtx",f,fontdata,specification)
+ readtable("vmtx",f,fontdata,specification)
+ readtable("vorg",f,fontdata,specification)
+ readtable("post",f,fontdata,specification)
+ readtable("cff" ,f,fontdata,specification)
+ readtable("cmap",f,fontdata,specification)
+ readtable("loca",f,fontdata,specification)
+ readtable("glyf",f,fontdata,specification)
+ readtable("colr",f,fontdata,specification)
+ readtable("cpal",f,fontdata,specification)
+ readtable("svg" ,f,fontdata,specification)
+ readtable("kern",f,fontdata,specification)
+ readtable("gdef",f,fontdata,specification)
+ readtable("gsub",f,fontdata,specification)
+ readtable("gpos",f,fontdata,specification)
+ readtable("math",f,fontdata,specification)
+ --
+ -- there are no proper fonts yet:
--
- -- readers["fvar"](f,fontdata,specification)
- -- readers["hvar"](f,fontdata,specification)
- -- readers["vvar"](f,fontdata,specification)
- -- readers["mvar"](f,fontdata,specification)
- -- readers["vorg"](f,fontdata,specification)
+ -- readtable("fvar",f,fontdata,specification) -- probably
+ -- readtable("hvar",f,fontdata,specification)
+ -- readtable("vvar",f,fontdata,specification)
+ -- readtable("mvar",f,fontdata,specification) -- probably
+ -- readtable("vorg",f,fontdata,specification)
--
fontdata.locations = nil
fontdata.tables = nil
diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua
index 742a0c561..7ef395330 100644
--- a/tex/context/base/mkiv/font-ots.lua
+++ b/tex/context/base/mkiv/font-ots.lua
@@ -3758,7 +3758,7 @@ otf.helpers.pardirstate = pardirstate
-- optimizations the principles of processing the features hasn't changed much since
-- the beginning.
-local function featuresprocessor(head,font,attr)
+local function featuresprocessor(head,font,attr,direction)
local sequences = sequencelists[font] -- temp hack
@@ -3802,7 +3802,8 @@ local function featuresprocessor(head,font,attr)
checkstep(head)
end
- local rlmode = 0
+ local initialrl = direction == "TRT" and -1 or 0
+
local done = false
local datasets = otf.dataset(tfmdata,font,attr)
local dirstack = { } -- could move outside function but we can have local runs
@@ -3819,7 +3820,7 @@ local function featuresprocessor(head,font,attr)
----- featurevalue = dataset[1] -- todo: pass to function instead of using a global
local attribute = dataset[2]
local sequence = dataset[3] -- sequences[s] -- also dataset[5]
- local rlparmode = 0
+ local rlparmode = initialrl
local topstack = 0
local typ = sequence.type
local gpossing = typ == "gpos_single" or typ == "gpos_pair" -- store in dataset
@@ -3837,7 +3838,8 @@ local function featuresprocessor(head,font,attr)
end
elseif typ == "gsub_reversecontextchain" then
-- this is a limited case, no special treatments like 'init' etc
- local start = find_node_tail(head)
+ local start = find_node_tail(head)
+ local rlmode = 0 -- how important is this .. do we need to check for dir?
while start do
local char = ischar(start,font)
if char then
@@ -3875,8 +3877,8 @@ local function featuresprocessor(head,font,attr)
end
end
else
- local start = head -- local ?
- rlmode = 0 -- to be checked ?
+ local start = head
+ local rlmode = initialrl
if nofsteps == 1 then -- happens often
local step = steps[1]
local lookupcache = step.coverage
diff --git a/tex/context/base/mkiv/l-io.lua b/tex/context/base/mkiv/l-io.lua
index 2039017b2..75976b858 100644
--- a/tex/context/base/mkiv/l-io.lua
+++ b/tex/context/base/mkiv/l-io.lua
@@ -19,38 +19,48 @@ else
io.fileseparator, io.pathseparator = "/" , ":"
end
-local function readall(f)
- return f:read("*all")
-end
+-- local function readall(f)
+-- return f:read("*all")
+-- end
-- The next one is upto 50% faster on large files and less memory consumption due
-- to less intermediate large allocations. This phenomena was discussed on the
-- luatex dev list.
+local large = 2^24 -- 16 MB
+local medium = large / 16 -- 1 MB
+local small = medium / 8
+
+-- local function readall(f)
+-- local size = f:seek("end")
+-- if size == 0 then
+-- return ""
+-- end
+-- f:seek("set",0)
+-- if size < medium then
+-- return f:read('*all')
+-- else
+-- local step = (size > large) and large or (floor(size/(medium)) * small)
+-- local data = { }
+-- while true do
+-- local r = f:read(step)
+-- if not r then
+-- return concat(data)
+-- else
+-- data[#data+1] = r
+-- end
+-- end
+-- end
+-- end
+
local function readall(f)
+-- return f:read("*all")
local size = f:seek("end")
- if size == 0 then
- return ""
- end
- f:seek("set",0)
- if size < 1024*1024 then
- return f:read('*all')
+ if size > 0 then
+ f:seek("set",0)
+ return f:read(size)
else
- local step
- if size > 16*1024*1024 then
- step = 16*1024*1024
- else
- step = floor(size/(1024*1024)) * 1024 * 1024 / 8
- end
- local data = { }
- while true do
- local r = f:read(step)
- if not r then
- return concat(data)
- else
- data[#data+1] = r
- end
- end
+ return ""
end
end
@@ -59,52 +69,75 @@ io.readall = readall
function io.loaddata(filename,textmode) -- return nil if empty
local f = open(filename,(textmode and 'r') or 'rb')
if f then
- local data = readall(f)
- f:close()
- if #data > 0 then
- return data
+ local size = f:seek("end")
+ local data = nil
+ if size > 0 then
+ -- data = f:read("*all")
+ f:seek("set",0)
+ data = f:read(size)
end
+ f:close()
+ return data
end
end
+-- function io.copydata(source,target,action)
+-- local f = open(source,"rb")
+-- if f then
+-- local g = open(target,"wb")
+-- if g then
+-- local size = f:seek("end")
+-- if size == 0 then
+-- -- empty
+-- else
+-- f:seek("set",0)
+-- if size < medium then
+-- local data = f:read('*all')
+-- if action then
+-- data = action(data)
+-- end
+-- if data then
+-- g:write(data)
+-- end
+-- else
+-- local step = (size > large) and large or (floor(size/(medium)) * small)
+-- while true do
+-- local data = f:read(step)
+-- if data then
+-- if action then
+-- data = action(data)
+-- end
+-- if data then
+-- g:write(data)
+-- end
+-- else
+-- break
+-- end
+-- end
+-- end
+-- end
+-- g:close()
+-- end
+-- f:close()
+-- flush()
+-- end
+-- end
+
function io.copydata(source,target,action)
local f = open(source,"rb")
if f then
local g = open(target,"wb")
if g then
local size = f:seek("end")
- if size == 0 then
- -- empty
- else
+ if size > 0 then
+ -- local data = f:read('*all')
f:seek("set",0)
- if size < 1024*1024 then
- local data = f:read('*all')
- if action then
- data = action(data)
- end
- if data then
- g:write(data)
- end
- else
- local step
- if size > 16*1024*1024 then
- step = 16*1024*1024
- else
- step = floor(size/(1024*1024)) * 1024 * 1024 / 8
- end
- while true do
- local data = f:read(step)
- if data then
- if action then
- data = action(data)
- end
- if data then
- g:write(data)
- end
- else
- break
- end
- end
+ local data = f:read(size)
+ if action then
+ data = action(data)
+ end
+ if data then
+ g:write(data)
end
end
g:close()
@@ -134,32 +167,70 @@ end
-- we can also chunk this one if needed: io.lines(filename,chunksize,"*l")
-function io.loadlines(filename,n) -- return nil if empty
- local f = open(filename,'r')
- if not f then
- -- no file
- elseif n then
- local lines = { }
- for i=1,n do
- local line = f:read("*lines")
- if line then
- lines[#lines+1] = line
- else
- break
+-- ffi.readline
+
+if fio.readline then
+
+ local readline = fio.readline
+
+ function io.loadlines(filename,n) -- return nil if empty
+ local f = open(filename,'r')
+ if not f then
+ -- no file
+ elseif n then
+ local lines = { }
+ for i=1,n do
+ local line = readline(f)
+ if line then
+ lines[i] = line
+ else
+ break
+ end
+ end
+ f:close()
+ lines = concat(lines,"\n")
+ if #lines > 0 then
+ return lines
+ end
+ else
+ local line = readline(f)
+ f:close()
+ if line and #line > 0 then
+ return line
end
end
- f:close()
- lines = concat(lines,"\n")
- if #lines > 0 then
- return lines
- end
- else
- local line = f:read("*line") or ""
- f:close()
- if #line > 0 then
- return line
+ end
+
+else
+
+ function io.loadlines(filename,n) -- return nil if empty
+ local f = open(filename,'r')
+ if not f then
+ -- no file
+ elseif n then
+ local lines = { }
+ for i=1,n do
+ local line = f:read("*lines")
+ if line then
+ lines[i] = line
+ else
+ break
+ end
+ end
+ f:close()
+ lines = concat(lines,"\n")
+ if #lines > 0 then
+ return lines
+ end
+ else
+ local line = f:read("*line") or ""
+ f:close()
+ if #line > 0 then
+ return line
+ end
end
end
+
end
function io.loadchunk(filename,n)
@@ -205,6 +276,7 @@ local function noflines(f)
return 0
end
else
+ -- todo: load and lpeg
local n = 0
for _ in f:lines() do
n = n + 1
@@ -216,7 +288,7 @@ end
io.noflines = noflines
--- inlined is faster
+-- inlined is faster ... beware, better use util-fil
local nextchar = {
[ 4] = function(f)
@@ -331,7 +403,7 @@ function io.ask(question,default,options)
end
end
-local function readnumber(f,n,m)
+local function readnumber(f,n,m) -- to be replaced
if m then
f:seek("set",n)
n = m
@@ -340,38 +412,32 @@ local function readnumber(f,n,m)
return byte(f:read(1))
elseif n == 2 then
local a, b = byte(f:read(2),1,2)
- return 256 * a + b
+ return 0x100 * a + b
elseif n == 3 then
local a, b, c = byte(f:read(3),1,3)
- return 256*256 * a + 256 * b + c
+ return 0x10000 * a + 0x100 * b + c
elseif n == 4 then
local a, b, c, d = byte(f:read(4),1,4)
- return 256*256*256 * a + 256*256 * b + 256 * c + d
+ return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
elseif n == 8 then
local a, b = readnumber(f,4), readnumber(f,4)
- return 256 * a + b
+ return 0x100 * a + b
elseif n == 12 then
local a, b, c = readnumber(f,4), readnumber(f,4), readnumber(f,4)
- return 256*256 * a + 256 * b + c
+ return 0x10000 * a + 0x100 * b + c
elseif n == -2 then
local b, a = byte(f:read(2),1,2)
- return 256*a + b
+ return 0x100 * a + b
elseif n == -3 then
local c, b, a = byte(f:read(3),1,3)
- return 256*256 * a + 256 * b + c
+ return 0x10000 * a + 0x100 * b + c
elseif n == -4 then
local d, c, b, a = byte(f:read(4),1,4)
- return 256*256*256 * a + 256*256 * b + 256*c + d
+ return 0x1000000 * a + 0x10000 * b + 0x100*c + d
elseif n == -8 then
local h, g, f, e, d, c, b, a = byte(f:read(8),1,8)
- return 256*256*256*256*256*256*256 * a +
- 256*256*256*256*256*256 * b +
- 256*256*256*256*256 * c +
- 256*256*256*256 * d +
- 256*256*256 * e +
- 256*256 * f +
- 256 * g +
- h
+ return 0x100000000000000 * a + 0x1000000000000 * b + 0x10000000000 * c + 0x100000000 * d +
+ 0x1000000 * e + 0x10000 * f + 0x100 * g + h
else
return 0
end
diff --git a/tex/context/base/mkiv/l-os.lua b/tex/context/base/mkiv/l-os.lua
index 5108faeef..9b54c9840 100644
--- a/tex/context/base/mkiv/l-os.lua
+++ b/tex/context/base/mkiv/l-os.lua
@@ -508,8 +508,10 @@ end
-- These are moved from core-con.lua (as I needed them elsewhere).
-local function isleapyear(year)
- return (year % 400 == 0) or ((year % 100 ~= 0) and (year % 4 == 0))
+local function isleapyear(year) -- timed for bram's cs practicum
+ -- return (year % 400 == 0) or (year % 100 ~= 0 and year % 4 == 0) -- 3:4:1600:1900 = 9.9 : 8.2 : 5.0 : 6.8 (29.9)
+ return (year % 4 == 0) and (year % 100 ~= 0 or year % 400 == 0) -- 3:4:1600:1900 = 5.1 : 6.5 : 8.1 : 10.2 (29.9)
+ -- return (year % 4 == 0) and (year % 400 == 0 or year % 100 ~= 0) -- 3:4:1600:1900 = 5.2 : 8.5 : 6.8 : 10.1 (30.6)
end
os.isleapyear = isleapyear
diff --git a/tex/context/base/mkiv/lxml-lpt.lua b/tex/context/base/mkiv/lxml-lpt.lua
index 939a737ab..bb6fb4568 100644
--- a/tex/context/base/mkiv/lxml-lpt.lua
+++ b/tex/context/base/mkiv/lxml-lpt.lua
@@ -177,7 +177,7 @@ apply_axis['child'] = function(list)
if dk.tg then
c = c + 1
collected[c] = dk
--- dk.ni = k -- refresh
+ dk.ni = k -- refresh
en = en + 1
dk.ei = en
end
@@ -197,7 +197,7 @@ local function collect(list,collected,c)
if dk.tg then
c = c + 1
collected[c] = dk
--- dk.ni = k -- refresh
+ dk.ni = k -- refresh
en = en + 1
dk.ei = en
c = collect(dk,collected,c)
@@ -225,7 +225,7 @@ local function collect(list,collected,c)
if dk.tg then
c = c + 1
collected[c] = dk
--- dk.ni = k -- refresh
+ dk.ni = k -- refresh
en = en + 1
dk.ei = en
c = collect(dk,collected,c)
diff --git a/tex/context/base/mkiv/lxml-tab.lua b/tex/context/base/mkiv/lxml-tab.lua
index 58b933c44..f2d38a654 100644
--- a/tex/context/base/mkiv/lxml-tab.lua
+++ b/tex/context/base/mkiv/lxml-tab.lua
@@ -264,7 +264,7 @@ local function add_empty(spacing, namespace, tag)
tg = tag,
at = at,
dt = { },
- ni = nt,
+ ni = nil, -- preset slot
__p__ = top
}
dt[nt] = t
@@ -287,7 +287,7 @@ local function add_begin(spacing, namespace, tag)
tg = tag,
at = at,
dt = { },
- ni = nt, -- preset slot
+ ni = nil, -- preset slot
__p__ = stack[level]
}
setmetatable(top, mt)
@@ -315,9 +315,7 @@ local function add_end(spacing, namespace, tag)
end
dt = top.dt
nt = #dt + 1
- toclose.ni = nt
dt[nt] = toclose
- -- dt[0] = top -- nasty circular reference when serializing table
if toclose.at.xmlns then
remove(xmlns)
end
@@ -377,7 +375,7 @@ local function add_special(what, spacing, text)
special = true,
ns = "",
tg = what,
- ni = nt,
+ ni = nil, -- preset slot
dt = { text },
}
end
diff --git a/tex/context/base/mkiv/node-fnt.lua b/tex/context/base/mkiv/node-fnt.lua
index 85525cac2..3dc99e5f2 100644
--- a/tex/context/base/mkiv/node-fnt.lua
+++ b/tex/context/base/mkiv/node-fnt.lua
@@ -192,7 +192,7 @@ end
report_fonts()
end
-function handlers.characters(head)
+function handlers.characters(head,groupcode,size,packtype,direction)
-- either next or not, but definitely no already processed list
starttiming(nodes)
@@ -430,7 +430,7 @@ function handlers.characters(head)
-- local attr = a == 0 and false or 0 -- 0 is the savest way
local attr = a > 0 and 0 or false -- 0 is the savest way
for i=1,#processors do
- local h, d = processors[i](head,font,attr)
+ local h, d = processors[i](head,font,attr,direction)
if d then
if h then
head = h
@@ -443,7 +443,7 @@ function handlers.characters(head)
local attr = a > 0 and 0 or false -- 0 is the savest way
for font, processors in next, usedfonts do -- unordered
for i=1,#processors do
- local h, d = processors[i](head,font,attr)
+ local h, d = processors[i](head,font,attr,direction)
if d then
if h then
head = h
@@ -459,7 +459,7 @@ function handlers.characters(head)
local font, dynamics = next(attrfonts)
for attribute, processors in next, dynamics do -- unordered, attr can switch in between
for i=1,#processors do
- local h, d = processors[i](head,font,attribute)
+ local h, d = processors[i](head,font,attribute,direction)
if d then
if h then
head = h
@@ -472,7 +472,7 @@ function handlers.characters(head)
for font, dynamics in next, attrfonts do
for attribute, processors in next, dynamics do -- unordered, attr can switch in between
for i=1,#processors do
- local h, d = processors[i](head,font,attribute)
+ local h, d = processors[i](head,font,attribute,direction)
if d then
if h then
head = h
diff --git a/tex/context/base/mkiv/page-ins.mkiv b/tex/context/base/mkiv/page-ins.mkiv
index 51f2a3c1c..09ba70b70 100644
--- a/tex/context/base/mkiv/page-ins.mkiv
+++ b/tex/context/base/mkiv/page-ins.mkiv
@@ -60,6 +60,7 @@
% \global\count\currentinsertionnumber\numexpr\insertionparameter\c!factor/\insertionparameter\c!n\relax
% \global\skip \currentinsertionnumber\insertionparameter\c!distance \relax
% \global\dimen\currentinsertionnumber\insertionparameter\c!maxheight\relax}
+% \floatingpenalty\zerocount
\appendtoks
\page_inserts_synchronize_registers
diff --git a/tex/context/base/mkiv/page-one.mkiv b/tex/context/base/mkiv/page-one.mkiv
index a41787133..9bd6951f3 100644
--- a/tex/context/base/mkiv/page-one.mkiv
+++ b/tex/context/base/mkiv/page-one.mkiv
@@ -213,7 +213,8 @@
\global\advance\d_page_floats_inserted_top\dimexpr\ht\floatbox+\dp\floatbox+\s_page_one_between_top_insert\relax}
\def\page_one_insert_top_float % maybe remember last beforeskip
- {\insert\namedinsertionnumber\s!topfloat\bgroup
+ {\floatingpenalty\zerocount
+ \insert\namedinsertionnumber\s!topfloat\bgroup
\forgetall
\ifconditional\c_page_one_top_of_insert
\ifconditional\c_page_one_correct_top_insert
@@ -284,6 +285,7 @@
\page_floats_get
\global\advance\d_page_floats_inserted_bottom\dimexpr\ht\floatbox+\dp\floatbox+\d_strc_floats_top\relax
\ifdim\d_page_floats_inserted_bottom<\pagegoal\relax
+ \floatingpenalty\zerocount
\insert\namedinsertionnumber\s!bottomfloat\bgroup
\forgetall
\blank[\rootfloatparameter\c!spacebefore]%
@@ -570,6 +572,7 @@
\def\page_one_place_float_bottom_indeed
{\global\advance\d_page_floats_inserted_bottom\dimexpr\ht\floatbox+\dp\floatbox+\d_strc_floats_top\relax
+ \floatingpenalty\zerocount
\insert\namedinsertionnumber\s!bottomfloat\bgroup
\forgetall
\blank[\rootfloatparameter\c!spacebefore]%
diff --git a/tex/context/base/mkiv/spac-ver.lua b/tex/context/base/mkiv/spac-ver.lua
index 569dfb982..2f0191e6a 100644
--- a/tex/context/base/mkiv/spac-ver.lua
+++ b/tex/context/base/mkiv/spac-ver.lua
@@ -1289,7 +1289,7 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also
local p = getprop(pagetail,"snapper")
if p then
local e = p.extra
- if e < 0 then
+ if e and e < 0 then
local t = texget("pagetotal")
if t > 0 then
local g = texget("pagegoal") -- 1073741823 is signal
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index aea5f09b7..7389dfad5 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index f36de8747..0adbb8f77 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/strc-not.mkvi b/tex/context/base/mkiv/strc-not.mkvi
index f1a51c5ad..db27cb5af 100644
--- a/tex/context/base/mkiv/strc-not.mkvi
+++ b/tex/context/base/mkiv/strc-not.mkvi
@@ -1366,10 +1366,24 @@
\inheritmaintextcolor % but we do want to obey the textcolor
\to \everybeforenoteinsert
+% \def\strc_notes_set_penalties
+% {\doif{\noteparameter\c!scope}\v!page{\floatingpenalty\maxdimen}% experiment
+% %\interlinepenalty\maxdimen % todo
+% \penalty\currentnotepenalty}
+
+\def\strc_notes_set_penalties
+ {% stored in insert node
+ \floatingpenalty \currentnotepenalty
+ % used when typesetting
+ \interlinepenalty\plushundred % plain value
+ % used when we need to split in columns
+ \ifnum\noteparameter\c!n>\plusone
+ \penalty\zerocount % otherwise no split in columns, maybe just always (tex just adds it to accumulated)
+ \fi}
+
+
\appendtoks
- \doif{\noteparameter\c!scope}\v!page{\floatingpenalty\maxdimen}% experiment
- \penalty\currentnotepenalty
- %\interlinepenalty\maxdimen % todo
+ \strc_notes_set_penalties
\forgetall
\strc_notes_set_bodyfont
\redoconvertfont % to undo \undo calls in in headings etc
diff --git a/tex/context/base/mkiv/trac-deb.lua b/tex/context/base/mkiv/trac-deb.lua
index d1168a3a9..03df86825 100644
--- a/tex/context/base/mkiv/trac-deb.lua
+++ b/tex/context/base/mkiv/trac-deb.lua
@@ -326,16 +326,20 @@ end
directives.register("system.showerror", lmx.overloaderror)
-local debugger = utilities.debugger
-
-local function trace_calls(n)
- debugger.enable()
- luatex.registerstopactions(function()
- debugger.disable()
- debugger.savestats(tex.jobname .. "-luacalls.log",tonumber(n))
- end)
- trace_calls = function() end
-end
+-- local debugger = utilities.debugger
+--
+-- local function trace_calls(n)
+-- debugger.enable()
+-- luatex.registerstopactions(function()
+-- debugger.disable()
+-- debugger.savestats(tex.jobname .. "-luacalls.log",tonumber(n))
+-- end)
+-- trace_calls = function() end
+-- end
+--
+-- directives.register("system.tracecalls", function(n)
+-- trace_calls(n)
+-- end) -- indirect is needed for nilling
local editor = [[scite "-open:%filename%" -goto:%linenumber%]]
@@ -354,8 +358,6 @@ callback.register("call_edit",function(filename,linenumber)
end
end)
-directives.register("system.tracecalls", function(n) trace_calls(n) end) -- indirect is needed for nilling
-
implement { name = "showtrackers", actions = trackers.show }
implement { name = "enabletrackers", actions = trackers.enable, arguments = "string" }
implement { name = "disabletrackers", actions = trackers.disable, arguments = "string" }
@@ -373,10 +375,12 @@ implement { name = "showdebuginfo", actions = lmx.showdebuginfo }
implement { name = "overloaderror", actions = lmx.overloaderror }
implement { name = "showlogcategories", actions = logs.show }
-directives.register("system.profile",function()
+local debugger = utilities.debugger
+
+directives.register("system.profile",function(n)
luatex.registerstopactions(function()
debugger.disable()
- debugger.savestats("luatex-profile.log")
+ debugger.savestats("luatex-profile.log",tonumber(n) or 0)
report_nl()
logs.report("system","profiler stopped, log saved in %a","luatex-profile.log")
report_nl()
diff --git a/tex/context/base/mkiv/trac-vis.lua b/tex/context/base/mkiv/trac-vis.lua
index 8cca4752b..5d69b406d 100644
--- a/tex/context/base/mkiv/trac-vis.lua
+++ b/tex/context/base/mkiv/trac-vis.lua
@@ -506,8 +506,8 @@ end
local math do
local m_cache = {
- b_cache = caches["bmath"],
- e_cache = caches["emath"],
+ beginmath = caches["bmath"],
+ endmath = caches["emath"],
}
local tags = {
diff --git a/tex/context/base/mkiv/typo-sus.lua b/tex/context/base/mkiv/typo-sus.lua
index e81b36b65..f728993f6 100644
--- a/tex/context/base/mkiv/typo-sus.lua
+++ b/tex/context/base/mkiv/typo-sus.lua
@@ -51,6 +51,7 @@ local getlist = nuts.getlist
local getkern = nuts.getkern
local getpenalty = nuts.getpenalty
local getwidth = nuts.getwidth
+local getwhd = nuts.getwhd
local isglyph = nuts.isglyph
local setattr = nuts.setattr
diff --git a/tex/context/base/mkiv/util-deb.lua b/tex/context/base/mkiv/util-deb.lua
index 040a7a9cf..57e015386 100644
--- a/tex/context/base/mkiv/util-deb.lua
+++ b/tex/context/base/mkiv/util-deb.lua
@@ -13,9 +13,10 @@ if not modules then modules = { } end modules ['util-deb'] = {
local debug = require "debug"
local getinfo, sethook = debug.getinfo, debug.sethook
-local type, next, tostring = type, next, tostring
+local type, next, tostring, tonumber = type, next, tostring, tonumber
local format, find, sub, gsub = string.format, string.find, string.sub, string.gsub
local insert, remove, sort = table.insert, table.remove, table.sort
+local setmetatableindex = table.setmetatableindex
utilities = utilities or { }
local debugger = utilities.debugger or { }
@@ -30,63 +31,73 @@ local dummycalls = 10*1000
local nesting = 0
local names = { }
-local function initialize()
+local initialize = false
- if FFISUPPORTED and ffi then
+if not (FFISUPPORTED and ffi) then
- if os.type == "windows" then
- local okay, kernel = pcall(ffi.load,"kernel32")
- if kernel then
- local tonumber = ffi.number or tonumber
-ffi.cdef[[
-int QueryPerformanceFrequency(int64_t *lpFrequency);
-int QueryPerformanceCounter(int64_t *lpPerformanceCount);
-]]
- local target = ffi.new("__int64[1]")
- ticks = function()
- if kernel.QueryPerformanceCounter(target) == 1 then
- return tonumber(target[0])
- else
- return 0
- end
- end
- local target = ffi.new("__int64[1]")
- seconds = function(ticks)
- if kernel.QueryPerformanceFrequency(target) == 1 then
- return ticks / tonumber(target[0])
- else
- return 0
- end
- end
- end
- elseif os.type == "unix" then
- local C = ffi.C
+ -- we have no precise timer
+
+elseif os.type == "windows" then
+
+ initialize = function()
+ local kernel = ffilib("kernel32","system") -- no checking
+ if kernel then
local tonumber = ffi.number or tonumber
- -- 1 = CLOCK_MONOTONIC
- -- 2 = CLOCK_PROCESS_CPUTIME_ID
-ffi.cdef [[
-struct timespec { long sec; long nsec; };
-int clock_gettime(int timerid, struct timespec *t);
- ]]
- local target = ffi.new("timespec[?]",1)
- function ticks()
- C.clock_gettime(2,target)
- return tonumber(target[0].sec*1000000000 + target[0].nsec)
+ ffi.cdef[[
+ int QueryPerformanceFrequency(int64_t *lpFrequency);
+ int QueryPerformanceCounter(int64_t *lpPerformanceCount);
+ ]]
+ local target = ffi.new("__int64[1]")
+ ticks = function()
+ if kernel.QueryPerformanceCounter(target) == 1 then
+ return tonumber(target[0])
+ else
+ return 0
+ end
end
+ local target = ffi.new("__int64[1]")
seconds = function(ticks)
- return ticks/1000000000
+ if kernel.QueryPerformanceFrequency(target) == 1 then
+ return ticks / tonumber(target[0])
+ else
+ return 0
+ end
end
-
end
+ initialize = false
end
- initialize = false
+elseif os.type == "unix" then
+
+ -- for the values: echo '#include <time.h>' > foo.h; gcc -dM -E foo.h
+
+ initialize = function()
+ local C = ffi.C
+ local tonumber = ffi.number or tonumber
+ ffi.cdef [[
+ /* what a mess */
+ typedef int clk_id_t;
+ typedef enum { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID } clk_id;
+ typedef struct timespec { long sec; long nsec; } ctx_timespec;
+ int clock_gettime(clk_id_t timerid, struct timespec *t);
+ ]]
+ local target = ffi.new("ctx_timespec[?]",1)
+ local clock = C.CLOCK_PROCESS_CPUTIME_ID
+ ticks = function ()
+ C.clock_gettime(clock,target)
+ return tonumber(target[0].sec*1000000000 + target[0].nsec)
+ end
+ seconds = function(ticks)
+ return ticks/1000000000
+ end
+ initialize = false
+ end
end
-table.setmetatableindex(names,function(t,name)
- local v = table.setmetatableindex(function(t,source)
- local v = table.setmetatableindex(function(t,line)
+setmetatableindex(names,function(t,name)
+ local v = setmetatableindex(function(t,source)
+ local v = setmetatableindex(function(t,line)
local v = { total = 0, count = 0 }
t[line] = v
return v
@@ -128,33 +139,39 @@ local function hook(where)
end
end
-function debugger.showstats(printer)
+function debugger.showstats(printer,threshold)
local printer = printer or report
local calls = 0
local functions = 0
local dataset = { }
local length = 0
local wholetime = 0
+ local threshold = threshold or 0
for name, sources in next, names do
for source, lines in next, sources do
for line, data in next, lines do
- if #name > length then
- length = #name
- end
- local total = data.total
local count = data.count
- local real = total
- if real > 0 then
- real = total - (count * overhead / dummycalls)
- if real < 0 then
- real = 0
+ if count > threshold then
+ if #name > length then
+ length = #name
end
- wholetime = wholetime + real
- end
- if line < 0 then
- line = 0
+ local total = data.total
+ local real = total
+ if real > 0 then
+ real = total - (count * overhead / dummycalls)
+ if real < 0 then
+ real = 0
+ end
+ wholetime = wholetime + real
+ end
+ if line < 0 then
+ line = 0
+ end
+ -- if name = "a" then
+ -- -- weird name
+ -- end
+ dataset[#dataset+1] = { real, total, count, name, source, line }
end
- dataset[#dataset+1] = { real, total, count, name, source, line }
end
end
end
@@ -206,12 +223,14 @@ function debugger.showstats(printer)
printer(format("functions : %i", functions))
printer(format("calls : %i", calls))
printer(format("overhead : %f", seconds(overhead/1000)))
+
+ -- table.save("luatex-profile.lua",names)
end
-function debugger.savestats(filename)
+function debugger.savestats(filename,threshold)
local f = io.open(filename,'w')
if f then
- debugger.showstats(function(str) f:write(str,"\n") end)
+ debugger.showstats(function(str) f:write(str,"\n") end,threshold)
f:close()
end
end
diff --git a/tex/context/base/mkiv/util-fil.lua b/tex/context/base/mkiv/util-fil.lua
index dba3b235c..4e66ba461 100644
--- a/tex/context/base/mkiv/util-fil.lua
+++ b/tex/context/base/mkiv/util-fil.lua
@@ -83,6 +83,12 @@ function files.readbytes(f,n)
return byte(f:read(n),1,n)
end
+function files.readbytetable(f,n)
+ -- return { byte(f:read(n),1,n) }
+ local s = f:read(n or 1)
+ return { byte(s,1,#s) } -- best use the real length
+end
+
function files.readchar(f)
return f:read(1)
end
@@ -183,24 +189,24 @@ function files.readcardinal4le(f)
return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
end
+-- function files.readinteger4(f)
+-- local a, b, c, d = byte(f:read(4),1,4)
+-- local n = 0x1000000 * a + 0x10000 * b + 0x100 * c + d
+-- if n >= 0x8000000 then
+-- -- return n - 0xFFFFFFFF - 1
+-- return n - 0x100000000
+-- else
+-- return n
+-- end
+-- end
function files.readinteger4(f)
local a, b, c, d = byte(f:read(4),1,4)
- local n = 0x1000000 * a + 0x10000 * b + 0x100 * c + d
- if n >= 0x8000000 then
- -- return n - 0xFFFFFFFF - 1
- return n - 0x100000000
+ if a >= 0x80 then
+ return 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000
else
- return n
+ return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
end
end
- function files.readinteger4(f)
- local a, b, c, d = byte(f:read(4),1,4)
- if a >= 0x80 then
- return 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000
- else
- return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
- end
- end
function files.readinteger4le(f)
local d, c, b, a = byte(f:read(4),1,4)
local n = 0x1000000 * a + 0x10000 * b + 0x100 * c + d
@@ -214,13 +220,12 @@ end
function files.readfixed4(f)
local a, b, c, d = byte(f:read(4),1,4)
- local n = 0x100 * a + b
- if n >= 0x8000 then
- -- return n - 0xFFFF - 1 + (0x100 * c + d)/0xFFFF
- return n - 0x10000 + (0x100 * c + d)/0xFFFF
+ if a >= 0x80 then
+ return (0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000)/65536.0
else
- return n + (0x100 * c + d)/0xFFFF
+ return (0x1000000 * a + 0x10000 * b + 0x100 * c + d)/65536.0
end
+
end
if extract then
@@ -276,3 +281,38 @@ function files.writebyte(f,b)
f:write(char(b))
end
+if fio and fio.readcardinal1 then
+
+ files.readcardinal1 = fio.readcardinal1
+ files.readcardinal2 = fio.readcardinal2
+ files.readcardinal3 = fio.readcardinal3
+ files.readcardinal4 = fio.readcardinal4
+ files.readinteger1 = fio.readinteger1
+ files.readinteger2 = fio.readinteger2
+ files.readinteger3 = fio.readinteger3
+ files.readinteger4 = fio.readinteger4
+ files.readfixed4 = fio.readfixed4
+ files.read2dot14 = fio.read2dot14
+ files.setposition = fio.setposition
+ files.getposition = fio.getposition
+
+ files.readbyte = files.readcardinel1
+ files.readsignedbyte = files.readinteger1
+ files.readcardinal = files.readcardinal1
+ files.readinteger = files.readinteger1
+
+ local skipposition = fio.skipposition
+ files.skipposition = skipposition
+
+ files.readbytes = fio.readbytes
+ files.readbytetable = fio.readbytetable
+
+ function files.skipshort(f,n)
+ skipposition(f,2*(n or 1))
+ end
+
+ function files.skiplong(f,n)
+ skipposition(f,4*(n or 1))
+ end
+
+end
diff --git a/tex/context/base/mkiv/util-lib.lua b/tex/context/base/mkiv/util-lib.lua
index e9a968228..98c417b8e 100644
--- a/tex/context/base/mkiv/util-lib.lua
+++ b/tex/context/base/mkiv/util-lib.lua
@@ -327,15 +327,21 @@ We use the same lookup logic for ffi loading.
trackers.register("resolvers.ffilib", function(v) trace_ffilib = v end)
+ local function locateindeed(name)
+ local message, library = pcall(savedffiload,removesuffix(name))
+ if type(library) == "userdata" then
+ return library
+ else
+ return false
+ end
+ end
+
function ffilib(required,version)
- return locate(required,version,trace_ffilib,report_ffilib,function(name)
- local message, library = pcall(savedffiload,removesuffix(name))
- if type(library) == "userdata" then
- return message, library
- else
- return message, false
- end
- end)
+ if version == "system" then
+ return locateindeed(name)
+ else
+ return locate(required,version,trace_ffilib,report_ffilib,locateindeed)
+ end
end
function ffi.load(name)
diff --git a/tex/context/base/mkiv/util-sac.lua b/tex/context/base/mkiv/util-sac.lua
index 5d16be3ec..1a52bfc58 100644
--- a/tex/context/base/mkiv/util-sac.lua
+++ b/tex/context/base/mkiv/util-sac.lua
@@ -82,6 +82,13 @@ function streams.readbytes(f,n)
return byte(f[1],i,j-1)
end
+function streams.readbytetable(f,n)
+ local i = f[2]
+ local j = i + n
+ f[2] = j
+ return { byte(f[1],i,j-1) }
+end
+
function streams.skipbytes(f,n)
f[2] = f[2] + n
end
@@ -104,7 +111,8 @@ function streams.readinteger1(f) -- one byte
f[2] = i + 1
local n = byte(f[1],i)
if n >= 0x80 then
- return n - 0xFF - 1
+ -- return n - 0xFF - 1
+ return n - 0x100
else
return n
end
@@ -129,7 +137,8 @@ function streams.readinteger2(f)
local a, b = byte(f[1],i,j)
local n = 0x100 * a + b
if n >= 0x8000 then
- return n - 0xFFFF - 1
+ -- return n - 0xFFFF - 1
+ return n - 0x10000
else
return n
end
@@ -158,7 +167,8 @@ function streams.readinteger4(f)
local a, b, c, d = byte(f[1],i,j)
local n = 0x1000000 * a + 0x10000 * b + 0x100 * c + d
if n >= 0x8000000 then
- return n - 0xFFFFFFFF - 1
+ -- return n - 0xFFFFFFFF - 1
+ return n - 0x100000000
else
return n
end
@@ -171,7 +181,8 @@ function streams.readfixed4(f)
local a, b, c, d = byte(f[1],i,j)
local n = 0x100 * a + b
if n >= 0x8000 then
- return n - 0xFFFF - 1 + (0x100 * c + d)/0xFFFF
+ -- return n - 0xFFFF - 1 + (0x100 * c + d)/0xFFFF
+ return n - 0x10000 + (0x100 * c + d)/0xFFFF
else
return n + (0x100 * c + d)/0xFFFF
end
diff --git a/tex/context/fonts/mkiv/xits-math.lfg b/tex/context/fonts/mkiv/xits-math.lfg
index dd09dd0f1..372224940 100644
--- a/tex/context/fonts/mkiv/xits-math.lfg
+++ b/tex/context/fonts/mkiv/xits-math.lfg
@@ -27,6 +27,11 @@ return {
-- italics = {
-- ["xits-math"] = italics,
-- },
+ -- kernpairs = {
+ -- [0x1D44A] = { -- 𝑊
+ -- [0x1D434] = -200, -- 𝐴
+ -- },
+ -- },
alternates = {
calligraphic = { feature = 'ss01', value = 1, comment = "Mathematical Calligraphic Alphabet" },
greekssup = { feature = 'ss02', value = 1, comment = "Mathematical Greek Sans Serif Alphabet" },
diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf
index 16463b9be..1418c1aea 100644
--- a/tex/context/interface/mkiv/i-context.pdf
+++ b/tex/context/interface/mkiv/i-context.pdf
Binary files differ
diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf
index 98314b3a2..d05ac8701 100644
--- a/tex/context/interface/mkiv/i-readme.pdf
+++ b/tex/context/interface/mkiv/i-readme.pdf
Binary files differ
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 52344aa26..2690045cf 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 02/25/17 16:24:36
+-- merge date : 03/01/17 13:40:58
do -- begin closure to overcome local limits and interference
@@ -2059,44 +2059,30 @@ if string.find(os.getenv("PATH"),";",1,true) then
else
io.fileseparator,io.pathseparator="/",":"
end
-local function readall(f)
- return f:read("*all")
-end
+local large=2^24
+local medium=large/16
+local small=medium/8
local function readall(f)
local size=f:seek("end")
- if size==0 then
- return ""
- end
- f:seek("set",0)
- if size<1024*1024 then
- return f:read('*all')
+ if size>0 then
+ f:seek("set",0)
+ return f:read(size)
else
- local step
- if size>16*1024*1024 then
- step=16*1024*1024
- else
- step=floor(size/(1024*1024))*1024*1024/8
- end
- local data={}
- while true do
- local r=f:read(step)
- if not r then
- return concat(data)
- else
- data[#data+1]=r
- end
- end
+ return ""
end
end
io.readall=readall
function io.loaddata(filename,textmode)
local f=open(filename,(textmode and 'r') or 'rb')
if f then
- local data=readall(f)
- f:close()
- if #data>0 then
- return data
+ local size=f:seek("end")
+ local data=nil
+ if size>0 then
+ f:seek("set",0)
+ data=f:read(size)
end
+ f:close()
+ return data
end
end
function io.copydata(source,target,action)
@@ -2105,37 +2091,14 @@ function io.copydata(source,target,action)
local g=open(target,"wb")
if g then
local size=f:seek("end")
- if size==0 then
- else
+ if size>0 then
f:seek("set",0)
- if size<1024*1024 then
- local data=f:read('*all')
- if action then
- data=action(data)
- end
- if data then
- g:write(data)
- end
- else
- local step
- if size>16*1024*1024 then
- step=16*1024*1024
- else
- step=floor(size/(1024*1024))*1024*1024/8
- end
- while true do
- local data=f:read(step)
- if data then
- if action then
- data=action(data)
- end
- if data then
- g:write(data)
- end
- else
- break
- end
- end
+ local data=f:read(size)
+ if action then
+ data=action(data)
+ end
+ if data then
+ g:write(data)
end
end
g:close()
@@ -2161,29 +2124,59 @@ function io.savedata(filename,data,joiner)
return false
end
end
-function io.loadlines(filename,n)
- local f=open(filename,'r')
- if not f then
- elseif n then
- local lines={}
- for i=1,n do
- local line=f:read("*lines")
- if line then
- lines[#lines+1]=line
- else
- break
+if fio.readline then
+ local readline=fio.readline
+ function io.loadlines(filename,n)
+ local f=open(filename,'r')
+ if not f then
+ elseif n then
+ local lines={}
+ for i=1,n do
+ local line=readline(f)
+ if line then
+ lines[i]=line
+ else
+ break
+ end
+ end
+ f:close()
+ lines=concat(lines,"\n")
+ if #lines>0 then
+ return lines
+ end
+ else
+ local line=readline(f)
+ f:close()
+ if line and #line>0 then
+ return line
end
end
- f:close()
- lines=concat(lines,"\n")
- if #lines>0 then
- return lines
- end
- else
- local line=f:read("*line") or ""
- f:close()
- if #line>0 then
- return line
+ end
+else
+ function io.loadlines(filename,n)
+ local f=open(filename,'r')
+ if not f then
+ elseif n then
+ local lines={}
+ for i=1,n do
+ local line=f:read("*lines")
+ if line then
+ lines[i]=line
+ else
+ break
+ end
+ end
+ f:close()
+ lines=concat(lines,"\n")
+ if #lines>0 then
+ return lines
+ end
+ else
+ local line=f:read("*line") or ""
+ f:close()
+ if #line>0 then
+ return line
+ end
end
end
end
@@ -2344,7 +2337,7 @@ function io.ask(question,default,options)
end
end
end
-local function readnumber(f,n,m)
+local function readnumber(f,n,m)
if m then
f:seek("set",n)
n=m
@@ -2353,31 +2346,31 @@ local function readnumber(f,n,m)
return byte(f:read(1))
elseif n==2 then
local a,b=byte(f:read(2),1,2)
- return 256*a+b
+ return 0x100*a+b
elseif n==3 then
local a,b,c=byte(f:read(3),1,3)
- return 256*256*a+256*b+c
+ return 0x10000*a+0x100*b+c
elseif n==4 then
local a,b,c,d=byte(f:read(4),1,4)
- return 256*256*256*a+256*256*b+256*c+d
+ return 0x1000000*a+0x10000*b+0x100*c+d
elseif n==8 then
local a,b=readnumber(f,4),readnumber(f,4)
- return 256*a+b
+ return 0x100*a+b
elseif n==12 then
local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4)
- return 256*256*a+256*b+c
+ return 0x10000*a+0x100*b+c
elseif n==-2 then
local b,a=byte(f:read(2),1,2)
- return 256*a+b
+ return 0x100*a+b
elseif n==-3 then
local c,b,a=byte(f:read(3),1,3)
- return 256*256*a+256*b+c
+ return 0x10000*a+0x100*b+c
elseif n==-4 then
local d,c,b,a=byte(f:read(4),1,4)
- return 256*256*256*a+256*256*b+256*c+d
+ return 0x1000000*a+0x10000*b+0x100*c+d
elseif n==-8 then
local h,g,f,e,d,c,b,a=byte(f:read(8),1,8)
- return 256*256*256*256*256*256*256*a+256*256*256*256*256*256*b+256*256*256*256*256*c+256*256*256*256*d+256*256*256*e+256*256*f+256*g+h
+ return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
else
return 0
end
@@ -4302,6 +4295,10 @@ end
function files.readbytes(f,n)
return byte(f:read(n),1,n)
end
+function files.readbytetable(f,n)
+ local s=f:read(n or 1)
+ return { byte(s,1,#s) }
+end
function files.readchar(f)
return f:read(1)
end
@@ -4390,21 +4387,12 @@ function files.readcardinal4le(f)
end
function files.readinteger4(f)
local a,b,c,d=byte(f:read(4),1,4)
- local n=0x1000000*a+0x10000*b+0x100*c+d
- if n>=0x8000000 then
- return n-0x100000000
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
else
- return n
+ return 0x1000000*a+0x10000*b+0x100*c+d
end
end
- function files.readinteger4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
- end
function files.readinteger4le(f)
local d,c,b,a=byte(f:read(4),1,4)
local n=0x1000000*a+0x10000*b+0x100*c+d
@@ -4416,11 +4404,10 @@ function files.readinteger4le(f)
end
function files.readfixed4(f)
local a,b,c,d=byte(f:read(4),1,4)
- local n=0x100*a+b
- if n>=0x8000 then
- return n-0x10000+(0x100*c+d)/0xFFFF
+ if a>=0x80 then
+ return (0x1000000*a+0x10000*b+0x100*c+d-0x100000000)/65536.0
else
- return n+(0x100*c+d)/0xFFFF
+ return (0x1000000*a+0x10000*b+0x100*c+d)/65536.0
end
end
if extract then
@@ -4465,6 +4452,34 @@ end
function files.writebyte(f,b)
f:write(char(b))
end
+if fio and fio.readcardinal1 then
+ files.readcardinal1=fio.readcardinal1
+ files.readcardinal2=fio.readcardinal2
+ files.readcardinal3=fio.readcardinal3
+ files.readcardinal4=fio.readcardinal4
+ files.readinteger1=fio.readinteger1
+ files.readinteger2=fio.readinteger2
+ files.readinteger3=fio.readinteger3
+ files.readinteger4=fio.readinteger4
+ files.readfixed4=fio.readfixed4
+ files.read2dot14=fio.read2dot14
+ files.setposition=fio.setposition
+ files.getposition=fio.getposition
+ files.readbyte=files.readcardinel1
+ files.readsignedbyte=files.readinteger1
+ files.readcardinal=files.readcardinal1
+ files.readinteger=files.readinteger1
+ local skipposition=fio.skipposition
+ files.skipposition=skipposition
+ files.readbytes=fio.readbytes
+ files.readbytetable=fio.readbytetable
+ function files.skipshort(f,n)
+ skipposition(f,2*(n or 1))
+ end
+ function files.skiplong(f,n)
+ skipposition(f,4*(n or 1))
+ end
+end
end -- closure
@@ -8106,10 +8121,10 @@ local readulong=streamreader.readcardinal4
local readshort=streamreader.readinteger2
local readlong=streamreader.readinteger4
local readfixed=streamreader.readfixed4
+local read2dot14=streamreader.read2dot14
local readfword=readshort
local readufword=readushort
local readoffset=readushort
-local read2dot14=streamreader.read2dot14
function streamreader.readtag(f)
return lower(stripstring(readstring(f,4)))
end
@@ -9421,12 +9436,18 @@ local function prepareglyps(fontdata)
fontdata.glyphs=glyphs
fontdata.mapping={}
end
+local function readtable(tag,f,fontdata,specification)
+ local reader=readers[tag]
+ if reader then
+ reader(f,fontdata,specification)
+ end
+end
local function readdata(f,offset,specification)
local fontdata=loadtables(f,specification,offset)
if specification.glyphs then
prepareglyps(fontdata)
end
- readers["name"](f,fontdata,specification)
+ readtable("name",f,fontdata,specification)
local askedname=specification.askedname
if askedname then
local fullname=getname(fontdata,"fullname") or ""
@@ -9436,27 +9457,27 @@ local function readdata(f,offset,specification)
return
end
end
- readers["os/2"](f,fontdata,specification)
- readers["head"](f,fontdata,specification)
- readers["maxp"](f,fontdata,specification)
- readers["hhea"](f,fontdata,specification)
- readers["vhea"](f,fontdata,specification)
- readers["hmtx"](f,fontdata,specification)
- readers["vmtx"](f,fontdata,specification)
- readers["vorg"](f,fontdata,specification)
- readers["post"](f,fontdata,specification)
- readers["cff" ](f,fontdata,specification)
- readers["cmap"](f,fontdata,specification)
- readers["loca"](f,fontdata,specification)
- readers["glyf"](f,fontdata,specification)
- readers["colr"](f,fontdata,specification)
- readers["cpal"](f,fontdata,specification)
- readers["svg" ](f,fontdata,specification)
- readers["kern"](f,fontdata,specification)
- readers["gdef"](f,fontdata,specification)
- readers["gsub"](f,fontdata,specification)
- readers["gpos"](f,fontdata,specification)
- readers["math"](f,fontdata,specification)
+ readtable("os/2",f,fontdata,specification)
+ readtable("head",f,fontdata,specification)
+ readtable("maxp",f,fontdata,specification)
+ readtable("hhea",f,fontdata,specification)
+ readtable("vhea",f,fontdata,specification)
+ readtable("hmtx",f,fontdata,specification)
+ readtable("vmtx",f,fontdata,specification)
+ readtable("vorg",f,fontdata,specification)
+ readtable("post",f,fontdata,specification)
+ readtable("cff",f,fontdata,specification)
+ readtable("cmap",f,fontdata,specification)
+ readtable("loca",f,fontdata,specification)
+ readtable("glyf",f,fontdata,specification)
+ readtable("colr",f,fontdata,specification)
+ readtable("cpal",f,fontdata,specification)
+ readtable("svg",f,fontdata,specification)
+ readtable("kern",f,fontdata,specification)
+ readtable("gdef",f,fontdata,specification)
+ readtable("gsub",f,fontdata,specification)
+ readtable("gpos",f,fontdata,specification)
+ readtable("math",f,fontdata,specification)
fontdata.locations=nil
fontdata.tables=nil
fontdata.cidmaps=nil
@@ -9725,13 +9746,12 @@ if not modules then modules={} end modules ['font-cff']={
local next,type,tonumber=next,type,tonumber
local byte=string.byte
local concat,remove=table.concat,table.remove
-local floor,abs,round,ceil=math.floor,math.abs,math.round,math.ceil
+local floor,abs,round,ceil,min,max=math.floor,math.abs,math.round,math.ceil,math.min,math.max
local P,C,R,S,C,Cs,Ct=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Ct
local lpegmatch=lpeg.match
local formatters=string.formatters
local readers=fonts.handlers.otf.readers
local streamreader=readers.streamreader
-local readbytes=streamreader.readbytes
local readstring=streamreader.readstring
local readbyte=streamreader.readcardinal1
local readushort=streamreader.readcardinal2
@@ -9739,6 +9759,7 @@ local readuint=streamreader.readcardinal3
local readulong=streamreader.readcardinal4
local setposition=streamreader.setposition
local getposition=streamreader.getposition
+local readbytetable=streamreader.readbytetable
local setmetatableindex=table.setmetatableindex
local trace_charstrings=false trackers.register("fonts.cff.charstrings",function(v) trace_charstrings=v end)
local report=logs.reporter("otf reader","cff")
@@ -10140,14 +10161,14 @@ do
report("%w%-10s : %s",depth*2,where,tostring(value))
end
end
- local function moveto(x,y)
+ local function moveto()
if keepcurve then
r=r+1
result[r]={ x,y,"m" }
end
if checked then
- if x<xmin then xmin=x elseif x>xmax then xmax=x end
- if y<ymin then ymin=y elseif y>ymax then ymax=y end
+ if x>xmax then xmax=x elseif x<xmin then xmin=x end
+ if y>ymax then ymax=y elseif y<ymin then ymin=y end
else
xmin=x
ymin=y
@@ -10156,14 +10177,48 @@ do
checked=true
end
end
- local function lineto(x,y)
+ local function xmoveto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"m" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif x>xmax then
+ xmax=x
+ elseif x<xmin then
+ xmin=x
+ end
+ end
+ local function ymoveto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"m" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif y>ymax then
+ ymax=y
+ elseif y<ymin then
+ ymin=y
+ end
+ end
+ local function lineto()
if keepcurve then
r=r+1
result[r]={ x,y,"l" }
end
if checked then
- if x<xmin then xmin=x elseif x>xmax then xmax=x end
- if y<ymin then ymin=y elseif y>ymax then ymax=y end
+ if x>xmax then xmax=x elseif x<xmin then xmin=x end
+ if y>ymax then ymax=y elseif y<ymin then ymin=y end
else
xmin=x
ymin=y
@@ -10172,14 +10227,48 @@ do
checked=true
end
end
+ local function xlineto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"l" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif x>xmax then
+ xmax=x
+ elseif x<xmin then
+ xmin=x
+ end
+ end
+ local function ylineto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"l" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif y>ymax then
+ ymax=y
+ elseif y<ymin then
+ ymin=y
+ end
+ end
local function curveto(x1,y1,x2,y2,x3,y3)
if keepcurve then
r=r+1
result[r]={ x1,y1,x2,y2,x3,y3,"c" }
end
if checked then
- if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
- if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
+ if x1>xmax then xmax=x1 elseif x1<xmin then xmin=x1 end
+ if y1>ymax then ymax=y1 elseif y1<ymin then ymin=y1 end
else
xmin=x1
ymin=y1
@@ -10187,21 +10276,21 @@ do
ymax=y1
checked=true
end
- if x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
- if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
- if x3<xmin then xmin=x3 elseif x3>xmax then xmax=x3 end
- if y3<ymin then ymin=y3 elseif y3>ymax then ymax=y3 end
+ if x2>xmax then xmax=x2 elseif x2<xmin then xmin=x2 end
+ if y2>ymax then ymax=y2 elseif y2<ymin then ymin=y2 end
+ if x3>xmax then xmax=x3 elseif x3<xmin then xmin=x3 end
+ if y3>ymax then ymax=y3 elseif y3<ymin then ymin=y3 end
end
local function rmoveto()
- if top>2 then
- if not width then
+ if not width then
+ if top>2 then
width=stack[1]
if trace_charstrings then
showvalue("width",width)
end
+ else
+ width=true
end
- elseif not width then
- width=true
end
if trace_charstrings then
showstate("rmoveto")
@@ -10209,43 +10298,43 @@ do
x=x+stack[top-1]
y=y+stack[top]
top=0
- moveto(x,y)
+ moveto()
end
local function hmoveto()
- if top>1 then
- if not width then
+ if not width then
+ if top>1 then
width=stack[1]
if trace_charstrings then
showvalue("width",width)
end
+ else
+ width=true
end
- elseif not width then
- width=true
end
if trace_charstrings then
showstate("hmoveto")
end
x=x+stack[top]
top=0
- moveto(x,y)
+ xmoveto()
end
local function vmoveto()
- if top>1 then
- if not width then
+ if not width then
+ if top>1 then
width=stack[1]
if trace_charstrings then
showvalue("width",width)
end
+ else
+ width=true
end
- elseif not width then
- width=true
end
if trace_charstrings then
showstate("vmoveto")
end
y=y+stack[top]
top=0
- moveto(x,y)
+ ymoveto()
end
local function rlineto()
if trace_charstrings then
@@ -10254,20 +10343,7 @@ do
for i=1,top,2 do
x=x+stack[i]
y=y+stack[i+1]
- lineto(x,y)
- end
- top=0
- end
- local function xlineto(swap)
- for i=1,top do
- if swap then
- x=x+stack[i]
- swap=false
- else
- y=y+stack[i]
- swap=true
- end
- lineto(x,y)
+ lineto()
end
top=0
end
@@ -10275,13 +10351,47 @@ do
if trace_charstrings then
showstate("hlineto")
end
- xlineto(true)
+ if top==1 then
+ x=x+stack[1]
+ xlineto()
+ else
+ local swap=true
+ for i=1,top do
+ if swap then
+ x=x+stack[i]
+ xlineto()
+ swap=false
+ else
+ y=y+stack[i]
+ ylineto()
+ swap=true
+ end
+ end
+ end
+ top=0
end
local function vlineto()
if trace_charstrings then
showstate("vlineto")
end
- xlineto(false)
+ if top==1 then
+ y=y+stack[1]
+ ylineto()
+ else
+ local swap=false
+ for i=1,top do
+ if swap then
+ x=x+stack[i]
+ xlineto()
+ swap=false
+ else
+ y=y+stack[i]
+ ylineto()
+ swap=true
+ end
+ end
+ end
+ top=0
end
local function rrcurveto()
if trace_charstrings then
@@ -10292,8 +10402,8 @@ do
local ay=y+stack[i+1]
local bx=ax+stack[i+2]
local by=ay+stack[i+3]
- x=bx+stack[i+4]
- y=by+stack[i+5]
+ x=bx+stack[i+4]
+ y=by+stack[i+5]
curveto(ax,ay,bx,by,x,y)
end
top=0
@@ -10304,15 +10414,15 @@ do
end
local s=1
if top%2~=0 then
- y=y+stack[1]
+ y=y+stack[1]
s=2
end
for i=s,top,4 do
- local ax=x+stack[i]
+ local ax=x+stack[i]
local ay=y
local bx=ax+stack[i+1]
local by=ay+stack[i+2]
- x=bx+stack[i+3]
+ x=bx+stack[i+3]
y=by
curveto(ax,ay,bx,by,x,y)
end
@@ -10325,16 +10435,16 @@ do
local s=1
local d=0
if top%2~=0 then
- d=stack[1]
+ d=stack[1]
s=2
end
for i=s,top,4 do
local ax=x+d
- local ay=y+stack[i]
+ local ay=y+stack[i]
local bx=ax+stack[i+1]
local by=ay+stack[i+2]
x=bx
- y=by+stack[i+3]
+ y=by+stack[i+3]
curveto(ax,ay,bx,by,x,y)
d=0
end
@@ -10345,7 +10455,6 @@ do
if last then
top=top-1
end
- local sw=swap
for i=1,top,4 do
local ax,ay,bx,by
if swap then
@@ -10404,7 +10513,7 @@ do
end
x=x+stack[top-1]
y=y+stack[top]
- lineto(x,y)
+ lineto()
top=0
end
local function rlinecurve()
@@ -10415,7 +10524,7 @@ do
for i=1,top-6,2 do
x=x+stack[i]
y=y+stack[i+1]
- lineto(x,y)
+ lineto()
end
end
local ax=x+stack[top-5]
@@ -10451,7 +10560,7 @@ do
if trace_charstrings then
showstate("hflex")
end
- local ax=x+stack[1]
+ local ax=x+stack[1]
local ay=y
local bx=ax+stack[2]
local by=ay+stack[3]
@@ -10688,8 +10797,8 @@ do
[036]=hflex1,
[037]=flex1,
}
- local p_bytes=Ct((P(1)/byte)^0)
- local function call(scope,list,bias,process)
+ local process
+ local function call(scope,list,bias)
depth=depth+1
if top==0 then
showstate(formatters["unknown %s call"](scope))
@@ -10702,10 +10811,6 @@ do
end
local tab=list[index]
if tab then
- if type(tab)=="string" then
- tab=lpegmatch(p_bytes,tab)
- list[index]=tab
- end
process(tab)
else
showstate(formatters["unknown %s call %i"](scope,index))
@@ -10714,50 +10819,52 @@ do
end
depth=depth-1
end
- local function process(tab)
+ process=function(tab)
local i=1
local n=#tab
while i<=n do
local t=tab[i]
- if t>=32 and t<=246 then
- top=top+1
- stack[top]=t-139
- i=i+1
- elseif t>=247 and t<=250 then
- top=top+1
- stack[top]=(t-247)*256+tab[i+1]+108
- i=i+2
- elseif t>=251 and t<=254 then
- top=top+1
- stack[top]=-(t-251)*256-tab[i+1]-108
- i=i+2
+ if t>=32 then
+ if t<=246 then
+ top=top+1
+ stack[top]=t-139
+ i=i+1
+ elseif t<=250 then
+ top=top+1
+ stack[top]=t*256-63124+tab[i+1]
+ i=i+2
+ elseif t<=254 then
+ top=top+1
+ stack[top]=-t*256+64148-tab[i+1]
+ i=i+2
+ else
+ local n=0x100*tab[i+1]+tab[i+2]
+ top=top+1
+ if n>=0x8000 then
+ stack[top]=n-0x10000+(0x100*tab[i+3]+tab[i+4])/0xFFFF
+ else
+ stack[top]=n+(0x100*tab[i+3]+tab[i+4])/0xFFFF
+ end
+ i=i+5
+ end
elseif t==28 then
top=top+1
local n=0x100*tab[i+1]+tab[i+2]
if n>=0x8000 then
- stack[top]=n-0xFFFF-1
+ stack[top]=n-0x10000
else
stack[top]=n
end
i=i+3
- elseif t==255 then
- local n=0x100*tab[i+1]+tab[i+2]
- top=top+1
- if n>=0x8000 then
- stack[top]=n-0xFFFF-1+(0x100*tab[i+3]+tab[i+4])/0xFFFF
- else
- stack[top]=n+(0x100*tab[i+3]+tab[i+4])/0xFFFF
- end
- i=i+5
elseif t==11 then
if trace_charstrings then
showstate("return")
end
return
elseif t==10 then
- call("local",locals,localbias,process)
+ call("local",locals,localbias)
i=i+1
- elseif t==14 then
+ elseif t==14 then
if width then
elseif top>0 then
width=stack[1]
@@ -10772,7 +10879,7 @@ do
end
return
elseif t==29 then
- call("global",globals,globalbias,process)
+ call("global",globals,globalbias)
i=i+1
elseif t==12 then
i=i+1
@@ -10833,9 +10940,7 @@ do
local defaultwidth=private.data.defaultwidthx or 0
for i=1,#charstrings do
local tab=charstrings[i]
- if type(tab)=="string" then
- tab=lpegmatch(p_bytes,tab)
- end
+ tab={ byte(tab,1,#tab) }
local index=i-1
x=0
y=0
@@ -10861,14 +10966,7 @@ do
width=nominalwidth+width
end
local glyph=glyphs[index]
- if not glyph then
- glyphs[index]={
- segments=doshapes~=false and result or nil,
- boundingbox=boundingbox,
- width=width,
- name=charset[index],
- }
- else
+ if glyph then
glyph.segments=doshapes~=false and result or nil
glyph.boundingbox=boundingbox
if not glyph.width then
@@ -10877,6 +10975,19 @@ do
if charset and not glyph.name then
glyph.name=charset[index]
end
+ elseif doshapes then
+ glyphs[index]={
+ segments=result,
+ boundingbox=boundingbox,
+ width=width,
+ name=charset[index],
+ }
+ else
+ glyphs[index]={
+ boundingbox=boundingbox,
+ width=width,
+ name=charset[index],
+ }
end
if trace_charstrings then
report("width: %s",tostring(width))
@@ -10896,9 +11007,7 @@ do
globalbias,localbias=setbias(globals,locals)
local nominalwidth=private and private.data.nominalwidthx or 0
local defaultwidth=private and private.data.defaultwidthx or 0
- if type(tab)=="string" then
- tab=lpegmatch(p_bytes,tab)
- end
+ tab={ byte(tab,1,#tab) }
x=0
y=0
width=false
@@ -10924,14 +11033,7 @@ do
end
index=index-1
local glyph=glyphs[index]
- if not glyph then
- glyphs[index]={
- segments=doshapes~=false and result or nil,
- boundingbox=boundingbox,
- width=width,
- name=charset[index],
- }
- else
+ if glyph then
glyph.segments=doshapes~=false and result or nil
glyph.boundingbox=boundingbox
if not glyph.width then
@@ -10940,6 +11042,19 @@ do
if charset and not glyph.name then
glyph.name=charset[index]
end
+ elseif doshapes then
+ glyphs[index]={
+ segments=result,
+ boundingbox=boundingbox,
+ width=width,
+ name=charset[index],
+ }
+ else
+ glyphs[index]={
+ boundingbox=boundingbox,
+ width=width,
+ name=charset[index],
+ }
end
if trace_charstrings then
report("width: %s",tostring(width))
@@ -10955,7 +11070,7 @@ end
local function readglobals(f,data)
local routines=readlengths(f)
for i=1,#routines do
- routines[i]=readstring(f,routines[i])
+ routines[i]=readbytetable(f,routines[i])
end
data.routines=routines
end
@@ -11013,7 +11128,7 @@ local function readlocals(f,data,dictionary)
setposition(f,header.offset+private.offset+subroutineoffset)
local subroutines=readlengths(f)
for i=1,#subroutines do
- subroutines[i]=readstring(f,subroutines[i])
+ subroutines[i]=readbytetable(f,subroutines[i])
end
dictionary.subroutines=subroutines
private.data.subroutines=nil
@@ -11131,6 +11246,7 @@ local function readfdselect(f,data,glyphs,doshapes,version)
end
for i=1,#charstrings do
parsecharstring(data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version)
+charstrings[i]=nil
end
resetcharstrings()
end
@@ -11638,18 +11754,18 @@ local readers=fonts.handlers.otf.readers
local streamreader=readers.streamreader
local setposition=streamreader.setposition
local getposition=streamreader.getposition
-local skipshort=streamreader.skipshort
-local skipbytes=streamreader.skip
local readushort=streamreader.readcardinal2
local readulong=streamreader.readcardinal4
+local readinteger=streamreader.readinteger1
local readshort=streamreader.readinteger2
-local readfword=readshort
local readstring=streamreader.readstring
local readtag=streamreader.readtag
local readbytes=streamreader.readbytes
local readfixed=streamreader.readfixed4
local read2dot14=streamreader.read2dot14
-local readinteger=streamreader.readinteger1
+local skipshort=streamreader.skipshort
+local skipbytes=streamreader.skip
+local readfword=readshort
local gsubhandlers={}
local gposhandlers={}
local lookupidoffset=-1
@@ -13168,57 +13284,61 @@ do
report("ignoring global kern table using gpos kern feature")
return
end
- report("adding global kern table as gpos feature %a",name)
setposition(f,datatable.offset)
local version=readushort(f)
local noftables=readushort(f)
- local kerns=setmetatableindex("table")
- for i=1,noftables do
- local version=readushort(f)
- local length=readushort(f)
- local coverage=readushort(f)
- local format=bit32.rshift(coverage,8)
- if format==0 then
- local nofpairs=readushort(f)
- local searchrange=readushort(f)
- local entryselector=readushort(f)
- local rangeshift=readushort(f)
- for i=1,nofpairs do
- kerns[readushort(f)][readushort(f)]=readfword(f)
- end
- elseif format==2 then
+ if noftables>1 then
+ report("adding global kern table as gpos feature %a",name)
+ local kerns=setmetatableindex("table")
+ for i=1,noftables do
+ local version=readushort(f)
+ local length=readushort(f)
+ local coverage=readushort(f)
+ local format=bit32.rshift(coverage,8)
+ if format==0 then
+ local nofpairs=readushort(f)
+ local searchrange=readushort(f)
+ local entryselector=readushort(f)
+ local rangeshift=readushort(f)
+ for i=1,nofpairs do
+ kerns[readushort(f)][readushort(f)]=readfword(f)
+ end
+ elseif format==2 then
+ else
+ end
+ end
+ local feature={ dflt={ dflt=true } }
+ if not features then
+ fontdata.features={ gpos={ [name]=feature } }
+ elseif not gposfeatures then
+ fontdata.features.gpos={ [name]=feature }
else
+ gposfeatures[name]=feature
end
- end
- local feature={ dflt={ dflt=true } }
- if not features then
- fontdata.features={ gpos={ [name]=feature } }
- elseif not gposfeatures then
- fontdata.features.gpos={ [name]=feature }
+ local sequences=fontdata.sequences
+ if not sequences then
+ sequences={}
+ fontdata.sequences=sequences
+ end
+ local nofsequences=#sequences+1
+ sequences[nofsequences]={
+ index=nofsequences,
+ name=name,
+ steps={
+ {
+ coverage=kerns,
+ format="kern",
+ },
+ },
+ nofsteps=1,
+ type="gpos_pair",
+ flags={ false,false,false,false },
+ order={ name },
+ features={ [name]=feature },
+ }
else
- gposfeatures[name]=feature
- end
- local sequences=fontdata.sequences
- if not sequences then
- sequences={}
- fontdata.sequences=sequences
+ report("ignoring empty kern table of feature %a",name)
end
- local nofsequences=#sequences+1
- sequences[nofsequences]={
- index=nofsequences,
- name=name,
- steps={
- {
- coverage=kerns,
- format="kern",
- },
- },
- nofsteps=1,
- type="gpos_pair",
- flags={ false,false,false,false },
- order={ name },
- features={ [name]=feature },
- }
end
function readers.gsub(f,fontdata,specification)
if specification.details then
@@ -21594,7 +21714,7 @@ end
otf.helpers=otf.helpers or {}
otf.helpers.txtdirstate=txtdirstate
otf.helpers.pardirstate=pardirstate
-local function featuresprocessor(head,font,attr)
+local function featuresprocessor(head,font,attr,direction)
local sequences=sequencelists[font]
if not sequencelists then
return head,false
@@ -21620,7 +21740,7 @@ local function featuresprocessor(head,font,attr)
if trace_steps then
checkstep(head)
end
- local rlmode=0
+ local initialrl=direction=="TRT" and -1 or 0
local done=false
local datasets=otf.dataset(tfmdata,font,attr)
local dirstack={}
@@ -21629,7 +21749,7 @@ local function featuresprocessor(head,font,attr)
local dataset=datasets[s]
local attribute=dataset[2]
local sequence=dataset[3]
- local rlparmode=0
+ local rlparmode=initialrl
local topstack=0
local typ=sequence.type
local gpossing=typ=="gpos_single" or typ=="gpos_pair"
@@ -21646,6 +21766,7 @@ local function featuresprocessor(head,font,attr)
end
elseif typ=="gsub_reversecontextchain" then
local start=find_node_tail(head)
+ local rlmode=0
while start do
local char=ischar(start,font)
if char then
@@ -21682,8 +21803,8 @@ local function featuresprocessor(head,font,attr)
end
end
else
- local start=head
- rlmode=0
+ local start=head
+ local rlmode=initialrl
if nofsteps==1 then
local step=steps[1]
local lookupcache=step.coverage
@@ -25156,8 +25277,8 @@ do
end
local setroutine=function(str,position,index,size)
local forward=position+tonumber(size)
- local stream=sub(str,position+1,forward)
- routines[index]=decrypt(stream,4330,4)
+ local stream=decrypt(sub(str,position+1,forward),4330,4)
+ routines[index]={ byte(stream,1,#stream) }
return forward
end
local setvector=function(str,position,name,size)