From 0da55392b876cef55845157c4bfb8244d84c6450 Mon Sep 17 00:00:00 2001
From: Hans Hagen <pragma@wxs.nl>
Date: Wed, 1 Mar 2017 13:51:17 +0100
Subject: 2017-03-01 13:47:00

---
 tex/generic/context/luatex/luatex-fonts-merged.lua | 715 ++++++++++++---------
 1 file changed, 418 insertions(+), 297 deletions(-)

(limited to 'tex/generic')

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)
-- 
cgit v1.2.3