diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/font-ttf.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/font-ttf.lua | 465 |
1 files changed, 292 insertions, 173 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-ttf.lua b/Master/texmf-dist/tex/context/base/mkiv/font-ttf.lua index df08787f9a8..d2fe0917c53 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/font-ttf.lua +++ b/Master/texmf-dist/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 |