From 5052417d215a921e2e219ac62fa49ac09c0f25b5 Mon Sep 17 00:00:00 2001 From: Luigi Scarso Date: Sat, 6 Apr 2019 22:20:27 +0000 Subject: Updated mflua 0.9.1 (with prev. permission of K.Berry) git-svn-id: svn://tug.org/texlive/trunk@50829 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/web2c/mfluadir/mflua_version.h | 1 + Build/source/texk/web2c/mfluadir/mfluac.c | 15 + Build/source/texk/web2c/mfluadir/mfluac.h | 1 + Build/source/texk/web2c/mfluadir/mfluaextra.h | 4 +- .../source/texk/web2c/mfluadir/mfluatrap/mflua.lua | 71 +- Master/texmf-dist/scripts/mflua/mflua.lua | 996 ++++++++++++++++++++- 6 files changed, 1019 insertions(+), 69 deletions(-) diff --git a/Build/source/texk/web2c/mfluadir/mflua_version.h b/Build/source/texk/web2c/mfluadir/mflua_version.h index bc9a85a9790..800714bc58c 100644 --- a/Build/source/texk/web2c/mfluadir/mflua_version.h +++ b/Build/source/texk/web2c/mfluadir/mflua_version.h @@ -1 +1,2 @@ #define MFLUA_VERSION "0.9.1" +#define BANNER "This is MFLua, Version 2.7182818-" MFLUA_VERSION \ No newline at end of file diff --git a/Build/source/texk/web2c/mfluadir/mfluac.c b/Build/source/texk/web2c/mfluadir/mfluac.c index 31ed66a4e3e..aea6a8a7e96 100644 --- a/Build/source/texk/web2c/mfluadir/mfluac.c +++ b/Build/source/texk/web2c/mfluadir/mfluac.c @@ -454,6 +454,19 @@ static int priv_mfweb_LUAGLOBALGET_boundary_char(lua_State *L) return 1; } +static int priv_mflua_version(lua_State *L) +{ + lua_pushstring(L,MFLUA_VERSION); + return 1; +} + +static int priv_mflua_banner(lua_State *L) +{ + lua_pushstring(L,BANNER); + return 1; +} + + /**************************************************************/ @@ -496,6 +509,8 @@ static const struct luaL_Reg MFbuiltin_l[] = { {"turning_check", priv_mfweb_LUAGLOBALGET_turning_check}, {"boundary_char", priv_mfweb_LUAGLOBALGET_boundary_char}, {"turning_number", priv_mfweb_LUAGLOBALGET_turning_number}, + {"mflua_version",priv_mflua_version}, + {"mflua_banner",priv_mflua_banner}, {NULL, NULL} /* sentinel */ }; diff --git a/Build/source/texk/web2c/mfluadir/mfluac.h b/Build/source/texk/web2c/mfluadir/mfluac.h index eb0f6a1a14d..10f7240c51e 100644 --- a/Build/source/texk/web2c/mfluadir/mfluac.h +++ b/Build/source/texk/web2c/mfluadir/mfluac.h @@ -1,6 +1,7 @@ #ifndef MFLUAC_H #define MFLUAC_H +#include extern int mfluabeginprogram(void); extern int mfluaPREstartofMF(void); extern int mfluaPREmaincontrol(void); diff --git a/Build/source/texk/web2c/mfluadir/mfluaextra.h b/Build/source/texk/web2c/mfluadir/mfluaextra.h index a798f2cf600..f1753c94054 100644 --- a/Build/source/texk/web2c/mfluadir/mfluaextra.h +++ b/Build/source/texk/web2c/mfluadir/mfluaextra.h @@ -3,9 +3,9 @@ This is included by MFLua, from mfluaextra.c */ -#include /* for MFLUA_VERSION */ +#include /* for MFLUA_VERSION and BANNER */ -#define BANNER "This is MFLua, Version 2.7182818-" MFLUA_VERSION +/*#define BANNER "This is MFLua, Version 2.7182818-" MFLUA_VERSION*/ #define COPYRIGHT_HOLDER "L. Scarso" #define AUTHOR NULL #define PROGRAM_HELP MFLUAHELP diff --git a/Build/source/texk/web2c/mfluadir/mfluatrap/mflua.lua b/Build/source/texk/web2c/mfluadir/mfluatrap/mflua.lua index aa319d756d0..1f8cd8c175b 100644 --- a/Build/source/texk/web2c/mfluadir/mfluatrap/mflua.lua +++ b/Build/source/texk/web2c/mfluadir/mfluatrap/mflua.lua @@ -1,3 +1,7 @@ +print("MFLua version: " .. mflua.MFbuiltin.mflua_version()) +print("MFLua banner: ".. mflua.MFbuiltin.mflua_banner()) + +local function PRINTDBG(s) print(tostring(s)) end local function PRINTDBG(s) end local function chMF(t,k) if t[k] then print(k.." already inserted") os.exit(1) end end @@ -875,7 +879,6 @@ local function printedges(s,nuline,x_off,y_off) -- -- local management of y, xq, xr -- - --f = mflua.print_specification.outfile1 index = (0+print_int(MFbuiltin.char_code())) + (0+print_int(MFbuiltin.char_ext()))*256 char = chartable[index] or {} --print("#xq=".. #xq) @@ -1237,6 +1240,7 @@ local function print_specification(c,h) -- f = mflua.print_specification.outfile1 -- f:write("\n%%POST START\n".. res .. "\n%%POST END\n") --f:close() + return res end mflua.MF.print_specification = print_specification @@ -1563,7 +1567,7 @@ local function _postprocessing_contour() index = (0+print_int(MFbuiltin.char_code())) + (0+print_int(MFbuiltin.char_ext()))*256 res = res .. "%% postprocessing contour for " .. index ..";\n" res = res .. "path p[];\n" - print("CHAR " .. index) + --print("\n_postprocessing_contour CHAR " .. index) bezier_octant_contour = mflua.do_add_to.bezier_octant_contour[#mflua.do_add_to.bezier_octant_contour] path_cnt = 1 @@ -1600,7 +1604,7 @@ local function _postprocessing_contour() char['contour'] = char['contour'] or {} char['contour'][#char['contour']+1] = bezier_octant_contour char['res'] = char['res'] or "" - char['res'] = char['res'] .. res + char['res'] = char['res'] .. res ; char['index'] = index chartable[index] = char return 0 @@ -1619,16 +1623,7 @@ mflua.do_add_to._postprocessing_contour = _postprocessing_contour local function _store_current_cycle(hs) local res, current_cycle res, current_cycle = mflua.do_add_to._get_cycle(hs) - --print( mflua_print_path(hs) ) if res=='cycle' then - -- for i=0,(#current_cycle/3)-1 do - -- local l = current_cycle - -- local base = i*3 - -- local p,c1,c2,q = _circular_list_geti(l,base+1) , _circular_list_geti(l,base+2),_circular_list_geti(l,base+3),_circular_list_geti(l,base+4) - -- print (string.format("%d/%d (%f,%f) .. controls (%f,%f) and (%f,%f) .. (%f,%f) ",(i-1)%3,#current_cycle, - -- p[1],p[2],c1[1],c1[2],c2[1],c2[2],q[1],q[2])) - - -- end local index = (0+print_int(MFbuiltin.char_code())) + (0+print_int(MFbuiltin.char_ext()))*256 local char = mflua.chartable[index] or {} char['cycle'] = char['cycle'] or {} @@ -1649,6 +1644,7 @@ end local function POST_make_spec_rhs(rhs) PRINTDBG("POST_make_spec_rhs") + --mflua.do_add_to._store_current_cycle(rhs) --print("post rhs MFbuiltin.turning_number=",MFbuiltin.turning_number() ) ; end @@ -1660,7 +1656,8 @@ end local function POST_make_spec_lhs(lhs) PRINTDBG("PRE_make_spec_lhs") - print("post lhs MFbuiltin.turning_number=",MFbuiltin.turning_number() ) ; + --mflua.do_add_to._store_current_cycle(lhs) + --print("post lhs MFbuiltin.turning_number=",MFbuiltin.turning_number() ) ; end local function PRE_fill_envelope_rhs(rhs) @@ -2101,9 +2098,7 @@ mflua.end_program = end_program mflua.max_recursion_level = 32 - mflua.bit = 7 -- should be 4 -mflua.pen = {} -- collect bezier curves of the pens mflua.pi = 2*math.atan2(1,0) mflua.print_specification = mflua.print_specification or {} @@ -2140,9 +2135,7 @@ mflua.mflua_exe = 'mflua' mflua.turningnumber_file='mflua_tn' mflua.fill_envelope = {} mflua.fill_envelope.temp_transition = "" -mflua.pen = {} - - +mflua.pen = {} -- collect bezier curves of the pens -- @@ -2187,6 +2180,7 @@ function mflua.angle(p,q) return math.acos(dot(p,q)/(math.sqrt(dot(p,p))*math.sqrt(dot(q,q)))) end end + -- function mflua.vec(a,w,b1) if b1 == nil then b=w else b = b1 end ; return {b[1]-a[1],b[2]-a[2]} end -- mflua.vec(a,b) == mflua.vec(a,'->',b) function mflua.round(p) @@ -2249,13 +2243,11 @@ function mflua.approx_curve_lenght(p,c1,c2,q) end --- to permit multiple instances of mflua -if io.open('LOCK1')==nil and io.open('LOCK_ELLIPSE')==nil then - mflua.print_specification.filename = "envelope.tex" - mflua.print_specification.outfile1 = io.open(mflua.print_specification.filename,'w') -end - - +-- for multiple instances of mflua one can define a LOCK like this +-- if io.open('LOCK1')==nil and io.open('LOCK_ELLIPSE')==nil then +-- mflua.print_specification.filename = "envelope.tex" +-- mflua.print_specification.outfile1 = io.open(mflua.print_specification.filename,'w') +-- end @@ -2498,9 +2490,13 @@ tfm.getface = tfm.printfloat = function(d,p) - local d,p = tostring(d), tonumber(p) or 6 - local f = string.format("%%.%df",p) - return string.format(f,d) + if d then + local d,p = d, tonumber(p) or 6 + local f = string.format("%%.%df",p) + return string.format(f,d) + else + return tostring(d) + end end tfm.array = {} @@ -2667,7 +2663,7 @@ tfm.build.all = tfm.array.param = tfm.build.param(1,np,w) end -tfm.debug = 1 +tfm.debug = 0 tfm.printdebug = function() if tfm.debug==1 then @@ -2697,7 +2693,7 @@ tfm.font = {} tfm.run= function(name) local name = name - local _print = tfm.printdebug + local _print = tfm.printdebug() local header ={} local char_info ={} local width ={} @@ -2813,7 +2809,7 @@ tfm.run= tfm.chars[current_char].depth = depth[depth_index] tfm.chars[current_char].italic = italic[italic_index] tfm.chars[current_char].tag = tag - _print(i,string.format("O %o",current_char),string.char(current_char), + _print(string.format("O %o",current_char),string.char(current_char), 'WIDTH='.._pf(width[width_index]), 'HEIGHT='.._pf(height[height_index]), 'DEPTH='.._pf(depth[depth_index]), @@ -2824,6 +2820,7 @@ tfm.run= local kern_program = tfm.dump.kernprogram(remainder,current_char) end end + tfm.font.slant = param[1] _print("SLANT=".._pf(tfm.font.slant)) @@ -2971,7 +2968,7 @@ do local function readuntileof() if gfdata_index>gfdata_len then - GF.warning("wrong index") + GF.warning("wrong index: gfdata_index="..tostring(gfdata_index).."> gfdata_len="..tostring(gfdata_len) ) return nil end local s = sub(gfdata,gfdata_index,gfdata_len) @@ -3510,12 +3507,14 @@ do GF.error("error post_post_1 "..pad223) return error.post_post end - local s = readuntileof() - local ctr223 = rep('\223',len(s)) - if ctr223 ~= s then + if gfdata_index <=gfdata_len then + local s = readuntileof() + local ctr223 = rep('\223',len(s)) + if ctr223 ~= s then GF.error("error post_post_2 "..pad223) return error.post_post - end + end + end chars.GF_format_post = i return error.ok end diff --git a/Master/texmf-dist/scripts/mflua/mflua.lua b/Master/texmf-dist/scripts/mflua/mflua.lua index 2596469d1d8..1f8cd8c175b 100644 --- a/Master/texmf-dist/scripts/mflua/mflua.lua +++ b/Master/texmf-dist/scripts/mflua/mflua.lua @@ -1,3 +1,7 @@ +print("MFLua version: " .. mflua.MFbuiltin.mflua_version()) +print("MFLua banner: ".. mflua.MFbuiltin.mflua_banner()) + +local function PRINTDBG(s) print(tostring(s)) end local function PRINTDBG(s) end local function chMF(t,k) if t[k] then print(k.." already inserted") os.exit(1) end end @@ -875,7 +879,6 @@ local function printedges(s,nuline,x_off,y_off) -- -- local management of y, xq, xr -- - --f = mflua.print_specification.outfile1 index = (0+print_int(MFbuiltin.char_code())) + (0+print_int(MFbuiltin.char_ext()))*256 char = chartable[index] or {} --print("#xq=".. #xq) @@ -1237,6 +1240,7 @@ local function print_specification(c,h) -- f = mflua.print_specification.outfile1 -- f:write("\n%%POST START\n".. res .. "\n%%POST END\n") --f:close() + return res end mflua.MF.print_specification = print_specification @@ -1563,7 +1567,7 @@ local function _postprocessing_contour() index = (0+print_int(MFbuiltin.char_code())) + (0+print_int(MFbuiltin.char_ext()))*256 res = res .. "%% postprocessing contour for " .. index ..";\n" res = res .. "path p[];\n" - print("CHAR " .. index) + --print("\n_postprocessing_contour CHAR " .. index) bezier_octant_contour = mflua.do_add_to.bezier_octant_contour[#mflua.do_add_to.bezier_octant_contour] path_cnt = 1 @@ -1600,7 +1604,7 @@ local function _postprocessing_contour() char['contour'] = char['contour'] or {} char['contour'][#char['contour']+1] = bezier_octant_contour char['res'] = char['res'] or "" - char['res'] = char['res'] .. res + char['res'] = char['res'] .. res ; char['index'] = index chartable[index] = char return 0 @@ -1619,16 +1623,7 @@ mflua.do_add_to._postprocessing_contour = _postprocessing_contour local function _store_current_cycle(hs) local res, current_cycle res, current_cycle = mflua.do_add_to._get_cycle(hs) - --print( mflua_print_path(hs) ) if res=='cycle' then - -- for i=0,(#current_cycle/3)-1 do - -- local l = current_cycle - -- local base = i*3 - -- local p,c1,c2,q = _circular_list_geti(l,base+1) , _circular_list_geti(l,base+2),_circular_list_geti(l,base+3),_circular_list_geti(l,base+4) - -- print (string.format("%d/%d (%f,%f) .. controls (%f,%f) and (%f,%f) .. (%f,%f) ",(i-1)%3,#current_cycle, - -- p[1],p[2],c1[1],c1[2],c2[1],c2[2],q[1],q[2])) - - -- end local index = (0+print_int(MFbuiltin.char_code())) + (0+print_int(MFbuiltin.char_ext()))*256 local char = mflua.chartable[index] or {} char['cycle'] = char['cycle'] or {} @@ -1649,6 +1644,7 @@ end local function POST_make_spec_rhs(rhs) PRINTDBG("POST_make_spec_rhs") + --mflua.do_add_to._store_current_cycle(rhs) --print("post rhs MFbuiltin.turning_number=",MFbuiltin.turning_number() ) ; end @@ -1660,7 +1656,8 @@ end local function POST_make_spec_lhs(lhs) PRINTDBG("PRE_make_spec_lhs") - print("post lhs MFbuiltin.turning_number=",MFbuiltin.turning_number() ) ; + --mflua.do_add_to._store_current_cycle(lhs) + --print("post lhs MFbuiltin.turning_number=",MFbuiltin.turning_number() ) ; end local function PRE_fill_envelope_rhs(rhs) @@ -2101,9 +2098,7 @@ mflua.end_program = end_program mflua.max_recursion_level = 32 - mflua.bit = 7 -- should be 4 -mflua.pen = {} -- collect bezier curves of the pens mflua.pi = 2*math.atan2(1,0) mflua.print_specification = mflua.print_specification or {} @@ -2140,9 +2135,7 @@ mflua.mflua_exe = 'mflua' mflua.turningnumber_file='mflua_tn' mflua.fill_envelope = {} mflua.fill_envelope.temp_transition = "" -mflua.pen = {} - - +mflua.pen = {} -- collect bezier curves of the pens -- @@ -2187,6 +2180,7 @@ function mflua.angle(p,q) return math.acos(dot(p,q)/(math.sqrt(dot(p,p))*math.sqrt(dot(q,q)))) end end + -- function mflua.vec(a,w,b1) if b1 == nil then b=w else b = b1 end ; return {b[1]-a[1],b[2]-a[2]} end -- mflua.vec(a,b) == mflua.vec(a,'->',b) function mflua.round(p) @@ -2249,13 +2243,11 @@ function mflua.approx_curve_lenght(p,c1,c2,q) end --- to permit multiple instances of mflua -if io.open('LOCK1')==nil and io.open('LOCK_ELLIPSE')==nil then - mflua.print_specification.filename = "envelope.tex" - mflua.print_specification.outfile1 = io.open(mflua.print_specification.filename,'w') -end - - +-- for multiple instances of mflua one can define a LOCK like this +-- if io.open('LOCK1')==nil and io.open('LOCK_ELLIPSE')==nil then +-- mflua.print_specification.filename = "envelope.tex" +-- mflua.print_specification.outfile1 = io.open(mflua.print_specification.filename,'w') +-- end @@ -2498,9 +2490,13 @@ tfm.getface = tfm.printfloat = function(d,p) - local d,p = tostring(d), tonumber(p) or 6 - local f = string.format("%%.%df",p) - return string.format(f,d) + if d then + local d,p = d, tonumber(p) or 6 + local f = string.format("%%.%df",p) + return string.format(f,d) + else + return tostring(d) + end end tfm.array = {} @@ -2667,7 +2663,7 @@ tfm.build.all = tfm.array.param = tfm.build.param(1,np,w) end -tfm.debug = 1 +tfm.debug = 0 tfm.printdebug = function() if tfm.debug==1 then @@ -2697,7 +2693,7 @@ tfm.font = {} tfm.run= function(name) local name = name - local _print = tfm.printdebug + local _print = tfm.printdebug() local header ={} local char_info ={} local width ={} @@ -2813,7 +2809,7 @@ tfm.run= tfm.chars[current_char].depth = depth[depth_index] tfm.chars[current_char].italic = italic[italic_index] tfm.chars[current_char].tag = tag - _print(i,string.format("O %o",current_char),string.char(current_char), + _print(string.format("O %o",current_char),string.char(current_char), 'WIDTH='.._pf(width[width_index]), 'HEIGHT='.._pf(height[height_index]), 'DEPTH='.._pf(depth[depth_index]), @@ -2824,6 +2820,7 @@ tfm.run= local kern_program = tfm.dump.kernprogram(remainder,current_char) end end + tfm.font.slant = param[1] _print("SLANT=".._pf(tfm.font.slant)) @@ -2855,3 +2852,940 @@ mflua.tfm = tfm +-------------------------------------------------------------------------------- +-- +-- gf module +-- +-------------------------------------------------------------------------------- +-- +-- In-memory parser, i.e. reads all the gf into memory +-- and then parses the byte stream +-- + +local GF = {} +do + + local sub = string.sub + local len = string.len + local byte = string.byte + local format = string.format + local rep = string.rep + + local gfdata='' + local gfdata_index + local gfdata_len + + local chars={} + local current_char + local current_row -- aka n + local current_col -- aka m + local white=0 + local black=white+1 + local paint_switch + chars.xxx1 = {} + chars.xxx2 = {} + chars.xxx3 = {} + chars.xxx4 = {} + chars.yyy = {} + chars.nop = {} + chars.all_nop = {} -- collect a xxx1 or xxx2 or xxx3 or xxx4 or yyy or nop + chars.locators = {} + + + + + local defDEBUG = false + local function DEBUG(k,s) + print("DEBUG:"..tostring(k).."="..tostring(s)) + end + + + local function error_msg(msg) + io.write(format("! mflua GF: char %s: %s",current_char, msg)) + io.write(format(" position=%s ",gfdata_index)) + print() + end + GF.error = error_msg + + local function warning_msg(msg) + print(format("\n! mflua GF: char %s: %s.",current_char, msg)) + end + GF.warning = warning_msg + + + + -- + -- read n bytes starting from from gfdata_index included + -- and move gfdata_index + -- + local function readbytes(n) + if (gfdata_index+n-1)<1 then + GF.warning("attempt to read before the beginning of the file") + return nil + end + if (gfdata_index+n-1)>gfdata_len then + GF.warning("attempt to read beyond the end of the file") + return nil + end + local s + if (n<0) then + s = sub(gfdata,gfdata_index+n+1,gfdata_index) + elseif n>0 then + s = sub(gfdata,gfdata_index,gfdata_index+n-1) + else + s ='' + end + gfdata_index = gfdata_index+n + return s + end + + + local function read4bytes() + local b0 = byte(readbytes(1)) + local b1 = byte(readbytes(1)) + local b2 = byte(readbytes(1)) + local b3 = byte(readbytes(1)) + local v = (b3+b2*256+b1*65536+b0*16777216) + if v >2147483647 then + v = v -4294967296 + end + return v + end + + + local function readrev4bytes() + local b3 = byte(readbytes(-1)) + local b2 = byte(readbytes(-1)) + local b1 = byte(readbytes(-1)) + local b0 = byte(readbytes(-1)) + local v = (b3+b2*256+b1*65536+b0*16777216) + if v >2147483647 then + v = v -4294967296 + end + return v + end + + + local function readuntileof() + if gfdata_index>gfdata_len then + GF.warning("wrong index: gfdata_index="..tostring(gfdata_index).."> gfdata_len="..tostring(gfdata_len) ) + return nil + end + local s = sub(gfdata,gfdata_index,gfdata_len) + gfdata_index = gfdata_len +1 + return s + end + + + local function datanotfinished() + return (gfdata_index <= gfdata_len) + end + + + local function moveindex_after(p) + gfdata_index = p+1 + end + + + + error = {} + error.ok = 0 + error.base = error.ok + error.pre = error.base +1 + error.parse = error.base +2 + error.post = error.base +3 + error.boc = error.base +4 + error.load = error.base +127 + error.parse = error.base +128 + error.parsechar = error.base +129 + error.paint = {} + for j=0,63 do + error.paint[j] = error.base +130+j + end + error.paint_switch=error.base +130+64 + error.paint1 = error.base +130+64+1 + error.paint2 = error.base +130+64+2 + error.paint3 = error.base +130+64+3 + error.eoc = error.base +130+64+6 + error.skip0 = error.base +130+64+7 + error.skip1 = error.base +130+64+8 + error.skip2 = error.base +130+64+9 + error.skip3 = error.base +130+64+10 + error.new_row = {} + for j=0,164 do + error.new_row[j]= error.base +130+64+10+1+j + end + + error.post_post=error.base +130+64+10+1+165 + + error.skip223=error.base +130+64+10+1+166 + + + error_name_t = {} + for k,v in pairs(error) do + error_name_t[v] = k + end + local function error_name(res) + if res==nil then + return "unknown error code" + elseif error_name_t[res] == nil then + return "unknown error code" + else + return error_name_t[res] + end + end + + local opcodes = {} + + -- {beginning of the \\{paint} commands} + for j=0,63 do + local s = format("paint_%d",j) + opcodes[s] = j + end + opcodes.paint1=64 -- {move right a given number of columns, then black${}\swap{}$white} + opcodes.paint2=65 + opcodes.paint3=66 + opcodes.boc=67 -- {beginning of a character} + opcodes.boc1=68 -- {short form of |boc|} + opcodes.eoc=69 -- {end of a character} + opcodes.skip0=70 -- {skip no blank rows} + opcodes.skip1=71 -- {skip over blank rows} + opcodes.skip2=72 + opcodes.skip3=73 + --opcodes.new_row_0=74 -- {move down one row and then right} + --: + --opcodes.new_row_164=238 + for j=0,164 do + local s = format("new_row_%d",j) + opcodes[s] = j+74 + end + + --opcodes.max_new_row=164 -- {the largest \\{new\_row} command is |new_row_164|} + opcodes.xxx1=239 -- {for \&{special} strings} + opcodes.xxx2=240 + opcodes.xxx3=241 -- {for long \&{special} strings} + opcodes.xxx4=242 + opcodes.yyy=243 -- {for \&{numspecial} numbers} + opcodes.nop=244 -- no operation + opcodes.char_loc=245 -- {character locators in the postamble} + opcodes.char_loc0=246 + opcodes.pre=247 -- {preamble} + opcodes.post=248 -- {postamble beginning} + opcodes.post_post=249 -- {postamble ending} + + opcodes.undefined_1=250 + opcodes.undefined_2=251 + opcodes.undefined_3=252 + opcodes.undefined_4=253 + opcodes.undefined_5=254 + opcodes.undefined_6=255 + + local revopcode = {} + for k,v in pairs(opcodes) do revopcode[v] = k end + + + + complement_paint_switch = function() + local res = error.ok + if( paint_switch==black or paint_switch==white) then + paint_switch=(paint_switch+1)%2 + else + GF.error("wrong value for paint_switch") + res = error.paint_switch + end + return res + end + + local paint = function(n) + local res = error.ok + local c = chars[current_char] + local row = c[current_row] + if row==nil then + GF.error("error in paint_"..tostring(n)..", row is nil") + end + if paint_switch==black then + for i=current_col,current_col+n-1 do + row[i]=true + end + end + res = complement_paint_switch() + current_col = current_col + n + if res~=error.ok then + if n<64 then + GF.error("error in paint_"..tostring(n)) + res = error.paint[n] + elseif (64<=n and n<256) then + GF.error("error in paint1") + res = error.paint1 + elseif (256<=n and n<65536) then + GF.error("error in paint2") + res = error.paint2 + elseif (65536<=n and n<16777216) then + GF.error("error in paint3") + res = error.paint3 + end + end + return res + end + + + opcodes.func = {} + + + opcodes.func[opcodes.paint_0]= function() + local res = error.ok + res = complement_paint_switch() + if res~=error.ok then + GF.error("error in paint_0") + res = error.paint[0] + end + return res + end + + --opcodes.func[opcodes.paint_1]= function() return paint(1) end + --: + --opcodes.func[opcodes.paint_63]= function() return paint(63) end + for i=1, 63 do + local key = format("paint_%d",i) + local index = opcodes[key] + opcodes.func[index] = function() return paint(i) end + end + + opcodes.func[opcodes.paint1]= function() + local res = error.ok + local b = byte(readbytes(1)) + if (64<=b and b<256) then + paint(b) + else + GF.error("wrong value " ..tostring(b) .. " in paint1") + res = error.paint1 + end + return res + end + + + opcodes.func[opcodes.paint2]= function() + local res = error.ok + local b1 = byte(readbytes(1)) + local b2 = byte(readbytes(1)) + local b = b2+b1*256 + if (256<=b and b<65536) then + paint(b) + else + GF.error("wrong value " ..tostring(b) .. " in paint2") + res = error.paint2 + end + return res + end + + + + opcodes.func[opcodes.paint3]= function() + local res = error.ok + local b1 = byte(readbytes(1)) + local b2 = byte(readbytes(1)) + local b3 = byte(readbytes(1)) + local b = b3+b2*256+ (b1*65536) + if (65536<=b and b<16777216) then + paint(b) + else + GF.error("wrong value " ..tostring(b) .. " in paint3") + res = error.paint3 + end + return res + end + + + opcodes.func[opcodes.boc]= function() + local pos = gfdata_index + local c = read4bytes() + local p = read4bytes() + local min_m = read4bytes() + local max_m = read4bytes() + local min_n = read4bytes() + local max_n = read4bytes() + current_char = c + chars[current_char] = chars[current_char] or {} + chars[current_char]['p'] = p + chars[current_char]['max_m'] = max_m + chars[current_char]['min_m'] = min_m + chars[current_char]['max_n'] = max_n + chars[current_char]['min_n'] = min_n + chars[current_char]['opened'] = true + chars[current_char]['stream_pos'] = gfdata_index + chars[current_char]['max_col'] = max_m + chars[current_char]['min_col'] = min_m + chars[current_char]['max_row'] = max_n + chars[current_char]['min_row'] = min_n + current_col = min_m + current_row = max_n + chars[current_char][current_row]={} + paint_switch = white + return error.ok + end + + + opcodes.func[opcodes.boc1]= function() + local pos = gfdata_index + local c = byte(readbytes(1)) + local del_m = byte(readbytes(1)) + local max_m = byte(readbytes(1)) + local del_n = byte(readbytes(1)) + local max_n = byte(readbytes(1)) + local p = -1 + local min_m = max_m - del_m + local min_n = max_n - del_n + current_char = c + chars[current_char] = chars[current_char] or {} + chars[current_char]['p'] = p + chars[current_char]['max_m'] = max_m + chars[current_char]['min_m'] = min_m + chars[current_char]['max_n'] = max_n + chars[current_char]['min_n'] = min_n + chars[current_char]['opened'] = true + chars[current_char]['stream_pos'] = gfdata_index + chars[current_char]['max_col'] = max_m + chars[current_char]['min_col'] = min_m + chars[current_char]['max_row'] = max_n + chars[current_char]['min_row'] = min_n + current_col = min_m + current_row = max_n + chars[current_char][current_row]={} + paint_switch = white + return error.ok + end + + + opcodes.func[opcodes.eoc]= function() + local res = error.ok + if chars[current_char].opened == true then + chars[current_char].opened = false + res = error.ok + else + GF.error("error closing char") + res = error.eoc + end + -- + -- use them as stack to tie the nop + -- opcodes to current_char + table.insert(chars.xxx1,{current_char,-1}) + table.insert(chars.xxx2,{current_char,-1}) + table.insert(chars.xxx3,{current_char,-1}) + table.insert(chars.xxx4,{current_char,-1}) + table.insert(chars.yyy,{current_char,-1}) + table.insert(chars.nop,{current_char,-1}) + table.insert(chars.all_nop,{'eoc',current_char,-1}) + return res + end + + + opcodes.func[opcodes.skip0]= function() + if chars[current_char]==nil or chars[current_char].min_m==nil then + GF.error("error in skip0") + return error.skip0 + end + current_row = current_row -1 + current_col = chars[current_char].min_m + paint_switch = white + chars[current_char][current_row]={} + return error.ok + end + + + opcodes.func[opcodes.skip1]= function() + if chars[current_char]==nil or chars[current_char].min_m==nil then + GF.error("error in skip1") + return error.skip1 + end + local b = byte(readbytes(1)) + current_row = current_row -(b+1) + current_col = chars[current_char].min_m + paint_switch = white + chars[current_char][current_row]={} + return error.ok + end + + + opcodes.func[opcodes.skip2]= function() + if chars[current_char]==nil or chars[current_char].min_m==nil then + GF.error("error in skip2") + return error.skip2 + end + local b0 = byte(readbytes(1)) + local b1 = byte(readbytes(1)) + local b = b1+256*b0 + current_row = current_row - (b+1) + current_col = chars[current_char].min_m + paint_switch = white + chars[current_char][current_row]={} + return error.ok + end + + + opcodes.func[opcodes.skip3]= function() + if chars[current_char]==nil or chars[current_char].min_m==nil then + GF.error("error in skip3 ") + return error.skip3 + end + local b0 = byte(readbytes(1)) + local b1 = byte(readbytes(1)) + local b2 = byte(readbytes(1)) + local b = b2+b1*256+b3*65536 + current_row = current_row - (b+1) + current_col = chars[current_char].min_m + paint_switch = white + chars[current_char][current_row]={} + return error.ok + end + + + local function new_row(n) + if chars[current_char]==nil or chars[current_char].min_m==nil then + GF.error("error in new_row_"..n) + return error.new_row[n] + end + current_row = current_row - 1 + current_col = chars[current_char].min_m+n + paint_switch = black + chars[current_char][current_row]={} + return error.ok + + end + + opcodes.func[opcodes.new_row_0]= function() + if chars[current_char]==nil or chars[current_char].min_m==nil then + GF.error("error in new_row_0") + return error.new_row[0] + end + current_row = current_row - 1 + current_col = chars[current_char].min_m + paint_switch = black + chars[current_char][current_row]={} + return error.ok + end + + --opcodes.func[opcodes.new_row_1]= function() new_row(1) end + --: + --opcodes.func[opcodes.new_row_164]= function() new_row(i)end + for i=1, 164 do + local key = format("new_row_%d",i) + local index = opcodes[key] + opcodes.func[index] = function() return new_row(i) end + end + + --opcodes.func[opcodes.max_new_row]= function() + -- return new_row(opcodes.max_new_row) + --end + + opcodes.func[opcodes.xxx1]= function() + local stream_pos = gfdata_index + local b = byte(readbytes(1)) + local k = readbytes(b) + table.insert(chars.xxx1,{k,stream_pos}) + table.insert(chars.all_nop,{'xxx1',k,stream_pos}) + return error.ok + end + + opcodes.func[opcodes.xxx2]= function() + local stream_pos = gfdata_index + local b0 = byte(readbytes(1)) + local b1 = byte(readbytes(1)) + local k = readbytes(b1+ b0*256) + table.insert(chars.xxx2,{k,stream_pos}) + table.insert(chars.all_nop,{'xxx2',k,stream_pos}) + return error.ok + end + + + opcodes.func[opcodes.xxx3]= function() + local stream_pos = gfdata_index + local b0 = byte(readbytes(1)) + local b1 = byte(readbytes(1)) + local b2 = byte(readbytes(1)) + local k = readbytes(b2+ b1*256+b0*65536) + table.insert(chars.xxx3,{k,stream_pos}) + table.insert(chars.all_nop,{'xxx3', k,stream_pos}) + return error.ok + end + + opcodes.func[opcodes.xxx4]= function() + local stream_pos = gfdata_index + local k = readbytes(read4bytes()) + -- k must be positive + if k<=0 then + k = k +4294967296 + end + table.insert(chars.xxx4,{k,stream_pos}) + table.insert(chars.all_nop,{'xxx4',k,stream_pos}) + return error.ok + end + + opcodes.func[opcodes.yyy]= function() + local stream_pos = gfdata_index + local v = read4bytes() + table.insert(chars.yyy,{v,stream_pos}) + table.insert(chars.all_nop,{'yyy',v,stream_pos}) + return error.ok + end + + opcodes.func[opcodes.nop]= function() + table.insert(chars.nop,gfdata_index) + table.insert(chars.all_nop,{'nop','',gfdata_index}) + return error.ok + end + + opcodes.func[opcodes.char_loc]= function() + local c = byte(readbytes(1)) + local dx = read4bytes() + local dy = read4bytes() + local w = read4bytes() + local p = read4bytes() + local char_locator = {} + char_locator['c'] = c + char_locator['dx'] = dx + char_locator['dy'] = dy + char_locator['w'] = w + char_locator['p'] = p + table.insert(chars.locators,char_locator) + return error.ok + end + + + opcodes.func[opcodes.char_loc0]= function() + local c = byte(readbytes(1)) + local dm = byte(readbytes(1)) + local w = read4bytes() + local p = read4bytes() + local dy = 0 + local dx = 65536*dm + local char_locator = {} + char_locator['c'] = c + char_locator['dx'] = dx + char_locator['dy'] = dy + char_locator['w'] = w + char_locator['p'] = p + table.insert(chars.locators,char_locator) + return error.ok + end + + + opcodes.func[opcodes.pre]= function() + local i = byte(readbytes(1)) + local k = byte(readbytes(1)) + local x = readbytes(k) + chars.GF_format = i + chars.GF_comment = x + return error.ok + end + + opcodes.func[opcodes.post]= function() + local p = read4bytes() + local ds = read4bytes() + local cs = read4bytes() + local hppp = read4bytes() + local vppp = read4bytes() + local min_m = read4bytes() + local max_m = read4bytes() + local min_n = read4bytes() + local max_n = read4bytes() + chars['ds'] = ds + chars['cs'] = cs + chars['hppp'] = hppp + chars['vppp'] = vppp + chars['min_m'] = min_m + chars['max_m'] = max_m + chars['min_n'] = min_n + chars['max_n'] = max_n + return error.ok + end + + opcodes.func[opcodes.post_post]= function() + local q = read4bytes() + local i = byte(readbytes(1)) + local pad223 = readbytes(4) + if ( pad223~='\223\223\223\223' ) then + GF.error("error post_post_1 "..pad223) + return error.post_post + end + if gfdata_index <=gfdata_len then + local s = readuntileof() + local ctr223 = rep('\223',len(s)) + if ctr223 ~= s then + GF.error("error post_post_2 "..pad223) + return error.post_post + end + end + chars.GF_format_post = i + return error.ok + end + + opcodes.func[opcodes.undefined_1]= function() + GF.warning("undefined command 1") + return error.ok + end + opcodes.func[opcodes.undefined_2]= function() + GF.warning("undefined command 2") + return error.ok + end + opcodes.func[opcodes.undefined_3]= function() + GF.warning("undefined command 3") + return error.ok + end + opcodes.func[opcodes.undefined_4]= function() + GF.warning("undefined command 4") + return error.ok + end + opcodes.func[opcodes.undefined_5]= function() + GF.warning("undefined command 5") + return error.ok + end + opcodes.func[opcodes.undefined_6]= function() + GF.warning("undefined command 6") + return error.ok + end + + + + -------------------------------------------------------------------------------- + -- + -------------------------------------------------------------------------------- + + local function load(gffile) + gfdata = '' + local f,res = io.open(gffile,'rb') + if f==nil then + GF.error(res) + gfdata_index=0 + return error.load + else + gfdata = f:read("*a") + gfdata_len = len(gfdata) + gfdata_index =1 + end + f:close() + return error.ok + end + + + local function parse_pre() + gfdata_index=1 + local res = error.ok + local b = byte(readbytes(1)) + if b==opcodes.pre then + local i=byte(readbytes(1)) + local k=byte(readbytes(1)) + local x=readbytes(k) + chars.GF_format=i + chars.comments=x + else + GF.error("error parsing pre") + res = error.pre + end + return res + end + + + local function parse_rest() + local b = byte(readbytes(1)) + local func = opcodes.func + local res = error.ok + local cond = true + while (cond) do + if func[b] then + res = (func[b])() + if res~=error.ok then + cond = false + elseif datanotfinished() then + b = byte(readbytes(1)) + else + res = error.ok + cond = false + end + else + cond = false + GF.error("wrong opcode while parsing char") + res = error.parsechar + end + end + return res + end + + + local function parse() + if gfdata_len == 0 then + GF.error("no data") + return error.parse + end + local res + res = parse_pre() + if res~=error.ok then + GF.error("wrong preamble") + return res + end + res = parse_rest() + if not(res==error.ok) then + GF.error("error while reading characters") + return res + end + return res + end + + + ---------------------------------------------------------------------------------- + -- Parse from the end + ---------------------------------------------------------------------------------- + + local function skip223() + local i = gfdata_len + local cond = true + while cond do + local c = byte(sub(gfdata,i,i)) + if c==223 then + i=i-1 + else + cond=false + end + end + if i<3 then + GF.error("error skip suffix ") + res = error.skip223 + else + res = error.ok + gfdata_index = i + end + return res + end + + + local function parse_char_fromlocator() + local cond = true + local func = opcodes.func + local b,res + while cond do + b = byte(readbytes(1)) + if func[b] then + res = (func[b])() + if res ~= error.ok then + cond = false + return res + elseif b==opcodes.eoc then + cond = false + else + cond = true + end + else + GF.error("wrong char from locator") + cond = false + return error.parse + end + end + if chars[current_char] and chars[current_char].p == -1 then + return error.ok + end + moveindex_after(chars[current_char].p) + return parse_char_fromlocator() + + end + + local function parse_from_end() + if gfdata_len == 0 then + GF.error("no data") + return error.parse + end + local res = error.ok + gfdata_index = gfdata_len + res = skip223() + if res ~= error.ok then + return res + end + -- + -- read identification byte + -- + chars.GF_format_post = byte(readbytes(-1)) + -- + -- read post_post + -- + local q = readrev4bytes() + if q<=0 then + q = q +4294967296 + end + if q<1 or q>gfdata_len then + GF.error("wrong pointer to post") + return error.parse + end + -- + -- reading post + -- + moveindex_after(q) + q = byte(readbytes(1)) + if q~=opcodes.post then + GF.error("expected post opcode") + return error.parse + end + -- + res = opcodes.func[opcodes.post]() + if res~=error.ok then + GF.error("reading postamble") + return error.parse + end + -- + -- read char locators + -- + local cond = true + local char_loc = opcodes.char_loc + local char_loc0 = opcodes.char_loc0 + local post_post = opcodes.post_post + local f = opcodes.func + while cond do + q = byte(readbytes(1)) + if q==char_loc or q==char_loc0 then + f[q]() + elseif q==post_post then + cond = false + res = error.ok + else + GF.error("reading char locators") + cond = false + return error.parse + end + end + -- + -- read chars + -- + if #chars.locators == 0 then + GF.error("no char locators") + return error.parse + end + for i,v in ipairs(chars.locators) do + local p = v.p + if p>-1 then + moveindex_after(p) + res = parse_char_fromlocator() + if res ~= error.ok then + break; + end + end + end + return res + end + + + -------------------------------------------------------------------------------- + + -- Already assigned before: + -- GF.warning = warning_msg + -- GF.error = error_msg + GF.load = load + GF.parse = parse + GF.chars = chars + GF.errorcode = error + GF.error_name = error_name + GF.parse_from_end = parse_from_end + -- + -- TODO: parsing by reading a file + -- + + +end +-- Add GF to the mflua table +mflua.GF = GF -- cgit v1.2.3