From cb71b62afd23fc35a04304858ee2d221b8a51dcb Mon Sep 17 00:00:00 2001 From: Luigi Scarso Date: Fri, 31 Dec 2021 10:38:50 +0000 Subject: sync luatex with upstream r7476. git-svn-id: svn://tug.org/texlive/trunk@61453 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/web2c/luatexdir/ChangeLog | 78 +++++++- Build/source/texk/web2c/luatexdir/NEWS | 34 ++++ .../source/texk/web2c/luatexdir/am/luaharfbuzz.am | 3 +- Build/source/texk/web2c/luatexdir/font/texfont.c | 13 +- Build/source/texk/web2c/luatexdir/font/tt_glyf.c | 35 +++- Build/source/texk/web2c/luatexdir/image/writepng.c | 12 +- Build/source/texk/web2c/luatexdir/lua/lnodelib.c | 40 +++- Build/source/texk/web2c/luatexdir/lua/loslibext.c | 12 ++ Build/source/texk/web2c/luatexdir/lua/luatex-api.h | 6 + Build/source/texk/web2c/luatexdir/lua/luatoken.c | 2 + .../luaharfbuzz/luaharfbuzz-1.1.0-1.rockspec | 1 + .../luaharfbuzz/luaharfbuzz-scm-1.rockspec | 1 + .../luatexdir/luaharfbuzz/spec/harfbuzz_spec.lua | 116 +++++++++++- .../luatexdir/luaharfbuzz/src/luaharfbuzz/face.c | 195 +++++++++++++++++++ .../luatexdir/luaharfbuzz/src/luaharfbuzz/font.c | 61 ++++++ .../luaharfbuzz/src/luaharfbuzz/luaharfbuzz.c | 3 + .../luaharfbuzz/src/luaharfbuzz/luaharfbuzz.h | 2 + .../luaharfbuzz/src/luaharfbuzz/variation.c | 82 ++++++++ .../texk/web2c/luatexdir/luasocket/src/inet.c | 2 - .../texk/web2c/luatexdir/luasocket/src/inet.h | 2 - Build/source/texk/web2c/luatexdir/luatex.c | 4 +- .../texk/web2c/luatexdir/luatex_svnversion.h | 2 +- Build/source/texk/web2c/luatexdir/pdf/pdfaction.c | 44 ++++- Build/source/texk/web2c/luatexdir/pdf/pdfdest.c | 37 +++- Build/source/texk/web2c/luatexdir/pdf/pdfdest.h | 1 + Build/source/texk/web2c/luatexdir/pdf/pdfgen.c | 33 ++++ Build/source/texk/web2c/luatexdir/pdf/pdftables.c | 2 +- Build/source/texk/web2c/luatexdir/pdf/pdftypes.h | 37 ++-- Build/source/texk/web2c/luatexdir/tex/commands.c | 11 +- Build/source/texk/web2c/luatexdir/tex/commands.h | 1 + Build/source/texk/web2c/luatexdir/tex/dumpdata.c | 2 +- .../source/texk/web2c/luatexdir/tex/equivalents.c | 2 +- .../source/texk/web2c/luatexdir/tex/equivalents.h | 5 +- Build/source/texk/web2c/luatexdir/tex/extensions.c | 9 +- Build/source/texk/web2c/luatexdir/tex/mainbody.c | 1 - .../source/texk/web2c/luatexdir/tex/maincontrol.c | 207 ++++++++++++++------- Build/source/texk/web2c/luatexdir/tex/primitive.c | 2 +- Build/source/texk/web2c/luatexdir/tex/printing.c | 1 + Build/source/texk/web2c/luatexdir/tex/scanning.c | 22 ++- Build/source/texk/web2c/luatexdir/tex/texfileio.c | 5 +- Build/source/texk/web2c/luatexdir/tex/texnodes.c | 23 ++- Build/source/texk/web2c/luatexdir/tex/texnodes.h | 3 +- Build/source/texk/web2c/luatexdir/tex/textoken.c | 2 + 43 files changed, 983 insertions(+), 173 deletions(-) create mode 100644 Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/variation.c (limited to 'Build') diff --git a/Build/source/texk/web2c/luatexdir/ChangeLog b/Build/source/texk/web2c/luatexdir/ChangeLog index f6bb2158983..d7b5f3bfaac 100644 --- a/Build/source/texk/web2c/luatexdir/ChangeLog +++ b/Build/source/texk/web2c/luatexdir/ChangeLog @@ -1,7 +1,77 @@ -2021-03-23 Siep Kroonenberg - *luasocket/src/inet.[ch] (inet_pton, inet_ntop) [_WS2TCPIP_H_]: - don't define fns if _WS2TCPIP_H_ is defined; for mingw. - https://tug.org/pipermail/tlbuild/2021q4/004980.html +2021-12-31 Luigi Scarso + * drop (for the moment) \showstream + +2021-12-30 Luigi Scarso + * struct dest (M.Krüger) + * fixed a 'Conditional jump or move depends on uninitialised value(s)' msg from valgrind + +2021-12-29 Luigi Scarso + * Correctly print \write for the error message + "Forbidden control sequence found while scanning text of" + (thanks to Hironobu Yamashita) + +2021-12-27 Luigi Scarso + * fixed a typo in a tex comment. + +2021-12-24 Luigi Scarso + * Metapost: make sure that an already open VF is closed before to read a new one + +2021-12-21 Luigi Scarso + * fixed os.uname on 64 bit Windows (A. Kakuto, L. Scarso) + +2021-12-13 Luigi Scarso + * fixed a typo in equivalents.c (user202729 @ https://chat.stackexchange.com/transcript/41/2021/12/12) + +2021-12-07 Luigi Scarso + * Fixed a typo in maincontrol.c (thanks to Hironobu Yamashita) + +2021-11-20 Luigi Scarso + * Ignore paragraphs with only a local par node followed by direction synchronization + nodes (paragraphs like that are seen as empty paragraphs) (HH) + +2021-08-28 Luigi Scarso + *more efficient fontdimen allocation (HH) + +2021-08-12 Luigi Scarso + *mplibdir: Fix _findfirst handle truncation on Windows x86_64. + Thanks to Richard Copley. + +2021-08-08 Luigi Scarso + *Improvements for glyph_stream_provider with TTF fonts (MK) + +2021-08-04 Luigi Scarso + *Fix named instance inconsistency in luaharfbuzz (MK) + +2021-08-03 Luigi Scarso + *luaharfbuzz: Provide interface for variable fonts (M.Krüger) + +2021-07-30 Luigi Scarso + *patch for luamplib to process string with "char 0"; fixed also mplib_text + +2021-07-30 Luigi Scarso + *patch for luamplib to process string with "char 0" + +2021-07-27 Luigi Scarso + *partoken primitives (HH & PO) + +2021-07-27 Luigi Scarso + *Sync with TeX Live revision 60088. + +2021-07-27 Luigi Scarso + *automake-1.16.4; initialize limit to avoid printing some garbage. + +2021-07-02 Luigi Scarso + *ePNG /Smask for pdf 2.0 + +2021-07-02 Luigi Scarso + *sync with upstream texlive; autoconf-2.71. + +2021-05-10 Luigi Scarso + *MetaPost: fixed the patch on the stack overflow. + +2021-05-09 Luigi Scarso + *Impose mp->stack_size < 1001 in @d push_input to avoid + stack overflow due infinite recursion of macro expansion (thanks to A. Kakuto). 2021-04-21 Luigi Scarso *\discretionaryligaturemode: optionally block select disc creation diff --git a/Build/source/texk/web2c/luatexdir/NEWS b/Build/source/texk/web2c/luatexdir/NEWS index 2b39dd75db5..cb5c37aaa53 100644 --- a/Build/source/texk/web2c/luatexdir/NEWS +++ b/Build/source/texk/web2c/luatexdir/NEWS @@ -1,3 +1,37 @@ + + +============================================================== +LuaTeX 1.14.1 2021-12-30 +============================================================== + +struct dest (M.F. Krüger); + +Ignore paragraphs with only a local par node followed by +direction synchronization nodes (paragraphs like that are seen +as empty paragraphs) (Hans Hagen); + +more efficient fontdimen allocation (Hans Hagen); + +improvements for glyph_stream_provider with TTF fonts (M.F. Krüger); + +provide interface for variable fonts in luaharfbuzz (M.F. Krüger); + +partoken primitives (Hans Hagen & Petr Olsak); + +PNG /Smask for pdf 2.0; + +\discretionaryligaturemode: optionally block select disc creation +(see [Dev-luatex] [PATCH] Nested discretionaries M.F. Krüger) (Hans Hagen); + +different radical style defaults in mathdefaultsmode +(see [Dev-luatex] Uunderdelimiter & friends and mathstyles by M.F. Krüger) (Hans Hagen). + + +Several bug fixes (see ChangeLog). + + + + ============================================================== LuaTeX 1.13.2 2021-04-10 ============================================================== diff --git a/Build/source/texk/web2c/luatexdir/am/luaharfbuzz.am b/Build/source/texk/web2c/luatexdir/am/luaharfbuzz.am index 1b6187eaaf1..f98dc79a01d 100644 --- a/Build/source/texk/web2c/luatexdir/am/luaharfbuzz.am +++ b/Build/source/texk/web2c/luatexdir/am/luaharfbuzz.am @@ -35,7 +35,8 @@ libluaharfbuzz_a_SOURCES = \ luatexdir/luaharfbuzz/src/luaharfbuzz/ot.c \ luatexdir/luaharfbuzz/src/luaharfbuzz/script.c \ luatexdir/luaharfbuzz/src/luaharfbuzz/tag.c \ - luatexdir/luaharfbuzz/src/luaharfbuzz/unicode.c + luatexdir/luaharfbuzz/src/luaharfbuzz/unicode.c \ + luatexdir/luaharfbuzz/src/luaharfbuzz/variation.c libluajitharfbuzz_a_SOURCES = $(libluaharfbuzz_a_SOURCES) diff --git a/Build/source/texk/web2c/luatexdir/font/texfont.c b/Build/source/texk/web2c/luatexdir/font/texfont.c index 0134243d929..496cb0838d0 100644 --- a/Build/source/texk/web2c/luatexdir/font/texfont.c +++ b/Build/source/texk/web2c/luatexdir/font/texfont.c @@ -1037,14 +1037,12 @@ void set_font_params(internal_font_number f, int b) int i; i = font_params(f); if (i != b) { - font_bytes += - (int) ((b - (int) font_params(f) + 1) * (int) sizeof(scaled)); + font_bytes += (int) ((b - (int) font_params(f) + 1) * (int) sizeof(scaled)); do_realloc(param_base(f), (b + 2), int); font_params(f) = b; if (b > i) { while (i < b) { - i++; - set_font_param(f, i, 0); + font_param(f, ++i) = 0; } } } @@ -1055,19 +1053,18 @@ void set_font_math_params(internal_font_number f, int b) int i; i = font_math_params(f); if (i != b) { - font_bytes += - ((b - (int) font_math_params(f) + 1) * (int) sizeof(scaled)); + font_bytes += ((b - (int) font_math_params(f) + 1) * (int) sizeof(scaled)); do_realloc(math_param_base(f), (b + 2), int); font_math_params(f) = b; if (b > i) { while (i < b) { - i++; - set_font_math_param(f, i, undefined_math_parameter); + font_math_param(f,++i) = undefined_math_parameter; } } } } + int copy_font(int f) { int i, ci_cnt, ci_size; diff --git a/Build/source/texk/web2c/luatexdir/font/tt_glyf.c b/Build/source/texk/web2c/luatexdir/font/tt_glyf.c index 750e126aa6a..b337eb9e7df 100644 --- a/Build/source/texk/web2c/luatexdir/font/tt_glyf.c +++ b/Build/source/texk/web2c/luatexdir/font/tt_glyf.c @@ -163,7 +163,7 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g, fd_entry * fd) int tex_font = fd->tex_font; int streamprovider = 0; int callback_id = 0 ; - if ((tex_font > 0) && (font_streamprovider(tex_font) == 2)) { + if ((tex_font > 0) && (font_streamprovider(tex_font) == 2 || font_streamprovider(tex_font) == 3)) { streamprovider = font_streamprovider(tex_font); callback_id = callback_defined(glyph_stream_provider_callback); } @@ -230,14 +230,24 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g, fd_entry * fd) formatted_error("ttf","invalid glyph index (gid %u)", gid); loc = location[gid]; len = location[gid + 1] - loc; - g->gd[i].advw = hmtx[gid].advance; - g->gd[i].lsb = hmtx[gid].sideBearing; - if (vmtx) { - g->gd[i].advh = vmtx[gid].advance; - g->gd[i].tsb = vmtx[gid].sideBearing; + if (callback_id > 0 && streamprovider == 3) { + int advw, lsb, advh, tsb; + run_callback(callback_id, "dddd->dddd", tex_font, g->gd[i].gid, + streamprovider, gid, &advw, &lsb, &advh, &tsb); + g->gd[i].advw = advw; + g->gd[i].lsb = lsb; + g->gd[i].advh = advh; + g->gd[i].tsb = tsb; } else { - g->gd[i].advh = g->default_advh; - g->gd[i].tsb = g->default_tsb; + g->gd[i].advw = hmtx[gid].advance; + g->gd[i].lsb = hmtx[gid].sideBearing; + if (vmtx) { + g->gd[i].advh = vmtx[gid].advance; + g->gd[i].tsb = vmtx[gid].sideBearing; + } else { + g->gd[i].advh = g->default_advh; + g->gd[i].tsb = g->default_tsb; + } } g->gd[i].length = len; g->gd[i].data = NULL; @@ -402,7 +412,14 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g, fd_entry * fd) if (callback_id > 0) { lstring * result; long size = 0; - run_callback(callback_id, "ddd->L", tex_font, g->gd[i].gid, streamprovider, &result); + /*tex + + The streamprovider here is always 2, even when we actually have streamprovider == 3, + to differentiate this call which behaves exactly like the call in the + streamprovider == 2 case from the streamprovider == 3 specific call earlier. + + */ + run_callback(callback_id, "ddd->L", tex_font, g->gd[i].gid, 2, &result); padlen = (int) ((result->l % 4) ? (4 - (result->l % 4)) : 0); size = (size_t) result->l + (ULONG) padlen; if (glyf_table_used + size >= glyf_table_size) { diff --git a/Build/source/texk/web2c/luatexdir/image/writepng.c b/Build/source/texk/web2c/luatexdir/image/writepng.c index 165e202f4e3..b9ed4d188d7 100644 --- a/Build/source/texk/web2c/luatexdir/image/writepng.c +++ b/Build/source/texk/web2c/luatexdir/image/writepng.c @@ -488,13 +488,13 @@ void write_png(PDF pdf, image_dict * idict) png_copy = false; } /*tex alpha channel support */ - if (pdf->minor_version < 4 + if ((pdf->major_version == 1 && pdf->minor_version < 4) && png_get_color_type(png_p, info_p) | PNG_COLOR_MASK_ALPHA) { png_set_strip_alpha(png_p); png_copy = false; } /*tex 16 bit depth support */ - if (pdf->minor_version < 5) + if (pdf->major_version == 1 && pdf->minor_version < 5) pdf->image_hicolor = 0; if ((png_get_bit_depth(png_p, info_p) == 16) && (pdf->image_hicolor == 0)) { png_set_strip_16(png_p); @@ -556,7 +556,7 @@ void write_png(PDF pdf, image_dict * idict) } } if (png_copy - && pdf->minor_version > 1 + && (pdf->major_version > 1 || pdf->minor_version > 1) && png_get_interlace_type(png_p, info_p) == PNG_INTERLACE_NONE && (png_get_color_type(png_p, info_p) == PNG_COLOR_TYPE_GRAY || png_get_color_type(png_p, info_p) == PNG_COLOR_TYPE_RGB) @@ -575,7 +575,7 @@ void write_png(PDF pdf, image_dict * idict) if (img_errorlevel(idict) > 1) { if (!png_copy) normal_warning("pngcopy","failed"); - if (!(pdf->minor_version > 1)) + if (!(pdf->major_version == 1 && pdf->minor_version > 1)) formatted_warning("pngcopy","skipped because minorversion is '%d'", pdf->minor_version); if (!(png_get_interlace_type(png_p, info_p) == PNG_INTERLACE_NONE)) normal_warning("pngcopy","skipped because of interlacing"); @@ -610,13 +610,13 @@ void write_png(PDF pdf, image_dict * idict) write_png_gray(pdf, idict); break; case PNG_COLOR_TYPE_GRAY_ALPHA: - if (pdf->minor_version >= 4) { + if (pdf->major_version > 1 || pdf->minor_version >= 4) { write_png_gray_alpha(pdf, idict); } else write_png_gray(pdf, idict); break; case PNG_COLOR_TYPE_RGB_ALPHA: - if (pdf->minor_version >= 4) { + if (pdf->major_version > 1 || pdf->minor_version >= 4) { write_png_rgb_alpha(pdf, idict); } else write_png_gray(pdf, idict); diff --git a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c index 0cd68038415..1ff36bc955c 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c @@ -4548,7 +4548,7 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, const char *s) } else if (lua_key_eq(s, named_id)) { lua_pushinteger(L, pdf_action_named_id(n)); } else if (lua_key_eq(s, action_id)) { - if (pdf_action_named_id(n) == 1) { + if (pdf_action_named_id(n) & 1) { tokenlist_to_luastring(L, pdf_action_id(n)); } else { lua_pushinteger(L, pdf_action_id(n)); @@ -4559,6 +4559,14 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, const char *s) lua_pushinteger(L, pdf_action_new_window(n)); } else if (lua_key_eq(s, data)) { tokenlist_to_luastring(L, pdf_action_tokens(n)); + } else if (lua_key_eq(s, struct_id)) { + if (pdf_action_struct_id(n) == null) { + lua_pushnil(L); + } else if (pdf_action_named_id(n) & 2) { + tokenlist_to_luastring(L, pdf_action_struct_id(n)); + } else { + lua_pushinteger(L, pdf_action_struct_id(n)); + } } else { lua_pushnil(L); } @@ -5320,7 +5328,7 @@ static void lua_nodelib_direct_getfield_whatsit(lua_State * L, int n, const char } else if (lua_key_eq(s, named_id)) { lua_pushinteger(L, pdf_action_named_id(n)); } else if (lua_key_eq(s, action_id)) { - if (pdf_action_named_id(n) == 1) { + if (pdf_action_named_id(n) & 1) { tokenlist_to_luastring(L, pdf_action_id(n)); } else { lua_pushinteger(L, pdf_action_id(n)); @@ -5331,6 +5339,14 @@ static void lua_nodelib_direct_getfield_whatsit(lua_State * L, int n, const char lua_pushinteger(L, pdf_action_new_window(n)); } else if (lua_key_eq(s, data)) { tokenlist_to_luastring(L, pdf_action_tokens(n)); + } else if (lua_key_eq(s, struct_id)) { + if (pdf_action_struct_id(n) == null) { + lua_pushnil(L); + } else if (pdf_action_named_id(n) & 2) { + tokenlist_to_luastring(L, pdf_action_struct_id(n)); + } else { + lua_pushinteger(L, pdf_action_struct_id(n)); + } } else { lua_pushnil(L); } @@ -6714,7 +6730,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, const char *s) } else if (lua_key_eq(s, named_id)) { pdf_action_named_id(n) = (quarterword) lua_tointeger(L, 3); } else if (lua_key_eq(s, action_id)) { - if (pdf_action_named_id(n) == 1) { + if (pdf_action_named_id(n) & 1) { pdf_action_id(n) = nodelib_gettoks(L, 3); } else { pdf_action_id(n) = (halfword) lua_tointeger(L, 3); @@ -6725,6 +6741,14 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, const char *s) pdf_action_new_window(n) = (halfword) lua_tointeger(L, 3); } else if (lua_key_eq(s, data)) { pdf_action_tokens(n) = nodelib_gettoks(L, 3); + } else if (lua_key_eq(s, struct_id)) { + if (lua_isnil(L, 3)) { + pdf_action_struct_id(n) = null; + } else if (pdf_action_named_id(n) & 2) { + pdf_action_struct_id(n) = nodelib_gettoks(L, 3); + } else { + pdf_action_struct_id(n) = (halfword) lua_tointeger(L, 3); + } } else { return nodelib_cantset(L, n, s); } @@ -7461,7 +7485,7 @@ static int lua_nodelib_direct_setfield_whatsit(lua_State * L, int n, const char } else if (lua_key_eq(s, named_id)) { pdf_action_named_id(n) = (quarterword) lua_tointeger(L, 3); } else if (lua_key_eq(s, action_id)) { - if (pdf_action_named_id(n) == 1) { + if (pdf_action_named_id(n) & 1) { pdf_action_id(n) = nodelib_gettoks(L, 3); } else { pdf_action_id(n) = (halfword) lua_tointeger(L, 3); @@ -7472,6 +7496,14 @@ static int lua_nodelib_direct_setfield_whatsit(lua_State * L, int n, const char pdf_action_new_window(n) = (halfword) lua_tointeger(L, 3); } else if (lua_key_eq(s, data)) { pdf_action_tokens(n) = nodelib_gettoks(L, 3); + } else if (lua_key_eq(s, struct_id)) { + if (lua_isnil(L, 3)) { + pdf_action_struct_id(n) = null; + } else if (pdf_action_named_id(n) & 2) { + pdf_action_struct_id(n) = nodelib_gettoks(L, 3); + } else { + pdf_action_struct_id(n) = (halfword) lua_tointeger(L, 3); + } } else { return nodelib_cantset(L, n, s); } diff --git a/Build/source/texk/web2c/luatexdir/lua/loslibext.c b/Build/source/texk/web2c/luatexdir/lua/loslibext.c index 979f724720f..2e6befc2da2 100644 --- a/Build/source/texk/web2c/luatexdir/lua/loslibext.c +++ b/Build/source/texk/web2c/luatexdir/lua/loslibext.c @@ -786,6 +786,18 @@ static int uname(struct utsname *uts) sprintf(uts->release, "build %ld", osver.dwBuildNumber & 0xFFFF); switch (sysinfo.wProcessorArchitecture) { + case PROCESSOR_ARCHITECTURE_AMD64: + strcpy(uts->machine, "amd64"); + break; + case PROCESSOR_ARCHITECTURE_ARM: + strcpy(uts->machine, "arm"); + break; + case PROCESSOR_ARCHITECTURE_ARM64: + strcpy(uts->machine, "arm64"); + break; + case PROCESSOR_ARCHITECTURE_IA64: + strcpy(uts->machine, "ia64"); + break; case PROCESSOR_ARCHITECTURE_PPC: strcpy(uts->machine, "ppc"); break; diff --git a/Build/source/texk/web2c/luatexdir/lua/luatex-api.h b/Build/source/texk/web2c/luatexdir/lua/luatex-api.h index 5f42bd5895c..c1e618f7a5d 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luatex-api.h +++ b/Build/source/texk/web2c/luatexdir/lua/luatex-api.h @@ -565,6 +565,7 @@ make_lua_key(advance);\ make_lua_key(after_assignment);\ make_lua_key(after_display);\ make_lua_key(after_group);\ +make_lua_key(partoken_name);\ make_lua_key(after_output);\ make_lua_key(afterdisplaypenalty);\ make_lua_key(align);\ @@ -1141,6 +1142,7 @@ make_lua_key(streamprovider);\ make_lua_key(stretch);\ make_lua_key(stretch_order);\ make_lua_key(string);\ +make_lua_key(struct_id);\ make_lua_key(style);\ make_lua_key(sub);\ make_lua_key(subfont);\ @@ -1276,6 +1278,7 @@ init_lua_key(advance);\ init_lua_key(after_assignment);\ init_lua_key(after_display);\ init_lua_key(after_group);\ +init_lua_key(partoken_name);\ init_lua_key(after_output);\ init_lua_key(afterdisplaypenalty);\ init_lua_key(align);\ @@ -1839,6 +1842,7 @@ init_lua_key(streamprovider);\ init_lua_key(stretch);\ init_lua_key(stretch_order);\ init_lua_key(string);\ +init_lua_key(struct_id);\ init_lua_key(style);\ init_lua_key(sub);\ init_lua_key(subfont);\ @@ -2036,6 +2040,7 @@ use_lua_key(advance); use_lua_key(after_assignment); use_lua_key(after_display); use_lua_key(after_group); +use_lua_key(partoken_name); use_lua_key(after_output); use_lua_key(afterdisplaypenalty); use_lua_key(align); @@ -2612,6 +2617,7 @@ use_lua_key(streamprovider); use_lua_key(stretch); use_lua_key(stretch_order); use_lua_key(string); +use_lua_key(struct_id); use_lua_key(style); use_lua_key(sub); use_lua_key(subfont); diff --git a/Build/source/texk/web2c/luatexdir/lua/luatoken.c b/Build/source/texk/web2c/luatexdir/lua/luatoken.c index 874fbc99a5d..dc2c6b8aaa5 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luatoken.c +++ b/Build/source/texk/web2c/luatexdir/lua/luatoken.c @@ -70,6 +70,7 @@ command_item command_names[] = { { ignore_spaces_cmd, NULL, 0}, { after_assignment_cmd, NULL, 0}, { after_group_cmd, NULL, 0}, + { partoken_name_cmd, NULL, 0}, { break_penalty_cmd, NULL, 0}, { start_par_cmd, NULL, 0}, { ital_corr_cmd, NULL, 0}, @@ -235,6 +236,7 @@ void l_set_token_data(void) init_token_key(command_names, ignore_spaces_cmd, ignore_spaces); init_token_key(command_names, after_assignment_cmd, after_assignment); init_token_key(command_names, after_group_cmd, after_group); + init_token_key(command_names, partoken_name_cmd, partoken_name); init_token_key(command_names, break_penalty_cmd, break_penalty); init_token_key(command_names, start_par_cmd, start_par); init_token_key(command_names, ital_corr_cmd, ital_corr); diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-1.1.0-1.rockspec b/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-1.1.0-1.rockspec index 17a84532b73..987e9748ff4 100644 --- a/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-1.1.0-1.rockspec +++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-1.1.0-1.rockspec @@ -31,6 +31,7 @@ build = { "src/luaharfbuzz/script.c", "src/luaharfbuzz/direction.c", "src/luaharfbuzz/language.c", + "src/luaharfbuzz/variation.c", "src/luaharfbuzz/class_utils.c" }, libraries = {"harfbuzz"}, diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-scm-1.rockspec b/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-scm-1.rockspec index 31ae2ab4fb7..0f0dd8d33bb 100644 --- a/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-scm-1.rockspec +++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-scm-1.rockspec @@ -33,6 +33,7 @@ build = { "src/luaharfbuzz/script.c", "src/luaharfbuzz/direction.c", "src/luaharfbuzz/language.c", + "src/luaharfbuzz/variation.c", "src/luaharfbuzz/class_utils.c" }, libraries = {"harfbuzz"}, diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/harfbuzz_spec.lua b/Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/harfbuzz_spec.lua index dfae07d8e65..38794372f66 100644 --- a/Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/harfbuzz_spec.lua +++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/harfbuzz_spec.lua @@ -230,6 +230,64 @@ describe("harfbuzz module", function() assert.True(r) assert.are_same(13, i) end) + + it("can return variation axes", function() + local f = harfbuzz.Face.new('fonts/STIXTwoText[wght].ttf') + + assert.is_same(true, f:ot_var_has_data()) + local axes = f:ot_var_get_axis_infos() + assert.are_same(1, #axes) + assert.are_same(harfbuzz.Tag.new("wght"), axes[1].tag) + assert.are_same(1, axes[1].axis_index) + assert.are_same(400, axes[1].min_value) + assert.are_same(400, axes[1].default_value) + assert.are_same(700, axes[1].max_value) + assert.are_same(0, axes[1].flags) + assert.are_same("Weight", f:get_name(axes[1].name_id)) + end) + + it("can find variation axis", function() + local f = harfbuzz.Face.new('fonts/STIXTwoText[wght].ttf') + + local axis = f:ot_var_find_axis_info(harfbuzz.Tag.new("wght")) + assert.is_not_nil(axis) + assert.are_same(harfbuzz.Tag.new("wght"), axis.tag) + assert.are_same(1, axis.axis_index) + assert.are_same(400, axis.min_value) + assert.are_same(400, axis.default_value) + assert.are_same(700, axis.max_value) + assert.are_same(0, axis.flags) + assert.are_same("Weight", f:get_name(axis.name_id)) + end) + + it("can return named instances", function() + local f = harfbuzz.Face.new('fonts/STIXTwoText[wght].ttf') + + local instances = f:ot_var_named_instance_get_infos() + assert.are_same(4, #instances) + assert.are_same(3, instances[3].index) + assert.are_same("SemiBold", f:get_name(instances[3].subfamily_name_id)) + assert.are_same(nil, f:get_name(instances[3].postscript_name_id)) + assert.are_same(600, f:ot_var_named_instance_get_design_coords(3)) + end) + + it("can normalize variations", function() + local f = harfbuzz.Face.new('fonts/STIXTwoText[wght].ttf') + + local normalized, after = f:ot_var_normalize_variations(harfbuzz.Variation.new("wght=400")) + assert.is_nil(after) + assert.are_same(0, normalized) + + normalized = f:ot_var_normalize_variations(harfbuzz.Variation.new("wght=700")) + assert.are_same(1<<14, normalized) + + normalized, after = f:ot_var_normalize_coords(700) + assert.is_nil(after) + assert.are_same(1<<14, normalized) + + normalized = f:ot_var_normalize_coords(400) + assert.are_same(0, normalized) + end) end) describe("harfbuzz.Font", function() @@ -318,6 +376,25 @@ describe("harfbuzz module", function() assert.are_same(2857,f:ot_color_glyph_get_png(2):get_length()) assert.are_same("\137PNG",f:ot_color_glyph_get_png(2):get_data():sub(1, 4)) end) + + it("can set variations", function() + local f = harfbuzz.Font.new(harfbuzz.Face.new('fonts/STIXTwoText[wght].ttf')) + + f:set_variations(harfbuzz.Variation.new("wght=500")) + local normalized, after = f:get_var_coords_normalized() + assert.is_nil(after) + assert.are_same(5174, normalized) + + f:set_var_coords_design(600) + local normalized, after = f:get_var_coords_normalized() + assert.is_nil(after) + assert.are_same(10348, normalized) + + f:set_var_coords_normalized(1<<13) + local normalized, after = f:get_var_coords_normalized() + assert.is_nil(after) + assert.are_same(1<<13, normalized) + end) end) describe("harfbuzz.Feature", function() @@ -339,7 +416,6 @@ describe("harfbuzz module", function() it("has visible fields", function() local f = harfbuzz.Feature.new('-kern') - print(getmetatable(f).__index) assert.are_equal(tostring(f.tag), 'kern') assert.are_equal(f.value, 0) assert.are_equal(f.start, nil) @@ -362,6 +438,44 @@ describe("harfbuzz module", function() end) end) + describe("harfbuzz.Variation", function() + it("can be initialised with a valid variation string", function() + harfbuzz.Variation.new('wght=default') + harfbuzz.Variation.new('wght=400') + harfbuzz.Variation.new('wght=-20') + end) + + it("throws an error when trying to initialise a new variation with an invalid string", function() + assert.are_equal(nil, harfbuzz.Variation.new('')) + assert.are_equal(nil, harfbuzz.Variation.new('wght')) + end) + + it("has a valid tostring value", function() + local vs = 'wght=200' + local v = harfbuzz.Variation.new(vs) + assert.are_equal(vs, tostring(v)) + end) + + it("has visible fields", function() + local v = harfbuzz.Variation.new('wght=400') + assert.are_equal(tostring(v.tag), 'wght') + assert.are_equal(v.value, 400) + + v = harfbuzz.Variation.new('slnt=-7.5') + assert.are_equal(tostring(v.tag), 'slnt') + assert.are_equal(v.value, -7.5) + end) + + it("has editable fields", function() + local f = harfbuzz.Variation.new('slnt=5') + f.tag, f.value = harfbuzz.Tag.new"wght", 7 + assert.are_equal(tostring(f), "wght=7") + + f.tag, f.value = harfbuzz.Tag.new"hght", 0 + assert.are_equal(tostring(f), "hght=0") + end) + end) + describe("harfbuzz.Tag", function() it("can be initialised with a valid tag string", function() harfbuzz.Tag.new('Zyyy') diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/face.c b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/face.c index 5538c704571..45296e04503 100644 --- a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/face.c +++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/face.c @@ -1,5 +1,20 @@ #include "luaharfbuzz.h" +#ifdef LuajitTeX + +static int lua_absindex (lua_State *L, int i) { + if (i < 0 && i > LUA_REGISTRYINDEX) + i += lua_gettop(L) + 1; + return i; +} +static void lua_seti (lua_State *L, int index, lua_Integer i) { + index = lua_absindex(L, index); + lua_pushinteger(L, i); + lua_insert(L, -2); + lua_settable(L, index); +} +#endif + /* Size of static arrays we use to avoid heap allocating memory when reading * data from HarfBuzz. */ #define STATIC_ARRAY_SIZE 128 @@ -423,6 +438,179 @@ static int face_ot_color_glyph_get_svg(lua_State *L) { return 1; } +static int face_var_has_data(lua_State *L) { + Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face"); + + lua_pushboolean(L, hb_ot_var_has_data(*f)); + return 1; +} + +static int push_axis_info(lua_State *L, const hb_ot_var_axis_info_t *info) { + lua_createtable(L, 0, 7); + + lua_pushinteger(L, info->axis_index + 1); + lua_setfield(L, -2, "axis_index"); + + Tag *tp = (Tag *)lua_newuserdata(L, sizeof(*tp)); + luaL_getmetatable(L, "harfbuzz.Tag"); + lua_setmetatable(L, -2); + *tp = info->tag; + lua_setfield(L, -2, "tag"); + + lua_pushinteger(L, info->name_id); + lua_setfield(L, -2, "name_id"); + + lua_pushinteger(L, info->flags); + lua_setfield(L, -2, "flags"); + + lua_pushnumber(L, info->min_value); + lua_setfield(L, -2, "min_value"); + + lua_pushnumber(L, info->default_value); + lua_setfield(L, -2, "default_value"); + + lua_pushnumber(L, info->max_value); + lua_setfield(L, -2, "max_value"); + + return 1; +} + +static int face_var_find_axis_info(lua_State *L) { + Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face"); + Tag *tag = (Tag *)luaL_checkudata(L, 2, "harfbuzz.Tag"); + hb_ot_var_axis_info_t axis_info; + + if (hb_ot_var_find_axis_info(*face, *tag, &axis_info)) + push_axis_info(L, &axis_info); + else + lua_pushnil(L); + return 1; +} + +static int face_var_get_axis_infos(lua_State *L) { + Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face"); + lua_Integer start = luaL_optinteger(L, 2, 1) - 1; + lua_Integer stop = luaL_optinteger(L, 2, -1); + if (start < -1) + start += hb_ot_var_get_axis_count(*face) + 1; + if (stop < 0) + stop += hb_ot_var_get_axis_count(*face) + 1; + + if (start < 0 || stop - start > STATIC_ARRAY_SIZE) + lua_pushnil(L); + else if (stop <= start) + lua_createtable(L, 0, 0); + else { + unsigned int count = stop - start; + hb_ot_var_axis_info_t axis_infos[STATIC_ARRAY_SIZE]; + + hb_ot_var_get_axis_infos(*face, start, &count, axis_infos); + + lua_createtable(L, count, 0); + for (int i = 0; i != count; i++) { + push_axis_info(L, axis_infos + i); + lua_seti(L, -2, i + 1); + } + } + return 1; +} + +static int face_var_named_instance_get_infos(lua_State *L) { + Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face"); + lua_Integer start = luaL_optinteger(L, 2, 1) - 1; + lua_Integer stop = luaL_optinteger(L, 2, -1); + + unsigned int total = hb_ot_var_get_named_instance_count(*face); + + if (start < -1) + start += total + 1; + if (stop < 0) + stop += total + 1; + if (stop > total) + stop = total; + + if (start < 0) + lua_pushnil(L); + else if (stop <= start) + lua_createtable(L, 0, 0); + else { + lua_createtable(L, stop - start, 0); + for (int i = start; i != stop; i++) { + lua_createtable(L, 0, 3); + + lua_pushinteger(L, i + 1); + lua_setfield(L, -2, "index"); + + lua_pushinteger(L, hb_ot_var_named_instance_get_subfamily_name_id(*face, i)); + lua_setfield(L, -2, "subfamily_name_id"); + + lua_pushinteger(L, hb_ot_var_named_instance_get_subfamily_name_id(*face, i)); + lua_setfield(L, -2, "subfamily_name_id"); + + lua_pushinteger(L, hb_ot_var_named_instance_get_postscript_name_id(*face, i)); + lua_setfield(L, -2, "postscript_name_id"); + + lua_seti(L, -2, i - start + 1); + } + } + return 1; +} + +static int face_var_named_instance_get_design_coords(lua_State *L) { + Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face"); + lua_Integer index = luaL_checkinteger(L, 2) - 1; + + float coords[STATIC_ARRAY_SIZE]; + unsigned int count = STATIC_ARRAY_SIZE; + count = hb_ot_var_named_instance_get_design_coords(*face, index, &count, coords); + + for (int i = 0; i != count; i++) { + lua_pushnumber(L, coords[i]); + } + return count; +} + +static int face_var_normalize_variations(lua_State *L) { + Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face"); + unsigned int count = lua_gettop(L)-1; + if (count > STATIC_ARRAY_SIZE) { + return 0; + } + + Variation variations[STATIC_ARRAY_SIZE]; + for (unsigned int i = 0; i != count; i++) + variations[i] = *(Variation *)luaL_checkudata(L, i+2, "harfbuzz.Variation"); + + unsigned int coord_count = hb_ot_var_get_axis_count(*face); + int normalized[STATIC_ARRAY_SIZE]; + hb_ot_var_normalize_variations(*face, variations, count, normalized, coord_count); + + for (int i = 0; i != coord_count; i++) { + lua_pushinteger(L, normalized[i]); + } + return coord_count; +} + +static int face_var_normalize_coords(lua_State *L) { + Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face"); + unsigned int count = lua_gettop(L)-1; + if (count > STATIC_ARRAY_SIZE) { + return 0; + } + + float coords[STATIC_ARRAY_SIZE]; + for (unsigned int i = 0; i != count; i++) + coords[i] = luaL_checknumber(L, i+2); + + int normalized[STATIC_ARRAY_SIZE]; + hb_ot_var_normalize_coords(*face, count, coords, normalized); + + for (int i = 0; i != count; i++) { + lua_pushinteger(L, normalized[i]); + } + return count; +} + static int face_destroy(lua_State *L) { Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face"); @@ -452,6 +640,13 @@ static const struct luaL_Reg face_methods[] = { { "ot_layout_find_script", face_ot_layout_find_script }, { "ot_layout_find_language", face_ot_layout_find_language }, { "ot_layout_find_feature", face_ot_layout_find_feature }, + { "ot_var_has_data", face_var_has_data }, + { "ot_var_find_axis_info", face_var_find_axis_info }, + { "ot_var_get_axis_infos", face_var_get_axis_infos }, + { "ot_var_named_instance_get_infos", face_var_named_instance_get_infos }, + { "ot_var_named_instance_get_design_coords", face_var_named_instance_get_design_coords }, + { "ot_var_normalize_variations", face_var_normalize_variations }, + { "ot_var_normalize_coords", face_var_normalize_coords }, { NULL, NULL } }; diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/font.c b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/font.c index c601673647e..d369f02f2fa 100644 --- a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/font.c +++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/font.c @@ -192,6 +192,62 @@ static int font_ot_color_glyph_get_png(lua_State *L) { return 1; } +static int font_set_variations(lua_State *L) { + Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font"); + unsigned int count = lua_gettop(L) - 1; + if (count > 128) + count = 128; + Variation variations[128]; + for (int i = 0; i != count; i++) + variations[i] = *(Variation *)luaL_checkudata(L, i + 2, "harfbuzz.Variation"); + + hb_font_set_variations(*f, variations, count); + return 0; +} + +static int font_set_var_coords_design(lua_State *L) { + Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font"); + unsigned int count = lua_gettop(L) - 1; + if (count > 128) + count = 128; + float coords[128]; + for (int i = 0; i != count; i++) + coords[i] = luaL_checknumber(L, i + 2); + + hb_font_set_var_coords_design(*f, coords, count); + return 0; +} + +static int font_set_var_coords_normalized(lua_State *L) { + Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font"); + unsigned int count = lua_gettop(L) - 1; + if (count > 128) + count = 128; + int coords[128]; + for (int i = 0; i != count; i++) + coords[i] = luaL_checkinteger(L, i + 2); + + hb_font_set_var_coords_normalized(*f, coords, count); + return 0; +} + +static int font_set_var_named_instance(lua_State *L) { + Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font"); + unsigned int instance = luaL_checkinteger(L, 2); + + hb_font_set_var_named_instance(*f, instance - 1); + return 0; +} + +static int font_get_var_coords_normalized(lua_State *L) { + Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font"); + unsigned int count; + const int *coords = hb_font_get_var_coords_normalized(*f, &count); + for (int i = 0; i != count; i++) + lua_pushinteger(L, coords[i]); + return count; +} + static const struct luaL_Reg font_methods[] = { { "__gc", font_destroy }, { "set_scale", font_set_scale }, @@ -205,6 +261,11 @@ static const struct luaL_Reg font_methods[] = { { "get_glyph_v_advance", font_get_glyph_v_advance }, { "get_nominal_glyph", font_get_nominal_glyph }, { "ot_color_glyph_get_png", font_ot_color_glyph_get_png }, + { "set_variations", font_set_variations }, + { "set_var_coords_design", font_set_var_coords_design }, + { "set_var_coords_normalized", font_set_var_coords_normalized }, + { "set_var_named_instance", font_set_var_named_instance }, + { "get_var_coords_normalized", font_get_var_coords_normalized }, { NULL, NULL } }; diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.c b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.c index 176c552aa59..8c841e56322 100644 --- a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.c +++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.c @@ -103,6 +103,9 @@ int luaopen_luaharfbuzz (lua_State *L) { register_language(L); lua_setfield(L, -2, "Language"); + register_variation(L); + lua_setfield(L, -2, "Variation"); + register_ot(L); lua_setfield(L, -2, "ot"); diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.h b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.h index 60f5db9c223..4b3aea6f5c0 100644 --- a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.h +++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.h @@ -18,6 +18,7 @@ typedef hb_tag_t Tag; typedef hb_script_t Script; typedef hb_direction_t Direction; typedef hb_language_t Language; +typedef hb_variation_t Variation; typedef struct luahb_constant_t { const char *name; @@ -35,6 +36,7 @@ int register_tag(lua_State *L); int register_script(lua_State *L); int register_direction(lua_State *L); int register_language(lua_State *L); +int register_variation(lua_State *L); int register_ot(lua_State *L); int register_unicode(lua_State *L); diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/variation.c b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/variation.c new file mode 100644 index 00000000000..5683aa607a5 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/variation.c @@ -0,0 +1,82 @@ +// harfbuzz.Variation +#include "luaharfbuzz.h" + +static int variation_new(lua_State *L) { + Variation v; + const char *variation = luaL_checkstring(L, 1); + + if (hb_variation_from_string(variation, -1, &v)) { + Variation *vp = (Variation *)lua_newuserdata(L, sizeof(*vp)); + luaL_getmetatable(L, "harfbuzz.Variation"); + lua_setmetatable(L, -2); + *vp = v; + } else { + lua_pushnil(L); + } + + return 1; +} + +static int variation_to_string(lua_State *L) { + Variation* v = (Variation *)luaL_checkudata(L, 1, "harfbuzz.Variation"); + char variation[128]; + + hb_variation_to_string(v, variation, 128); + lua_pushstring(L, variation); + return 1; +} + +static const char *variation_tag_ptr; +static const char *variation_value_ptr; + +static int variation_index(lua_State *L) { + Variation* v = (Variation *)luaL_checkudata(L, 1, "harfbuzz.Variation"); + const char *key = lua_tostring(L, 2); + + if (key == variation_tag_ptr) { + Tag *tag = (Tag *)lua_newuserdata(L, sizeof(*tag)); + luaL_getmetatable(L, "harfbuzz.Tag"); + lua_setmetatable(L, -2); + *tag = v->tag; + } else if (key == variation_value_ptr) { + lua_pushnumber(L, v->value); + } else { + lua_pushnil(L); + } + return 1; +} + +static int variation_newindex(lua_State *L) { + Variation* v = (Variation *)luaL_checkudata(L, 1, "harfbuzz.Variation"); + const char *key = lua_tostring(L, 2); + + if (key == variation_tag_ptr) { + v->tag = *(Tag *)luaL_checkudata(L, 3, "harfbuzz.Tag"); + } else if (key == variation_value_ptr) { + v->value = luaL_checknumber(L, 3); + } + return 0; +} + +static const struct luaL_Reg variation_methods[] = { + { "__index", variation_index }, + { "__newindex", variation_newindex }, + { "__tostring", variation_to_string }, + { NULL, NULL }, +}; + +static const struct luaL_Reg variation_functions[] = { + { "new", variation_new }, + { NULL, NULL } +}; + +int register_variation(lua_State *L) { + lua_pushliteral(L, "tag"); + variation_tag_ptr = lua_tostring(L, -1); + (void) luaL_ref (L, LUA_REGISTRYINDEX); + lua_pushliteral(L, "value"); + variation_value_ptr = lua_tostring(L, -1); + (void) luaL_ref (L, LUA_REGISTRYINDEX); + + return register_class(L, "harfbuzz.Variation", variation_methods, variation_functions, NULL); +} diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/inet.c b/Build/source/texk/web2c/luatexdir/luasocket/src/inet.c index 5df3d9d5ebe..f4c84044eb7 100644 --- a/Build/source/texk/web2c/luatexdir/luasocket/src/inet.c +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/inet.c @@ -519,7 +519,6 @@ int inet_aton(const char *cp, struct in_addr *inp) #endif #ifdef LUASOCKET_INET_PTON -#ifndef _WS2TCPIP_H_ int inet_pton(int af, const char *src, void *dst) { struct addrinfo hints, *res; @@ -542,4 +541,3 @@ int inet_pton(int af, const char *src, void *dst) } #endif -#endif diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/inet.h b/Build/source/texk/web2c/luatexdir/luasocket/src/inet.h index 829526d0872..928c7eb407e 100644 --- a/Build/source/texk/web2c/luatexdir/luasocket/src/inet.h +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/inet.h @@ -47,10 +47,8 @@ int inet_aton(const char *cp, struct in_addr *inp); #endif #ifdef LUASOCKET_INET_PTON -#ifndef _WS2TCPIP_H_ const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt); int inet_pton(int af, const char *src, void *dst); #endif -#endif #endif /* INET_H */ diff --git a/Build/source/texk/web2c/luatexdir/luatex.c b/Build/source/texk/web2c/luatexdir/luatex.c index d441d53f952..b28398652ae 100644 --- a/Build/source/texk/web2c/luatexdir/luatex.c +++ b/Build/source/texk/web2c/luatexdir/luatex.c @@ -32,9 +32,9 @@ stick to "0" upto "9" so users can expect a number represented as string. */ -int luatex_version = 114; +int luatex_version = 115; int luatex_revision = '0'; -const char *luatex_version_string = "1.14.0"; +const char *luatex_version_string = "1.15.0"; const char *engine_name = my_name; #include diff --git a/Build/source/texk/web2c/luatexdir/luatex_svnversion.h b/Build/source/texk/web2c/luatexdir/luatex_svnversion.h index b40380e1055..b44df5aab7c 100644 --- a/Build/source/texk/web2c/luatexdir/luatex_svnversion.h +++ b/Build/source/texk/web2c/luatexdir/luatex_svnversion.h @@ -1 +1 @@ -#define luatex_svn_revision 7439 +#define luatex_svn_revision 7474 diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfaction.c b/Build/source/texk/web2c/luatexdir/pdf/pdfaction.c index 2909ac6ad74..a1ed199cc29 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfaction.c +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfaction.c @@ -40,10 +40,33 @@ halfword scan_action(PDF pdf) set_pdf_action_tokens(p, def_ref); return p; } + pdf_action_named_id(p) = 0; if (scan_keyword("file")) { scan_toks(false, true); set_pdf_action_file(p, def_ref); } + if (scan_keyword("struct")) { + if (pdf_action_type(p) != pdf_action_goto) + normal_error("pdf backend", "only GoTo action can be used with `struct'"); + if (pdf_action_file(p) != null) { + scan_toks(false, true); + pdf_action_named_id(p) |= 2; + pdf_action_struct_id(p) = def_ref; + } else if (scan_keyword("name")) { + scan_toks(false, true); + pdf_action_named_id(p) |= 2; + pdf_action_struct_id(p) = def_ref; + } + else if (scan_keyword("num")) { + scan_int(); + if (cur_val <= 0) + normal_error("pdf backend", "num identifier must be positive"); + pdf_action_struct_id(p) = cur_val; + } + else + normal_error("pdf backend", "identifier type missing"); + } else + pdf_action_struct_id(p) = null; if (scan_keyword("page")) { if (pdf_action_type(p) != pdf_action_goto) normal_error("pdf backend", "only GoTo action can be used with 'page'"); @@ -52,12 +75,11 @@ halfword scan_action(PDF pdf) if (cur_val <= 0) normal_error("pdf backend", "page number must be positive"); set_pdf_action_id(p, cur_val); - set_pdf_action_named_id(p, 0); scan_toks(false, true); set_pdf_action_tokens(p, def_ref); } else if (scan_keyword("name")) { scan_toks(false, true); - set_pdf_action_named_id(p, 1); + pdf_action_named_id(p) |= 1; set_pdf_action_id(p, def_ref); } else if (scan_keyword("num")) { if ((pdf_action_type(p) == pdf_action_goto) && @@ -66,7 +88,6 @@ halfword scan_action(PDF pdf) scan_int(); if (cur_val <= 0) normal_error("pdf backend", "num identifier must be positive"); - set_pdf_action_named_id(p, 0); set_pdf_action_id(p, cur_val); } else { normal_error("pdf backend", "identifier type missing"); @@ -143,10 +164,10 @@ void write_action(PDF pdf, halfword p) case pdf_action_goto: if (pdf_action_file(p) == null) { pdf_dict_add_name(pdf, "S", "GoTo"); - d = pdf_get_obj(pdf, obj_type_dest, pdf_action_id(p), pdf_action_named_id(p)); + d = pdf_get_obj(pdf, obj_type_dest, pdf_action_id(p), (pdf_action_named_id(p) & 1) == 1); } else pdf_dict_add_name(pdf, "S", "GoToR"); - if (pdf_action_named_id(p) > 0) { + if (pdf_action_named_id(p) & 1) { char *tokstr = tokenlist_to_cstring(pdf_action_id(p), true, NULL); pdf_dict_add_string(pdf, "D", tokstr); xfree(tokstr); @@ -159,8 +180,8 @@ void write_action(PDF pdf, halfword p) case pdf_action_thread: pdf_dict_add_name(pdf, "S", "Thread"); if (pdf_action_file(p) == null) { - d = pdf_get_obj(pdf, obj_type_thread, pdf_action_id(p), pdf_action_named_id(p)); - if (pdf_action_named_id(p) > 0) { + d = pdf_get_obj(pdf, obj_type_thread, pdf_action_id(p), (pdf_action_named_id(p) & 1) == 1); + if (pdf_action_named_id(p) & 1) { char *tokstr = tokenlist_to_cstring(pdf_action_id(p), true, NULL); pdf_dict_add_string(pdf, "D", tokstr); xfree(tokstr); @@ -172,5 +193,14 @@ void write_action(PDF pdf, halfword p) } break; } + if (pdf_action_struct_id(p) != null) { + if (pdf_action_file(p) == null) { + d = pdf_get_obj(pdf, obj_type_struct_dest, pdf_action_struct_id(p), (pdf_action_named_id(p) & 2) == 2); + pdf_dict_add_ref(pdf, "SD", d); + } else { + pdf_add_name(pdf, "SD"); + pdf_print_toks(pdf, pdf_action_struct_id(p)); + } + } pdf_end_dict(pdf); } diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfdest.c b/Build/source/texk/web2c/luatexdir/pdf/pdfdest.c index 346cd26e031..ca3c76faa3c 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfdest.c +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfdest.c @@ -70,6 +70,16 @@ static void warn_dest_dup(int id, small_number byname) } } +/*tex + + In |do_dest|, structure destinations and regular destinations use separate object + types for |pdf_get_obj| but share an object type for |addto_page_resources|. + This allows |write_out_pdf_mark_destinations| to handle both kinds of destinations + in a uniform way, while still allowing to use the same name for both kinds of + destinations. This is a useful feature since it's rather common to have both kinds + of destinations for the same object and therefore they will often have the same name. + +*/ void do_dest(PDF pdf, halfword p, halfword parent_box, scaledpos cur) { scaledpos pos = pdf->posstruct->pos; @@ -79,7 +89,9 @@ void do_dest(PDF pdf, halfword p, halfword parent_box, scaledpos cur) normal_error("pdf backend", "destinations cannot be inside an xform"); if (doing_leaders) return; - k = pdf_get_obj(pdf, obj_type_dest, pdf_dest_id(p), pdf_dest_named_id(p)); + k = pdf_get_obj(pdf, + pdf_dest_objnum(p) == null ? obj_type_dest : obj_type_struct_dest, + pdf_dest_id(p), pdf_dest_named_id(p)); if (obj_dest_ptr(pdf, k) != null) { warn_dest_dup(pdf_dest_id(p), (small_number) pdf_dest_named_id(p)); return; @@ -133,14 +145,16 @@ void write_out_pdf_mark_destinations(PDF pdf) normal_error("pdf backend","destination has been already written (this shouldn't happen)"); } else { int i; + int objnum; i = obj_dest_ptr(pdf, k->info); + objnum = pdf_dest_objnum(i); pdf_begin_obj(pdf, k->info, OBJSTM_ALWAYS); - if (pdf_dest_named_id(i) > 0) { + if (pdf_dest_named_id(i) > 0 && objnum == null) { pdf_begin_dict(pdf); pdf_add_name(pdf, "D"); } pdf_begin_array(pdf); - pdf_add_ref(pdf, pdf->last_page); + pdf_add_ref(pdf, objnum == null ? pdf->last_page : objnum); switch (pdf_dest_type(i)) { case pdf_dest_xyz: pdf_add_name(pdf, "XYZ"); @@ -187,7 +201,7 @@ void write_out_pdf_mark_destinations(PDF pdf) break; } pdf_end_array(pdf); - if (pdf_dest_named_id(i) > 0) + if (pdf_dest_named_id(i) > 0 && objnum == null) pdf_end_dict(pdf); pdf_end_obj(pdf); } @@ -200,10 +214,21 @@ void scan_pdfdest(PDF pdf) { halfword q; int k; + int obj_type; str_number i; scaled_whd alt_rule; q = cur_list.tail_field; new_whatsit(pdf_dest_node); + if (scan_keyword("struct")) { + scan_int(); + if (cur_val <= 0) + normal_error("pdf backend", "struct identifier must be positive"); + pdf_dest_objnum(cur_list.tail_field) = cur_val; + obj_type = obj_type_struct_dest; + } else { + pdf_dest_objnum(cur_list.tail_field) = null; + obj_type = obj_type_dest; + } if (scan_keyword("num")) { scan_int(); if (cur_val <= 0) @@ -258,10 +283,10 @@ void scan_pdfdest(PDF pdf) } if (pdf_dest_named_id(cur_list.tail_field) != 0) { i = tokens_to_string(pdf_dest_id(cur_list.tail_field)); - k = find_obj(pdf, obj_type_dest, i, true); + k = find_obj(pdf, obj_type, i, true); flush_str(i); } else { - k = find_obj(pdf, obj_type_dest, pdf_dest_id(cur_list.tail_field), false); + k = find_obj(pdf, obj_type, pdf_dest_id(cur_list.tail_field), false); } if ((k != 0) && (obj_dest_ptr(pdf, k) != null)) { warn_dest_dup(pdf_dest_id(cur_list.tail_field),(small_number) pdf_dest_named_id(cur_list.tail_field)); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfdest.h b/Build/source/texk/web2c/luatexdir/pdf/pdfdest.h index 576baea0434..c1f0da8e65b 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfdest.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfdest.h @@ -44,6 +44,7 @@ typedef enum { # define obj_dest_ptr obj_aux /* pointer to |pdf_dest_node| */ # define set_obj_dest_ptr(pdf,A,B) obj_dest_ptr(pdf,A)=B +# define set_pdf_dest_struct_id(A,B)pdf_dest_struct_id(A)=B # define set_pdf_dest_id(A,B) pdf_dest_id(A)=B # define set_pdf_dest_named_id(A,B) pdf_dest_named_id(A)=B # define set_pdf_dest_type(A,B) pdf_dest_type(A)=B diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfgen.c b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.c index ce610cb4925..2f288fac50a 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfgen.c +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.c @@ -2065,6 +2065,38 @@ static void check_nonexisting_destinations(PDF pdf) } } +/*tex + + For structure destinations we don't have a fallback structure element to use when + they are not defined, so we insert "null" instead + referenced but don't exists have |obj_dest_ptr=null|. Leaving them undefined + might cause troubles for PDF browsers, so we need to fix them; they point to + the last page. + +*/ + +static void check_nonexisting_structure_destinations(PDF pdf) +{ + int k; + for (k = pdf->head_tab[obj_type_struct_dest]; k != 0; k = obj_link(pdf, k)) { + if (obj_dest_ptr(pdf, k) == null) { + if (obj_info(pdf, k) < 0) { + char *ss = makecstring(-obj_info(pdf, k)); + formatted_warning("pdf backend", "unreferenced structure destination with name '%s'",ss); + } else { + formatted_warning("pdf backend", "unreferenced structure destination with num '%d'",obj_info(pdf,k)); + } + + pdf_begin_obj(pdf, k, OBJSTM_ALWAYS); + pdf_begin_array(pdf); + pdf_add_null(pdf); + pdf_add_name(pdf, "Fit"); + pdf_end_array(pdf); + pdf_end_obj(pdf); + } + } +} + static void check_nonexisting_pages(PDF pdf) { struct avl_traverser t; @@ -2226,6 +2258,7 @@ void pdf_finish_file(PDF pdf, int fatal_error) { if (total_pages > 0) { check_nonexisting_pages(pdf); check_nonexisting_destinations(pdf); + check_nonexisting_structure_destinations(pdf); } /*tex Output fonts definition. diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdftables.c b/Build/source/texk/web2c/luatexdir/pdf/pdftables.c index 2a02dcd98ec..f7a0df0063a 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdftables.c +++ b/Build/source/texk/web2c/luatexdir/pdf/pdftables.c @@ -22,7 +22,7 @@ with LuaTeX; if not, see . #include "ptexlib.h" const char *pdf_obj_typenames[PDF_OBJ_TYPE_MAX + 1] = { - "font", "outline", "dest", "obj", "xform", "ximage", "thread", + "font", "outline", "dest", "struct dest", "obj", "xform", "ximage", "thread", "pagestream", "page", "pages", "catalog", "info", "link", "annot", "annots", "bead", "beads", "objstm", "others" }; diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdftypes.h b/Build/source/texk/web2c/luatexdir/pdf/pdftypes.h index ad2465f5283..76bc69916b0 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdftypes.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdftypes.h @@ -203,26 +203,27 @@ typedef enum { obj_type_font = 0, /* index of linked list of Fonts objects */ obj_type_outline = 1, /* index of linked list of outline objects */ obj_type_dest = 2, /* index of linked list of destination objects */ - obj_type_obj = 3, /* index of linked list of raw objects */ - obj_type_xform = 4, /* index of linked list of XObject forms */ - obj_type_ximage = 5, /* index of linked list of XObject images */ - obj_type_thread = 6, /* index of linked list of num article threads */ - obj_type_pagestream = 7, /* Page stream objects */ - obj_type_page = 8, /* /Page objects */ - obj_type_pages = 9, /* /Pages objects */ - obj_type_catalog = 10, /* /Catalog object */ - obj_type_info = 11, /* /Info object */ - obj_type_link = 12, /* link objects */ - obj_type_annot = 13, /* annotation objects */ - obj_type_annots = 14, /* /Annots objects */ - obj_type_bead = 15, /* thread bead objects */ - obj_type_beads = 16, /* /B objects (array of bead objects) */ - obj_type_objstm = 17, /* /ObjStm objects */ - obj_type_others = 18 /* any other objects (also not linked in any list) */ + obj_type_struct_dest = 3, /* index of linked list of structure destination objects */ + obj_type_obj = 4, /* index of linked list of raw objects */ + obj_type_xform = 5, /* index of linked list of XObject forms */ + obj_type_ximage = 6, /* index of linked list of XObject images */ + obj_type_thread = 7, /* index of linked list of num article threads */ + obj_type_pagestream = 8, /* Page stream objects */ + obj_type_page = 9, /* /Page objects */ + obj_type_pages = 10, /* /Pages objects */ + obj_type_catalog = 11, /* /Catalog object */ + obj_type_info = 12, /* /Info object */ + obj_type_link = 13, /* link objects */ + obj_type_annot = 14, /* annotation objects */ + obj_type_annots = 15, /* /Annots objects */ + obj_type_bead = 16, /* thread bead objects */ + obj_type_beads = 17, /* /B objects (array of bead objects) */ + obj_type_objstm = 18, /* /ObjStm objects */ + obj_type_others = 19 /* any other objects (also not linked in any list) */ } pdf_obj_type; -# define HEAD_TAB_MAX 6 /* obj_type_thread */ -# define PDF_OBJ_TYPE_MAX 18 /* obj_type_others */ +# define HEAD_TAB_MAX 7 /* obj_type_thread */ +# define PDF_OBJ_TYPE_MAX 19 /* obj_type_others */ typedef struct pdf_resource_struct_ { struct avl_table *resources_tree; diff --git a/Build/source/texk/web2c/luatexdir/tex/commands.c b/Build/source/texk/web2c/luatexdir/tex/commands.c index c4f85dd0437..e9c0ad88803 100644 --- a/Build/source/texk/web2c/luatexdir/tex/commands.c +++ b/Build/source/texk/web2c/luatexdir/tex/commands.c @@ -178,6 +178,7 @@ void initialize_commands(void) primitive_luatex("glyphdimensionsmode", assign_int_cmd, int_base + glyph_dimensions_code, int_base); primitive_luatex("mathdefaultsmode", assign_int_cmd, int_base + math_defaults_mode_code, int_base); primitive_luatex("discretionaryligaturemode", assign_int_cmd, int_base + discretionary_ligature_mode_code, int_base); + primitive_etex("partokencontext", assign_int_cmd, int_base + partoken_context_code, int_base); /*tex @@ -193,6 +194,7 @@ void initialize_commands(void) primitive_tex("advance", advance_cmd, 0, 0); primitive_tex("afterassignment", after_assignment_cmd, 0, 0); primitive_tex("aftergroup", after_group_cmd, 0, 0); + primitive_etex("partokenname", partoken_name_cmd, 0, 0); primitive_tex("begingroup", begin_group_cmd, 0, 0); primitive_tex("char", char_num_cmd, 0, 0); primitive_tex("csname", cs_name_cmd, 0, 0); @@ -818,15 +820,6 @@ void initialize_etex_commands(void) primitive_luatex("shapemode", assign_int_cmd, int_base + shape_mode_code, int_base); primitive_luatex("hyphenationbounds", assign_int_cmd, int_base + hyphenation_bounds_code, int_base); - /*tex - - The \.{\\showstream} parameter allows to redirect the output of xray_cmd - commands to any write stream. - - */ - - primitive_tex("showstream", assign_int_cmd, int_base + show_stream_code, int_base); - primitive_etex("showgroups", xray_cmd, show_groups, 0); /*tex diff --git a/Build/source/texk/web2c/luatexdir/tex/commands.h b/Build/source/texk/web2c/luatexdir/tex/commands.h index 7d7a7056564..9ae92c0e6f0 100644 --- a/Build/source/texk/web2c/luatexdir/tex/commands.h +++ b/Build/source/texk/web2c/luatexdir/tex/commands.h @@ -115,6 +115,7 @@ typedef enum { ignore_spaces_cmd, /* gobble |spacer| tokens ( \.{\\ignorespaces} ) */ after_assignment_cmd, /* save till assignment is done ( \.{\\afterassignment} ) */ after_group_cmd, /* save till group is done ( \.{\\aftergroup} ) */ + partoken_name_cmd, /* something pdftex, not sure if this is the right order */ break_penalty_cmd, /* additional badness ( \.{\\penalty} ) */ start_par_cmd, /* begin paragraph ( \.{\\indent}, \.{\\noindent} ) */ ital_corr_cmd, /* italic correction ( \.{\\/} ) */ diff --git a/Build/source/texk/web2c/luatexdir/tex/dumpdata.c b/Build/source/texk/web2c/luatexdir/tex/dumpdata.c index 8270277c38d..0457def2965 100644 --- a/Build/source/texk/web2c/luatexdir/tex/dumpdata.c +++ b/Build/source/texk/web2c/luatexdir/tex/dumpdata.c @@ -32,7 +32,7 @@ with LuaTeX; if not, see . */ -#define FORMAT_ID (907+56) +#define FORMAT_ID (907+57) #if ((FORMAT_ID>=0) && (FORMAT_ID<=256)) #error Wrong value for FORMAT_ID. #endif diff --git a/Build/source/texk/web2c/luatexdir/tex/equivalents.c b/Build/source/texk/web2c/luatexdir/tex/equivalents.c index 3d260d5c5ee..b1fbcce63b8 100644 --- a/Build/source/texk/web2c/luatexdir/tex/equivalents.c +++ b/Build/source/texk/web2c/luatexdir/tex/equivalents.c @@ -922,7 +922,7 @@ algorithms into low-level languages that do not support recursion. In general, |cur_cmd| is the current command as set by |get_next|, while |cur_chr| is the operand of the current command. The control sequence found here -is registsred in |cur_cs| and is zero if none found. The |cur_tok| variable +is registered in |cur_cs| and is zero if none found. The |cur_tok| variable contains the packed representative of |cur_cmd| and |cur_chr| and like the other ones is global. diff --git a/Build/source/texk/web2c/luatexdir/tex/equivalents.h b/Build/source/texk/web2c/luatexdir/tex/equivalents.h index 84f85ba88ea..e4872f74896 100644 --- a/Build/source/texk/web2c/luatexdir/tex/equivalents.h +++ b/Build/source/texk/web2c/luatexdir/tex/equivalents.h @@ -311,8 +311,7 @@ the |number_regs| \.{\\dimen} registers. # define glyph_dimensions_code 118 # define math_defaults_mode_code 119 /* > 0 : latex preferences */ # define discretionary_ligature_mode_code 120 - -# define show_stream_code 121 +# define partoken_context_code 121 # define math_option_code 122 @@ -817,8 +816,8 @@ extern halfword last_cs_name; #define glyph_dimensions_par int_par(glyph_dimensions_code) #define math_defaults_mode_par int_par(math_defaults_mode_code) #define discretionary_ligature_mode_par int_par(discretionary_ligature_mode_code) +#define partoken_context_code_par int_par(partoken_context_code) -#define show_stream_par int_par(show_stream_code) /* */ diff --git a/Build/source/texk/web2c/luatexdir/tex/extensions.c b/Build/source/texk/web2c/luatexdir/tex/extensions.c index 19d4e444173..aa7538acf43 100644 --- a/Build/source/texk/web2c/luatexdir/tex/extensions.c +++ b/Build/source/texk/web2c/luatexdir/tex/extensions.c @@ -365,8 +365,8 @@ static void new_write_whatsit(int w, int check) void do_extension(int immediate) { - /*tex An all-purpose pointer. */ - halfword p; + /*tex All-purpose pointers. */ + halfword k,p; if (cur_cmd == extension_cmd) { /*tex These have their own range starting at 0. */ switch (cur_chr) { @@ -403,9 +403,10 @@ void do_extension(int immediate) be expanded later when this token list is rescanned. */ + k = cur_cs; p = tail; - new_write_whatsit(write_node_size,0); - cur_cs = write_stream(tail); + new_write_whatsit(write_node_size,0); // this can modify cur_cs + cur_cs = k; // so we restore the prev. cur_cs, as in pdftex scan_toks(false, false); write_tokens(tail) = def_ref; if (immediate) { diff --git a/Build/source/texk/web2c/luatexdir/tex/mainbody.c b/Build/source/texk/web2c/luatexdir/tex/mainbody.c index 4fbe62b69bc..2f45f9989d2 100644 --- a/Build/source/texk/web2c/luatexdir/tex/mainbody.c +++ b/Build/source/texk/web2c/luatexdir/tex/mainbody.c @@ -441,7 +441,6 @@ int main_initialize(void) memset(eqtb, 0, sizeof(memory_word) * (unsigned) (eqtb_top + 1)); init_string_pool_array((unsigned) max_strings); reset_cur_string(); - show_stream_par = -1; } /*tex Check the ``constant'' values... diff --git a/Build/source/texk/web2c/luatexdir/tex/maincontrol.c b/Build/source/texk/web2c/luatexdir/tex/maincontrol.c index 9aec6c12ff4..f72659c5064 100644 --- a/Build/source/texk/web2c/luatexdir/tex/maincontrol.c +++ b/Build/source/texk/web2c/luatexdir/tex/maincontrol.c @@ -463,8 +463,16 @@ static void run_start_par (void) { } static void run_new_graf (void) { - back_input(); - new_graf(true); + /* the |partoken_context_code_par| branch is taken from pdftex as-is: */ + if (cur_cmd == valign_cmd && partoken_context_code_par > 0 && mode == hmode) { + back_input(); + cur_tok = par_token; + back_input(); + token_type = inserted; + } else { + back_input(); + new_graf(true); + } } /*tex @@ -607,6 +615,14 @@ static void run_after_group (void) { save_for_after(cur_tok); } +static void run_par_token (void) { + get_token(); + if (cur_cs > 0) { + par_loc = cur_cs; + par_token = cur_tok; + } +} + static void run_extension (void) { do_extension(0); } @@ -976,6 +992,7 @@ static void init_main_control (void) { any_mode(set_interaction_cmd, prefixed_command); any_mode(after_assignment_cmd,run_after_assignment); any_mode(after_group_cmd,run_after_group); + any_mode(partoken_name_cmd,run_par_token); any_mode(in_stream_cmd,open_or_close_in); any_mode(message_cmd,issue_message); any_mode(case_shift_cmd, shift_case); @@ -1272,7 +1289,7 @@ void report_illegal_case(void) you_cant(); help4( "Sorry, but I'm not programmed to handle this case;", - "I'll just pretend that you didn''t ask for it.", + "I'll just pretend that you didn't ask for it.", "If you're in the wrong mode, you might be able to", "return to the right one by typing `I}' or `I$' or `I\\par'." ); @@ -1459,10 +1476,14 @@ deal with such errors. void handle_right_brace(void) { - halfword p, q; /* for short-term use */ - scaled d; /* holds |split_max_depth| in |insert_group| */ - int f; /* holds |floating_penalty| in |insert_group| */ + halfword p, q; /* for short-term use */ + scaled d; /* holds |split_max_depth| in |insert_group| */ + int f; /* holds |floating_penalty| in |insert_group| */ p = null; + /* + The |partoken_context_code_par| branch is taken from pdftex as-is. We could save some lines + by first testing for hmode and the parameter but in the end it's not cleaner. + */ switch (cur_group) { case simple_group: fixup_directions(); @@ -1502,57 +1523,89 @@ void handle_right_brace(void) package(0); break; case vbox_group: - end_graf(vbox_group); - package(0); + /* the |partoken_context_code_par| branch is taken from pdftex as-is: */ + if (partoken_context_code_par > 0 && mode == hmode) { + back_input(); + cur_tok = par_token; + back_input(); + token_type = inserted; + } else { + end_graf(vbox_group); + package(0); + } break; case vtop_group: - end_graf(vtop_group); - package(vtop_code); + /* the |partoken_context_code_par| branch is taken from pdftex as-is: */ + if (partoken_context_code_par > 0 && mode == hmode) { + back_input(); + cur_tok = par_token; + back_input(); + token_type = inserted; + } else { + end_graf(vtop_group); + package(vtop_code); + } break; case insert_group: - end_graf(insert_group); - q = new_glue(split_top_skip_par); - d = split_max_depth_par; - f = floating_penalty_par; - unsave(); - save_ptr--; - /*tex - Now |saved_value(0)| is the insertion number, or the |vadjust| subtype. - */ - p = vpack(vlink(head), 0, additional, -1); - pop_nest(); - if (saved_type(0) == saved_insert) { - tail_append(new_node(ins_node, saved_value(0))); - height(tail) = height(p) + depth(p); - ins_ptr(tail) = list_ptr(p); - split_top_ptr(tail) = q; - depth(tail) = d; - float_cost(tail) = f; - } 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); + /* the |partoken_context_code_par| branch is taken from pdftex as-is: */ + if (partoken_context_code_par > 1 && mode == hmode) { + back_input(); + cur_tok = par_token; + back_input(); + token_type = inserted; } else { - confusion("insert_group"); - } - list_ptr(p) = null; - flush_node(p); - if (nest_ptr == 0) { - checked_page_filter(insert); - build_page(); + end_graf(insert_group); + q = new_glue(split_top_skip_par); + d = split_max_depth_par; + f = floating_penalty_par; + unsave(); + save_ptr--; + /*tex + Now |saved_value(0)| is the insertion number, or the |vadjust| subtype. + */ + p = vpack(vlink(head), 0, additional, -1); + pop_nest(); + if (saved_type(0) == saved_insert) { + tail_append(new_node(ins_node, saved_value(0))); + height(tail) = height(p) + depth(p); + ins_ptr(tail) = list_ptr(p); + split_top_ptr(tail) = q; + depth(tail) = d; + float_cost(tail) = f; + } 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); + } else { + confusion("insert_group"); + } + list_ptr(p) = null; + flush_node(p); + if (nest_ptr == 0) { + checked_page_filter(insert); + build_page(); + } } break; case output_group: - /*tex - this is needed in case the \.{\\output} executes a \.{\\textdir} command. - */ - if (dir_level(text_dir_ptr) == cur_level) { - /*tex Remove from |text_dir_ptr| */ - halfword text_dir_tmp = vlink(text_dir_ptr); - flush_node(text_dir_ptr); - text_dir_ptr = text_dir_tmp; + /* the |partoken_context_code_par| branch is taken from pdftex as-is: */ + if (partoken_context_code_par > 1 && mode == hmode) { + back_input(); + cur_tok = par_token; + back_input(); + token_type = inserted; + } else { + /*tex + this is needed in case the \.{\\output} executes a \.{\\textdir} command. + */ + if (dir_level(text_dir_ptr) == cur_level) { + /*tex Remove from |text_dir_ptr| */ + halfword text_dir_tmp = vlink(text_dir_ptr); + flush_node(text_dir_ptr); + text_dir_ptr = text_dir_tmp; + } + resume_after_output(); } - resume_after_output(); break; case disc_group: build_discretionary(); @@ -1570,13 +1623,29 @@ void handle_right_brace(void) ins_error(); break; case no_align_group: - end_graf(no_align_group); - unsave(); - align_peek(); + /* the |partoken_context_code_par| branch is taken from pdftex as-is: */ + if (partoken_context_code_par > 1 && mode == hmode) { + back_input(); + cur_tok = par_token; + back_input(); + token_type = inserted; + } else { + end_graf(no_align_group); + unsave(); + align_peek(); + } break; case vcenter_group: - end_graf(vcenter_group); - finish_vcenter(); + /* the |partoken_context_code_par| branch is taken from pdftex as-is: */ + if (partoken_context_code_par > 0 && mode == hmode) { + back_input(); + cur_tok = par_token; + back_input(); + token_type = inserted; + } else { + end_graf(vcenter_group); + finish_vcenter(); + } break; case math_choice_group: build_choices(); @@ -1873,13 +1942,29 @@ displays. */ +static int only_dirs(halfword n) +{ + while (n) { + if (type(n) == local_par_node || type(n) == dir_node) { + n = vlink(n); + } else { + return 0; + } + } + return 1; +} + void end_graf(int line_break_context) { if (mode == hmode) { - if ((head == tail) || (vlink(head) == tail)) { - if (vlink(head) == tail) - flush_node(vlink(head)); - /*tex |null| paragraphs are ignored, all contain a |local_paragraph| node */ + /*tex + We ignore |null| paragraphs, that is those that only have a local par node + and possibly a few dir nodes injected automatically. + */ + if (head == tail) { + pop_nest(); + } else if (only_dirs(vlink(head))) { + flush_node(vlink(head)); pop_nest(); } else { line_break(false, line_break_context); @@ -3968,10 +4053,6 @@ void show_whatever(void) int m; /* upper bound on |fi_or_else| codes */ int l; /* line where that conditional began */ int n; /* level of \.{\\if...\\fi} nesting */ - int saved_selector; /* previous selector. Must be distinct from the global err_old_setting. */ - saved_selector = selector; - if (file_can_be_written(show_stream_par)) - selector = show_stream_par; switch (cur_chr) { case show_lists: begin_diagnostic(); @@ -4066,10 +4147,6 @@ void show_whatever(void) } } COMMON_ENDING: - if (valid_write_file(selector)) { - selector = saved_selector; - return; - } if (interaction < error_stop_mode) { help0(); decr(error_count); diff --git a/Build/source/texk/web2c/luatexdir/tex/primitive.c b/Build/source/texk/web2c/luatexdir/tex/primitive.c index f16d69a333c..30954c6fa21 100644 --- a/Build/source/texk/web2c/luatexdir/tex/primitive.c +++ b/Build/source/texk/web2c/luatexdir/tex/primitive.c @@ -582,7 +582,7 @@ and most of it was essentially an inverse to the |primitive| routine that enters a \TeX\ primitive into |eqtb|. Thanks to |prim_data|, there is no need for all that tediousness. What is left of -|primt_cnd_chr| are just the exceptions to the general rule that the +|print_cmd_chr| are just the exceptions to the general rule that the |cmd,chr_code| pair represents in a single primitive command. */ diff --git a/Build/source/texk/web2c/luatexdir/tex/printing.c b/Build/source/texk/web2c/luatexdir/tex/printing.c index 31125d2ebca..2ee5a110606 100644 --- a/Build/source/texk/web2c/luatexdir/tex/printing.c +++ b/Build/source/texk/web2c/luatexdir/tex/printing.c @@ -466,6 +466,7 @@ void tprint(const char *sss) /*tex What is left is the 3 term/log settings. */ if (dolog || doterm) { buffer = xmalloc(strlen(sss)*3); + buffer[0] = '\0'; /*tex The |wrapup_run| callback acts when the log file is already closed.*/ if (dolog && log_opened_global) { const unsigned char *ss = (const unsigned char *) sss; diff --git a/Build/source/texk/web2c/luatexdir/tex/scanning.c b/Build/source/texk/web2c/luatexdir/tex/scanning.c index f3313f065b5..f4ddd34ff77 100644 --- a/Build/source/texk/web2c/luatexdir/tex/scanning.c +++ b/Build/source/texk/web2c/luatexdir/tex/scanning.c @@ -1818,9 +1818,10 @@ void set_font_dimen(void) font_param_error(f); } else { /*tex Increase the number of parameters in the font. */ - do { - set_font_param(f, (font_params(f) + 1), 0); - } while (n != font_params(f)); + // do { + // set_font_param(f, (font_params(f) + 1), 0); + // } while (n != font_params(f)); + set_font_params(f, n); } } scan_optional_equals(); @@ -1848,9 +1849,10 @@ void get_font_dimen(void) goto EXIT; } else { /*tex Increase the number of parameters in the font. */ - do { - set_font_param(f, (font_params(f) + 1), 0); - } while (n != font_params(f)); + // do { + // set_font_param(f, (font_params(f) + 1), 0); + // } while (n != font_params(f)); + set_font_params(f, n); } } cur_val = font_param(f, n); @@ -2521,10 +2523,10 @@ static void scan_expr(void) a = arith_error; b = false; p = null; - /*tex - - Scan and evaluate an expression |e| of type |l|. - To avoid an infinite recursion we set|max_nesting| as upper limit. + /*tex + + Scan and evaluate an expression |e| of type |l|. + To avoid an infinite recursion we set|max_nesting| as upper limit. This limit is unrelated to the expansion limit |expand_depth| and it cannot be modify at compile time. */ diff --git a/Build/source/texk/web2c/luatexdir/tex/texfileio.c b/Build/source/texk/web2c/luatexdir/tex/texfileio.c index 4e0677a564b..8d8cdc04363 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texfileio.c +++ b/Build/source/texk/web2c/luatexdir/tex/texfileio.c @@ -637,8 +637,11 @@ void term_input(void) int k; /*tex Now the user sees the prompt for sure: */ update_terminal(); - if (!input_ln(term_in, true)) + if (!input_ln(term_in, true)) { + /*tex initialize limit to avoid printing some garbage. */ + ilimit=0; fatal_error("End of file on the terminal!"); + } /*tex The user's line ended with \.{}: */ term_offset = 0; /*tex Prepare to echo the input. */ diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.c b/Build/source/texk/web2c/luatexdir/tex/texnodes.c index 02e117a876b..4e645fda976 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texnodes.c +++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.c @@ -1107,7 +1107,8 @@ void l_set_whatsit_data(void) { init_field_key(node_fields_whatsit_pdf_action, 3, file); init_field_key(node_fields_whatsit_pdf_action, 4, new_window); init_field_key(node_fields_whatsit_pdf_action, 5, data); - init_field_nop(node_fields_whatsit_pdf_action, 6); + init_field_key(node_fields_whatsit_pdf_action, 6, struct_id); + init_field_nop(node_fields_whatsit_pdf_action, 7); init_field_key(node_fields_whatsit_pdf_annot, 0, attr); init_field_key(node_fields_whatsit_pdf_annot, 1, width); @@ -2302,8 +2303,10 @@ void flush_node_wrapup_pdf(halfword p) delete_token_ref(pdf_action_file(p)); if (pdf_action_type(p) == pdf_action_page) delete_token_ref(pdf_action_tokens(p)); - else if (pdf_action_named_id(p) > 0) + else if (pdf_action_named_id(p) & 1) delete_token_ref(pdf_action_id(p)); + if (pdf_action_named_id(p) & 2) + delete_token_ref(pdf_action_struct_id(p)); } break; case pdf_thread_data_node: @@ -3636,9 +3639,21 @@ void show_node_wrapup_pdf(int p) tprint(" file"); print_mark(pdf_action_file(pdf_link_action(p))); } + if (pdf_action_struct_id(pdf_link_action(p)) != null) { + tprint(" struct"); + if (pdf_action_file(pdf_link_action(p)) != null) { + print_mark(pdf_action_struct_id(pdf_link_action(p))); + } else if (pdf_action_named_id(pdf_link_action(p)) & 2) { + tprint(" name"); + print_mark(pdf_action_struct_id(pdf_link_action(p))); + } else { + tprint(" num"); + print_int(pdf_action_struct_id(pdf_link_action(p))); + } + } switch (pdf_action_type(pdf_link_action(p))) { case pdf_action_goto: - if (pdf_action_named_id(pdf_link_action(p)) > 0) { + if (pdf_action_named_id(pdf_link_action(p)) & 1) { tprint(" goto name"); print_mark(pdf_action_id(pdf_link_action(p))); } else { @@ -3652,7 +3667,7 @@ void show_node_wrapup_pdf(int p) print_mark(pdf_action_tokens(pdf_link_action(p))); break; case pdf_action_thread: - if (pdf_action_named_id(pdf_link_action(p)) > 0) { + if (pdf_action_named_id(pdf_link_action(p)) & 1) { tprint(" thread name"); print_mark(pdf_action_id(pdf_link_action(p))); } else { diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.h b/Build/source/texk/web2c/luatexdir/tex/texnodes.h index 9742ca4966c..a5549deb963 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texnodes.h +++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.h @@ -949,12 +949,13 @@ typedef enum { # define pdf_action_size 6 # define pdf_action_type(a) vlink((a)+2) /* enum pdf_action_type */ -# define pdf_action_named_id(a) vinfo((a)+2) /* boolean */ +# define pdf_action_named_id(a) vinfo((a)+2) /* bitset of two booleans */ # define pdf_action_id(a) vlink((a)+3) /* number or toks */ # define pdf_action_file(a) vinfo((a)+3) /* toks */ # define pdf_action_new_window(a) vlink((a)+4) /* enum pdf_window_type */ # define pdf_action_tokens(a) vinfo((a)+4) /* toks */ # define pdf_action_refcount(a) vlink((a)+5) /* number */ +# define pdf_action_struct_id(a) vinfo((a)+5) /* number or toks */ typedef enum { colorstack_set = 0, diff --git a/Build/source/texk/web2c/luatexdir/tex/textoken.c b/Build/source/texk/web2c/luatexdir/tex/textoken.c index e28626bbd26..10a9f80e9fe 100644 --- a/Build/source/texk/web2c/luatexdir/tex/textoken.c +++ b/Build/source/texk/web2c/luatexdir/tex/textoken.c @@ -3469,6 +3469,8 @@ void read_toks(int n, halfword r, halfword j) n = -1; } } else { + /*tex initialize limit to avoid printing some garbage. */ + ilimit=0; fatal_error ("*** (cannot \\read from terminal in nonstop modes)"); } -- cgit v1.2.3