summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/font-ttf.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/font-ttf.lua')
-rw-r--r--tex/context/base/mkiv/font-ttf.lua465
1 files changed, 292 insertions, 173 deletions
diff --git a/tex/context/base/mkiv/font-ttf.lua b/tex/context/base/mkiv/font-ttf.lua
index df08787f9..d2fe0917c 100644
--- a/tex/context/base/mkiv/font-ttf.lua
+++ b/tex/context/base/mkiv/font-ttf.lua
@@ -35,26 +35,53 @@ if not modules then modules = { } end modules ['font-ttf'] = {
local next, type, unpack = next, type, unpack
local band, rshift = bit32.band, bit32.rshift
local sqrt, round = math.sqrt, math.round
-local char = string.char
+local char, rep = string.char, string.rep
local concat = table.concat
+local idiv = number.idiv
+local setmetatableindex = table.setmetatableindex
-local report = logs.reporter("otf reader","ttf")
+local report = logs.reporter("otf reader","ttf")
-local trace_deltas = false
+local trace_deltas = false
-local readers = fonts.handlers.otf.readers
-local streamreader = readers.streamreader
+local readers = fonts.handlers.otf.readers
+local streamreader = readers.streamreader
-local setposition = streamreader.setposition
-local getposition = streamreader.getposition
-local skipbytes = streamreader.skip
-local readbyte = streamreader.readcardinal1 -- 8-bit unsigned integer
-local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer
-local readulong = streamreader.readcardinal4 -- 24-bit unsigned integer
-local readchar = streamreader.readinteger1 -- 8-bit signed integer
-local readshort = streamreader.readinteger2 -- 16-bit signed integer
-local read2dot14 = streamreader.read2dot14 -- 16-bit signed fixed number with the low 14 bits of fraction (2.14) (F2DOT14)
-local readinteger = streamreader.readinteger1
+local setposition = streamreader.setposition
+local getposition = streamreader.getposition
+local skipbytes = streamreader.skip
+local readbyte = streamreader.readcardinal1 -- 8-bit unsigned integer
+local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer
+local readulong = streamreader.readcardinal4 -- 24-bit unsigned integer
+local readchar = streamreader.readinteger1 -- 8-bit signed integer
+local readshort = streamreader.readinteger2 -- 16-bit signed integer
+local read2dot14 = streamreader.read2dot14 -- 16-bit signed fixed number with the low 14 bits of fraction (2.14) (F2DOT14)
+local readinteger = streamreader.readinteger1
+local readcardinaltable = streamreader.readcardinaltable
+local readintegertable = streamreader.readintegertable
+
+directives.register("fonts.streamreader",function()
+
+ streamreader = utilities.streams
+
+ setposition = streamreader.setposition
+ getposition = streamreader.getposition
+ skipbytes = streamreader.skip
+ readbyte = streamreader.readcardinal1
+ readushort = streamreader.readcardinal2
+ readulong = streamreader.readcardinal4
+ readchar = streamreader.readinteger1
+ readshort = streamreader.readinteger2
+ read2dot14 = streamreader.read2dot14
+ readinteger = streamreader.readinteger1
+ readcardinaltable = streamreader.readcardinaltable
+ readintegertable = streamreader.readintegertable
+
+end)
+
+local short = 2
+local ushort = 2
+local ulong = 4
local helpers = readers.helpers
local gotodatatable = helpers.gotodatatable
@@ -90,22 +117,41 @@ local function mergecomposites(glyphs,shapes)
local yscale = matrix[4]
local xoffset = matrix[5]
local yoffset = matrix[6]
- for i=1,#subpoints do
- local p = subpoints[i]
- local x = p[1]
- local y = p[2]
- nofpoints = nofpoints + 1
- points[nofpoints] = {
- xscale * x + xrotate * y + xoffset,
- yscale * y + yrotate * x + yoffset,
- p[3]
- }
+ local count = #subpoints
+ if xscale == 1 and yscale == 1 and xrotate == 0 and yrotate == 0 then
+ for i=1,count do
+ local p = subpoints[i]
+ nofpoints = nofpoints + 1
+ points[nofpoints] = {
+ p[1] + xoffset,
+ p[2] + yoffset,
+ p[3]
+ }
+ end
+ else
+ for i=1,count do
+ local p = subpoints[i]
+ local x = p[1]
+ local y = p[2]
+ nofpoints = nofpoints + 1
+ points[nofpoints] = {
+ xscale * x + xrotate * y + xoffset,
+ yscale * y + yrotate * x + yoffset,
+ p[3]
+ }
+ end
end
- for i=1,#subcontours do
+ local subcount = #subcontours
+ if subcount == 1 then
nofcontours = nofcontours + 1
- contours[nofcontours] = offset + subcontours[i]
+ contours[nofcontours] = offset + subcontours[1]
+ else
+ for i=1,#subcontours do
+ nofcontours = nofcontours + 1
+ contours[nofcontours] = offset + subcontours[i]
+ end
end
- offset = offset + #subpoints
+ offset = offset + count
else
report("missing contours composite %s, component %s of %s, glyph %s",index,i,#components,subindex)
end
@@ -116,7 +162,8 @@ local function mergecomposites(glyphs,shapes)
return contours, points
end
- for index=1,#glyphs do
+-- for index=1,#glyphs do
+ for index=0,#glyphs-1 do
local shape = shapes[index]
if shape then
local components = shape.components
@@ -128,7 +175,7 @@ local function mergecomposites(glyphs,shapes)
end
-local function readnothing(f,nofcontours)
+local function readnothing(f)
return {
type = "nothing",
}
@@ -259,7 +306,8 @@ end
local quadratic = false
local function contours2outlines_normal(glyphs,shapes) -- maybe accept the bbox overhead
- for index=1,#glyphs do
+-- for index=1,#glyphs do
+ for index=0,#glyphs-1 do
local shape = shapes[index]
if shape then
local glyph = glyphs[index]
@@ -271,7 +319,8 @@ local function contours2outlines_normal(glyphs,shapes) -- maybe accept the bbox
local nofsegments = 0
glyph.segments = segments
if nofcontours > 0 then
- local px, py = 0, 0 -- we could use these in calculations which saves a copy
+ local px = 0
+ local py = 0
local first = 1
for i=1,nofcontours do
local last = contours[i]
@@ -299,15 +348,20 @@ local function contours2outlines_normal(glyphs,shapes) -- maybe accept the bbox
end
control_pt = first_pt
end
- local x, y = first_pt[1], first_pt[2]
+ local x = first_pt[1]
+ local y = first_pt[2]
if not done then
- xmin, ymin, xmax, ymax = x, y, x, y
+ xmin = x
+ ymin = y
+ xmax = x
+ ymax = y
done = true
end
nofsegments = nofsegments + 1
segments[nofsegments] = { x, y, "m" } -- "moveto"
if not quadratic then
- px, py = x, y
+ px = x
+ py = y
end
local previous_pt = first_pt
for i=first,last do
@@ -327,8 +381,10 @@ local function contours2outlines_normal(glyphs,shapes) -- maybe accept the bbox
control_pt = current_pt
end
elseif current_on then
- local x1, y1 = control_pt[1], control_pt[2]
- local x2, y2 = current_pt[1], current_pt[2]
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
+ local x2 = current_pt[1]
+ local y2 = current_pt[2]
nofsegments = nofsegments + 1
if quadratic then
segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto"
@@ -338,8 +394,10 @@ local function contours2outlines_normal(glyphs,shapes) -- maybe accept the bbox
end
control_pt = false
else
- local x2, y2 = (previous_pt[1]+current_pt[1])/2, (previous_pt[2]+current_pt[2])/2
- local x1, y1 = control_pt[1], control_pt[2]
+ local x2 = (previous_pt[1]+current_pt[1])/2
+ local y2 = (previous_pt[2]+current_pt[2])/2
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
nofsegments = nofsegments + 1
if quadratic then
segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto"
@@ -355,14 +413,17 @@ local function contours2outlines_normal(glyphs,shapes) -- maybe accept the bbox
-- we're already done, probably a simple curve
else
nofsegments = nofsegments + 1
- local x2, y2 = first_pt[1], first_pt[2]
+ local x2 = first_pt[1]
+ local y2 = first_pt[2]
if not control_pt then
segments[nofsegments] = { x2, y2, "l" } -- "lineto"
elseif quadratic then
- local x1, y1 = control_pt[1], control_pt[2]
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto"
else
- local x1, y1 = control_pt[1], control_pt[2]
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2)
segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto"
-- px, py = x2, y2
@@ -379,7 +440,8 @@ local function contours2outlines_normal(glyphs,shapes) -- maybe accept the bbox
end
local function contours2outlines_shaped(glyphs,shapes,keepcurve)
- for index=1,#glyphs do
+-- for index=1,#glyphs do
+ for index=0,#glyphs-1 do
local shape = shapes[index]
if shape then
local glyph = glyphs[index]
@@ -425,7 +487,8 @@ local function contours2outlines_shaped(glyphs,shapes,keepcurve)
end
control_pt = first_pt
end
- local x, y = first_pt[1], first_pt[2]
+ local x = first_pt[1]
+ local y = first_pt[2]
if not done then
xmin, ymin, xmax, ymax = x, y, x, y
done = true
@@ -438,7 +501,8 @@ local function contours2outlines_shaped(glyphs,shapes,keepcurve)
segments[nofsegments] = { x, y, "m" } -- "moveto"
end
if not quadratic then
- px, py = x, y
+ px = x
+ py = y
end
local previous_pt = first_pt
for i=first,last do
@@ -448,7 +512,8 @@ local function contours2outlines_shaped(glyphs,shapes,keepcurve)
if previous_on then
if current_on then
-- both normal points
- local x, y = current_pt[1], current_pt[2]
+ local x = current_pt[1]
+ local y = current_pt[2]
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 keepcurve then
@@ -456,14 +521,17 @@ local function contours2outlines_shaped(glyphs,shapes,keepcurve)
segments[nofsegments] = { x, y, "l" } -- "lineto"
end
if not quadratic then
- px, py = x, y
+ px = x
+ py = y
end
else
control_pt = current_pt
end
elseif current_on then
- local x1, y1 = control_pt[1], control_pt[2]
- local x2, y2 = current_pt[1], current_pt[2]
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
+ local x2 = current_pt[1]
+ local y2 = current_pt[2]
if quadratic 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
@@ -486,8 +554,10 @@ local function contours2outlines_shaped(glyphs,shapes,keepcurve)
end
control_pt = false
else
- local x2, y2 = (previous_pt[1]+current_pt[1])/2, (previous_pt[2]+current_pt[2])/2
- local x1, y1 = control_pt[1], control_pt[2]
+ local x2 = (previous_pt[1]+current_pt[1])/2
+ local y2 = (previous_pt[2]+current_pt[2])/2
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
if quadratic 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
@@ -520,8 +590,10 @@ local function contours2outlines_shaped(glyphs,shapes,keepcurve)
segments[nofsegments] = { first_pt[1], first_pt[2], "l" } -- "lineto"
end
else
- local x1, y1 = control_pt[1], control_pt[2]
- local x2, y2 = first_pt[1], first_pt[2]
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
+ local x2 = first_pt[1]
+ local y2 = first_pt[2]
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 quadratic then
@@ -558,8 +630,13 @@ end
local c_zero = char(0)
local s_zero = char(0,0)
+-- local shorthash = setmetatableindex(function(t,k)
+-- t[k] = char(band(rshift(k,8),0xFF),band(k,0xFF)) return t[k]
+-- end)
+
local function toushort(n)
return char(band(rshift(n,8),0xFF),band(n,0xFF))
+ -- return shorthash[n]
end
local function toshort(n)
@@ -567,125 +644,152 @@ local function toshort(n)
n = n + 0x10000
end
return char(band(rshift(n,8),0xFF),band(n,0xFF))
+ -- return shorthash[n]
end
-- todo: we can reuse result, xpoints and ypoints
+local chars = setmetatableindex(function(t,k)
+ for i=0,255 do local v = char(i) t[i] = v end return t[k]
+end)
+
local function repackpoints(glyphs,shapes)
local noboundingbox = { 0, 0, 0, 0 }
local result = { } -- reused
- for index=1,#glyphs do
+ local xpoints = { } -- reused
+ local ypoints = { } -- reused
+ for index=0,#glyphs-1 do
local shape = shapes[index]
if shape then
local r = 0
local glyph = glyphs[index]
- if false then -- shape.type == "composite"
- -- we merged them
- else
- local contours = shape.contours
- local nofcontours = contours and #contours or 0
- local boundingbox = glyph.boundingbox or noboundingbox
- r = r + 1 result[r] = toshort(nofcontours)
- r = r + 1 result[r] = toshort(boundingbox[1]) -- xmin
- r = r + 1 result[r] = toshort(boundingbox[2]) -- ymin
- r = r + 1 result[r] = toshort(boundingbox[3]) -- xmax
- r = r + 1 result[r] = toshort(boundingbox[4]) -- ymax
- if nofcontours > 0 then
- for i=1,nofcontours do
- r = r + 1 result[r] = toshort(contours[i]-1)
- end
- r = r + 1 result[r] = s_zero -- no instructions
- local points = shape.points
- local currentx = 0
- local currenty = 0
- local xpoints = { }
- local ypoints = { }
- local x = 0
- local y = 0
- local lastflag = nil
- local nofflags = 0
- for i=1,#points do
- local pt = points[i]
- local px = pt[1]
- local py = pt[2]
- local fl = pt[3] and 0x01 or 0x00
- if px == currentx then
- fl = fl + 0x10
+ local contours = shape.contours
+ local nofcontours = contours and #contours or 0
+ local boundingbox = glyph.boundingbox or noboundingbox
+ r = r + 1 result[r] = toshort(nofcontours)
+ r = r + 1 result[r] = toshort(boundingbox[1]) -- xmin
+ r = r + 1 result[r] = toshort(boundingbox[2]) -- ymin
+ r = r + 1 result[r] = toshort(boundingbox[3]) -- xmax
+ r = r + 1 result[r] = toshort(boundingbox[4]) -- ymax
+ if nofcontours > 0 then
+ for i=1,nofcontours do
+ r = r + 1 result[r] = toshort(contours[i]-1)
+ end
+ r = r + 1 result[r] = s_zero -- no instructions
+ local points = shape.points
+ local currentx = 0
+ local currenty = 0
+ -- local xpoints = { }
+ -- local ypoints = { }
+ local x = 0
+ local y = 0
+ local lastflag = nil
+ local nofflags = 0
+ for i=1,#points do
+ local pt = points[i]
+ local px = pt[1]
+ local py = pt[2]
+ local fl = pt[3] and 0x01 or 0x00
+ if px == currentx then
+ fl = fl + 0x10
+ else
+ local dx = round(px - currentx)
+ x = x + 1
+ if dx < -255 or dx > 255 then
+ xpoints[x] = toshort(dx)
+ elseif dx < 0 then
+ fl = fl + 0x02
+ -- xpoints[x] = char(-dx)
+ xpoints[x] = chars[-dx]
+ elseif dx > 0 then
+ fl = fl + 0x12
+ -- xpoints[x] = char(dx)
+ xpoints[x] = chars[dx]
else
- local dx = round(px - currentx)
- if dx < -255 or dx > 255 then
- x = x + 1 xpoints[x] = toshort(dx)
- elseif dx < 0 then
- fl = fl + 0x02
- x = x + 1 xpoints[x] = char(-dx)
- elseif dx > 0 then
- fl = fl + 0x12
- x = x + 1 xpoints[x] = char(dx)
- else
- fl = fl + 0x02
- x = x + 1 xpoints[x] = c_zero
- end
+ fl = fl + 0x02
+ xpoints[x] = c_zero
end
- if py == currenty then
- fl = fl + 0x20
+ end
+ if py == currenty then
+ fl = fl + 0x20
+ else
+ local dy = round(py - currenty)
+ y = y + 1
+ if dy < -255 or dy > 255 then
+ ypoints[y] = toshort(dy)
+ elseif dy < 0 then
+ fl = fl + 0x04
+ -- ypoints[y] = char(-dy)
+ ypoints[y] = chars[-dy]
+ elseif dy > 0 then
+ fl = fl + 0x24
+ -- ypoints[y] = char(dy)
+ ypoints[y] = chars[dy]
else
- local dy = round(py - currenty)
- if dy < -255 or dy > 255 then
- y = y + 1 ypoints[y] = toshort(dy)
- elseif dy < 0 then
- fl = fl + 0x04
- y = y + 1 ypoints[y] = char(-dy)
- elseif dy > 0 then
- fl = fl + 0x24
- y = y + 1 ypoints[y] = char(dy)
- else
- fl = fl + 0x04
- y = y + 1 ypoints[y] = c_zero
- end
- end
- currentx = px
- currenty = py
- if lastflag == fl then
- nofflags = nofflags + 1
- else -- if > 255
- if nofflags == 1 then
- r = r + 1 result[r] = char(lastflag)
- elseif nofflags == 2 then
- r = r + 1 result[r] = char(lastflag,lastflag)
- elseif nofflags > 2 then
- lastflag = lastflag + 0x08
- r = r + 1 result[r] = char(lastflag,nofflags-1)
- end
- nofflags = 1
- lastflag = fl
+ fl = fl + 0x04
+ ypoints[y] = c_zero
end
end
- if nofflags == 1 then
- r = r + 1 result[r] = char(lastflag)
- elseif nofflags == 2 then
- r = r + 1 result[r] = char(lastflag,lastflag)
- elseif nofflags > 2 then
- lastflag = lastflag + 0x08
- r = r + 1 result[r] = char(lastflag,nofflags-1)
+ currentx = px
+ currenty = py
+ if lastflag == fl then
+ nofflags = nofflags + 1
+ else -- if > 255
+ if nofflags == 1 then
+ -- r = r + 1 result[r] = char(lastflag)
+ r = r + 1 result[r] = chars[lastflag]
+ elseif nofflags == 2 then
+ r = r + 1 result[r] = char(lastflag,lastflag)
+ elseif nofflags > 2 then
+ lastflag = lastflag + 0x08
+ r = r + 1 result[r] = char(lastflag,nofflags-1)
+ end
+ nofflags = 1
+ lastflag = fl
end
- r = r + 1 result[r] = concat(xpoints)
- r = r + 1 result[r] = concat(ypoints)
end
+ if nofflags == 1 then
+ -- r = r + 1 result[r] = char(lastflag)
+ r = r + 1 result[r] = chars[lastflag]
+ elseif nofflags == 2 then
+ r = r + 1 result[r] = char(lastflag,lastflag)
+ elseif nofflags > 2 then
+ lastflag = lastflag + 0x08
+ r = r + 1 result[r] = char(lastflag,nofflags-1)
+ end
+ -- r = r + 1 result[r] = concat(xpoints)
+ -- r = r + 1 result[r] = concat(ypoints)
+ r = r + 1 result[r] = concat(xpoints,"",1,x)
+ r = r + 1 result[r] = concat(ypoints,"",1,y)
end
- glyph.stream = concat(result,"",1,r)
- else
- -- fatal
+ -- can be helper or delegated to user
+ local stream = concat(result,"",1,r)
+ local length = #stream
+ local padding = idiv(length+3,4) * 4 - length
+ if padding > 0 then
+ -- stream = stream .. rep("\0",padding) -- can be a repeater
+ if padding == 1 then
+ padding = "\0"
+ elseif padding == 2 then
+ padding = "\0\0"
+ else
+ padding = "\0\0\0"
+ end
+ padding = stream .. padding
+ end
+ glyph.stream = stream
end
end
end
-- end of converter
+local flags = { }
+
local function readglyph(f,nofcontours) -- read deltas here, saves space
- local points = { }
- local contours = { }
- local instructions = { }
- local flags = { }
+ local points = { }
+ -- local instructions = { }
+ local contours = { } -- readintegertable(f,nofcontours,short)
for i=1,nofcontours do
contours[i] = readshort(f) + 1
end
@@ -699,9 +803,15 @@ local function readglyph(f,nofcontours) -- read deltas here, saves space
local flag = readbyte(f)
flags[i] = flag
if band(flag,0x08) ~= 0 then
- for j=1,readbyte(f) do
+ local n = readbyte(f)
+ if n == 1 then
i = i + 1
flags[i] = flag
+ else
+ for j=1,n do
+ i = i + 1
+ flags[i] = flag
+ end
end
end
i = i + 1
@@ -710,16 +820,16 @@ local function readglyph(f,nofcontours) -- read deltas here, saves space
-- can be repeated
local x = 0
for i=1,nofpoints do
- local flag = flags[i]
- local short = band(flag,0x02) ~= 0
- local same = band(flag,0x10) ~= 0
- if short then
- if same then
+ local flag = flags[i]
+ -- local short = band(flag,0x04) ~= 0
+ -- local same = band(flag,0x20) ~= 0
+ if band(flag,0x02) ~= 0 then
+ if band(flag,0x10) ~= 0 then
x = x + readbyte(f)
else
x = x - readbyte(f)
end
- elseif same then
+ elseif band(flag,0x10) ~= 0 then
-- copy
else
x = x + readshort(f)
@@ -728,16 +838,16 @@ local function readglyph(f,nofcontours) -- read deltas here, saves space
end
local y = 0
for i=1,nofpoints do
- local flag = flags[i]
- local short = band(flag,0x04) ~= 0
- local same = band(flag,0x20) ~= 0
- if short then
- if same then
+ local flag = flags[i]
+ -- local short = band(flag,0x04) ~= 0
+ -- local same = band(flag,0x20) ~= 0
+ if band(flag,0x04) ~= 0 then
+ if band(flag,0x20) ~= 0 then
y = y + readbyte(f)
else
y = y - readbyte(f)
end
- elseif same then
+ elseif band(flag,0x20) ~= 0 then
-- copy
else
y = y + readshort(f)
@@ -833,7 +943,7 @@ local function readcomposite(f)
if band(flags,0x0100) ~= 0 then
instructions = true
end
- if not band(flags,0x0020) ~= 0 then -- f_more
+ if band(flags,0x0020) == 0 then -- f_more
break
end
end
@@ -858,21 +968,27 @@ function readers.loca(f,fontdata,specification)
-- locations are relative to the glypdata table (glyf)
local offset = fontdata.tables.glyf.offset
local format = fontdata.fontheader.indextolocformat
+ local profile = fontdata.maximumprofile
+ local nofglyphs = profile and profile.nofglyphs
local locations = { }
setposition(f,datatable.offset)
if format == 1 then
- local nofglyphs = datatable.length/4 - 2
+ if not nofglyphs then
+ nofglyphs = idiv(datatable.length,4) - 1
+ end
for i=0,nofglyphs do
locations[i] = offset + readulong(f)
end
fontdata.nofglyphs = nofglyphs
else
- local nofglyphs = datatable.length/2 - 2
+ if not nofglyphs then
+ nofglyphs = idiv(datatable.length,2) - 1
+ end
for i=0,nofglyphs do
locations[i] = offset + readushort(f) * 2
end
- fontdata.nofglyphs = nofglyphs
end
+ fontdata.nofglyphs = nofglyphs
fontdata.locations = locations
end
end
@@ -888,15 +1004,16 @@ function readers.glyf(f,fontdata,specification) -- part goes to cff module
local filesize = fontdata.filesize
local nothing = { 0, 0, 0, 0 }
local shapes = { }
- local loadshapes = specification.shapes or specification.instance
- for index=0,nofglyphs do
+ local loadshapes = specification.shapes or specification.instance or specification.streams
+ for index=0,nofglyphs-1 do
local location = locations[index]
+ local length = locations[index+1] - location
if location >= filesize then
report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1)
fontdata.nofglyphs = index - 1
fontdata.badfont = true
break
- elseif location > 0 then
+ elseif length > 0 then
setposition(f,location)
local nofcontours = readshort(f)
glyphs[index].boundingbox = {
@@ -908,7 +1025,7 @@ function readers.glyf(f,fontdata,specification) -- part goes to cff module
if not loadshapes then
-- save space
elseif nofcontours == 0 then
- shapes[index] = readnothing(f,nofcontours)
+ shapes[index] = readnothing(f)
elseif nofcontours > 0 then
shapes[index] = readglyph(f,nofcontours)
else
@@ -916,7 +1033,7 @@ function readers.glyf(f,fontdata,specification) -- part goes to cff module
end
else
if loadshapes then
- shapes[index] = { }
+ shapes[index] = readnothing(f)
end
glyphs[index].boundingbox = nothing
end
@@ -933,7 +1050,13 @@ function readers.glyf(f,fontdata,specification) -- part goes to cff module
contours2outlines_shaped(glyphs,shapes,specification.shapes)
end
elseif specification.shapes then
- contours2outlines_normal(glyphs,shapes)
+ if specification.streams then
+ repackpoints(glyphs,shapes)
+ else
+ contours2outlines_normal(glyphs,shapes)
+ end
+ elseif specification.streams then
+ repackpoints(glyphs,shapes)
end
end
end
@@ -1234,10 +1357,6 @@ function readers.gvar(f,fontdata,specification,glyphdata,shapedata)
end
end
if shape.type == "glyph" then
--- if glyph.name == "u1f31d" then
--- if glyph.unicode == 127773 then
--- inspect(deltas)
--- end
applyaxis(glyph,shape,deltas,dowidth)
else
-- todo: args_are_xy_values mess .. i have to be really bored