summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/luametatex/build.sh15
-rw-r--r--source/luametatex/source/lua/lmtfontlib.c4
-rw-r--r--source/luametatex/source/lua/lmtinterface.h1
-rw-r--r--source/luametatex/source/lua/lmtnodelib.c22
-rw-r--r--source/luametatex/source/lua/lmttexlib.c37
-rw-r--r--source/luametatex/source/luacore/lua54/src/ldo.c14
-rw-r--r--source/luametatex/source/luacore/lua54/src/lopcodes.h2
-rw-r--r--source/luametatex/source/luacore/lua54/src/loslib.c21
-rw-r--r--source/luametatex/source/luacore/lua54/src/ltable.c2
-rw-r--r--source/luametatex/source/luacore/lua54/src/lvm.c4
-rw-r--r--source/luametatex/source/luametatex.h6
-rw-r--r--source/luametatex/source/tex/texexpand.c3
-rw-r--r--source/luametatex/source/tex/texfont.h34
-rw-r--r--source/luametatex/source/tex/texmath.c190
-rw-r--r--source/luametatex/source/tex/texmlist.c83
-rw-r--r--source/luametatex/source/tex/texnodes.h10
16 files changed, 200 insertions, 248 deletions
diff --git a/source/luametatex/build.sh b/source/luametatex/build.sh
index 56ed63497..2f5514316 100644
--- a/source/luametatex/build.sh
+++ b/source/luametatex/build.sh
@@ -15,6 +15,13 @@
# mtxrun.lua (latest version)
# context.lua (latest version)
+#NINJA=$(which ninja);
+#if (NINJA) then
+# NINJA="-G Ninja"
+#else
+ NINJA=""
+#fi
+
if [ "$1" = "mingw-64" ] || [ "$1" = "mingw64" ] || [ "$1" = "mingw" ] || [ "$1" == "--mingw64" ]
then
@@ -22,7 +29,7 @@ then
SUFFIX=".exe"
mkdir -p build/mingw-64
cd build/mingw-64
- cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=./cmake/mingw-64.cmake ../..
+ cmake $NINJA -DCMAKE_TOOLCHAIN_FILE=./cmake/mingw-64.cmake ../..
elif [ "$1" = "mingw-32" ] || [ "$1" = "mingw32" ] || [ "$1" == "--mingw32" ]
then
@@ -31,7 +38,7 @@ then
SUFFIX=".exe"
mkdir -p build/mingw-32
cd build/mingw-32
- cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=./cmake/mingw-32.cmake ../..
+ cmake $NINJA -DCMAKE_TOOLCHAIN_FILE=./cmake/mingw-32.cmake ../..
elif [ "$1" = "mingw-64-ucrt" ] || [ "$1" = "mingw64ucrt" ] || [ "$1" = "--mingw64ucrt" ] || [ "$1" = "ucrt" ] || [ "$1" = "--ucrt" ]
then
@@ -40,7 +47,7 @@ then
SUFFIX=".exe"
mkdir -p build/mingw-64-ucrt
cd build/mingw-64-ucrt
- cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=./cmake/mingw-64-ucrt.cmake ../..
+ cmake $NINJA -DCMAKE_TOOLCHAIN_FILE=./cmake/mingw-64-ucrt.cmake ../..
else
@@ -48,7 +55,7 @@ else
SUFFIX=" "
mkdir -p build/native
cd build/native
- cmake -G Ninja ../..
+ cmake $NINJA ../..
fi
diff --git a/source/luametatex/source/lua/lmtfontlib.c b/source/luametatex/source/lua/lmtfontlib.c
index b2982cc49..9850d59e7 100644
--- a/source/luametatex/source/lua/lmtfontlib.c
+++ b/source/luametatex/source/lua/lmtfontlib.c
@@ -313,6 +313,10 @@ static void fontlib_aux_font_char_from_lua(lua_State *L, halfword f, int i, int
set_charinfo_tag(co, inner_left_tag);
} else if (lua_key_eq(starget, right)) {
set_charinfo_tag(co, inner_right_tag);
+ } else if (lua_key_eq(starget, top)) {
+ set_charinfo_tag(co, inner_top_tag);
+ } else if (lua_key_eq(starget, bottom)) {
+ set_charinfo_tag(co, inner_bottom_tag);
}
set_numeric_field_by_index(target, innerxoffset, INT_MIN);
set_charinfo_inner_x_offset(co, target);
diff --git a/source/luametatex/source/lua/lmtinterface.h b/source/luametatex/source/lua/lmtinterface.h
index 26481d075..d98b55294 100644
--- a/source/luametatex/source/lua/lmtinterface.h
+++ b/source/luametatex/source/lua/lmtinterface.h
@@ -517,6 +517,7 @@ make_lua_key(L, catalog);\
make_lua_key(L, catcode_table);\
make_lua_key(L, category);\
make_lua_key(L, cell);\
+make_lua_key(L, center);\
make_lua_key(L, char);\
make_lua_key(L, char_given);\
make_lua_key(L, char_number);\
diff --git a/source/luametatex/source/lua/lmtnodelib.c b/source/luametatex/source/lua/lmtnodelib.c
index 997115267..d4a325c21 100644
--- a/source/luametatex/source/lua/lmtnodelib.c
+++ b/source/luametatex/source/lua/lmtnodelib.c
@@ -8243,7 +8243,7 @@ static int nodelib_direct_currentattributes(lua_State* L)
/* node.direct.todirect */
-static int nodelib_direct_todirect(lua_State* L)
+static int nodelib_shared_todirect(lua_State* L)
{
if (lua_type(L, 1) != LUA_TNUMBER) {
/* assume node, no further testing, used in known situations */
@@ -8271,7 +8271,7 @@ static int nodelib_direct_tovaliddirect(lua_State* L)
/* node.direct.tonode */
-static int nodelib_direct_tonode(lua_State* L)
+static int nodelib_shared_tonode(lua_State* L)
{
halfword n = nodelib_valid_direct_from_index(L, 1);
if (n) {
@@ -9882,8 +9882,6 @@ static const struct luaL_Reg nodelib_direct_function_list[] = {
{ "slide", nodelib_direct_slide },
{ "startofpar", nodelib_direct_startofpar },
{ "tail", nodelib_direct_tail },
- { "todirect", nodelib_direct_todirect },
- { "tonode", nodelib_direct_tonode },
{ "tostring", nodelib_direct_tostring },
{ "tovaliddirect", nodelib_direct_tovaliddirect },
{ "traverse", nodelib_direct_traverse },
@@ -9911,6 +9909,8 @@ static const struct luaL_Reg nodelib_direct_function_list[] = {
{ "setspeciallist", nodelib_direct_setspeciallist },
{ "isspeciallist", nodelib_direct_isspeciallist },
{ "getusedattributes", nodelib_direct_getusedattributes },
+ { "show", nodelib_direct_show },
+ { "serialized", nodelib_direct_serialized },
/* dual node and direct */
{ "type", nodelib_hybrid_type },
{ "types", nodelib_shared_types },
@@ -9918,10 +9918,10 @@ static const struct luaL_Reg nodelib_direct_function_list[] = {
{ "subtypes", nodelib_shared_subtypes },
{ "values", nodelib_shared_values },
{ "id", nodelib_shared_id },
- { "show", nodelib_direct_show },
- { "gluetostring", nodelib_hybrid_gluetostring },
- { "serialized", nodelib_direct_serialized },
{ "getcachestate", nodelib_shared_getcachestate },
+ { "todirect", nodelib_shared_todirect },
+ { "tonode", nodelib_shared_tonode },
+ { "gluetostring", nodelib_hybrid_gluetostring },
{ NULL, NULL },
};
@@ -9959,6 +9959,8 @@ static const struct luaL_Reg nodelib_function_list[] = {
{ "insertafter", nodelib_userdata_insertafter },
{ "insertbefore", nodelib_userdata_insertbefore },
{ "remove", nodelib_userdata_remove },
+ { "show", nodelib_userdata_show },
+ { "serialized", nodelib_userdata_serialized },
/* shared between userdata and direct */
{ "type", nodelib_hybrid_type },
{ "types", nodelib_shared_types },
@@ -9966,10 +9968,10 @@ static const struct luaL_Reg nodelib_function_list[] = {
{ "subtypes", nodelib_shared_subtypes },
{ "values", nodelib_shared_values },
{ "id", nodelib_shared_id },
- { "show", nodelib_userdata_show },
- { "gluetostring", nodelib_hybrid_gluetostring },
- { "serialized", nodelib_userdata_serialized },
{ "getcachestate", nodelib_shared_getcachestate },
+ { "todirect", nodelib_shared_todirect },
+ { "tonode", nodelib_shared_tonode },
+ { "gluetostring", nodelib_hybrid_gluetostring },
{ NULL, NULL },
};
diff --git a/source/luametatex/source/lua/lmttexlib.c b/source/luametatex/source/lua/lmttexlib.c
index 38c8e3fa8..0ce5bfd08 100644
--- a/source/luametatex/source/lua/lmttexlib.c
+++ b/source/luametatex/source/lua/lmttexlib.c
@@ -4829,7 +4829,7 @@ static int texlib_getglyphoptionvalues(lua_State *L)
static int texlib_getnoadoptionvalues(lua_State *L)
{
- lua_createtable(L, 2, 34);
+ lua_createtable(L, 2, 36);
lua_push_key_at_index(L, axis, noad_option_axis);
lua_push_key_at_index(L, noaxis, noad_option_no_axis);
lua_push_key_at_index(L, exact, noad_option_exact);
@@ -4866,6 +4866,9 @@ static int texlib_getnoadoptionvalues(lua_State *L)
lua_push_key_at_index(L, fixedsuperorsubscript, noad_option_fixed_super_or_sub_script);
lua_push_key_at_index(L, fixedsuperandsubscript, noad_option_fixed_super_and_sub_script);
lua_push_key_at_index(L, autobase, noad_option_auto_base);
+ lua_push_key_at_index(L, shrink, noad_option_shrink);
+ lua_push_key_at_index(L, stretch, noad_option_stretch);
+ lua_push_key_at_index(L, center, noad_option_center);
return 1;
}
@@ -5090,21 +5093,23 @@ static int texlib_getkerneloptionvalues(lua_State *L)
static int texlib_getcharactertagvalues(lua_State *L)
{
lua_createtable(L, 2, 12);
- lua_set_string_by_index(L, no_tag, "normal");
- lua_set_string_by_index(L, ligatures_tag, "ligatures");
- lua_set_string_by_index(L, kerns_tag, "kerns");
- lua_set_string_by_index(L, list_tag, "list");
- lua_set_string_by_index(L, callback_tag, "callback");
- lua_set_string_by_index(L, extensible_tag, "extensible");
- lua_set_string_by_index(L, horizontal_tag, "horizontal");
- lua_set_string_by_index(L, vertical_tag, "vertical");
- lua_set_string_by_index(L, extend_last_tag, "extendlast");
- lua_set_string_by_index(L, inner_left_tag, "innerleft");
- lua_set_string_by_index(L, inner_right_tag, "innerright");
- lua_set_string_by_index(L, italic_tag, "italic");
- lua_set_string_by_index(L, n_ary_tag, "nary");
- lua_set_string_by_index(L, radical_tag, "radical");
- lua_set_string_by_index(L, punctuation_tag, "punctuation");
+ lua_set_string_by_index(L, no_tag, "normal");
+ lua_set_string_by_index(L, ligatures_tag, "ligatures");
+ lua_set_string_by_index(L, kerns_tag, "kerns");
+ lua_set_string_by_index(L, list_tag, "list");
+ lua_set_string_by_index(L, callback_tag, "callback");
+ lua_set_string_by_index(L, extensible_tag, "extensible");
+ lua_set_string_by_index(L, horizontal_tag, "horizontal");
+ lua_set_string_by_index(L, vertical_tag, "vertical");
+ lua_set_string_by_index(L, inner_left_tag, "innerleft");
+ lua_set_string_by_index(L, inner_right_tag, "innerright");
+ lua_set_string_by_index(L, inner_top_tag, "innertop");
+ lua_set_string_by_index(L, inner_bottom_tag, "innerbottom");
+ lua_set_string_by_index(L, extend_last_tag, "extendlast");
+ lua_set_string_by_index(L, italic_tag, "italic");
+ lua_set_string_by_index(L, n_ary_tag, "nary");
+ lua_set_string_by_index(L, radical_tag, "radical");
+ lua_set_string_by_index(L, punctuation_tag, "punctuation");
return 1;
}
diff --git a/source/luametatex/source/luacore/lua54/src/ldo.c b/source/luametatex/source/luacore/lua54/src/ldo.c
index c30cde76f..2a0017ca6 100644
--- a/source/luametatex/source/luacore/lua54/src/ldo.c
+++ b/source/luametatex/source/luacore/lua54/src/ldo.c
@@ -299,17 +299,13 @@ static int stackinuse (lua_State *L) {
*/
void luaD_shrinkstack (lua_State *L) {
int inuse = stackinuse(L);
- int nsize = inuse * 2; /* proposed new size */
- int max = inuse * 3; /* maximum "reasonable" size */
- if (max > LUAI_MAXSTACK) {
- max = LUAI_MAXSTACK; /* respect stack limit */
- if (nsize > LUAI_MAXSTACK)
- nsize = LUAI_MAXSTACK;
- }
+ int max = (inuse > LUAI_MAXSTACK / 3) ? LUAI_MAXSTACK : inuse * 3;
/* if thread is currently not handling a stack overflow and its
size is larger than maximum "reasonable" size, shrink it */
- if (inuse <= LUAI_MAXSTACK && stacksize(L) > max)
+ if (inuse <= LUAI_MAXSTACK && stacksize(L) > max) {
+ int nsize = (inuse > LUAI_MAXSTACK / 2) ? LUAI_MAXSTACK : inuse * 2;
luaD_reallocstack(L, nsize, 0); /* ok if that fails */
+ }
else /* don't change stack */
condmovestack(L,{},{}); /* (change only for debugging) */
luaE_shrinkCI(L); /* shrink CI list */
@@ -629,7 +625,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
** check the stack before doing anything else. 'luaD_precall' already
** does that.
*/
-l_sinline void ccall (lua_State *L, StkId func, int nResults, int inc) {
+l_sinline void ccall (lua_State *L, StkId func, int nResults, l_uint32 inc) {
CallInfo *ci;
L->nCcalls += inc;
if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) {
diff --git a/source/luametatex/source/luacore/lua54/src/lopcodes.h b/source/luametatex/source/luacore/lua54/src/lopcodes.h
index 7c2745159..4c5514539 100644
--- a/source/luametatex/source/luacore/lua54/src/lopcodes.h
+++ b/source/luametatex/source/luacore/lua54/src/lopcodes.h
@@ -21,7 +21,7 @@ iABC C(8) | B(8) |k| A(8) | Op(7) |
iABx Bx(17) | A(8) | Op(7) |
iAsBx sBx (signed)(17) | A(8) | Op(7) |
iAx Ax(25) | Op(7) |
-isJ sJ(25) | Op(7) |
+isJ sJ (signed)(25) | Op(7) |
A signed argument is represented in excess K: the represented value is
the written unsigned value minus K, where K is half the maximum for the
diff --git a/source/luametatex/source/luacore/lua54/src/loslib.c b/source/luametatex/source/luacore/lua54/src/loslib.c
index 89ac06bc4..ad5a92768 100644
--- a/source/luametatex/source/luacore/lua54/src/loslib.c
+++ b/source/luametatex/source/luacore/lua54/src/loslib.c
@@ -30,23 +30,14 @@
*/
#if !defined(LUA_STRFTIMEOPTIONS) /* { */
-/* options for ANSI C 89 (only 1-char options) */
-#define L_STRFTIMEC89 "aAbBcdHIjmMpSUwWxXyYZ%"
-
-/* options for ISO C 99 and POSIX */
-#define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \
- "||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" /* two-char options */
-
-/* options for Windows */
-#define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \
- "||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y" /* two-char options */
-
#if defined(LUA_USE_WINDOWS)
-#define LUA_STRFTIMEOPTIONS L_STRFTIMEWIN
-#elif defined(LUA_USE_C89)
-#define LUA_STRFTIMEOPTIONS L_STRFTIMEC89
+#define LUA_STRFTIMEOPTIONS "aAbBcdHIjmMpSUwWxXyYzZ%" \
+ "||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y" /* two-char options */
+#elif defined(LUA_USE_C89) /* ANSI C 89 (only 1-char options) */
+#define LUA_STRFTIMEOPTIONS "aAbBcdHIjmMpSUwWxXyYZ%"
#else /* C99 specification */
-#define LUA_STRFTIMEOPTIONS L_STRFTIMEC99
+#define LUA_STRFTIMEOPTIONS "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \
+ "||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" /* two-char options */
#endif
#endif /* } */
diff --git a/source/luametatex/source/luacore/lua54/src/ltable.c b/source/luametatex/source/luacore/lua54/src/ltable.c
index cc7993e08..3c690c5f1 100644
--- a/source/luametatex/source/luacore/lua54/src/ltable.c
+++ b/source/luametatex/source/luacore/lua54/src/ltable.c
@@ -257,10 +257,12 @@ LUAI_FUNC unsigned int luaH_realasize (const Table *t) {
size |= (size >> 2);
size |= (size >> 4);
size |= (size >> 8);
+#if (UINT_MAX >> 14) > 3 /* unsigned int has more than 16 bits */
size |= (size >> 16);
#if (UINT_MAX >> 30) > 3
size |= (size >> 32); /* unsigned int has more than 32 bits */
#endif
+#endif
size++;
lua_assert(ispow2(size) && size/2 < t->alimit && t->alimit < size);
return size;
diff --git a/source/luametatex/source/luacore/lua54/src/lvm.c b/source/luametatex/source/luacore/lua54/src/lvm.c
index 2e84dc63c..8493a770c 100644
--- a/source/luametatex/source/luacore/lua54/src/lvm.c
+++ b/source/luametatex/source/luacore/lua54/src/lvm.c
@@ -1410,6 +1410,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
vmbreak;
}
vmcase(OP_MODK) {
+ savestate(L, ci); /* in case of division by 0 */
op_arithK(L, luaV_mod, luaV_modf);
vmbreak;
}
@@ -1422,6 +1423,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
vmbreak;
}
vmcase(OP_IDIVK) {
+ savestate(L, ci); /* in case of division by 0 */
op_arithK(L, luaV_idiv, luai_numidiv);
vmbreak;
}
@@ -1470,6 +1472,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
vmbreak;
}
vmcase(OP_MOD) {
+ savestate(L, ci); /* in case of division by 0 */
op_arith(L, luaV_mod, luaV_modf);
vmbreak;
}
@@ -1482,6 +1485,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
vmbreak;
}
vmcase(OP_IDIV) { /* floor division */
+ savestate(L, ci); /* in case of division by 0 */
op_arith(L, luaV_idiv, luai_numidiv);
vmbreak;
}
diff --git a/source/luametatex/source/luametatex.h b/source/luametatex/source/luametatex.h
index 4d79c6cf2..05c40321d 100644
--- a/source/luametatex/source/luametatex.h
+++ b/source/luametatex/source/luametatex.h
@@ -90,9 +90,9 @@
# include "tex/textypes.h"
# define luametatex_version 210
-# define luametatex_revision 07
-# define luametatex_version_string "2.10.07"
-# define luametatex_development_id 20230306
+# define luametatex_revision 8
+# define luametatex_version_string "2.10.08"
+# define luametatex_development_id 20230320
# define luametatex_name_camelcase "LuaMetaTeX"
# define luametatex_name_lowercase "luametatex"
diff --git a/source/luametatex/source/tex/texexpand.c b/source/luametatex/source/tex/texexpand.c
index 6cf887bea..706972bfe 100644
--- a/source/luametatex/source/tex/texexpand.c
+++ b/source/luametatex/source/tex/texexpand.c
@@ -550,7 +550,8 @@ void tex_expand_current_token(void)
/*tex Complain about an undefined macro */
tex_handle_error(
normal_error_type,
- "Undefined control sequence %m", cur_cs,
+ // "Undefined control sequence %m", cur_cs,
+ "Undefined control sequence",
"The control sequence at the end of the top line of your error message was never\n"
"\\def'ed. You can just continue as I'll forget about whatever was undefined."
);
diff --git a/source/luametatex/source/tex/texfont.h b/source/luametatex/source/tex/texfont.h
index 947cdf446..0d3fa9fb3 100644
--- a/source/luametatex/source/tex/texfont.h
+++ b/source/luametatex/source/tex/texfont.h
@@ -465,21 +465,23 @@ extern int tex_get_math_char (halfword f, int c, int size, scaled *scal
*/
typedef enum char_tag_codes {
- no_tag = 0x0000, /*tex vanilla character */
- ligatures_tag = 0x0001, /*tex character has a ligature program, not used */
- kerns_tag = 0x0002, /*tex character has a kerning program, not used */
- list_tag = 0x0004, /*tex character has a successor in a charlist */
- callback_tag = 0x0010,
- extensible_tag = 0x0020, /*tex character is extensible, we can unset it in order to block */
- horizontal_tag = 0x0040, /*tex horizontal extensible */
- vertical_tag = 0x0080, /*tex vertical extensible */
- extend_last_tag = 0x0100, /*tex auto scale last variant */
- inner_left_tag = 0x0200, /*tex anchoring */
- inner_right_tag = 0x0400, /*tex anchoring */
- italic_tag = 0x0800,
- n_ary_tag = 0x1000,
- radical_tag = 0x2000,
- punctuation_tag = 0x4000,
+ no_tag = 0x00000, /*tex vanilla character */
+ ligatures_tag = 0x00001, /*tex character has a ligature program, not used */
+ kerns_tag = 0x00002, /*tex character has a kerning program, not used */
+ list_tag = 0x00004, /*tex character has a successor in a charlist */
+ callback_tag = 0x00010,
+ extensible_tag = 0x00020, /*tex character is extensible, we can unset it in order to block */
+ horizontal_tag = 0x00040, /*tex horizontal extensible */
+ vertical_tag = 0x00080, /*tex vertical extensible */
+ inner_left_tag = 0x00100, /*tex anchoring */
+ inner_right_tag = 0x00200, /*tex anchoring */
+ inner_top_tag = 0x00400, /*tex anchoring */
+ inner_bottom_tag = 0x00800, /*tex anchoring */
+ extend_last_tag = 0x01000, /*tex auto scale last variant */
+ italic_tag = 0x02000,
+ n_ary_tag = 0x04000,
+ radical_tag = 0x08000,
+ punctuation_tag = 0x10000,
} char_tag_codes;
/*tex
@@ -597,8 +599,6 @@ extern scaled tex_char_top_margin_from_font (halfword f, halfword c)
extern scaled tex_char_bottom_margin_from_font (halfword f, halfword c);
extern scaled tex_char_top_overshoot_from_font (halfword f, halfword c);
extern scaled tex_char_bottom_overshoot_from_font (halfword f, halfword c);
-extern scaled tex_char_inner_x_offset_from_font (halfword f, halfword c);
-extern scaled tex_char_inner_y_offset_from_font (halfword f, halfword c);
extern extinfo *tex_char_extensible_recipe_from_font (halfword f, halfword c);
extern halfword tex_char_unchecked_top_anchor_from_font (halfword f, halfword c);
diff --git a/source/luametatex/source/tex/texmath.c b/source/luametatex/source/tex/texmath.c
index 01db082b2..0e52f7c70 100644
--- a/source/luametatex/source/tex/texmath.c
+++ b/source/luametatex/source/tex/texmath.c
@@ -2672,37 +2672,49 @@ void tex_run_math_radical(void)
attrlist = tex_scan_attribute(attrlist);
}
break;
- case 'e': case 'E':
- if (tex_scan_mandate_keyword("exact", 1)) {
- options = options | noad_option_exact;
- }
- break;
case 'b': case 'B':
if (tex_scan_mandate_keyword("bottom", 1)) {
bottom = 1;
}
break;
+ case 'e': case 'E':
+ if (tex_scan_mandate_keyword("exact", 1)) {
+ options = options | noad_option_exact;
+ }
+ break;
case 't': case 'T':
if (tex_scan_mandate_keyword("top", 1)) {
top = 1;
}
break;
case 's': case 'S':
- switch (tex_scan_character("itoITO", 0, 0, 0)) {
+ switch (tex_scan_character("hitoHITO", 0, 0, 0)) {
case 't': case 'T':
- if (tex_scan_mandate_keyword("style", 2)) {
- switch (code) {
- case normal_radical_subtype:
- case radical_radical_subtype:
- case root_radical_subtype:
- case rooted_radical_subtype:
- case delimited_radical_subtype:
- style = tex_scan_math_style_identifier(1, 0);
- break;
- default:
- /* ignore */
- break;
- }
+ switch (tex_scan_character("ryRY", 0, 0, 0)) {
+ case 'y': case 'Y':
+ if (tex_scan_mandate_keyword("style", 3)) {
+ switch (code) {
+ case normal_radical_subtype:
+ case radical_radical_subtype:
+ case root_radical_subtype:
+ case rooted_radical_subtype:
+ case delimited_radical_subtype:
+ style = tex_scan_math_style_identifier(1, 0);
+ break;
+ default:
+ /* ignore */
+ break;
+ }
+ }
+ break;
+ case 'r': case 'R':
+ if (tex_scan_mandate_keyword("stretch", 3)) {
+ options = options | noad_option_stretch;
+ }
+ break;
+ default:
+ tex_aux_show_keyword_error("style|stretch");
+ goto DONE;
}
break;
case 'o': case 'O':
@@ -2715,8 +2727,13 @@ void tex_run_math_radical(void)
radical_size(radical) = tex_scan_int(0, NULL);
}
break;
+ case 'h': case 'H':
+ if (tex_scan_mandate_keyword("shrink", 2)) {
+ options = options | noad_option_shrink;
+ }
+ break;
default:
- tex_aux_show_keyword_error("style|source");
+ tex_aux_show_keyword_error("style|source|stretch|shrink");
goto DONE;
}
break;
@@ -2898,132 +2915,6 @@ void tex_finish_math_radical(void)
}
}
-// void tex_run_math_accent(void)
-// {
-// mathcodeval t = tex_no_math_code();
-// mathcodeval b = tex_no_math_code();
-// mathcodeval o = tex_no_math_code();
-// halfword code = cur_chr;
-// halfword accent = tex_new_node(accent_noad, bothflexible_accent_subtype);
-// quarterword subtype = ordinary_noad_subtype;
-// halfword attrlist = null;
-// if (cur_cmd == accent_cmd) {
-// tex_handle_error(
-// normal_error_type,
-// "Please use \\mathaccent for accents in math mode",
-// "I'm changing \\accent to \\mathaccent here; wish me luck. (Accents are not the\n"
-// "same in formulas as they are in text.)" );
-// }
-// tex_tail_append(accent);
-// switch (code) {
-// case math_accent_code:
-// /*tex |\mathaccent| */
-// t = tex_scan_mathchar(tex_mathcode);
-// break;
-// case math_uaccent_code:
-// /*tex |\Umathaccent| */
-// while (1) {
-// switch (tex_scan_character("abnsfABNSF", 0, 1, 0)) {
-// case 'a': case 'A':
-// if (tex_scan_mandate_keyword("attr", 1)) {
-// attrlist = tex_scan_attribute(attrlist);
-// }
-// break;
-// case 's': case 'S':
-// if (tex_scan_mandate_keyword("source", 1)) {
-// noad_source(accent) = tex_scan_int(0, NULL);
-// }
-// break;
-// case 'f': case 'F':
-// if (tex_scan_mandate_keyword("fraction", 1)) {
-// accent_fraction(accent) = tex_scan_int(0, NULL);
-// }
-// break;
-// case 'n': case 'N':
-// if (tex_scan_mandate_keyword("nooverflow", 1)) {
-// /*tex
-// Actually there never is an overflow but for consistency we do
-// accept this key. Mayebe in the future it will be used.
-// */
-// noad_options(accent) |= noad_option_no_overflow;
-// }
-// break;
-// case 'b': case 'B':
-// if (tex_scan_mandate_keyword("base", 1)) {
-// noad_options(accent) |= noad_option_auto_base;
-// }
-// break;
-// default:
-// goto DONE;
-// }
-// }
-// DONE:
-// /* todo: integrate in the above */
-// if (tex_scan_keyword("fixed")) {
-// /*tex top */
-// node_subtype(accent) = fixedtop_accent_subtype;
-// t = tex_scan_mathchar(umath_mathcode);
-// } else if (tex_scan_keyword("both")) {
-// /*tex top bottom */
-// if (tex_scan_keyword("fixed")) {
-// node_subtype(accent) = fixedtop_accent_subtype;
-// }
-// t = tex_scan_mathchar(umath_mathcode);
-// if (tex_scan_keyword("fixed")) {
-// node_subtype(accent) = fixedboth_accent_subtype;
-// }
-// b = tex_scan_mathchar(umath_mathcode);
-// } else if (tex_scan_keyword("bottom")) {
-// /*tex bottom */
-// if (tex_scan_keyword("fixed")) {
-// node_subtype(accent) = fixedbottom_accent_subtype;
-// }
-// b = tex_scan_mathchar(umath_mathcode);
-// } else if (tex_scan_keyword("top")) {
-// /*tex top */
-// if (tex_scan_keyword("fixed")) {
-// node_subtype(accent) = fixedtop_accent_subtype;
-// }
-// t = tex_scan_mathchar(umath_mathcode);
-// } else if (tex_scan_keyword("overlay")) {
-// /* overlay */
-// if (tex_scan_keyword("fixed")) {
-// node_subtype(accent) = fixedtop_accent_subtype;
-// }
-// o = tex_scan_mathchar(umath_mathcode);
-// } else {
-// /*tex top */
-// t = tex_scan_mathchar(umath_mathcode);
-// }
-// break;
-// default:
-// tex_confusion("scan math accent");
-// }
-// if (attrlist) {
-// tex_attach_attribute_list_attribute(accent, attrlist);
-// }
-// if (! (t.character_value == 0 && t.family_value == 0)) {
-// halfword n = tex_new_node(math_char_node, 0);
-// subtype = tex_aux_set_math_char(n, &t, NULL);
-// accent_top_character(accent) = n;
-// }
-// if (! (b.character_value == 0 && b.family_value == 0)) {
-// halfword n = tex_new_node(math_char_node, 0);
-// subtype = tex_aux_set_math_char(n, &b, NULL);
-// accent_bottom_character(accent) = n;
-// }
-// if (! (o.character_value == 0 && o.family_value == 0)) {
-// halfword n = tex_new_node(math_char_node, 0);
-// subtype = tex_aux_set_math_char(n, &o, NULL);
-// accent_middle_character(accent) = n;
-// }
-// {
-// halfword n = tex_new_node(math_char_node, subtype);
-// noad_nucleus(accent) = n;
-// tex_aux_scan_math(n, tex_math_style_variant(cur_list.math_style, math_parameter_accent_variant), 0, 0, 0, 0, unset_noad_class, unset_noad_class);
-// }
-// }
-
void tex_run_math_accent(void)
{
mathcodeval t = tex_no_math_code();
@@ -3049,12 +2940,17 @@ void tex_run_math_accent(void)
case math_uaccent_code:
/*tex |\Umathaccent| */
while (1) {
- switch (tex_scan_character("abnsftoABNSFTO", 0, 1, 0)) {
+ switch (tex_scan_character("abcnsftoABCNSFTO", 0, 1, 0)) {
case 'a': case 'A':
if (tex_scan_mandate_keyword("attr", 1)) {
attrlist = tex_scan_attribute(attrlist);
}
break;
+ case 'c': case 'C':
+ if (tex_scan_mandate_keyword("center", 1)) {
+ noad_options(accent) |= noad_option_center;
+ }
+ break;
case 's': case 'S':
if (tex_scan_mandate_keyword("source", 1)) {
noad_source(accent) = tex_scan_int(0, NULL);
diff --git a/source/luametatex/source/tex/texmlist.c b/source/luametatex/source/tex/texmlist.c
index 56b780506..3b7734ccf 100644
--- a/source/luametatex/source/tex/texmlist.c
+++ b/source/luametatex/source/tex/texmlist.c
@@ -861,7 +861,7 @@ static halfword tex_aux_underbar(halfword box, scaled gap, scaled height, scaled
*/
-static halfword tex_aux_char_box(halfword fnt, int chr, halfword att, scaled *ic, quarterword subtype, scaled target, int style)
+static halfword tex_aux_char_box(halfword fnt, int chr, halfword att, scaled *ic, quarterword subtype, scaled target, int style, int shrink, int stretch)
{
/*tex The new box and its character node. */
halfword glyph = tex_aux_new_math_glyph(fnt, chr, subtype);
@@ -876,7 +876,7 @@ static halfword tex_aux_char_box(halfword fnt, int chr, halfword att, scaled *ic
if (tex_has_glyph_option(glyph, glyph_option_no_italic_correction)) {
whd.ic = 0;
}
- if (whd.ic) {
+ if (! (stretch || shrink) && whd.ic) {
if (ic) {
*ic = whd.ic; /* also in open type? needs checking */
}
@@ -889,12 +889,19 @@ static halfword tex_aux_char_box(halfword fnt, int chr, halfword att, scaled *ic
} else if (ic) {
*ic = 0;
}
- if (target && whd.wd > 0 && whd.wd < target && tex_aux_math_engine_control(fnt, math_control_extend_accents) && tex_char_has_tag_from_font(fnt, chr, extend_last_tag)) {
- scaled margin = tex_get_math_x_parameter_default(style, math_parameter_accent_extend_margin, 0);
- scaled amount = target - 2 * margin;
- if (amount > 0) {
- glyph_x_scale(glyph) = lround((double) glyph_x_scale(glyph) * amount/whd.wd);
- glyph_x_offset(glyph) = (whd.wd - amount)/2;
+ if (target && whd.wd > 0) {
+ if (whd.wd < target && tex_aux_math_engine_control(fnt, math_control_extend_accents) && tex_char_has_tag_from_font(fnt, chr, extend_last_tag)) {
+ scaled margin = tex_get_math_x_parameter_default(style, math_parameter_accent_extend_margin, 0);
+ scaled amount = target - 2 * margin;
+ if (amount > 0) {
+ glyph_x_scale(glyph) = lround((double) glyph_x_scale(glyph) * amount/whd.wd);
+ glyph_x_offset(glyph) = (whd.wd - amount)/2;
+ }
+ return box;
+ }
+ if ((shrink && (whd.wd > target)) || (stretch && (whd.wd < target))) {
+ glyph_x_scale(glyph) = lround((double) glyph_x_scale(glyph) * target/whd.wd);
+ glyph_x_offset(glyph) = (whd.wd - target)/2;
}
}
return box;
@@ -1384,6 +1391,8 @@ static halfword tex_aux_make_delimiter(halfword target, halfword delimiter, int
/*tex are we trying the large variant? */
int large_attempt = 0;
int do_parts = 0;
+ int shrink = flat && tex_has_noad_option(target, noad_option_shrink);
+ int stretch = flat && tex_has_noad_option(target, noad_option_stretch);
/*tex to save the current attribute list */
halfword att = null;
if (extremes) {
@@ -1448,7 +1457,7 @@ static halfword tex_aux_make_delimiter(halfword target, halfword delimiter, int
if (total >= (targetsize - tolerance)) {
goto FOUND;
}
- }
+ }
if (tex_char_has_tag_from_font(curfnt, curchr, extensible_tag)) {
if (tex_char_has_tag_from_font(curfnt, curchr, horizontal_tag) || tex_char_has_tag_from_font(curfnt, curchr, vertical_tag)) {
/*tex We only check when we are explicit. */
@@ -1498,8 +1507,13 @@ static halfword tex_aux_make_delimiter(halfword target, halfword delimiter, int
*/
extinfo *ext = do_parts ? tex_char_extensible_recipe_from_font(fnt, chr) : NULL;
if (ext) {
- scaled minoverlap = flat ? tex_get_math_x_parameter_default(style, math_parameter_connector_overlap_min, 0) : tex_get_math_y_parameter_default(style, math_parameter_connector_overlap_min, 0);;
+ scaled minoverlap = flat ? tex_get_math_x_parameter_default(style, math_parameter_connector_overlap_min, 0) : tex_get_math_y_parameter_default(style, math_parameter_connector_overlap_min, 0);
result = tex_aux_get_delimiter_box(fnt, chr, targetsize, minoverlap, flat, att);
+ if (stretch && flat && (box_width(result) > targetsize)) { // threshold nooverflow
+ tex_flush_node_list(result);
+ do_parts = 0;
+ goto HERE;
+ }
if (delta) {
/*tex Not yet done: horizontal italics. */
if (tex_aux_math_engine_control(fnt, math_control_apply_vertical_italic_kern)) {
@@ -1529,7 +1543,8 @@ static halfword tex_aux_make_delimiter(halfword target, halfword delimiter, int
the traditional width (which is fake width + italic) becomes less and the delta is
added. See (**).
*/
- result = tex_aux_char_box(fnt, chr, att, delta, glyph_math_delimiter_subtype, flat ? targetsize : 0, style);
+ HERE:
+ result = tex_aux_char_box(fnt, chr, att, delta, glyph_math_delimiter_subtype, flat ? targetsize : 0, style, shrink, stretch);
if (flat) {
/* This will be done when we have a reasonable example. */
} else {
@@ -2395,12 +2410,20 @@ static void tex_aux_make_root_radical(halfword target, int style, int size, kern
}
delimiter = tex_aux_make_delimiter(target, delimiter, size, box_total(nucleus) + clearance + theta, 0, style, 1, NULL, NULL, 0, has_noad_option_nooverflow(target), &extremes, 0);
if (radical_degree(target)) {
+ halfword innerf = 0;
+ halfword innerc = 0;
if (tex_char_has_tag_from_font(extremes.bfont, extremes.bchar, inner_left_tag)) {
- innerx = tex_char_inner_x_offset_from_font(extremes.bfont, extremes.bchar);
- innery = tex_char_inner_y_offset_from_font(extremes.bfont, extremes.bchar);
+ innerf = extremes.bfont;
+ innerc = extremes.bchar;
} else if (tex_char_has_tag_from_font(extremes.tfont, extremes.tchar, inner_left_tag)) {
- innerx = tex_char_inner_x_offset_from_font(extremes.tfont, extremes.tchar);
- innery = tex_char_inner_y_offset_from_font(extremes.tfont, extremes.tchar);
+ innerf = extremes.tfont;
+ innerc = extremes.tchar;
+ }
+ if (innerc) {
+ innerx = tex_char_inner_x_offset_from_font(innerf, innerc);
+ innery = tex_char_inner_y_offset_from_font(innerf, innerc);
+ innerx = innerx == INT_MIN ? 0 : tex_aux_math_y_size_scaled(innerf, innerx, size);
+ innery = innery == INT_MIN ? 0 : tex_aux_math_y_size_scaled(innerf, innery, size);
}
}
if (companion) {
@@ -2790,7 +2813,7 @@ static void tex_aux_preroll_radical(halfword target, int style, int size)
typedef enum math_accent_location_codes {
top_accent_code = 1,
- bot_accent_code = 2,
+ bot_accent_code = 2, // todo : bottom_accent_code
overlay_accent_code = 4,
stretch_accent_code = 8, /* reserved, not yet set */
} math_accent_location_codes;
@@ -2896,6 +2919,7 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal
scaled fraction = accent_fraction(target) > 0 ? accent_fraction(target) : 1000;
scaled skew = 0;
scaled offset = 0;
+ scaled innery = 0;
halfword accent = null;
halfword base = null;
halfword result = null;
@@ -3008,7 +3032,7 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal
}
if (! accent) {
/*tex Italic gets added to width for traditional fonts (no italic anyway): */
- accent = tex_aux_char_box(accentfnt, accentchr, attrlist, NULL, glyph_math_accent_subtype, basewidth, style); // usedwidth
+ accent = tex_aux_char_box(accentfnt, accentchr, attrlist, NULL, glyph_math_accent_subtype, basewidth, style, 0, 0); // usedwidth
}
if (flags & top_accent_code) {
scaled b = tex_get_math_y_parameter(style, math_parameter_accent_base_height);
@@ -3019,7 +3043,7 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal
halfword flatchr = tex_char_flat_accent_from_font(accentfnt, accentchr);
if (flatchr != INT_MIN && flatchr != accentchr) {
tex_flush_node(accent);
- accent = tex_aux_char_box(accentfnt, flatchr, attrlist, NULL, glyph_math_accent_subtype, usedwidth, style);
+ accent = tex_aux_char_box(accentfnt, flatchr, attrlist, NULL, glyph_math_accent_subtype, usedwidth, style, 0, 0);
if (tracing_math_par >= 2) {
tex_begin_diagnostic();
tex_print_format("[math: flattening accent, old %x, new %x]", accentchr, flatchr);
@@ -3039,6 +3063,10 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal
if (u != undefined_math_parameter) {
delta -= u;
}
+ if (tex_char_has_tag_from_font(accentfnt, accentchr, inner_top_tag)) {
+ innery = tex_char_inner_y_offset_from_font(accentfnt, accentchr);
+ innery = innery == INT_MIN ? 0 : tex_aux_math_y_size_scaled(accentfnt, innery, size);
+ }
} else if (flags & bot_accent_code) {
// scaled b = tex_get_math_y_parameter(style, math_parameter_accent_base_depth, 0);
// scaled f = tex_get_math_y_parameter(style, math_parameter_flattened_accent_base_depth, 0);
@@ -3050,6 +3078,10 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal
if (l != undefined_math_parameter) {
delta += l;
}
+ if (tex_char_has_tag_from_font(accentfnt, accentchr, inner_bottom_tag)) {
+ innery = tex_char_inner_y_offset_from_font(accentfnt, accentchr);
+ innery = innery == INT_MIN ? 0 : tex_aux_math_y_size_scaled(accentfnt, innery, size);
+ }
} else { /* if (flags & overlay_accent_code) { */
/*tex Center the accent vertically around base: */
delta = tex_half_scaled(box_total(accent) + box_total(base));
@@ -3082,11 +3114,11 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal
anchor = tex_half_scaled(accentwidth);
} else {
anchor = tex_char_unchecked_top_anchor_from_font(accentfnt, accentchr); /* no bot accent key */
- if (anchor != INT_MIN) {
- anchor = tex_aux_math_y_size_scaled(accentfnt, anchor, size); /* why y and not x */
- } else {
+ if (anchor == INT_MIN || has_noad_option_center(target)) {
/*tex just take the center */
anchor = tex_half_scaled(accentwidth);
+ } else {
+ anchor = tex_aux_math_x_size_scaled(accentfnt, anchor, size);
}
}
if (math_direction_par == dir_righttoleft) {
@@ -3117,6 +3149,7 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal
accent_bot_overshoot(target) = overshoot;
}
if (flags & (top_accent_code | overlay_accent_code)) {
+ delta += innery;
if (delta) {
halfword kern = tex_new_kern_node(-delta, vertical_math_kern_subtype);
tex_attach_attribute_list_copy(kern, target);
@@ -3126,6 +3159,12 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal
tex_couple_nodes(accent, base);
}
result = accent;
+ } else if ((flags & bot_accent_code) && innery) {
+ halfword kern = tex_new_kern_node(innery, vertical_math_kern_subtype);
+ tex_attach_attribute_list_copy(kern, target);
+ tex_couple_nodes(base, kern);
+ tex_couple_nodes(kern, accent);
+ result = base;
} else {
tex_couple_nodes(base, accent);
result = base;
@@ -7107,7 +7146,7 @@ static void tex_mlist_to_hlist_finalize_list(mliststate *state)
tex_couple_nodes(p, box_list(l));
box_list(l) = null;
tex_flush_node(l);
- } else if (current_type == simple_noad && current_subtype == math_end_class) {
+ } else if (current_type == simple_noad && (current_subtype == math_end_class) || (current_subtype == math_begin_class)) {
if (noad_new_hlist(current)) {
tex_flush_node(noad_new_hlist(current));
noad_new_hlist(current) = null;
diff --git a/source/luametatex/source/tex/texnodes.h b/source/luametatex/source/tex/texnodes.h
index f3f9276a6..cb666f874 100644
--- a/source/luametatex/source/tex/texnodes.h
+++ b/source/luametatex/source/tex/texnodes.h
@@ -1788,13 +1788,16 @@ typedef enum noad_options {
# define noad_option_fixed_super_or_sub_script 0x0200000000
# define noad_option_fixed_super_and_sub_script 0x0400000000
# define noad_option_auto_base 0x0800000000
+# define noad_option_stretch 0x1000000000
+# define noad_option_shrink 0x2000000000
+# define noad_option_center 0x4000000000
# define has_option(a,b) (((a) & (b)) == (b))
# define unset_option(a,b) ((a) & ~(b))
-inline static void tex_add_noad_option (halfword a, halfword r) { noad_options(a) |= r; }
-inline static void tex_remove_noad_option (halfword a, halfword r) { noad_options(a) &= ~(r | noad_options(a)); }
-inline static int tex_has_noad_option (halfword a, halfword r) { return (noad_options(a) & r) == r; }
+inline static void tex_add_noad_option (halfword a, long long r) { noad_options(a) |= r; }
+inline static void tex_remove_noad_option (halfword a, long long r) { noad_options(a) &= ~(r | noad_options(a)); }
+inline static int tex_has_noad_option (halfword a, long long r) { return (noad_options(a) & r) == r; }
inline static int has_noad_no_script_option(halfword n, halfword option)
{
@@ -1842,6 +1845,7 @@ inline static int has_noad_no_script_option(halfword n, halfword option)
# define has_noad_option_unrolllist(a) (has_option(noad_options(a), noad_option_unroll_list))
# define has_noad_option_followedbyspace(a) (has_option(noad_options(a), noad_option_followed_by_space))
# define has_noad_option_proportional(a) (has_option(noad_options(a), noad_option_proportional))
+# define has_noad_option_center(a) (has_option(noad_options(a), noad_option_center))
# define has_noad_option_source_on_nucleus(a) (has_option(noad_options(a), noad_option_source_on_nucleus))
# define has_noad_option_fixed_super_or_sub_script(a) (has_option(noad_options(a), noad_option_fixed_super_or_sub_script))
# define has_noad_option_fixed_super_and_sub_script(a) (has_option(noad_options(a), noad_option_fixed_super_and_sub_script))