From 265ba2a85e0945a37972e22f23bcaac16d6c08a1 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Mon, 5 Dec 2022 23:11:09 +0100 Subject: 2022-12-05 18:51:00 --- .../general/manuals/luametatex/luametatex-math.tex | 10 +- scripts/context/lua/mtx-fonts.lua | 2 +- source/luametatex/source/lua/lmtinterface.h | 36 +++- source/luametatex/source/lua/lmtmplib.c | 9 +- source/luametatex/source/lua/lmtnodelib.c | 62 +++++- source/luametatex/source/lua/lmttexiolib.c | 3 +- source/luametatex/source/lua/lmttexlib.c | 4 +- source/luametatex/source/luametatex.h | 6 +- source/luametatex/source/luarest/lmtpdfelib.c | 50 +++-- source/luametatex/source/tex/texcommands.c | 1 + source/luametatex/source/tex/texcommands.h | 1 + source/luametatex/source/tex/texexpand.c | 14 ++ source/luametatex/source/tex/texfont.c | 4 +- source/luametatex/source/tex/texnodes.c | 118 ++++++++--- source/luametatex/source/tex/texnodes.h | 6 +- source/luametatex/source/tex/texprinting.c | 15 +- source/luametatex/source/tex/texscanning.c | 21 +- source/luametatex/source/tex/texscanning.h | 2 - source/luametatex/source/tex/textoken.c | 32 +++ source/luametatex/source/tex/textoken.h | 1 + tex/context/base/mkii/cont-new.mkii | 2 +- tex/context/base/mkii/context.mkii | 2 +- tex/context/base/mkiv/cont-new.mkiv | 2 +- tex/context/base/mkiv/context.mkiv | 2 +- tex/context/base/mkiv/font-dsp.lua | 18 ++ tex/context/base/mkiv/font-mis.lua | 2 +- tex/context/base/mkiv/font-otl.lua | 2 +- tex/context/base/mkiv/font-otr.lua | 3 + tex/context/base/mkiv/font-ots.lua | 4 +- tex/context/base/mkiv/font-prv.lua | 16 ++ tex/context/base/mkiv/font-ttf.lua | 44 ++-- tex/context/base/mkiv/math-ini.mkiv | 36 ++-- tex/context/base/mkiv/status-files.pdf | Bin 24588 -> 24597 bytes tex/context/base/mkiv/status-lua.pdf | Bin 264506 -> 264620 bytes tex/context/base/mkxl/cont-new.mkxl | 2 +- tex/context/base/mkxl/context.mkxl | 4 +- tex/context/base/mkxl/driv-shp.lmt | 64 +++--- tex/context/base/mkxl/font-col.lmt | 21 +- tex/context/base/mkxl/font-dsp.lmt | 172 +++++++++------- tex/context/base/mkxl/font-otl.lmt | 2 +- tex/context/base/mkxl/lpdf-emb.lmt | 8 +- tex/context/base/mkxl/mult-aux.mkxl | 22 +- tex/context/base/mkxl/node-fnt.lmt | 229 ++++++++++++--------- tex/context/base/mkxl/node-nut.lmt | 2 + tex/context/base/mkxl/pack-rul.lmt | 26 ++- tex/context/base/mkxl/pack-rul.mkxl | 6 +- tex/context/base/mkxl/page-lay.mkxl | 9 + tex/context/base/mkxl/page-sel.lmt | 77 +++++++ tex/context/base/mkxl/page-sel.mklx | 36 ++++ tex/context/base/mkxl/spac-ver.mkxl | 9 +- tex/context/base/mkxl/trac-vis.lmt | 1 + tex/context/base/mkxl/util-sac.lmt | 2 + tex/context/fonts/mkiv/bonum-math.lfg | 2 +- tex/generic/context/luatex/luatex-fonts-merged.lua | 45 ++-- 54 files changed, 865 insertions(+), 404 deletions(-) create mode 100644 tex/context/base/mkxl/page-sel.lmt diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-math.tex b/doc/context/sources/general/manuals/luametatex/luametatex-math.tex index 66a62ee72..82a6cce50 100644 --- a/doc/context/sources/general/manuals/luametatex/luametatex-math.tex +++ b/doc/context/sources/general/manuals/luametatex/luametatex-math.tex @@ -2510,11 +2510,11 @@ If you also want to see something on the console make sure to set \prm You can change the class of a math character on the fly: \startbuffer -$x\mathopen {!}+123+\mathclose {!}x$ -$x\Umathclass4 ! +123+\Umathclass5 ! x$ -$x ! +123+ ! x$ -$x\mathclose {!}+123+\mathopen {!}x$ -$x\Umathclass5 ! +123+\Umathclass4 ! x$ +$x\mathopen {!}+123+\mathclose {!}x$ +$x\Umathclass4 `! +123+\Umathclass5 `! x$ +$x ! +123+ ! x$ +$x\mathclose {!}+123+\mathopen {!}x$ +$x\Umathclass5 `! +123+\Umathclass4 `! x$ \stopbuffer \typebuffer diff --git a/scripts/context/lua/mtx-fonts.lua b/scripts/context/lua/mtx-fonts.lua index a7cf817d5..1a677cb26 100644 --- a/scripts/context/lua/mtx-fonts.lua +++ b/scripts/context/lua/mtx-fonts.lua @@ -16,7 +16,7 @@ local lower, gsub = string.lower, string.gsub local concat = table.concat local write_nl = (logs and logs.writer) or (texio and texio.write_nl) or print -local otlversion = 3.130 +local otlversion = 3.131 local helpinfo = [[ diff --git a/source/luametatex/source/lua/lmtinterface.h b/source/luametatex/source/lua/lmtinterface.h index 707d3aefb..756a25331 100644 --- a/source/luametatex/source/lua/lmtinterface.h +++ b/source/luametatex/source/lua/lmtinterface.h @@ -234,8 +234,8 @@ extern int luaextend_xcomplex (lua_State *L); /*tex Used in |lmttokenlib|. */ -# define TOKEN_METATABLE_INSTANCE "token.instance" -# define TOKEN_METATABLE_PACKAGE "token.package" +# define TOKEN_METATABLE_INSTANCE "token.instance" +# define TOKEN_METATABLE_PACKAGE "token.package" /*tex Used in |lmtepdflib|. */ @@ -255,6 +255,28 @@ extern int luaextend_xcomplex (lua_State *L); # define SPARSE_METATABLE_INSTANCE "sparse.instance" +/*tex + There are some more but for now we have no reason to alias them for performance reasons, so + that got postponed. We then also need to move the defines here: +*/ + +/* +# define DIR_METATABLE "file.directory" + +# define LUA_BYTECODES_INDIRECT + +# define TEX_METATABLE_TEX "tex.tex" +# define TEX_NEST_INSTANCE "tex.nest.instance" +# define TEX_* "tex.*" + +# define LUA_FUNCTIONS "lua.functions" +# define LUA_BYTECODES "lua.bytecodes" +# define LUA_BYTECODES_INDIRECT "lua.bytecodes.indirect" + +# define LANGUAGE_METATABLE "luatex.language" +# define LANGUAGE_FUNCTIONS "luatex.language.wordhandlers" +*/ + /*tex Currently we sometimes use numbers and sometimes strings in node properties. We can make that @@ -1458,10 +1480,12 @@ make_lua_key_alias(L, token_package, TOKEN_METATABLE_PACKAGE);\ make_lua_key_alias(L, sparse_instance, SPARSE_METATABLE_INSTANCE);\ /* */ \ make_lua_key_alias(L, pdfe_instance, PDFE_METATABLE_INSTANCE);\ -make_lua_key_alias(L, pdfe_dictionary, PDFE_METATABLE_DICTIONARY);\ -make_lua_key_alias(L, pdfe_array, PDFE_METATABLE_ARRAY);\ -make_lua_key_alias(L, pdfe_stream, PDFE_METATABLE_STREAM);\ -make_lua_key_alias(L, pdfe_reference, PDFE_METATABLE_REFERENCE);\ +make_lua_key_alias(L, pdfe_dictionary_instance, PDFE_METATABLE_DICTIONARY);\ +make_lua_key_alias(L, pdfe_array_instance, PDFE_METATABLE_ARRAY);\ +make_lua_key_alias(L, pdfe_stream_instance, PDFE_METATABLE_STREAM);\ +make_lua_key_alias(L, pdfe_reference_instance, PDFE_METATABLE_REFERENCE);\ +/* */ \ +make_lua_key_alias(L, file_handle_instance, LUA_FILEHANDLE);\ /* done */ # define declare_metapost_lua_keys(L) \ diff --git a/source/luametatex/source/lua/lmtmplib.c b/source/luametatex/source/lua/lmtmplib.c index ecbfd46b6..83fe3efd4 100644 --- a/source/luametatex/source/lua/lmtmplib.c +++ b/source/luametatex/source/lua/lmtmplib.c @@ -1703,7 +1703,8 @@ static int mplib_new(lua_State *L) *mpud = mp; mplib_aux_set_bend_tolerance(L, bendtolerance); mplib_aux_set_move_tolerance(L, movetolerance); - luaL_getmetatable(L, MP_METATABLE_INSTANCE); + // luaL_getmetatable(L, MP_METATABLE_INSTANCE); + lua_get_metatablelua(mplib_instance); lua_setmetatable(L, -2); return 1; } @@ -1763,7 +1764,8 @@ static int mplib_aux_wrapresults(lua_State *L, mp_run_data *res, int status, lua *v = p; mplib_aux_set_bend_tolerance(L, bendtolerance); mplib_aux_set_move_tolerance(L, movetolerance); - luaL_getmetatable(L, MP_METATABLE_FIGURE); + // luaL_getmetatable(L, MP_METATABLE_FIGURE); + lua_get_metatablelua(mplib_figure); lua_setmetatable(L, -2); lua_rawseti(L, -2, i); i++; @@ -2341,7 +2343,8 @@ static int mplib_figure_objects(lua_State *L) *v = p; mplib_aux_set_bend_tolerance(L, bendtolerance); mplib_aux_set_move_tolerance(L, movetolerance); - luaL_getmetatable(L, MP_METATABLE_OBJECT); + // luaL_getmetatable(L, MP_METATABLE_OBJECT); + lua_get_metatablelua(mplib_object); lua_setmetatable(L, -2); lua_rawseti(L, -2, i); i++; diff --git a/source/luametatex/source/lua/lmtnodelib.c b/source/luametatex/source/lua/lmtnodelib.c index 2a02fbd11..58a98f7e3 100644 --- a/source/luametatex/source/lua/lmtnodelib.c +++ b/source/luametatex/source/lua/lmtnodelib.c @@ -2489,10 +2489,18 @@ static int nodelib_direct_getgeometry(lua_State* L) lua_pushboolean(L, tex_has_box_geometry(n, offset_geometry)); lua_pushboolean(L, tex_has_box_geometry(n, orientation_geometry)); lua_pushboolean(L, tex_has_box_geometry(n, anchor_geometry)); - return 4; + lua_pushinteger(L, checked_direction_value(box_dir(n))); + return 5; } else { return 1; } + } else if (lua_toboolean(L, 2)) { + lua_pushboolean(L, 0); + lua_pushboolean(L, 0); + lua_pushboolean(L, 0); + lua_pushboolean(L, 0); + lua_pushinteger(L, checked_direction_value(box_dir(n))); + return 5; } break; } @@ -2870,6 +2878,25 @@ static int nodelib_direct_getkerndimension(lua_State *L) } } +static int nodelib_direct_getlistdimensions(lua_State *L) +{ + halfword n = nodelib_valid_direct_from_index(L, 1); + if (n) { + switch (node_type(n)) { + /* when we need it more node types will be handled */ + case hlist_node: + case vlist_node: + lua_pushinteger(L, box_width(n)); + lua_pushinteger(L, box_height(n)); + lua_pushinteger(L, box_depth(n)); + lua_pushinteger(L, box_shift_amount(n)); + nodelib_push_direct_or_nil_node_prev(L, box_list(n)); + return 5; + } + } + return 0; +} + /* node.direct.getlist */ static int nodelib_direct_getlist(lua_State *L) @@ -3874,7 +3901,7 @@ static int nodelib_direct_remove(lua_State *L) return 3; } } else { - lua_pushinteger(L, head); + nodelib_push_direct_or_nil(L, head); lua_pushnil(L); } } else { @@ -3884,6 +3911,34 @@ static int nodelib_direct_remove(lua_State *L) return 2; } +static int nodelib_direct_remove_from_list(lua_State *L) +{ + halfword head = nodelib_valid_direct_from_index(L, 1); + int count = 0; + if (head) { + halfword id = lmt_tohalfword(L, 2); + halfword subtype = lmt_opthalfword(L, 3, -1); + halfword current = head; + while (current) { + halfword next = node_next(current); + if (node_type(current) == id && (subtype < 0 || node_subtype(current) == subtype)) { + if (current == head) { + head = next; + node_prev(next) = null; + } else { + tex_try_couple_nodes(node_prev(current), next); + } + tex_flush_node(current); + ++count; + } + current = next; + } + } + nodelib_push_direct_or_nil(L, head); + lua_push_integer(L, count); + return 2; +} + /* node.insertbefore (insert a node in a list) */ static int nodelib_userdata_insertbefore(lua_State *L) @@ -8436,7 +8491,6 @@ static int nodelib_direct_isprevglyph(lua_State *L) } } - /* direct.usesfont */ inline static int nodelib_aux_uses_font_disc(lua_State *L, halfword n, halfword font) @@ -9700,8 +9754,10 @@ static const struct luaL_Reg nodelib_direct_function_list[] = { { "rangedimensions", nodelib_direct_rangedimensions }, /* maybe get... */ { "getglyphdimensions", nodelib_direct_getglyphdimensions }, { "getkerndimension", nodelib_direct_getkerndimension }, + { "getlistdimensions", nodelib_direct_getlistdimensions }, { "patchattributes", nodelib_direct_patchattributes }, { "remove", nodelib_direct_remove }, + { "removefromlist", nodelib_direct_remove_from_list }, { "repack", nodelib_direct_repack }, { "freeze", nodelib_direct_freeze }, { "setattribute", nodelib_direct_setattribute }, diff --git a/source/luametatex/source/lua/lmttexiolib.c b/source/luametatex/source/lua/lmttexiolib.c index f7f7751d8..416293164 100644 --- a/source/luametatex/source/lua/lmttexiolib.c +++ b/source/luametatex/source/lua/lmttexiolib.c @@ -19,7 +19,8 @@ FILE *lmt_valid_file(lua_State *L) { luaL_Stream *p = (luaL_Stream *) lua_touserdata(L, 1); if (p && lua_getmetatable(L, 1)) { - luaL_getmetatable(L, LUA_FILEHANDLE); + // luaL_getmetatable(L, LUA_FILEHANDLE); + lua_get_metatablelua(file_handle_instance); if (! lua_rawequal(L, -1, -2)) { p = NULL; } diff --git a/source/luametatex/source/lua/lmttexlib.c b/source/luametatex/source/lua/lmttexlib.c index 7d1f3c32f..d3f4c0ab9 100644 --- a/source/luametatex/source/lua/lmttexlib.c +++ b/source/luametatex/source/lua/lmttexlib.c @@ -27,7 +27,8 @@ /*tex Due to the nature of the accessors, this is the module with most metatables. However, we - provide getters and setters too. Users can choose what they like most. + provide getters and setters too. Users can choose what they like most. If needed we can use + fast metatable resolvers but there is no real need. */ # define TEX_METATABLE_ATTRIBUTE "tex.attribute" @@ -2604,6 +2605,7 @@ static int texlib_aux_convert(lua_State *L, int cur_code) case string_code: /* arg token */ case cs_string_code: /* arg token */ case cs_active_code: /* arg token */ + /* case cs_lastname_code: */ /* arg token */ case detokenized_code: /* arg token */ case meaning_code: /* arg token */ case to_mathstyle_code: diff --git a/source/luametatex/source/luametatex.h b/source/luametatex/source/luametatex.h index 6bb728234..a9f739cec 100644 --- a/source/luametatex/source/luametatex.h +++ b/source/luametatex/source/luametatex.h @@ -87,9 +87,9 @@ # include "tex/textypes.h" # define luametatex_version 210 -# define luametatex_revision 02 -# define luametatex_version_string "2.10.02" -# define luametatex_development_id 20221118 +# define luametatex_revision 04 +# define luametatex_version_string "2.10.04" +# define luametatex_development_id 20221202 # define luametatex_name_camelcase "LuaMetaTeX" # define luametatex_name_lowercase "luametatex" diff --git a/source/luametatex/source/luarest/lmtpdfelib.c b/source/luametatex/source/luarest/lmtpdfelib.c index b22626749..74000d756 100644 --- a/source/luametatex/source/luarest/lmtpdfelib.c +++ b/source/luametatex/source/luarest/lmtpdfelib.c @@ -90,7 +90,7 @@ static pdfe_dictionary *pdfelib_aux_check_isdictionary(lua_State *L, int n) { pdfe_dictionary *p = (pdfe_dictionary *) lua_touserdata(L, n); if (p && lua_getmetatable(L, n)) { - lua_get_metatablelua(pdfe_dictionary); + lua_get_metatablelua(pdfe_dictionary_instance); if (! lua_rawequal(L, -1, -2)) { p = NULL; } @@ -107,7 +107,7 @@ static pdfe_array *pdfelib_aux_check_isarray(lua_State *L, int n) { pdfe_array *p = (pdfe_array *) lua_touserdata(L, n); if (p && lua_getmetatable(L, n)) { - lua_get_metatablelua(pdfe_array); + lua_get_metatablelua(pdfe_array_instance); if (! lua_rawequal(L, -1, -2)) { p = NULL; } @@ -124,7 +124,7 @@ static pdfe_stream *pdfelib_aux_check_isstream(lua_State *L, int n) { pdfe_stream *p = (pdfe_stream *) lua_touserdata(L, n); if (p && lua_getmetatable(L, n)) { - lua_get_metatablelua(pdfe_stream); + lua_get_metatablelua(pdfe_stream_instance); if (! lua_rawequal(L, -1, -2)) { p = NULL; } @@ -141,7 +141,7 @@ static pdfe_reference *pdfelib_aux_check_isreference(lua_State *L, int n) { pdfe_reference *p = (pdfe_reference *) lua_touserdata(L, n); if (p && lua_getmetatable(L, n)) { - lua_get_metatablelua(pdfe_reference); + lua_get_metatablelua(pdfe_reference_instance); if (! lua_rawequal(L, -1, -2)) { p = NULL; } @@ -203,10 +203,10 @@ static int pdfelib_type(lua_State *L) void *p = lua_touserdata(L, 1); if (p && lua_getmetatable(L, 1)) { check_type(document, pdfe_instance); - check_type(dictionary, pdfe_dictionary); - check_type(array, pdfe_array); - check_type(reference, pdfe_reference); - check_type(stream, pdfe_stream); + check_type(dictionary, pdfe_dictionary_instance); + check_type(array, pdfe_array_instance); + check_type(reference, pdfe_reference_instance); + check_type(stream, pdfe_stream_instance); } return 0; } @@ -278,7 +278,8 @@ static int pdfelib_reference_tostring(lua_State *L) { inline static void pdfe_push_dictionary(lua_State *L, ppdict *dictionary) { pdfe_dictionary *d = (pdfe_dictionary *) lua_newuserdatauv(L, sizeof(pdfe_dictionary), 0); - luaL_getmetatable(L, PDFE_METATABLE_DICTIONARY); + // luaL_getmetatable(L, PDFE_METATABLE_DICTIONARY); + lua_get_metatablelua(pdfe_dictionary_instance); lua_setmetatable(L, -2); d->dictionary = dictionary; } @@ -307,7 +308,8 @@ static int pdfelib_aux_pushdictionaryonly(lua_State *L, ppdict *dictionary) inline static void pdfe_push_array(lua_State *L, pparray *array) { pdfe_array *a = (pdfe_array *) lua_newuserdatauv(L, sizeof(pdfe_array), 0); - luaL_getmetatable(L, PDFE_METATABLE_ARRAY); + // luaL_getmetatable(L, PDFE_METATABLE_ARRAY); + lua_get_metatablelua(pdfe_array_instance); lua_setmetatable(L, -2); a->array = array; } @@ -336,7 +338,8 @@ static int pdfelib_aux_pusharrayonly(lua_State *L, pparray *array) inline static void pdfe_push_stream(lua_State *L, ppstream *stream) { pdfe_stream *s = (pdfe_stream *) lua_newuserdatauv(L, sizeof(pdfe_stream), 0); - luaL_getmetatable(L, PDFE_METATABLE_STREAM); + // luaL_getmetatable(L, PDFE_METATABLE_STREAM); + lua_get_metatablelua(pdfe_stream_instance); lua_setmetatable(L, -2); s->stream = stream; s->open = 0; @@ -374,7 +377,8 @@ static int pdfelib_aux_pushstreamonly(lua_State *L, ppstream *stream) inline static void pdfe_push_reference(lua_State *L, ppref *reference) { pdfe_reference *r = (pdfe_reference *) lua_newuserdatauv(L, sizeof(pdfe_reference), 0); - luaL_getmetatable(L, PDFE_METATABLE_REFERENCE); + // luaL_getmetatable(L, PDFE_METATABLE_REFERENCE); + lua_get_metatablelua(pdfe_reference_instance); lua_setmetatable(L, -2); r->xref = reference->xref; r->onum = (int) reference->number; @@ -861,7 +865,8 @@ static void aux_pdfelib_open(lua_State *L, FILE *f) { pdfe_document *p = (pdfe_document *) lua_newuserdatauv(L, sizeof(pdfe_document), 0); ppdoc *d = ppdoc_filehandle(f, 1); - luaL_getmetatable(L, PDFE_METATABLE_INSTANCE); + // luaL_getmetatable(L, PDFE_METATABLE_INSTANCE); + lua_get_metatablelua(pdfe_instance); lua_setmetatable(L, -2); p->document = d; p->open = 1; @@ -936,7 +941,8 @@ static int pdfelib_new(lua_State *L) d = ppdoc_mem(memstream, streamsize); if (d) { pdfe_document *p = (pdfe_document *) lua_newuserdatauv(L, sizeof(pdfe_document), 0); - luaL_getmetatable(L, PDFE_METATABLE_INSTANCE); + // luaL_getmetatable(L, PDFE_METATABLE_INSTANCE); + lua_get_metatablelua(pdfe_instance); lua_setmetatable(L, -2); p->document = d; p->open = 1; @@ -1321,12 +1327,12 @@ static int pdfelib_get_value_direct(lua_State *L, void **value, pp_d_direct get_ case LUA_TSTRING: { const char *key = lua_tostring(L, 2); - lua_get_metatablelua(pdfe_dictionary); + lua_get_metatablelua(pdfe_dictionary_instance); if (lua_rawequal(L, -1, -2)) { *value = get_d(((pdfe_dictionary *) p)->dictionary, key); return 1; } else { - lua_get_metatablelua(pdfe_reference); + lua_get_metatablelua(pdfe_reference_instance); if (lua_rawequal(L, -1, -3)) { ppref *r = (((pdfe_reference *) p)->xref) ? ppxref_find(((pdfe_reference *) p)->xref, (ppuint) (((pdfe_reference *) p)->onum)) : NULL; \ ppobj *o = (r) ? ppref_obj(r) : NULL; @@ -1341,12 +1347,12 @@ static int pdfelib_get_value_direct(lua_State *L, void **value, pp_d_direct get_ case LUA_TNUMBER: { size_t index = lua_tointeger(L, 2); - lua_get_metatablelua(pdfe_array); + lua_get_metatablelua(pdfe_array_instance); if (lua_rawequal(L, -1, -2)) { *value = get_a(((pdfe_array *) p)->array, index); return 2; } else { - lua_get_metatablelua(pdfe_reference); + lua_get_metatablelua(pdfe_reference_instance); if (lua_rawequal(L, -1, -3)) { ppref *r = (((pdfe_reference *) p)->xref) ? ppxref_find(((pdfe_reference *) p)->xref, (ppuint) (((pdfe_reference *) p)->onum)) : NULL; \ ppobj *o = (r) ? ppref_obj(r) : NULL; @@ -1375,11 +1381,11 @@ static int pdfelib_get_value_indirect(lua_State *L, void **value, pp_d_indirect case LUA_TSTRING: { const char *key = lua_tostring(L, 2); - lua_get_metatablelua(pdfe_dictionary); + lua_get_metatablelua(pdfe_dictionary_instance); if (lua_rawequal(L, -1, -2)) { return get_d(((pdfe_dictionary *) p)->dictionary, key, value); } else { - lua_get_metatablelua(pdfe_reference); + lua_get_metatablelua(pdfe_reference_instance); if (lua_rawequal(L, -1, -3)) { ppref *r = (((pdfe_reference *) p)->xref) ? ppxref_find(((pdfe_reference *) p)->xref, (ppuint) (((pdfe_reference *) p)->onum)) : NULL; ppobj *o = (r) ? ppref_obj(r) : NULL; @@ -1392,11 +1398,11 @@ static int pdfelib_get_value_indirect(lua_State *L, void **value, pp_d_indirect case LUA_TNUMBER: { size_t index = lua_tointeger(L, 2); - lua_get_metatablelua(pdfe_array); + lua_get_metatablelua(pdfe_array_instance); if (lua_rawequal(L, -1, -2)) { return get_a(((pdfe_array *) p)->array, index, value); } else { - lua_get_metatablelua(pdfe_reference); + lua_get_metatablelua(pdfe_reference_instance); if (lua_rawequal(L, -1, -3)) { ppref *r = (((pdfe_reference *) p)->xref) ? ppxref_find(((pdfe_reference *) p)->xref, (ppuint) (((pdfe_reference *) p)->onum)) : NULL; ppobj *o = (r) ? ppref_obj(r) : NULL; diff --git a/source/luametatex/source/tex/texcommands.c b/source/luametatex/source/tex/texcommands.c index 0e9bb7ac9..9425141db 100644 --- a/source/luametatex/source/tex/texcommands.c +++ b/source/luametatex/source/tex/texcommands.c @@ -657,6 +657,7 @@ void tex_initialize_commands(void) tex_primitive(luatex_command, "directlua", convert_cmd, lua_code, 0); tex_primitive(luatex_command, "csstring", convert_cmd, cs_string_code, 0); tex_primitive(luatex_command, "csactive", convert_cmd, cs_active_code, 0); + /* tex_primitive(luatex_command, "csnamestring", convert_cmd, cs_lastname_code, 0); */ tex_primitive(luatex_command, "detokenized", convert_cmd, detokenized_code, 0); tex_primitive(luatex_command, "expanded", convert_cmd, expanded_code, 0); tex_primitive(luatex_command, "semiexpanded", convert_cmd, semi_expanded_code, 0); diff --git a/source/luametatex/source/tex/texcommands.h b/source/luametatex/source/tex/texcommands.h index a5c157a44..55de1dce6 100644 --- a/source/luametatex/source/tex/texcommands.h +++ b/source/luametatex/source/tex/texcommands.h @@ -443,6 +443,7 @@ typedef enum convert_codes { string_code, /*tex command code for |\string| */ cs_string_code, /*tex command code for |\csstring| */ cs_active_code, /*tex command code for |\csactive| */ + /* cs_lastname_code, */ /*tex command code for |\cslastname| */ detokenized_code, /*tex command code for |\detokenized| */ roman_numeral_code, /*tex command code for |\romannumeral| */ meaning_code, /*tex command code for |\meaning| */ diff --git a/source/luametatex/source/tex/texexpand.c b/source/luametatex/source/tex/texexpand.c index cec254d2b..8a2fa79a0 100644 --- a/source/luametatex/source/tex/texexpand.c +++ b/source/luametatex/source/tex/texexpand.c @@ -677,6 +677,20 @@ int tex_is_valid_csname(void) tex_get_x_or_protected(); /* we skip unprotected ! */ } while (cur_cmd != end_cs_name_cmd); goto FINISH; + /* no real gain: */ + // while (1) { + // tex_get_token(); + // if (cur_cmd == end_cs_name_cmd) { + // goto FINISH; + // } else if (cur_cmd <= max_command_cmd || is_protected_cmd(cur_cmd)) { + // /* go on */ + // } else { + // tex_expand_current_token(); + // if (cur_cmd != end_cs_name_cmd) { + // goto FINISH; + // } + // } + // } } else if (n) { /*tex Look up the characters of list |n| in the hash table, and set |cur_cs|. */ int f = lmt_fileio_state.io_first; diff --git a/source/luametatex/source/tex/texfont.c b/source/luametatex/source/tex/texfont.c index ac0ea1290..0f1cf6117 100644 --- a/source/luametatex/source/tex/texfont.c +++ b/source/luametatex/source/tex/texfont.c @@ -1958,7 +1958,9 @@ scaled tex_char_depth_from_glyph(halfword g) scaled tex_char_total_from_glyph(halfword g) { charinfo *ci = tex_aux_char_info(glyph_font(g), glyph_character(g)); - return tex_aux_glyph_y_scaled(g, ci->height + ci->depth); + scaled ht = ci->height; + scaled dp = ci->depth; + return tex_aux_glyph_y_scaled(g, (ht > 0 ? ht : 0) + (dp > 0 ? dp : 0)); /* so not progression */ } scaled tex_char_italic_from_glyph(halfword g) diff --git a/source/luametatex/source/tex/texnodes.c b/source/luametatex/source/tex/texnodes.c index ab2601a43..1c4a6b896 100644 --- a/source/luametatex/source/tex/texnodes.c +++ b/source/luametatex/source/tex/texnodes.c @@ -2669,9 +2669,9 @@ void tex_show_node_list(halfword p, int threshold, int max) if (valid_direction(box_dir(p))) { tex_print_str(", direction "); switch (box_dir(p)) { - case 0 : tex_print_str("l2r"); break; - case 1 : tex_print_str("r2l"); break; - default : tex_print_str("unset"); break; + case dir_lefttoright: tex_print_str("l2r"); break; + case dir_righttoleft: tex_print_str("r2l"); break; + default : tex_print_str("unset"); break; } } if (box_geometry(p)) { @@ -3372,14 +3372,38 @@ scaled tex_glyph_depth(halfword p) /* not used */ return d < 0 ? 0 : d; } +// scaledwhd tex_glyph_dimensions(halfword p) +// { +// scaledwhd whd = { 0, 0, 0, 0 }; +// scaled x = glyph_x_offset(p); +// scaled y = glyph_y_offset(p); +// whd.ht = tex_char_height_from_glyph(p) + glyph_raise(p); +// whd.dp = tex_char_depth_from_glyph(p) - glyph_raise(p); +// whd.wd = tex_char_width_from_glyph(p) - (glyph_left(p) + glyph_right(p)); +// if (x && tex_has_glyph_option(p, glyph_option_apply_x_offset)) { +// whd.wd += x; +// } +// if (y && tex_has_glyph_option(p, glyph_option_apply_y_offset)) { +// whd.ht += y; +// whd.dp -= y; +// } +// if (whd.ht < 0) { +// whd.ht = 0; +// } +// if (whd.dp < 0) { +// whd.dp = 0; +// } +// return whd; +// } + scaledwhd tex_glyph_dimensions(halfword p) { - scaledwhd whd = { 0, 0, 0, 0 }; + scaledwhd whd = tex_char_whd_from_glyph(p); scaled x = glyph_x_offset(p); scaled y = glyph_y_offset(p); - whd.ht = tex_char_height_from_glyph(p) + glyph_raise(p); - whd.dp = tex_char_depth_from_glyph(p) - glyph_raise(p); - whd.wd = tex_char_width_from_glyph(p) - (glyph_left(p) + glyph_right(p)); + whd.ht += glyph_raise(p); + whd.dp -= glyph_raise(p); + whd.wd += (glyph_left(p) + glyph_right(p)); if (x && tex_has_glyph_option(p, glyph_option_apply_x_offset)) { whd.wd += x; } @@ -3396,14 +3420,41 @@ scaledwhd tex_glyph_dimensions(halfword p) return whd; } +// scaledwhd tex_glyph_dimensions_ex(halfword p) +// { +// scaledwhd whd = { 0, 0, 0, 0 }; +// scaled x = glyph_x_offset(p); +// scaled y = glyph_y_offset(p); +// whd.ht = tex_char_height_from_glyph(p) + glyph_raise(p); +// whd.dp = tex_char_depth_from_glyph(p) - glyph_raise(p); +// whd.wd = tex_char_width_from_glyph(p) - (glyph_left(p) + glyph_right(p)); +// if (x && tex_has_glyph_option(p, glyph_option_apply_x_offset)) { +// whd.wd += x; +// } +// if (y && tex_has_glyph_option(p, glyph_option_apply_y_offset)) { +// whd.ht += y; +// whd.dp -= y; +// } +// if (whd.ht < 0) { +// whd.ht = 0; +// } +// if (whd.dp < 0) { +// whd.dp = 0; +// } +// if (whd.wd && glyph_expansion(p)) { +// whd.wd = tex_ext_xn_over_d(whd.wd, 1000000 + glyph_expansion(p), 1000000); +// } +// return whd; +// } + scaledwhd tex_glyph_dimensions_ex(halfword p) { - scaledwhd whd = { 0, 0, 0, 0 }; + scaledwhd whd = tex_char_whd_from_glyph(p); scaled x = glyph_x_offset(p); scaled y = glyph_y_offset(p); - whd.ht = tex_char_height_from_glyph(p) + glyph_raise(p); - whd.dp = tex_char_depth_from_glyph(p) - glyph_raise(p); - whd.wd = tex_char_width_from_glyph(p) - (glyph_left(p) + glyph_right(p)); + whd.ht += glyph_raise(p); + whd.dp -= glyph_raise(p); + whd.wd -= (glyph_left(p) + glyph_right(p)); if (x && tex_has_glyph_option(p, glyph_option_apply_x_offset)) { whd.wd += x; } @@ -3423,23 +3474,43 @@ scaledwhd tex_glyph_dimensions_ex(halfword p) return whd; } + scaled tex_glyph_total(halfword p) { - scaled ht = tex_char_height_from_glyph(p); - scaled dp = tex_char_depth_from_glyph(p); - if (ht < 0) { - ht = 0; - } - if (dp < 0) { - dp = 0; - } - return ht + dp; + // scaled ht = tex_char_height_from_glyph(p); + // scaled dp = tex_char_depth_from_glyph(p); + // if (ht < 0) { + // ht = 0; + // } + // if (dp < 0) { + // dp = 0; + // } + // return ht + dp; + return tex_char_total_from_glyph(p); } +// int tex_glyph_has_dimensions(halfword p) +// { +// scaled offset = glyph_x_offset(p); +// scaled amount = tex_char_width_from_glyph(p); +// if (offset && tex_has_glyph_option(p, glyph_option_apply_x_offset)) { +// amount += offset; +// } +// amount -= (glyph_left(p) + glyph_right(p)); +// if (amount) { +// return 1; +// } else { +// amount = tex_char_total_from_glyph(p); +// /* here offset and raise just moves */ +// return amount != 0; +// } +// } + int tex_glyph_has_dimensions(halfword p) { + scaledwhd whd = tex_char_whd_from_glyph(p); scaled offset = glyph_x_offset(p); - scaled amount = tex_char_width_from_glyph(p); + scaled amount = whd.wd; if (offset && tex_has_glyph_option(p, glyph_option_apply_x_offset)) { amount += offset; } @@ -3447,9 +3518,8 @@ int tex_glyph_has_dimensions(halfword p) if (amount) { return 1; } else { - amount = tex_char_total_from_glyph(p); - /* here offset adn raise just moves */ - return amount != 0; + /* here offset and raise just moves */ + return whd.ht > 0 || whd.dp > 0; } } diff --git a/source/luametatex/source/tex/texnodes.h b/source/luametatex/source/tex/texnodes.h index 50dbeaa97..8a462ebac 100644 --- a/source/luametatex/source/tex/texnodes.h +++ b/source/luametatex/source/tex/texnodes.h @@ -867,11 +867,11 @@ typedef enum list_geometries { # define box_glue_order(a) vlink(a,6) # define box_glue_sign(a) vinfo(a,6) # define box_glue_set(a) dvalue(a,7) /* So we reserve a whole memory word! */ -# define box_dir(a) vlink00(a,8) +# define box_dir(a) vlink00(a,8) /* We could encode it as geomtry but not now. */ # define box_package_state(a) vlink01(a,8) # define box_axis(a) vlink02(a,8) # define box_geometry(a) vlink03(a,8) -# define box_orientation(a) vinfo(a,8) /* also used for size in alignments */ +# define box_orientation(a) vinfo(a,8) /* Also used for size in alignments. */ # define box_x_offset(a) vlink(a,9) # define box_y_offset(a) vinfo(a,9) # define box_pre_migrated(a) vlink(a,10) @@ -885,7 +885,7 @@ typedef enum list_geometries { # define box_input_file(a) vlink(a,14) /* aka box_synctex_tag */ # define box_input_line(a) vinfo(a,14) /* aka box_synctex_line */ -# define box_total(a) (box_height(a) + box_depth(a)) +# define box_total(a) (box_height(a) + box_depth(a)) /* Here we add, with glyphs we maximize. */ inline static void tex_set_box_geometry (halfword b, halfword g) { box_geometry(b) |= (singleword) (g); } /* static void tex_unset_box_geometry (halfword b, halfword g) { box_geometry(b) &= (singleword) ~((singleword) (g) | box_geometry(b)); } */ diff --git a/source/luametatex/source/tex/texprinting.c b/source/luametatex/source/tex/texprinting.c index 860ff6731..d18445f36 100644 --- a/source/luametatex/source/tex/texprinting.c +++ b/source/luametatex/source/tex/texprinting.c @@ -465,15 +465,22 @@ void tex_print_str_esc(const char *s) void tex_print_int(int n) { /*tex In the end a 0..9 fast path works out best; using |sprintf| is slower. */ + if (n < 0) { + tex_print_char('-'); + n = -n; + } if (n >= 0 && n <= 9) { tex_print_char('0' + n); + } else if (n >= 0 && n <= 99) { + tex_print_char('0' + n/10); + tex_print_char('0' + n%10); } else { int k = 0; unsigned char digits[24]; - if (n < 0) { - tex_print_char('-'); - n = -n; - } +// if (n < 0) { +// tex_print_char('-'); +// n = -n; +// } do { digits[k] = '0' + (unsigned char) (n % 10); n = n / 10; diff --git a/source/luametatex/source/tex/texscanning.c b/source/luametatex/source/tex/texscanning.c index 3c9859de9..15e887a71 100644 --- a/source/luametatex/source/tex/texscanning.c +++ b/source/luametatex/source/tex/texscanning.c @@ -3378,25 +3378,6 @@ halfword tex_scan_general_text(halfword *tail) return head; } -/*tex - - The |get_x_or_protected| procedure is like |get_x_token| except that protected macros are not - expanded. It sets |cur_cmd|, |cur_chr|, |cur_tok|, and expands non-protected macros. - -*/ - -void tex_get_x_or_protected(void) -{ - while (1) { - tex_get_token(); - if (cur_cmd <= max_command_cmd || is_protected_cmd(cur_cmd)) { - return; - } else { - tex_expand_current_token(); - } - } -} - /*tex |scan_toks|. This function returns a pointer to the tail of a new token list, and it also makes @@ -3759,7 +3740,7 @@ halfword tex_scan_macro_normal(void) return result; } -# define optimize_grouping 0 +# define optimize_grouping 1 halfword tex_scan_macro_expand(void) { diff --git a/source/luametatex/source/tex/texscanning.h b/source/luametatex/source/tex/texscanning.h index 303143587..3415c27dd 100644 --- a/source/luametatex/source/tex/texscanning.h +++ b/source/luametatex/source/tex/texscanning.h @@ -136,8 +136,6 @@ extern halfword tex_get_font_dimen (void); extern void tex_set_scaled_font_dimen (void); extern halfword tex_get_scaled_font_dimen (void); -extern void tex_get_x_or_protected (void); - extern int tex_fract (int x, int n, int d, int max_answer); extern halfword tex_scan_lua_value (int index); diff --git a/source/luametatex/source/tex/textoken.c b/source/luametatex/source/tex/textoken.c index ba457491a..b46e6de85 100644 --- a/source/luametatex/source/tex/textoken.c +++ b/source/luametatex/source/tex/textoken.c @@ -2078,6 +2078,28 @@ halfword tex_get_token(void) return cur_tok; } +/*tex + + The |get_x_or_protected| procedure is like |get_x_token| except that protected macros are not + expanded. It sets |cur_cmd|, |cur_chr|, |cur_tok|, and expands non-protected macros. + +*/ + +void tex_get_x_or_protected(void) +{ + lmt_hash_state.no_new_cs = 0; + while (1) { + tex_get_next(); + if (cur_cmd <= max_command_cmd || is_protected_cmd(cur_cmd)) { + break; + } else { + tex_expand_current_token(); + } + } + cur_tok = cur_cs ? cs_token_flag + cur_cs : token_val(cur_cmd, cur_chr); /* needed afterwards ? */ + lmt_hash_state.no_new_cs = 1; +} + /*tex This changes the string |s| to a token list. */ halfword tex_string_to_toks(const char *ss) @@ -2765,6 +2787,16 @@ void tex_run_convert_tokens(halfword code) pop_selector; break; } + /* + case cs_lastname_code: + if (lmt_scanner_state.last_cs_name != null_cs) { + int saved_selector; + push_selector; + tex_print_cs_name(lmt_scanner_state.last_cs_name); + pop_selector; + } + break; + */ case detokenized_code: { int saved_selector; diff --git a/source/luametatex/source/tex/textoken.h b/source/luametatex/source/tex/textoken.h index 843304405..da2d01f7c 100644 --- a/source/luametatex/source/tex/textoken.h +++ b/source/luametatex/source/tex/textoken.h @@ -359,6 +359,7 @@ extern halfword tex_active_to_cs (int c, int force); extern halfword tex_string_to_toks (const char *s); extern int tex_get_char_cat_code (int c); extern halfword tex_get_token (void); +extern void tex_get_x_or_protected (void); extern halfword tex_str_toks (lstring s, halfword *tail); /* returns head */ extern halfword tex_cur_str_toks (halfword *tail); /* returns head */ extern halfword tex_str_scan_toks (int c, lstring b); /* returns head */ diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 163951adb..e793ca865 100644 --- a/tex/context/base/mkii/cont-new.mkii +++ b/tex/context/base/mkii/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2022.12.01 12:38} +\newcontextversion{2022.12.05 18:49} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii index d07c96f1a..870b3d0c9 100644 --- a/tex/context/base/mkii/context.mkii +++ b/tex/context/base/mkii/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2022.12.01 12:38} +\edef\contextversion{2022.12.05 18:49} %D For those who want to use this: diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 820a372bb..642c58bd3 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -13,7 +13,7 @@ % \normalend % uncomment this to get the real base runtime -\newcontextversion{2022.12.01 12:38} +\newcontextversion{2022.12.05 18:49} %D This file is loaded at runtime, thereby providing an excellent place for hacks, %D patches, extensions and new features. There can be local overloads in cont-loc diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index d7a655b4f..60320035e 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -49,7 +49,7 @@ %D {YYYY.MM.DD HH:MM} format. \edef\contextformat {\jobname} -\edef\contextversion{2022.12.01 12:38} +\edef\contextversion{2022.12.05 18:49} %D Kind of special: diff --git a/tex/context/base/mkiv/font-dsp.lua b/tex/context/base/mkiv/font-dsp.lua index 80e623929..6ed0c04d1 100644 --- a/tex/context/base/mkiv/font-dsp.lua +++ b/tex/context/base/mkiv/font-dsp.lua @@ -234,6 +234,24 @@ local read_integer = { streamreader.readinteger4, } +directives.register("fonts.streamreader",function() + + read_cardinal = { + streamreader.readcardinal1, + streamreader.readcardinal2, + streamreader.readcardinal3, + streamreader.readcardinal4, + } + + read_integer = { + streamreader.readinteger1, + streamreader.readinteger2, + streamreader.readinteger3, + streamreader.readinteger4, + } + +end) + -- Traditionally we use these unique names (so that we can flatten the lookup list -- (we create subsets runtime) but I will adapt the old code to newer names. diff --git a/tex/context/base/mkiv/font-mis.lua b/tex/context/base/mkiv/font-mis.lua index 4937dca31..e00c84e40 100644 --- a/tex/context/base/mkiv/font-mis.lua +++ b/tex/context/base/mkiv/font-mis.lua @@ -21,7 +21,7 @@ local readers = otf.readers if readers then - otf.version = otf.version or 3.130 + otf.version = otf.version or 3.131 otf.cache = otf.cache or containers.define("fonts", "otl", otf.version, true) function fonts.helpers.getfeatures(name,save) diff --git a/tex/context/base/mkiv/font-otl.lua b/tex/context/base/mkiv/font-otl.lua index fc101c9c9..7114f5ba2 100644 --- a/tex/context/base/mkiv/font-otl.lua +++ b/tex/context/base/mkiv/font-otl.lua @@ -52,7 +52,7 @@ local report_otf = logs.reporter("fonts","otf loading") local fonts = fonts local otf = fonts.handlers.otf -otf.version = 3.130 -- beware: also sync font-mis.lua and in mtx-fonts +otf.version = 3.131 -- beware: also sync font-mis.lua and in mtx-fonts otf.cache = containers.define("fonts", "otl", otf.version, true) otf.svgcache = containers.define("fonts", "svg", otf.version, true) otf.pngcache = containers.define("fonts", "png", otf.version, true) diff --git a/tex/context/base/mkiv/font-otr.lua b/tex/context/base/mkiv/font-otr.lua index 0b4bb65bb..1e6f94e45 100644 --- a/tex/context/base/mkiv/font-otr.lua +++ b/tex/context/base/mkiv/font-otr.lua @@ -1190,6 +1190,9 @@ readers.hmtx = function(f,fontdata,specification) -- if leftsidebearing ~= 0 then -- glyph.lsb = leftsidebearing -- end +-- if leftsidebearing ~= 0 then +-- glyph.lsb = leftsidebearing +-- end end -- The next can happen in for instance a monospace font or in a cjk font -- with fixed widths. diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua index b3055976a..6d7c5fb25 100644 --- a/tex/context/base/mkiv/font-ots.lua +++ b/tex/context/base/mkiv/font-ots.lua @@ -2448,7 +2448,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) if useddisc and start ~= usedstart then -- make this option per font -- new 2022-09-25 start = getnext(start) -- new 2022-09-25 end -- new 2022-09-25 - return head, start, done, useddisc -- new 2022-09-25 + return head, start, done, useddisc -- new 2022-09-25 end local chaintrac do @@ -2971,7 +2971,7 @@ handlers.gpos_context = handle_contextchain -- end -- new 2022-09-25 - + local function chained_contextchain(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash) local steps = currentlookup.steps local nofsteps = currentlookup.nofsteps diff --git a/tex/context/base/mkiv/font-prv.lua b/tex/context/base/mkiv/font-prv.lua index e613eb7d3..59b793444 100644 --- a/tex/context/base/mkiv/font-prv.lua +++ b/tex/context/base/mkiv/font-prv.lua @@ -83,6 +83,22 @@ function helpers.newprivateslot(name) return sharedprivates[name] end +function helpers.isprivate(unicode) + if unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then + return false + elseif unicode >= 0x00E000 and unicode <= 0x00F8FF then + return true + elseif unicode >= 0x0F0000 and unicode <= 0x0FFFFF then + return true + elseif unicode >= 0x100000 and unicode <= 0x10FFFF then + return true + elseif unicode >= 0x00D800 and unicode <= 0x00DFFF then + return true + else + return false + end +end + do local context = context diff --git a/tex/context/base/mkiv/font-ttf.lua b/tex/context/base/mkiv/font-ttf.lua index 0f3838c88..1fee9fa88 100644 --- a/tex/context/base/mkiv/font-ttf.lua +++ b/tex/context/base/mkiv/font-ttf.lua @@ -230,20 +230,7 @@ local function applyaxis(glyph,shape,deltas,dowidth) if dowidth then cnt = cnt - 4 end - if cnt == 1 then - local d = dpoints[1] - local x = xvalues[d] * factor - local y = yvalues[d] * factor - for i=1,nofpoints do - local p = points[i] - if x ~= 0 then - p[1] = p[1] + x - end - if y ~= 0 then - p[2] = p[2] + y - end - end - elseif cnt > 0 then + if cnt > 0 then -- Not the most efficient solution but we seldom do this. We -- actually need to avoid the extra points here but I'll deal -- with that when needed. @@ -265,14 +252,13 @@ local function applyaxis(glyph,shape,deltas,dowidth) lastindex = currentindex break elseif found > last then - --- \definefontfeature[book][default][axis={weight=800}] --- \definefont[testfont][file:Commissioner-vf-test.ttf*book] --- \testfont EΘÄΞ -while lastindex > 1 and dpoints[lastindex] > last do - lastindex = lastindex - 1 -end - + -- \definefontfeature[book][default][axis={weight=800}] + -- \definefont[testfont][file:Commissioner-vf-test.ttf*book] + -- \testfont EΘÄΞ + while lastindex > 1 and dpoints[lastindex] > last do + lastindex = lastindex - 1 + end + -- break end end @@ -351,6 +337,7 @@ end end else fx = (p2x - p1x)/(p3x - p1x) +-- fx = round(fx) fx = (1 - fx) * x1 + fx * x3 end -- @@ -374,6 +361,7 @@ end end else fy = (p2y - p1y)/(p3y - p1y) +-- fy = round(fy) fy = (1 - fy) * y1 + fy * y3 end -- -- maybe: @@ -777,6 +765,18 @@ local function contours2outlines_shaped(glyphs,shapes,keepcurve) end first = last + 1 end + -- See readers.hvar where we set the delta lsb as well as the adapted + -- width. At this point we do know the boundingbox's llx. The xmax is + -- not that relevant. It needs more testing! + -- + xmin = glyph.boundingbox[1] + -- + local dlsb = glyph.dlsb + if dlsb then + xmin = xmin + dlsb + glyph.dlsb = nil -- save space + end + -- glyph.boundingbox = { round(xmin), round(ymin), round(xmax), round(ymax) } end end diff --git a/tex/context/base/mkiv/math-ini.mkiv b/tex/context/base/mkiv/math-ini.mkiv index 94b50c12a..ca6cccf73 100644 --- a/tex/context/base/mkiv/math-ini.mkiv +++ b/tex/context/base/mkiv/math-ini.mkiv @@ -324,18 +324,30 @@ % e.g.: \definemathematics[i:mp][setups=i:tight,openup=yes] -\newmuskip\defaultthickmuskip \defaultthickmuskip 5mu plus 5mu -\newmuskip\defaultmedmuskip \defaultmedmuskip 4mu plus 2mu minus 4mu -\newmuskip\defaultthinmuskip \defaultthinmuskip 3mu - -\newmuskip\halfthickmuskip \halfthickmuskip 2.5mu plus 2.5mu -\newmuskip\halfmedmuskip \halfmedmuskip 2.0mu plus 1.0mu minus 2.0mu -\newmuskip\halfthinmuskip \halfthinmuskip 1.5mu - -\newcount \defaultrelpenalty \defaultrelpenalty 500 -\newcount \defaultbinoppenalty \defaultbinoppenalty 700 -\newcount \defaultprerelpenalty \defaultprerelpenalty -100 -\newcount \defaultprebinoppenalty \defaultprebinoppenalty -100 +\newmuskip\defaultthickmuskip \defaultthickmuskip 5mu plus 5mu +\newmuskip\defaultmedmuskip \defaultmedmuskip 4mu plus 2mu minus 4mu +\newmuskip\defaultthinmuskip \defaultthinmuskip 3mu + +\newmuskip\halfthickmuskip \halfthickmuskip 2.5mu plus 2.5mu +\newmuskip\halfmedmuskip \halfmedmuskip 2.0mu plus 1.0mu minus 2.0mu +\newmuskip\halfthinmuskip \halfthinmuskip 1.5mu + +\newcount \defaultrelpenalty \defaultrelpenalty 500 +\newcount \defaultbinoppenalty \defaultbinoppenalty 700 +\newcount \defaultprerelpenalty \defaultprerelpenalty -100 +\newcount \defaultprebinoppenalty \defaultprebinoppenalty -100 +\newcount \defaultdisplayprepenalty \defaultdisplayprepenalty -10 + +% For the moment this way: + +\appendtoks + \setmathprepenalty \mathbinarycode \defaultdisplayprepenalty + % \setmathpostpenalty\mathbinarycode \zerocount + \setmathprepenalty \mathrelationcode \defaultdisplayprepenalty + % \setmathpostpenalty\mathrelationcode \zerocount + \setmathpostpenalty\mathtextpunctuationcode\defaultdisplayprepenalty + % \setmathprepenalty \mathtextpunctuationcode\zerocount +\to \everybeforedisplayformula % we need to control these otherwise: % diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf index da390abd8..24196b4e9 100644 Binary files a/tex/context/base/mkiv/status-files.pdf and b/tex/context/base/mkiv/status-files.pdf differ diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf index ffd8cb5f2..6c406bfa1 100644 Binary files a/tex/context/base/mkiv/status-lua.pdf and b/tex/context/base/mkiv/status-lua.pdf differ diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl index 2ac4217cd..21de832b0 100644 --- a/tex/context/base/mkxl/cont-new.mkxl +++ b/tex/context/base/mkxl/cont-new.mkxl @@ -13,7 +13,7 @@ % \normalend % uncomment this to get the real base runtime -\newcontextversion{2022.12.01 12:38} +\newcontextversion{2022.12.05 18:49} %D This file is loaded at runtime, thereby providing an excellent place for hacks, %D patches, extensions and new features. There can be local overloads in cont-loc diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl index 1391f64e7..7942fb93a 100644 --- a/tex/context/base/mkxl/context.mkxl +++ b/tex/context/base/mkxl/context.mkxl @@ -29,7 +29,7 @@ %D {YYYY.MM.DD HH:MM} format. \immutable\edef\contextformat {\jobname} -\immutable\edef\contextversion{2022.12.01 12:38} +\immutable\edef\contextversion{2022.12.05 18:49} %overloadmode 1 % check frozen / warning %overloadmode 2 % check frozen / error @@ -135,7 +135,7 @@ \loadmkxlfile{mult-ini} \loadmkxlfile{mult-sys} \loadmkxlfile{mult-aux} -%doiffileelse{mult-aux-new.mkxl}{\loadmkxlfile{mult-aux-new}}{\loadmkxlfile{mult-aux}} +% \doiffileelse{mult-aux-new.mkxl}{\loadmkxlfile{mult-aux-new}}{\loadmkxlfile{mult-aux}} \loadmkxlfile{mult-def} %loadmarkfile{mult-chk} \loadmklxfile{mult-dim} diff --git a/tex/context/base/mkxl/driv-shp.lmt b/tex/context/base/mkxl/driv-shp.lmt index 7f74bd2e3..0b9418ab8 100644 --- a/tex/context/base/mkxl/driv-shp.lmt +++ b/tex/context/base/mkxl/driv-shp.lmt @@ -45,8 +45,10 @@ local getshift = nuts.getshift local getreplace = nuts.getreplace local setreplace = nuts.setreplace local getfont = nuts.getfont -local getkerndimension = nuts.getkerndimension + local getglyphdimensions = nuts.getglyphdimensions +local getkerndimension = nuts.getkerndimension +local getlistdimensions = nuts.getlistdimensions local setdirection = nuts.setdirection local setlink = nuts.setlink @@ -543,20 +545,19 @@ local flush_character do end local width, height, depth, naturalwidth, sx, sy if current then - -- height and depth not needed - if true then + -- if true then width, height, depth, factor, sx, sy = getglyphdimensions(current) - else - naturalwidth, height, depth, factor = getwhd(current,true) -- also get corrected width - sx, sy = getxyscales(current) - if factor == 0 then - width = naturalwidth - else - -- width = (1.0 + factor/1000000.0) * naturalwidth - width = naturalwidth + naturalwidth * factor/1000000.0 - -- width = naturalwidth + naturalwidth * 0.000001 * factor - end - end + -- else + -- naturalwidth, height, depth, factor = getwhd(current,true) -- also get corrected width + -- sx, sy = getxyscales(current) + -- if factor == 0 then + -- width = naturalwidth + -- else + -- -- width = (1.0 + factor/1000000.0) * naturalwidth + -- width = naturalwidth + naturalwidth * factor/1000000.0 + -- -- width = naturalwidth + naturalwidth * 0.000001 * factor + -- end + -- end else width = data.width or 0 height = data.height or 0 @@ -799,12 +800,8 @@ local hlist_out, vlist_out do -- we can encounter par, boundary and penalty nodes but a special -- iterator over content nodes won't save much for current, id, subtype in nextnode, current do --- if id == nil then --- print("bad node",current) --- end if id == glyph_code then local char, font = isglyph(current) --- if char then local x_offset, y_offset, left, right, raise = getoffsets(current) if x_offset ~= 0 or y_offset ~= 0 then if pos_r == righttoleft_code then @@ -821,9 +818,6 @@ local hlist_out, vlist_out do local wd = flush_character(current,font,char,false,true,pos_h,pos_v,pos_r) -- cur_h = cur_h + wd - right -- hm, no left here? cur_h = cur_h + wd -- see new tabulate alignment code --- else --- print("bad character",current,nuts.getfont(current),nuts.getchar(current)) --- end elseif id == glue_code then -- local gluewidth = effectiveglue(current,this_box) local gluewidth = effectiveglue(current,this_box,true) @@ -970,12 +964,16 @@ local hlist_out, vlist_out do end end elseif id == hlist_code or id == vlist_code then - local width, height, depth = getwhd(current) - local list = getlist(current) +-- local width, height, depth = getwhd(current) +-- local list = getlist(current) +-- if list then +-- local boxdir = getdirection(current) or lefttoright_code +-- local shift = getshift(current) + local width, height, depth, shift, list = getlistdimensions(current) if list then - local boxdir = getdirection(current) or lefttoright_code - local shift = getshift(current) - local geometry, hasoffset, hasorientation, hasanchor = getgeometry(current,true) +-- local boxdir = getdirection(current) or lefttoright_code +-- local geometry, hasoffset, hasorientation, hasanchor = getgeometry(current,true) + local geometry, hasoffset, hasorientation, hasanchor, boxdir = getgeometry(current,true) local anchor, source, target, targetdata, s_anchor, t_anchor local anc_h, anc_v local usedorientation = false @@ -1360,12 +1358,16 @@ local glueheight = effectiveglue(current,this_box,true) end end elseif id == hlist_code or id == vlist_code then - local width, height, depth = getwhd(current) - local list = getlist(current) +-- local width, height, depth = getwhd(current) +-- local list = getlist(current) +-- if list then +-- local boxdir = getdirection(current) or lefttoright_code +-- local shift = getshift(current) + local width, height, depth, shift, list = getlistdimensions(current) if list then - local boxdir = getdirection(current) or lefttoright_code - local shift = getshift(current) - local geometry, hasoffset, hasorientation, hasanchor = getgeometry(current,true) +-- local boxdir = getdirection(current) or lefttoright_code +-- local geometry, hasoffset, hasorientation, hasanchor = getgeometry(current,true) + local geometry, hasoffset, hasorientation, hasanchor, boxdir = getgeometry(current,true) local anchor, source, target, targetdata, s_anchor, t_anchor local usedorientation = false if hasanchor then diff --git a/tex/context/base/mkxl/font-col.lmt b/tex/context/base/mkxl/font-col.lmt index 1bce9b3a9..2a999ddeb 100644 --- a/tex/context/base/mkxl/font-col.lmt +++ b/tex/context/base/mkxl/font-col.lmt @@ -53,6 +53,7 @@ local charcommand = helpers.commands.char local rightcommand = helpers.commands.right local addprivate = helpers.addprivate local hasprivate = helpers.hasprivate +local isprivate = helpers.isprivate local fontpatternhassize = helpers.fontpatternhassize local hashes = fonts.hashes @@ -258,7 +259,9 @@ function collections.clonevector(name) if target then for unicode = start, stop do local unic = unicode + offset - start - if not newchars[target] then + if isprivate(unic) or isprivate(target) then + -- ignore + elseif not newchars[target] then -- not in font elseif force or (not vector[unic] and not oldchars[unic]) then vector[unic] = { cloneid, target } @@ -270,7 +273,9 @@ function collections.clonevector(name) else for unicode = start, stop do local unic = unicode + offset - start - if not newchars[unicode] then + if isprivate(unic) or isprivate(unicode) then + -- ignore + elseif not newchars[target] then -- not in font elseif force or (not vector[unic] and not oldchars[unic]) then vector[unic] = cloneid @@ -281,7 +286,9 @@ function collections.clonevector(name) if target then for unicode = start, stop do local unic = unicode + offset - start - if force or (not vector[unic] and not oldchars[unic]) then + if isprivate(unic) or isprivate(target) then + -- ignore + elseif force or (not vector[unic] and not oldchars[unic]) then vector[unic] = { cloneid, target } end target = target + 1 @@ -289,14 +296,18 @@ function collections.clonevector(name) elseif remap then for unicode = start, stop do local unic = unicode + offset - start - if force or (not vector[unic] and not oldchars[unic]) then + if isprivate(unic) or isprivate(unicode) then + -- ignore + elseif force or (not vector[unic] and not oldchars[unic]) then vector[unic] = { cloneid, remap[unicode] } end end else for unicode = start, stop do local unic = unicode + offset - start - if force or (not vector[unic] and not oldchars[unic]) then + if isprivate(unic) then + -- ignore + elseif force or (not vector[unic] and not oldchars[unic]) then vector[unic] = cloneid end end diff --git a/tex/context/base/mkxl/font-dsp.lmt b/tex/context/base/mkxl/font-dsp.lmt index 28a1d4e3c..a8dc2e5dc 100644 --- a/tex/context/base/mkxl/font-dsp.lmt +++ b/tex/context/base/mkxl/font-dsp.lmt @@ -237,6 +237,24 @@ local read_integer = { streamreader.readinteger4, } +directives.register("fonts.streamreader",function() + + read_cardinal = { + streamreader.readcardinal1, + streamreader.readcardinal2, + streamreader.readcardinal3, + streamreader.readcardinal4, + } + + read_integer = { + streamreader.readinteger1, + streamreader.readinteger2, + streamreader.readinteger3, + streamreader.readinteger4, + } + +end) + -- Traditionally we use these unique names (so that we can flatten the lookup list -- (we create subsets runtime) but I will adapt the old code to newer names. @@ -433,7 +451,7 @@ local function getfactors(data,instancespec) for i=1,#axis do local a = axis[i] local d = a.default - factors[i] = getaxisscale(segments,a.minimum,d,a.maximum,values[a.name or a.tag] or d) + factors[i] = getaxisscale(segments,a.minimum,d,a.maximum,values[a.name or a.tag] or values[a.tag] or d) end return factors end @@ -4498,6 +4516,66 @@ function readers.fvar(f,fontdata,specification) end end +local function calculate(f,fontdata,specification,offset,field,regions,deltas,nozero) + -- + -- innerIndexBitCountMask = 0x000F + -- mapEntrySizeMask = 0x0030 + -- reservedFlags = 0xFFC0 + -- + -- outerIndex = entry >> ((entryFormat & innerIndexBitCountMask) + 1) + -- innerIndex = entry & ((1 << ((entryFormat & innerIndexBitCountMask) + 1)) - 1) + -- + setposition(f,offset) + local format = readushort(f) -- todo: check + local mapcount = readushort(f) + local entrysize = rshift(band(format,0x0030),4) + 1 + local nofinnerbits = band(format,0x000F) + 1 -- n of inner bits + local innermask = lshift(1,nofinnerbits) - 1 + local readcardinal = read_cardinal[entrysize] -- 1 upto 4 bytes + local innerindex = { } -- size is mapcount + local outerindex = { } -- size is mapcount + for i=0,mapcount-1 do + local mapdata = readcardinal(f) + outerindex[i] = rshift(mapdata,nofinnerbits) + innerindex[i] = band(mapdata,innermask) + end + -- use last entry when no match i + setvariabledata(fontdata,"hvarwidths",true) + local glyphs = fontdata.glyphs + for i=0,fontdata.nofglyphs-1 do + local glyph = glyphs[i] + local outer = outerindex[i] or 0 + local inner = innerindex[i] or i + if outer and inner then -- not needed + local delta = deltas[outer+1] + if delta then + local d = delta.deltas[inner+1] + if d then + local scales = delta.scales + local deltaw = field and glyph[field] or 0 + for i=1,#scales do + local di = d[i] + if di then + deltaw = deltaw + scales[i] * di + else + break -- can't happen + end + end + deltaw = round(deltaw) + if nozero and deltaw == 0 then + -- no need for dlsb zero + else + glyph[field] = deltaw + end + end + end + end + end +end + +-- Todo: when it's tested for a while the lsb hackery can be backported from the +-- font-dsp.lmt file. + function readers.hvar(f,fontdata,specification) local factors = specification.factors if not factors then @@ -4508,93 +4586,31 @@ function readers.hvar(f,fontdata,specification) report("no hvar table, expect problems due to messy widths") return end - local version = readulong(f) -- 0x00010000 local variationoffset = tableoffset + readulong(f) -- the store local advanceoffset = tableoffset + readulong(f) local lsboffset = tableoffset + readulong(f) local rsboffset = tableoffset + readulong(f) - - local regions = { } - local variations = { } - local innerindex = { } -- size is mapcount - local outerindex = { } -- size is mapcount - local deltas = { } - - if variationoffset > 0 then - regions, deltas = readvariationdata(f,variationoffset,factors) - end - if not regions then - -- for now .. what to do ? - return - end - - if advanceoffset > 0 then - -- - -- innerIndexBitCountMask = 0x000F - -- mapEntrySizeMask = 0x0030 - -- reservedFlags = 0xFFC0 - -- - -- outerIndex = entry >> ((entryFormat & innerIndexBitCountMask) + 1) - -- innerIndex = entry & ((1 << ((entryFormat & innerIndexBitCountMask) + 1)) - 1) - -- - setposition(f,advanceoffset) - local format = readushort(f) -- todo: check - local mapcount = readushort(f) - local entrysize = rshift(band(format,0x0030),4) + 1 - local nofinnerbits = band(format,0x000F) + 1 -- n of inner bits - local innermask = lshift(1,nofinnerbits) - 1 - local readcardinal = read_cardinal[entrysize] -- 1 upto 4 bytes - for i=0,mapcount-1 do - local mapdata = readcardinal(f) - outerindex[i] = rshift(mapdata,nofinnerbits) - innerindex[i] = band(mapdata,innermask) - end - -- use last entry when no match i - setvariabledata(fontdata,"hvarwidths",true) - local glyphs = fontdata.glyphs - for i=0,fontdata.nofglyphs-1 do - local glyph = glyphs[i] - local width = glyph.width - if width then - local outer = outerindex[i] or 0 - local inner = innerindex[i] or i - if outer and inner then -- not needed - local delta = deltas[outer+1] - if delta then - local d = delta.deltas[inner+1] - if d then - local scales = delta.scales - local deltaw = 0 - for i=1,#scales do - local di = d[i] - if di then - deltaw = deltaw + scales[i] * di - else - break -- can't happen - end - end --- report("index: %i, outer: %i, inner: %i, deltas: %|t, scales: %|t, width: %i, delta %i", --- i,outer,inner,d,scales,width,round(deltaw)) - glyph.width = width + round(deltaw) - end - end - end + if variationoffset > tableoffset then + local regions, deltas = readvariationdata(f,variationoffset,factors) + if regions then + if advanceoffset > tableoffset then + calculate(f,fontdata,specification,advanceoffset,"width",regions,deltas,false) end + -- I don't want to save the lsb as it is the llx that we already store but as + -- we're ahead of reading the bounding box so we cannot set the right lsb here + -- so we set the delta (d) instead. + if lsboffset > tableoffset then + calculate(f,fontdata,specification,lsboffset,"dlsb",regions,deltas,true) -- delta lsb + end + -- if rsboffset > tableoffset then + -- -- we don't use right side bearings + -- end + -- setvariabledata(fontdata,"hregions",regions) end end - -- if lsboffset > 0 then - -- -- we don't use left side bearings - -- end - - -- if rsboffset > 0 then - -- -- we don't use right side bearings - -- end - - -- setvariabledata(fontdata,"hregions",regions) - end function readers.vvar(f,fontdata,specification) diff --git a/tex/context/base/mkxl/font-otl.lmt b/tex/context/base/mkxl/font-otl.lmt index 2d0d58a97..0d654edf6 100644 --- a/tex/context/base/mkxl/font-otl.lmt +++ b/tex/context/base/mkxl/font-otl.lmt @@ -52,7 +52,7 @@ local report_otf = logs.reporter("fonts","otf loading") local fonts = fonts local otf = fonts.handlers.otf -otf.version = 3.130 -- beware: also sync font-mis.lua and in mtx-fonts +otf.version = 3.131 -- beware: also sync font-mis.lua and in mtx-fonts otf.cache = containers.define("fonts", "otl", otf.version, true) otf.svgcache = containers.define("fonts", "svg", otf.version, true) otf.pngcache = containers.define("fonts", "png", otf.version, true) diff --git a/tex/context/base/mkxl/lpdf-emb.lmt b/tex/context/base/mkxl/lpdf-emb.lmt index 3ce288b48..271aadd8d 100644 --- a/tex/context/base/mkxl/lpdf-emb.lmt +++ b/tex/context/base/mkxl/lpdf-emb.lmt @@ -768,11 +768,11 @@ do local blob = blobs[include[index]] -- we assume padding if blob and #blob > 0 then g = g + 1 ; glyphstreams[g] = blob - h = h + 1 ; horizontals [h] = tocardinal2(data.width or 0) - h = h + 1 ; horizontals [h] = tocardinal2(data.boundingbox[1]) + h = h + 1 ; horizontals [h] = tocardinal2(round(data.width or 0)) + h = h + 1 ; horizontals [h] = tocardinal2(round(data.boundingbox[1])) if vertical then - v = v + 1 ; verticals[v] = tocardinal2(data.height or 0) - v = v + 1 ; verticals[v] = tocardinal2(data.boundingbox[3]) + v = v + 1 ; verticals[v] = tocardinal2(round(data.height or 0)) -- how about depth + v = v + 1 ; verticals[v] = tocardinal2(round(data.boundingbox[3])) end streamoffset = streamoffset + #blob lastoffset = tocardinal4(streamoffset) diff --git a/tex/context/base/mkxl/mult-aux.mkxl b/tex/context/base/mkxl/mult-aux.mkxl index 9cdfebac2..f387bf95d 100644 --- a/tex/context/base/mkxl/mult-aux.mkxl +++ b/tex/context/base/mkxl/mult-aux.mkxl @@ -215,16 +215,16 @@ \stopinterface -%D Used? - -\def\mult_check_for_assignment_indeed#-=#1#-^^^^0004% - {\if#1^^^^0003\assignmentfalse\else\assignmenttrue\fi} - -\def\mult_check_for_assignment_indeed_begin_#-=#1#-^^^^0004% - {\if#1^^^^0003} - -\def\mult_check_for_assignment#1% - {\expandafter\mult_check_for_assignment_indeed\detokenize{#1}=^^^^0003^^^^0003^^^^0004} +% % No longer used: +% +% \def\mult_check_for_assignment_indeed#-=#1#-^^^^0004% +% {\if#1^^^^0003\assignmentfalse\else\assignmenttrue\fi} +% +% \def\mult_check_for_assignment_indeed_begin_#-=#1#-^^^^0004% +% {\if#1^^^^0003} +% +% \def\mult_check_for_assignment#1% +% {\expandafter\mult_check_for_assignment_indeed\detokenize{#1}=^^^^0003^^^^0003^^^^0004} %D Beware, zero arguments is an assignment! @@ -266,7 +266,7 @@ % slower: \def#3##1{\csname\ifcsname#1#2:##1\endcsname\expandafter\csstring\lastnamedcs\else\expandafter#5\csname#1#2:\s!parent\endcsname{##1}\fi\endcsname}% %D pre-expansion can be a bit faster but handly any effect on a normal run so let's -%D go for saving some memory +%D go for saving some memory. \def\mult_interfaces_detokenize{\expandafter\expandafter\expandafter\detokenize\expandafter\expandafter\expandafter} diff --git a/tex/context/base/mkxl/node-fnt.lmt b/tex/context/base/mkxl/node-fnt.lmt index 61a20c628..c5f953741 100644 --- a/tex/context/base/mkxl/node-fnt.lmt +++ b/tex/context/base/mkxl/node-fnt.lmt @@ -21,7 +21,7 @@ local trace_variants = false trackers.register("nodes.variants", function( local force_discrun = true directives.register("nodes.discrun", function(v) force_discrun = v end) local force_boundaryrun = true directives.register("nodes.boundaryrun", function(v) force_boundaryrun = v end) -local force_basepass = true directives.register("nodes.basepass", function(v) force_basepass = v end) +----- force_basepass = true directives.register("nodes.basepass", function(v) force_basepass = v end) local keep_redundant = false directives.register("nodes.keepredundant",function(v) keep_redundant = v end) local report_fonts = logs.reporter("fonts","processing") @@ -65,6 +65,7 @@ local nextdisc = nuts.traversers.disc local nextchar = nuts.traversers.char local flushnode = nuts.flush +local removefromlist = nuts.removefromlist local disc_code = nodecodes.disc local boundary_code = nodecodes.boundary @@ -137,37 +138,37 @@ fonts.hashes.processes = fontprocesses local ligaturing = nuts.ligaturing local kerning = nuts.kerning -local function start_trace(head) - run = run + 1 - report_fonts() - report_fonts("checking node list, run %s",run) - report_fonts() - local n = head - while n do - local char, id = isglyph(n) - if char then - local font = id - local dynamic = getglyphdata(n) or 0 - report_fonts("font %03i, dynamic %03i, glyph %C",font,dynamic,char) - elseif id == disc_code then - report_fonts("[disc] %s",nodes.listtoutf(n,true,false,n)) - elseif id == boundary_code then - report_fonts("[boundary] %i:%i",getsubtype(n),getdata(n)) - else - report_fonts("[%s]",nodecodes[id]) - end - n = getnext(n) - end -end +-- local function start_trace(head) +-- run = run + 1 +-- report_fonts() +-- report_fonts("checking node list, run %s",run) +-- report_fonts() +-- local n = head +-- while n do +-- local char, id = isglyph(n) +-- if char then +-- local font = id +-- local dynamic = getglyphdata(n) or 0 +-- report_fonts("font %03i, dynamic %03i, glyph %C",font,dynamic,char) +-- elseif id == disc_code then +-- report_fonts("[disc] %s",nodes.listtoutf(n,true,false,n)) +-- elseif id == boundary_code then +-- report_fonts("[boundary] %i:%i",getsubtype(n),getdata(n)) +-- else +-- report_fonts("[%s]",nodecodes[id]) +-- end +-- n = getnext(n) +-- end +-- end -local function stop_trace(u,usedfonts,d,dynamicfonts,b,basefonts,r,redundant) - report_fonts() - report_fonts("statics : %s",u > 0 and concat(keys(usedfonts)," ") or "none") - report_fonts("dynamics: %s",d > 0 and concat(keys(dynamicfonts)," ") or "none") - report_fonts("built-in: %s",b > 0 and b or "none") - report_fonts("removed : %s",r > 0 and r or "none") - report_fonts() -end +-- local function stop_trace(u,usedfonts,d,dynamicfonts,b,basefonts,r,redundant) +-- report_fonts() +-- report_fonts("statics : %s",u > 0 and concat(keys(usedfonts)," ") or "none") +-- report_fonts("dynamics: %s",d > 0 and concat(keys(dynamicfonts)," ") or "none") +-- report_fonts("built-in: %s",b > 0 and b or "none") +-- report_fonts("removed : %s",r > 0 and r or "none") +-- report_fonts() +-- end -- This is the original handler and we keep it around as reference. It served us -- well for quite a while. @@ -575,42 +576,70 @@ do local redundant -- could be reused local lastfont local lastproc - local basedone - local nonedone + -- local basedone + -- local nonedone - local d, u, b, r + -- local d, u, b, r + local d, u, r - local function setnone(n) - nonedone = true - end + -- local function setnone() + -- nonedone = true + -- end - local function setbase(n) - if force_basepass then - basedone = true - end - end + -- local function setbase() + -- if force_basepass then + -- basedone = true + -- end + -- end - local function setnode(n,font,dynamic) -- we could use prevfont and prevdynamic when we set then first - if dynamic > 0 then - local used = dynamicfonts[font] +-- local function setnode(font,dynamic) -- we could use prevfont and prevdynamic when we set them first +-- if dynamic > 0 then +-- local used = dynamicfonts[font] +-- if not used then +-- used = { } +-- dynamicfonts[font] = used +-- end +-- if not used[dynamic] then +-- local fd = setfontdynamics[font] +-- if fd then +-- used[dynamic] = fd[dynamic] +-- d = d + 1 +-- end +-- end +-- else +-- local used = usedfonts[font] +-- if not used then +-- lastfont = font +-- lastproc = fontprocesses[font] +-- if lastproc then +-- usedfonts[font] = lastproc +-- u = u + 1 +-- end +-- end +-- end +-- end + + local function setnode() -- we could use prevfont and prevdynamic when we set them first + if prevdynamic > 0 then + local used = dynamicfonts[prevfont] if not used then used = { } - dynamicfonts[font] = used + dynamicfonts[prevfont] = used end - if not used[dynamic] then - local fd = setfontdynamics[font] + if not used[prevdynamic] then + local fd = setfontdynamics[prevfont] if fd then - used[dynamic] = fd[dynamic] + used[prevdynamic] = fd[prevdynamic] d = d + 1 end end else - local used = usedfonts[font] + local used = usedfonts[prevfont] if not used then - lastfont = font - lastproc = fontprocesses[font] + lastfont = prevfont + lastproc = fontprocesses[prevfont] if lastproc then - usedfonts[font] = lastproc + usedfonts[prevfont] = lastproc u = u + 1 end end @@ -623,22 +652,26 @@ do usedfonts = { } dynamicfonts = { } - prevfont = nil - prevdynamic = 0 - variants = nil - redundant = nil + prevfont = nil -- local + prevdynamic = 0 -- local + variants = nil -- local + redundant = nil -- local lastfont = nil lastproc = nil - nonedone = nil - basedone = nil + -- nonedone = nil + -- basedone = nil + + local nonedone = nil + local basedone = nil local fontmode = nil -- base none or other - d, u, b, r = 0, 0, 0, 0 + -- d, u, b, r = 0, 0, 0, 0 + d, u, r = 0, 0, 0 --- if trace_fontrun then --- start_trace(head) --- end + -- if trace_fontrun then + -- start_trace(head) + -- end -- There is no gain in checking for a single glyph and then having a fast path. On the -- metafun manual (with some 2500 single char lists) the difference is just noise. @@ -651,32 +684,38 @@ do if fontmode == "none" then prevdynamic = 0 variants = false - setnone(n) + -- setnone() + nonedone = true elseif fontmode == "base" then prevdynamic = 0 variants = false - setbase(n) + -- setbase() + basedone = true else - -- local dynamic = getglyphdata(n) or 0 -- zero dynamic is reserved for fonts in context prevdynamic = dynamic variants = fontvariants[font] - setnode(n,font,dynamic) + -- setnode(font,dynamic) + setnode() end elseif fontmode == "node" then - local dynamic = getglyphdata(n) or 0 -- zero dynamic is reserved for fonts in context if dynamic ~= prevdynamic then prevdynamic = dynamic variants = fontvariants[font] - setnode(n,font,dynamic) + -- setnode(font,dynamic) + setnode() end end + -- we could just mark them and then have a separate pass .. happens seldom + if variants then + -- We need a proper test for this! if (char >= 0xFE00 and char <= 0xFE0F) or (char >= 0xE0100 and char <= 0xE01EF) then - -- if variants and char >= 0xFE00 then - -- if char < 0xFE0F or (char >= 0xE0100 and char <= 0xE01EF) then local hash = variants[char] if hash then + -- local p, _, char = isprevchar(n) + -- if char then + -- local variant = hash[char] local p = getprev(n) if p then local char = ischar(p) -- checked @@ -710,22 +749,23 @@ do end if force_boundaryrun then - -- we can inject wordboundaries and then let the hyphenator do its work -- but we need to get rid of those nodes in order to build ligatures -- and kern (a rather context thing) - for b, subtype in nextboundary, head do - if subtype == wordboundary_code then - if redundant then - r = r + 1 - redundant[r] = b - else - r = 1 - redundant = { b } - end - end - end + -- for b, subtype in nextboundary, head do + -- if subtype == wordboundary_code then + -- if redundant then + -- r = r + 1 + -- redundant[r] = b + -- else + -- r = 1 + -- redundant = { b } + -- end + -- end + -- end + + head = removefromlist(head,boundary_code,wordboundary_code) end @@ -751,21 +791,22 @@ do -- for hyphens and these come from fonts that part of the hyphenated word local r = getreplace(disc) if r then - local prevfont = nil - local prevdynamic = nil - local none = false + prevfont = nil + prevdynamic = nil + -- fontmode = nil for n, char, font, dynamic in nextchar, r do - -- local dynamic = getglyphdata(n) or 0 -- zero dynamic is reserved for fonts in context if font ~= prevfont or dynamic ~= prevdynamic then prevfont = font prevdynamic = dynamic - local fontmode = fontmodes[font] + fontmode = fontmodes[font] if fontmode == "none" then - setnone(n) + -- setnone() + nonedone = true elseif fontmode == "base" then - setbase(n) + -- setbase() + basedone = true else - setnode(n,font,dynamic) + setnode() -- (font,dynamic) end end -- we assume one font for now (and if there are more and we get into issues then @@ -777,9 +818,9 @@ do end --- if trace_fontrun then --- stop_trace(u,usedfonts,d,dynamicfonts,b,basefonts,r,redundant) --- end + -- if trace_fontrun then + -- stop_trace(u,usedfonts,d,dynamicfonts,b,basefonts,r,redundant) + -- end if nonedone then protectglyphsnone(head) diff --git a/tex/context/base/mkxl/node-nut.lmt b/tex/context/base/mkxl/node-nut.lmt index 38c182f8a..89c1fbac6 100644 --- a/tex/context/base/mkxl/node-nut.lmt +++ b/tex/context/base/mkxl/node-nut.lmt @@ -120,6 +120,7 @@ local nuts = { getleader = direct.getleader, getleftdelimiter = direct.getleftdelimiter, getlist = d_getlist, + getlistdimensions = direct.getlistdimensions, getmiddledelimiter = direct.getdelimiter, getnext = d_getnext, getnormalizedline = direct.getnormalizedline, @@ -203,6 +204,7 @@ local nuts = { protrusionskippable = direct.protrusionskippable, rangedimensions = direct.rangedimensions, remove = d_remove_node, + removefromlist = direct.removefromlist, repack = direct.repack, reverse = direct.reverse, serialized = direct.serialized, diff --git a/tex/context/base/mkxl/pack-rul.lmt b/tex/context/base/mkxl/pack-rul.lmt index c2183c1ad..12d131c88 100644 --- a/tex/context/base/mkxl/pack-rul.lmt +++ b/tex/context/base/mkxl/pack-rul.lmt @@ -195,15 +195,7 @@ local function doanalyzeframedbox(n) if getwidth(box) ~= 0 then local list = getlist(box) if list then - for n in nexthlist, list do - local width, height, depth = getwhd(n) - if not firstheight then - firstheight = height - end - lastdepth = depth - noflines = noflines + 1 - end - for n in nextvlist, list do + for n in nextlist, list do local width, height, depth = getwhd(n) if not firstheight then firstheight = height @@ -211,6 +203,22 @@ local function doanalyzeframedbox(n) lastdepth = depth noflines = noflines + 1 end + -- for n in nexthlist, list do + -- local width, height, depth = getwhd(n) + -- if not firstheight then + -- firstheight = height + -- end + -- lastdepth = depth + -- noflines = noflines + 1 + -- end + -- for n in nextvlist, list do + -- local width, height, depth = getwhd(n) + -- if not firstheight then + -- firstheight = height + -- end + -- lastdepth = depth + -- noflines = noflines + 1 + -- end end end texsetcount("global",c_framednoflines,noflines) diff --git a/tex/context/base/mkxl/pack-rul.mkxl b/tex/context/base/mkxl/pack-rul.mkxl index b06e8f57c..3f43b2abc 100644 --- a/tex/context/base/mkxl/pack-rul.mkxl +++ b/tex/context/base/mkxl/pack-rul.mkxl @@ -1288,9 +1288,9 @@ \enforced\lettonothing\delayedendstrut \enforced\lettonothing\delayedstrut \else - \enforced\let \delayedbegstrut\localbegstrut - \enforced\let \delayedendstrut\localendstrut - \enforced\let \delayedstrut \localstrut + \enforced\let \delayedbegstrut\localbegstrut + \enforced\let \delayedendstrut\localendstrut + \enforced\let \delayedstrut \localstrut \enforced\lettonothing\localbegstrut \enforced\lettonothing\localendstrut \enforced\lettonothing\localstrut diff --git a/tex/context/base/mkxl/page-lay.mkxl b/tex/context/base/mkxl/page-lay.mkxl index 9dbe9aef0..628e112b6 100644 --- a/tex/context/base/mkxl/page-lay.mkxl +++ b/tex/context/base/mkxl/page-lay.mkxl @@ -121,6 +121,15 @@ \installswitchcommandhandler \??layout {layout} \??layout +\pushoverloadmode + + \let\page_layouts_define\definelayout % ugly hack for MS + + \permanent\protected\def\definelayout[#1]% intercept relative pages + {\normalexpanded{\page_layouts_define[\ifhastoks{+}{#1}\the\numexpr\realpageno#1\relax\else#1\fi]}} + +\popoverloadmode + \appendtoks \doifnothing{\directlayoutparameter\c!state}{\letlayoutparameter\c!state\v!start}% \to \everydefinelayout diff --git a/tex/context/base/mkxl/page-sel.lmt b/tex/context/base/mkxl/page-sel.lmt new file mode 100644 index 000000000..a6ea84f47 --- /dev/null +++ b/tex/context/base/mkxl/page-sel.lmt @@ -0,0 +1,77 @@ +if not modules then modules = { } end modules ['page-sel'] = { + version = 1.001, + comment = "companion to page-sel.mkxl", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--- maybe more will end up here + +local addsuffix = file.addsuffix +local context = context + +do + + local sections = { } + + local function sectionpage(filename,reference,what) + local filedata = sections[filename] + if not filedata then + filedata = { + data = job.loadother(addsuffix(filename,"tuc")) or false, + list = { } + } + sections[filename] = filedata + end + local list = filedata.list + local entry = list[reference] + if not entry then + local first = 0 + local last = 0 + local data = filedata.data + if data then + local lists = data.structures.lists.collected + local pages = data.structures.pages.collected + if lists and pages then + for i=1,#lists do + local li = lists[i] + if li.references.reference == reference then + local level = li.metadata.level + first = li.references.realpage + last = pages[#pages].number + for j=i+1,#lists do + local lj = lists[j] + if lj.metadata.level == level then + last = lj.references.realpage - 1 + break + end + end + end + end + end + end + entry = { + first = first, + last = last, + } + list[reference] = entry + end + context(what and entry.first or entry.last) + end + + interfaces.implement { + name = "firstsectionpage", + public = true, + arguments = { "optional", "optional", true }, + actions = sectionpage + } + + interfaces.implement { + name = "lastsectionpage", + public = true, + arguments = { "optional", "optional", false }, + actions = sectionpage + } + +end diff --git a/tex/context/base/mkxl/page-sel.mklx b/tex/context/base/mkxl/page-sel.mklx index 0cdef5ba4..f6b3840a9 100644 --- a/tex/context/base/mkxl/page-sel.mklx +++ b/tex/context/base/mkxl/page-sel.mklx @@ -19,6 +19,8 @@ \unprotect +\registerctxluafile{page-sel}{autosuffix} + \startcontextdefinitioncode %D One can (mis)use this mechanism to (re)arrange pages of already produced files. @@ -425,4 +427,38 @@ \stopcontextdefinitioncode +%D Implemented in Lua: + +% crap.tex: +% +% \starttext +% \dorecurse{10}{ +% \startchapter[title=Chapter #1,reference=chapter:#1] +% \dorecurse{10}{ +% \startsubject[title=Subject #1] +% \dorecurse{2}{\samplefile{tufte}\par} +% \stopsubject +% \startsection[title=Section #1.##1,reference=#1.##1] +% \dorecurse{10}{\samplefile{tufte}\par} +% \stopsection +% } +% \stopchapter +% } +% \stoptext +% +% load.tex: +% +% \starttext +% \dostepwiserecurse {\firstsectionpage[crap][chapter:3]} {\lastsectionpage[crap][chapter:3]} {1} { +% \startpagemakeup +% \externalfigure[crap.pdf][page=#1] +% \stoppagemakeup +% } +% \dostepwiserecurse {\firstsectionpage[crap][chapter:5]} {\lastsectionpage[crap][chapter:5]} {1} { +% \dontleavehmode +% \externalfigure[crap.pdf][page=#1,width=3cm,frame=on]% +% \space\allowbreak +% } +% \stoptext + \protect \endinput diff --git a/tex/context/base/mkxl/spac-ver.mkxl b/tex/context/base/mkxl/spac-ver.mkxl index 7ab80d6a9..755460ac2 100644 --- a/tex/context/base/mkxl/spac-ver.mkxl +++ b/tex/context/base/mkxl/spac-ver.mkxl @@ -1110,19 +1110,20 @@ %\boundary\plusone \penalty\plustenthousand %\boundary\plusone - \hskip\zeropoint - \ignorespaces} + \hskip\zeropoint} \permanent\protected\def\endstrut {% \ifmmode M\fi % \ifinner I\fi \relax\ifhmode - \removeunwantedspaces + %\removeunwantedspaces + \spac_helpers_remove_unwantedspace \ifcase\struthtdp\else \spac_struts_end \fi \orelse\ifmmode - \removeunwantedspaces + %\removeunwantedspaces hmode only anyway + \spac_helpers_remove_unwantedspace \strut \fi} diff --git a/tex/context/base/mkxl/trac-vis.lmt b/tex/context/base/mkxl/trac-vis.lmt index 2b209e748..91d3bfc3f 100644 --- a/tex/context/base/mkxl/trac-vis.lmt +++ b/tex/context/base/mkxl/trac-vis.lmt @@ -810,6 +810,7 @@ local ruledbox do ruledbox = function(head,current,vertical,layer,what,simple,previous,trace_origin,parent) local wd, ht, dp = getwhd(current) +-- todo local wd, ht, dh, shift = getlistdimensions(current) local force_origin = wd == 0 or (dp + ht) == 0 local shift = getshift(current) local orientation, xoffset, yoffset = getorientation(current) diff --git a/tex/context/base/mkxl/util-sac.lmt b/tex/context/base/mkxl/util-sac.lmt index e0a9f77de..f64602d54 100644 --- a/tex/context/base/mkxl/util-sac.lmt +++ b/tex/context/base/mkxl/util-sac.lmt @@ -218,8 +218,10 @@ end streams.readbyte = streams.readcardinal1 streams.readsignedbyte = streams.readinteger1 +streams.readcardinal1 = streams.readcardinal1 streams.readcardinal = streams.readcardinal1 streams.readinteger = streams.readinteger1 +streams.readinteger1 = streams.readinteger1 local readcardinaltable = sio.readcardinaltable local readintegertable = sio.readintegertable diff --git a/tex/context/fonts/mkiv/bonum-math.lfg b/tex/context/fonts/mkiv/bonum-math.lfg index 736b8a176..a7f4ec306 100644 --- a/tex/context/fonts/mkiv/bonum-math.lfg +++ b/tex/context/fonts/mkiv/bonum-math.lfg @@ -126,7 +126,7 @@ return { [0x0029] = { topright = -0.15, bottomright = -0.15 }, -- right parenthesis variants ["0x29.variants.*"] = { topright = -0.15, bottomright = -0.15 }, -- right parenthesis variants ["0x29.parts.top"] = { topright = -0.15, }, -- right parenthesis top - ["0x29.parts.bottom"] = { bottomright = -0.15 }, -- right parenthesis bottom + ["0x29.parts.bottom"] = { bottomright = -0.15 }, -- right parenthesis bottom [0x221A] = { topright = 0.2, bottomright = 0.2 }, -- radical ["0x221A.variants.*"] = { topright = 0.2, bottomright = 0.2 }, ["0x221A.parts.top"] = { topright = 0.2, }, diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index eee1dc4e2..53cd64c67 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 2022-12-01 12:38 +-- merge date : 2022-12-05 18:49 do -- begin closure to overcome local limits and interference @@ -15611,20 +15611,7 @@ local function applyaxis(glyph,shape,deltas,dowidth) if dowidth then cnt=cnt-4 end - if cnt==1 then - local d=dpoints[1] - local x=xvalues[d]*factor - local y=yvalues[d]*factor - for i=1,nofpoints do - local p=points[i] - if x~=0 then - p[1]=p[1]+x - end - if y~=0 then - p[2]=p[2]+y - end - end - elseif cnt>0 then + if cnt>0 then local contours=shape.contours local nofcontours=#contours local first=1 @@ -15643,9 +15630,9 @@ local function applyaxis(glyph,shape,deltas,dowidth) lastindex=currentindex break elseif found>last then -while lastindex>1 and dpoints[lastindex]>last do - lastindex=lastindex-1 -end + while lastindex>1 and dpoints[lastindex]>last do + lastindex=lastindex-1 + end break end end @@ -16101,6 +16088,12 @@ local function contours2outlines_shaped(glyphs,shapes,keepcurve) end first=last+1 end + xmin=glyph.boundingbox[1] + local dlsb=glyph.dlsb + if dlsb then + xmin=xmin+dlsb + glyph.dlsb=nil + end glyph.boundingbox={ round(xmin),round(ymin),round(xmax),round(ymax) } end end @@ -16875,6 +16868,20 @@ local read_integer={ streamreader.readinteger3, streamreader.readinteger4, } +directives.register("fonts.streamreader",function() + read_cardinal={ + streamreader.readcardinal1, + streamreader.readcardinal2, + streamreader.readcardinal3, + streamreader.readcardinal4, + } + read_integer={ + streamreader.readinteger1, + streamreader.readinteger2, + streamreader.readinteger3, + streamreader.readinteger4, + } +end) local lookupnames={ gsub={ single="gsub_single", @@ -21327,7 +21334,7 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_d local report_otf=logs.reporter("fonts","otf loading") local fonts=fonts local otf=fonts.handlers.otf -otf.version=3.130 +otf.version=3.131 otf.cache=containers.define("fonts","otl",otf.version,true) otf.svgcache=containers.define("fonts","svg",otf.version,true) otf.pngcache=containers.define("fonts","png",otf.version,true) -- cgit v1.2.3