texlive[52705] Build/source/texk/web2c/mfluadir: updated mflua.lua &

commits+lscarso at tug.org commits+lscarso at tug.org
Sat Nov 9 18:26:00 CET 2019


Revision: 52705
          http://tug.org/svn/texlive?view=revision&revision=52705
Author:   lscarso
Date:     2019-11-09 18:26:00 +0100 (Sat, 09 Nov 2019)
Log Message:
-----------
updated mflua.lua & ttx backend; stubs for  shellenabledp restrictedshell shell_cmd_is_allowed (mflua part).

Modified Paths:
--------------
    trunk/Build/source/texk/web2c/mfluadir/mfluac.c
    trunk/Build/source/texk/web2c/mfluadir/mfluac.h
    trunk/Build/source/texk/web2c/mfluadir/mfluaextra.h
    trunk/Build/source/texk/web2c/mfluadir/mfluatrap/mflua.lua
    trunk/Build/source/texk/web2c/mfluadir/mfluatrap/mflua_ttx_backend.lua

Modified: trunk/Build/source/texk/web2c/mfluadir/mfluac.c
===================================================================
--- trunk/Build/source/texk/web2c/mfluadir/mfluac.c	2019-11-09 17:25:12 UTC (rev 52704)
+++ trunk/Build/source/texk/web2c/mfluadir/mfluac.c	2019-11-09 17:26:00 UTC (rev 52705)
@@ -13,6 +13,11 @@
 #if defined(JIT)
 #include <luajit.h>
 #endif
+
+/* See  shell_cmd_is_allowed below */
+shellenabledp = 1;
+restrictedshell = 0;
+
 /**************************************************************/
 /*                                                            */
 /* private functions                                          */
@@ -1414,3 +1419,6 @@
   }
   return 0;
 }
+
+/* TODO: check if shell_cmd_is_allowed make se sense */
+int shell_cmd_is_allowed(const char *cmd, char **safecmd, char **cmdname){return 1;}

Modified: trunk/Build/source/texk/web2c/mfluadir/mfluac.h
===================================================================
--- trunk/Build/source/texk/web2c/mfluadir/mfluac.h	2019-11-09 17:25:12 UTC (rev 52704)
+++ trunk/Build/source/texk/web2c/mfluadir/mfluac.h	2019-11-09 17:26:00 UTC (rev 52705)
@@ -46,6 +46,11 @@
 extern int mfluaPREmakeellipse(integer, integer, integer, integer, integer, integer);
 extern int mfluaPOSTmakeellipse(integer, integer, integer, integer, integer, integer);
 
+/* TODO: check if  shell_cmd_is_allowed makes sense */
+extern int shellenabledp;
+extern int restrictedshell;
+extern int shell_cmd_is_allowed(const char *, char **, char **);
+
 #include <lauxlib.h>
 extern int luaopen_kpse(lua_State * L);
 

Modified: trunk/Build/source/texk/web2c/mfluadir/mfluaextra.h
===================================================================
--- trunk/Build/source/texk/web2c/mfluadir/mfluaextra.h	2019-11-09 17:25:12 UTC (rev 52704)
+++ trunk/Build/source/texk/web2c/mfluadir/mfluaextra.h	2019-11-09 17:26:00 UTC (rev 52705)
@@ -21,4 +21,5 @@
 #define INPUT_FORMAT kpse_mf_format
 #define INI_PROGRAM "inimflua"
 #define VIR_PROGRAM "virmflua"
-#define MFLua
\ No newline at end of file
+#define MFLua
+

Modified: trunk/Build/source/texk/web2c/mfluadir/mfluatrap/mflua.lua
===================================================================
--- trunk/Build/source/texk/web2c/mfluadir/mfluatrap/mflua.lua	2019-11-09 17:25:12 UTC (rev 52704)
+++ trunk/Build/source/texk/web2c/mfluadir/mfluatrap/mflua.lua	2019-11-09 17:26:00 UTC (rev 52705)
@@ -441,7 +441,6 @@
 local function print_two(x,y) -- {prints `|(x,y)|'}
  local res 
  -- debug 
- -- print("print_two(x,y)",x,y)
  res = '(' .. print_scaled(x) .. ',' .. print_scaled(y) .. ')'
  return res
 end
@@ -1544,12 +1543,12 @@
    if (#bezier_octant_contour == 0) then
       local _t = {} 
       for i,v in ipairs(bezier_octant_I) do _t[i] = v end
-      bezier_octant_contour[1] = _t
+      bezier_octant_contour[1] = _t; 
    else
       local _cnt=0 
       for i,v in ipairs(bezier_octant_contour) do _cnt=_cnt+#v end
       local _t = {} 
-      for i,v in ipairs(bezier_octant_I) do if i>_cnt then _t[#_t+1] = v end end
+      for i,v in ipairs(bezier_octant_I) do if i>_cnt then _t[#_t+1] = v; end end
       bezier_octant_contour[#bezier_octant_contour+1] = _t
    end
    mflua.do_add_to.bezier_octant_contour = bezier_octant_contour 
@@ -1754,7 +1753,7 @@
 	   end_loop_2=true 
 	else    
 	   bezier_contour['p'] = print_two_true(x_coord(p),y_coord(p),octant);
-           bezier_contour['control1'] = print_two_true(right_x(p),right_y(p),octant)
+           bezier_contour['control1'] = print_two_true(right_x(p),right_y(p),octant) 
            bezier_contour['control2'] = print_two_true(left_x(q),left_y(q),octant)
 	   bezier_contour['q'] =  print_two_true(x_coord(q),y_coord(q),octant)
 	   beziers_contour[#beziers_contour+1] = bezier_contour

Modified: trunk/Build/source/texk/web2c/mfluadir/mfluatrap/mflua_ttx_backend.lua
===================================================================
--- trunk/Build/source/texk/web2c/mfluadir/mfluatrap/mflua_ttx_backend.lua	2019-11-09 17:25:12 UTC (rev 52704)
+++ trunk/Build/source/texk/web2c/mfluadir/mfluatrap/mflua_ttx_backend.lua	2019-11-09 17:26:00 UTC (rev 52705)
@@ -1,21 +1,26 @@
---
---
--- Experimental ttx back end
---
---
-
-
 local format = string.format
 local table_insert = table.insert
+local table_remove = table.remove
 local table_concat = table.concat
+local table_sort = table.sort
 local print_int    = mflua.MF.print_int
 local abs = math.abs
+local math_floor = math.floor
+local math_tointeger = math.tointeger or math.floor
 
+local print_scaled = mflua.MF.print_scaled
+local unity = mflua.MF.unity
+
+local GF = mflua.GF
+local GF_chars = GF.chars
+
 local ttx	= {}
 local xmlstream = {}
-
 local scrt	= {} -- general table for local use
 
+
+
+
 local function DUMP(t)
    if type(t) == 'table' then 
       print("table",#table)
@@ -23,7 +28,65 @@
    end
 end
 
+local function print_err(msg)
+   print(format("! ttx backend: %s",tostring(msg)))
+end
 
+local function tointeger(n)
+   return math_tointeger(n)
+end
+
+local function _normalize(w,n)
+   n = tonumber(n) or 5
+   n = math_floor(abs(n))
+   n = (n<25 and n) or 24
+   local fmt = format("%%0.%sf", n)
+   local W = tonumber(format(fmt,w))
+   nx = tointeger(W)
+   if nx==W then
+      return nx
+   else
+      return w
+   end
+end
+
+local function normalize(w,n)
+   return print_scaled(w)
+end
+
+local function _normalize_and_simplify(w,n)
+   n = tonumber(n) or 2
+   n = math_floor(abs(n))
+   n = (n<25 and n) or 24
+   local fmt = format("%%0.%sf", n)
+   local W = tonumber(format(fmt,w))
+   nx = tointeger(W)
+   if nx==W then
+      return nx
+   else
+      return W
+   end
+end
+
+local function normalize_and_simplify(w,n)
+   return print_scaled(w)
+end
+
+
+local function toscaled(n)
+   return tonumber(format("%0.0f",n*unity))
+end
+
+local function table_sorted(t)
+   if type(t)=='table' then 
+     table_sort(t) 
+     return t
+   else 
+    return {t}
+   end
+end
+
+
 local xml_comment                      = 'c'
 local xml_processing_instruction       = 'p'
 local xml_element                      = 'e'
@@ -153,6 +216,38 @@
    return res
 end
 
+--
+-- remove the first xml_element inserted
+-- with name. Return the element removed
+-- false otherwise
+local function remove_child(t,name)
+   for i=1,#t do
+      if t[i][0]==xml_element and t[i][1]==tostring(name) then
+	 return table.remove(t,i)
+      end
+   end
+   return false
+end
+
+--
+-- call remove_child on all elements of
+-- names 
+
+local function remove_children(t,names)
+   local res = {}
+   local name, r
+   for _,v in pairs(names) do
+      name = tostring(v)
+      r = remove_child(t,name)
+      if r then
+	 table_insert(res,r)
+      end
+   end
+   return res
+end
+
+
+
 --------------------------------------------------------------------------------
 --
 -- Serialization
@@ -189,7 +284,7 @@
      end
    end
    for j=1,#_t do 
-      elem[#elem+1]=format([[ %s="%s"]],_t[j],toattr(t[_t[j]])) 
+      elem[#elem+1]=format([[ %s="%s"]],_t[j],toattr(t[_t[j]]))  
    end
    elem[#elem+1]='?>'
    elem[#elem+1]="\n"
@@ -247,7 +342,9 @@
       elem[#elem+1]=format([[ %s="%s"]],_t[j],toattr(t[_t[j]])) --
    end
    elem[#elem+1]='>'
+   if type(t[2])~= 'string' then 
    elem[#elem+1]="\n"
+   end
    xmlstream[#xmlstream+1] = table_concat(elem)
    elem = {}
    for j=2,#t do
@@ -281,11 +378,18 @@
 local name       
 local cmap       
 local post       
-local CFF, CFFFont, Private   -- handy to have        
+local CFF, CFFFont, Private   -- only a single CFFFont, for the moment
 local FFTM       
 local GDEF  
 local hmtx       
 
+-- For variable fonts
+local extranames -- handy to have 
+local CFF2
+local HVAR,VarStore,VarRegionList,Regions,VarRegionAxis,VarData,AdvWidthMap
+local fvar
+
+
 -- Important, child of CFFFont 
 local CharStrings
 
@@ -325,6 +429,11 @@
     table_insert(CFF,new_element(name, {['value']=tostring(value)}))
 end
 
+local function put_CFF2(name,value)
+    table_insert(CFF2,new_element(name, {['value']=tostring(value)}))
+end
+
+
 local function put_CFFFont(name,value)
     table_insert(CFFFont,new_element(name, {['value']=tostring(value)}))
 end
@@ -371,11 +480,6 @@
 
 
 
---for i=1,255 do table_insert(GlyphOrder,new_element('GlyphID', {['id']=i, ['name']="uni"..tostring(i)})) end
---local ttFont = dofile('ttx_sample.lua')
---savettfont(ttFont)
-
-
 --------------------------------------------------------------------------------
 --
 -- Create & save xml font
@@ -382,7 +486,62 @@
 --------------------------------------------------------------------------------
 
 local function checkall(tfm)
-   -- several checks here
+   -- several checks & fixes here
+   local gf_chars = {}
+   if GF then
+      for k,_ in pairs(GF.chars) do
+	 if type(k)=='number' then
+	    table_insert(gf_chars,k)
+	 end
+      end
+      table_sort(gf_chars)
+   end
+   --
+   -- fix head
+   if ttx.userdata.update_head and
+   type(ttx.userdata.update_head)=='function' then
+      ttx.userdata.update_head(tfm)
+   elseif GF then 
+      remove_children(head,{'xMin', 'xMax','yMin','yMax','modified'})
+      put_head('xMin',GF_chars.min_m);
+      put_head('yMin',GF_chars.min_n);
+      put_head('xMax',GF_chars.max_m-GF_chars.min_m+1);
+      put_head('yMax',GF_chars.max_n-GF_chars.min_n+1);
+      -- Date is UTC
+      put_head('modified',os.date("!%c"));
+   end
+   --
+   -- fix CFFFont, only one for the moment
+   if ttx.userdata.update_CFFFont and
+   type(ttx.userdata.update_CFFFont)=='function' then
+      ttx.userdata.update_CFFFont(CFFont)
+   elseif GF then 
+      remove_child(CFFFont,'FontBBox')
+      put_CFFFont('FontBBox',
+		  format("%s %s %s %s",GF_chars.min_m,GF_chars.min_n,
+			 GF_chars.max_m-GF_chars.min_m+1,
+			 GF_chars.max_n-GF_chars.min_n+1))
+   end
+   --
+   -- fix OS_2
+   if ttx.userdata.update_OS_2 and
+   type(ttx.userdata.update_OS_2)=='function' then
+      ttx.userdata.update_CFFFont(OS_2)
+   elseif mflua.chartable then
+      local design_size=tonumber ( print_scaled(MFbuiltin.designsize()) ) --pt 
+      local emsize = ttx.emsize or 1000
+      local avgx = 0
+      local avgx_cnt=0
+      for k,v in pairs(mflua.chartable) do
+	 if tonumber(v.char_wd) > 0 then 
+	    avgx = tonumber(v.char_wd)*emsize/design_size+avgx
+	    avgx_cnt=avgx_cnt+1
+	 end
+      end
+      avgx = math_floor(avgx/avgx_cnt+0.5)
+      remove_child(OS_2,'xAvgCharWidth')
+      put_OS_2('xAvgCharWidth',avgx)
+   end
    -- fix cmap0
    -- local t = {}
    -- for k,_ in pairs(scrt.cmap.rawcmap0) do t[#t+1]=k end
@@ -427,7 +586,7 @@
 end
 
 local function setup(tfm,index,chartable)
-   -- Default emsize is 1000 of CFF
+   -- Default emsize is 1000 for CFF and  CFF2
    ttx.emsize = ttx.emsize or 1000
 
    scrt.font_space = tfm.printfloat(ttx.emsize*(tfm.font.space),3)
@@ -442,14 +601,27 @@
    name       = new_element('name')
    cmap       = new_element('cmap')
    post       = new_element('post')
-   CFF        = new_element('CFF')
+   if ttx.cffver==1 then 
+      CFF        = new_element('CFF')
+      CFF2       = nil
+   elseif ttx.cffver==2 then
+      CFF2       = new_element('CFF2')
+      CFF        = nil
+   end      
    -- FFTM       = new_element('FFTM') --FontForge TimeStamp table
    GDEF       = new_element('GDEF')
+   if ttx.cffver==2 then
+      HVAR       = new_element('HVAR')
+   end
    hmtx       = new_element('hmtx')
 
    -- handy 
    panose     = new_element('panose')
-   CFFFont    = new_element('CFFFont',{['name']="SourceCode"})
+   if ttx.cffver==1 then 
+      CFFFont    = new_element('CFFFont',{['name']= (ttx.userdata.CFFFont['FullName'] or "mfluatestfont"..tostring(math.random(0,1000000)))})
+   elseif ttx.cffver==2 then
+      CFFFont    = new_element('CFFFont',{['name']="CFF2Font"})
+   end
    Private    = new_element('Private')
 
    CharStrings= new_element('CharStrings')
@@ -462,9 +634,43 @@
    table_insert(ttFont,name)
    table_insert(ttFont,cmap)
    table_insert(ttFont,post)
-   table_insert(ttFont,CFF)
---   table_insert(ttFont,FFTM)
+   if ttx.cffver==1 then 
+      table_insert(ttFont,CFF)
+   elseif ttx.cffver==2 then 
+      table_insert(ttFont,CFF2)
+   end
+   --   table_insert(ttFont,FFTM)
    table_insert(ttFont,GDEF)
+
+   if ttx.cffver==2 then
+      table_insert(ttFont,HVAR)
+      insert_child(HVAR,{'Version', ['value']="0x00010000"})
+      VarStore = new_element('VarStore',{['Format']="1"}) 
+      insert_child(VarStore,{'Format',['value']="1"})
+      VarRegionList = new_element('VarRegionList') 
+      -- For the moment, 1 axis and 1 region 
+      Regions = {new_element('Region',{['index']="0"})}
+      VarRegionAxis = new_element('VarRegionAxis',{['index']="0"})
+      insert_child(VarRegionAxis,new_element('StartCoord',{['value']="-1.0"}))
+      insert_child(VarRegionAxis,new_element('PeakCoord',{['value']="-1.0"}))
+      insert_child(VarRegionAxis,new_element('EndCoord',{['value']="0.0"}))
+      -- insert_child(VarRegionAxis,new_element('StartCoord',{['value']="0.0"}))
+      -- insert_child(VarRegionAxis,new_element('PeakCoord',{['value']="1.0"}))
+      -- insert_child(VarRegionAxis,new_element('EndCoord',{['value']="1.0"}))
+      insert_child(Regions[1],VarRegionAxis)
+      insert_children(VarRegionList,Regions)
+      insert_child(VarStore,VarRegionList)
+      VarData = new_element('VarData',{['index']="0"})
+      insert_child(VarData,new_element('NumShorts',{['value']="1"}))
+      insert_child(VarData,new_element('VarRegionIndex',{['value']="0"}))
+      insert_child(VarData,new_element('Item',{['index']="0", ['value']="[-125]"}))
+      insert_child(VarStore,VarData)
+      AdvWidthMap = new_element('AdvWidthMap')
+      insert_child(AdvWidthMap,new_element('Map', {['index']="0", ['outer']="0", ['inner']="0"}))
+      insert_child(HVAR,VarStore)
+      --insert_child(HVAR,AdvWidthMap)
+   end
+   
    table_insert(ttFont,hmtx)
    
    table_insert(GlyphOrder,GlyphID)
@@ -539,62 +745,89 @@
 	 put_post(k,v)
       end
    end
+   if ttx.cffver==2 then
+      insert_child(post,{'psNames'})
+      extranames = new_element('extraNames')
+      insert_child(post,extranames)
+   end
    
-   put_CFF('major',"1")
-   put_CFF('minor',"0")
-   insert_child(CFF,CFFFont)
-
-   if ttx.userdata.CFFFont then
-      for k,v in pairs(mflua.ttx.userdata.CFFFont) do
-	 put_CFFFont(k,v)
-      end
+   if ttx.cffver==1 then 
+      put_CFF('major',"1")
+      put_CFF('minor',"0")
+      insert_child(CFF,CFFFont)
+   elseif ttx.cffver==2 then 
+      put_CFF2('major',"2")
+      put_CFF2('minor',"0")
+      insert_child(CFF2,CFFFont)
    end
-   
-   insert_child(CFFFont,{'Encoding', ['name']=mflua.ttx.userdata.CFFFont.Encoding})
 
-   insert_child(CFFFont,Private)
-   if ttx.userdata.CFFFont.Private then
-      for k,v in pairs(ttx.userdata.CFFFont.Private) do
-	 put_Private(k,v)
+   if ttx.cffver==1 then 
+      if ttx.userdata.CFFFont then
+	 for k,v in pairs(mflua.ttx.userdata.CFFFont) do
+	    put_CFFFont(k,v)
+	 end
       end
-   end
 
-   local subrs = new_element('Subrs')
-   scrt.subrs  = subrs
-   if ttx.userdata.CFFFont.Private.Subrs then
-      for k,v in pairs(ttx.userdata.CFFFont.Private.Subrs) do
-	 insert_child(subrs,{'CharString', ['index']=k, v})
+      insert_child(CFFFont,{'Encoding', ['name']=mflua.ttx.userdata.CFFFont.Encoding})
+
+      insert_child(CFFFont,Private)
+      if ttx.userdata.CFFFont.Private then
+	 for k,v in pairs(ttx.userdata.CFFFont.Private) do
+	    put_Private(k,v)
+	 end
+      end 
+
+      local subrs = new_element('Subrs')
+      scrt.subrs  = subrs
+      if ttx.userdata.CFFFont.Private.Subrs then
+	 for k,v in pairs(ttx.userdata.CFFFont.Private.Subrs) do
+	    insert_child(subrs,{'CharString', ['index']=k, v})
+	 end
       end
-   end
       insert_child(Private,subrs)
 
+   elseif ttx.cffver==2 then 
+      insert_child(CFFFont,{'FontMatrix', ['value']=mflua.ttx.userdata.CFF2Font['FontMatrix']})
+      local FDArray  = new_element('FDArray')
+      local FontDict = new_element('FontDict', {['index']="0"})
+      insert_child(FontDict,{'FontMatrix', ['value']=mflua.ttx.userdata.CFF2Font['FontMatrix']})
+      insert_child(FontDict,{'Private'})
+      insert_child(FDArray,FontDict)
+      insert_child(CFFFont,FDArray)
+   end
+      
    -- .notdef char
    local notdef = new_element('CharString', {['name']=".notdef"})
-   insert_child(notdef,"107 endchar\n")
+   if ttx.cffver == 1 then 
+      insert_child(notdef,"endchar\n")
+   elseif ttx.cffver == 2 then
+      insert_child(notdef,"0 0  0 0  0 0 rrcurveto \n")
+   end
+
    insert_child_at_beginning(CharStrings, notdef)
    
    insert_child(CFFFont,CharStrings)
 
+   if CFF2 and  mflua.ttx.userdata.varstore then
+      insert_child(CFFFont,mflua.ttx.userdata.varstore)
+   end
+   
+   
    --
    -- TODO: check GlobalSubrs!!
    --
    local globsubrs = new_element('GlobalSubrs')
-   insert_child(CFF,globsubrs)
+   if ttx.cffver==1 then 
+      insert_child(CFF,globsubrs)
+   elseif ttx.cffver==2 then 
+      insert_child(CFF2,globsubrs)
+   end
    if ttx.userdata.CFF.GlobalSubrs then
       for k,v in pairs(ttx.userdata.CFF.GlobalSubrs) do
 	 insert_child(globsubrs,{'CharString', ['index']=k, v})
       end
    end
-   
-   --
-   -- fontforge timestamp table.
-   --
-   -- put_FFTM('version', "1")
-   -- put_FFTM('FFTimeStamp', "Fri Oct  7 21:32:10 2016")
-   -- put_FFTM('sourceCreated', "Tue Apr  4 13:38:00 2017")
-   -- put_FFTM('sourceModified', "Wed Apr  5 16:26:11 2017")
 
-
    local glyphclassdef = new_element('GlyphClassDef',{['Format']="2"})
    insert_child(GDEF,{'Version',['value']="0x00010000"})
    insert_child(GDEF,glyphclassdef)
@@ -605,7 +838,27 @@
    insert_child(LigCaretList,new_element('Coverage',{['Format']="2"}))
    insert_child(GDEF,LigCaretList)
 
-   insert_child(hmtx, get_mtx('.notdef',scrt.font_space,"0"))
+
+   insert_child(hmtx, get_mtx('.notdef',
+                               ttx.userdata.char_notdef['width'],
+                               ttx.userdata.char_notdef['lsb']))
+
+   if CFF2 and ttx.userdata.fvar then
+      local fvar = new_element('fvar')
+      local v, axis, _e
+      for i=1,#ttx.userdata.fvar.Axis do
+	 v = ttx.userdata.fvar.Axis[i]
+	 axis = new_element('Axis')
+	 _e = new_element('AxisTag');	   _e[2] = v['AxisTag'];      insert_child(axis,_e)
+	 _e = new_element('MinValue');	   _e[2] = v['MinValue'];     insert_child(axis,_e)
+	 _e = new_element('DefaultValue'); _e[2] = v['DefaultValue']; insert_child(axis,_e)
+	 _e = new_element('MaxValue');	   _e[2] = v['MaxValue'];     insert_child(axis,_e)
+	 _e = new_element('AxisNameID');   _e[2] = v['AxisNameID'];   insert_child(axis,_e)
+      end
+      insert_child(fvar,axis)
+      insert_child(ttFont,fvar)
+   end
+   
 end
 
 
@@ -622,6 +875,33 @@
    return t
 end
 
+
+local function sort(cycle)
+   local t={}
+   local curve
+   local p,q, index
+   local xmin,ymin = 4096,4096
+   index = 1
+   for i=1,#cycle do
+      curve=cycle[i]
+      p=curve[1]; 
+      t = _eval_tonumber(p)
+      -- Align to leftmost x and y 
+      --if t[1]<=xmin and t[2]<=ymin then index = i;xmin,ymin=t[1],t[2]  end
+      -- Align to the leftmost x
+      if t[1]<=xmin  then index = i;xmin,ymin=t[1],t[2]  end
+   end
+   t={}
+   for i=index,#cycle do t[#t+1]=cycle[i] end
+   for i=1,index-1    do t[#t+1]=cycle[i] end
+   for i=1,#t do
+      curve=t[i]
+      p,c1,c2,q=curve[1],curve[2],curve[3],curve[4]
+    end
+    return t
+end
+
+
 local function _reverse(cycle)
   local cv1, cv2
   local p,c1,c2,q
@@ -639,20 +919,101 @@
 end
 
 
+-- local function updateminmax(p,c1,c2,q)
+--   ttx = ttx or {}
+--   ttx.userdata = ttx.userdata or {}
+--   ttx.userdata.head = ttx.userdata.head or {}
+--   local t;
+--   -- hm not ok, too raw
+--   -- we need at least 3 bisections
+--   t = {p[1],c1[1],c2[1],q[1]}
+--   table_sort(t) 
+--   ttx.userdata.head['xMin']= math_floor(t[1])
+--   ttx.userdata.head['xMax']= math_floor(t[4])
+--   t = {p[2],c1[2],c2[2],q[2]}
+--   table_sort(t) 
+--   ttx.userdata.head['yMin']= math_floor(t[1])
+--   ttx.userdata.head['yMax']= math_floor(t[4])
+-- end
 
+
+local function update_char_lsb(glyph_name,char_wd_emunit,index)
+   local err = true
+   if ttx.userdata.update_char_lsb and
+   type(ttx.userdata.update_char_lsb)=='function' then
+      ttx.userdata.update_char_lsb(glyph_name,char_wd_emunit,index)
+      return
+   end
+   if GF_chars[index] then
+      insert_child(hmtx, get_mtx(glyph_name,
+				 char_wd_emunit,GF_chars[index].min_m))
+      return
+   end
+   if err then print_err("update_char_lsb failed") end
+end
+
+
+
+
+
+local function isvhline(py,c1y,c2y,qy)
+  if (py==c1y) and (c1y==c2y) and (c2y==qy) then 
+    return true
+  end
+  --local abs = math.abs
+  local eps = ttx.eps or 0.01
+  local d1,d2,d3,d4 = abs(py-c1y), abs(c1y-c2y), abs(c2y-qy),abs(py-qy)
+  if d1<eps and d2<eps and d3<eps and d4<eps then 
+    return true 
+  end
+  return false
+end
+
+
+local function isline(px,py,c1x,c1y,c2x,c2y,qx,qy)
+  local px,py,c1x,c1y,c2x,c2y,qx,qy = 0,0,c1x-px,c1y-py,c2x-px,c2y-py,qx-px,qy-py
+  local eps = ttx.deps or 0.01
+  local atan2,abs = math.atan2, math.abs
+  a  = atan2(qy,qx)
+  a1 = atan2(c1y,c1x) 
+  a2 = atan2(c2y,c2x) 
+  if abs(a-a1)<eps and abs(a-a2)<eps and abs(a1-a2)<eps then 
+   return true 
+  end
+ return false
+end
+
+
+local function insert_stem(index,stem_type)
+ if mflua and mflua.userdata and mflua.userdata.char and mflua.userdata.char[index]  and mflua.userdata.char[index][stem_type] then
+     -- stem[i]={base, delta} 
+     local stem = mflua.userdata.char[index][stem_type]
+     local content = {}
+     for i=1,#stem do 
+	--table_insert(content, format("%s %s", normalize(stem[i][1]),normalize(stem[i][2])))
+	table_insert(content, format("%s %s",stem[i][1],stem[i][2]))
+     end 
+     table_insert(content,stem_type)
+     return table_concat(content, " ")
+ end
+ return nil
+end
+
+
+
 local function make_glyph(valid_curves,char,cycles,tfm)
    -- Write the ttx
-   --
-   --  print('BEZ  MFbuiltin.hppp='..print_scaled(MFbuiltin.hppp()))
-   --  print('BEZ  MFbuiltin.vppp='..print_scaled(MFbuiltin.vppp()))
-   --  print('BEZ  MFbuiltin.designsize='..print_scaled(MFbuiltin.designsize()))
+
+   if #cycles == 0 and #valid_curves==0 then
+       print("no outlines ")
+       --return
+   end 
    local tfm = tfm
-   local mflua_index = tonumber( char['index'] ) -- better a string or a number
+   local mflua_index = tointeger( char['index'] )  -- better a string or a number
    local index = mflua_index
    if mflua.ttx.userdata.charindex and mflua.ttx.userdata.charindex[index] then
       index = mflua.ttx.userdata.charindex[index]
    end
-   
    local design_size=tonumber ( print_scaled(MFbuiltin.designsize()) ) --pt 
    local char_wd=tonumber( char['char_wd'] ) -- pt
    local char_ht=tonumber( char['char_ht'] ) -- pt
@@ -664,36 +1025,44 @@
 
    local glyphclassdef =  scrt.gdef.glyphclassdef
 
-   --local xheight =  0.458333 *  design_size -- must be read from tfm !!
 
-   local x_resolution = math.floor(0.5+tonumber( print_scaled(MFbuiltin.hppp()) )* 72.27)
-   local y_resolution = math.floor(0.5+tonumber( print_scaled(MFbuiltin.vppp()) )* 72.27)
+   local x_resolution = math_floor(0.5+tonumber( print_scaled(MFbuiltin.hppp()) )* 72.27)
+   local y_resolution = math_floor(0.5+tonumber( print_scaled(MFbuiltin.vppp()) )* 72.27)
    assert(x_resolution==y_resolution, format('Error on _make_glyph x_res=%d and y_res=%d differ',x_resolution,y_resolution))
 
    local resolution = x_resolution 
    local emsize = ttx.emsize -- 1000, type 1, also known as em_unit: 1000 emsize = 1em
    local em_unit  = emsize  
-
    local em_unit_for_pixel = (72.27/design_size) * (emsize / resolution)
    local bp_for_pt = 72/72.27
-   local char_wd_emunit = (char_wd/design_size) *em_unit
-   local char_ht_emunit = (char_ht/design_size) *em_unit
-   local char_dp_emunit = (char_dp/design_size) *em_unit
-    
+   local char_wd_emunit = tonumber(format("%0.0f", (char_wd/design_size) *em_unit))
+   local char_ht_emunit = tonumber(format("%0.0f", (char_ht/design_size) *em_unit))
+   local char_dp_emunit = tonumber(format("%0.0f", (char_dp/design_size) *em_unit))
    local glyph_name  = tostring(char['charname'])
+
    if glyph_name and glyph_name ~= '' and not(index==0) then 
       table_insert(GlyphOrder,get_GlyphID(index,glyph_name))
    end
+
    local content = {}
-   if (abs(char_wd_emunit-scrt.font_space)>1e-4) then
-      table_insert(content,format("%0.3f w",char_wd_emunit-scrt.font_space,print_int(1000*(tfm.font.space)))) 
+   table_insert(content," ")
+   if CFF2 and (abs(char_wd_emunit-scrt.font_space)>1e-4) then
+      table_insert(content,format("%0.3f w",char_wd_emunit-scrt.font_space))  
    end
-   --table_insert(content,"stem ?")  -- TODO
+     
+
+   table_insert(content,insert_stem(mflua_index,"hstem"))
+   table_insert(content,insert_stem(mflua_index,"vstem"))
    --table_insert(content,"mask ?")  -- TODO
+
    local origin = {0,0}
-   for i,cycle in pairs(cycles) do 
+   for i,_cycle in pairs(cycles) do 
+      local cycle 
       local p,c1,c2,q,offset
-      cycle = reverse(cycle)
+      --cycle = reverse(_cycle)
+      cycle = _cycle
+      --  do we need a sort ?
+      --cycle = sort(cycle)
       for i1,curve in ipairs(cycle) do 
 	 p,c1,c2,q,offset=curve[1],curve[2],curve[3],curve[4],curve[5]
 	 p =_eval_tonumber(p ,offset)
@@ -705,18 +1074,119 @@
 	 q[1],q[2]   = q[1] *em_unit_for_pixel,  q[2]*em_unit_for_pixel
 	 c1[1],c1[2] = c1[1]*em_unit_for_pixel, c1[2]*em_unit_for_pixel
 	 c2[1],c2[2] = c2[1]*em_unit_for_pixel, c2[2]*em_unit_for_pixel
-	 if i1==1 then
-	    table_insert(content,format("%0.2f %0.2f rmoveto",p[1]-origin[1],p[2]-origin[2]))
-	    origin = {p[1],p[2]}
+
+
+	 p[1],p[2]   = toscaled(p[1]), toscaled(p[2])
+	 q[1],q[2]   = toscaled(q[1]), toscaled(q[2])
+	 c1[1],c1[2] = toscaled(c1[1]), toscaled(c1[2])
+	 c2[1],c2[2] = toscaled(c2[1]), toscaled(c2[2])
+ 
+	 
+	 if CFF then
+	    -- print(format("p1 %s path=(%0.14f,%0.14f) (%0.14f,%0.14f) (%0.14f,%0.14f) (%0.14f,%0.14f)",  index,
+	    -- 					    p[1], p[2],
+	    -- 					    c1[1], c1[2],
+	    -- 					    c2[1], c2[2],
+	    -- 					    q[1],q[2]))
+	    -- print(format("p2 %s path=(%0.4f,%0.4f) (%0.4f,%0.4f) (%0.4f,%0.4f) (%0.4f,%0.4f)",  index,
+	    -- 					    p[1], p[2],
+	    -- 					    c1[1], c1[2],
+	    -- 					    c2[1], c2[2],
+	    -- 					    q[1],q[2]))
+	    -- print(format("p3 %s path=(%s,%s) (%s,%s) (%s,%s) (%s,%s)",  index,
+	    -- 		 normalize(p[1]), normalize(p[2]), 
+	    -- 		 normalize(c1[1]), normalize(c1[2]), 
+	    -- 		 normalize(c2[1]), normalize(c2[2]), 
+	    -- 		 normalize(q[1]), normalize(q[2])))
+
+	    if i1==1 then
+	       --print(format("m %s %s %s rmoveto",index, normalize(p[1]-origin[1]),normalize(p[2]-origin[2])))
+	       table_insert(content,format("%s %s rmoveto",normalize(p[1]-origin[1]),normalize(p[2]-origin[2])))
+	       origin = {p[1],p[2]}
+	    end
+            if isvhline(p[2],c1[2],c2[2], q[2]) then     -- check  horizontal line
+               --print(format("h %s %s hlineto", index, normalize(q[1]-p[1])))
+	       table_insert(content,format("%s hlineto", normalize(q[1]-p[1])))
+            elseif isvhline(p[1],c1[1],c2[1], q[1]) then -- check  vertical line
+	       --print(format("v %s %s vlineto", index,normalize(q[2]-p[2])))
+	       table_insert(content,format("%s vlineto", normalize(q[2]-p[2])))
+            elseif isline(p[1],p[2],c1[1],c1[2],c2[1],c2[2],q[1],q[2]) then -- check a line 
+               --print(format("r %s %s %s rlineto", index, normalize(q[1]-p[1]), normalize(q[2]-p[2])))
+	       table_insert(content,format("%s %s rlineto", normalize(q[1]-p[1]), normalize(q[2]-p[2])))
+            else 
+	       local prec = 3;
+               -- p[1] =  normalize_and_simplify(p[1],prec);p[2] =  normalize_and_simplify(p[2],prec);
+               -- c1[1] =  normalize_and_simplify(c1[1],prec);c1[2] =  normalize_and_simplify(c1[2],prec);
+               -- c2[1] =  normalize_and_simplify(c2[1],prec);c2[2] =  normalize_and_simplify(c2[2],prec);
+               -- q[1] =  normalize_and_simplify(q[1],prec);q[2] =  normalize_and_simplify(q[2],prec);
+
+
+	       table_insert(content,(format("%s %s %s %s %s %s rrcurveto", 
+			    normalize_and_simplify(c1[1] -p[1],prec), normalize_and_simplify(c1[2]-p[2],prec),
+			    normalize_and_simplify(c2[1]-c1[1],prec), normalize_and_simplify(c2[2]-c1[2],prec),
+			    normalize_and_simplify(q[1] -c2[1],prec),  normalize_and_simplify(q[2]-c2[2],prec))))
+	       
+            end  
+
+	 elseif CFF2 then -- 
+	    -- reverse the key, because we reverse the cycle
+	    local kp = table.concat({curve[4],curve[3],curve[2],curve[1]}) 
+	    local deltas_width = {{0,0},{0,0}, {0,0},{0,0}, {0,0},{0,0}, {0,0},{0,0}}
+	    local origin_deltas_width = {0,0}
+	    local a, b, c, d, da, Da, db, Db, dc, Dc, dd, Dd
+	    if mflua.userdata.deltas_width[glyph_name] then 
+	       deltas_width  = mflua.userdata.deltas_width[glyph_name][kp] 
+	       -- Original from MF, we have to reverse it; d..c..b..a is the key,
+	       -- da and Da are the delta min and delta max,
+	       -- where delta is (variated_instance - reference_instance)
+	       -- delta are not affected by offset, but scaling are cannot be discarded
+	       a, b, c, d, da, Da, db, Db, dc, Dc, dd, Dd = table.unpack(deltas_width)
+	       deltas_width = {dd, Dd,dc, Dc,db, Db,da, Da}
+	       for _,v in ipairs(deltas_width) do
+	       	 v[1],v[2]=v[1]*em_unit_for_pixel, v[2]*em_unit_for_pixel
+  	       end
+	    end	
+	    da, Da, db, Db, dc, Dc, dd, Dd = table.unpack(deltas_width)
+	    -- One axis only, width 
+	    -- Condensed Regular (still not Extended)
+	    local blend
+	    if i1==1 then
+	       blend = format("%0.2f %0.2f  2 blend",da[1]-origin_deltas_width[1],da[2]-origin_deltas_width[2]) ; 
+	       table_insert(content,format("%0.0f %0.0f %s rmoveto",p[1]-origin[1],p[2]-origin[2],blend))
+	       origin = {p[1],p[2]}
+	       origin_deltas_width ={da[1],da[2]}
+	    end
+	    blend = format("%0.2f %0.2f %0.2f %0.2f %0.2f %0.2f 6 blend",
+	                                                                db[1]-da[1],db[2]-da[2],
+	       	      	      		    	  	  	       dc[1]-db[1],dc[2]-db[2],
+	       	      	      		    	  	  	       dd[1]-dc[1],dd[2]-dc[2]) 	
+
+	    table_insert(content,format("%0.0f %0.0f %0.0f %0.0f %0.0f %0.0f %s rrcurveto",
+	    				c1[1] -p[1], c1[2]-p[2],
+	    				c2[1]-c1[1], c2[2]-c1[2],
+	    				q[1] -c2[1],  q[2]-c2[2],blend))
+
+
+
+	    -- if i1==1 then
+	    --    blend = '0 0 2 blend' ; 
+	    --    table_insert(content,format("%0.0f %0.0f %s rmoveto",p[1]-origin[1],p[2]-origin[2],blend))
+	    --    origin = {p[1],p[2]}
+	    -- end
+	    -- --table_insert(content,format("%0.2f %0.2f %0.2f %0.2f %0.2f %0.2f rrcurveto",
+	    -- if i1==1 then  blend = '0 0  0 0  0 0  6 blend' ; else  blend = '0 0  0 0  -10 0  6 blend'  end
+	    -- table_insert(content,format("%0.0f %0.0f %0.0f %0.0f %0.0f %0.0f %s rrcurveto",
+	    -- 				c1[1] -p[1], c1[2]-p[2],
+	    -- 				c2[1]-c1[1], c2[2]-c1[2],
+	    -- 				q[1] -c2[1],  q[2]-c2[2],blend))
 	 end
-	 --table_insert(content,format("%0.2f %0.2f %0.2f %0.2f %0.2f %0.2f rrcurveto",
-	 table_insert(content,format("%0.0f %0.0f %0.0f %0.0f %0.0f %0.0f rrcurveto",
-				     c1[1] -p[1], c1[2]-p[2],
-				     c2[1]-c1[1], c2[2]-c1[2],
-				     q[1] -c2[1],  q[2]-c2[2],p[1],p[2],c1[1],c1[2],c2[1],c2[2],q[1],q[2]))
       end
    end
-   table_insert(content,"endchar\n")
+   if ttx.cffver == 1 then  
+      table_insert(content,"endchar\n")
+   elseif ttx.cffver == 2 then 
+      table_insert(content,"")
+   end
    local CharString = new_element('CharString', {['name']=glyph_name})
    insert_child(CharString,table_concat(content,"\n"))
 
@@ -726,8 +1196,21 @@
    insert_child(cmap4_3,get_map(format("0x%x",index),glyph_name))
    
    insert_child(glyphclassdef, get_ClassDef(glyph_name,"1"))
-   insert_child(hmtx, get_mtx(glyph_name,char_wd_emunit,"80"))
+   update_char_lsb(glyph_name,char_wd_emunit,mflua_index)
    
+
+   if ttx.cffver==2 then
+      local psName = new_element('psName', {['name']=glyph_name})
+      local Item = new_element('Item', {['index']=format("%d",index), ['value']="[-125]"})
+      local Map  = new_element('Map', {['index']=format("%d",index), ['outer']="0", ['inner']="0"})
+      local VarStore = get_children(HVAR,{'VarStore'}) 
+      local VarData  = get_children(VarStore[1],{'VarData'}) 
+      --local AdvWidthMap = get_children(HVAR,{'AdvWidthMap'}) 
+      insert_child(VarData[1],Item)
+      --insert_child(AdvWidthMap[1],Map)
+      insert_child(extranames,psName)
+        
+   end
    
 end -- make_glyph
 
@@ -739,5 +1222,7 @@
 ttx.makefont   = makefont
 ttx.setup      = setup
 ttx.userdata   = {}
-
+ttx.cffver     = 1
+ttx.eps        = 0.01
+ttx.deps       = 0.01
 return ttx



More information about the tex-live-commits mailing list