diff options
24 files changed, 690 insertions, 733 deletions
diff --git a/Build/source/texk/web2c/luatexdir/NEWS b/Build/source/texk/web2c/luatexdir/NEWS index 5e6a9e4eb61..47f8bc4c783 100644 --- a/Build/source/texk/web2c/luatexdir/NEWS +++ b/Build/source/texk/web2c/luatexdir/NEWS @@ -2,19 +2,6 @@ This file is in the public domain. ============================================================== -LuaTeX Release 0.95 -============================================================== -- this is an experimental version - -- glues now have gluespec merged in (idem math and insert) -- registers are still glue specs -- extra tex.setglue and tex.setmuglue -- obsolete dvi related dir fields removed - - - - -============================================================== LuaTeX Release 0.90.0 was released 2016032512 ============================================================== @@ -2702,7 +2689,7 @@ Other news: we probably introduced new problems as well). * Most (all?) files now have a corrected Copyright header, - and link in $Id: NEWS 5903 2016-03-31 15:49:44Z luigi $ and $URL: https://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/NEWS $ into the object file. + and link in $Id: NEWS 5886 2016-03-25 12:13:10Z luigi $ and $URL: https://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/NEWS $ into the object file. * Some unnecessary files were removed from the distribution. diff --git a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c index 5511805d928..3a8982604c6 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c @@ -185,6 +185,30 @@ } \ } while (0) +#define nodelib_check_glue_spec(n,g,field) do { \ + g = glue_ptr(n); \ + v = (halfword) lua_tointeger(L, 3); \ + if (!g) { \ + g = new_node(glue_spec_node,0); \ + add_glue_ref(g); \ + glue_ptr(n) = g; \ + field(g) = v; \ + } else if (field(g) != v) { \ + if (valid_node(g)) { \ + int c = new_spec(g); \ + delete_glue_ref(g); \ + add_glue_ref(c); \ + glue_ptr(n) = c; \ + field(c) = v; \ + } else { \ + g = new_spec(g); \ + add_glue_ref(g); \ + glue_ptr(n) = g; \ + field(g) = v; \ + } \ + } \ +} while (0) + #define nodelib_setattr(L, s, n) reassign_attribute(n,nodelib_getlist(L,s)) #define nodelib_gettoks(L,a) tokenlist_from_lua(L) @@ -196,6 +220,7 @@ #define nodelib_pushlist(L,n) { lua_pushinteger(L,n); lua_nodelib_push(L); } /* can be: fast_metatable_or_nil(n) */ #define nodelib_pushattr(L,n) { lua_pushinteger(L,n); lua_nodelib_push(L); } /* can be: fast_metatable_or_nil(n) */ +#define nodelib_pushspec(L,n) { lua_pushinteger(L,n); lua_nodelib_push_spec(L); } /* can be: fast_metatable_or_nil(n) - different criterium? */ #define nodelib_pushaction(L,n) { lua_pushinteger(L,n); lua_nodelib_push(L); } /* can be: fast_metatable_or_nil(n) */ #define nodelib_pushstring(L,n) { char *ss=makecstring(n); lua_pushstring(L,ss); free(ss); } @@ -371,6 +396,27 @@ void lua_nodelib_push(lua_State * L) return; } +/* |spec_ptr| fields can legally be zero, which is why there is a special function. */ + +static void lua_nodelib_push_spec(lua_State * L) +{ + halfword n; + halfword *a; + n = -1; + if (lua_type(L, -1) == LUA_TNUMBER) + n = (halfword) lua_tointeger(L, -1); + lua_pop(L, 1); + if ((n < 0) || (n > var_mem_max)) { + lua_pushnil(L); + } else { + a = lua_newuserdata(L, sizeof(halfword)); + *a = n; + lua_get_metatablelua(luatex_node); + lua_setmetatable(L, -2); + } + return; +} + void lua_nodelib_push_fast(lua_State * L, halfword n) { halfword *a; @@ -2352,13 +2398,14 @@ static int lua_nodelib_unset_attribute(lua_State * L) static int lua_nodelib_direct_unset_attribute(lua_State * L) { + int i, val, ret; halfword n = lua_tointeger(L, 1); if (n == null) { lua_pushnil(L); } else if (lua_gettop(L) <= 3) { /* a useless test, we never test for that elsewhere */ - int i = (int)luaL_checknumber(L, 2); - int val = (int)luaL_optnumber(L, 3, UNUSED_ATTRIBUTE); - int ret = unset_attribute(n, i, val); + i=(int)luaL_checknumber(L, 2); + val=(int)luaL_optnumber(L, 3, UNUSED_ATTRIBUTE); + ret = unset_attribute(n, i, val); if (ret > UNUSED_ATTRIBUTE) { lua_pushinteger(L, ret); } else { @@ -2370,92 +2417,6 @@ static int lua_nodelib_direct_unset_attribute(lua_State * L) return 1; } -/* glue */ - -static int lua_nodelib_set_glue(lua_State * L) -{ - halfword n = *check_isnode(L, 1); - int top = lua_gettop(L) ; - if ((n != null) && (type(n) == glue_node || type(n) == glue_spec_node)) { - width(n) = ((top > 1 && lua_type(L, n) == LUA_TNUMBER)) ? lua_tointeger(L,2) : 0; - stretch(n) = ((top > 2 && lua_type(L, n) == LUA_TNUMBER)) ? lua_tointeger(L,3) : 0; - shrink(n) = ((top > 3 && lua_type(L, n) == LUA_TNUMBER)) ? lua_tointeger(L,4) : 0; - stretch_order(n) = ((top > 4 && lua_type(L, n) == LUA_TNUMBER)) ? lua_tointeger(L,5) : 0; - shrink_order(n) = ((top > 5 && lua_type(L, n) == LUA_TNUMBER)) ? lua_tointeger(L,6) : 0; - return 0; - } else { - return luaL_error(L, "glue (spec) expected"); - } -} - -static int lua_nodelib_direct_set_glue(lua_State * L) -{ - halfword n = lua_tointeger(L, 1); - int top = lua_gettop(L) ; - if ((n != null) && (type(n) == glue_node || type(n) == glue_spec_node)) { - width(n) = ((top > 1 && lua_type(L, n) == LUA_TNUMBER)) ? lua_tointeger(L,2) : 0; - stretch(n) = ((top > 2 && lua_type(L, n) == LUA_TNUMBER)) ? lua_tointeger(L,3) : 0; - shrink(n) = ((top > 3 && lua_type(L, n) == LUA_TNUMBER)) ? lua_tointeger(L,4) : 0; - stretch_order(n) = ((top > 4 && lua_type(L, n) == LUA_TNUMBER)) ? lua_tointeger(L,5) : 0; - shrink_order(n) = ((top > 5 && lua_type(L, n) == LUA_TNUMBER)) ? lua_tointeger(L,6) : 0; - return 0; - } else { - return luaL_error(L, "glue (spec) expected"); - } -} - -static int lua_nodelib_get_glue(lua_State * L) -{ - halfword n = *check_isnode(L, 1); - if ((n != null) && (type(n) == glue_node || type(n) == glue_spec_node)) { - lua_pushinteger(L,width(n)); - lua_pushinteger(L,stretch(n)); - lua_pushinteger(L,shrink(n)); - lua_pushinteger(L,stretch_order(n)); - lua_pushinteger(L,shrink_order(n)); - return 5; - } else { - return luaL_error(L, "glue (spec) expected"); - } -} - -static int lua_nodelib_direct_get_glue(lua_State * L) -{ - halfword n = lua_tointeger(L, 1); - if ((n != null) && (type(n) == glue_node || type(n) == glue_spec_node)) { - lua_pushinteger(L,width(n)); - lua_pushinteger(L,stretch(n)); - lua_pushinteger(L,shrink(n)); - lua_pushinteger(L,stretch_order(n)); - lua_pushinteger(L,shrink_order(n)); - return 5; - } else { - return luaL_error(L, "glue (spec) expected"); - } -} - -static int lua_nodelib_is_zero_glue(lua_State * L) -{ - halfword n = *check_isnode(L, 1); - if ((n != null) && (type(n) == glue_node || type(n) == glue_spec_node)) { - lua_toboolean(L,(width(n) == 0 && stretch(n) == 0 && shrink(n) == 0)); - return 1; - } else { - return luaL_error(L, "glue (spec) expected"); - } -} - -static int lua_nodelib_direct_is_zero_glue(lua_State * L) -{ - halfword n = lua_tointeger(L, 1); - if ((n != null) && (type(n) == glue_node || type(n) == glue_spec_node)) { - lua_toboolean(L,(width(n) == 0 && stretch(n) == 0 && shrink(n) == 0)); - return 1; - } else { - return luaL_error(L, "glue (spec) expected"); - } -} - /* iteration */ static int nodelib_aux_nil(lua_State * L) @@ -2829,6 +2790,12 @@ static int nodelib_cantset(lua_State * L, int n, const char *s) return 0; } +static int nodelib_nonwritable(lua_State * L, int n, const char *s) +{ + luaL_error(L,"You cannot set field %s in a non writable node of type %s",s,node_data[type(n)].name); + return 0; +} + /* node.direct.getfield */ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, const char *s) @@ -3194,6 +3161,31 @@ static int lua_nodelib_fast_getfield(lua_State * L) } else if (t == glue_node) { if (lua_key_eq(s, subtype)) { lua_pushinteger(L, subtype(n)); + } else if (lua_key_eq(s, spec)) { + nodelib_pushspec(L, glue_ptr(n)); + } else if (lua_key_eq(s, leader)) { + fast_metatable_or_nil(leader_ptr(n)); + } else { + n = glue_ptr(n); + if (!n) { + lua_pushinteger(L, 0); /* zero skip constant */ + } else if (lua_key_eq(s, width)) { + lua_pushinteger(L, width(n)); + } else if (lua_key_eq(s, stretch)) { + lua_pushinteger(L, stretch(n)); + } else if (lua_key_eq(s, shrink)) { + lua_pushinteger(L, shrink(n)); + } else if (lua_key_eq(s, stretch_order)) { + lua_pushinteger(L, stretch_order(n)); + } else if (lua_key_eq(s, shrink_order)) { + lua_pushinteger(L, shrink_order(n)); + } else { + lua_pushnil(L); + } + } + } else if (t == glue_spec_node) { + if (lua_key_eq(s, subtype)) { + lua_pushinteger(L, 0); /* dummy, the only one that prevents move up */ } else if (lua_key_eq(s, width)) { lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, stretch)) { @@ -3204,8 +3196,10 @@ static int lua_nodelib_fast_getfield(lua_State * L) lua_pushinteger(L, stretch_order(n)); } else if (lua_key_eq(s, shrink_order)) { lua_pushinteger(L, shrink_order(n)); - } else if (lua_key_eq(s, leader)) { - fast_metatable_or_nil(leader_ptr(n)); + } else if (lua_key_eq(s, ref_count)) { + lua_pushinteger(L, glue_ref_count(n)); + } else if (lua_key_eq(s, writable)) { + lua_pushboolean(L, valid_node(n)); } else { lua_pushnil(L); } @@ -3251,8 +3245,10 @@ static int lua_nodelib_fast_getfield(lua_State * L) lua_push_dir_text(L, dir_dir(n)); } else if (lua_key_eq(s, level)) { lua_pushinteger(L, dir_level(n)); - } else if (lua_key_eq(s, subtype)) { /* can be used for anything */ - lua_pushinteger(L, subtype(n)); + } else if (lua_key_eq(s, dvi_ptr)) { + lua_pushinteger(L, dir_dvi_ptr(n)); + } else if (lua_key_eq(s, dir_h)) { + lua_pushinteger(L, dir_dvi_h(n)); } else { lua_pushnil(L); } @@ -3276,20 +3272,6 @@ static int lua_nodelib_fast_getfield(lua_State * L) } else { lua_pushnil(L); } - } else if (t == glue_spec_node) { - if (lua_key_eq(s, width)) { - lua_pushinteger(L, width(n)); - } else if (lua_key_eq(s, stretch)) { - lua_pushinteger(L, stretch(n)); - } else if (lua_key_eq(s, shrink)) { - lua_pushinteger(L, shrink(n)); - } else if (lua_key_eq(s, stretch_order)) { - lua_pushinteger(L, stretch_order(n)); - } else if (lua_key_eq(s, shrink_order)) { - lua_pushinteger(L, shrink_order(n)); - } else { - lua_pushnil(L); - } } else if (t == whatsit_node) { if (lua_key_eq(s, subtype)) { lua_pushinteger(L, subtype(n)); @@ -3340,19 +3322,10 @@ static int lua_nodelib_fast_getfield(lua_State * L) lua_pushinteger(L, depth(n)); } else if (lua_key_eq(s, height)) { lua_pushinteger(L, height(n)); - } else if ((lua_key_eq(s, list)) || (lua_key_eq(s, head))) { /* already mapped */ + } else if (lua_key_eq(s, spec)) { + nodelib_pushspec(L, split_top_ptr(n)); + } else if ((lua_key_eq(s, list)) || (lua_key_eq(s, head))) { fast_metatable_or_nil_alink(ins_ptr(n)); - /* glue parameters */ - } else if (lua_key_eq(s, width)) { - lua_pushinteger(L, width(n)); - } else if (lua_key_eq(s, stretch)) { - lua_pushinteger(L, stretch(n)); - } else if (lua_key_eq(s, shrink)) { - lua_pushinteger(L, shrink(n)); - } else if (lua_key_eq(s, stretch_order)) { - lua_pushinteger(L, stretch_order(n)); - } else if (lua_key_eq(s, shrink_order)) { - lua_pushinteger(L, shrink_order(n)); } else { lua_pushnil(L); } @@ -3361,17 +3334,6 @@ static int lua_nodelib_fast_getfield(lua_State * L) lua_pushinteger(L, subtype(n)); } else if (lua_key_eq(s, surround)) { lua_pushinteger(L, surround(n)); - /* glue parameters */ - } else if (lua_key_eq(s, width)) { - lua_pushinteger(L, width(n)); - } else if (lua_key_eq(s, stretch)) { - lua_pushinteger(L, stretch(n)); - } else if (lua_key_eq(s, shrink)) { - lua_pushinteger(L, shrink(n)); - } else if (lua_key_eq(s, stretch_order)) { - lua_pushinteger(L, stretch_order(n)); - } else if (lua_key_eq(s, shrink_order)) { - lua_pushinteger(L, shrink_order(n)); } else { lua_pushnil(L); } @@ -3938,6 +3900,29 @@ static int lua_nodelib_direct_getfield(lua_State * L) lua_pushnil(L); } } else if (t == glue_node) { + if (lua_key_eq(s, spec)) { + nodelib_pushdirect(glue_ptr(n)); + } else if (lua_key_eq(s, leader)) { + nodelib_pushdirect_or_nil(leader_ptr(n)); + } else { + n = glue_ptr(n); + if (!n) { + lua_pushinteger(L, 0); /* zero skip constant */ + } else if (lua_key_eq(s, width)) { + lua_pushinteger(L, width(n)); + } else if (lua_key_eq(s, stretch)) { + lua_pushinteger(L, stretch(n)); + } else if (lua_key_eq(s, shrink)) { + lua_pushinteger(L, shrink(n)); + } else if (lua_key_eq(s, stretch_order)) { + lua_pushinteger(L, stretch_order(n)); + } else if (lua_key_eq(s, shrink_order)) { + lua_pushinteger(L, shrink_order(n)); + } else { + lua_pushnil(L); + } + } + } else if (t == glue_spec_node) { if (lua_key_eq(s, width)) { lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, stretch)) { @@ -3948,8 +3933,10 @@ static int lua_nodelib_direct_getfield(lua_State * L) lua_pushinteger(L, stretch_order(n)); } else if (lua_key_eq(s, shrink_order)) { lua_pushinteger(L, shrink_order(n)); - } else if (lua_key_eq(s, leader)) { - nodelib_pushdirect_or_nil(leader_ptr(n)); + } else if (lua_key_eq(s, ref_count)) { + lua_pushinteger(L, glue_ref_count(n)); + } else if (lua_key_eq(s, writable)) { + lua_pushboolean(L, valid_node(n)); } else { lua_pushnil(L); } @@ -3986,11 +3973,13 @@ static int lua_nodelib_direct_getfield(lua_State * L) } } else if (t == dir_node) { if (lua_key_eq(s, dir)) { - lua_push_dir_text(L, dir_dir(n)); + lua_push_dir_text(L, dir_dir(n)); } else if (lua_key_eq(s, level)) { lua_pushinteger(L, dir_level(n)); - } else if (lua_key_eq(s, subtype)) { /* can be used for anything */ - lua_pushinteger(L, subtype(n)); + } else if (lua_key_eq(s, dvi_ptr)) { + lua_pushinteger(L, dir_dvi_ptr(n)); + } else if (lua_key_eq(s, dir_h)) { + lua_pushinteger(L, dir_dvi_h(n)); } else { lua_pushnil(L); } @@ -4049,36 +4038,16 @@ static int lua_nodelib_direct_getfield(lua_State * L) lua_pushinteger(L, depth(n)); } else if (lua_key_eq(s, height)) { lua_pushinteger(L, height(n)); + } else if (lua_key_eq(s, spec)) { + nodelib_pushdirect_or_nil(split_top_ptr(n)); } else if ((lua_key_eq(s, list)) || (lua_key_eq(s, head))) { nodelib_pushdirect_or_nil_alink(ins_ptr(n)); - /* glue */ - } else if (lua_key_eq(s, width)) { - lua_pushinteger(L, width(n)); - } else if (lua_key_eq(s, stretch)) { - lua_pushinteger(L, stretch(n)); - } else if (lua_key_eq(s, shrink)) { - lua_pushinteger(L, shrink(n)); - } else if (lua_key_eq(s, stretch_order)) { - lua_pushinteger(L, stretch_order(n)); - } else if (lua_key_eq(s, shrink_order)) { - lua_pushinteger(L, shrink_order(n)); } else { lua_pushnil(L); } } else if (t == math_node) { if (lua_key_eq(s, surround)) { lua_pushinteger(L, surround(n)); - /* glue */ - } else if (lua_key_eq(s, width)) { - lua_pushinteger(L, width(n)); - } else if (lua_key_eq(s, stretch)) { - lua_pushinteger(L, stretch(n)); - } else if (lua_key_eq(s, shrink)) { - lua_pushinteger(L, shrink(n)); - } else if (lua_key_eq(s, stretch_order)) { - lua_pushinteger(L, stretch_order(n)); - } else if (lua_key_eq(s, shrink_order)) { - lua_pushinteger(L, shrink_order(n)); } else { lua_pushnil(L); } @@ -4244,20 +4213,6 @@ static int lua_nodelib_direct_getfield(lua_State * L) } else { lua_pushnil(L); } - } else if (t == glue_spec_node) { - if (lua_key_eq(s, width)) { - lua_pushinteger(L, width(n)); - } else if (lua_key_eq(s, stretch)) { - lua_pushinteger(L, stretch(n)); - } else if (lua_key_eq(s, shrink)) { - lua_pushinteger(L, shrink(n)); - } else if (lua_key_eq(s, stretch_order)) { - lua_pushinteger(L, stretch_order(n)); - } else if (lua_key_eq(s, shrink_order)) { - lua_pushinteger(L, shrink_order(n)); - } else { - lua_pushnil(L); - } } else { lua_pushnil(L); } @@ -5103,6 +5058,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, const char *s) static int lua_nodelib_fast_setfield(lua_State * L) { + halfword g, v; const char *s; halfword n = *((halfword *) lua_touserdata(L, 1)); int t = type(n); @@ -5216,6 +5172,28 @@ static int lua_nodelib_fast_setfield(lua_State * L) } else if (t == glue_node) { if (lua_key_eq(s, subtype)) { subtype(n) = (quarterword) lua_tointeger(L, 3); + } else if (lua_key_eq(s, spec)) { + glue_ptr(n) = nodelib_getspec(L, 3); + } else if (lua_key_eq(s, leader)) { + leader_ptr(n) = nodelib_getlist(L, 3); + } else if (lua_key_eq(s, width)) { + nodelib_check_glue_spec(n, g, width); + } else if (lua_key_eq(s, stretch)) { + nodelib_check_glue_spec(n, g, stretch); + } else if (lua_key_eq(s, shrink)) { + nodelib_check_glue_spec(n, g, shrink); + } else if (lua_key_eq(s, stretch_order)) { + nodelib_check_glue_spec(n, g, stretch_order); + } else if (lua_key_eq(s, shrink_order)) { + nodelib_check_glue_spec(n, g, shrink_order); + } else { + return nodelib_cantset(L, n, s); + } + } else if (t == glue_spec_node) { + if (!valid_node(n)) { + return nodelib_nonwritable(L, n, s); + } else if (lua_key_eq(s, subtype)) { + subtype(n) = (quarterword) lua_tointeger(L, 3); /* dummy, the only one that prevents move up */ } else if (lua_key_eq(s, width)) { width(n) = (halfword) lua_tointeger(L, 3); } else if (lua_key_eq(s, stretch)) { @@ -5226,8 +5204,6 @@ static int lua_nodelib_fast_setfield(lua_State * L) stretch_order(n) = (quarterword) lua_tointeger(L, 3); } else if (lua_key_eq(s, shrink_order)) { shrink_order(n) = (quarterword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, leader)) { - leader_ptr(n) = nodelib_getlist(L, 3); } else { return nodelib_cantset(L, n, s); } @@ -5272,8 +5248,10 @@ static int lua_nodelib_fast_setfield(lua_State * L) dir_dir(n) = nodelib_getdir(L, 3, 0); } else if (lua_key_eq(s, level)) { dir_level(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, subtype)) { /* can be used for anything */ - subtype(n) = (quarterword) lua_tointeger(L, 3); + } else if (lua_key_eq(s, dvi_ptr)) { + dir_dvi_ptr(n) = (halfword) lua_tointeger(L, 3); + } else if (lua_key_eq(s, dir_h)) { + dir_dvi_h(n) = (halfword) lua_tointeger(L, 3); } else { return nodelib_cantset(L, n, s); } @@ -5342,19 +5320,10 @@ static int lua_nodelib_fast_setfield(lua_State * L) depth(n) = (halfword) lua_tointeger(L, 3); } else if (lua_key_eq(s, height)) { height(n) = (halfword) lua_tointeger(L, 3); + } else if (lua_key_eq(s, spec)) { + split_top_ptr(n) = nodelib_getspec(L, 3); } else if ((lua_key_eq(s, list)) || (lua_key_eq(s, head))) { ins_ptr(n) = nodelib_getlist(L, 3); - /* glue */ - } else if (lua_key_eq(s, width)) { - width(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, stretch)) { - stretch(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, shrink)) { - shrink(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, stretch_order)) { - stretch_order(n) = (quarterword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, shrink_order)) { - shrink_order(n) = (quarterword) lua_tointeger(L, 3); } else { return nodelib_cantset(L, n, s); } @@ -5363,17 +5332,6 @@ static int lua_nodelib_fast_setfield(lua_State * L) subtype(n) = (quarterword) lua_tointeger(L, 3); } else if (lua_key_eq(s, surround)) { surround(n) = (halfword) lua_tointeger(L, 3); - /* glue */ - } else if (lua_key_eq(s, width)) { - width(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, stretch)) { - stretch(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, shrink)) { - shrink(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, stretch_order)) { - stretch_order(n) = (quarterword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, shrink_order)) { - shrink_order(n) = (quarterword) lua_tointeger(L, 3); } else { return nodelib_cantset(L, n, s); } @@ -5571,20 +5529,6 @@ static int lua_nodelib_fast_setfield(lua_State * L) } else { return nodelib_cantset(L, n, s); } - } else if (t == glue_spec_node) { - if (lua_key_eq(s, width)) { - width(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, stretch)) { - stretch(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, shrink)) { - shrink(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, stretch_order)) { - stretch_order(n) = (quarterword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, shrink_order)) { - shrink_order(n) = (quarterword) lua_tointeger(L, 3); - } else { - return nodelib_cantset(L, n, s); - } } else { return luaL_error(L, "You can't assign to this %s node (%d)\n", node_data[t].name, n); } @@ -5990,6 +5934,7 @@ static int lua_nodelib_direct_setdiscretionary(lua_State * L) static int lua_nodelib_direct_setfield(lua_State * L) { + halfword g, v; const char *s; halfword n = lua_tointeger(L, 1); @@ -6104,6 +6049,28 @@ static int lua_nodelib_direct_setfield(lua_State * L) } else if (t == glue_node) { if (lua_key_eq(s, subtype)) { subtype(n) = (quarterword) lua_tointeger(L, 3); + } else if (lua_key_eq(s, spec)) { + glue_ptr(n) = nodelib_popdirect(3); + } else if (lua_key_eq(s, leader)) { + leader_ptr(n) = nodelib_popdirect(3); + } else if (lua_key_eq(s, width)) { + nodelib_check_glue_spec(n, g, width); + } else if (lua_key_eq(s, stretch)) { + nodelib_check_glue_spec(n, g, stretch); + } else if (lua_key_eq(s, shrink)) { + nodelib_check_glue_spec(n, g, shrink); + } else if (lua_key_eq(s, stretch_order)) { + nodelib_check_glue_spec(n, g, stretch_order); + } else if (lua_key_eq(s, shrink_order)) { + nodelib_check_glue_spec(n, g, shrink_order); + } else { + return nodelib_cantset(L, n, s); + } + } else if (t == glue_spec_node) { + if (!valid_node(n)) { + return nodelib_nonwritable(L, n, s); + } else if (lua_key_eq(s, subtype)) { + subtype(n) = (quarterword) lua_tointeger(L, 3); /* dummy, the only one that prevents move up */ } else if (lua_key_eq(s, width)) { width(n) = (halfword) lua_tointeger(L, 3); } else if (lua_key_eq(s, stretch)) { @@ -6114,8 +6081,6 @@ static int lua_nodelib_direct_setfield(lua_State * L) stretch_order(n) = (quarterword) lua_tointeger(L, 3); } else if (lua_key_eq(s, shrink_order)) { shrink_order(n) = (quarterword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, leader)) { - leader_ptr(n) = nodelib_popdirect(3); } else { return nodelib_cantset(L, n, s); } @@ -6160,12 +6125,14 @@ static int lua_nodelib_direct_setfield(lua_State * L) dir_dir(n) = nodelib_getdir(L, 3, 0); } else if (lua_key_eq(s, level)) { dir_level(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, subtype)) { /* can be used for anything */ - subtype(n) = (quarterword) lua_tointeger(L, 3); + } else if (lua_key_eq(s, dvi_ptr)) { + dir_dvi_ptr(n) = (halfword) lua_tointeger(L, 3); + } else if (lua_key_eq(s, dir_h)) { + dir_dvi_h(n) = (halfword) lua_tointeger(L, 3); } else { return nodelib_cantset(L, n, s); } - } else if (t == whatsit_node) { + } else if (t == whatsit_node) { if (lua_key_eq(s, subtype)) { subtype(n) = (quarterword) lua_tointeger(L, 3); } else { @@ -6230,19 +6197,10 @@ static int lua_nodelib_direct_setfield(lua_State * L) depth(n) = (halfword) lua_tointeger(L, 3); } else if (lua_key_eq(s, height)) { height(n) = (halfword) lua_tointeger(L, 3); + } else if (lua_key_eq(s, spec)) { + split_top_ptr(n) = nodelib_popdirect(3); } else if ((lua_key_eq(s, list)) || (lua_key_eq(s, head))) { ins_ptr(n) = nodelib_popdirect(3); - /* glue */ - } else if (lua_key_eq(s, width)) { - width(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, stretch)) { - stretch(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, shrink)) { - shrink(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, stretch_order)) { - stretch_order(n) = (quarterword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, shrink_order)) { - shrink_order(n) = (quarterword) lua_tointeger(L, 3); } else { return nodelib_cantset(L, n, s); } @@ -6251,17 +6209,6 @@ static int lua_nodelib_direct_setfield(lua_State * L) subtype(n) = (quarterword) lua_tointeger(L, 3); } else if (lua_key_eq(s, surround)) { surround(n) = (halfword) lua_tointeger(L, 3); - /* glue */ - } else if (lua_key_eq(s, width)) { - width(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, stretch)) { - stretch(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, shrink)) { - shrink(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, stretch_order)) { - stretch_order(n) = (quarterword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, shrink_order)) { - shrink_order(n) = (quarterword) lua_tointeger(L, 3); } else { return nodelib_cantset(L, n, s); } @@ -6459,20 +6406,6 @@ static int lua_nodelib_direct_setfield(lua_State * L) } else { return nodelib_cantset(L, n, s); } - } else if (t == glue_spec_node) { - if (lua_key_eq(s, width)) { - width(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, stretch)) { - stretch(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, shrink)) { - shrink(n) = (halfword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, stretch_order)) { - stretch_order(n) = (quarterword) lua_tointeger(L, 3); - } else if (lua_key_eq(s, shrink_order)) { - shrink_order(n) = (quarterword) lua_tointeger(L, 3); - } else { - return nodelib_cantset(L, n, s); - } } else { return luaL_error(L, "You can't assign to this %s node (%d)\n", node_data[t].name, n); } @@ -6756,16 +6689,17 @@ static int lua_nodelib_effective_glue(lua_State * L) if ((glue == NULL) || (type(*glue) != glue_node)) { lua_pushnil(L) ; } else { - int w = width(*glue) ; + halfword s = glue_ptr(*glue); + int w = width(s) ; parent = lua_touserdata(L, 2); if ((parent != NULL) && ((type(*parent) == hlist_node) || (type(*parent) == vlist_node))) { if ((int)glue_sign(*parent) == 1) { - if (stretch_order(*glue) == glue_order(*parent)) { - w += stretch(*glue) * glue_set(*parent); + if (stretch_order(s) == glue_order(*parent)) { + w += stretch(s) * glue_set(*parent); } } else if (glue_sign(*parent) == 2) { - if (shrink_order(*glue) == glue_order(*parent)) { - w -= shrink(*glue) * glue_set(*parent); + if (shrink_order(s) == glue_order(*parent)) { + w -= shrink(s) * glue_set(*parent); } } } @@ -6781,16 +6715,17 @@ static int lua_nodelib_direct_effective_glue(lua_State * L) if ((glue == null) || (type(glue) != glue_node)) { lua_pushnil(L) ; } else { - int w = width(glue) ; + halfword s = glue_ptr(glue); + int w = width(s) ; halfword parent = lua_tointeger(L, 2); if ((parent != null) && ((type(parent) == hlist_node) || (type(parent) == vlist_node))) { if ((int)glue_sign(parent) == 1) { - if (stretch_order(glue) == glue_order(parent)) { - w += stretch(glue) * glue_set(parent); + if (stretch_order(s) == glue_order(parent)) { + w += stretch(s) * glue_set(parent); } } else if (glue_sign(parent) == 2) { - if (shrink_order(glue) == glue_order(parent)) { - w -= shrink(glue) * glue_set(parent); + if (shrink_order(s) == glue_order(parent)) { + w -= shrink(s) * glue_set(parent); } } } @@ -6895,9 +6830,6 @@ static const struct luaL_Reg direct_nodelib_f[] = { /* {"types", lua_nodelib_types}, */ /* no node argument */ {"unprotect_glyphs", lua_nodelib_direct_unprotect_glyphs}, {"unset_attribute", lua_nodelib_direct_unset_attribute}, - {"setglue",lua_nodelib_direct_set_glue}, - {"getglue",lua_nodelib_direct_get_glue}, - {"is_zero_glue",lua_nodelib_direct_is_zero_glue}, {"usedlist", lua_nodelib_direct_usedlist}, {"vpack", lua_nodelib_direct_vpack}, /* {"whatsits", lua_nodelib_whatsits}, */ /* no node argument */ @@ -6978,9 +6910,6 @@ static const struct luaL_Reg nodelib_f[] = { {"types", lua_nodelib_types}, {"unprotect_glyphs", lua_nodelib_unprotect_glyphs}, {"unset_attribute", lua_nodelib_unset_attribute}, - {"setglue",lua_nodelib_set_glue}, - {"getglue",lua_nodelib_get_glue}, - {"is_zero_glue",lua_nodelib_is_zero_glue}, {"usedlist", lua_nodelib_usedlist}, {"vpack", lua_nodelib_vpack}, {"whatsits", lua_nodelib_whatsits}, diff --git a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c index 84627b2dc3f..b4bd9a3a63c 100644 --- a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c +++ b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c @@ -890,54 +890,6 @@ static int getskip(lua_State * L) return 1; } -static int setglue(lua_State * L) -{ - int isglobal = 0; - int index = 1; - halfword value = copy_node(zero_glue); - int top = lua_gettop(L); - check_item_global(L,top,isglobal); - if (isglobal) { - index = 2; - top -= 1; - } - /* [global] slot [width] [stretch] [shrink] [stretch_order] [shrink_order] */ - if (top > 1) { - width(value) = lua_tointeger(L,index+1); - } - if (top > 2) { - stretch(value) = lua_tointeger(L,index+2); - } - if (top > 3) { - shrink(value) = lua_tointeger(L,index+3); - } - if (top > 4) { - stretch_order(value) = lua_tointeger(L,index+4); - } - if (top > 5) { - shrink_order(value) = lua_tointeger(L,index+5); - } - set_item_index_plus(L, index, skip_base, "skip", value, isglobal, is_glue_assign, set_tex_skip_register, true); - return 0; -} - -static int getglue(lua_State * L) -{ - int value = 0; - get_item_index_plus(L, lua_gettop(L), skip_base, "skip", value, is_glue_assign, get_tex_skip_register, true); - if (value == null) { - lua_pushnil(L); - return 1; - } else { - lua_pushinteger(L,width(value)); - lua_pushinteger(L,stretch(value)); - lua_pushinteger(L,shrink(value)); - lua_pushinteger(L,stretch_order(value)); - lua_pushinteger(L,shrink_order(value)); - return 5; - } -} - static int ismuskip(lua_State * L) { check_register(mu_skip_base); @@ -962,54 +914,6 @@ static int getmuskip(lua_State * L) return 1; } -static int setmuglue(lua_State * L) -{ - int isglobal = 0; - int index = 1; - halfword value = copy_node(zero_glue); - int top = lua_gettop(L); - check_item_global(L,top,isglobal); - if (isglobal) { - index = 2; - top -= 1; - } - /* [global] slot [width] [stretch] [shrink] [stretch_order] [shrink_order] */ - if (top > 1) { - width(value) = lua_tointeger(L,index+1); - } - if (top > 2) { - stretch(value) = lua_tointeger(L,index+2); - } - if (top > 3) { - shrink(value) = lua_tointeger(L,index+3); - } - if (top > 4) { - stretch_order(value) = lua_tointeger(L,index+4); - } - if (top > 5) { - shrink_order(value) = lua_tointeger(L,index+5); - } - set_item_index_plus(L, index, mu_skip_base, "muskip", value, isglobal, is_mu_glue_assign, set_tex_mu_skip_register, true); - return 0; -} - -static int getmuglue(lua_State * L) -{ - int value = 0; - get_item_index_plus(L, lua_gettop(L), mu_skip_base, "muskip", value, is_mu_glue_assign, get_tex_mu_skip_register, true); - if (value == null) { - lua_pushnil(L); - return 1; - } else { - lua_pushinteger(L,width(value)); - lua_pushinteger(L,stretch(value)); - lua_pushinteger(L,shrink(value)); - lua_pushinteger(L,stretch_order(value)); - lua_pushinteger(L,shrink_order(value)); - return 5; - } -} - static int iscount(lua_State * L) { check_register(count_base); @@ -2965,13 +2869,9 @@ static const struct luaL_Reg texlib[] = { { "isskip", isskip }, { "setskip", setskip }, { "getskip", getskip }, - { "setglue", setglue }, - { "getglue", getglue }, { "ismuskip", ismuskip }, { "setmuskip", setmuskip }, { "getmuskip", getmuskip }, - { "setmuglue", setmuglue }, - { "getmuglue", getmuglue }, { "isattribute", isattribute }, { "setattribute", setattribute }, { "getattribute", getattribute }, @@ -3045,9 +2945,7 @@ int luaopen_tex(lua_State * L) /* *INDENT-OFF* */ make_table(L, "attribute", "tex.attribute", "getattribute", "setattribute"); make_table(L, "skip", "tex.skip", "getskip", "setskip"); - make_table(L, "glue", "tex.glue", "getglue", "setglue"); make_table(L, "muskip", "tex.muskip", "getmuskip", "setmuskip"); - make_table(L, "muglue", "tex.muglue", "getmuglue", "setmuglue"); make_table(L, "dimen", "tex.dimen", "getdimen", "setdimen"); make_table(L, "count", "tex.count", "getcount", "setcount"); make_table(L, "toks", "tex.toks", "gettoks", "settoks"); diff --git a/Build/source/texk/web2c/luatexdir/lua/luatex-api.h b/Build/source/texk/web2c/luatexdir/lua/luatex-api.h index 07bfcba5a70..8802253c199 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luatex-api.h +++ b/Build/source/texk/web2c/luatexdir/lua/luatex-api.h @@ -556,6 +556,7 @@ make_lua_key(disc);\ make_lua_key(display);\ make_lua_key(doublehyphendemerits);\ make_lua_key(down);\ +make_lua_key(dvi_ptr);\ make_lua_key(embedding);\ make_lua_key(emergencystretch);\ make_lua_key(empty_string);\ @@ -755,6 +756,7 @@ make_lua_key(space);\ make_lua_key(space_shrink);\ make_lua_key(space_stretch);\ make_lua_key(spacefactor);\ +make_lua_key(spec);\ make_lua_key(special);\ make_lua_key(split_discards_head);\ make_lua_key(split_keep);\ @@ -813,6 +815,7 @@ make_lua_key(visiblefilename);\ make_lua_key(vtop);\ make_lua_key(widowpenalty);\ make_lua_key(width);\ +make_lua_key(writable);\ make_lua_key(x_height);\ make_lua_key(xadvance);\ make_lua_key(xformresources);\ @@ -919,6 +922,7 @@ init_lua_key(disc);\ init_lua_key(display);\ init_lua_key(doublehyphendemerits);\ init_lua_key(down);\ +init_lua_key(dvi_ptr);\ init_lua_key(embedding);\ init_lua_key(emergencystretch);\ init_lua_key(encodingbytes);\ @@ -1108,6 +1112,7 @@ init_lua_key(space);\ init_lua_key(space_shrink);\ init_lua_key(space_stretch);\ init_lua_key(spacefactor);\ +init_lua_key(spec);\ init_lua_key(special);\ init_lua_key(split_discards_head);\ init_lua_key(split_keep);\ @@ -1165,6 +1170,7 @@ init_lua_key(visiblefilename);\ init_lua_key(vtop);\ init_lua_key(widowpenalty);\ init_lua_key(width);\ +init_lua_key(writable);\ init_lua_key(x_height);\ init_lua_key(xadvance);\ init_lua_key(xformresources);\ @@ -1328,6 +1334,7 @@ use_lua_key(disc); use_lua_key(display); use_lua_key(doublehyphendemerits); use_lua_key(down); +use_lua_key(dvi_ptr); use_lua_key(embedding); use_lua_key(emergencystretch); use_lua_key(empty_string); @@ -1527,6 +1534,7 @@ use_lua_key(space); use_lua_key(space_shrink); use_lua_key(space_stretch); use_lua_key(spacefactor); +use_lua_key(spec); use_lua_key(special); use_lua_key(split_discards_head); use_lua_key(split_keep); @@ -1585,6 +1593,7 @@ use_lua_key(visiblefilename); use_lua_key(vtop); use_lua_key(widowpenalty); use_lua_key(width); +use_lua_key(writable); use_lua_key(x_height); use_lua_key(xadvance); use_lua_key(xformresources); diff --git a/Build/source/texk/web2c/luatexdir/luatex.c b/Build/source/texk/web2c/luatexdir/luatex.c index 1ee5ba963b6..522c24dee7c 100644 --- a/Build/source/texk/web2c/luatexdir/luatex.c +++ b/Build/source/texk/web2c/luatexdir/luatex.c @@ -28,10 +28,10 @@ #define TeX -int luatex_version = 95; /* \.{\\luatexversion} */ +int luatex_version = 90; /* \.{\\luatexversion} */ int luatex_revision = '0'; /* \.{\\luatexrevision} */ -int luatex_date_info = 2016033010; /* the compile date is now hardwired */ -const char *luatex_version_string = "beta-0.95.0"; +int luatex_date_info = 2016032512; /* the compile date is now hardwired */ +const char *luatex_version_string = "beta-0.90.0"; const char *engine_name = my_name; /* the name of this engine */ #include <kpathsea/c-ctype.h> diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfgen.w b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.w index 5f6756b1e7d..c5db4c71413 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfgen.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.w @@ -1427,25 +1427,17 @@ difficult, we start with a simpler implementation using just the first two items @c - -/* - A user supplied trailerid had better be an array! So maybe we need to check - for [] and error otherwise. -*/ - static void print_ID(PDF pdf) { if ((pdf_suppress_optional_info & 512) == 0) { - const char *p = NULL; - pdf_add_name(pdf, "ID"); - p = get_pdf_table_string("trailerid"); - if (p && strlen(p) > 0) { - pdf_puts(pdf,p); - } else if (pdf_trailer_id != 0) { - /* user provided one */ - pdf_print_toks(pdf, pdf_trailer_id); + if (pdf_trailer_id != 0) { + char *s = NULL; + int len; + s = tokenlist_to_cstring(pdf_trailer_id, true, &len); + /* this had better be an array! sp maybe we need to check for [] and error otherwise */ + pdf_add_name(pdf, "ID"); + pdf_out_block(pdf,s,len); } else { - /* system provided one */ time_t t; size_t size; char time_str[32]; @@ -1481,6 +1473,7 @@ static void print_ID(PDF pdf) md5_finish(&state, digest); /* write the IDs */ convertStringToHexString((char *) digest, id, 16); + pdf_add_name(pdf, "ID"); pdf_begin_array(pdf); pdf_printf(pdf, "<%s> <%s>", id, id); pdf_end_array(pdf); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdflistout.w b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.w index b6f3e6ff1a1..65295c6145b 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdflistout.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.w @@ -112,7 +112,7 @@ void init_backend_functionpointers(output_mode o_mode) track of the needed width in |w|. When it finds the node that will end this segment, it stores the accumulated with in the |dir_dvi_h| field of that end node, so that when that node is found later in the -processing, the correct glue correction can be applied (obsolete). +processing, the correct glue correction can be applied. @c static scaled simple_advance_width(halfword p) @@ -154,6 +154,7 @@ static halfword calculate_width_to_enddir(halfword p, real cur_glue, scaled cur_ int dir_nest = 1; halfword q = p, enddir_ptr = p; scaled w = 0; + halfword g; /* this is normally a global variable, but that is just too hideous */ real glue_temp; /* glue value before rounding */ int g_sign = glue_sign(this_box); int g_order = glue_order(this_box); @@ -177,7 +178,7 @@ static halfword calculate_width_to_enddir(halfword p, real cur_glue, scaled cur_ break; case math_node: /* begin mathskip code */ - if (glue_is_zero(q)) { + if (glue_ptr(q) == zero_glue) { w += surround(q); break; } else { @@ -185,16 +186,17 @@ static halfword calculate_width_to_enddir(halfword p, real cur_glue, scaled cur_ } /* end mathskip code */ case glue_node: - w += width(q) - cur_g; + g = glue_ptr(q); + w += width(g) - cur_g; if (g_sign != normal) { if (g_sign == stretching) { - if (stretch_order(q) == g_order) { - cur_glue = cur_glue + stretch(q); + if (stretch_order(g) == g_order) { + cur_glue = cur_glue + stretch(g); vet_glue(float_cast(glue_set(this_box)) * cur_glue); cur_g = float_round(glue_temp); } - } else if (shrink_order(q) == g_order) { - cur_glue = cur_glue - shrink(q); + } else if (shrink_order(g) == g_order) { + cur_glue = cur_glue - shrink(g); vet_glue(float_cast(glue_set(this_box)) * cur_glue); cur_g = float_round(glue_temp); } @@ -440,16 +442,17 @@ cur.h += x_advance(p); case glue_node: { /* move right or output leaders, we use real multiplication */ - rule.wd = width(p) - cur_g; + halfword g = glue_ptr(p); + rule.wd = width(g) - cur_g; if (g_sign != normal) { if (g_sign == stretching) { - if (stretch_order(p) == g_order) { - cur_glue = cur_glue + stretch(p); + if (stretch_order(g) == g_order) { + cur_glue = cur_glue + stretch(g); vet_glue(float_cast(glue_set(this_box)) * cur_glue); cur_g = float_round(glue_temp); } - } else if (shrink_order(p) == g_order) { - cur_glue = cur_glue - shrink(p); + } else if (shrink_order(g) == g_order) { + cur_glue = cur_glue - shrink(g); vet_glue(float_cast(glue_set(this_box)) * cur_glue); cur_g = float_round(glue_temp); } @@ -651,7 +654,7 @@ cur.h += x_advance(p); synctexmath(p, this_box); } /* begin mathskip code */ - if (glue_is_zero(p)) { + if (glue_ptr(p) == zero_glue) { cur.h += surround(p); break; } else { @@ -877,16 +880,17 @@ void vlist_out(PDF pdf, halfword this_box, int rule_callback_id) case glue_node: { /* move down or output leaders, we use real multiplication */ - rule.ht = width(p) - cur_g; + halfword g = glue_ptr(p); + rule.ht = width(g) - cur_g; if (g_sign != normal) { if (g_sign == stretching) { - if (stretch_order(p) == g_order) { - cur_glue = cur_glue + stretch(p); + if (stretch_order(g) == g_order) { + cur_glue = cur_glue + stretch(g); vet_glue(float_cast(glue_set(this_box)) * cur_glue); cur_g = float_round(glue_temp); } - } else if (shrink_order(p) == g_order) { - cur_glue = cur_glue - shrink(p); + } else if (shrink_order(g) == g_order) { + cur_glue = cur_glue - shrink(g); vet_glue(float_cast(glue_set(this_box)) * cur_glue); cur_g = float_round(glue_temp); } diff --git a/Build/source/texk/web2c/luatexdir/tex/align.w b/Build/source/texk/web2c/luatexdir/tex/align.w index cd8086af301..d54eabac131 100644 --- a/Build/source/texk/web2c/luatexdir/tex/align.w +++ b/Build/source/texk/web2c/luatexdir/tex/align.w @@ -518,7 +518,7 @@ void init_row(void) space_factor = 0; else prev_depth = 0; - tail_append(new_glue(preamble)); + tail_append(new_glue(glue_ptr(preamble))); subtype(cur_list.tail_field) = tab_skip_code + 1; cur_align = vlink(preamble); cur_tail = cur_head; @@ -650,7 +650,7 @@ boolean fin_col(void) v_part(p) = token_link(hold_token_head); cur_loop = vlink(cur_loop); - r = new_glue(cur_loop); + r = new_glue(glue_ptr(cur_loop)); vlink(p) = r; } else { const char *hlp[] = @@ -719,7 +719,7 @@ boolean fin_col(void) cur_list.tail_field = u; /* Copy the tabskip glue between columns */ - tail_append(new_glue(vlink(cur_align))); + tail_append(new_glue(glue_ptr(vlink(cur_align)))); subtype(cur_list.tail_field) = tab_skip_code + 1; if (extra_info(cur_align) >= cr_code) { @@ -803,13 +803,13 @@ set so that the columns line up, taking due account of spanned columns. @c void fin_align(void) { - pointer p, q, r, s, u, rr; /* registers for the list operations */ + pointer p, q, r, s, u, v, rr; /* registers for the list operations */ scaled t, w; /* width of column */ scaled o; /* shift offset for unset boxes */ halfword n; /* matching span amount */ scaled rule_save; /* temporary storage for |overfull_rule| */ halfword pd; /* temporary storage for |prev_depth| */ - halfword ng; /* temporary storage for |new_glue| */ + halfword ng; /* temporary storage for |new_glue| */ if (cur_group != align_group) confusion("align1"); unsave(); /* that |align_group| was for individual entries */ @@ -856,7 +856,12 @@ value is changed to zero and so is the next tabskip. /* Nullify |width(q)| and the tabskip glue following this column */ width(q) = 0; r = vlink(q); - reset_glue_to_zero(r); /* is a lready copy */ + s = glue_ptr(r); + if (s != zero_glue) { + add_glue_ref(zero_glue); + delete_glue_ref(s); + glue_ptr(r) = zero_glue; + } } if (span_ptr(q) != end_span) { /* Merge the widths in the span nodes of |q| with those of |p|, @@ -869,7 +874,7 @@ value is changed to zero and so is the next tabskip. have been processed, and the successor of |s| matches |r| or precedes |r| or follows |r|, according as |link(r)=n| or |link(r)>n| or |link(r)<n|. */ - t = width(q) + width(vlink(q)); + t = width(q) + width(glue_ptr(vlink(q))); r = span_ptr(q); s = end_span; span_ptr(s) = p; @@ -982,17 +987,22 @@ value is changed to zero and so is the next tabskip. and update |s| and |t| as the prototype nodes are passed */ s = vlink(s); - ng = new_glue(s); + v = glue_ptr(s); + ng = new_glue(v); vlink(u) = ng; u = vlink(u); subtype(u) = tab_skip_code + 1; - t = t + width(s); + t = t + width(v); if (glue_sign(p) == stretching) { - if (stretch_order(s) == glue_order(p)) - t = t + round(float_cast(glue_set(p)) * float_cast(stretch(s))); + if (stretch_order(v) == glue_order(p)) + t = t + + round(float_cast(glue_set(p)) * + float_cast(stretch(v))); } else if (glue_sign(p) == shrinking) { - if (shrink_order(s) == glue_order(p)) - t = t - round(float_cast(glue_set(p)) * float_cast(shrink(s))); + if (shrink_order(v) == glue_order(p)) + t = t - + round(float_cast(glue_set(p)) * + float_cast(shrink(v))); } s = vlink(s); rr = new_null_box(); diff --git a/Build/source/texk/web2c/luatexdir/tex/buildpage.w b/Build/source/texk/web2c/luatexdir/tex/buildpage.w index 104566f790b..4c61a510a9c 100644 --- a/Build/source/texk/web2c/luatexdir/tex/buildpage.w +++ b/Build/source/texk/web2c/luatexdir/tex/buildpage.w @@ -316,14 +316,15 @@ void build_page(void) p = vlink(contrib_head); /* Update the values of |last_glue|, |last_penalty|, and |last_kern| */ if (last_glue != max_halfword) { - flush_node(last_glue); + delete_glue_ref(last_glue); last_glue = max_halfword; } last_penalty = 0; last_kern = 0; last_node_type = type(p) + 1; if (type(p) == glue_node) { - last_glue = new_glue(p); + last_glue = glue_ptr(p); + add_glue_ref(last_glue); } else if (type(p) == penalty_node) { last_penalty = penalty(p); } else if (type(p) == kern_node) { @@ -359,17 +360,17 @@ void build_page(void) freeze_page_specs(box_there); else page_contents = box_there; - q = new_skip_param(top_skip_code); + q = new_skip_param(top_skip_code); /* now |temp_ptr=glue_ptr(q)| */ if ((type(p) == hlist_node) && is_mirrored(body_direction)) { - if (width(q) > depth(p)) - width(q) = width(q) - depth(p); + if (width(temp_ptr) > depth(p)) + width(temp_ptr) = width(temp_ptr) - depth(p); else - width(q) = 0; + width(temp_ptr) = 0; } else { - if (width(q) > height(p)) - width(q) = width(q) - height(p); + if (width(temp_ptr) > height(p)) + width(temp_ptr) = width(temp_ptr) - height(p); else - width(q) = 0; + width(temp_ptr) = 0; } couple_nodes(q, p); couple_nodes(contrib_head, q); @@ -632,24 +633,32 @@ void build_page(void) /* Update the current page measurements with respect to the glue or kern specified by node~|p| */ - if (type(p) != kern_node) { - if (stretch_order(p) > 1) - page_so_far[1 + stretch_order(p)] = page_so_far[1 + stretch_order(p)] + stretch(p); + if (type(p) == kern_node) { + q = p; + } else { + q = glue_ptr(p); + if (stretch_order(q) > 1) + page_so_far[1 + stretch_order(q)] = + page_so_far[1 + stretch_order(q)] + stretch(q); else - page_so_far[2 + stretch_order(p)] = page_so_far[2 + stretch_order(p)] + stretch(p); - page_shrink = page_shrink + shrink(p); - if ((shrink_order(p) != normal) && (shrink(p) != 0)) { + page_so_far[2 + stretch_order(q)] = + page_so_far[2 + stretch_order(q)] + stretch(q); + page_shrink = page_shrink + shrink(q); + if ((shrink_order(q) != normal) && (shrink(q) != 0)) { print_err("Infinite glue shrinkage found on current page"); help4("The page about to be output contains some infinitely", "shrinkable glue, e.g., `\\vss' or `\\vskip 0pt minus 1fil'.", "Such glue doesn't belong there; but you can safely proceed,", "since the offensive shrinkability has been made finite."); error(); - reset_glue_to_zero(p); - shrink_order(p) = normal; + r = new_spec(q); + shrink_order(r) = normal; + delete_glue_ref(q); + glue_ptr(p) = r; + q = r; } } - page_total = page_total + page_depth + width(p); + page_total = page_total + page_depth + width(q); page_depth = 0; CONTRIBUTE: /* go here to link a node into the current page */ @@ -805,7 +814,6 @@ void fire_up(halfword c) s = last_ins_ptr(r); vlink(s) = ins_ptr(p); if (best_ins_ptr(r) == p) { - halfword t; /* was a global temp_ptr */ /* Wrap up the box specified by node |r|, splitting node |p| if called for; set |wait:=true| if node |p| holds a remainder after splitting */ @@ -818,20 +826,22 @@ void fire_up(halfword c) ins_ptr(p) = prune_page_top(broken_ptr(r), false); if (ins_ptr(p) != null) { - t = vpack(ins_ptr(p), 0, additional, -1); - height(p) = height(t) + depth(t); - list_ptr(t) = null; - flush_node(t); + temp_ptr = + vpack(ins_ptr(p), 0, additional, -1); + height(p) = + height(temp_ptr) + depth(temp_ptr); + list_ptr(temp_ptr) = null; + flush_node(temp_ptr); wait = true; } } } best_ins_ptr(r) = null; n = subtype(r); - t = list_ptr(box(n)); + temp_ptr = list_ptr(box(n)); list_ptr(box(n)) = null; flush_node(box(n)); - box(n) = vpack(t, 0, additional, body_direction); + box(n) = vpack(temp_ptr, 0, additional, body_direction); } else { while (vlink(s) != null) @@ -900,7 +910,7 @@ void fire_up(halfword c) vbadness = save_vbadness; vfuzz = save_vfuzz; if (last_glue != max_halfword) - flush_node(last_glue); + delete_glue_ref(last_glue); /* Start a new current page */ start_new_page(); /* this sets |last_glue:=max_halfword| */ if (q != hold_head) { @@ -911,7 +921,6 @@ void fire_up(halfword c) /* Delete the page-insertion nodes */ r = vlink(page_ins_head); while (r != page_ins_head) { - /* todo: couple */ q = vlink(r); flush_node(r); r = q; diff --git a/Build/source/texk/web2c/luatexdir/tex/directions.w b/Build/source/texk/web2c/luatexdir/tex/directions.w index 20d46606d6a..7af25187999 100644 --- a/Build/source/texk/web2c/luatexdir/tex/directions.w +++ b/Build/source/texk/web2c/luatexdir/tex/directions.w @@ -86,6 +86,7 @@ halfword new_dir(int s) { halfword p = new_node(dir_node, 0); dir_dir(p) = s; + dir_dvi_ptr(p) = -1; dir_level(p) = cur_level; return p; } diff --git a/Build/source/texk/web2c/luatexdir/tex/dumpdata.w b/Build/source/texk/web2c/luatexdir/tex/dumpdata.w index be5f0074639..ac4f96f2f0e 100644 --- a/Build/source/texk/web2c/luatexdir/tex/dumpdata.w +++ b/Build/source/texk/web2c/luatexdir/tex/dumpdata.w @@ -27,7 +27,7 @@ /* we start with 907: the sum of the values of the bytes of "don knuth" */ -#define FORMAT_ID (907+14) +#define FORMAT_ID (907+13) #if ((FORMAT_ID>=0) && (FORMAT_ID<=256)) #error Wrong value for FORMAT_ID. #endif diff --git a/Build/source/texk/web2c/luatexdir/tex/equivalents.w b/Build/source/texk/web2c/luatexdir/tex/equivalents.w index cc709c1bd7e..d88b7322a76 100644 --- a/Build/source/texk/web2c/luatexdir/tex/equivalents.w +++ b/Build/source/texk/web2c/luatexdir/tex/equivalents.w @@ -567,8 +567,6 @@ within |save_stack|, so these counts must be handled carefully. @^reference counts@> @c -/* we don't need to destroy when an assignment has the same node */ - void eq_destroy(memory_word w) { /* gets ready to forget |w| */ halfword q; /* |equiv| field of |w| */ @@ -580,7 +578,7 @@ void eq_destroy(memory_word w) delete_token_ref(equiv_field(w)); break; case glue_ref_cmd: - flush_node(equiv_field(w)); + delete_glue_ref(equiv_field(w)); break; case shape_ref_cmd: q = equiv_field(w); /* we need to free a \.{\\parshape} block */ diff --git a/Build/source/texk/web2c/luatexdir/tex/linebreak.h b/Build/source/texk/web2c/luatexdir/tex/linebreak.h index 99560ebed2e..1b5d1da96ca 100644 --- a/Build/source/texk/web2c/luatexdir/tex/linebreak.h +++ b/Build/source/texk/web2c/luatexdir/tex/linebreak.h @@ -82,7 +82,7 @@ extern halfword find_protchar_right(halfword l, halfword r); ) # define cp_skipable(a) ( (! is_char_node((a))) && ( \ - ((type((a)) == glue_node) && (glue_is_zero((a)))) \ + ((type((a)) == glue_node) && (glue_ptr((a)) == zero_glue)) \ || (type((a)) == penalty_node) \ || ((type((a)) == disc_node) && empty_disc(a)) \ || ((type((a)) == kern_node) && ((width((a)) == 0) || (subtype((a)) == normal))) \ diff --git a/Build/source/texk/web2c/luatexdir/tex/linebreak.w b/Build/source/texk/web2c/luatexdir/tex/linebreak.w index 8b8f47bc9d5..6560192da93 100644 --- a/Build/source/texk/web2c/luatexdir/tex/linebreak.w +++ b/Build/source/texk/web2c/luatexdir/tex/linebreak.w @@ -108,10 +108,11 @@ void line_break(boolean d, int line_break_context) } else if (type(cur_list.tail_field) != glue_node) { tail_append(new_penalty(inf_penalty)); } else { - halfword t = alink(cur_list.tail_field); - flush_node(cur_list.tail_field); - cur_list.tail_field = t; - tail_append(new_penalty(inf_penalty)); + type(cur_list.tail_field) = penalty_node; + delete_glue_ref(glue_ptr(cur_list.tail_field)); + if (leader_ptr(cur_list.tail_field) != null) + flush_node_list(leader_ptr(cur_list.tail_field)); + penalty(cur_list.tail_field) = inf_penalty; } final_par_glue = new_param_glue(par_fill_skip_code); couple_nodes(cur_list.tail_field, final_par_glue); @@ -209,6 +210,7 @@ static boolean no_shrink_error_yet; /*have we complained about infinite shri static halfword finite_shrink(halfword p) { /* recovers from infinite shrinkage */ + halfword q; /*new glue specification */ const char *hlp[] = { "The paragraph just ended includes some glue that has", "infinite shrinkability, e.g., `\\hskip 0pt minus 1fil'.", @@ -221,8 +223,10 @@ static halfword finite_shrink(halfword p) no_shrink_error_yet = false; tex_error("Infinite glue shrinkage found in a paragraph", hlp); } - shrink_order(p) = normal; - return p; + q = new_spec(p); + shrink_order(q) = normal; + delete_glue_ref(p); + return q; } @ A pointer variable |cur_p| runs through the given horizontal list as we look @@ -896,7 +900,7 @@ static void compute_break_width(int break_type, int line_break_dir, int adjust_s switch (type(s)) { case math_node: /* begin mathskip code */ - if (glue_is_zero(math_skip)) { + if (math_skip == zero_glue) { break_width[1] -= surround(s); break; } else { @@ -905,9 +909,12 @@ static void compute_break_width(int break_type, int line_break_dir, int adjust_s /* end mathskip code */ case glue_node: /*Subtract glue from |break_width|; */ - break_width[1] -= width(s); - break_width[2 + stretch_order(s)] -= stretch(s); - break_width[7] -= shrink(s); + { + halfword v = glue_ptr(s); + break_width[1] -= width(v); + break_width[2 + stretch_order(v)] -= stretch(v); + break_width[7] -= shrink(v); + } break; case penalty_node: break; @@ -1691,7 +1698,7 @@ void ext_do_line_break(int paragraph_dir, */ do_last_line_fit = false; if (last_line_fit > 0) { - q = last_line_fill; + q = glue_ptr(last_line_fill); if ((stretch(q) > 0) && (stretch_order(q) > normal)) { if ((background[3] == 0) && (background[4] == 0) && (background[5] == 0) && (background[6] == 0)) { @@ -1838,7 +1845,7 @@ void ext_do_line_break(int paragraph_dir, case math_node: auto_breaking = (subtype(cur_p) == after); /* begin mathskip code */ - if (glue_is_zero(math_skip)) { + if (math_skip == zero_glue) { kern_break(); break; } else { @@ -1879,10 +1886,16 @@ void ext_do_line_break(int paragraph_dir, } } /* *INDENT-ON* */ - check_shrinkage(cur_p); - active_width[1] += width(cur_p); - active_width[2 + stretch_order(cur_p)] += stretch(cur_p); - active_width[7] += shrink(cur_p); + check_shrinkage(glue_ptr(cur_p)); + q = glue_ptr(cur_p); + active_width[1] += width(q); + active_width[2 + stretch_order(q)] += stretch(q); + active_width[7] += shrink(q); + /* begin mathskip code */ + if (type(cur_p)==math_node) { + active_width[1]+=surround(cur_p); + } + /* end mathskip code */ break; case kern_node: if (subtype(cur_p) == explicit_kern || subtype(cur_p) == italic_kern) { @@ -2109,8 +2122,11 @@ void ext_do_line_break(int paragraph_dir, if (active_short(best_bet) == 0) { do_last_line_fit = false; } else { - width(last_line_fill) += (active_short(best_bet) - active_glue(best_bet)); - stretch(last_line_fill) = 0; + q = new_spec(glue_ptr(last_line_fill)); + delete_glue_ref(glue_ptr(last_line_fill)); + width(q) += (active_short(best_bet) - active_glue(best_bet)); + stretch(q) = 0; + glue_ptr(last_line_fill) = q; } } diff --git a/Build/source/texk/web2c/luatexdir/tex/mainbody.w b/Build/source/texk/web2c/luatexdir/tex/mainbody.w index ad0bb783a1f..a8d35d7ac56 100644 --- a/Build/source/texk/web2c/luatexdir/tex/mainbody.w +++ b/Build/source/texk/web2c/luatexdir/tex/mainbody.w @@ -549,8 +549,7 @@ been scanned and |its_all_over|\kern-2pt. void final_cleanup(void) { int c; /* 0 for \.{\\end}, 1 for \.{\\dump} */ - halfword i; /* for looping marks */ - halfword t; /* was a global temp_ptr */ + halfword i; /* for looping marks */ c = cur_chr; if (job_name == 0) open_log_file(); @@ -579,16 +578,17 @@ void final_cleanup(void) tprint(" was incomplete)"); if_line = if_line_field(cond_ptr); cur_if = subtype(cond_ptr); - t = cond_ptr; + temp_ptr = cond_ptr; cond_ptr = vlink(cond_ptr); - flush_node(t); + flush_node(temp_ptr); } if (callback_defined(stop_run_callback) == 0) if (history != spotless) if ((history == warning_issued) || (interaction < error_stop_mode)) if (selector == term_and_log) { selector = term_only; - tprint_nl("(see the transcript file for additional information)"); + tprint_nl + ("(see the transcript file for additional information)"); selector = term_and_log; } if (c == 1) { @@ -602,9 +602,8 @@ void final_cleanup(void) } for (c = last_box_code; c <= vsplit_code; c++) flush_node_list(disc_ptr[c]); - if (last_glue != max_halfword) { - flush_node(last_glue); - } + if (last_glue != max_halfword) + delete_glue_ref(last_glue); while (pseudo_files != null) pseudo_close(); /* flush pseudo files */ store_fmt_file(); diff --git a/Build/source/texk/web2c/luatexdir/tex/maincontrol.h b/Build/source/texk/web2c/luatexdir/tex/maincontrol.h index c42dcc93aa4..ea22ff80dc7 100644 --- a/Build/source/texk/web2c/luatexdir/tex/maincontrol.h +++ b/Build/source/texk/web2c/luatexdir/tex/maincontrol.h @@ -176,6 +176,7 @@ extern void fixup_directions(void); extern void get_r_token(void); extern void assign_internal_value(int a, halfword p, int cur_val); +extern void trap_zero_glue(void); extern void do_register_command(int a); extern void alter_aux(void); extern void alter_prev_graf(void); diff --git a/Build/source/texk/web2c/luatexdir/tex/maincontrol.w b/Build/source/texk/web2c/luatexdir/tex/maincontrol.w index af89da9d5d7..bf432e308da 100644 --- a/Build/source/texk/web2c/luatexdir/tex/maincontrol.w +++ b/Build/source/texk/web2c/luatexdir/tex/maincontrol.w @@ -130,7 +130,11 @@ and kerns, is part of \TeX's ``inner loop''; the whole program runs efficiently when its inner loop is fast, so this part has been written with particular care. -We leave the |space_factor| unchanged if |sf_code(cur_chr)=0|; otherwise we +@c +static halfword main_p; /* temporary register for list manipulation */ +static halfword main_s; /* space factor value */ + +@ We leave the |space_factor| unchanged if |sf_code(cur_chr)=0|; otherwise we set it equal to |sf_code(cur_chr)|, except that it should never change from a value less than 1000 to a value exceeding 1000. The most common case is |sf_code(cur_chr)=1000|, so we want that case to be fast. @@ -138,16 +142,16 @@ case is |sf_code(cur_chr)=1000|, so we want that case to be fast. @c void adjust_space_factor(void) { - halfword s = get_sf_code(cur_chr); - if (s == 1000) { + main_s = get_sf_code(cur_chr); + if (main_s == 1000) { space_factor = 1000; - } else if (s < 1000) { - if (s > 0) - space_factor = s; + } else if (main_s < 1000) { + if (main_s > 0) + space_factor = main_s; } else if (space_factor < 1000) { space_factor = 1000; } else { - space_factor = s; + space_factor = main_s; } } @@ -156,6 +160,10 @@ both time and memory.'' That may be true, but it also punches through the API wall for fonts, so I removed that -- Taco. But a bit of caching is very welcome, which is why I need to have the next two globals: +@c +internal_font_number space_spec_font; +halfword space_spec_cache; + @ To handle the execution state of |main_control|'s eternal loop, an extra global variable is used, along with a macro to define its values. @@ -200,32 +208,38 @@ is zero or~not. @c static void run_app_space (void) { - halfword p; /* was a global temp_ptr */ int method = int_par(disable_space_code) ; if (method == 1) { /* don't inject anything, not even zero skip */ } else if (method == 2) { - p = new_glue(zero_glue); - couple_nodes(tail,p); - tail = p; + temp_ptr = new_glue(zero_glue); + couple_nodes(tail,temp_ptr); + tail = temp_ptr; } else if ((abs(mode) + cur_cmd == hmode + spacer_cmd) && (!(space_factor == 1000))) { app_space(); } else { /* Append a normal inter-word space to the current list */ - if (glue_is_zero(space_skip)) { - /* Find the glue specification for text spaces in the current font */ - p = new_glue(zero_glue); - width(p) = space(cur_font); - stretch(p) = space_stretch(cur_font); - shrink(p) = space_shrink(cur_font); - + if (space_skip == zero_glue) { + /* Find the glue specification, |main_p|, for + text spaces in the current font */ + if (cur_font != space_spec_font) { + if (space_spec_cache != zero_glue) + delete_glue_ref(space_spec_cache); + space_spec_cache = new_spec(zero_glue); + width(space_spec_cache) = space(cur_font); + stretch(space_spec_cache) = space_stretch(cur_font); + shrink(space_spec_cache) = space_shrink(cur_font); + space_spec_font = cur_font; + } + main_p = space_spec_cache; + temp_ptr = new_glue(main_p); } else { - p = new_param_glue(space_skip_code); + temp_ptr = new_param_glue(space_skip_code); } - /* so from now we have a subtype with spaces: */ - subtype(p) = space_skip_code + 1 ; - couple_nodes(tail,p); - tail = p; +/* so from now we have a subtype with spaces: */ +subtype(temp_ptr) = space_skip_code + 1 ; + couple_nodes(tail,temp_ptr); + tail = temp_ptr; } } @@ -987,27 +1001,28 @@ void main_control(void) void app_space(void) { /* handle spaces when |space_factor<>1000| */ halfword q; /* glue node */ - if ((space_factor >= 2000) && (! glue_is_zero(xspace_skip))) { + if ((space_factor >= 2000) && (xspace_skip != zero_glue)) { q = new_param_glue(xspace_skip_code); - /* so from now we have a subtype with spaces: */ - subtype(q) = xspace_skip_code + 1; +/* so from now we have a subtype with spaces: */ +subtype(q) = xspace_skip_code + 1; } else { - if (!glue_is_zero(space_skip)) { - q = new_glue(space_skip); + if (space_skip != zero_glue) { + main_p = new_spec(space_skip); } else { - q = new_glue(zero_glue); - width(q) = space(cur_font); - stretch(q) = space_stretch(cur_font); - shrink(q) = space_shrink(cur_font); + main_p = new_spec(zero_glue); + width(main_p) = space(cur_font); + stretch(main_p) = space_stretch(cur_font); + shrink(main_p) = space_shrink(cur_font); } - /* Modify the glue specification in |q| according to the space factor */ + /* Modify the glue specification in |main_p| according to the space factor */ if (space_factor >= 2000) - width(q) = width(q) + extra_space(cur_font); - stretch(q) = xn_over_d(stretch(q), space_factor, 1000); - shrink(q) = xn_over_d(shrink(q), 1000, space_factor); - - /* so from now we have a subtype with spaces: */ - subtype(q) = space_skip_code + 1; + width(main_p) = width(main_p) + extra_space(cur_font); + stretch(main_p) = xn_over_d(stretch(main_p), space_factor, 1000); + shrink(main_p) = xn_over_d(shrink(main_p), 1000, space_factor); + q = new_glue(main_p); + glue_ref_count(main_p) = null; +/* so from now we have a subtype with spaces: */ +subtype(q) = space_skip_code + 1; } couple_nodes(tail, q); tail = q; @@ -1121,19 +1136,20 @@ used in at least one place where that would be a mistake. @c void append_glue(void) { - int s = cur_chr; + int s; /* modifier of skip command */ + s = cur_chr; switch (s) { case fil_code: - cur_val = new_glue(fil_glue); + cur_val = fil_glue; break; case fill_code: - cur_val = new_glue(fill_glue); + cur_val = fill_glue; break; case ss_code: - cur_val = new_glue(ss_glue); + cur_val = ss_glue; break; case fil_neg_code: - cur_val = new_glue(fil_neg_glue); + cur_val = fil_neg_glue; break; case skip_code: scan_glue(glue_val_level); @@ -1141,12 +1157,12 @@ void append_glue(void) case mskip_code: scan_glue(mu_val_level); break; - } - /* now |cur_val| points to the glue specification */ + } /* now |cur_val| points to the glue specification */ tail_append(new_glue(cur_val)); - flush_node(cur_val); - if (s > skip_code) { - subtype(tail) = mu_glue; + if (s >= skip_code) { + decr(glue_ref_count(cur_val)); + if (s > skip_code) + subtype(tail) = mu_glue; } } @@ -1271,7 +1287,8 @@ void handle_right_brace(void) break; case insert_group: end_graf(insert_group); - q = new_glue(split_top_skip); + q = split_top_skip; + add_glue_ref(q); d = split_max_depth; f = floating_penalty; unsave(); @@ -1289,7 +1306,7 @@ void handle_right_brace(void) } else if (saved_type(0) == saved_adjust) { tail_append(new_node(adjust_node, saved_value(0))); adjust_ptr(tail) = list_ptr(p); - flush_node(q); + delete_glue_ref(q); } else { confusion("insert_group"); } @@ -2522,6 +2539,7 @@ void prefixed_command(void) scan_glue(mu_val_level); else scan_glue(glue_val_level); + trap_zero_glue(); define(p, glue_ref_cmd, cur_val); break; case def_char_code_cmd: @@ -2620,6 +2638,7 @@ void prefixed_command(void) scan_dimen(false, false, false); } else { scan_glue(mu_val_level); + trap_zero_glue(); if (cur_val == glue_par(thin_mu_skip_code)) cur_val = thin_mu_skip_code; else if (cur_val == glue_par(med_mu_skip_code)) @@ -2973,6 +2992,21 @@ void assign_internal_value(int a, halfword p, int val) } } +@ When a glue register or parameter becomes zero, it will always point to +|zero_glue| because of the following procedure. (Exception: The tabskip +glue isn't trapped while preambles are being scanned.) + +@c +void trap_zero_glue(void) +{ + if ((width(cur_val) == 0) && (stretch(cur_val) == 0) + && (shrink(cur_val) == 0)) { + add_glue_ref(zero_glue); + delete_glue_ref(cur_val); + cur_val = zero_glue; + } +} + @ We use the fact that |register<advance<multiply<divide| Compute the register location |l| and its type |p|; but |return| if invalid @@ -3031,20 +3065,20 @@ void do_register_command(int a) if (q == advance_cmd) cur_val = cur_val + eqtb[l].cint; } else { - /* we can probably save a copy */ scan_glue(p); if (q == advance_cmd) { /* Compute the sum of two glue specs */ halfword r = equiv(l); q = new_spec(cur_val); - flush_node(cur_val); + delete_glue_ref(cur_val); width(q) = width(q) + width(r); if (stretch(q) == 0) { stretch_order(q) = normal; } if (stretch_order(q) == stretch_order(r)) { stretch(q) = stretch(q) + stretch(r); - } else if ((stretch_order(q) < stretch_order(r)) && (stretch(r) != 0)) { + } else if ((stretch_order(q) < stretch_order(r)) + && (stretch(r) != 0)) { stretch(q) = stretch(r); stretch_order(q) = stretch_order(r); } @@ -3053,7 +3087,8 @@ void do_register_command(int a) } if (shrink_order(q) == shrink_order(r)) { shrink(q) = shrink(q) + shrink(r); - } else if ((shrink_order(q) < shrink_order(r)) && (shrink(r) != 0)) { + } else if ((shrink_order(q) < shrink_order(r)) + && (shrink(r) != 0)) { shrink(q) = shrink(r); shrink_order(q) = shrink_order(r); } @@ -3093,7 +3128,7 @@ void do_register_command(int a) help2("I can't carry out that multiplication or division,", "since the result is out of range."); if (p >= glue_val_level) - flush_node(cur_val); + delete_glue_ref(cur_val); error(); return; } @@ -3108,6 +3143,7 @@ void do_register_command(int a) else word_define(l, cur_val); } else { + trap_zero_glue(); define(l, glue_ref_cmd, cur_val); } } @@ -3563,9 +3599,11 @@ void initialize(void) set_equiv(glue_base, zero_glue); set_eq_level(glue_base, level_one); set_eq_type(glue_base, glue_ref_cmd); - for (k = glue_base + 1; k <= local_base - 1; k++) { + for (k = glue_base + 1; k <= local_base - 1; k++) eqtb[k] = eqtb[glue_base]; - } + glue_ref_count(zero_glue) = + glue_ref_count(zero_glue) + local_base - glue_base; + par_shape_ptr = null; set_eq_type(par_shape_loc, shape_ref_cmd); set_eq_level(par_shape_loc, level_one); diff --git a/Build/source/texk/web2c/luatexdir/tex/mlist.w b/Build/source/texk/web2c/luatexdir/tex/mlist.w index 0fc21de7ceb..5932a9f9dbe 100644 --- a/Build/source/texk/web2c/luatexdir/tex/mlist.w +++ b/Build/source/texk/web2c/luatexdir/tex/mlist.w @@ -1063,15 +1063,17 @@ static scaled stack_into_box(pointer b, internal_font_number f, int c) } static void stack_glue_into_box(pointer b, scaled min, scaled max) { - halfword p = new_glue(zero_glue); - width(p) = min; - stretch(p) = max - min; + pointer p, q; /* new node placed into |b| */ + q = new_spec(zero_glue); + width(q) = min; + stretch(q) = max-min; + p = new_glue(q); reset_attributes(p, node_attr(b)); if (type(b) == vlist_node) { try_couple_nodes(p,list_ptr(b)); list_ptr(b) = p; } else { - halfword q = list_ptr(b); + q = list_ptr(b); if (q == null) { list_ptr(b) = p; } else { @@ -1541,7 +1543,7 @@ static pointer math_glue(pointer g, scaled m) decr(n); f = f + unity; } - p = new_node(glue_node, 0); + p = new_node(glue_spec_node, 0); width(p) = mu_mult(width(g)); /* convert \.{mu} to \.{pt} */ stretch_order(p) = stretch_order(g); if (stretch_order(p) == normal) @@ -1949,12 +1951,12 @@ static pointer wrapup_over_under_delimiter(pointer x, pointer y, pointer q, scal #define fixup_widths(q,x,y) do { \ if (width(y) >= width(x)) { \ - if (radicalwidth(q) != 0) { \ + if (radicalwidth(q) != zero_glue) { \ shift_amount(x) += half(width(y)-width(x)) ; \ } \ width(x) = width(y); \ } else { \ - if (radicalwidth(q) != 0) { \ + if (radicalwidth(q) != zero_glue) { \ shift_amount(y) += half(width(x)-width(y)) ; \ } \ width(y) = width(x); \ @@ -1963,7 +1965,7 @@ static pointer wrapup_over_under_delimiter(pointer x, pointer y, pointer q, scal #define check_radical(q,stack,r,t) do { \ - if (!stack && (width(r) >= width(t)) && (radicalwidth(q) != 0) && (radicalwidth(q) != width(r))) { \ + if (!stack && (width(r) >= width(t)) && (radicalwidth(q) != zero_glue) && (radicalwidth(q) != width(r))) { \ if (radicalleft(q)) { \ halfword p = new_kern(radicalwidth(q)-width(r)); \ reset_attributes(p, node_attr(q)); \ @@ -1988,7 +1990,7 @@ static pointer wrapup_over_under_delimiter(pointer x, pointer y, pointer q, scal } while (0) #define check_widths(q,p) do { \ - if (radicalwidth(q) != 0) { \ + if (radicalwidth(q) != zero_glue) { \ wd = radicalwidth(q); \ } else { \ wd = width(p); \ @@ -3708,11 +3710,13 @@ static pointer math_spacing_glue(int l_type, int r_type, int mstyle, scaled mmu) /* trap thin/med/thick settings cf. old TeX */ y = math_glue(glue_par(x), mmu); z = new_glue(y); + glue_ref_count(y) = null; /* store a symbolic subtype */ subtype(z) = (quarterword) (x + 1); } else { y = math_glue(x, mmu); z = new_glue(y); + glue_ref_count(y) = null; } } return z; @@ -3964,9 +3968,10 @@ void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) */ if (subtype(q) == mu_glue) { - x = q; /* was ptr */ + x = glue_ptr(q); y = math_glue(x, cur_mu); - q = y; /* we can get rid of the indirect */ + delete_glue_ref(x); + glue_ptr(q) = y; subtype(q) = normal; } else if ((cur_size != text_size) && (subtype(q) == cond_math_glue)) { p = vlink(q); diff --git a/Build/source/texk/web2c/luatexdir/tex/packaging.w b/Build/source/texk/web2c/luatexdir/tex/packaging.w index 5b9aa8b8995..0c474a50add 100644 --- a/Build/source/texk/web2c/luatexdir/tex/packaging.w +++ b/Build/source/texk/web2c/luatexdir/tex/packaging.w @@ -625,6 +625,7 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction) scaled x = 0; /* natural width */ scaled_whd whd; scaled s; /* shift amount */ + halfword g; /* points to a glue specification */ int o; /* order of infinity */ halfword dir_ptr1 = null; /* for managing the direction stack */ int hpack_dir; /* the current direction */ @@ -757,13 +758,14 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction) /* */ case glue_node: /* Incorporate glue into the horizontal totals */ - x += width(p); - o = stretch_order(p); - total_stretch[o] = total_stretch[o] + stretch(p); - o = shrink_order(p); - total_shrink[o] = total_shrink[o] + shrink(p); + g = glue_ptr(p); + x += width(g); + o = stretch_order(g); + total_stretch[o] = total_stretch[o] + stretch(g); + o = shrink_order(g); + total_shrink[o] = total_shrink[o] + shrink(g); if (subtype(p) >= a_leaders) { - halfword g = leader_ptr(p); + g = leader_ptr(p); if (height(g) > h) h = height(g); if (depth(g) > d) @@ -815,7 +817,7 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction) break; case math_node: /* begin mathskip code */ - if (glue_is_zero(p)) { + if (glue_ptr(p) == zero_glue) { x += surround(p); break; } else { @@ -1196,7 +1198,7 @@ scaled_whd natural_sizes(halfword p, halfword pp, glue_ratio g_mult, /* */ case math_node: /* begin mathskip code */ - if (glue_is_zero(p)) { + if (glue_ptr(p) == zero_glue) { siz.wd += surround(p); break; } else { @@ -1204,14 +1206,15 @@ scaled_whd natural_sizes(halfword p, halfword pp, glue_ratio g_mult, } /* end mathskip code */ case glue_node: - siz.wd += width(p); + g = glue_ptr(p); + siz.wd += width(g); if (g_sign != normal) { if (g_sign == stretching) { - if (stretch_order(p) == g_order) { - siz.wd += float_round(float_cast(g_mult) * float_cast(stretch(p))); + if (stretch_order(g) == g_order) { + siz.wd += float_round(float_cast(g_mult) * float_cast(stretch(g))); } - } else if (shrink_order(p) == g_order) { - siz.wd -= float_round(float_cast(g_mult) * float_cast(shrink(p))); + } else if (shrink_order(g) == g_order) { + siz.wd -= float_round(float_cast(g_mult) * float_cast(shrink(g))); } } if (subtype(p) >= a_leaders) { @@ -1273,6 +1276,7 @@ halfword vpackage(halfword p, scaled h, int m, scaled l, int pack_direction) scaled x = 0; /* natural height */ scaled_whd whd; scaled s; /* shift amount */ + halfword g; /* points to a glue specification */ int o; /* order of infinity */ last_badness = 0; r = new_node(vlist_node, 0); @@ -1343,13 +1347,14 @@ halfword vpackage(halfword p, scaled h, int m, scaled l, int pack_direction) /* Incorporate glue into the vertical totals */ x += d; d = 0; - x += width(p); - o = stretch_order(p); - total_stretch[o] = total_stretch[o] + stretch(p); - o = shrink_order(p); - total_shrink[o] = total_shrink[o] + shrink(p); + g = glue_ptr(p); + x += width(g); + o = stretch_order(g); + total_stretch[o] = total_stretch[o] + stretch(g); + o = shrink_order(g); + total_shrink[o] = total_shrink[o] + shrink(g); if (subtype(p) >= a_leaders) { - halfword g = leader_ptr(p); + g = leader_ptr(p); if (width(g) > w) w = width(g); } @@ -1638,7 +1643,8 @@ void append_to_vlist(halfword b, int location) p = new_param_glue(line_skip_code); } else { p = new_skip_param(baseline_skip_code); - width(p) = d; + /* |temp_ptr=glue_ptr(p)| */ + width(temp_ptr) = d; } couple_nodes(cur_list.tail_field, p); cur_list.tail_field = p; @@ -1696,10 +1702,11 @@ halfword prune_page_top(halfword p, boolean s) q = new_skip_param(split_top_skip_code); vlink(prev_p) = q; vlink(q) = p; - if (width(q) > height(p)) - width(q) = width(q) - height(p); + /* now |temp_ptr=glue_ptr(q)| */ + if (width(temp_ptr) > height(p)) + width(temp_ptr) = width(temp_ptr) - height(p); else - width(q) = 0; + width(temp_ptr) = 0; p = null; break; case boundary_node: @@ -1768,6 +1775,7 @@ halfword vert_break(halfword p, scaled h, scaled d) { halfword prev_p = p; /* if |p| is a glue node, |type(prev_p)| determines whether |p| is a legal breakpoint, an initial glue node is not a legal breakpoint */ + halfword q, r; /* glue specifications */ int pi = 0; /* penalty value */ int b; /* badness at a trial breakpoint */ int t; /* |type| of the node following a kern */ @@ -1873,20 +1881,27 @@ halfword vert_break(halfword p, scaled h, scaled d) contain infinite shrinkability, since that would permit any amount of information to ``fit'' on one page. */ - if (type(p) != kern_node) { - active_height[2 + stretch_order(p)] += stretch(p); - active_height[7] += shrink(p); - if ((shrink_order(p) != normal) && (shrink(p) != 0)) { + if (type(p) == kern_node) { + q = p; + } else { + q = glue_ptr(p); + active_height[2 + stretch_order(q)] += stretch(q); + active_height[7] += shrink(q); + if ((shrink_order(q) != normal) && (shrink(q) != 0)) { print_err("Infinite glue shrinkage found in box being split"); help4("The box you are \\vsplitting contains some infinitely", "shrinkable glue, e.g., `\\vss' or `\\vskip 0pt minus 1fil'.", "Such glue doesn't belong there; but you can safely proceed,", "since the offensive shrinkability has been made finite."); error(); - shrink_order(p) = normal; + r = new_spec(q); + shrink_order(r) = normal; + delete_glue_ref(q); + glue_ptr(p) = r; + q = r; } } - cur_height = cur_height + prev_dp + width(p); + cur_height = cur_height + prev_dp + width(q); prev_dp = 0; NOT_FOUND: if (prev_dp > d) { diff --git a/Build/source/texk/web2c/luatexdir/tex/postlinebreak.w b/Build/source/texk/web2c/luatexdir/tex/postlinebreak.w index fe11d76d0b1..43ceadcca28 100644 --- a/Build/source/texk/web2c/luatexdir/tex/postlinebreak.w +++ b/Build/source/texk/web2c/luatexdir/tex/postlinebreak.w @@ -163,7 +163,10 @@ void ext_post_line_break(int paragraph_dir, while(q != null) { if (type(q) == math_node) { surround(q) = 0 ; - reset_glue_to_zero(q); + if (glue_ptr(q) != zero_glue) { + delete_glue_ref(glue_ptr(q)); + glue_ptr(q) = zero_glue; + } break; } else if ((type(q) == hlist_node) && (subtype(q) == indent_list)) { /* go on */ @@ -199,11 +202,16 @@ void ext_post_line_break(int paragraph_dir, } else if (type(r) == math_node) { surround(r) = 0; /* begin mathskip code */ - reset_glue_to_zero(r); + if (glue_ptr(r) != zero_glue) { + delete_glue_ref(glue_ptr(r)); + glue_ptr(r) = zero_glue; + } /* end mathskip code */ } else if (type(r) == glue_node) { - copy_glue_values(r,right_skip); + delete_glue_ref(glue_ptr(r)); + glue_ptr(r) = right_skip; subtype(r) = right_skip_code + 1; + incr(glue_ref_count(right_skip)); glue_break = true; /* |q| refers to the last node of the line */ q = r; @@ -349,8 +357,9 @@ void ext_post_line_break(int paragraph_dir, then we append |rightskip| after |q| now */ if (!glue_break) { /* Put the \.{\\rightskip} glue after node |q|; */ - halfword r1 = new_glue((right_skip == null ? zero_glue : right_skip)); - subtype(r1) = right_skip_code+1; + halfword r1 = new_glue((right_skip == null ? null : copy_node(right_skip))); + glue_ref_count(glue_ptr(r1)) = null; + subtype(r1) = right_skip_code+1; try_couple_nodes(r1,vlink(q)); delete_attribute_ref(node_attr(r1)); node_attr(r1) = node_attr(q); @@ -390,7 +399,7 @@ void ext_post_line_break(int paragraph_dir, } /*at this point |q| is the leftmost node; all discardable nodes have been discarded */ if (protrude_chars > 0) { - halfword p; + halfword p; p = q; p = find_protchar_left(p, false); /* no more discardables */ w = char_pw(p, left_side); @@ -403,8 +412,9 @@ void ext_post_line_break(int paragraph_dir, q = k; } } - if (! glue_is_zero(left_skip)) { - r = new_glue(left_skip); + if (left_skip != zero_glue) { + r = new_glue(copy_node(left_skip)); + glue_ref_count(glue_ptr(r)) = null; subtype(r) = left_skip_code+1; delete_attribute_ref(node_attr(r)); node_attr(r) = node_attr(q); @@ -552,7 +562,11 @@ void ext_post_line_break(int paragraph_dir, if (type(q) == math_node) { /* begin mathskip code */ surround(q) = 0 ; - reset_glue_to_zero(q); + if (glue_ptr(q) != zero_glue) { + delete_glue_ref(glue_ptr(q)); + glue_ptr(q) = zero_glue; + add_glue_ref(glue_ptr(q)); + } /* end mathskip code */ } if (q == cur_break(cur_p)) { diff --git a/Build/source/texk/web2c/luatexdir/tex/scanning.w b/Build/source/texk/web2c/luatexdir/tex/scanning.w index 907d25f5bac..90499e8b4e5 100644 --- a/Build/source/texk/web2c/luatexdir/tex/scanning.w +++ b/Build/source/texk/web2c/luatexdir/tex/scanning.w @@ -139,10 +139,10 @@ int cur_val; /* value returned by numeric scanners */ int cur_val1; /* delcodes are sometimes 51 digits */ int cur_val_level; /* the ``level'' of this value */ -#define scanned_result(A,B) do { \ - cur_val=A; \ - cur_val_level=B; \ -} while (0) +#define scanned_result(A,B) do { \ + cur_val=A; \ + cur_val_level=B; \ + } while (0) @ When a |glue_val| changes to a |dimen_val|, we use the width component of the glue; there is no need to decrease the reference count, since it @@ -158,7 +158,7 @@ static void downgrade_cur_val(boolean delete_glue) m = cur_val; cur_val = width(m); if (delete_glue) - flush_node(m); + delete_glue_ref(m); } else if (cur_val_level == mu_val_level) { mu_error(); } @@ -172,7 +172,7 @@ static void negate_cur_val(boolean delete_glue) m = cur_val; cur_val = new_spec(m); if (delete_glue) - flush_node(m); + delete_glue_ref(m); /* Negate all three glue components of |cur_val| */ negate(width(cur_val)); negate(stretch(cur_val)); @@ -215,11 +215,9 @@ static boolean short_scan_something_internal(int cmd, int chr, int level, break; case assign_glue_cmd: scanned_result(equiv(m), glue_val_level); -// cur_val = new_spec(cur_val); break; case assign_mu_glue_cmd: scanned_result(equiv(m), mu_val_level); -// cur_val = new_spec(cur_val); break; case math_style_cmd: scanned_result(m, int_val_level); @@ -403,7 +401,7 @@ static boolean short_scan_something_internal(int cmd, int chr, int level, cur_val = stretch(q); else cur_val = shrink(q); - flush_node(q); + delete_glue_ref(q); break; } /* there are no other cases */ cur_val_level = dimen_val_level; @@ -480,7 +478,7 @@ static boolean short_scan_something_internal(int cmd, int chr, int level, cur_val = stretch_order(q); else cur_val = shrink_order(q); - flush_node(q); + delete_glue_ref(q); break; } /* there are no other cases */ cur_val_level = int_val_level; @@ -512,7 +510,7 @@ static boolean short_scan_something_internal(int cmd, int chr, int level, break; case lastskip_code: if (type(cur_list.tail_field) == glue_node) - cur_val = new_glue(cur_list.tail_field); + cur_val = glue_ptr(cur_list.tail_field); if (subtype(cur_list.tail_field) == mu_glue) cur_val_level = mu_val_level; break; @@ -531,7 +529,7 @@ static boolean short_scan_something_internal(int cmd, int chr, int level, break; case lastskip_code: if (last_glue != max_halfword) - cur_val = last_glue; /* maybe new_glue */ + cur_val = last_glue; break; case last_node_type_code: cur_val = last_node_type; @@ -556,8 +554,9 @@ static boolean short_scan_something_internal(int cmd, int chr, int level, */ if (negative) { negate_cur_val(false); - } else if ((cur_val_level >= glue_val_level) && (cur_val_level <= mu_val_level)) { - cur_val = new_glue(cur_val); + } else if ((cur_val_level >= glue_val_level) + && (cur_val_level <= mu_val_level)) { + add_glue_ref(cur_val); } } return succeeded; @@ -854,8 +853,9 @@ void scan_something_internal(int level, boolean negative) */ if (negative) { negate_cur_val(false); - } else if ((cur_val_level >= glue_val_level) && (cur_val_level <= mu_val_level)) { - cur_val = new_glue(cur_val); + } else if ((cur_val_level >= glue_val_level) && + (cur_val_level <= mu_val_level)) { + add_glue_ref(cur_val); } } } @@ -1103,7 +1103,7 @@ static void coerce_glue(void) int v; if (cur_val_level >= glue_val_level) { v = width(cur_val); - flush_node(cur_val); + delete_glue_ref(cur_val); cur_val = v; } } @@ -1513,18 +1513,36 @@ void scan_glue(int level) Create a new glue specification whose width is |cur_val|; scan for its stretch and shrink components. */ - q = new_spec(zero_glue); - width(q) = cur_val; + /* + In several places there is a test for zero glue, for instance in protrusion + left/right node detection. In that case a \hskip\dimen<n> with the dimen being + zero will not be seen as zero glue. Therefore we delay the allocation of + glue till we know for sure that there are no fils involved. (!!) + */ + if (cur_val != 0) { /* !! new test */ + q = new_spec(zero_glue); + width(q) = cur_val; + } if (scan_keyword("plus")) { + if (q == null) { /* !! new test */ + q = new_spec(zero_glue); + } scan_dimen(mu, true, false); stretch(q) = cur_val; stretch_order(q) = (quarterword) cur_order; } if (scan_keyword("minus")) { + if (q == null) { /* !! new test */ + q = new_spec(zero_glue); + } scan_dimen(mu, true, false); shrink(q) = cur_val; shrink_order(q) = (quarterword) cur_order; } + if (q == null) { /* !! new test */ + q = zero_glue ; + add_glue_ref(zero_glue); + } cur_val = q; } @@ -1680,11 +1698,11 @@ halfword the_toks(void) break; case glue_val_level: print_spec(cur_val, "pt"); - flush_node(cur_val); + delete_glue_ref(cur_val); break; case mu_val_level: print_spec(cur_val, "mu"); - flush_node(cur_val); + delete_glue_ref(cur_val); break; } /* there are no other cases */ selector = old_setting; @@ -1726,11 +1744,11 @@ str_number the_scanned_result(void) break; case glue_val_level: print_spec(cur_val, "pt"); - flush_node(cur_val); + delete_glue_ref(cur_val); break; case mu_val_level: print_spec(cur_val, "mu"); - flush_node(cur_val); + delete_glue_ref(cur_val); break; } /* there are no other cases */ r = make_string(); @@ -2185,7 +2203,8 @@ typedef enum { @c #define glue_error(A) do { \ arith_error=true; \ - reset_glue_to_zero(A); \ + delete_glue_ref(A); \ + A=new_spec(zero_glue); \ } while (0) #define normalize_glue(A) do { \ @@ -2491,11 +2510,9 @@ static void scan_expr(void) unless the next operator is a right parenthesis; this allows us later on to simply modify the glue components. */ - t = f; if ((l >= glue_val_level) && (o != expr_none)) { - /* do we really need to copy here ? */ t = new_spec(f); - flush_node(f); + delete_glue_ref(f); normalize_glue(t); } else { t = f; @@ -2571,7 +2588,7 @@ static void scan_expr(void) shrink(e) = shrink(t); shrink_order(e) = shrink_order(t); } - flush_node(t); + delete_glue_ref(t); normalize_glue(e); } r = o; @@ -2600,7 +2617,9 @@ static void scan_expr(void) "since the result is out of range."); error(); if (l >= glue_val_level) { - reset_glue_to_zero(e); + delete_glue_ref(e); + e = zero_glue; + add_glue_ref(e); } else { e = 0; } diff --git a/Build/source/texk/web2c/luatexdir/tex/texmath.w b/Build/source/texk/web2c/luatexdir/tex/texmath.w index 5067764fbf9..216d2364984 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texmath.w +++ b/Build/source/texk/web2c/luatexdir/tex/texmath.w @@ -2454,8 +2454,9 @@ void after_math(void) } tail_append(new_math(math_surround, before)); /* begin mathskip code */ - if (! glue_is_zero(math_skip)) { - copy_glue_values(tail,math_skip); + if (math_skip != zero_glue) { + glue_ptr(tail) = math_skip; + add_glue_ref(math_skip); } /* end mathskip code */ if (dir_math_save) { @@ -2463,17 +2464,17 @@ void after_math(void) } run_mlist_to_hlist(p, (mode > 0), text_style); vlink(tail) = vlink(temp_head); - while (vlink(tail) != null) { + while (vlink(tail) != null) tail = vlink(tail); - } if (dir_math_save) { tail_append(new_dir(math_direction - dir_swap)); } dir_math_save = false; tail_append(new_math(math_surround, after)); /* begin mathskip code */ - if (! glue_is_zero(math_skip)) { - copy_glue_values(tail,math_skip); + if (math_skip != zero_glue) { + glue_ptr(tail) = math_skip; + add_glue_ref(math_skip); } /* end mathskip code */ space_factor = 1000; diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.h b/Build/source/texk/web2c/luatexdir/tex/texnodes.h index 0da84945184..1f1a4e82964 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texnodes.h +++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.h @@ -68,6 +68,8 @@ extern void undump_node_mem(void); # define rlink(a) vlink((a)+1) /* aka alink() */ # define tlink(a) vinfo((a)+1) /* overlaps with node_attr() */ +# define add_glue_ref(a) glue_ref_count(a)++ /* new reference to a glue spec */ + /* really special head node pointers that only need links */ # define temp_node_size 2 @@ -104,6 +106,15 @@ extern void update_attribute_cache(void); extern halfword copy_attribute_list(halfword n); extern halfword do_set_attribute(halfword p, int i, int val); +/* a glue spec */ +# define glue_spec_size 4 +# define stretch(a) vlink((a)+1) +/* width == a+2 */ +# define shrink(a) vinfo((a)+1) +# define stretch_order(a) type((a)+3) +# define shrink_order(a) subtype((a)+3) +# define glue_ref_count(a) vlink((a)+3) + # define width_offset 2 # define depth_offset 3 # define height_offset 4 @@ -127,53 +138,11 @@ typedef enum { # define penalty_node_size 3 # define penalty(a) vlink((a)+2) -/* # define glue_node_size 4 # define glue_ptr(a) vinfo((a)+2) # define leader_ptr(a) vlink((a)+2) # define synctex_tag_glue(a) vinfo((a)+3) # define synctex_line_glue(a) vlink((a)+3) -*/ - -# define glue_node_size 7 -# define glue_spec_size 5 -/* define width(a) vinfo((a)+2) */ -/* define leader_ptr(a) vlink((a)+2) */ -# define shrink(a) vinfo((a)+3) -# define stretch(a) vlink((a)+3) -# define stretch_order(a) vinfo((a)+4) -# define shrink_order(a) vlink((a)+4) -# define leader_ptr(a) vlink((a)+5) /* should be in vlink((a)+2) but fails */ -# define synctex_tag_glue(a) vinfo((a)+6) -# define synctex_line_glue(a) vlink((a)+6) - -#define glue_is_zero(p) \ - ((p == null) || (width(p) == 0 && stretch(p) == 0 && shrink(p) == 0)) - -#define reset_glue_to_zero(p) \ - if (p != null) { \ - width(p) = 0; \ - stretch(p) = 0; \ - shrink(p) = 0; \ - stretch_order(p) = 0; \ - shrink_order(p) = 0; \ - } - -#define copy_glue_values(p,q) \ - if (q == null) { \ - width(p) = 0; \ - stretch(p) = 0; \ - shrink(p) = 0; \ - stretch_order(p) = 0; \ - shrink_order(p) = 0; \ - } else { \ - width(p) = width(q); \ - stretch(p) = stretch(q); \ - shrink(p) = shrink(q); \ - stretch_order(p) = stretch_order(q); \ - shrink_order(p) = shrink_order(q); \ - } - /* disc nodes could eventually be smaller, because the indirect @@ -313,17 +282,11 @@ typedef enum { # define before 0 /* |subtype| for math node that introduces a formula */ # define after 1 /* |subtype| for math node that winds up a formula */ -# define math_node_size 7 -/* define width(a) vinfo((a)+2) */ -/* overlaps width */ -/* define shrink(a) vinfo((a)+3) */ -/* define stretch(a) vlink((a)+3) */ -/* define stretch_order(a) vinfo((a)+4) */ -/* define shrink_order(a) vlink((a)+4) */ -/* leader_ptr slot */ -# define surround(a) vinfo((a)+5) -# define synctex_tag_math(a) vinfo((a)+6) -# define synctex_line_math(a) vlink((a)+6) +# define math_node_size 4 +# define surround(a) vlink((a)+2) +/* also: glue_ptr(a) vinfo((a)+2) */ +# define synctex_tag_math(a) vinfo((a)+3) +# define synctex_line_math(a) vlink((a)+3) # define ins_node_size 6 # define float_cost(a) varmem[(a)+2].cint @@ -657,13 +620,15 @@ typedef enum { # define special_node_size 3 -# define dir_node_size 5 +# define dir_node_size 6 # define dir_dir(a) vinfo((a)+2) # define dir_level(a) vlink((a)+2) -# define dir_refpos_h(a) vinfo((a)+3) -# define dir_refpos_v(a) vlink((a)+3) -# define dir_cur_h(a) vinfo((a)+4) -# define dir_cur_v(a) vlink((a)+4) +# define dir_dvi_ptr(a) vinfo((a)+3) +# define dir_dvi_h(a) vlink((a)+3) /* obsolete */ +# define dir_refpos_h(a) vinfo((a)+4) +# define dir_refpos_v(a) vlink((a)+4) +# define dir_cur_h(a) vinfo((a)+5) +# define dir_cur_v(a) vlink((a)+5) # define write_node_size 3 # define close_node_size 3 @@ -945,8 +910,10 @@ typedef enum { # define is_running(A) ((A)==null_flag) /* tests for a running dimension */ extern halfword tail_of_list(halfword p); +extern void delete_glue_ref(halfword p); extern int var_used; +extern halfword temp_ptr; # define cache_disabled max_halfword diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.w b/Build/source/texk/web2c/luatexdir/tex/texnodes.w index 77610988d95..a201c6da714 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texnodes.w +++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.w @@ -89,10 +89,10 @@ const char *node_fields_disc[] = { "attr", "pre", "post", "replace", "penalty", NULL }; const char *node_fields_math[] = { - "attr", "surround", "width", "stretch", "shrink", "stretch_order", "shrink_order", NULL + "attr", "surround", NULL }; const char *node_fields_glue[] = { - "attr", "leader", "width", "stretch", "shrink", "stretch_order", "shrink_order", NULL + "attr", "spec", "leader", NULL }; const char *node_fields_kern[] = { "attr", "kern", "expansion_factor", NULL @@ -112,8 +112,7 @@ const char *node_fields_glyph[] = { "xoffset", "yoffset", "width", "height", "depth", "expansion_factor", NULL }; const char *node_fields_inserting[] = { - "height", "last_ins_ptr", "best_ins_ptr", - "width", "stretch", "shrink", "stretch_order", "shrink_order", NULL + "height", "last_ins_ptr", "best_ins_ptr", NULL }; const char *node_fields_splitup[] = { "height", "last_ins_ptr", "best_ins_ptr", "broken_ptr", "broken_ins", NULL @@ -122,7 +121,8 @@ const char *node_fields_attribute[] = { "number", "value", NULL }; const char *node_fields_glue_spec[] = { - "width", "stretch", "shrink", "stretch_order", "shrink_order", NULL + "width", "stretch", "shrink", "stretch_order", "shrink_order", "ref_count", + "writable", NULL }; const char *node_fields_attribute_list[] = { NULL @@ -132,7 +132,7 @@ const char *node_fields_local_par[] = { "box_right", "box_right_width", NULL }; const char *node_fields_dir[] = { - "attr", "dir", "level", NULL + "attr", "dir", "level", "dvi_ptr", "dvi_h", NULL }; const char *node_fields_boundary[] = { "attr", "value", NULL @@ -620,6 +620,7 @@ static int test_count = 1; } } while (0) #define check_action_ref(a) { dorangetest(p,a,var_mem_max); } +#define check_glue_ref(a) { dorangetest(p,a,var_mem_max); } #define check_attribute_ref(a) { dorangetest(p,a,var_mem_max); } #define check_token_ref(a) { confusion("fuzzy token cleanup in node"); } @@ -1077,6 +1078,7 @@ halfword copy_node(const halfword p) copy_sub_list(lig_ptr(r),lig_ptr(p)) ; break; case glue_node: + add_glue_ref(glue_ptr(p)); copy_sub_list(leader_ptr(r),leader_ptr(p)) ; break; case hlist_node: @@ -1114,8 +1116,12 @@ halfword copy_node(const halfword p) } break; case math_node: + if (glue_ptr(p) != zero_glue) { + add_glue_ref(glue_ptr(p)); + } break; case ins_node: + add_glue_ref(split_top_ptr(p)); copy_sub_list(ins_ptr(r),ins_ptr(p)) ; break; case margin_kern_node: @@ -1167,6 +1173,8 @@ halfword copy_node(const halfword p) copy_sub_node(right_delimiter(r),right_delimiter(p)) ; break; case glue_spec_node: + glue_ref_count(r) = null; + break; case dir_node: case local_par_node: case boundary_node: @@ -1312,6 +1320,7 @@ void flush_node(halfword p) free_sub_list(lig_ptr(p)); break; case glue_node: + delete_glue_ref(glue_ptr(p)); free_sub_list(leader_ptr(p)); break; case hlist_node: @@ -1328,14 +1337,24 @@ void flush_node(halfword p) case rule_node: case kern_node: case penalty_node: + break; case math_node: + /* begin mathskip code */ + if (glue_ptr(p) != zero_glue) { + delete_glue_ref(glue_ptr(p)); + } + /* end mathskip code */ break; case glue_spec_node: /* this allows free-ing of lua-allocated glue specs */ -//if (valid_node(p)) { -// free_node(p, subtype(p)); -//} -// return ; + if (valid_node(p)) { + if (glue_ref_count(p)!=null) { + decr(glue_ref_count(p)); + } else { + free_node(p, get_node_size(type(p), subtype(p))); + } + } + return ; break ; case dir_node: case local_par_node: @@ -1353,6 +1372,7 @@ void flush_node(halfword p) break; case ins_node: flush_node_list(ins_ptr(p)); + delete_glue_ref(split_top_ptr(p)); break; case margin_kern_node: flush_node(margin_char(p)); @@ -1559,6 +1579,7 @@ void check_node(halfword p) dorangetest(p, lig_ptr(p), var_mem_max); break; case glue_node: + check_glue_ref(glue_ptr(p)); dorangetest(p, leader_ptr(p), var_mem_max); break; case hlist_node: @@ -1569,6 +1590,7 @@ void check_node(halfword p) break; case ins_node: dorangetest(p, ins_ptr(p), var_mem_max); + check_glue_ref(split_top_ptr(p)); break; case whatsit_node: w = subtype(p) ; @@ -1584,6 +1606,11 @@ void check_node(halfword p) check_node(margin_char(p)); break; case math_node: + /* begin mathskip code */ + if (glue_ptr(p) != zero_glue) { + check_glue_ref(glue_ptr(p)); + } + /* end mathskip code */ break; case disc_node: dorangetest(p, vlink(pre_break(p)), var_mem_max); @@ -1777,6 +1804,7 @@ void init_node_mem(int t) node_size(rover) = (t - rover); var_used = 0; /* initialize static glue specs */ + glue_ref_count(zero_glue) = null + 1; width(zero_glue) = 0; type(zero_glue) = glue_spec_node; vlink(zero_glue) = null; @@ -1784,6 +1812,7 @@ void init_node_mem(int t) stretch_order(zero_glue) = normal; shrink(zero_glue) = 0; shrink_order(zero_glue) = normal; + glue_ref_count(sfi_glue) = null + 1; width(sfi_glue) = 0; type(sfi_glue) = glue_spec_node; vlink(sfi_glue) = null; @@ -1791,6 +1820,7 @@ void init_node_mem(int t) stretch_order(sfi_glue) = sfi; shrink(sfi_glue) = 0; shrink_order(sfi_glue) = normal; + glue_ref_count(fil_glue) = null + 1; width(fil_glue) = 0; type(fil_glue) = glue_spec_node; vlink(fil_glue) = null; @@ -1798,6 +1828,7 @@ void init_node_mem(int t) stretch_order(fil_glue) = fil; shrink(fil_glue) = 0; shrink_order(fil_glue) = normal; + glue_ref_count(fill_glue) = null + 1; width(fill_glue) = 0; type(fill_glue) = glue_spec_node; vlink(fill_glue) = null; @@ -1805,6 +1836,7 @@ void init_node_mem(int t) stretch_order(fill_glue) = fill; shrink(fill_glue) = 0; shrink_order(fill_glue) = normal; + glue_ref_count(ss_glue) = null + 1; width(ss_glue) = 0; type(ss_glue) = glue_spec_node; vlink(ss_glue) = null; @@ -1812,6 +1844,7 @@ void init_node_mem(int t) stretch_order(ss_glue) = fil; shrink(ss_glue) = unity; shrink_order(ss_glue) = fil; + glue_ref_count(fil_neg_glue) = null + 1; width(fil_neg_glue) = 0; type(fil_neg_glue) = glue_spec_node; vlink(fil_neg_glue) = null; @@ -2474,7 +2507,7 @@ void print_short_node_contents(halfword p) print_char('|'); break; case glue_node: - if (! glue_is_zero(p)) + if (glue_ptr(p) != zero_glue) print_char(' '); break; case math_node: @@ -3015,7 +3048,7 @@ void show_node_list(int p) normal_warning("nodes","weird glue leader subtype ignored"); } tprint("leaders "); - print_spec(p, NULL); + print_spec(glue_ptr(p), NULL); node_list_display(leader_ptr(p)); /* recursive call */ } else { tprint_esc("glue"); @@ -3037,9 +3070,9 @@ void show_node_list(int p) if (subtype(p) != cond_math_glue) { print_char(' '); if (subtype(p) < cond_math_glue) - print_spec(p, NULL); + print_spec(glue_ptr(p), NULL); else - print_spec(p, "mu"); + print_spec(glue_ptr(p), "mu"); } } break; @@ -3136,6 +3169,7 @@ void show_node_list(int p) @c pointer actual_box_width(pointer r, scaled base_width) { + pointer q; /* glue specification when calculating |pre_display_size| */ scaled d; /* increment to |v| */ scaled w = -max_dimen; /* calculated |size| */ scaled v = shift_amount(r) + base_width; /* |w| plus possible glue amount */ @@ -3160,7 +3194,7 @@ pointer actual_box_width(pointer r, scaled base_width) break; case math_node: /* begin mathskip code */ - if (glue_is_zero(p)) { + if (glue_ptr(p) == zero_glue) { d = surround(p); break; } else { @@ -3174,12 +3208,15 @@ pointer actual_box_width(pointer r, scaled base_width) |pre_display_size|, since \TeX82 is supposed to make the same decisions on all machines. */ - d = width(p); + q = glue_ptr(p); + d = width(q); if (glue_sign(r) == stretching) { - if ((glue_order(r) == stretch_order(p)) && (stretch(p) != 0)) + if ((glue_order(r) == stretch_order(q)) + && (stretch(q) != 0)) v = max_dimen; } else if (glue_sign(r) == shrinking) { - if ((glue_order(r) == shrink_order(p)) && (shrink(p) != 0)) + if ((glue_order(r) == shrink_order(q)) + && (shrink(q) != 0)) v = max_dimen; } if (subtype(p) >= a_leaders) @@ -3215,10 +3252,26 @@ halfword tail_of_list(halfword p) return q; } +@ |delete_glue_ref| is called when a pointer to a glue + specification is being withdrawn. +@c +void delete_glue_ref(halfword p) +{ /* |p| points to a glue specification */ + if (type(p) == glue_spec_node) { + if (glue_ref_count(p) == null) { + flush_node(p); + } else { + decr(glue_ref_count(p)); + } + } else { + normal_error("nodes","invalid glue spec node"); + } +} @ @c int var_used; +halfword temp_ptr; /* a pointer variable for occasional emergency use */ @ Attribute lists need two extra globals to increase processing efficiency. |max_used_attr| limits the test loop that checks for set attributes, and @@ -3532,8 +3585,10 @@ to be exactly one reference to the new specification. @c halfword new_spec(halfword p) -{ - return copy_node(p == null ? zero_glue : p); +{ /* duplicates a glue specification */ + halfword q = copy_node(p); + glue_ref_count(q) = null; + return q; } @ And here's a function that creates a glue node for a given parameter @@ -3546,11 +3601,8 @@ halfword new_param_glue(int n) { halfword p = new_node(glue_node, n + 1); halfword q = glue_par(n); - width(p) = width(q); - stretch(p) = stretch(q); - shrink(p) = shrink(q); - stretch_order(p) = stretch_order(q); - shrink_order(p) = shrink_order(q); + glue_ptr(p) = q; + incr(glue_ref_count(q)); return p; } @@ -3561,11 +3613,8 @@ whose argument points to a glue specification. halfword new_glue(halfword q) { halfword p = new_node(glue_node, normal); - width(p) = width(q); - stretch(p) = stretch(q); - shrink(p) = shrink(q); - stretch_order(p) = stretch_order(q); - shrink_order(p) = shrink_order(q); + glue_ptr(p) = q; + incr(glue_ref_count(q)); return p; } @@ -3573,22 +3622,17 @@ halfword new_glue(halfword q) of |new_param_glue| and |new_glue|. It creates a glue node for one of the current glue parameters, but it makes a fresh copy of the glue specification, since that specification will probably be subject to change, -while the parameter will stay put. - -/* - The global variable |temp_ptr| is set to the address of the new spec. -*/ +while the parameter will stay put. The global variable |temp_ptr| is +set to the address of the new spec. @c halfword new_skip_param(int n) { - halfword p = new_node(glue_node, n + 1); - halfword q = glue_par(n); - width(p) = width(q); - stretch(p) = stretch(q); - shrink(p) = shrink(q); - stretch_order(p) = stretch_order(q); - shrink_order(p) = shrink_order(q); + halfword p; /* the new node */ + temp_ptr = new_spec(glue_par(n)); + p = new_glue(temp_ptr); + glue_ref_count(temp_ptr) = null; + subtype(p) = (quarterword) (n + 1); return p; } |