summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir
diff options
context:
space:
mode:
authorLuigi Scarso <luigi.scarso@gmail.com>2019-07-08 06:07:11 +0000
committerLuigi Scarso <luigi.scarso@gmail.com>2019-07-08 06:07:11 +0000
commitf93b62903a20648ab4328443b88495da81f70909 (patch)
tree6a870996cc04dca9a1ae3dbbc334b4c2a1385711 /Build/source/texk/web2c/luatexdir
parent54d39e16610eee4dde770b0a6b569203c79abde8 (diff)
sync with luatex rev.7174: luatex and luahbtex and jit variants
git-svn-id: svn://tug.org/texlive/trunk@51577 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir')
-rw-r--r--Build/source/texk/web2c/luatexdir/ChangeLog4
-rw-r--r--Build/source/texk/web2c/luatexdir/am/libluatex.am458
-rw-r--r--Build/source/texk/web2c/luatexdir/am/luaharfbuzz.am77
-rw-r--r--Build/source/texk/web2c/luatexdir/am/luatex.am169
-rw-r--r--Build/source/texk/web2c/luatexdir/font/luafont.c8
-rw-r--r--Build/source/texk/web2c/luatexdir/font/writecff.c1
-rw-r--r--Build/source/texk/web2c/luatexdir/font/writetype2.c1
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/limglib.c3
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/lnewtokenlib.c26
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/ltexlib.c36
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luastuff.c3
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luatex-api.h21
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/LICENSE22
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/Makefile15
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/README-win.md53
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/README.md154
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/THANKS2
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/config.ld9
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/core_types.lua.html108
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/custom_callbacks.lua.html85
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/harfbuzz_setup.lua.html231
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/ot_font_loader.lua.html139
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/package_path_searcher.lua.html104
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/index.html2829
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/ldoc.css303
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/examples/core_types.lua52
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/fixtures/AppleGothic_korean_issue_22.json1
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/fixtures/amiri-regular_123.json1
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/fixtures/amiri-regular_123_numr.json1
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/fixtures/notonastaliq_U06CC_U06C1.json1
-rwxr-xr-xBuild/source/texk/web2c/luatexdir/luaharfbuzz/fonts/Rajdhani-Regular.ttfbin0 -> 378456 bytes
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/fonts/amiri-regular.ttfbin0 -> 548016 bytes
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/fonts/amiriquran-colored.ttfbin0 -> 173108 bytes
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/fonts/notocoloremoji-subset.ttfbin0 -> 6124 bytes
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/fonts/notonastaliq.ttfbin0 -> 497204 bytes
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-1.0.0-1.rockspec51
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-scm-1.rockspec45
-rwxr-xr-xBuild/source/texk/web2c/luatexdir/luaharfbuzz/scripts/generate_harfbuzz_api_list.sh2
-rwxr-xr-xBuild/source/texk/web2c/luatexdir/luaharfbuzz/scripts/generate_hb_shape_json.sh11
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/buffer_spec.lua172
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/harfbuzz_spec.lua501
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/shaping_spec.lua157
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/harfbuzz.lua84
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/harfbuzz.luadoc535
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/blob.c60
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/buffer.c274
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/class_utils.c33
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/direction.c84
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/face.c439
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/feature.c41
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/font.c218
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/language.c49
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.c119
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.h39
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/ot.c47
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/script.c71
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/tag.c50
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/unicode.c22
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/status/done.txt42
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/status/full_api.txt303
-rw-r--r--Build/source/texk/web2c/luatexdir/luatex.c6
-rw-r--r--Build/source/texk/web2c/luatexdir/luatex_svnversion.h2
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/align.c4
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/postlinebreak.h13
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texdeffont.c44
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texfileio.c22
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texmath.c7
-rw-r--r--Build/source/texk/web2c/luatexdir/utils/utils.c14
68 files changed, 8110 insertions, 368 deletions
diff --git a/Build/source/texk/web2c/luatexdir/ChangeLog b/Build/source/texk/web2c/luatexdir/ChangeLog
index b5d13759fe3..f845f9bf463 100644
--- a/Build/source/texk/web2c/luatexdir/ChangeLog
+++ b/Build/source/texk/web2c/luatexdir/ChangeLog
@@ -1,3 +1,7 @@
+2019-07-06 Luigi Scarso <luigi.scarso@gmail.com>
+ * Integration of harfbuzz.
+ * Splitting of exe into *hbtex variants.
+
2019-02-19 Luigi Scarso <luigi.scarso@gmail.com>
* am/luatex.am ([un]install-lua[jit]tex-links) [MINGW32]:
different commands for mingw.
diff --git a/Build/source/texk/web2c/luatexdir/am/libluatex.am b/Build/source/texk/web2c/luatexdir/am/libluatex.am
index 5f7ae526c6c..8302c311143 100644
--- a/Build/source/texk/web2c/luatexdir/am/libluatex.am
+++ b/Build/source/texk/web2c/luatexdir/am/libluatex.am
@@ -3,17 +3,9 @@
## Copyright (C) 2009-2015 Peter Breitenlohner <tex-live@tug.org>
## You may freely use, modify and/or distribute this file.
-## liblua52
-##
-#LUA_INCLUDES = $(LUA52_INCLUDES) $(LUA52_DEFINES)
-#LUA_LIBS = $(LUA52_LIBS)
-#LUA_DEPEND = $(LUA52_DEPEND)
## liblua53
##
-#LUA_LUA53_INCLUDES = $(LUA53_INCLUDES) $(LUA53_DEFINES)
-#LUA_LUA53_LIBS = $(LUA53_LIBS)
-#LUA_LUA53_DEPEND = $(LUA53_DEPEND)
LUA_INCLUDES = $(LUA53_INCLUDES) $(LUA53_DEFINES)
LUA_LIBS = $(LUA53_LIBS)
LUA_DEPEND = $(LUA53_DEPEND)
@@ -23,14 +15,16 @@ LUA_DEPEND = $(LUA53_DEPEND)
## libluatex
##
-#EXTRA_LIBRARIES += libluatex.a liblua53tex.a libluajittex.a
-EXTRA_LIBRARIES += libluatex.a libluajittex.a
+EXTRA_LIBRARIES += libluatex.a libluajittex.a libluatexspecific.a libluajittexspecific.a libluahbtexspecific.a libluajithbtexspecific.a
+
-libluatex_a_DEPENDENCIES = libff.a libluamisc.a
-#liblua53tex_a_DEPENDENCIES = libff.a liblua53misc.a
-libluajittex_a_DEPENDENCIES = libff.a libluajitmisc.a
+## it's not true that luatex depends on libluaharfbuzz.a
+## but for the moment we keep it
+##
+libluatex_a_DEPENDENCIES = libff.a libluamisc.a libluaharfbuzz.a
+libluajittex_a_DEPENDENCIES = libff.a libluajitmisc.a libluajitharfbuzz.a
-libluatex_a_preflags = $(AM_CPPFLAGS) $(ZLIB_INCLUDES) $(LIBPNG_INCLUDES)
+libluatex_a_preflags = $(AM_CPPFLAGS) $(ZLIB_INCLUDES) $(LIBPNG_INCLUDES) $(HARFBUZZ_INCLUDES)
libluatex_a_preflags += -I$(srcdir)/libmd5
libluatex_a_preflags += -DpdfTeX -I$(srcdir)/luatexdir
libluatex_a_preflags += -I$(srcdir)/luatexdir/unilib
@@ -40,14 +34,18 @@ libluatex_a_preflags += -DLUA_FF_LIB=1 -I$(srcdir)/luatexdir/luafontloader/fontf
libluatex_a_preflags += -DSYNCTEX_ENGINE_H='<synctex-luatex.h>' -I$(srcdir)/synctexdir
libluatex_a_CPPFLAGS = $(libluatex_a_preflags) $(LUA_INCLUDES)
-#liblua53tex_a_CPPFLAGS = $(libluatex_a_preflags) $(LUA_LUA53_INCLUDES)
libluajittex_a_CPPFLAGS = $(libluatex_a_preflags) $(LUAJIT_INCLUDES) $(LUAJIT_DEFINES)
libluajittex_a_CPPFLAGS += -DLuajitTeX
libluatex_a_CXXFLAGS = $(WARNING_CXXFLAGS)
-#liblua53tex_a_CXXFLAGS = $(WARNING_CXXFLAGS)
libluajittex_a_CXXFLAGS = $(WARNING_CXXFLAGS)
+libluatexspecific_a_CPPFLAGS = $(libluatex_a_CPPFLAGS)
+libluajittexspecific_a_CPPFLAGS = $(libluajittex_a_CPPFLAGS)
+libluahbtexspecific_a_CPPFLAGS = -DLUATEX_HARFBUZZ_ENABLED $(libluatex_a_CPPFLAGS)
+libluajithbtexspecific_a_CPPFLAGS = -DLUATEX_HARFBUZZ_ENABLED $(libluajittex_a_CPPFLAGS)
+
+
dist_libluatex_a_SOURCES = \
luatexdir/lua/lstrlibext.c \
luatexdir/lua/helpers.c \
@@ -55,13 +53,6 @@ dist_libluatex_a_SOURCES = \
nodist_libluatex_a_SOURCES = \
$(dist_libluatex_sources) \
$(nodist_libluatex_sources)
-# dist_liblua53tex_a_SOURCES = \
-# luatexdir/lua/lstrlibext.c \
-# luatexdir/lua/helpers.c \
-# luatexdir/lua/texluac.c
-# nodist_liblua53tex_a_SOURCES = \
-# $(dist_libluatex_sources) \
-# $(nodist_libluatex_sources)
dist_libluajittex_a_SOURCES = \
luatexdir/lua/lauxlib_bridge.h \
luatexdir/lua/lstrlibext.c \
@@ -70,11 +61,81 @@ nodist_libluajittex_a_SOURCES = \
$(dist_libluatex_sources) \
$(nodist_libluatex_sources)
+
+#dist_libluatexspecific_a_SOURCES =
+nodist_libluatexspecific_a_SOURCES = \
+ $(dist_libluatexspecific_sources)
+#dist_libluajittexspecific_a_SOURCES =
+nodist_libluajittexspecific_a_SOURCES = \
+ $(dist_libluajittexspecific_sources)
+#dist_libluahbtexspecific_a_SOURCES =
+nodist_libluahbtexspecific_a_SOURCES = \
+ $(dist_libluahbtexspecific_sources)
+#dist_libluajithbtexspecific_a_SOURCES =
+nodist_libluajithbtexspecific_a_SOURCES =\
+ $(dist_libluajithbtexspecific_sources)
+
+
+
## mplib "stub" backends are in mplibstuff.c
$(libluatex_a_OBJECTS): libff.a libmplibcore.a libluamisc.a
-#$(liblua53tex_a_OBJECTS): libff.a libmplibcore.a liblua53misc.a
$(libluajittex_a_OBJECTS): libff.a libmplibcore.a libluajitmisc.a
+$(libluatexspecific_a_OBJECTS): libff.a libmplibcore.a libluamisc.a
+$(libluajittexspecific_a_OBJECTS): libff.a libmplibcore.a libluajitmisc.a
+
+$(libluahbtexspecific_a_OBJECTS): libff.a libmplibcore.a libluamisc.a
+$(libluajithbtexspecific_a_OBJECTS): libff.a libmplibcore.a libluajitmisc.a
+
+
+## specific files for luatex and luahbtex
+##
+dist_libluatexspecific_sources = \
+ luatexdir/utils/utils.c \
+ luatexdir/lua/luatex-api.h \
+ luatexdir/lua/luastuff.c \
+ luatexdir/lua/luainit.c \
+ luatexdir/tex/printing.c
+
+dist_libluajittexspecific_sources = \
+ luatexdir/utils/utils.c \
+ luatexdir/lua/luatex-api.h \
+ luatexdir/lua/luastuff.c \
+ luatexdir/lua/luainit.c \
+ luatexdir/tex/printing.c
+
+# luatexdir/utils/utils-hb.c
+dist_libluahbtexspecific_sources = \
+ utils-hb.c \
+ luatex-api-hb.h \
+ luastuff-hb.c \
+ luainit-hb.c \
+ printing-hb.c
+
+#luatexdir/utils/utils-hb.c
+dist_libluajithbtexspecific_sources = \
+ utils-hb.c \
+ luatex-api-hb.h \
+ luastuff-hb.c \
+ luainit-hb.c \
+ printing-hb.c
+
+
+utils-hb.c: luatexdir/utils/utils.c
+ $(LN_S) $(srcdir)/luatexdir/utils/utils.c utils-hb.c
+
+luatex-api-hb.h: luatexdir/lua/luatex-api.h
+ $(LN_S) $(srcdir)/luatexdir/lua/luatex-api.h luatex-api-hb.h
+
+luastuff-hb.c: luatexdir/lua/luastuff.c
+ $(LN_S) $(srcdir)/luatexdir/lua/luastuff.c luastuff-hb.c
+
+luainit-hb.c: luatexdir/lua/luainit.c
+ $(LN_S) $(srcdir)/luatexdir/lua/luainit.c luainit-hb.c
+
+printing-hb.c: luatexdir/tex/printing.c
+ $(LN_S) $(srcdir)/luatexdir/tex/printing.c printing-hb.c
+
## from luatexdir
##
@@ -99,12 +160,6 @@ dist_libluatex_sources += \
##
luatex_dvi_ctangle = $(ctangle_silent)CWEBINPUTS=$(srcdir)/luatexdir/dvi $(ctangle)
-#dvigen.c: ctangle$(EXEEXT) luatexdir/dvi/dvigen.w
-# $(luatex_dvi_ctangle) dvigen.w
-
-#libluatex_web += luatexdir/dvi/dvigen.w
-
-#nodist_libluatex_sources += dvigen.c
dist_libluatex_sources += \
luatexdir/dvi/dvigen.h \
@@ -114,63 +169,6 @@ dist_libluatex_sources += \
##
luatex_font_ctangle = $(ctangle_silent)CWEBINPUTS=$(srcdir)/luatexdir/font $(ctangle)
-# dofont.c: ctangle$(EXEEXT) luatexdir/font/dofont.w
-# $(luatex_font_ctangle) dofont.w
-# luafont.c: ctangle$(EXEEXT) luatexdir/font/luafont.w
-# $(luatex_font_ctangle) luafont.w
-# mapfile.c: ctangle$(EXEEXT) luatexdir/font/mapfile.w
-# $(luatex_font_ctangle) mapfile.w
-# pkin.c: ctangle$(EXEEXT) luatexdir/font/pkin.w
-# $(luatex_font_ctangle) pkin.w
-# sfnt.c: ctangle$(EXEEXT) luatexdir/font/sfnt.w
-# $(luatex_font_ctangle) sfnt.w
-# texfont.c: ctangle$(EXEEXT) luatexdir/font/texfont.w
-# $(luatex_font_ctangle) texfont.w
-# tfmofm.c: ctangle$(EXEEXT) luatexdir/font/tfmofm.w
-# $(luatex_font_ctangle) tfmofm.w
-# tounicode.c: ctangle$(EXEEXT) luatexdir/font/tounicode.w
-# $(luatex_font_ctangle) tounicode.w
-# tt_glyf.c: ctangle$(EXEEXT) luatexdir/font/tt_glyf.w
-# $(luatex_font_ctangle) tt_glyf.w
-# tt_table.c: ctangle$(EXEEXT) luatexdir/font/tt_table.w
-# $(luatex_font_ctangle) tt_table.w
-# vfovf.c: ctangle$(EXEEXT) luatexdir/font/vfovf.w
-# $(luatex_font_ctangle) vfovf.w
-# vfpacket.c: ctangle$(EXEEXT) luatexdir/font/vfpacket.w
-# $(luatex_font_ctangle) vfpacket.w
-# writecff.c: ctangle$(EXEEXT) luatexdir/font/writecff.w
-# $(luatex_font_ctangle) writecff.w
-# writeenc.c: ctangle$(EXEEXT) luatexdir/font/writeenc.w
-# $(luatex_font_ctangle) writeenc.w
-# writefont.c: ctangle$(EXEEXT) luatexdir/font/writefont.w
-# $(luatex_font_ctangle) writefont.w
-# writet1.c: ctangle$(EXEEXT) luatexdir/font/writet1.w
-# $(luatex_font_ctangle) writet1.w
-# writet3.c: ctangle$(EXEEXT) luatexdir/font/writet3.w
-# $(luatex_font_ctangle) writet3.w
-# writettf.c: ctangle$(EXEEXT) luatexdir/font/writettf.w
-# $(luatex_font_ctangle) writettf.w
-# writetype0.c: ctangle$(EXEEXT) luatexdir/font/writetype0.w
-# $(luatex_font_ctangle) writetype0.w
-# writetype2.c: ctangle$(EXEEXT) luatexdir/font/writetype2.w
-# $(luatex_font_ctangle) writetype2.w
-
-# libluatex_web += luatexdir/font/dofont.w luatexdir/font/luafont.w luatexdir/font/mapfile.w
-# libluatex_web += luatexdir/font/pkin.w luatexdir/font/sfnt.w
-# libluatex_web += luatexdir/font/texfont.w luatexdir/font/tfmofm.w
-# libluatex_web += luatexdir/font/tounicode.w luatexdir/font/tt_glyf.w
-# libluatex_web += luatexdir/font/tt_table.w luatexdir/font/vfovf.w
-# libluatex_web += luatexdir/font/vfpacket.w luatexdir/font/writecff.w
-# libluatex_web += luatexdir/font/writeenc.w luatexdir/font/writefont.w
-# libluatex_web += luatexdir/font/writet1.w luatexdir/font/writet3.w
-# libluatex_web += luatexdir/font/writettf.w luatexdir/font/writetype0.w
-# libluatex_web += luatexdir/font/writetype2.w
-
-# nodist_libluatex_sources += dofont.c luafont.c mapfile.c pkin.c sfnt.c
-# nodist_libluatex_sources += texfont.c tfmofm.c tounicode.c tt_glyf.c tt_table.c vfovf.c vfpacket.c
-# nodist_libluatex_sources += writecff.c writeenc.c writefont.c writet1.c writet3.c writettf.c
-# nodist_libluatex_sources += writetype0.c writetype2.c
-
dist_libluatex_sources += \
luatexdir/font/luatexfont.h \
luatexdir/font/mapfile.h \
@@ -206,27 +204,6 @@ dist_libluatex_sources += \
##
luatex_image_ctangle = $(ctangle_silent)CWEBINPUTS=$(srcdir)/luatexdir/image $(ctangle)
-#writeimg.c: ctangle$(EXEEXT) luatexdir/image/writeimg.w
-# $(luatex_image_ctangle) writeimg.w
-#writejbig2.c: ctangle$(EXEEXT) luatexdir/image/writejbig2.w
-# $(luatex_image_ctangle) writejbig2.w
-#writejpg.c: ctangle$(EXEEXT) luatexdir/image/writejpg.w
-# $(luatex_image_ctangle) writejpg.w
-#writejp2.c: ctangle$(EXEEXT) luatexdir/image/writejp2.w
-# $(luatex_image_ctangle) writejp2.w
-#writepng.c: ctangle$(EXEEXT) luatexdir/image/writepng.w
-# $(luatex_image_ctangle) writepng.w
-#pdftoepdf.cc: ctangle$(EXEEXT) luatexdir/image/pdftoepdf.w
-# $(luatex_image_ctangle) pdftoepdf.w - $@
-
-#libluatex_web += luatexdir/image/writeimg.w
-#libluatex_web += luatexdir/image/writejbig2.w
-#libluatex_web += luatexdir/image/writejpg.w
-#libluatex_web += luatexdir/image/writejp2.w
-#libluatex_web += luatexdir/image/writepng.w
-#libluatex_web += luatexdir/image/pdftoepdf.w
-
-#nodist_libluatex_sources += writeimg.c writejbig2.c writejpg.c writejp2.c writepng.c
dist_libluatex_sources += \
luatexdir/image/epdf.h \
@@ -260,28 +237,6 @@ dist_libluatex_sources += \
##
luatex_lua_ctangle = $(ctangle_silent)CWEBINPUTS=$(srcdir)/luatexdir/lua $(ctangle)
-#helpers.c: ctangle$(EXEEXT) luatexdir/lua/helpers.w
-# $(luatex_lua_ctangle) helpers.w
-#luainit.c: ctangle$(EXEEXT) luatexdir/lua/luainit.w
-# $(luatex_lua_ctangle) luainit.w
-#luajitstuff.c: ctangle$(EXEEXT) luatexdir/lua/luajitstuff.w
-# $(luatex_lua_ctangle) luajitstuff.w
-#luanode.c: ctangle$(EXEEXT) luatexdir/lua/luanode.w
-# $(luatex_lua_ctangle) luanode.w
-#luastuff.c: ctangle$(EXEEXT) luatexdir/lua/luastuff.w
-# $(luatex_lua_ctangle) luastuff.w
-#luatoken.c: ctangle$(EXEEXT) luatexdir/lua/luatoken.w
-# $(luatex_lua_ctangle) luatoken.w
-#mplibstuff.c: ctangle$(EXEEXT) luatexdir/lua/mplibstuff.w
-# $(luatex_lua_ctangle) mplibstuff.w
-#texluac.c: ctangle$(EXEEXT) luatexdir/lua/texluac.w
-# $(luatex_lua_ctangle) texluac.w
-#texluajitc.c: ctangle$(EXEEXT) luatexdir/lua/texluajitc.w
-# $(luatex_lua_ctangle) texluajitc.w
-
-#libluatex_web += luatexdir/lua/luainit.w luatexdir/lua/luajitstuff.w
-
-
dist_libluatex_sources += \
luatexdir/lua/lcallbacklib.c \
luatexdir/lua/lfontlib.c \
@@ -299,81 +254,44 @@ dist_libluatex_sources += \
luatexdir/lua/ltexiolib.c \
luatexdir/lua/ltexlib.c \
luatexdir/lua/lnewtokenlib.c \
- luatexdir/lua/luatex-api.h \
luatexdir/lua/luatex-core.c \
luatexdir/lua/helpers.c \
- luatexdir/lua/luainit.c \
luatexdir/lua/luanode.c \
- luatexdir/lua/luastuff.c \
luatexdir/lua/luatoken.c \
luatexdir/lua/mplibstuff.c
+# dist_libluatex_sources += \
+# luatexdir/lua/lcallbacklib.c \
+# luatexdir/lua/lfontlib.c \
+# luatexdir/lua/limglib.c \
+# luatexdir/lua/lpdfelib.c \
+# luatexdir/lua/lpdfscannerlib.c \
+# luatexdir/lua/lkpselib.c \
+# luatexdir/lua/llanglib.c \
+# luatexdir/lua/llualib.c \
+# luatexdir/lua/lnodelib.c \
+# luatexdir/lua/liolibext.c \
+# luatexdir/lua/loslibext.c \
+# luatexdir/lua/lpdflib.c \
+# luatexdir/lua/lstatslib.c \
+# luatexdir/lua/ltexiolib.c \
+# luatexdir/lua/ltexlib.c \
+# luatexdir/lua/lnewtokenlib.c \
+# luatexdir/lua/luatex-api.h \
+# luatexdir/lua/luatex-core.c \
+# luatexdir/lua/helpers.c \
+# luatexdir/lua/luainit.c \
+# luatexdir/lua/luanode.c \
+# luatexdir/lua/luastuff.c \
+# luatexdir/lua/luatoken.c \
+# luatexdir/lua/mplibstuff.c
+
## from luatexdir/pdf
##
luatex_pdf_ctangle = $(ctangle_silent)CWEBINPUTS=$(srcdir)/luatexdir/pdf $(ctangle)
-# pdfpagetree.c: ctangle$(EXEEXT) luatexdir/pdf/pdfpagetree.w
-# $(luatex_pdf_ctangle) pdfpagetree.w
-# pdfaction.c: ctangle$(EXEEXT) luatexdir/pdf/pdfaction.w
-# $(luatex_pdf_ctangle) pdfaction.w
-# pdfannot.c: ctangle$(EXEEXT) luatexdir/pdf/pdfannot.w
-# $(luatex_pdf_ctangle) pdfannot.w
-# pdfcolorstack.c: ctangle$(EXEEXT) luatexdir/pdf/pdfcolorstack.w
-# $(luatex_pdf_ctangle) pdfcolorstack.w
-# pdfdest.c: ctangle$(EXEEXT) luatexdir/pdf/pdfdest.w
-# $(luatex_pdf_ctangle) pdfdest.w
-# pdffont.c: ctangle$(EXEEXT) luatexdir/pdf/pdffont.w
-# $(luatex_pdf_ctangle) pdffont.w
-# pdfgen.c: ctangle$(EXEEXT) luatexdir/pdf/pdfgen.w
-# $(luatex_pdf_ctangle) pdfgen.w
-# pdfglyph.c: ctangle$(EXEEXT) luatexdir/pdf/pdfglyph.w
-# $(luatex_pdf_ctangle) pdfglyph.w
-# pdfimage.c: ctangle$(EXEEXT) luatexdir/pdf/pdfimage.w
-# $(luatex_pdf_ctangle) pdfimage.w
-# pdflink.c: ctangle$(EXEEXT) luatexdir/pdf/pdflink.w
-# $(luatex_pdf_ctangle) pdflink.w
-# pdflistout.c: ctangle$(EXEEXT) luatexdir/pdf/pdflistout.w
-# $(luatex_pdf_ctangle) pdflistout.w
-# pdfliteral.c: ctangle$(EXEEXT) luatexdir/pdf/pdfliteral.w
-# $(luatex_pdf_ctangle) pdfliteral.w
-# pdfobj.c: ctangle$(EXEEXT) luatexdir/pdf/pdfobj.w
-# $(luatex_pdf_ctangle) pdfobj.w
-# pdfoutline.c: ctangle$(EXEEXT) luatexdir/pdf/pdfoutline.w
-# $(luatex_pdf_ctangle) pdfoutline.w
-# pdfpage.c: ctangle$(EXEEXT) luatexdir/pdf/pdfpage.w
-# $(luatex_pdf_ctangle) pdfpage.w
-# pdfrule.c: ctangle$(EXEEXT) luatexdir/pdf/pdfrule.w
-# $(luatex_pdf_ctangle) pdfrule.w
-# pdfsaverestore.c: ctangle$(EXEEXT) luatexdir/pdf/pdfsaverestore.w
-# $(luatex_pdf_ctangle) pdfsaverestore.w
-# pdfsetmatrix.c: ctangle$(EXEEXT) luatexdir/pdf/pdfsetmatrix.w
-# $(luatex_pdf_ctangle) pdfsetmatrix.w
-# pdfshipout.c: ctangle$(EXEEXT) luatexdir/pdf/pdfshipout.w
-# $(luatex_pdf_ctangle) pdfshipout.w
-# pdftables.c: ctangle$(EXEEXT) luatexdir/pdf/pdftables.w
-# $(luatex_pdf_ctangle) pdftables.w
-# pdfthread.c: ctangle$(EXEEXT) luatexdir/pdf/pdfthread.w
-# $(luatex_pdf_ctangle) pdfthread.w
-# pdfxform.c: ctangle$(EXEEXT) luatexdir/pdf/pdfxform.w
-# $(luatex_pdf_ctangle) pdfxform.w
-
-#libluatex_web += luatexdir/pdf/pdfpagetree.w luatexdir/pdf/pdfaction.w luatexdir/pdf/pdfannot.w
-#libluatex_web += luatexdir/pdf/pdfcolorstack.w luatexdir/pdf/pdfdest.w
-#libluatex_web += luatexdir/pdf/pdffont.w luatexdir/pdf/pdfgen.w luatexdir/pdf/pdfglyph.w
-#libluatex_web += luatexdir/pdf/pdfimage.w luatexdir/pdf/pdflink.w luatexdir/pdf/pdflistout.w
-#libluatex_web += luatexdir/pdf/pdfliteral.w luatexdir/pdf/pdfobj.w
-#libluatex_web += luatexdir/pdf/pdfoutline.w luatexdir/pdf/pdfpage.w luatexdir/pdf/pdfrule.w
-#libluatex_web += luatexdir/pdf/pdfsaverestore.w luatexdir/pdf/pdfsetmatrix.w
-#libluatex_web += luatexdir/pdf/pdfshipout.w luatexdir/pdf/pdftables.w
-#libluatex_web += luatexdir/pdf/pdfthread.w luatexdir/pdf/pdfxform.w
-
-#nodist_libluatex_sources += pdfpagetree.c pdfaction.c pdfannot.c pdfcolorstack.c pdfdest.c pdffont.c
-#nodist_libluatex_sources += pdfgen.c pdfglyph.c pdfimage.c pdflink.c pdflistout.c pdfliteral.c
-#nodist_libluatex_sources += pdfobj.c pdfoutline.c pdfpage.c pdfrule.c pdfsaverestore.c
-#nodist_libluatex_sources += pdfsetmatrix.c pdfshipout.c pdftables.c pdfthread.c pdfxform.c
-
dist_libluatex_sources += \
luatexdir/pdf/pdfpagetree.h \
luatexdir/pdf/pdfaction.h \
@@ -425,8 +343,7 @@ dist_libluatex_sources += \
################################################################################
################################################################################
## REMOVED
-## but still left as example.
-## from luatexdir/scripts
+## (left as example from luatexdir/scripts
##
# luatex_luascripts_ctangle = $(ctangle_silent)CWEBINPUTS=$(srcdir)/luatexdir/luascripts $(ctangle)
@@ -464,72 +381,74 @@ dist_libluatex_sources += \
##
luatex_tex_ctangle = $(ctangle_silent)CWEBINPUTS=$(srcdir)/luatexdir/tex $(ctangle)
-# align.c: ctangle$(EXEEXT) luatexdir/tex/align.w
-# $(luatex_tex_ctangle) align.w
-#arithmetic.c: ctangle$(EXEEXT) luatexdir/tex/arithmetic.w
-# $(luatex_tex_ctangle) arithmetic.w
-# buildpage.c: ctangle$(EXEEXT) luatexdir/tex/buildpage.w
-# $(luatex_tex_ctangle) buildpage.w
-#commands.c: ctangle$(EXEEXT) luatexdir/tex/commands.w
-# $(luatex_tex_ctangle) commands.w
-#conditional.c: ctangle$(EXEEXT) luatexdir/tex/conditional.w
-# $(luatex_tex_ctangle) conditional.w
-#directions.c: ctangle$(EXEEXT) luatexdir/tex/directions.w
-# $(luatex_tex_ctangle) directions.w
-#dumpdata.c: ctangle$(EXEEXT) luatexdir/tex/dumpdata.w
-# $(luatex_tex_ctangle) dumpdata.w
-#equivalents.c: ctangle$(EXEEXT) luatexdir/tex/equivalents.w
-# $(luatex_tex_ctangle) equivalents.w
-#errors.c: ctangle$(EXEEXT) luatexdir/tex/errors.w
-# $(luatex_tex_ctangle) errors.w
-# expand.c: ctangle$(EXEEXT) luatexdir/tex/expand.w
-# $(luatex_tex_ctangle) expand.w
-# extensions.c: ctangle$(EXEEXT) luatexdir/tex/extensions.w
-# $(luatex_tex_ctangle) extensions.w
-#filename.c: ctangle$(EXEEXT) luatexdir/tex/filename.w
-# $(luatex_tex_ctangle) filename.w
-#inputstack.c: ctangle$(EXEEXT) luatexdir/tex/inputstack.w
-# $(luatex_tex_ctangle) inputstack.w
-# linebreak.c: ctangle$(EXEEXT) luatexdir/tex/linebreak.w
-# $(luatex_tex_ctangle) linebreak.w
-#mainbody.c: ctangle$(EXEEXT) luatexdir/tex/mainbody.w
-# $(luatex_tex_ctangle) mainbody.w
-#maincontrol.c: ctangle$(EXEEXT) luatexdir/tex/maincontrol.w
-# $(luatex_tex_ctangle) maincontrol.w
-#mathcodes.c: ctangle$(EXEEXT) luatexdir/tex/mathcodes.w
-# $(luatex_tex_ctangle) mathcodes.w
-#memoryword.c: ctangle$(EXEEXT) luatexdir/tex/memoryword.w
-# $(luatex_tex_ctangle) memoryword.w
-# mlist.c: ctangle$(EXEEXT) luatexdir/tex/mlist.w
-# $(luatex_tex_ctangle) mlist.w
-#nesting.c: ctangle$(EXEEXT) luatexdir/tex/nesting.w
-# $(luatex_tex_ctangle) nesting.w
-# packaging.c: ctangle$(EXEEXT) luatexdir/tex/packaging.w
-# $(luatex_tex_ctangle) packaging.w
-#postlinebreak.c: ctangle$(EXEEXT) luatexdir/tex/postlinebreak.w
-# $(luatex_tex_ctangle) postlinebreak.w
-#primitive.c: ctangle$(EXEEXT) luatexdir/tex/primitive.w
-# $(luatex_tex_ctangle) primitive.w
-#printing.c: ctangle$(EXEEXT) luatexdir/tex/printing.w
-# $(luatex_tex_ctangle) printing.w
-# scanning.c: ctangle$(EXEEXT) luatexdir/tex/scanning.w
-# $(luatex_tex_ctangle) scanning.w
-#stringpool.c: ctangle$(EXEEXT) luatexdir/tex/stringpool.w
-# $(luatex_tex_ctangle) stringpool.w
-#texdeffont.c: ctangle$(EXEEXT) luatexdir/tex/texdeffont.w
-# $(luatex_tex_ctangle) texdeffont.w
-# texfileio.c: ctangle$(EXEEXT) luatexdir/tex/texfileio.w
-# $(luatex_tex_ctangle) texfileio.w
-# texmath.c: ctangle$(EXEEXT) luatexdir/tex/texmath.w
-# $(luatex_tex_ctangle) texmath.w
-# texnodes.c: ctangle$(EXEEXT) luatexdir/tex/texnodes.w
-# $(luatex_tex_ctangle) texnodes.w
-#textcodes.c: ctangle$(EXEEXT) luatexdir/tex/textcodes.w
-# $(luatex_tex_ctangle) textcodes.w
-# textoken.c: ctangle$(EXEEXT) luatexdir/tex/textoken.w
-# $(luatex_tex_ctangle) textoken.w
-
+# dist_libluatex_sources += \
+# luatexdir/tex/align.h \
+# luatexdir/tex/arithmetic.h \
+# luatexdir/tex/backend.h \
+# luatexdir/tex/backend.c \
+# luatexdir/tex/buildpage.h \
+# luatexdir/tex/commands.h \
+# luatexdir/tex/conditional.h \
+# luatexdir/tex/directions.h \
+# luatexdir/tex/dumpdata.h \
+# luatexdir/tex/equivalents.h \
+# luatexdir/tex/errors.h \
+# luatexdir/tex/expand.h \
+# luatexdir/tex/extensions.h \
+# luatexdir/tex/filename.h \
+# luatexdir/tex/inputstack.h \
+# luatexdir/tex/linebreak.h \
+# luatexdir/tex/mainbody.h \
+# luatexdir/tex/maincontrol.h \
+# luatexdir/tex/mathcodes.h \
+# luatexdir/tex/memoryword.h \
+# luatexdir/tex/mlist.h \
+# luatexdir/tex/nesting.h \
+# luatexdir/tex/packaging.h \
+# luatexdir/tex/postlinebreak.h \
+# luatexdir/tex/primitive.h \
+# luatexdir/tex/printing.h \
+# luatexdir/tex/scanning.h \
+# luatexdir/tex/stringpool.h \
+# luatexdir/tex/texdeffont.h \
+# luatexdir/tex/texfileio.h \
+# luatexdir/tex/texmath.h \
+# luatexdir/tex/texnodes.h \
+# luatexdir/tex/textcodes.h \
+# luatexdir/tex/textoken.h \
+# luatexdir/tex/align.c \
+# luatexdir/tex/arithmetic.c \
+# luatexdir/tex/buildpage.c \
+# luatexdir/tex/commands.c \
+# luatexdir/tex/conditional.c \
+# luatexdir/tex/directions.c \
+# luatexdir/tex/dumpdata.c \
+# luatexdir/tex/equivalents.c \
+# luatexdir/tex/errors.c \
+# luatexdir/tex/expand.c \
+# luatexdir/tex/extensions.c \
+# luatexdir/tex/filename.c \
+# luatexdir/tex/inputstack.c \
+# luatexdir/tex/linebreak.c \
+# luatexdir/tex/mainbody.c \
+# luatexdir/tex/maincontrol.c \
+# luatexdir/tex/mathcodes.c \
+# luatexdir/tex/memoryword.c \
+# luatexdir/tex/mlist.c \
+# luatexdir/tex/nesting.c \
+# luatexdir/tex/packaging.c \
+# luatexdir/tex/postlinebreak.c \
+# luatexdir/tex/primitive.c \
+# luatexdir/tex/printing.c \
+# luatexdir/tex/scanning.c \
+# luatexdir/tex/stringpool.c \
+# luatexdir/tex/texdeffont.c \
+# luatexdir/tex/texfileio.c \
+# luatexdir/tex/texmath.c \
+# luatexdir/tex/texnodes.c \
+# luatexdir/tex/textcodes.c \
+# luatexdir/tex/textoken.c
dist_libluatex_sources += \
@@ -590,7 +509,6 @@ dist_libluatex_sources += \
luatexdir/tex/packaging.c \
luatexdir/tex/postlinebreak.c \
luatexdir/tex/primitive.c \
- luatexdir/tex/printing.c \
luatexdir/tex/scanning.c \
luatexdir/tex/stringpool.c \
luatexdir/tex/texdeffont.c \
@@ -600,23 +518,10 @@ dist_libluatex_sources += \
luatexdir/tex/textcodes.c \
luatexdir/tex/textoken.c
-
## from luatexdir/utils
##
luatex_utils_ctangle = $(ctangle_silent)CWEBINPUTS=$(srcdir)/luatexdir/utils $(ctangle)
-#avlstuff.c: ctangle$(EXEEXT) luatexdir/utils/avlstuff.w
-# $(luatex_utils_ctangle) avlstuff.w
-#managed-sa.c: ctangle$(EXEEXT) luatexdir/utils/managed-sa.w
-# $(luatex_utils_ctangle) managed-sa.w
-#utils.c: ctangle$(EXEEXT) luatexdir/utils/utils.w
-# $(luatex_utils_ctangle) utils.w
-#unistring.c: ctangle$(EXEEXT) luatexdir/utils/unistring.w
-# $(luatex_utils_ctangle) unistring.w
-
-#libluatex_web += luatexdir/utils/avlstuff.w luatexdir/utils/managed-sa.w luatexdir/utils/utils.w luatexdir/utils/unistring.w
-
-#nodist_libluatex_sources += avlstuff.c managed-sa.c utils.c unistring.c
dist_libluatex_sources += \
luatexdir/utils/avl.c \
@@ -627,8 +532,7 @@ dist_libluatex_sources += \
luatexdir/utils/unistring.h \
luatexdir/utils/avlstuff.c \
luatexdir/utils/managed-sa.c \
- luatexdir/utils/unistring.c \
- luatexdir/utils/utils.c
+ luatexdir/utils/unistring.c
## from ../synctexdir
##
@@ -638,10 +542,10 @@ dist_libluatex_sources += \
synctexdir/synctex.c \
synctexdir/synctex.h
-#dist_liblua53tex_sources = $(dist_libluatex_sources)
EXTRA_DIST += \
$(dist_libluatex_sources) \
+ $(dist_libluahbtexspecific_sources) \
$(libluatex_web)
DISTCLEANFILES += $(nodist_libluatex_sources)
diff --git a/Build/source/texk/web2c/luatexdir/am/luaharfbuzz.am b/Build/source/texk/web2c/luatexdir/am/luaharfbuzz.am
new file mode 100644
index 00000000000..1b6187eaaf1
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/am/luaharfbuzz.am
@@ -0,0 +1,77 @@
+## texk/web2c/luatexdir/am/luaharfbuzz.am: Makefile fragment for luaharfbuzz.
+##
+## Copyright (C) 2019 Khaled Hosny
+## You may freely use, modify and/or distribute this file.
+
+## luaharfbuzz
+##
+EXTRA_LIBRARIES += libluaharfbuzz.a libluajitharfbuzz.a
+
+libluaharfbuzz_a_DEPENDENCIES = $(HARFBUZZ_DEPEND) $(GRAPHITE2_DEPEND)
+libluajitharfbuzz_a_DEPENDENCIES = $(HARFBUZZ_DEPEND) $(GRAPHITE2_DEPEND)
+
+$(libluaharfbuzz_a_OBJECTS): $(LUA_DEPEND)
+$(libluajitharfbuzz_a_OBJECTS): $(LUAJIT_DEPEND)
+
+
+libluaharfbuzz_a_CPPFLAGS = $(AM_CPPFLAGS) $(LUA_INCLUDES) $(HARFBUZZ_INCLUDES) $(GRAPHITE2_INCLUDES)
+libluajitharfbuzz_a_CPPFLAGS = $(AM_CPPFLAGS) $(LUAJIT_INCLUDES) $(HARFBUZZ_INCLUDES) $(GRAPHITE2_INCLUDES)
+libluajitharfbuzz_a_CPPFLAGS += -DLuajitTeX
+
+libluaharfbuzz_a_CFLAGS = # $(WARNING_CFLAGS)
+libluajitharfbuzz_a_CFLAGS = # $(WARNING_CFLAGS)
+
+libluaharfbuzz_a_SOURCES = \
+ luatexdir/luaharfbuzz/src/luaharfbuzz/blob.c \
+ luatexdir/luaharfbuzz/src/luaharfbuzz/buffer.c \
+ luatexdir/luaharfbuzz/src/luaharfbuzz/class_utils.c \
+ luatexdir/luaharfbuzz/src/luaharfbuzz/direction.c \
+ luatexdir/luaharfbuzz/src/luaharfbuzz/face.c \
+ luatexdir/luaharfbuzz/src/luaharfbuzz/feature.c \
+ luatexdir/luaharfbuzz/src/luaharfbuzz/font.c \
+ luatexdir/luaharfbuzz/src/luaharfbuzz/language.c \
+ luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.c \
+ luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.h \
+ luatexdir/luaharfbuzz/src/luaharfbuzz/ot.c \
+ luatexdir/luaharfbuzz/src/luaharfbuzz/script.c \
+ luatexdir/luaharfbuzz/src/luaharfbuzz/tag.c \
+ luatexdir/luaharfbuzz/src/luaharfbuzz/unicode.c
+
+libluajitharfbuzz_a_SOURCES = $(libluaharfbuzz_a_SOURCES)
+
+## Not used
+##
+EXTRA_DIST += \
+ luatexdir/luaharfbuzz/docs/examples/core_types.lua.html \
+ luatexdir/luaharfbuzz/docs/examples/custom_callbacks.lua.html \
+ luatexdir/luaharfbuzz/docs/examples/harfbuzz_setup.lua.html \
+ luatexdir/luaharfbuzz/docs/examples/ot_font_loader.lua.html \
+ luatexdir/luaharfbuzz/docs/examples/package_path_searcher.lua.html \
+ luatexdir/luaharfbuzz/docs/index.html \
+ luatexdir/luaharfbuzz/docs/ldoc.css \
+ luatexdir/luaharfbuzz/examples/core_types.lua \
+ luatexdir/luaharfbuzz/fixtures/amiri-regular_123.json \
+ luatexdir/luaharfbuzz/fixtures/amiri-regular_123_numr.json \
+ luatexdir/luaharfbuzz/fixtures/AppleGothic_korean_issue_22.json \
+ luatexdir/luaharfbuzz/fixtures/notonastaliq_U06CC_U06C1.json \
+ luatexdir/luaharfbuzz/fonts/amiri-regular.ttf \
+ luatexdir/luaharfbuzz/fonts/notonastaliq.ttf \
+ luatexdir/luaharfbuzz/fonts/Rajdhani-Regular.ttf \
+ luatexdir/luaharfbuzz/scripts/generate_harfbuzz_api_list.sh \
+ luatexdir/luaharfbuzz/scripts/generate_hb_shape_json.sh \
+ luatexdir/luaharfbuzz/spec/buffer_spec.lua \
+ luatexdir/luaharfbuzz/spec/harfbuzz_spec.lua \
+ luatexdir/luaharfbuzz/spec/shaping_spec.lua \
+ luatexdir/luaharfbuzz/src/harfbuzz.lua \
+ luatexdir/luaharfbuzz/src/harfbuzz.luadoc \
+ luatexdir/luaharfbuzz/status/done.txt \
+ luatexdir/luaharfbuzz/status/full_api.txt \
+ luatexdir/luaharfbuzz/config.ld \
+ luatexdir/luaharfbuzz/LICENSE \
+ luatexdir/luaharfbuzz/luaharfbuzz-1.0.0-1.rockspec \
+ luatexdir/luaharfbuzz/luaharfbuzz-scm-1.rockspec \
+ luatexdir/luaharfbuzz/Makefile \
+ luatexdir/luaharfbuzz/README.md \
+ luatexdir/luaharfbuzz/README-win.md \
+ luatexdir/luaharfbuzz/THANKS
+
diff --git a/Build/source/texk/web2c/luatexdir/am/luatex.am b/Build/source/texk/web2c/luatexdir/am/luatex.am
index 4ee88f114bc..9643a7ec8be 100644
--- a/Build/source/texk/web2c/luatexdir/am/luatex.am
+++ b/Build/source/texk/web2c/luatexdir/am/luatex.am
@@ -4,8 +4,8 @@
## Copyright 2009-2015 Peter Breitenlohner <tex-live@tug.org>
## You may freely use, modify and/or distribute this file.
-## LuaTeX and LuaJITTeX
-##
+## LuaTeX and LuaJITTeX
+## LuaHBTeX and LuaJITHBTex
if LUATEX
bin_PROGRAMS += luatex
if WIN32
@@ -17,16 +17,16 @@ bin_links += luatex$(EXEEXT):texlua luatex$(EXEEXT):texluac
endif !WIN32
endif LUATEX
-#if LUATEX53
-#bin_PROGRAMS += luatex53
-#if WIN32
-#noinst_PROGRAMS += call_luatex53
-#install_exe_links += install-luatex53-links
-#uninstall_exe_links += uninstall-luatex53-links
-#else !WIN32
-#bin_links += luatex53$(EXEEXT):texlua53
-#endif !WIN32
-#endif LUATEX53
+if LUAHBTEX
+bin_PROGRAMS += luahbtex
+if WIN32
+noinst_PROGRAMS += call_luahbtex
+install_exe_links += install-luahbtex-links
+uninstall_exe_links += uninstall-luahbtex-links
+else !WIN32
+bin_links += luahbtex$(EXEEXT):texlua luahbtex$(EXEEXT):texluac
+endif !WIN32
+endif LUAHBTEX
if LUAJITTEX
bin_PROGRAMS += luajittex
@@ -39,55 +39,100 @@ bin_links += luajittex$(EXEEXT):texluajit luajittex$(EXEEXT):texluajitc
endif !WIN32
endif LUAJITTEX
-#EXTRA_PROGRAMS += luatex luatex53 luajittex
-EXTRA_PROGRAMS += luatex luajittex
+if LUAJITHBTEX
+bin_PROGRAMS += luajithbtex
+if WIN32
+noinst_PROGRAMS += call_luajithbtex
+install_exe_links += install-luajithbtex-links
+uninstall_exe_links += uninstall-luajithbtex-links
+else !WIN32
+bin_links += luajithbtex$(EXEEXT):texluajit luajithbtex$(EXEEXT):texluajitc
+endif !WIN32
+endif LUAJITHBTEX
+
+
+EXTRA_PROGRAMS += luatex luajittex luahbtex luajithbtex
# Force Automake to use CXXLD for linking
-#nodist_EXTRA_luatex_SOURCES = dummy.cxx
-#nodist_EXTRA_luatex53_SOURCES = dummy.cxx
-#nodist_EXTRA_luajittex_SOURCES = dummy.cxx
+nodist_EXTRA_luahbtex_SOURCES = dummy.cxx
+nodist_EXTRA_luajithbtex_SOURCES = dummy.cxx
+
luatex_preflags = $(AM_CPPFLAGS) $(ZLIB_INCLUDES) $(LIBPNG_INCLUDES)
luatex_postflags = -I$(srcdir)/libmd5 -DpdfTeX -I$(srcdir)/luatexdir -I$(srcdir)/mplibdir
luatex_postflags += -Dextra_version_info=`date +-%Y%m%d%H`
luatex_postflags += -I$(srcdir)/synctexdir -DSYNCTEX_ENGINE_H='<synctex-luatex.h>'
+luahbtex_preflags = $(AM_CPPFLAGS) $(ZLIB_INCLUDES) $(LIBPNG_INCLUDES) $(HARFBUZZ_INCLUDES)
+luahbtex_postflags = -I$(srcdir)/libmd5 -DpdfTeX -I$(srcdir)/luatexdir -I$(srcdir)/mplibdir
+luahbtex_postflags += -Dextra_version_info=`date +-%Y%m%d%H`
+luahbtex_postflags += -DLUATEX_HARFBUZZ_ENABLED
+luahbtex_postflags += -I$(srcdir)/synctexdir -DSYNCTEX_ENGINE_H='<synctex-luatex.h>'
+
+
luatex_CPPFLAGS = $(luatex_preflags) $(LUA_INCLUDES) $(luatex_postflags)
-#luatex53_CPPFLAGS = $(luatex_preflags) $(LUA_LUA53_INCLUDES) $(luatex_postflags)
luajittex_CPPFLAGS = $(luatex_preflags) $(LUAJIT_INCLUDES) $(LUAJIT_DEFINES) $(luatex_postflags)
luajittex_CPPFLAGS += -DLuajitTeX
-luatex_CXXFLAGS = $(WARNING_CXXFLAGS)
-#luatex53_CXXFLAGS = $(WARNING_CXXFLAGS)
-luajittex_CXXFLAGS = $(WARNING_CXXFLAGS)
+luahbtex_CPPFLAGS = $(luahbtex_preflags) $(LUA_INCLUDES) $(luahbtex_postflags)
+luajithbtex_CPPFLAGS = $(luahbtex_preflags) $(LUAJIT_INCLUDES) $(LUAJIT_DEFINES) $(luahbtex_postflags)
+luajithbtex_CPPFLAGS += -DLuajitTeX
+
+
+luahbtex_CXXFLAGS = $(WARNING_CXXFLAGS)
+luajithbtex_CXXFLAGS = $(WARNING_CXXFLAGS)
luatex_LDFLAGS = -export-dynamic
-#luatex53_LDFLAGS = -export-dynamic
luajittex_LDFLAGS = -export-dynamic $(LUAJIT_LDEXTRA)
-#luatex_postldadd = libmplibcore.a $(MPFR_LIBS) $(GMP_LIBS)
+luahbtex_LDFLAGS = -export-dynamic
+luajithbtex_LDFLAGS = -export-dynamic $(LUAJIT_LDEXTRA)
+
luatex_postldadd = libmplibcore.a
-luatex_postldadd += $(ZZIPLIB_LIBS) $(LIBPNG_LIBS) $(ZLIB_LIBS)
+luatex_postldadd += $(ZZIPLIB_LIBS) $(LIBPNG_LIBS) $(ZLIB_LIBS)
luatex_postldadd += $(LDADD) libmputil.a libunilib.a libmd5.a $(lua_socketlibs)
+luahbtex_postldadd = libmplibcore.a
+luahbtex_postldadd += $(ZZIPLIB_LIBS) $(LIBPNG_LIBS) $(ZLIB_LIBS) $(HARFBUZZ_LIBS) $(GRAPHITE2_LIBS)
+luahbtex_postldadd += $(LDADD) libmputil.a libunilib.a libmd5.a $(lua_socketlibs)
+
+
+luatex_LDADD = libluatex.a libluatexspecific.a libluatex.a libff.a libluamisc.a libluasocket.a libluaffi.a libluapplib.a $(LUA_LIBS) $(luatex_postldadd)
+luajittex_LDADD = libluajittex.a libluajittexspecific.a libluajittex.a libff.a libluajitmisc.a libluajitsocket.a libluajitpplib.a $(LUAJIT_LIBS) $(luatex_postldadd)
+
+luahbtex_LDADD = libluatex.a libluahbtexspecific.a libluatex.a libff.a libluamisc.a libluasocket.a libluaffi.a libluapplib.a libluaharfbuzz.a $(LUA_LIBS) $(luahbtex_postldadd)
+luajithbtex_LDADD = libluajittex.a libluajithbtexspecific.a libluajittex.a libff.a libluajitmisc.a libluajitsocket.a libluajitpplib.a libluajitharfbuzz.a $(LUAJIT_LIBS) $(luahbtex_postldadd)
+
+
+#not here ?
+#LIBTOOLFLAGS += --preserve-dup-deps
-luatex_LDADD = libluatex.a libff.a libluamisc.a libluasocket.a libluaffi.a libluapplib.a $(LUA_LIBS) $(luatex_postldadd)
-#luatex53_LDADD = liblua53tex.a libff.a liblua53misc.a liblua53socket.a liblua53ffi.a liblua53pplib.a $(LUA_LUA53_LIBS) $(luatex_postldadd)
-luajittex_LDADD = libluajittex.a libff.a libluajitmisc.a libluajitsocket.a libluajitpplib.a $(LUAJIT_LIBS) $(luatex_postldadd)
luatex_depend = $(proglib) $(KPATHSEA_DEPEND) $(LIBPNG_DEPEND) libmputil.a libmd5.a
-luatex_DEPENDENCIES = $(luatex_depend) libluatex.a
-#luatex53_DEPENDENCIES = $(luatex_depend) liblua53tex.a
-luajittex_DEPENDENCIES = $(luatex_depend) libluajittex.a
+luatex_DEPENDENCIES = $(luatex_depend) libluatex.a libluatexspecific.a
+luajittex_DEPENDENCIES = $(luatex_depend) libluajittex.a libluajittexspecific.a
+
+luahbtex_depend = $(proglib) $(KPATHSEA_DEPEND) $(LIBPNG_DEPEND) libmputil.a libmd5.a
+luahbtex_DEPENDENCIES = $(luahbtex_depend) libluatex.a libluahbtexspecific.a
+luajithbtex_DEPENDENCIES = $(luatex_depend) libluajittex.a libluajithbtexspecific.a
+
+
$(luatex_OBJECTS): libluatex.a
-#$(luatex53_OBJECTS): liblua53tex.a
$(luajittex_OBJECTS): libluajittex.a
+$(luahbtex_OBJECTS): libluatex.a
+$(luajithbtex_OBJECTS): libluajittex.a
+
+
+
nodist_luatex_SOURCES = $(luatex_sources)
-#nodist_luatex53_SOURCES = $(luatex_sources)
nodist_luajittex_SOURCES = $(luatex_sources)
+nodist_luahbtex_SOURCES = $(luatex_sources)
+nodist_luajithbtex_SOURCES = $(luatex_sources)
+
+
luatex_sources = \
luatexdir/luatex_svnversion.h \
@@ -102,17 +147,28 @@ call_luatex_CPPFLAGS = -DEXEPROG=\"luatex.exe\"
nodist_call_luatex_SOURCES = callexe.c
call_luatex_LDADD =
-#call_luatex53_CPPFLAGS = -DEXEPROG=\"luatex53.exe\"
-#nodist_call_luatex53_SOURCES = callexe.c
-#call_luatex53_LDADD =
+call_luahbtex_CPPFLAGS = -DEXEPROG=\"luahbtex.exe\"
+nodist_call_luahbtex_SOURCES = callexe.c
+call_luahbtex_LDADD =
+
call_luajittex_CPPFLAGS = -DEXEPROG=\"luajittex.exe\"
nodist_call_luajittex_SOURCES = callexe.c
call_luajittex_LDADD =
+call_luajithbtex_CPPFLAGS = -DEXEPROG=\"luajithbtex.exe\"
+nodist_call_luajithbtex_SOURCES = callexe.c
+call_luajithbtex_LDADD =
+
+
.PHONY: install-luatex-links uninstall-luatex-links
.PHONY: install-luajittex-links uninstall-luajittex-links
+.PHONY: install-luahbtex-links uninstall-luahbtex-links
+.PHONY: install-luajithbtex-links uninstall-luajithbtex-links
+
+
+
if WIN32
if MINGW32
install-luatex-links: .libs/luatex$(EXEEXT)
@@ -121,12 +177,24 @@ install-luatex-links: .libs/luatex$(EXEEXT)
uninstall-luatex-links:
rm -f $(DESTDIR)$(bindir)/texlua$(EXEEXT)
rm -f $(DESTDIR)$(bindir)/texluac$(EXEEXT)
+install-luahbtex-links: .libs/luahbtex$(EXEEXT)
+ $(INSTALL_PROGRAM) .libs/luahbtex$(EXEEXT) $(DESTDIR)$(bindir)/texlua$(EXEEXT)
+ $(INSTALL_PROGRAM) .libs/luahbtex$(EXEEXT) $(DESTDIR)$(bindir)/texluac$(EXEEXT)
+uninstall-luahbtex-links:
+ rm -f $(DESTDIR)$(bindir)/texlua$(EXEEXT)
+ rm -f $(DESTDIR)$(bindir)/texluac$(EXEEXT)
install-luajittex-links: .libs/luajittex$(EXEEXT)
$(INSTALL_PROGRAM) .libs/luajittex$(EXEEXT) $(DESTDIR)$(bindir)/texluajit$(EXEEXT)
$(INSTALL_PROGRAM) .libs/luajittex$(EXEEXT) $(DESTDIR)$(bindir)/texluajitc$(EXEEXT)
uninstall-luajittex-links:
rm -f $(DESTDIR)$(bindir)/texluajit$(EXEEXT)
rm -f $(DESTDIR)$(bindir)/texluajitc$(EXEEXT)
+install-luajithbtex-links: .libs/luajithbtex$(EXEEXT)
+ $(INSTALL_PROGRAM) .libs/luajithbtex$(EXEEXT) $(DESTDIR)$(bindir)/texluajit$(EXEEXT)
+ $(INSTALL_PROGRAM) .libs/luajithbtex$(EXEEXT) $(DESTDIR)$(bindir)/texluajitc$(EXEEXT)
+uninstall-luajithbtex-links:
+ rm -f $(DESTDIR)$(bindir)/texluajit$(EXEEXT)
+ rm -f $(DESTDIR)$(bindir)/texluajitc$(EXEEXT)
else !MINGW32
install-luatex-links: call_luatex$(EXEEXT)
$(INSTALL_PROGRAM) call_luatex$(EXEEXT) $(DESTDIR)$(bindir)/texlua$(EXEEXT)
@@ -134,37 +202,56 @@ install-luatex-links: call_luatex$(EXEEXT)
uninstall-luatex-links:
rm -f $(DESTDIR)$(bindir)/texlua$(EXEEXT)
rm -f $(DESTDIR)$(bindir)/texluac$(EXEEXT)
+install-luahbtex-links: call_luahbtex$(EXEEXT)
+ $(INSTALL_PROGRAM) call_luahbtex$(EXEEXT) $(DESTDIR)$(bindir)/texlua$(EXEEXT)
+ $(INSTALL_PROGRAM) call_luahbtex$(EXEEXT) $(DESTDIR)$(bindir)/texluac$(EXEEXT)
+uninstall-luahbtex-links:
+ rm -f $(DESTDIR)$(bindir)/texlua$(EXEEXT)
+ rm -f $(DESTDIR)$(bindir)/texluac$(EXEEXT)
install-luajittex-links: call_luajittex$(EXEEXT)
$(INSTALL_PROGRAM) call_luajittex$(EXEEXT) $(DESTDIR)$(bindir)/texluajit$(EXEEXT)
$(INSTALL_PROGRAM) call_luajittex$(EXEEXT) $(DESTDIR)$(bindir)/texluajitc$(EXEEXT)
uninstall-luajittex-links:
rm -f $(DESTDIR)$(bindir)/texluajit$(EXEEXT)
rm -f $(DESTDIR)$(bindir)/texluajitc$(EXEEXT)
+install-luajithbtex-links: call_luajithbtex$(EXEEXT)
+ $(INSTALL_PROGRAM) call_luajithbtex$(EXEEXT) $(DESTDIR)$(bindir)/texluajit$(EXEEXT)
+ $(INSTALL_PROGRAM) call_luajithbtex$(EXEEXT) $(DESTDIR)$(bindir)/texluajitc$(EXEEXT)
+uninstall-luajithbtex-links:
+ rm -f $(DESTDIR)$(bindir)/texluajit$(EXEEXT)
+ rm -f $(DESTDIR)$(bindir)/texluajitc$(EXEEXT)
endif !MINGW32
endif WIN32
+
# LuaTeX/LuaJITTeX Tests
#
luatex_tests = luatexdir/luatex.test luatexdir/luaimage.test
luatexdir/luatex.log luatexdir/luaimage.log: luatex$(EXEEXT)
-#luatex53_tests = luatexdir/luatex.test luatexdir/luaimage.test
-#luatexdir/luatex53.log luatexdir/luaimage53.log: luatex53$(EXEEXT)
+luahbtex_tests = luatexdir/luatex.test luatexdir/luaimage.test
+luatexdir/luahbtex.log luatexdir/luahbimage.log: luahbtex$(EXEEXT)
luajittex_tests = luatexdir/luajittex.test luatexdir/luajitimage.test
luatexdir/luajittex.log luatexdir/luajitimage.log: luajittex$(EXEEXT)
+luajithbtex_tests = luatexdir/luajittex.test luatexdir/luajitimage.test
+luatexdir/luajithbtex.log luatexdir/luajithbimage.log: luajithbtex$(EXEEXT)
+
-EXTRA_DIST += $(luatex_tests) $(luajittex_tests)
+EXTRA_DIST += $(luatex_tests) $(luajittex_tests) $(luahbtex_tests) $(luajithbtex_tests)
if LUATEX
TESTS += $(luatex_tests)
endif LUATEX
-#if LUATEX53
-#TESTS += $(luatex_tests)
-#endif LUATEX53
+if LUAHBTEX
+TESTS += $(luahbtex_tests)
+endif LUAHBTEX
if LUAJITTEX
TESTS += $(luajittex_tests)
endif LUAJITTEX
+if LUAJITHBTEX
+TESTS += $(luajithbtex_tests)
+endif LUAJITHBTEX
## luaimage.test/luajitimage.test
EXTRA_DIST += luatexdir/tests/luaimage.tex \
diff --git a/Build/source/texk/web2c/luatexdir/font/luafont.c b/Build/source/texk/web2c/luatexdir/font/luafont.c
index 7cb03521d4e..62edb175812 100644
--- a/Build/source/texk/web2c/luatexdir/font/luafont.c
+++ b/Build/source/texk/web2c/luatexdir/font/luafont.c
@@ -950,8 +950,16 @@ static void read_char_packets(lua_State * L, int *l_fonts, charinfo * co, intern
lua_rawgeti(L, -2, 2);
if (lua_istable(L, -1)) {
lua_getglobal(L, "img");
+ /*tex Just in case one accidentely wipes |img|: */
+ if (lua_type(L,-1) != LUA_TTABLE) {
+ normal_error("vf command","no img table found");
+ }
lua_pushstring(L, "new");
lua_gettable(L, -2);
+ /*tex or the |new| entry: */
+ if (lua_type(L,-1) != LUA_TFUNCTION) {
+ normal_error("vf command","no img.new function found");
+ }
lua_insert(L, -3);
lua_pop(L, 1);
lua_call(L, 1, 1);
diff --git a/Build/source/texk/web2c/luatexdir/font/writecff.c b/Build/source/texk/web2c/luatexdir/font/writecff.c
index 2d0b16b085d..31a49bae01d 100644
--- a/Build/source/texk/web2c/luatexdir/font/writecff.c
+++ b/Build/source/texk/web2c/luatexdir/font/writecff.c
@@ -2975,6 +2975,7 @@ void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd)
size_t l = (last_cid / 8) + 1;
char *stream = xmalloc(l);
memset(stream, 0, l);
+ stream[0] |= 1 << 7; /*tex Force |.notdef| into the map. */
for (cid = 1; cid <= (long) last_cid; cid++) {
if (CIDToGIDMap[2 * cid] || CIDToGIDMap[2 * cid + 1]) {
stream[(cid / 8)] |= (1 << (7 - (cid % 8)));
diff --git a/Build/source/texk/web2c/luatexdir/font/writetype2.c b/Build/source/texk/web2c/luatexdir/font/writetype2.c
index b8a74609007..49193579b7e 100644
--- a/Build/source/texk/web2c/luatexdir/font/writetype2.c
+++ b/Build/source/texk/web2c/luatexdir/font/writetype2.c
@@ -334,6 +334,7 @@ boolean make_tt_subset(PDF pdf, fd_entry * fd, unsigned char *buff, int buflen)
size_t l = (last_cid / 8) + 1;
char *stream = xmalloc(l);
memset(stream, 0, l);
+ stream[0] |= 1 << 7; /*tex Force |.notdef| into the map. */
for (cid = 1; cid <= (long) last_cid; cid++) {
if (used_chars[cid]) {
stream[(cid / 8)] |= (1 << (7 - (cid % 8)));
diff --git a/Build/source/texk/web2c/luatexdir/lua/limglib.c b/Build/source/texk/web2c/luatexdir/lua/limglib.c
index 76c96bfb316..734e591a4d3 100644
--- a/Build/source/texk/web2c/luatexdir/lua/limglib.c
+++ b/Build/source/texk/web2c/luatexdir/lua/limglib.c
@@ -729,7 +729,8 @@ static void lua_to_image(lua_State * L, image * a, image_dict * d)
img_type(d) = IMG_TYPE_PDFSTREAM;
}
} else {
- luaL_error(L, "img.%s can not be set", s);
+ /*tex Let's be a bit more tolerant to adding private keys. */
+ /* luaL_error(L, "img.%s can not be set", s); */
}
}
diff --git a/Build/source/texk/web2c/luatexdir/lua/lnewtokenlib.c b/Build/source/texk/web2c/luatexdir/lua/lnewtokenlib.c
index 1c2bd8533f0..a50ea2f20d9 100644
--- a/Build/source/texk/web2c/luatexdir/lua/lnewtokenlib.c
+++ b/Build/source/texk/web2c/luatexdir/lua/lnewtokenlib.c
@@ -812,34 +812,40 @@ inline static int lua_tokenlib_get_command(lua_State * L)
inline static int lua_tokenlib_get_index(lua_State * L)
{
+ int cmd, chr;
lua_token *n = check_istoken(L, 1);
halfword t = token_info(n->token);
- int cmd = (t >= cs_token_flag ? eq_type(t - cs_token_flag) : token_cmd(t));
- halfword e = equiv(t - cs_token_flag);
+ if (t >= cs_token_flag) {
+ cmd = eq_type(t - cs_token_flag);
+ chr = equiv(t - cs_token_flag);
+ } else {
+ cmd = token_cmd(t);
+ chr = token_chr(t);
+ }
switch (cmd) {
case assign_int_cmd:
- e -= count_base;
+ chr -= count_base;
break;
case assign_attr_cmd:
- e -= attribute_base;
+ chr -= attribute_base;
break;
case assign_dimen_cmd:
- e -= dimen_base;
+ chr -= scaled_base;
break;
case assign_glue_cmd:
- e -= skip_base;
+ chr -= skip_base;
break;
case assign_mu_glue_cmd:
- e -= mu_skip_base;
+ chr -= mu_skip_base;
break;
case assign_toks_cmd:
- e -= toks_base;
+ chr -= toks_base;
break;
default:
break;
}
- if ((e >= 0) && (e <= 65535)) {
- lua_pushinteger(L, e);
+ if (chr >= 0 && chr <= 65535) {
+ lua_pushinteger(L, chr);
} else {
lua_pushnil(L);
}
diff --git a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c
index c3e459b2211..9dc9350b5c6 100644
--- a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c
+++ b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c
@@ -1781,7 +1781,7 @@ static int getdelcodes(lua_State * L)
static int settex(lua_State * L)
{
const char *st;
- int texstr;
+ int texstr, isprim;
size_t k;
int cur_cs1, cur_cmd1;
int isglobal = 0;
@@ -1814,7 +1814,9 @@ static int settex(lua_State * L)
return 0;
}
texstr = maketexlstring(st, k);
- if (is_primitive(texstr)) {
+ isprim = is_primitive(texstr);
+ flush_str(texstr);
+ if (isprim) {
if (i == 3 && (lua_type(L,1) == LUA_TSTRING)) {
const char *s = lua_tostring(L, 1);
if (lua_key_eq(s,global))
@@ -2545,7 +2547,7 @@ static int tex_definefont(lua_State * L)
{
const char *csname;
int f, u;
- str_number t;
+ str_number t, d;
size_t l;
int i = 1;
int a = 0;
@@ -2559,7 +2561,6 @@ static int tex_definefont(lua_State * L)
}
csname = luaL_checklstring(L, i, &l);
f = luaL_checkinteger(L, (i + 1));
- t = maketexlstring(csname, l);
no_new_control_sequence = 0;
u = string_lookup(csname, l);
no_new_control_sequence = 1;
@@ -2568,7 +2569,32 @@ static int tex_definefont(lua_State * L)
else
eq_define(u, set_font_cmd, f);
eqtb[font_id_base + f] = eqtb[u];
- hash_text(font_id_base + f) = t;
+ /*tex
+
+ This is tricky: when we redefine a string we loose the old one. So this
+ will change as it's only used to display the |\fontname| so we can store
+ that with the font.
+
+ */
+ d = cs_text(font_id_base + f);
+ t = maketexlstring(csname, l); /* the csname */
+ if (!d) {
+ /*tex We have a new string. */
+ cs_text(font_id_base + f) = t;
+ } else if ((d!=t) && str_eq_str(d,t)){
+ /*tex We have a duplicate string. */
+ flush_str(t);
+ } else if(d!=t){
+ d = search_string(t);
+ if (d) {
+ /*tex We have already such a string. */
+ cs_text(font_id_base + f) = d;
+ flush_str(t);
+ } else {
+ /*tex The old value is lost but still in the pool. */
+ cs_text(font_id_base + f) = t;
+ }
+ }
return 0;
}
diff --git a/Build/source/texk/web2c/luatexdir/lua/luastuff.c b/Build/source/texk/web2c/luatexdir/lua/luastuff.c
index cf2b1684431..fb05c60dd1f 100644
--- a/Build/source/texk/web2c/luatexdir/lua/luastuff.c
+++ b/Build/source/texk/web2c/luatexdir/lua/luastuff.c
@@ -189,6 +189,9 @@ static const luaL_Reg lualibs[] = {
#endif
{ "ffi", luaopen_ffi },
/*tex more libraries will be loaded later */
+#ifdef LUATEX_HARFBUZZ_ENABLED
+ { "luaharfbuzz", luaopen_luaharfbuzz },
+#endif
{ NULL, NULL }
};
diff --git a/Build/source/texk/web2c/luatexdir/lua/luatex-api.h b/Build/source/texk/web2c/luatexdir/lua/luatex-api.h
index c662e76b983..d54bd84663f 100644
--- a/Build/source/texk/web2c/luatexdir/lua/luatex-api.h
+++ b/Build/source/texk/web2c/luatexdir/lua/luatex-api.h
@@ -50,12 +50,29 @@ extern void fix_o_mode(void);
# include "lualib.h"
#ifdef LuajitTeX
# include "luajit.h"
+#endif
+
+/* Names */
+#ifndef LUATEX_HARFBUZZ_ENABLED
+#ifdef LuajitTeX
# define MyName "LuajitTeX"
# define my_name "luajittex"
#else
# define MyName "LuaTeX"
# define my_name "luatex"
#endif
+#endif
+
+#ifdef LUATEX_HARFBUZZ_ENABLED
+#ifdef LuajitTeX
+# define MyName "LuajitHBTeX"
+# define my_name "luajithbtex"
+#else
+# define MyName "LuaHBTeX"
+# define my_name "luahbtex"
+#endif
+#endif
+
#ifdef __cplusplus
extern "C" {
@@ -94,6 +111,10 @@ extern int luaopen_sha2(lua_State * L);
extern int luaopen_ffi(lua_State * L);
#endif
+#ifdef LUATEX_HARFBUZZ_ENABLED
+extern int luaopen_luaharfbuzz(lua_State * L);
+#endif
+
extern int luaopen_zlib(lua_State * L);
extern int luaopen_gzip(lua_State * L);
extern int luaopen_ff(lua_State * L);
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/LICENSE b/Build/source/texk/web2c/luatexdir/luaharfbuzz/LICENSE
new file mode 100644
index 00000000000..157ffe59094
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015-16 Deepak Jois
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/Makefile b/Build/source/texk/web2c/luatexdir/luaharfbuzz/Makefile
new file mode 100644
index 00000000000..71d1fd2712e
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/Makefile
@@ -0,0 +1,15 @@
+DOCS_DIR := docs
+
+spec:
+ busted .
+
+clean:
+ rm -rf build *.so
+
+lint:
+ luacheck src spec examples
+
+doc:
+ ldoc -d ${DOCS_DIR} .
+
+.PHONY: clean lint spec doc
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/README-win.md b/Build/source/texk/web2c/luatexdir/luaharfbuzz/README-win.md
new file mode 100644
index 00000000000..d7a769ffa4b
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/README-win.md
@@ -0,0 +1,53 @@
+# Building Harfbuzz and _luaharfbuzz_ on Windows
+
+## Building Harfbuzz
+
+### Prerequisites
+* [Visual Studio Community Edition](https://www.visualstudio.com/vs/community/)
+* C++ Support for Visual Studio (See [here](http://stackoverflow.com/questions/31953769/visual-studio-doesnt-have-cl-exe))
+
+### Building
+* Download the Harfbuzz source for win32 from the [releases pages](https://github.com/behdad/harfbuzz/releases) (look for a zip file that ends with _-win32_, for e.g. _harfbuzz-1.4.2-win32.zip_), and unzip it.
+* Launch the Visual Studio developer prompt for the platform you want to target. This is very important. For e.g, on my 64-bit system, I am using _VS2015 x64 Native Tools Command Prompt_
+* Navigate to the _win32_ folder in the Harfbuzz source tree and do `nmake /f Makefile.vc CFG=release`
+* This should generate _harfbuzz.lib_ and _harfbuzz-vs14.dll_.
+
+## Copying Harfbuzz headers and DLL to the right locations
+The Harfbuzz headers and DLLs must be copied to the right locations, for Lua and LuaRocks to be able to find them during installation and running:
+
+* Copy all the Harfbuzz header (_src/*.h_) files to _C:\external\include\harfbuzz_. This is where LuaRocks will look for them by default. Make sure the header files are in the _harfbuzz_ sub-directory under _C:\external\include_, otherwise it will not work.
+* Copy _harfbuzz.lib_ and _harfbuzz-vs14.dll_ to the folder _C:\external\lib_. This is where LuaRocks will look for them by default.
+* Copy _harfbuzz-vs14.dll_ to _C:\Windows\System32_. This is where running programs can locate the Harfbuzz DLL.
+
+## Installing Lua and LuaRocks
+It is highly recommended that you install Lua 5.2 and LuaRocks in a sandboxed environment on your machine. [Hererocks] makes it dead simple to do on Windows. Make sure you have installed Python first. On my system, I just did `chocolatey install python`, but you can use an alternate method and skip running that command below.
+
+[Hererocks]:https://github.com/mpeterv/hererocks
+
+```
+chocolatey install python
+wget https://raw.githubusercontent.com/mpeterv/hererocks/latest/hererocks.py
+python hererocks.py lua52 -l5.2 -rlatest
+source lua52/bin/activate
+```
+## Install _luaharfbuzz_
+If you followed the steps in the previous sections, and have a sandboxed Lua installation, which the Lua program on %PATH%, then doing the following should just work:
+
+```
+C:\> luarocks install luaharfbuzz
+```
+
+This will download the _luaharfbuzz_ source, compile the C modules, link them against Lua and Harfbuzz, and install it in the right location.
+
+## Test
+Test whether the installation was successful by loading _luaharfbuzz_ in the Lua REPL
+
+```
+C:\> lua
+Lua 5.2.4 Copyright (C) 1994-2015 Lua.org, PUC-Rio
+> hb = require("harfbuzz")
+> print(hb.version())
+1.4.1
+>
+```
+
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/README.md b/Build/source/texk/web2c/luatexdir/luaharfbuzz/README.md
new file mode 100644
index 00000000000..f5a900c65b1
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/README.md
@@ -0,0 +1,154 @@
+# _luaharfbuzz_
+
+Lua bindings for [Harfbuzz].
+
+[Harfbuzz]:http://harfbuzz.org
+
+## Contents
+
+* [Overview](#overview)
+* [Installing Harfbuzz](#installing-harfbuzz)
+* [Installing _luaharfbuzz_](#installing-luaharfbuzz)
+* [Documentation](#documentation)
+* [Sample Code](#sample-code)
+* [Development](#development)
+* [Contact](#contact)
+
+## Overview
+HarfBuzz is an OpenType text shaping engine. It is used in software like Qt,
+Pango, Firefox, Chromium, XeTeX and LibreOffice.
+
+_luaharfbuzz_ provides bindings for the most common types in Harfbuzz. The
+initial motivation for building it is to use Harfbuzz with the [LuaTeX]
+typesetting system. However, the module isn’t tied to LuaTeX in any way. It
+can be used with any Lua codebase.
+
+[LuaTeX]:luatex.org
+
+## Installing Harfbuzz
+
+Make sure [Harfbuzz] libraries and headers are installed. before trying to
+install _luaharfbuzz_
+
+#### OS X
+
+Install via [Homebrew](http://brew.sh/)
+
+```
+brew install harfbuzz
+```
+#### Ubuntu Linux
+
+```
+apt-get install libharfbuzz0b libharfbuzz-dev
+```
+
+#### Windows
+Getting the whole setup running on Windows is very tedious, so all instructions are in their own file [README-win.md](https://github.com/deepakjois/luaharfbuzz/blob/master/README-win.md).
+
+#### Other Platforms
+_Send a pull request if you want to include specific instructions to install
+Harfbuzz on your preferred platform._
+
+Before building the package, LuaRocks populates the `HARFBUZZ_INCDIR` and `HARFBUZZ_LIBDIR` to point to the correct locations. If you can populate these variables manually before running LuaRocks, you can install _luaharfbuzz_ on any system that supports Lua and Harfbuzz.
+
+## Installing _luaharfbuzz_
+
+#### Luarocks
+If [Luarocks] and Harfbuzz are installed, _luaharfbuzz_ can be installed like this:
+
+```
+luarocks install luaharfbuzz
+```
+
+[Luarocks]: https://luarocks.org
+
+## Documentation
+* [API Docs](http://ufytex.github.io/luaharfbuzz/)
+* [Wiki](http://github.com/ufytex/luaharfbuzz/wiki)
+
+## Sample Code
+
+Here is some sample code, showcasing the core types and methods in the API.
+
+```lua
+local harfbuzz = require('harfbuzz')
+local serpent = require('serpent') -- luarocks install serpent
+
+-- Harfbuzz API Version
+print("Harfbuzz API version", harfbuzz.version())
+
+-- Shapers available
+print("Shapers:", serpent.line({ harfbuzz.shapers() }, {comment = false}))
+
+-- harfbuzz.Face
+local face = harfbuzz.Face.new('../fonts/notonastaliq.ttf')
+print('\nFace upem = '..face:get_upem())
+
+-- harfbuzz.Font
+local font = harfbuzz.Font.new(face)
+local xs, xy = font:get_scale()
+print("\nDefault font scale = X: "..xs..", Y: "..xy)
+
+-- harfbuzz.Buffer
+local text = "یہ" -- U+06CC U+06C1
+local buf = harfbuzz.Buffer.new()
+buf:add_utf8(text)
+
+-- harfbuzz.shape (Shapes text)
+print("\nShaping '"..text.."' set with Noto Nastaliq Urdu")
+harfbuzz.shape(font, buf, { language = harfbuzz.Language.new("urd"), script = harfbuzz.Script.new("Arab"), direction = harfbuzz.Direction.RTL})
+
+local glyphs = buf:get_glyphs()
+print("No. of glyphs", #glyphs)
+print(serpent.line(glyphs, {comment = false}))
+
+local opts = { language = harfbuzz.Language.new("eng"), script = harfbuzz.Script.new("Latn"), direction = harfbuzz.Direction.LTR }
+local amiri_face = harfbuzz.Face.new('../fonts/amiri-regular.ttf')
+local amiri_font = harfbuzz.Font.new(amiri_face)
+
+-- shaping '123' w/o features
+print("\nShaping '123' set with Amiri Regular and no features")
+buf= harfbuzz.Buffer.new()
+buf:add_utf8("123")
+harfbuzz.shape(amiri_font, buf, opts)
+glyphs = buf:get_glyphs()
+print(serpent.line(glyphs, {comment = false}))
+
+-- shaping '123' with '+numr' (numerators)
+print("\nShaping '123' set with Amiri Regular with 'numr' feature turned on")
+buf= harfbuzz.Buffer.new()
+buf:add_utf8("123")
+opts.features = "+numr"
+harfbuzz.shape(amiri_font, buf, opts)
+glyphs = buf:get_glyphs()
+print(serpent.line(glyphs, {comment = false}))
+```
+
+## Development
+
+#### Building
+You can build the package for development purposes using LuaRocks as well. It is recommended that you build it to your local tree (using `--local`) to isolate it from your actual installation.
+
+```
+luarocks --local make
+```
+
+#### Testing and Linting
+In order to make changes to the code and run the tests, the following dependencies need to be installed:
+
+* [Busted](http://olivinelabs.com/busted/) – `luarocks install busted`
+* [luacheck](luacheck.readthedocs.org) – `luarocks install luacheck`
+
+Run the test suite:
+```
+make spec
+```
+
+Lint the codebase:
+```
+make lint
+```
+
+## Contact
+Open a Github issue, or email me at <deepak.jois@gmail.com>.
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/THANKS b/Build/source/texk/web2c/luatexdir/luaharfbuzz/THANKS
new file mode 100644
index 00000000000..1d996820929
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/THANKS
@@ -0,0 +1,2 @@
+Simon Cozens
+Michal Hoftich
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/config.ld b/Build/source/texk/web2c/luatexdir/luaharfbuzz/config.ld
new file mode 100644
index 00000000000..95d27f9a39f
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/config.ld
@@ -0,0 +1,9 @@
+project = 'luaharfbuzz'
+description = 'Lua bindings to Harfbuzz'
+full_description = 'The documentation is available on the @{https://github.com/deepakjois/luaharfbuzz/wiki|wiki}'
+use_markdown_titles = true
+backtick_references = false
+title = 'luaharfbuzz Documentation'
+file = 'src/harfbuzz.luadoc'
+examples = 'examples'
+format = 'markdown'
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/core_types.lua.html b/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/core_types.lua.html
new file mode 100644
index 00000000000..fe9e5c39c9b
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/core_types.lua.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+<head>
+ <title>luaharfbuzz Documentation</title>
+ <link rel="stylesheet" href="../ldoc.css" type="text/css" />
+</head>
+<body>
+
+<div id="container">
+
+<div id="product">
+ <div id="product_logo"></div>
+ <div id="product_name"><big><b></b></big></div>
+ <div id="product_description"></div>
+</div> <!-- id="product" -->
+
+
+<div id="main">
+
+
+<!-- Menu -->
+
+<div id="navigation">
+<br/>
+<h1>luaharfbuzz</h1>
+
+
+
+
+<h2>Examples</h2>
+<ul class="nowrap">
+ <li><strong>core_types.lua</strong></li>
+</ul>
+<h2>Modules</h2>
+<ul class="nowrap">
+ <li><a href="../index.html">harfbuzz</a></li>
+</ul>
+
+</div>
+
+<div id="content">
+
+ <h2>core_types.lua</h2>
+<pre>
+<span class="keyword">local</span> harfbuzz = <span class="global">require</span>(<span class="string">'harfbuzz'</span>)
+<span class="keyword">local</span> serpent = <span class="global">require</span>(<span class="string">'serpent'</span>) <span class="comment">-- luarocks install serpent
+</span>
+<span class="comment">-- Harfbuzz API Version
+</span><span class="global">print</span>(<span class="string">"Harfbuzz API version"</span>, harfbuzz.version())
+
+<span class="comment">-- Shapers available
+</span><span class="global">print</span>(<span class="string">"Shapers:"</span>, serpent.line({ harfbuzz.shapers() }, {comment = <span class="keyword">false</span>}))
+
+<span class="comment">-- harfbuzz.Face
+</span><span class="keyword">local</span> face = harfbuzz.Face.new(<span class="string">'../fonts/notonastaliq.ttf'</span>)
+<span class="global">print</span>(<span class="string">'\nFace upem = '</span>..face:get_upem())
+
+<span class="comment">-- harfbuzz.Font
+</span><span class="keyword">local</span> font = harfbuzz.Font.new(face)
+<span class="keyword">local</span> xs, xy = font:get_scale()
+<span class="global">print</span>(<span class="string">"\nDefault font scale = X: "</span>..xs..<span class="string">", Y: "</span>..xy)
+
+<span class="comment">-- harfbuzz.Buffer
+</span><span class="keyword">local</span> text = <span class="string">"یہ"</span> <span class="comment">-- U+06CC U+06C1
+</span><span class="keyword">local</span> buf = harfbuzz.Buffer.new()
+buf:add_utf8(text)
+
+<span class="comment">-- harfbuzz.shape (Shapes text)
+</span><span class="global">print</span>(<span class="string">"\nShaping '"</span>..text..<span class="string">"' set with Noto Nastaliq Urdu"</span>)
+harfbuzz.shape(font, buf, { language = harfbuzz.Language.new(<span class="string">"urd"</span>), script = harfbuzz.Script.new(<span class="string">"Arab"</span>), direction = harfbuzz.Direction.RTL})
+
+<span class="keyword">local</span> glyphs = buf:get_glyphs()
+<span class="global">print</span>(<span class="string">"No. of glyphs"</span>, #glyphs)
+<span class="global">print</span>(serpent.line(glyphs, {comment = <span class="keyword">false</span>}))
+
+<span class="keyword">local</span> opts = { language = harfbuzz.Language.new(<span class="string">"eng"</span>), script = harfbuzz.Script.new(<span class="string">"Latn"</span>), direction = harfbuzz.Direction.LTR }
+<span class="keyword">local</span> amiri_face = harfbuzz.Face.new(<span class="string">'../fonts/amiri-regular.ttf'</span>)
+<span class="keyword">local</span> amiri_font = harfbuzz.Font.new(amiri_face)
+
+<span class="comment">-- shaping '123' w/o features
+</span><span class="global">print</span>(<span class="string">"\nShaping '123' set with Amiri Regular and no features"</span>)
+buf= harfbuzz.Buffer.new()
+buf:add_utf8(<span class="string">"123"</span>)
+harfbuzz.shape(amiri_font, buf, opts)
+glyphs = buf:get_glyphs()
+<span class="global">print</span>(serpent.line(glyphs, {comment = <span class="keyword">false</span>}))
+
+<span class="comment">-- shaping '123' with '+numr' (numerators)
+</span><span class="global">print</span>(<span class="string">"\nShaping '123' set with Amiri Regular with 'numr' feature turned on"</span>)
+buf= harfbuzz.Buffer.new()
+buf:add_utf8(<span class="string">"123"</span>)
+opts.features = <span class="string">"+numr"</span>
+harfbuzz.shape(amiri_font, buf, opts)
+glyphs = buf:get_glyphs()
+<span class="global">print</span>(serpent.line(glyphs, {comment = <span class="keyword">false</span>}))</pre>
+
+
+</div> <!-- id="content" -->
+</div> <!-- id="main" -->
+<div id="about">
+<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
+<i style="float:right;">Last updated 2019-04-13 17:03:03 </i>
+</div> <!-- id="about" -->
+</div> <!-- id="container" -->
+</body>
+</html>
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/custom_callbacks.lua.html b/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/custom_callbacks.lua.html
new file mode 100644
index 00000000000..eff09e27b8d
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/custom_callbacks.lua.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+<head>
+ <title>luaharfbuzz Documentation</title>
+ <link rel="stylesheet" href="../ldoc.css" type="text/css" />
+</head>
+<body>
+
+<div id="container">
+
+<div id="product">
+ <div id="product_logo"></div>
+ <div id="product_name"><big><b></b></big></div>
+ <div id="product_description"></div>
+</div> <!-- id="product" -->
+
+
+<div id="main">
+
+
+<!-- Menu -->
+
+<div id="navigation">
+<br/>
+<h1>luaharfbuzz</h1>
+
+
+
+
+<h2>Examples</h2>
+<ul class="nowrap">
+ <li><a href="../examples/core_types.lua.html">core_types.lua</a></li>
+ <li><strong>custom_callbacks.lua</strong></li>
+ <li><a href="../examples/harfbuzz_setup.lua.html">harfbuzz_setup.lua</a></li>
+ <li><a href="../examples/ot_font_loader.lua.html">ot_font_loader.lua</a></li>
+ <li><a href="../examples/package_path_searcher.lua.html">package_path_searcher.lua</a></li>
+</ul>
+<h2>Modules</h2>
+<ul class="nowrap">
+ <li><a href="../index.html">harfbuzz</a></li>
+</ul>
+
+</div>
+
+<div id="content">
+
+ <h2>custom_callbacks.lua</h2>
+<pre>
+<span class="comment">-- Switch off some callbacks
+</span>callback.register(<span class="string">"hyphenate"</span>, <span class="keyword">false</span>)
+callback.register(<span class="string">"ligaturing"</span>, <span class="keyword">false</span>)
+callback.register(<span class="string">"kerning"</span>, <span class="keyword">false</span>)
+
+<span class="comment">-- Add debug statements to some callbacks
+</span>callback.register(<span class="string">"post_linebreak_filter"</span>, <span class="keyword">function</span>()
+ texio.write_nl(<span class="string">"POST_LINEBREAK"</span>)
+ <span class="keyword">return</span> <span class="keyword">true</span>
+<span class="keyword">end</span>)
+
+callback.register(<span class="string">"hpack_filter"</span>, <span class="keyword">function</span>()
+ texio.write_nl(<span class="string">"HPACK"</span>)
+ <span class="keyword">return</span> <span class="keyword">true</span>
+<span class="keyword">end</span>)
+
+callback.register(<span class="string">"vpack_filter"</span>, <span class="keyword">function</span>()
+ texio.write_nl(<span class="string">"VPACK"</span>)
+ <span class="keyword">return</span> <span class="keyword">true</span>
+<span class="keyword">end</span>)
+
+callback.register(<span class="string">"buildpage_filter"</span>, <span class="keyword">function</span>(extrainfo)
+ texio.write_nl(<span class="string">"BUILDPAGE_FILTER "</span>..extrainfo)
+<span class="keyword">end</span>)</pre>
+
+
+</div> <!-- id="content" -->
+</div> <!-- id="main" -->
+<div id="about">
+<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.5</a></i>
+<i style="float:right;">Last updated 2016-08-31 21:59:58 </i>
+</div> <!-- id="about" -->
+</div> <!-- id="container" -->
+</body>
+</html>
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/harfbuzz_setup.lua.html b/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/harfbuzz_setup.lua.html
new file mode 100644
index 00000000000..dba607a9f6c
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/harfbuzz_setup.lua.html
@@ -0,0 +1,231 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+<head>
+ <title>luaharfbuzz Documentation</title>
+ <link rel="stylesheet" href="../ldoc.css" type="text/css" />
+</head>
+<body>
+
+<div id="container">
+
+<div id="product">
+ <div id="product_logo"></div>
+ <div id="product_name"><big><b></b></big></div>
+ <div id="product_description"></div>
+</div> <!-- id="product" -->
+
+
+<div id="main">
+
+
+<!-- Menu -->
+
+<div id="navigation">
+<br/>
+<h1>luaharfbuzz</h1>
+
+
+
+
+<h2>Examples</h2>
+<ul class="nowrap">
+ <li><a href="../examples/core_types.lua.html">core_types.lua</a></li>
+ <li><a href="../examples/custom_callbacks.lua.html">custom_callbacks.lua</a></li>
+ <li><strong>harfbuzz_setup.lua</strong></li>
+ <li><a href="../examples/ot_font_loader.lua.html">ot_font_loader.lua</a></li>
+ <li><a href="../examples/package_path_searcher.lua.html">package_path_searcher.lua</a></li>
+</ul>
+<h2>Modules</h2>
+<ul class="nowrap">
+ <li><a href="../index.html">harfbuzz</a></li>
+</ul>
+
+</div>
+
+<div id="content">
+
+ <h2>harfbuzz_setup.lua</h2>
+<pre>
+<span class="comment">-- Allow external Lua modules to be loaded.
+</span><span class="global">dofile</span> <span class="string">'package_path_searcher.lua'</span>
+
+<span class="comment">-- Attach a OpenType font loader to define_font callback.
+</span><span class="global">require</span> <span class="string">'ot_font_loader'</span>
+
+<span class="comment">-- Disable some callbacks, and attach debug logging to others.
+</span><span class="global">require</span> <span class="string">'custom_callbacks'</span>
+
+<span class="comment">-- List all callbacks
+</span><span class="keyword">local</span> serpent = <span class="global">require</span> <span class="string">'serpent'</span>
+texio.write_nl(serpent.block(callback.list()))
+
+<span class="comment">-- Load luaharfbuzz
+</span><span class="keyword">local</span> harfbuzz = <span class="global">require</span> <span class="string">'harfbuzz'</span>
+
+<span class="keyword">local</span> lt_to_hb_dir = { TLT = <span class="string">"ltr"</span>, TRT = <span class="string">"rtl"</span> }
+<span class="comment">-- local hb_to_lt_dir = { ltr = "TLT", rtl = "TRT" }
+</span>
+<span class="keyword">local</span> <span class="keyword">function</span> upem_to_sp(v,font)
+ <span class="keyword">return</span> <span class="global">math</span>.floor(v / font.units_per_em * font.size)
+<span class="keyword">end</span>
+
+<span class="comment">-- Print the contents of a nodelist.
+</span><span class="comment">-- Glyph nodes are printed as UTF-8 characters, while other nodes are printed
+</span><span class="comment">-- by calling node.type on it, along with the subtype of the node.
+</span><span class="keyword">local</span> <span class="keyword">function</span> show_nodes (head, raw)
+ <span class="keyword">local</span> nodes = <span class="string">''</span>
+ <span class="keyword">for</span> item <span class="keyword">in</span> node.traverse(head) <span class="keyword">do</span>
+ <span class="keyword">local</span> i = item.id
+ <span class="keyword">if</span> i == node.id(<span class="string">"glyph"</span>) <span class="keyword">then</span>
+ <span class="keyword">if</span> raw <span class="keyword">then</span> i = <span class="global">string</span>.format(<span class="string">'&lt;glyph %d&gt;'</span>, item.char) <span class="keyword">else</span> i = unicode.utf8.char(item.char) <span class="keyword">end</span>
+ <span class="keyword">else</span>
+ i = <span class="global">string</span>.format(<span class="string">'&lt;%s%s&gt;'</span>, node.<span class="global">type</span>(i), ( item.subtype <span class="keyword">and</span> (<span class="string">"("</span>.. item.subtype .. <span class="string">")"</span>) <span class="keyword">or</span> <span class="string">''</span>))
+ <span class="keyword">end</span>
+ nodes = nodes .. i .. <span class="string">' '</span>
+ <span class="keyword">end</span>
+ texio.write_nl(nodes)
+ <span class="keyword">return</span> <span class="keyword">true</span>
+<span class="keyword">end</span>
+
+<span class="comment">-- Process a paragraph nodelist and shape it with Harfbuzz.
+</span><span class="comment">-- Only works for the most simple paragraphs. Check the assertions in the code
+</span><span class="comment">-- to understand what kind of nodes the shaping routine is expecting at
+</span><span class="comment">-- any point.
+</span><span class="keyword">local</span> <span class="keyword">function</span> process_nodes(head)
+ <span class="comment">-- Pointer to traverse head nodelist
+</span> <span class="keyword">local</span> head_slider = head
+
+ <span class="comment">-- First node is a local_par
+</span> <span class="global">assert</span>(head_slider.id == node.id(<span class="string">"local_par"</span>), <span class="string">"local_par expected"</span>)
+
+ <span class="comment">-- Get direction
+</span> <span class="keyword">local</span> dir = head_slider.dir
+ texio.write_nl(<span class="string">"direction is: "</span>..dir)
+
+
+ <span class="comment">-- Second node is indentation
+</span> head_slider = head_slider.<span class="global">next</span>
+ <span class="global">assert</span>(head_slider.id == node.id(<span class="string">"hlist"</span>) <span class="keyword">and</span> head_slider.subtype == <span class="number">3</span>, <span class="string">"parindent hlist expected"</span>)
+
+ <span class="comment">-- Check if font can be shaped by Harfbuzz
+</span> <span class="keyword">local</span> fontid = head_slider.<span class="global">next</span>.font
+ texio.write_nl(<span class="string">"fontid is "</span>..fontid)
+ <span class="keyword">local</span> font = font.getfont(fontid)
+ <span class="keyword">if</span> <span class="keyword">not</span> font.harfbuzz <span class="keyword">then</span> <span class="keyword">return</span> head <span class="keyword">end</span>
+ texio.write_nl(<span class="string">"paragraph can be shaped by Harfbuzz"</span>)
+
+ <span class="comment">-- Initialise new head
+</span> <span class="keyword">local</span> new_head = node.copy_list(head, head_slider.<span class="global">next</span>)
+ <span class="global">assert</span>(node.length(new_head) == <span class="number">2</span>, <span class="string">"expected two nodes in new_head"</span>)
+
+ <span class="comment">-- Pointer to traverse new heade nodelist
+</span> <span class="keyword">local</span> new_head_slider = node.slide(new_head)
+
+ <span class="comment">-- Build text
+</span> <span class="keyword">local</span> codepoints = { }
+ <span class="keyword">while</span> head_slider.<span class="global">next</span>.id ~= node.id(<span class="string">"penalty"</span>) <span class="keyword">do</span>
+ head_slider = head_slider.<span class="global">next</span>
+ <span class="keyword">if</span> head_slider.id == node.id(<span class="string">"glyph"</span>) <span class="keyword">then</span>
+ <span class="global">table</span>.insert(codepoints, head_slider.char)
+ <span class="keyword">elseif</span> head_slider.id == node.id(<span class="string">"glue"</span>) <span class="keyword">and</span> head_slider.subtype == <span class="number">13</span> <span class="keyword">then</span>
+ <span class="global">table</span>.insert(codepoints, <span class="number">0x20</span>)
+ <span class="keyword">else</span>
+ <span class="global">error</span>(<span class="global">string</span>.format(<span class="string">"Cant handle node of type %s, subtype %s"</span>, node.<span class="global">type</span>(head_slider.id), <span class="global">tostring</span>(head_slider.subtype)))
+ <span class="keyword">end</span>
+ <span class="keyword">end</span>
+
+ <span class="comment">-- Initialise new tail at the last penalty node.
+</span> <span class="keyword">local</span> new_tail = head_slider.<span class="global">next</span>
+
+ <span class="comment">-- Skip over penalty node
+</span> head_slider = head_slider.<span class="global">next</span>.<span class="global">next</span>
+
+ <span class="comment">-- Last node is a \parfillskip
+</span> <span class="global">assert</span>(head_slider.id == node.id(<span class="string">"glue"</span>) <span class="keyword">and</span> head_slider.subtype == <span class="number">15</span>, <span class="string">"\\parfillskip expected"</span>)
+ <span class="global">assert</span>(<span class="keyword">not</span> head_slider.<span class="global">next</span>, <span class="string">"Expected this to be the last node."</span>)
+
+ <span class="comment">-- Shape text
+</span> <span class="keyword">local</span> buf = harfbuzz.Buffer.new()
+ buf:set_cluster_level(harfbuzz.Buffer.HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)
+ buf:add_codepoints(codepoints)
+ harfbuzz.shape(font.harfbuzz.font,buf, { direction = lt_to_hb_dir[dir] })
+
+ <span class="comment">-- Create new nodes from shaped text
+</span> <span class="keyword">if</span> dir == <span class="string">'TRT'</span> <span class="keyword">then</span> buf:reverse() <span class="keyword">end</span>
+ <span class="keyword">local</span> glyphs = buf:get_glyph_infos_and_positions()
+
+ <span class="keyword">for</span> _, v <span class="keyword">in</span> <span class="global">ipairs</span>(glyphs) <span class="keyword">do</span>
+ <span class="keyword">local</span> n,k <span class="comment">-- Node and (optional) Kerning
+</span> <span class="keyword">local</span> char = font.backmap[v.codepoint]
+ <span class="keyword">if</span> codepoints[v.cluster+<span class="number">1</span>] == <span class="number">0x20</span> <span class="keyword">then</span>
+ <span class="global">assert</span>(char == <span class="number">0x20</span> <span class="keyword">or</span> char == <span class="number">0xa0</span>, <span class="string">"Expected char to be 0x20 or 0xa0"</span>)
+ n = node.new(<span class="string">"glue"</span>)
+ n.subtype = <span class="number">0</span>
+ n.width = font.parameters.space
+ n.stretch = font.parameters.space_stretch
+ n.shrink = font.parameters.space_shrink
+ new_head_slider.<span class="global">next</span> = n
+ <span class="keyword">else</span>
+ <span class="comment">-- Create glyph node
+</span> n = node.new(<span class="string">"glyph"</span>)
+ n.font = fontid
+ n.char = char
+ n.subtype = <span class="number">1</span>
+
+ <span class="comment">-- Set offsets from Harfbuzz data
+</span> n.yoffset = upem_to_sp(v.y_offset, font)
+ n.xoffset = upem_to_sp(v.x_offset, font)
+ <span class="keyword">if</span> dir == <span class="string">'TRT'</span> <span class="keyword">then</span> n.xoffset = n.xoffset * -<span class="number">1</span> <span class="keyword">end</span>
+
+ <span class="comment">-- Adjust kerning if Harfbuzz’s x_advance does not match glyph width
+</span> <span class="keyword">local</span> x_advance = upem_to_sp(v.x_advance, font)
+ <span class="keyword">if</span> <span class="global">math</span>.abs(x_advance - n.width) &gt; <span class="number">1</span> <span class="keyword">then</span> <span class="comment">-- needs kerning
+</span> k = node.new(<span class="string">"kern"</span>)
+ k.kern = (x_advance - n.width)
+ <span class="keyword">end</span>
+
+ <span class="comment">-- Insert glyph node into new list,
+</span> <span class="comment">-- adjusting for direction and kerning.
+</span> <span class="keyword">if</span> k <span class="keyword">then</span>
+ <span class="keyword">if</span> dir == <span class="string">'TRT'</span> <span class="keyword">then</span> <span class="comment">-- kerning goes before glyph
+</span> k.<span class="global">next</span> = n
+ new_head_slider.<span class="global">next</span> = k
+ <span class="keyword">else</span> <span class="comment">-- kerning goes after glyph
+</span> n.<span class="global">next</span> = k
+ new_head_slider.<span class="global">next</span> = n
+ <span class="keyword">end</span>
+ <span class="keyword">else</span> <span class="comment">-- no kerning
+</span> new_head_slider.<span class="global">next</span> = n
+ <span class="keyword">end</span>
+ <span class="keyword">end</span>
+ new_head_slider = node.slide(new_head_slider)
+ <span class="keyword">end</span>
+
+ new_head_slider.<span class="global">next</span> = new_tail
+ texio.write_nl(<span class="string">"No. of nodes after shaping: "</span>..node.length(new_head))
+ show_nodes(new_head, <span class="keyword">true</span>)
+ <span class="keyword">return</span> new_head
+<span class="keyword">end</span>
+
+<span class="comment">-- Callback function
+</span><span class="keyword">local</span> <span class="keyword">function</span> show_and_process_nodes(head)
+ texio.write_nl(<span class="string">"No. of nodes: "</span>..node.length(head))
+ show_nodes(head)
+ <span class="keyword">return</span> process_nodes(head)
+<span class="keyword">end</span>
+
+<span class="comment">-- Register shaping callback
+</span>callback.register(<span class="string">"pre_linebreak_filter"</span>, show_and_process_nodes)</pre>
+
+
+</div> <!-- id="content" -->
+</div> <!-- id="main" -->
+<div id="about">
+<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.5</a></i>
+<i style="float:right;">Last updated 2016-08-31 21:59:58 </i>
+</div> <!-- id="about" -->
+</div> <!-- id="container" -->
+</body>
+</html>
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/ot_font_loader.lua.html b/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/ot_font_loader.lua.html
new file mode 100644
index 00000000000..1abf52eebde
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/ot_font_loader.lua.html
@@ -0,0 +1,139 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+<head>
+ <title>luaharfbuzz Documentation</title>
+ <link rel="stylesheet" href="../ldoc.css" type="text/css" />
+</head>
+<body>
+
+<div id="container">
+
+<div id="product">
+ <div id="product_logo"></div>
+ <div id="product_name"><big><b></b></big></div>
+ <div id="product_description"></div>
+</div> <!-- id="product" -->
+
+
+<div id="main">
+
+
+<!-- Menu -->
+
+<div id="navigation">
+<br/>
+<h1>luaharfbuzz</h1>
+
+
+
+
+<h2>Examples</h2>
+<ul class="nowrap">
+ <li><a href="../examples/core_types.lua.html">core_types.lua</a></li>
+ <li><a href="../examples/custom_callbacks.lua.html">custom_callbacks.lua</a></li>
+ <li><a href="../examples/harfbuzz_setup.lua.html">harfbuzz_setup.lua</a></li>
+ <li><strong>ot_font_loader.lua</strong></li>
+ <li><a href="../examples/package_path_searcher.lua.html">package_path_searcher.lua</a></li>
+</ul>
+<h2>Modules</h2>
+<ul class="nowrap">
+ <li><a href="../index.html">harfbuzz</a></li>
+</ul>
+
+</div>
+
+<div id="content">
+
+ <h2>ot_font_loader.lua</h2>
+<pre>
+<span class="keyword">local</span> harfbuzz = <span class="global">require</span>(<span class="string">'harfbuzz'</span>)
+
+<span class="comment">-- Load OpenType font.
+</span><span class="comment">-- https://tug.org/TUGboat/tb33-1/tb103isambert.pdf
+</span><span class="keyword">local</span> <span class="keyword">function</span> read_font (name, size, fontid)
+ <span class="keyword">if</span> size &lt; <span class="number">0</span> <span class="keyword">then</span>
+ size = size * tex.sp(<span class="string">"10pt"</span>) / -<span class="number">1000</span>
+ <span class="keyword">end</span>
+
+ <span class="comment">-- Load file using fontloader.open
+</span> <span class="keyword">local</span> f = fontloader.open (name)
+ <span class="keyword">local</span> fonttable = fontloader.to_table(f)
+ fontloader.close(f)
+
+ <span class="keyword">local</span> metrics = {
+ name = fonttable.fontname,
+ fullname = fonttable.fontname..fontid,
+ psname = fonttable.fontname,
+ <span class="global">type</span> = <span class="string">"real"</span>,
+ filename = name,
+ format = <span class="global">string</span>.match(<span class="global">string</span>.lower(name), <span class="string">"otf$"</span>) <span class="keyword">and</span> <span class="string">"opentype"</span> <span class="keyword">or</span> <span class="global">string</span>.match(<span class="global">string</span>.lower(name), <span class="string">"ttf$"</span>) <span class="keyword">and</span> <span class="string">"truetype"</span>,
+ embedding = <span class="string">'subset'</span>,
+ size = size,
+ designsize = fonttable.design_size*<span class="number">6553.6</span>,
+ cidinfo = fonttable.cidinfo,
+ units_per_em = fonttable.units_per_em
+ }
+
+ <span class="comment">-- Scaling for font metrics
+</span> <span class="keyword">local</span> mag = size / fonttable.units_per_em
+
+ <span class="comment">-- Find glyph for 0x20, and get width for spacing glue.
+</span> <span class="keyword">local</span> space_glyph = fonttable.map.map[<span class="number">0x20</span>]
+ <span class="keyword">local</span> space_glyph_table = fonttable.glyphs[space_glyph]
+ <span class="keyword">local</span> space_glyph_width = space_glyph_table.width * mag
+
+ metrics.parameters = {
+ slant = <span class="number">0</span>,
+ space = space_glyph_width,
+ space_stretch = <span class="number">1.5</span> * space_glyph_width,
+ space_shrink = <span class="number">0.5</span> * space_glyph_width,
+ x_height = fonttable.pfminfo.os2_xheight * mag,
+ quad = <span class="number">1.0</span> * size,
+ extra_space = <span class="number">0</span>
+ }
+
+ <span class="comment">-- Save backmap in TeX font, so we can get char code from glyph index
+</span> <span class="comment">-- obtainded from Harfbuzz
+</span> metrics.backmap = fonttable.map.backmap
+
+ metrics.characters = { }
+ <span class="keyword">for</span> char, glyph <span class="keyword">in</span> <span class="global">pairs</span>(fonttable.map.map) <span class="keyword">do</span>
+ <span class="keyword">local</span> glyph_table = fonttable.glyphs[glyph]
+ metrics.characters[char] = {
+ index = glyph,
+ width = glyph_table.width * mag,
+ name = glyph_table.name,
+ }
+ <span class="keyword">if</span> glyph_table.boundingbox[<span class="number">4</span>] <span class="keyword">then</span>
+ metrics.characters[char].height = glyph_table.boundingbox[<span class="number">4</span>] * mag
+ <span class="keyword">end</span>
+ <span class="keyword">if</span> glyph_table.boundingbox[<span class="number">2</span>] <span class="keyword">then</span>
+ metrics.characters[char].depth = -glyph_table.boundingbox[<span class="number">2</span>] * mag
+ <span class="keyword">end</span>
+ <span class="keyword">end</span>
+
+ <span class="comment">-- Store Harfbuzz data in the font to retrieve it in the shaping routine.
+</span> <span class="keyword">local</span> face = harfbuzz.Face.new(name)
+ metrics.harfbuzz = {
+ face = face,
+ font = harfbuzz.Font.new(face)
+ }
+
+ <span class="keyword">return</span> metrics
+<span class="keyword">end</span>
+
+<span class="comment">-- Register OpenType font loader in define_font callback.
+</span>callback.register(<span class="string">'define_font'</span>, read_font, <span class="string">"font loader"</span>)</pre>
+
+
+</div> <!-- id="content" -->
+</div> <!-- id="main" -->
+<div id="about">
+<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.5</a></i>
+<i style="float:right;">Last updated 2016-08-31 21:59:58 </i>
+</div> <!-- id="about" -->
+</div> <!-- id="container" -->
+</body>
+</html>
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/package_path_searcher.lua.html b/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/package_path_searcher.lua.html
new file mode 100644
index 00000000000..9ff317b2ea0
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/examples/package_path_searcher.lua.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+<head>
+ <title>luaharfbuzz Documentation</title>
+ <link rel="stylesheet" href="../ldoc.css" type="text/css" />
+</head>
+<body>
+
+<div id="container">
+
+<div id="product">
+ <div id="product_logo"></div>
+ <div id="product_name"><big><b></b></big></div>
+ <div id="product_description"></div>
+</div> <!-- id="product" -->
+
+
+<div id="main">
+
+
+<!-- Menu -->
+
+<div id="navigation">
+<br/>
+<h1>luaharfbuzz</h1>
+
+
+
+
+<h2>Examples</h2>
+<ul class="nowrap">
+ <li><a href="../examples/core_types.lua.html">core_types.lua</a></li>
+ <li><a href="../examples/custom_callbacks.lua.html">custom_callbacks.lua</a></li>
+ <li><a href="../examples/harfbuzz_setup.lua.html">harfbuzz_setup.lua</a></li>
+ <li><a href="../examples/ot_font_loader.lua.html">ot_font_loader.lua</a></li>
+ <li><strong>package_path_searcher.lua</strong></li>
+</ul>
+<h2>Modules</h2>
+<ul class="nowrap">
+ <li><a href="../index.html">harfbuzz</a></li>
+</ul>
+
+</div>
+
+<div id="content">
+
+ <h2>package_path_searcher.lua</h2>
+<pre>
+<span class="comment">-- Allows Lua modules to be loaded from package.path and package.cpath.
+</span><span class="comment">--
+</span><span class="comment">-- This behavior is overridden by default in LuaTeX. This module reverts the
+</span><span class="comment">-- packaging searching logic to use package.path and package.cpath first,
+</span><span class="comment">-- failing which it tries to use the overridden loading logic (which uses
+</span><span class="comment">-- kpse).
+</span><span class="comment">--
+</span><span class="comment">-- Package Loading References:
+</span><span class="comment">-- 1. http://www.lua.org/manual/5.2/manual.html#pdf-package.searchers
+</span><span class="comment">-- 2. LuaTeX Manual, Section 3.2, Lua behavior
+</span>
+<span class="keyword">local</span> make_loader = <span class="keyword">function</span>(path, pos,loadfunc)
+ <span class="keyword">local</span> default_loader = <span class="global">package</span>.searchers[pos]
+ <span class="keyword">local</span> loader = <span class="keyword">function</span>(name)
+ <span class="keyword">local</span> file = <span class="global">package</span>.searchpath(name,path)
+ <span class="keyword">if</span> <span class="keyword">not</span> file <span class="keyword">then</span>
+ <span class="keyword">local</span> msg = <span class="string">"\n\t[lualoader] Search failed"</span>
+ <span class="keyword">local</span> ret = default_loader(name)
+ <span class="keyword">if</span> <span class="global">type</span>(ret) == <span class="string">"string"</span> <span class="keyword">then</span>
+ <span class="keyword">return</span> msg ..ret
+ <span class="keyword">elseif</span> <span class="global">type</span>(ret) == <span class="string">"nil"</span> <span class="keyword">then</span>
+ <span class="keyword">return</span> msg
+ <span class="keyword">else</span>
+ <span class="keyword">return</span> ret
+ <span class="keyword">end</span>
+ <span class="keyword">end</span>
+ <span class="keyword">local</span> loader,err = loadfunc(file)
+ <span class="keyword">if</span> <span class="keyword">not</span> loader <span class="keyword">then</span>
+ <span class="keyword">return</span> <span class="string">"\n\t[lualoader] Loading error:\n\t"</span>..err
+ <span class="keyword">end</span>
+ <span class="keyword">return</span> loader
+ <span class="keyword">end</span>
+ <span class="global">package</span>.searchers[pos] = loader
+<span class="keyword">end</span>
+
+<span class="keyword">local</span> binary_loader = <span class="keyword">function</span>(file)
+ <span class="keyword">local</span> base = file:match(<span class="string">"/([^%.]+)%.[%w]+$"</span>)
+ <span class="keyword">local</span> symbol = base:gsub(<span class="string">"%."</span>,<span class="string">"_"</span>)
+ <span class="keyword">return</span> <span class="global">package</span>.loadlib(file, <span class="string">"luaopen_"</span>..symbol)
+<span class="keyword">end</span>
+
+make_loader(<span class="global">package</span>.path,<span class="number">2</span>,<span class="global">loadfile</span>)
+make_loader(<span class="global">package</span>.cpath,<span class="number">3</span>, binary_loader)</pre>
+
+
+</div> <!-- id="content" -->
+</div> <!-- id="main" -->
+<div id="about">
+<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.5</a></i>
+<i style="float:right;">Last updated 2016-08-31 21:59:58 </i>
+</div> <!-- id="about" -->
+</div> <!-- id="container" -->
+</body>
+</html>
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/index.html b/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/index.html
new file mode 100644
index 00000000000..443a4117ffc
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/index.html
@@ -0,0 +1,2829 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+<head>
+ <title>luaharfbuzz Documentation</title>
+ <link rel="stylesheet" href="ldoc.css" type="text/css" />
+</head>
+<body>
+
+<div id="container">
+
+<div id="product">
+ <div id="product_logo"></div>
+ <div id="product_name"><big><b></b></big></div>
+ <div id="product_description"></div>
+</div> <!-- id="product" -->
+
+
+<div id="main">
+
+
+<!-- Menu -->
+
+<div id="navigation">
+<br/>
+<h1>luaharfbuzz</h1>
+
+
+<h2>Contents</h2>
+<ul>
+<li><a href="#Functions">Functions</a></li>
+<li><a href="#Class_Blob">Class Blob </a></li>
+<li><a href="#Class_Face">Class Face </a></li>
+<li><a href="#Class_Font">Class Font </a></li>
+<li><a href="#Class_Buffer">Class Buffer </a></li>
+<li><a href="#Cluster_Levels">Cluster Levels </a></li>
+<li><a href="#Class_Feature">Class Feature </a></li>
+<li><a href="#Class_Tag">Class Tag </a></li>
+<li><a href="#Class_Script">Class Script </a></li>
+<li><a href="#Predefined_Script_Codes">Predefined Script Codes </a></li>
+<li><a href="#Class_Direction">Class Direction </a></li>
+<li><a href="#Predefined_directions">Predefined directions </a></li>
+<li><a href="#Class_Language">Class Language </a></li>
+<li><a href="#Predefined_languages">Predefined languages </a></li>
+<li><a href="#Unicode_functions">Unicode functions </a></li>
+<li><a href="#Predefined_Name_IDs">Predefined Name IDs </a></li>
+</ul>
+
+
+<h2>Modules</h2>
+<ul class="nowrap">
+ <li><strong>harfbuzz</strong></li>
+</ul>
+<h2>Examples</h2>
+<ul class="nowrap">
+ <li><a href="examples/core_types.lua.html">core_types.lua</a></li>
+</ul>
+
+</div>
+
+<div id="content">
+
+<h1>Module <code>harfbuzz</code></h1>
+<p>Lua bindings to Harfbuzz.</p>
+<p>
+
+<ul>
+ <li><a href="http://github.com/deepakjois/luaharfbuzz/wiki">Wiki</a></li>
+ <li><a href="https://github.com/deepakjois/luaharfbuzz">Source on Github</a></li>
+ <li><a href="https://github.com/deepakjois/luaharfbuzz/blob/master/status/done.txt">API Coverage Status</a></li>
+</ul>
+</p>
+ <h3>Info:</h3>
+ <ul>
+ <li><strong>Copyright</strong>: 2016</li>
+ <li><strong>License</strong>: MIT</li>
+ <li><strong>Author</strong>: Deepak Jois <<a href="&#x6d;&#97;&#x69;&#108;&#x74;&#111;&#x3a;d&#101;&#x65;&#112;&#x61;&#107;&#x2e;&#106;&#x6f;i&#115;&#x40;&#103;&#x6d;&#97;&#x69;&#108;&#x2e;&#99;&#x6f;m">&#x64;&#101;&#x65;&#112;&#x61;&#107;&#x2e;j&#111;&#x69;&#115;&#x40;&#103;&#x6d;&#97;&#x69;l&#46;&#x63;&#111;&#x6d;</a>></li>
+ </ul>
+
+
+<h2><a href="#Functions">Functions</a></h2>
+<table class="function_list">
+ <tr>
+ <td class="name" nowrap><a href="#version">version ()</a></td>
+ <td class="summary">Wraps <code>hb_version</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#shape">shape (font, buffer[, options])</a></td>
+ <td class="summary">Wraps <code>hb_shape</code>.</td>
+ </tr>
+</table>
+<h2><a href="#Class_Blob">Class Blob </a></h2>
+<table class="function_list">
+ <tr>
+ <td class="name" nowrap><a href="#Blob.new">Blob.new (data)</a></td>
+ <td class="summary">Wraps <code>hb_blob_create</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Blob.new_from_file">Blob.new_from_file (filename)</a></td>
+ <td class="summary">Wraps <code>hb_blob_create_from_file</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Blob:get_length">Blob:get_length ()</a></td>
+ <td class="summary">Wraps <code>hb_blob_get_length</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Blob:get_data">Blob:get_data ()</a></td>
+ <td class="summary">Wraps <code>hb_blob_get_data</code>.</td>
+ </tr>
+</table>
+<h2><a href="#Class_Face">Class Face </a></h2>
+<table class="function_list">
+ <tr>
+ <td class="name" nowrap><a href="#Face.new_from_blob">Face.new_from_blob (blob[, font_index=0])</a></td>
+ <td class="summary">Wraps <code>hb_face_create</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Face.new">Face.new (file[, font_index=0])</a></td>
+ <td class="summary">Create a new <code>Face</code> from a file.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Face:collect_unicodes">Face:collect_unicodes ()</a></td>
+ <td class="summary">Wraps <code>hb_face_collect_unicodes</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Face:get_glyph_count">Face:get_glyph_count ()</a></td>
+ <td class="summary">Wraps <code>hb_face_get_glyph_count</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Face:get_table">Face:get_table (tag)</a></td>
+ <td class="summary">Wraps <code>hb_face_reference_table</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Face:get_table_tags">Face:get_table_tags ()</a></td>
+ <td class="summary">Wraps <code>hb_face_get_table_tags</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Face:get_upem">Face:get_upem ()</a></td>
+ <td class="summary">Wraps <code>hb_face_get_upem</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Face:ot_color_has_palettes">Face:ot_color_has_palettes ()</a></td>
+ <td class="summary">Wraps <code>hb_ot_color_has_palettes</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Face:ot_color_palette_get_count">Face:ot_color_palette_get_count ()</a></td>
+ <td class="summary">Wraps <code>hb_ot_color_palette_get_count</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Face:ot_color_palette_get_colors">Face:ot_color_palette_get_colors ()</a></td>
+ <td class="summary">Wraps <code>hb_ot_color_palette_get_colors</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Face:ot_color_has_layers">Face:ot_color_has_layers ()</a></td>
+ <td class="summary">Wraps <code>hb_ot_color_has_layers</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Face:ot_color_glyph_get_layers">Face:ot_color_glyph_get_layers ()</a></td>
+ <td class="summary">Wraps <code>hb_ot_color_glyph_get_layers</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Face:ot_color_has_png">Face:ot_color_has_png ()</a></td>
+ <td class="summary">Wraps <code>hb_ot_color_has_png</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Face:ot_layout_get_script_tags">Face:ot_layout_get_script_tags ()</a></td>
+ <td class="summary">Wraps <code>hb_ot_layout_table_get_script_tags</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Face:ot_layout_get_language_tags">Face:ot_layout_get_language_tags ()</a></td>
+ <td class="summary">Wraps <code>hb_ot_layout_script_get_language_tags</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Face:ot_layout_get_feature_tags">Face:ot_layout_get_feature_tags ()</a></td>
+ <td class="summary">Wraps <code>hb_ot_layout_language_get_feature_tags</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Face:ot_layout_find_script">Face:ot_layout_find_script ()</a></td>
+ <td class="summary">Wraps <code>hb_ot_layout_table_find_script</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Face:ot_layout_find_language">Face:ot_layout_find_language ()</a></td>
+ <td class="summary">Wraps <code>hb_ot_layout_script_find_language</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Face:ot_layout_find_feature">Face:ot_layout_find_feature ()</a></td>
+ <td class="summary">Wraps <code>hb_ot_layout_language_find_feature</code>.</td>
+ </tr>
+</table>
+<h2><a href="#Class_Font">Class Font </a></h2>
+<table class="function_list">
+ <tr>
+ <td class="name" nowrap><a href="#Font.new">Font.new (face)</a></td>
+ <td class="summary">Wraps <code>hb_font_create</code>, and sets up some defaults for scale and shaping functions.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Font:get_scale">Font:get_scale ()</a></td>
+ <td class="summary">Wraps <code>hb_font_get_scale</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Font:set_scale">Font:set_scale (x_scale, y_scale)</a></td>
+ <td class="summary">Wraps <code>hb_font_set_scale</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Font:get_h_extents">Font:get_h_extents ()</a></td>
+ <td class="summary">Wraps <code>hb_font_get_h_extents</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Font:get_v_extents">Font:get_v_extents ()</a></td>
+ <td class="summary">Wraps <code>hb_font_get_v_extents</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Font:get_glyph_extents">Font:get_glyph_extents (glyph)</a></td>
+ <td class="summary">Wraps <code>hb_font_get_glyph_extents</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Font:get_glyph_name">Font:get_glyph_name (glyph)</a></td>
+ <td class="summary">Wraps <code>hb_font_get_glyph_name</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Font:get_glyph_from_name">Font:get_glyph_from_name (name)</a></td>
+ <td class="summary">Wraps <code>hb_font_get_glyph_from_name</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Font:get_glyph_h_advance">Font:get_glyph_h_advance (glyph)</a></td>
+ <td class="summary">Wraps <code>hb_font_get_glyph_h_advance</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Font:get_glyph_v_advance">Font:get_glyph_v_advance (glyph)</a></td>
+ <td class="summary">Wraps <code>hb_font_get_glyph_v_advance</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Font:get_nominal_glyph">Font:get_nominal_glyph (codepoint.)</a></td>
+ <td class="summary">Wraps <code>hb_font_get_nominal_glyph</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Font:ot_color_glyph_get_png">Font:ot_color_glyph_get_png ()</a></td>
+ <td class="summary">Wraps <code>hb_ot_color_glyph_get_png</code>.</td>
+ </tr>
+</table>
+<h2><a href="#Class_Buffer">Class Buffer </a></h2>
+<table class="function_list">
+ <tr>
+ <td class="name" nowrap><a href="#Buffer.new">Buffer.new ()</a></td>
+ <td class="summary">Wraps <code>hb_buffer_create</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Buffer:add_utf8">Buffer:add_utf8 (text[, item_offset=0[, item_length=-1]])</a></td>
+ <td class="summary">Wraps <code>hb_buffer_add_utf8</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Buffer:add_codepoints">Buffer:add_codepoints (text[, item_offset=0[, item_length=-1]])</a></td>
+ <td class="summary">Wraps <code>hb_buffer_add_codepoints</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Buffer:set_direction">Buffer:set_direction (dir)</a></td>
+ <td class="summary">Wraps <code>hb_buffer_set_direction</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Buffer:get_direction">Buffer:get_direction ()</a></td>
+ <td class="summary">Wraps <code>hb_buffer_get_direction</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Buffer:set_script">Buffer:set_script (script)</a></td>
+ <td class="summary">Wraps <code>hb_buffer_set_script</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Buffer:get_script">Buffer:get_script ()</a></td>
+ <td class="summary">Wraps <code>hb_buffer_get_script</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Buffer:set_language">Buffer:set_language (lang)</a></td>
+ <td class="summary">Wraps <code>hb_buffer_set_language</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Buffer:get_language">Buffer:get_language ()</a></td>
+ <td class="summary">Wraps <code>hb_buffer_get_language</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Buffer:reverse">Buffer:reverse ()</a></td>
+ <td class="summary">Wraps <code>hb_buffer_reverse</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Buffer:get_length">Buffer:get_length ()</a></td>
+ <td class="summary">Wraps <code>hb_buffer_get_length</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Buffer:get_cluster_level">Buffer:get_cluster_level ()</a></td>
+ <td class="summary">Wraps <code>hb_buffer_get_cluster_level</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Buffer:set_cluster_level">Buffer:set_cluster_level (level)</a></td>
+ <td class="summary">Wraps <code>hb_buffer_set_cluster_level</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Buffer:guess_segment_properties">Buffer:guess_segment_properties ()</a></td>
+ <td class="summary">Wraps <code>hb_buffer_guess_segment_properties</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Buffer:get_glyphs">Buffer:get_glyphs ()</a></td>
+ <td class="summary">Helper method to get shaped glyph data.</td>
+ </tr>
+</table>
+<h2><a href="#Cluster_Levels">Cluster Levels </a></h2>
+<table class="function_list">
+ <tr>
+ <td class="name" nowrap><a href="#Buffer.CLUSTER_LEVEL_MONOTONE_GRAPHEMES">Buffer.CLUSTER_LEVEL_MONOTONE_GRAPHEMES</a></td>
+ <td class="summary">Wraps <code>HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Buffer.CLUSTER_LEVEL_MONOTONE_CHARACTERS">Buffer.CLUSTER_LEVEL_MONOTONE_CHARACTERS</a></td>
+ <td class="summary">Wraps <code>HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Buffer.CLUSTER_LEVEL_CHARACTERS">Buffer.CLUSTER_LEVEL_CHARACTERS</a></td>
+ <td class="summary">Wraps <code>HB_BUFFER_CLUSTER_LEVEL_CHARACTERS</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Buffer.CLUSTER_LEVEL_DEFAULT">Buffer.CLUSTER_LEVEL_DEFAULT</a></td>
+ <td class="summary">Wraps <code>HB_BUFFER_CLUSTER_LEVEL_DEFAULT</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Buffer.GLYPH_FLAG_UNSAFE_TO_BREAK">Buffer.GLYPH_FLAG_UNSAFE_TO_BREAK</a></td>
+ <td class="summary">Wraps <code>HB_GLYPH_FLAG_UNSAFE_TO_BREAK</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Buffer.GLYPH_FLAG_DEFINED">Buffer.GLYPH_FLAG_DEFINED</a></td>
+ <td class="summary">Wraps <code>HB_GLYPH_FLAG_DEFINED</code>.</td>
+ </tr>
+</table>
+<h2><a href="#Class_Feature">Class Feature </a></h2>
+<table class="function_list">
+ <tr>
+ <td class="name" nowrap><a href="#Feature.new">Feature.new (feature_string)</a></td>
+ <td class="summary">Wraps <code>hb_feature_from_string</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Feature:__tostring">Feature:__tostring ()</a></td>
+ <td class="summary">Wraps <code>hb_feature_to_string</code>.</td>
+ </tr>
+</table>
+<h2><a href="#Class_Tag">Class Tag </a></h2>
+<table class="function_list">
+ <tr>
+ <td class="name" nowrap><a href="#Tag.new">Tag.new (string)</a></td>
+ <td class="summary">Wraps <code>hb_tag_from_string</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Tag:__to_string">Tag:__to_string ()</a></td>
+ <td class="summary">Wraps <code>hb_tag_to_string</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Tag:__eq">Tag:__eq ()</a></td>
+ <td class="summary">Enables equality comparisions with <code>==</code> between two tags.</td>
+ </tr>
+</table>
+<h2><a href="#Class_Script">Class Script </a></h2>
+<table class="function_list">
+ <tr>
+ <td class="name" nowrap><a href="#Script.new">Script.new (script)</a></td>
+ <td class="summary">Wraps <code>hb_script_from_string</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Script.from_iso15924_tag">Script.from_iso15924_tag (tag)</a></td>
+ <td class="summary">Wraps <code>hb_script_from_iso15924_tag</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Script:to_iso15924_tag">Script:to_iso15924_tag ()</a></td>
+ <td class="summary">Wraps <code>hb_script_to_iso15924_tag</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Script:__to_string">Script:__to_string ()</a></td>
+ <td class="summary">Enable nice output with <code>tostring(…)</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Script:__eq">Script:__eq ()</a></td>
+ <td class="summary">Enables equality comparisions with <code>==</code> between two scripts.</td>
+ </tr>
+</table>
+<h2><a href="#Predefined_Script_Codes">Predefined Script Codes </a></h2>
+<table class="function_list">
+ <tr>
+ <td class="name" nowrap><a href="#Script.COMMON">Script.COMMON</a></td>
+ <td class="summary">Wraps <code>HB_SCRIPT_COMMON</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Script.INHERITED">Script.INHERITED</a></td>
+ <td class="summary">Wraps <code>HB_SCRIPT_INHERITED</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Script.UNKNOWN">Script.UNKNOWN</a></td>
+ <td class="summary">Wraps <code>HB_SCRIPT_UNKNOWN</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Script.INVALID">Script.INVALID</a></td>
+ <td class="summary">Wraps <code>HB_SCRIPT_INVALID</code>.</td>
+ </tr>
+</table>
+<h2><a href="#Class_Direction">Class Direction </a></h2>
+<table class="function_list">
+ <tr>
+ <td class="name" nowrap><a href="#Direction.new">Direction.new (dir)</a></td>
+ <td class="summary">Wraps <code>hb_direction_from_string</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Direction:__to_string">Direction:__to_string ()</a></td>
+ <td class="summary">Wraps <code>hb_direction_to_string</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Direction:__eq">Direction:__eq ()</a></td>
+ <td class="summary">Enables equality comparisions with <code>==</code> between two directions.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Direction:is_valid">Direction:is_valid ()</a></td>
+ <td class="summary">Wraps <code>HB_DIRECTION_IS_VALID</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Direction:is_horizontal">Direction:is_horizontal ()</a></td>
+ <td class="summary">Wraps <code>HB_DIRECTION_IS_HORIZONTAL</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Direction:is_vertical">Direction:is_vertical ()</a></td>
+ <td class="summary">Wraps <code>HB_DIRECTION_IS_VERTICAL</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Direction:is_forward">Direction:is_forward ()</a></td>
+ <td class="summary">Wraps <code>HB_DIRECTION_IS_FORWARD</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Direction:is_backward">Direction:is_backward ()</a></td>
+ <td class="summary">Wraps <code>HB_DIRECTION_IS_BACKWARD</code>.</td>
+ </tr>
+</table>
+<h2><a href="#Predefined_directions">Predefined directions </a></h2>
+<table class="function_list">
+ <tr>
+ <td class="name" nowrap><a href="#Direction.LTR">Direction.LTR</a></td>
+ <td class="summary">Wraps <code>HB_DIRECTION_LTR</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Direction.RTL">Direction.RTL</a></td>
+ <td class="summary">Wraps <code>HB_DIRECTION_RTL</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Direction.TTB">Direction.TTB</a></td>
+ <td class="summary">Wraps <code>HB_DIRECTION_TTB</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Direction.BTT">Direction.BTT</a></td>
+ <td class="summary">Wraps <code>HB_DIRECTION_LTR</code>.</td>
+ </tr>
+</table>
+<h2><a href="#Class_Language">Class Language </a></h2>
+<table class="function_list">
+ <tr>
+ <td class="name" nowrap><a href="#Language.new">Language.new (lang)</a></td>
+ <td class="summary">Wraps <code>hb_language_from_string</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Language:__to_string">Language:__to_string ()</a></td>
+ <td class="summary">Wraps <code>hb_language_to_string</code>.</td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#Language:__eq">Language:__eq ()</a></td>
+ <td class="summary">Enables equality comparisions with <code>==</code> between two languages.</td>
+ </tr>
+</table>
+<h2><a href="#Predefined_languages">Predefined languages </a></h2>
+<table class="function_list">
+ <tr>
+ <td class="name" nowrap><a href="#Language.INVALID">Language.INVALID</a></td>
+ <td class="summary">Wraps <code>HB_LANGUAGE_INVALID</code>.</td>
+ </tr>
+</table>
+<h2><a href="#Unicode_functions">Unicode functions </a></h2>
+<table class="function_list">
+ <tr>
+ <td class="name" nowrap><a href="#unicode.script">unicode.script (char)</a></td>
+ <td class="summary">Wraps <code>hb_unicode_script</code></td>
+ </tr>
+</table>
+<h2><a href="#Predefined_Name_IDs">Predefined Name IDs </a></h2>
+<table class="function_list">
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_COPYRIGHT">ot.NAME_ID_COPYRIGHT</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_COPYRIGHT</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_FONT_FAMILY">ot.NAME_ID_FONT_FAMILY</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_FONT_FAMILY</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_FONT_SUBFAMILY">ot.NAME_ID_FONT_SUBFAMILY</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_FONT_SUBFAMILY</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_UNIQUE_ID">ot.NAME_ID_UNIQUE_ID</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_UNIQUE_ID</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_FULL_NAME">ot.NAME_ID_FULL_NAME</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_FULL_NAME</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_VERSION_STRING">ot.NAME_ID_VERSION_STRING</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_VERSION_STRING</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_POSTSCRIPT_NAME">ot.NAME_ID_POSTSCRIPT_NAME</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_POSTSCRIPT_NAME</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_TRADEMARK">ot.NAME_ID_TRADEMARK</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_TRADEMARK</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_MANUFACTURER">ot.NAME_ID_MANUFACTURER</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_MANUFACTURER</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_DESIGNER">ot.NAME_ID_DESIGNER</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_DESIGNER</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_DESCRIPTION">ot.NAME_ID_DESCRIPTION</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_DESCRIPTION</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_VENDOR_URL">ot.NAME_ID_VENDOR_URL</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_VENDOR_URL</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_DESIGNER_URL">ot.NAME_ID_DESIGNER_URL</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_DESIGNER_URL</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_LICENSE">ot.NAME_ID_LICENSE</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_LICENSE</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_LICENSE_URL">ot.NAME_ID_LICENSE_URL</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_LICENSE_URL</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_TYPOGRAPHIC_FAMILY">ot.NAME_ID_TYPOGRAPHIC_FAMILY</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_TYPOGRAPHIC_FAMILY</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_TYPOGRAPHIC_SUBFAMILY">ot.NAME_ID_TYPOGRAPHIC_SUBFAMILY</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_TYPOGRAPHIC_SUBFAMILY</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_MAC_FULL_NAME">ot.NAME_ID_MAC_FULL_NAME</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_MAC_FULL_NAME</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_SAMPLE_TEXT">ot.NAME_ID_SAMPLE_TEXT</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_SAMPLE_TEXT</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_CID_FINDFONT_NAME">ot.NAME_ID_CID_FINDFONT_NAME</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_CID_FINDFONT_NAME</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_WWS_FAMILY">ot.NAME_ID_WWS_FAMILY</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_WWS_FAMILY</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_WWS_SUBFAMILY">ot.NAME_ID_WWS_SUBFAMILY</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_WWS_SUBFAMILY</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_LIGHT_BACKGROUND">ot.NAME_ID_LIGHT_BACKGROUND</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_LIGHT_BACKGROUND</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_DARK_BACKGROUND">ot.NAME_ID_DARK_BACKGROUND</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_DARK_BACKGROUND</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_VARIATIONS_PS_PREFIX">ot.NAME_ID_VARIATIONS_PS_PREFIX</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_VARIATIONS_PS_PREFIX</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.NAME_ID_INVALID">ot.NAME_ID_INVALID</a></td>
+ <td class="summary">Wraps <code>HB_OT_NAME_ID_INVALID</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.LAYOUT_NO_SCRIPT_INDEX">ot.LAYOUT_NO_SCRIPT_INDEX</a></td>
+ <td class="summary">Wraps <code>HB_OT_LAYOUT_NO_SCRIPT_INDEX</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.LAYOUT_NO_FEATURE_INDEX">ot.LAYOUT_NO_FEATURE_INDEX</a></td>
+ <td class="summary">Wraps <code>HB_OT_LAYOUT_NO_FEATURE_INDEX</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.LAYOUT_DEFAULT_LANGUAGE_INDEX">ot.LAYOUT_DEFAULT_LANGUAGE_INDEX</a></td>
+ <td class="summary">Wraps <code>HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX</code></td>
+ </tr>
+ <tr>
+ <td class="name" nowrap><a href="#ot.LAYOUT_NO_VARIATIONS_INDEX">ot.LAYOUT_NO_VARIATIONS_INDEX</a></td>
+ <td class="summary">Wraps <code>HB_OT_LAYOUT_NO_VARIATIONS_INDEX</code></td>
+ </tr>
+</table>
+
+<br/>
+<br/>
+
+
+ <h2 class="section-header "><a name="Functions"></a>Functions</h2>
+
+ <dl class="function">
+ <dt>
+ <a name = "version"></a>
+ <strong>version ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_version</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "shape"></a>
+ <strong>shape (font, buffer[, options])</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_shape</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">font</span>
+ <code>Font</code> to use for shaping
+ </li>
+ <li><span class="parameter">buffer</span>
+ <code>Buffer</code> to shape
+ </li>
+ <li><span class="parameter">options</span>
+
+<p> table containing one or more supported options:</p>
+
+<ul>
+ <li><code>direction</code>: A <code>Direction</code> object representing the object.</li>
+ <li><code>script</code>: A <code>Script</code> object representing the script.</li>
+ <li><code>language</code>: A <code>Language</code> object representing the language.</li>
+ <li><code>features</code>: features to enable, specified as either of the following.
+ <ul>
+ <li>comma-separated list of features. See <a href="https://github.com/deepakjois/luaharfbuzz/wiki/Feature-Strings">feature string syntax reference</a></li>
+ <li>table of <code>Feature</code> objects</li>
+ </ul></li>
+</ul>
+
+ (<em>optional</em>)
+ </li>
+ </ul>
+
+
+
+
+
+</dd>
+</dl>
+ <h2 class="section-header has-description"><a name="Class_Blob"></a>Class Blob </h2>
+
+ <div class="section-description">
+ Lua wrapper for <code>hb_blob_t</code> type
+ </div>
+ <dl class="function">
+ <dt>
+ <a name = "Blob.new"></a>
+ <strong>Blob.new (data)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_blob_create</code>.
+ Initializes a new <code>hb_blob_t</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">data</span>
+ lua string containing binary or character data.
+ </li>
+ </ul>
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Blob.new_from_file"></a>
+ <strong>Blob.new_from_file (filename)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_blob_create_from_file</code>.
+ Initializes a new <code>hb_blob_t</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">filename</span>
+ lua string.
+ </li>
+ </ul>
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Blob:get_length"></a>
+ <strong>Blob:get_length ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_blob_get_length</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Blob:get_data"></a>
+ <strong>Blob:get_data ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_blob_get_data</code>.
+
+
+
+
+
+
+
+</dd>
+</dl>
+ <h2 class="section-header has-description"><a name="Class_Face"></a>Class Face </h2>
+
+ <div class="section-description">
+ Lua wrapper for <code>hb_face_t</code> type
+ </div>
+ <dl class="function">
+ <dt>
+ <a name = "Face.new_from_blob"></a>
+ <strong>Face.new_from_blob (blob[, font_index=0])</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_face_create</code>.
+ Initializes a new <code>hb_face_t</code> from a <code>Blob</code> object.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">blob</span>
+ <code>Blob</code> to read the font from.
+ </li>
+ <li><span class="parameter">font_index</span>
+ index of font to read.
+ (<em>default</em> 0)
+ </li>
+ </ul>
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Face.new"></a>
+ <strong>Face.new (file[, font_index=0])</strong>
+ </dt>
+ <dd>
+ Create a new <code>Face</code> from a file.
+ Makes a call to <code>Face:new_from_blob</code> after creating a <code>Blob</code> from the
+ file contents.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">file</span>
+ path to font file.
+ </li>
+ <li><span class="parameter">font_index</span>
+ index of font to read.
+ (<em>default</em> 0)
+ </li>
+ </ul>
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Face:collect_unicodes"></a>
+ <strong>Face:collect_unicodes ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_face_collect_unicodes</code>.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ table of codepoints supported by the face.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Face:get_glyph_count"></a>
+ <strong>Face:get_glyph_count ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_face_get_glyph_count</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Face:get_table"></a>
+ <strong>Face:get_table (tag)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_face_reference_table</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">tag</span>
+ <code>Tag</code> object of the table.
+ </li>
+ </ul>
+
+ <h3>Returns:</h3>
+ <ol>
+
+ <code>Blob</code> object for the face table of <code>tag</code>.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Face:get_table_tags"></a>
+ <strong>Face:get_table_tags ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_face_get_table_tags</code>.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ table of <code>Tag</code>s representing face table tags.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Face:get_upem"></a>
+ <strong>Face:get_upem ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_face_get_upem</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Face:ot_color_has_palettes"></a>
+ <strong>Face:ot_color_has_palettes ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_ot_color_has_palettes</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Face:ot_color_palette_get_count"></a>
+ <strong>Face:ot_color_palette_get_count ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_ot_color_palette_get_count</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Face:ot_color_palette_get_colors"></a>
+ <strong>Face:ot_color_palette_get_colors ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_ot_color_palette_get_colors</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Face:ot_color_has_layers"></a>
+ <strong>Face:ot_color_has_layers ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_ot_color_has_layers</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Face:ot_color_glyph_get_layers"></a>
+ <strong>Face:ot_color_glyph_get_layers ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_ot_color_glyph_get_layers</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Face:ot_color_has_png"></a>
+ <strong>Face:ot_color_has_png ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_ot_color_has_png</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Face:ot_layout_get_script_tags"></a>
+ <strong>Face:ot_layout_get_script_tags ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_ot_layout_table_get_script_tags</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Face:ot_layout_get_language_tags"></a>
+ <strong>Face:ot_layout_get_language_tags ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_ot_layout_script_get_language_tags</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Face:ot_layout_get_feature_tags"></a>
+ <strong>Face:ot_layout_get_feature_tags ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_ot_layout_language_get_feature_tags</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Face:ot_layout_find_script"></a>
+ <strong>Face:ot_layout_find_script ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_ot_layout_table_find_script</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Face:ot_layout_find_language"></a>
+ <strong>Face:ot_layout_find_language ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_ot_layout_script_find_language</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Face:ot_layout_find_feature"></a>
+ <strong>Face:ot_layout_find_feature ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_ot_layout_language_find_feature</code>.
+
+
+
+
+
+
+
+</dd>
+</dl>
+ <h2 class="section-header has-description"><a name="Class_Font"></a>Class Font </h2>
+
+ <div class="section-description">
+ Lua wrapper for <code>hb_font_t</code> type
+ </div>
+ <dl class="function">
+ <dt>
+ <a name = "Font.new"></a>
+ <strong>Font.new (face)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_font_create</code>, and sets up some defaults for scale and shaping functions.
+ Initializes a new <code>hb_font_t</code> from a <code>Face</code> object. Sets the default scale
+ to the face’s upem value, and sets the font shaping functions by
+ calling <code>hb_ot_font_set_funcs</code> on it.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">face</span>
+ <code>Face</code> object.
+ </li>
+ </ul>
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Font:get_scale"></a>
+ <strong>Font:get_scale ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_font_get_scale</code>.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ two values for the x-scale and y-scale of the font.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Font:set_scale"></a>
+ <strong>Font:set_scale (x_scale, y_scale)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_font_set_scale</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">x_scale</span>
+ desired x-scale of font.
+ </li>
+ <li><span class="parameter">y_scale</span>
+ desired y-scale of font.
+ </li>
+ </ul>
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Font:get_h_extents"></a>
+ <strong>Font:get_h_extents ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_font_get_h_extents</code>.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+
+<p> font extents table for horizontal direction, contains the following
+ or <code>nil</code> if HarfBuzz fails to load font extents:</p>
+
+<ul>
+ <li><code>ascender</code>: typographic ascender.</li>
+ <li><code>descender</code>: typographic descender.</li>
+ <li><code>line_gap</code>: line spacing gap.</li>
+</ul>
+
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Font:get_v_extents"></a>
+ <strong>Font:get_v_extents ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_font_get_v_extents</code>.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ font extents table for vertical direction, similar to
+ <code>Font:get_h_extents</code>, or <code>nil</code> if HarfBuzz fails to load font extents:
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Font:get_glyph_extents"></a>
+ <strong>Font:get_glyph_extents (glyph)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_font_get_glyph_extents</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">glyph</span>
+ index inside the font.
+ </li>
+ </ul>
+
+ <h3>Returns:</h3>
+ <ol>
+
+
+<p> extents table contains the following or <code>nil</code> if HarfBuzz fails to
+ load glyph extents:</p>
+
+<ul>
+ <li><code>x_bearing</code>: left side of glyph from origin.</li>
+ <li><code>y_bearing</code>: top side of glyph from origin.</li>
+ <li><code>width</code>: distance from left to right side.</li>
+ <li><code>height</code>: distance from top to bottom side.</li>
+</ul>
+
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Font:get_glyph_name"></a>
+ <strong>Font:get_glyph_name (glyph)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_font_get_glyph_name</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">glyph</span>
+ index inside the font.
+ </li>
+ </ul>
+
+ <h3>Returns:</h3>
+ <ol>
+
+ name of the glyph or nil.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Font:get_glyph_from_name"></a>
+ <strong>Font:get_glyph_from_name (name)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_font_get_glyph_from_name</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">name</span>
+ of the glyph.
+ </li>
+ </ul>
+
+ <h3>Returns:</h3>
+ <ol>
+
+ glyph index inside the font or nil.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Font:get_glyph_h_advance"></a>
+ <strong>Font:get_glyph_h_advance (glyph)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_font_get_glyph_h_advance</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">glyph</span>
+ index inside the font.
+ </li>
+ </ul>
+
+ <h3>Returns:</h3>
+ <ol>
+
+ advance glyph advance of the glyph in horizontal direction.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Font:get_glyph_v_advance"></a>
+ <strong>Font:get_glyph_v_advance (glyph)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_font_get_glyph_v_advance</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">glyph</span>
+ index inside the font.
+ </li>
+ </ul>
+
+ <h3>Returns:</h3>
+ <ol>
+
+ advance glyph advance of the glyph in vertical direction.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Font:get_nominal_glyph"></a>
+ <strong>Font:get_nominal_glyph (codepoint.)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_font_get_nominal_glyph</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">codepoint.</span>
+
+
+
+ </li>
+ </ul>
+
+ <h3>Returns:</h3>
+ <ol>
+
+ glyph index or <code>nil</code> if <code>codepoint</code> is not supported by the font.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Font:ot_color_glyph_get_png"></a>
+ <strong>Font:ot_color_glyph_get_png ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_ot_color_glyph_get_png</code>.
+
+
+
+
+
+
+
+</dd>
+</dl>
+ <h2 class="section-header has-description"><a name="Class_Buffer"></a>Class Buffer </h2>
+
+ <div class="section-description">
+ Lua wrapper for <code>hb_buffer_t</code> type.
+ </div>
+ <dl class="function">
+ <dt>
+ <a name = "Buffer.new"></a>
+ <strong>Buffer.new ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_buffer_create</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Buffer:add_utf8"></a>
+ <strong>Buffer:add_utf8 (text[, item_offset=0[, item_length=-1]])</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_buffer_add_utf8</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">text</span>
+ UTF8 encoded string.
+ </li>
+ <li><span class="parameter">item_offset</span>
+ 0-indexed offset in <code>text</code>, from where to start adding.
+ (<em>default</em> 0)
+ </li>
+ <li><span class="parameter">item_length</span>
+ length to add from <code>item_offset</code>. <code>-1</code> adds till end of <code>text</code>.
+ (<em>default</em> -1)
+ </li>
+ </ul>
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Buffer:add_codepoints"></a>
+ <strong>Buffer:add_codepoints (text[, item_offset=0[, item_length=-1]])</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_buffer_add_codepoints</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">text</span>
+ table with codepoints as lua numbers.
+ </li>
+ <li><span class="parameter">item_offset</span>
+ 0-indexed offset in <code>text</code>, from where to start adding.
+ (<em>default</em> 0)
+ </li>
+ <li><span class="parameter">item_length</span>
+ length to add from <code>item_offset</code>. <code>-1</code> adds till end of&nbsp;<code>text</code>.
+ (<em>default</em> -1)
+ </li>
+ </ul>
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Buffer:set_direction"></a>
+ <strong>Buffer:set_direction (dir)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_buffer_set_direction</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">dir</span>
+ A <code>Direction</code> object.
+ </li>
+ </ul>
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Buffer:get_direction"></a>
+ <strong>Buffer:get_direction ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_buffer_get_direction</code>.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ A <code>Direction</code> object.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Buffer:set_script"></a>
+ <strong>Buffer:set_script (script)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_buffer_set_script</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">script</span>
+ A <code>Script</code> object.
+ </li>
+ </ul>
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Buffer:get_script"></a>
+ <strong>Buffer:get_script ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_buffer_get_script</code>.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ A <code>Script</code> object.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Buffer:set_language"></a>
+ <strong>Buffer:set_language (lang)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_buffer_set_language</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">lang</span>
+ A <code>Language</code> object
+ </li>
+ </ul>
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Buffer:get_language"></a>
+ <strong>Buffer:get_language ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_buffer_get_language</code>.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ A <code>Language</code> object
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Buffer:reverse"></a>
+ <strong>Buffer:reverse ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_buffer_reverse</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Buffer:get_length"></a>
+ <strong>Buffer:get_length ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_buffer_get_length</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Buffer:get_cluster_level"></a>
+ <strong>Buffer:get_cluster_level ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_buffer_get_cluster_level</code>.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ see <a href="#Cluster_Levels">Cluster Levels</a>
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Buffer:set_cluster_level"></a>
+ <strong>Buffer:set_cluster_level (level)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_buffer_set_cluster_level</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">level</span>
+ see <a href="#Cluster_Levels">Cluster Levels</a>
+ </li>
+ </ul>
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Buffer:guess_segment_properties"></a>
+ <strong>Buffer:guess_segment_properties ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_buffer_guess_segment_properties</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Buffer:get_glyphs"></a>
+ <strong>Buffer:get_glyphs ()</strong>
+ </dt>
+ <dd>
+ Helper method to get shaped glyph data.
+ Calls <code>hb_buffer_get_glyph_infos</code>, <code>hb_buffer_get_glyph_positions</code> and
+ <code>hb_glyph_info_get_glyph_flags</code>, and assembles the data into a Lua table.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+
+<p> table containing data for each glyph, in a nested table. Each nested
+ table contains the following:</p>
+
+<ul>
+ <li><code>x_advance</code>: horizontal advance.</li>
+ <li><code>y_advance</code>: vertical advance.</li>
+ <li><code>x_offset</code>: horizontal displacement.</li>
+ <li><code>y_offset</code>: vertical displacement.</li>
+ <li><code>cluster</code>: glyph cluster index within input.</li>
+ <li><code>codepoint</code>: glyph index inside the font <em>(this field name is a bit misleading, but that’s what Harfbuzz uses)</em>.</li>
+ <li><code>flags</code>: glyph flags</li>
+</ul>
+
+ </ol>
+
+
+
+
+</dd>
+</dl>
+ <h2 class="section-header has-description"><a name="Cluster_Levels"></a>Cluster Levels </h2>
+
+ <div class="section-description">
+ See <a href="http://behdad.github.io/harfbuzz/clusters.html">Harfbuzz docs</a> for more details
+ about what each of these levels mean.
+ </div>
+ <dl class="function">
+ <dt>
+ <a name = "Buffer.CLUSTER_LEVEL_MONOTONE_GRAPHEMES"></a>
+ <strong>Buffer.CLUSTER_LEVEL_MONOTONE_GRAPHEMES</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Buffer.CLUSTER_LEVEL_MONOTONE_CHARACTERS"></a>
+ <strong>Buffer.CLUSTER_LEVEL_MONOTONE_CHARACTERS</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Buffer.CLUSTER_LEVEL_CHARACTERS"></a>
+ <strong>Buffer.CLUSTER_LEVEL_CHARACTERS</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_BUFFER_CLUSTER_LEVEL_CHARACTERS</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Buffer.CLUSTER_LEVEL_DEFAULT"></a>
+ <strong>Buffer.CLUSTER_LEVEL_DEFAULT</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_BUFFER_CLUSTER_LEVEL_DEFAULT</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Buffer.GLYPH_FLAG_UNSAFE_TO_BREAK"></a>
+ <strong>Buffer.GLYPH_FLAG_UNSAFE_TO_BREAK</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_GLYPH_FLAG_UNSAFE_TO_BREAK</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Buffer.GLYPH_FLAG_DEFINED"></a>
+ <strong>Buffer.GLYPH_FLAG_DEFINED</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_GLYPH_FLAG_DEFINED</code>.
+
+
+
+
+
+
+
+</dd>
+</dl>
+ <h2 class="section-header has-description"><a name="Class_Feature"></a>Class Feature </h2>
+
+ <div class="section-description">
+ Lua wrapper for <code>hb_feature_t</code> type
+ </div>
+ <dl class="function">
+ <dt>
+ <a name = "Feature.new"></a>
+ <strong>Feature.new (feature_string)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_feature_from_string</code>
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">feature_string</span>
+ See <a href="https://github.com/deepakjois/luaharfbuzz/wiki/Feature-Strings">feature string syntax reference</a>
+ </li>
+ </ul>
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Feature:__tostring"></a>
+ <strong>Feature:__tostring ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_feature_to_string</code>.
+ Enables nice output with <code>tostring(…)</code>.
+
+
+
+
+
+
+
+</dd>
+</dl>
+ <h2 class="section-header has-description"><a name="Class_Tag"></a>Class Tag </h2>
+
+ <div class="section-description">
+ Lua wrapper for <code>hb_tag_t</code> type.
+ </div>
+ <dl class="function">
+ <dt>
+ <a name = "Tag.new"></a>
+ <strong>Tag.new (string)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_tag_from_string</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">string</span>
+ to be converted to a <code>Tag</code> object.
+ </li>
+ </ul>
+
+ <h3>Returns:</h3>
+ <ol>
+
+ a <code>Tag</code> object.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Tag:__to_string"></a>
+ <strong>Tag:__to_string ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_tag_to_string</code>. Enable nice output with <code>tostring(…)</code>.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ Returns a string representation for the tag object.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Tag:__eq"></a>
+ <strong>Tag:__eq ()</strong>
+ </dt>
+ <dd>
+ Enables equality comparisions with <code>==</code> between two tags.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ <code>true</code> or <code>false</code> depending on whether the two tags are equal.
+ </ol>
+
+
+
+
+</dd>
+</dl>
+ <h2 class="section-header has-description"><a name="Class_Script"></a>Class Script </h2>
+
+ <div class="section-description">
+ Lua wrapper for <code>hb_script_t</code> type.
+ </div>
+ <dl class="function">
+ <dt>
+ <a name = "Script.new"></a>
+ <strong>Script.new (script)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_script_from_string</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">script</span>
+ 4-letter script code according to the <a href="http://www.unicode.org/iso15924/iso15924-num.html">ISO 15924 standard</a>.
+ </li>
+ </ul>
+
+ <h3>Returns:</h3>
+ <ol>
+
+ a <code>Script</code> object.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Script.from_iso15924_tag"></a>
+ <strong>Script.from_iso15924_tag (tag)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_script_from_iso15924_tag</code>
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">tag</span>
+ a <code>Tag</code> object representing a <a href="http://www.unicode.org/iso15924/iso15924-num.html">ISO 15924 script</a>.
+ </li>
+ </ul>
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Script:to_iso15924_tag"></a>
+ <strong>Script:to_iso15924_tag ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_script_to_iso15924_tag</code>.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ a <code>Tag</code> object representing the script.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Script:__to_string"></a>
+ <strong>Script:__to_string ()</strong>
+ </dt>
+ <dd>
+ Enable nice output with <code>tostring(…)</code>
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ Returns a 4-letter <a href="http://www.unicode.org/iso15924/iso15924-num.html">ISO 15924 script code</a> for the script object.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Script:__eq"></a>
+ <strong>Script:__eq ()</strong>
+ </dt>
+ <dd>
+ Enables equality comparisions with <code>==</code> between two scripts.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ <code>true</code> or <code>false</code> depending on whether the two scripts are equal.
+ </ol>
+
+
+
+
+</dd>
+</dl>
+ <h2 class="section-header has-description"><a name="Predefined_Script_Codes"></a>Predefined Script Codes </h2>
+
+ <div class="section-description">
+ Predefined directions that correspond to their original definitions in Harfbuzz.
+ </div>
+ <dl class="function">
+ <dt>
+ <a name = "Script.COMMON"></a>
+ <strong>Script.COMMON</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_SCRIPT_COMMON</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Script.INHERITED"></a>
+ <strong>Script.INHERITED</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_SCRIPT_INHERITED</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Script.UNKNOWN"></a>
+ <strong>Script.UNKNOWN</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_SCRIPT_UNKNOWN</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Script.INVALID"></a>
+ <strong>Script.INVALID</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_SCRIPT_INVALID</code>.
+
+
+
+
+
+
+
+</dd>
+</dl>
+ <h2 class="section-header has-description"><a name="Class_Direction"></a>Class Direction </h2>
+
+ <div class="section-description">
+ Lua wrapper for <code>hb_direction_t</code> type.
+ </div>
+ <dl class="function">
+ <dt>
+ <a name = "Direction.new"></a>
+ <strong>Direction.new (dir)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_direction_from_string</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">dir</span>
+ can be one of <code>ltr</code>, <code>rtl</code>, <code>ttb</code>, <code>btt</code> or <code>invalid</code>.
+ </li>
+ </ul>
+
+ <h3>Returns:</h3>
+ <ol>
+
+ a <code>Direction</code> object.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Direction:__to_string"></a>
+ <strong>Direction:__to_string ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_direction_to_string</code>. Enable nice output with <code>tostring(…)</code>.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ Returns a string representation for direction.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Direction:__eq"></a>
+ <strong>Direction:__eq ()</strong>
+ </dt>
+ <dd>
+ Enables equality comparisions with <code>==</code> between two directions.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ <code>true</code> or <code>false</code> depending on whether the two tags are equal.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Direction:is_valid"></a>
+ <strong>Direction:is_valid ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_DIRECTION_IS_VALID</code>.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ a boolean value
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Direction:is_horizontal"></a>
+ <strong>Direction:is_horizontal ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_DIRECTION_IS_HORIZONTAL</code>.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ a boolean value
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Direction:is_vertical"></a>
+ <strong>Direction:is_vertical ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_DIRECTION_IS_VERTICAL</code>.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ a boolean value
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Direction:is_forward"></a>
+ <strong>Direction:is_forward ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_DIRECTION_IS_FORWARD</code>.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ a boolean value
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Direction:is_backward"></a>
+ <strong>Direction:is_backward ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_DIRECTION_IS_BACKWARD</code>.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ a boolean value
+ </ol>
+
+
+
+
+</dd>
+</dl>
+ <h2 class="section-header has-description"><a name="Predefined_directions"></a>Predefined directions </h2>
+
+ <div class="section-description">
+ Predefined directions that correspond to their original definitions in Harfbuzz.
+ </div>
+ <dl class="function">
+ <dt>
+ <a name = "Direction.LTR"></a>
+ <strong>Direction.LTR</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_DIRECTION_LTR</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Direction.RTL"></a>
+ <strong>Direction.RTL</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_DIRECTION_RTL</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Direction.TTB"></a>
+ <strong>Direction.TTB</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_DIRECTION_TTB</code>.
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Direction.BTT"></a>
+ <strong>Direction.BTT</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_DIRECTION_LTR</code>.
+
+
+
+
+
+
+
+</dd>
+</dl>
+ <h2 class="section-header has-description"><a name="Class_Language"></a>Class Language </h2>
+
+ <div class="section-description">
+ Lua wrapper for <code>hb_language_t</code> type.
+ </div>
+ <dl class="function">
+ <dt>
+ <a name = "Language.new"></a>
+ <strong>Language.new (lang)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_language_from_string</code>.
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">lang</span>
+ <a href="http://www.microsoft.com/typography/otspec/languagetags.htm">three-letter language tag</a> to be converted to a <code>Language</code> object.
+ </li>
+ </ul>
+
+ <h3>Returns:</h3>
+ <ol>
+
+ a <code>Language</code> object.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Language:__to_string"></a>
+ <strong>Language:__to_string ()</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_language_to_string</code>. Enable nice output with <code>tostring(…)</code>.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ Returns a string representation for the language object.
+ </ol>
+
+
+
+
+</dd>
+ <dt>
+ <a name = "Language:__eq"></a>
+ <strong>Language:__eq ()</strong>
+ </dt>
+ <dd>
+ Enables equality comparisions with <code>==</code> between two languages.
+
+
+
+ <h3>Returns:</h3>
+ <ol>
+
+ <code>true</code> or <code>false</code> depending on whether the two languages are equal.
+ </ol>
+
+
+
+
+</dd>
+</dl>
+ <h2 class="section-header has-description"><a name="Predefined_languages"></a>Predefined languages </h2>
+
+ <div class="section-description">
+ Predefined languages that correspond to their original definitions in Harfbuzz.
+ </div>
+ <dl class="function">
+ <dt>
+ <a name = "Language.INVALID"></a>
+ <strong>Language.INVALID</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_LANGUAGE_INVALID</code>.
+
+
+
+
+
+
+
+</dd>
+</dl>
+ <h2 class="section-header "><a name="Unicode_functions"></a>Unicode functions </h2>
+
+ <dl class="function">
+ <dt>
+ <a name = "unicode.script"></a>
+ <strong>unicode.script (char)</strong>
+ </dt>
+ <dd>
+ Wraps <code>hb_unicode_script</code>
+
+
+ <h3>Parameters:</h3>
+ <ul>
+ <li><span class="parameter">char</span>
+ Unicode codepoint
+ </li>
+ </ul>
+
+ <h3>Returns:</h3>
+ <ol>
+
+ a <code>Script</code> object.
+ </ol>
+
+
+
+
+</dd>
+</dl>
+ <h2 class="section-header has-description"><a name="Predefined_Name_IDs"></a>Predefined Name IDs </h2>
+
+ <div class="section-description">
+ Predefined OpenType 'name' table name identifier.
+ </div>
+ <dl class="function">
+ <dt>
+ <a name = "ot.NAME_ID_COPYRIGHT"></a>
+ <strong>ot.NAME_ID_COPYRIGHT</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_COPYRIGHT</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_FONT_FAMILY"></a>
+ <strong>ot.NAME_ID_FONT_FAMILY</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_FONT_FAMILY</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_FONT_SUBFAMILY"></a>
+ <strong>ot.NAME_ID_FONT_SUBFAMILY</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_FONT_SUBFAMILY</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_UNIQUE_ID"></a>
+ <strong>ot.NAME_ID_UNIQUE_ID</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_UNIQUE_ID</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_FULL_NAME"></a>
+ <strong>ot.NAME_ID_FULL_NAME</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_FULL_NAME</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_VERSION_STRING"></a>
+ <strong>ot.NAME_ID_VERSION_STRING</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_VERSION_STRING</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_POSTSCRIPT_NAME"></a>
+ <strong>ot.NAME_ID_POSTSCRIPT_NAME</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_POSTSCRIPT_NAME</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_TRADEMARK"></a>
+ <strong>ot.NAME_ID_TRADEMARK</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_TRADEMARK</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_MANUFACTURER"></a>
+ <strong>ot.NAME_ID_MANUFACTURER</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_MANUFACTURER</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_DESIGNER"></a>
+ <strong>ot.NAME_ID_DESIGNER</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_DESIGNER</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_DESCRIPTION"></a>
+ <strong>ot.NAME_ID_DESCRIPTION</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_DESCRIPTION</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_VENDOR_URL"></a>
+ <strong>ot.NAME_ID_VENDOR_URL</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_VENDOR_URL</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_DESIGNER_URL"></a>
+ <strong>ot.NAME_ID_DESIGNER_URL</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_DESIGNER_URL</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_LICENSE"></a>
+ <strong>ot.NAME_ID_LICENSE</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_LICENSE</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_LICENSE_URL"></a>
+ <strong>ot.NAME_ID_LICENSE_URL</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_LICENSE_URL</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_TYPOGRAPHIC_FAMILY"></a>
+ <strong>ot.NAME_ID_TYPOGRAPHIC_FAMILY</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_TYPOGRAPHIC_FAMILY</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_TYPOGRAPHIC_SUBFAMILY"></a>
+ <strong>ot.NAME_ID_TYPOGRAPHIC_SUBFAMILY</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_TYPOGRAPHIC_SUBFAMILY</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_MAC_FULL_NAME"></a>
+ <strong>ot.NAME_ID_MAC_FULL_NAME</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_MAC_FULL_NAME</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_SAMPLE_TEXT"></a>
+ <strong>ot.NAME_ID_SAMPLE_TEXT</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_SAMPLE_TEXT</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_CID_FINDFONT_NAME"></a>
+ <strong>ot.NAME_ID_CID_FINDFONT_NAME</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_CID_FINDFONT_NAME</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_WWS_FAMILY"></a>
+ <strong>ot.NAME_ID_WWS_FAMILY</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_WWS_FAMILY</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_WWS_SUBFAMILY"></a>
+ <strong>ot.NAME_ID_WWS_SUBFAMILY</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_WWS_SUBFAMILY</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_LIGHT_BACKGROUND"></a>
+ <strong>ot.NAME_ID_LIGHT_BACKGROUND</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_LIGHT_BACKGROUND</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_DARK_BACKGROUND"></a>
+ <strong>ot.NAME_ID_DARK_BACKGROUND</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_DARK_BACKGROUND</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_VARIATIONS_PS_PREFIX"></a>
+ <strong>ot.NAME_ID_VARIATIONS_PS_PREFIX</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_VARIATIONS_PS_PREFIX</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.NAME_ID_INVALID"></a>
+ <strong>ot.NAME_ID_INVALID</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_NAME_ID_INVALID</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.LAYOUT_NO_SCRIPT_INDEX"></a>
+ <strong>ot.LAYOUT_NO_SCRIPT_INDEX</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_LAYOUT_NO_SCRIPT_INDEX</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.LAYOUT_NO_FEATURE_INDEX"></a>
+ <strong>ot.LAYOUT_NO_FEATURE_INDEX</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_LAYOUT_NO_FEATURE_INDEX</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.LAYOUT_DEFAULT_LANGUAGE_INDEX"></a>
+ <strong>ot.LAYOUT_DEFAULT_LANGUAGE_INDEX</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX</code>
+
+
+
+
+
+
+
+</dd>
+ <dt>
+ <a name = "ot.LAYOUT_NO_VARIATIONS_INDEX"></a>
+ <strong>ot.LAYOUT_NO_VARIATIONS_INDEX</strong>
+ </dt>
+ <dd>
+ Wraps <code>HB_OT_LAYOUT_NO_VARIATIONS_INDEX</code>
+
+
+
+
+
+
+
+</dd>
+</dl>
+
+
+</div> <!-- id="content" -->
+</div> <!-- id="main" -->
+<div id="about">
+<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
+<i style="float:right;">Last updated 2019-05-01 16:42:35 </i>
+</div> <!-- id="about" -->
+</div> <!-- id="container" -->
+</body>
+</html>
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/ldoc.css b/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/ldoc.css
new file mode 100644
index 00000000000..52c4ad2bd8a
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/docs/ldoc.css
@@ -0,0 +1,303 @@
+/* BEGIN RESET
+
+Copyright (c) 2010, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.com/yui/license.html
+version: 2.8.2r1
+*/
+html {
+ color: #000;
+ background: #FFF;
+}
+body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td {
+ margin: 0;
+ padding: 0;
+}
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+fieldset,img {
+ border: 0;
+}
+address,caption,cite,code,dfn,em,strong,th,var,optgroup {
+ font-style: inherit;
+ font-weight: inherit;
+}
+del,ins {
+ text-decoration: none;
+}
+li {
+ margin-left: 20px;
+}
+caption,th {
+ text-align: left;
+}
+h1,h2,h3,h4,h5,h6 {
+ font-size: 100%;
+ font-weight: bold;
+}
+q:before,q:after {
+ content: '';
+}
+abbr,acronym {
+ border: 0;
+ font-variant: normal;
+}
+sup {
+ vertical-align: baseline;
+}
+sub {
+ vertical-align: baseline;
+}
+legend {
+ color: #000;
+}
+input,button,textarea,select,optgroup,option {
+ font-family: inherit;
+ font-size: inherit;
+ font-style: inherit;
+ font-weight: inherit;
+}
+input,button,textarea,select {*font-size:100%;
+}
+/* END RESET */
+
+body {
+ margin-left: 1em;
+ margin-right: 1em;
+ font-family: arial, helvetica, geneva, sans-serif;
+ background-color: #ffffff; margin: 0px;
+}
+
+code, tt { font-family: monospace; font-size: 1.1em; }
+span.parameter { font-family:monospace; }
+span.parameter:after { content:":"; }
+span.types:before { content:"("; }
+span.types:after { content:")"; }
+.type { font-weight: bold; font-style:italic }
+
+body, p, td, th { font-size: .95em; line-height: 1.2em;}
+
+p, ul { margin: 10px 0 0 0px;}
+
+strong { font-weight: bold;}
+
+em { font-style: italic;}
+
+h1 {
+ font-size: 1.5em;
+ margin: 20px 0 20px 0;
+}
+h2, h3, h4 { margin: 15px 0 10px 0; }
+h2 { font-size: 1.25em; }
+h3 { font-size: 1.15em; }
+h4 { font-size: 1.06em; }
+
+a:link { font-weight: bold; color: #004080; text-decoration: none; }
+a:visited { font-weight: bold; color: #006699; text-decoration: none; }
+a:link:hover { text-decoration: underline; }
+
+hr {
+ color:#cccccc;
+ background: #00007f;
+ height: 1px;
+}
+
+blockquote { margin-left: 3em; }
+
+ul { list-style-type: disc; }
+
+p.name {
+ font-family: "Andale Mono", monospace;
+ padding-top: 1em;
+}
+
+pre {
+ background-color: rgb(245, 245, 245);
+ border: 1px solid #C0C0C0; /* silver */
+ padding: 10px;
+ margin: 10px 0 10px 0;
+ overflow: auto;
+ font-family: "Andale Mono", monospace;
+}
+
+pre.example {
+ font-size: .85em;
+}
+
+table.index { border: 1px #00007f; }
+table.index td { text-align: left; vertical-align: top; }
+
+#container {
+ margin-left: 1em;
+ margin-right: 1em;
+ background-color: #f0f0f0;
+}
+
+#product {
+ text-align: center;
+ border-bottom: 1px solid #cccccc;
+ background-color: #ffffff;
+}
+
+#product big {
+ font-size: 2em;
+}
+
+#main {
+ background-color: #f0f0f0;
+ border-left: 2px solid #cccccc;
+}
+
+#navigation {
+ float: left;
+ width: 14em;
+ vertical-align: top;
+ background-color: #f0f0f0;
+ overflow: visible;
+}
+
+#navigation h2 {
+ background-color:#e7e7e7;
+ font-size:1.1em;
+ color:#000000;
+ text-align: left;
+ padding:0.2em;
+ border-top:1px solid #dddddd;
+ border-bottom:1px solid #dddddd;
+}
+
+#navigation ul
+{
+ font-size:1em;
+ list-style-type: none;
+ margin: 1px 1px 10px 1px;
+}
+
+#navigation li {
+ text-indent: -1em;
+ display: block;
+ margin: 3px 0px 0px 22px;
+}
+
+#navigation li li a {
+ margin: 0px 3px 0px -1em;
+}
+
+#content {
+ margin-left: 14em;
+ padding: 1em;
+ width: 700px;
+ border-left: 2px solid #cccccc;
+ border-right: 2px solid #cccccc;
+ background-color: #ffffff;
+}
+
+#about {
+ clear: both;
+ padding: 5px;
+ border-top: 2px solid #cccccc;
+ background-color: #ffffff;
+}
+
+@media print {
+ body {
+ font: 12pt "Times New Roman", "TimeNR", Times, serif;
+ }
+ a { font-weight: bold; color: #004080; text-decoration: underline; }
+
+ #main {
+ background-color: #ffffff;
+ border-left: 0px;
+ }
+
+ #container {
+ margin-left: 2%;
+ margin-right: 2%;
+ background-color: #ffffff;
+ }
+
+ #content {
+ padding: 1em;
+ background-color: #ffffff;
+ }
+
+ #navigation {
+ display: none;
+ }
+ pre.example {
+ font-family: "Andale Mono", monospace;
+ font-size: 10pt;
+ page-break-inside: avoid;
+ }
+}
+
+table.module_list {
+ border-width: 1px;
+ border-style: solid;
+ border-color: #cccccc;
+ border-collapse: collapse;
+}
+table.module_list td {
+ border-width: 1px;
+ padding: 3px;
+ border-style: solid;
+ border-color: #cccccc;
+}
+table.module_list td.name { background-color: #f0f0f0; min-width: 200px; }
+table.module_list td.summary { width: 100%; }
+
+
+table.function_list {
+ border-width: 1px;
+ border-style: solid;
+ border-color: #cccccc;
+ border-collapse: collapse;
+}
+table.function_list td {
+ border-width: 1px;
+ padding: 3px;
+ border-style: solid;
+ border-color: #cccccc;
+}
+table.function_list td.name { background-color: #f0f0f0; min-width: 200px; }
+table.function_list td.summary { width: 100%; }
+
+ul.nowrap {
+ overflow:auto;
+ white-space:nowrap;
+}
+
+dl.table dt, dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;}
+dl.table dd, dl.function dd {padding-bottom: 1em; margin: 10px 0 0 20px;}
+dl.table h3, dl.function h3 {font-size: .95em;}
+
+/* stop sublists from having initial vertical space */
+ul ul { margin-top: 0px; }
+ol ul { margin-top: 0px; }
+ol ol { margin-top: 0px; }
+ul ol { margin-top: 0px; }
+
+/* make the target distinct; helps when we're navigating to a function */
+a:target + * {
+ background-color: #FF9;
+}
+
+
+/* styles for prettification of source */
+pre .comment { color: #558817; }
+pre .constant { color: #a8660d; }
+pre .escape { color: #844631; }
+pre .keyword { color: #aa5050; font-weight: bold; }
+pre .library { color: #0e7c6b; }
+pre .marker { color: #512b1e; background: #fedc56; font-weight: bold; }
+pre .string { color: #8080ff; }
+pre .number { color: #f8660d; }
+pre .operator { color: #2239a8; font-weight: bold; }
+pre .preprocessor, pre .prepro { color: #a33243; }
+pre .global { color: #800080; }
+pre .user-keyword { color: #800080; }
+pre .prompt { color: #558817; }
+pre .url { color: #272fc2; text-decoration: underline; }
+
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/examples/core_types.lua b/Build/source/texk/web2c/luatexdir/luaharfbuzz/examples/core_types.lua
new file mode 100644
index 00000000000..ec3d0d4388c
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/examples/core_types.lua
@@ -0,0 +1,52 @@
+local harfbuzz = require('harfbuzz')
+local serpent = require('serpent') -- luarocks install serpent
+
+-- Harfbuzz API Version
+print("Harfbuzz API version", harfbuzz.version())
+
+-- Shapers available
+print("Shapers:", serpent.line({ harfbuzz.shapers() }, {comment = false}))
+
+-- harfbuzz.Face
+local face = harfbuzz.Face.new('../fonts/notonastaliq.ttf')
+print('\nFace upem = '..face:get_upem())
+
+-- harfbuzz.Font
+local font = harfbuzz.Font.new(face)
+local xs, xy = font:get_scale()
+print("\nDefault font scale = X: "..xs..", Y: "..xy)
+
+-- harfbuzz.Buffer
+local text = "یہ" -- U+06CC U+06C1
+local buf = harfbuzz.Buffer.new()
+buf:add_utf8(text)
+
+-- harfbuzz.shape (Shapes text)
+print("\nShaping '"..text.."' set with Noto Nastaliq Urdu")
+harfbuzz.shape(font, buf, { language = harfbuzz.Language.new("urd"), script = harfbuzz.Script.new("Arab"), direction = harfbuzz.Direction.RTL})
+
+local glyphs = buf:get_glyphs()
+print("No. of glyphs", #glyphs)
+print(serpent.line(glyphs, {comment = false}))
+
+local opts = { language = harfbuzz.Language.new("eng"), script = harfbuzz.Script.new("Latn"), direction = harfbuzz.Direction.LTR }
+local amiri_face = harfbuzz.Face.new('../fonts/amiri-regular.ttf')
+local amiri_font = harfbuzz.Font.new(amiri_face)
+
+-- shaping '123' w/o features
+print("\nShaping '123' set with Amiri Regular and no features")
+buf= harfbuzz.Buffer.new()
+buf:add_utf8("123")
+harfbuzz.shape(amiri_font, buf, opts)
+glyphs = buf:get_glyphs()
+print(serpent.line(glyphs, {comment = false}))
+
+-- shaping '123' with '+numr' (numerators)
+print("\nShaping '123' set with Amiri Regular with 'numr' feature turned on")
+buf= harfbuzz.Buffer.new()
+buf:add_utf8("123")
+opts.features = "+numr"
+harfbuzz.shape(amiri_font, buf, opts)
+glyphs = buf:get_glyphs()
+print(serpent.line(glyphs, {comment = false}))
+
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/fixtures/AppleGothic_korean_issue_22.json b/Build/source/texk/web2c/luatexdir/luaharfbuzz/fixtures/AppleGothic_korean_issue_22.json
new file mode 100644
index 00000000000..2fa441bcd50
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/fixtures/AppleGothic_korean_issue_22.json
@@ -0,0 +1 @@
+[{"g":2651,"cl":0,"dx":0,"dy":0,"ax":1000,"ay":0},{"g":2942,"cl":1,"dx":0,"dy":0,"ax":1000,"ay":0},{"g":3083,"cl":2,"dx":0,"dy":0,"ax":1000,"ay":0}]
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/fixtures/amiri-regular_123.json b/Build/source/texk/web2c/luatexdir/luaharfbuzz/fixtures/amiri-regular_123.json
new file mode 100644
index 00000000000..b4bc7fb19a2
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/fixtures/amiri-regular_123.json
@@ -0,0 +1 @@
+[{"g":20,"cl":0,"dx":0,"dy":0,"ax":1090,"ay":0},{"g":21,"cl":1,"dx":0,"dy":0,"ax":1090,"ay":0},{"g":22,"cl":2,"dx":0,"dy":0,"ax":1090,"ay":0}]
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/fixtures/amiri-regular_123_numr.json b/Build/source/texk/web2c/luatexdir/luaharfbuzz/fixtures/amiri-regular_123_numr.json
new file mode 100644
index 00000000000..f5423328096
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/fixtures/amiri-regular_123_numr.json
@@ -0,0 +1 @@
+[{"g":6673,"cl":0,"dx":0,"dy":0,"ax":600,"ay":0},{"g":6674,"cl":1,"dx":0,"dy":0,"ax":600,"ay":0},{"g":6675,"cl":2,"dx":0,"dy":0,"ax":600,"ay":0}]
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/fixtures/notonastaliq_U06CC_U06C1.json b/Build/source/texk/web2c/luatexdir/luaharfbuzz/fixtures/notonastaliq_U06CC_U06C1.json
new file mode 100644
index 00000000000..218dcb0376b
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/fixtures/notonastaliq_U06CC_U06C1.json
@@ -0,0 +1 @@
+[{"g":277,"cl":2,"dx":0,"dy":0,"ax":472,"ay":0,"fl":1},{"g":19,"cl":0,"dx":310,"dy":-383,"ax":0,"ay":0},{"g":985,"cl":0,"dx":0,"dy":0,"ax":0,"ay":0},{"g":316,"cl":0,"dx":0,"dy":-68,"ax":731,"ay":0}]
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/fonts/Rajdhani-Regular.ttf b/Build/source/texk/web2c/luatexdir/luaharfbuzz/fonts/Rajdhani-Regular.ttf
new file mode 100755
index 00000000000..4b6ccefe34a
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/fonts/Rajdhani-Regular.ttf
Binary files differ
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/fonts/amiri-regular.ttf b/Build/source/texk/web2c/luatexdir/luaharfbuzz/fonts/amiri-regular.ttf
new file mode 100644
index 00000000000..f898e3b2b7f
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/fonts/amiri-regular.ttf
Binary files differ
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/fonts/amiriquran-colored.ttf b/Build/source/texk/web2c/luatexdir/luaharfbuzz/fonts/amiriquran-colored.ttf
new file mode 100644
index 00000000000..5ebf488bee8
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/fonts/amiriquran-colored.ttf
Binary files differ
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/fonts/notocoloremoji-subset.ttf b/Build/source/texk/web2c/luatexdir/luaharfbuzz/fonts/notocoloremoji-subset.ttf
new file mode 100644
index 00000000000..875ca15b480
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/fonts/notocoloremoji-subset.ttf
Binary files differ
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/fonts/notonastaliq.ttf b/Build/source/texk/web2c/luatexdir/luaharfbuzz/fonts/notonastaliq.ttf
new file mode 100644
index 00000000000..891f633d802
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/fonts/notonastaliq.ttf
Binary files differ
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-1.0.0-1.rockspec b/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-1.0.0-1.rockspec
new file mode 100644
index 00000000000..c7cd2cc8c93
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-1.0.0-1.rockspec
@@ -0,0 +1,51 @@
+package = "luaharfbuzz"
+version = "1.0.0-1"
+source = {
+ url = "git://github.com/deepakjois/luaharfbuzz",
+ tag = "v1.0.0"
+}
+description = {
+ summary = "Lua bindings for the Harfbuzz text shaping library",
+ homepage = "https://github.com/deepakjois/luaharfbuzz",
+ license = "MIT",
+ maintainer = "Deepak Jois <deepak.jois@gmail.com>"
+}
+dependencies = {
+ "lua >= 5.2"
+}
+external_dependencies = {
+ HARFBUZZ = {
+ header = "harfbuzz/hb.h"
+ }
+}
+build = {
+ type = "builtin",
+ modules = {
+ harfbuzz = "src/harfbuzz.lua",
+ luaharfbuzz = {
+ incdirs = {
+ "$(HARFBUZZ_INCDIR)/harfbuzz"
+ },
+ libdirs = {
+ "$(HARFBUZZ_LIBDIR)"
+ },
+ libraries = {
+ "harfbuzz"
+ },
+ sources = {
+ "src/luaharfbuzz/luaharfbuzz.c",
+ "src/luaharfbuzz/blob.c",
+ "src/luaharfbuzz/face.c",
+ "src/luaharfbuzz/font.c",
+ "src/luaharfbuzz/buffer.c",
+ "src/luaharfbuzz/feature.c",
+ "src/luaharfbuzz/tag.c",
+ "src/luaharfbuzz/unicode.c",
+ "src/luaharfbuzz/script.c",
+ "src/luaharfbuzz/direction.c",
+ "src/luaharfbuzz/language.c",
+ "src/luaharfbuzz/class_utils.c"
+ }
+ }
+ }
+}
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-scm-1.rockspec b/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-scm-1.rockspec
new file mode 100644
index 00000000000..108dde354fc
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-scm-1.rockspec
@@ -0,0 +1,45 @@
+package = "luaharfbuzz"
+version = "scm-1"
+source = {
+ url = "git://github.com/ufytex/luaharfbuzz"
+}
+description = {
+ summary = "Lua bindings for the Harfbuzz text shaping library",
+ homepage = "https://github.com/ufytex/luaharfbuzz",
+ license = "MIT",
+ maintainer = "Deepak Jois <deepak.jois@gmail.com>"
+}
+dependencies = {
+ "lua >= 5.2"
+}
+build = {
+ type = "builtin",
+ modules = {
+ harfbuzz ="src/harfbuzz.lua",
+ luaharfbuzz= {
+ sources = {
+ "src/luaharfbuzz/luaharfbuzz.c",
+ "src/luaharfbuzz/blob.c",
+ "src/luaharfbuzz/face.c",
+ "src/luaharfbuzz/font.c",
+ "src/luaharfbuzz/buffer.c",
+ "src/luaharfbuzz/feature.c",
+ "src/luaharfbuzz/tag.c",
+ "src/luaharfbuzz/ot.c",
+ "src/luaharfbuzz/unicode.c",
+ "src/luaharfbuzz/script.c",
+ "src/luaharfbuzz/direction.c",
+ "src/luaharfbuzz/language.c",
+ "src/luaharfbuzz/class_utils.c"
+ },
+ libraries = {"harfbuzz"},
+ incdirs = {"$(HARFBUZZ_INCDIR)/harfbuzz"},
+ libdirs = {"$(HARFBUZZ_LIBDIR)"}
+ }
+ }
+}
+external_dependencies = {
+ HARFBUZZ = {
+ header = "harfbuzz/hb.h"
+ }
+}
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/scripts/generate_harfbuzz_api_list.sh b/Build/source/texk/web2c/luatexdir/luaharfbuzz/scripts/generate_harfbuzz_api_list.sh
new file mode 100755
index 00000000000..07d4770b0b6
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/scripts/generate_harfbuzz_api_list.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+grep -e "^hb_" /usr/local/include/harfbuzz/hb*.h | grep "(" | sed -e 's/ .*$//' | awk -F: '{print $2}' | sort > status/full_api.txt
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/scripts/generate_hb_shape_json.sh b/Build/source/texk/web2c/luatexdir/luaharfbuzz/scripts/generate_hb_shape_json.sh
new file mode 100755
index 00000000000..5389845f326
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/scripts/generate_hb_shape_json.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+SHAPER_OPTS="--font-funcs=ot --shapers=ot"
+CLUSTER_OPTS="--utf8-clusters"
+FORMAT_OPTS="--show-flags --no-glyph-names --output-format=json"
+STANDARD_OPTS="$SHAPER_OPTS $CLUSTER_OPTS $FORMAT_OPTS"
+
+hb-shape $STANDARD_OPTS fonts/notonastaliq.ttf "یہ" > fixtures/notonastaliq_U06CC_U06C1.json
+hb-shape $STANDARD_OPTS fonts/amiri-regular.ttf "123" > fixtures/amiri-regular_123.json
+hb-shape $STANDARD_OPTS --features="+numr" fonts/amiri-regular.ttf "123" > fixtures/amiri-regular_123_numr.json
+hb-shape $SHAPER_OPTS $FORMAT_OPTS /Library/Fonts/AppleGothic.ttf "가나다" > fixtures/AppleGothic_korean_issue_22.json
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/buffer_spec.lua b/Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/buffer_spec.lua
new file mode 100644
index 00000000000..1950354eaf6
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/buffer_spec.lua
@@ -0,0 +1,172 @@
+local harfbuzz = require("harfbuzz")
+
+describe("harfbuzz.Buffer", function()
+ it("can be created", function()
+ harfbuzz.Buffer.new()
+ end)
+
+ it("can add a UTF8 string", function()
+ local b = harfbuzz.Buffer.new()
+ local s = "Some String"
+ b:add_utf8(s)
+ assert.are_equal(string.len(s), b:get_length())
+ end)
+
+ it("can add a UTF 8 string with item_offset", function()
+ local b = harfbuzz.Buffer.new()
+ local s = "Some String"
+ local o = 5
+ b:add_utf8(s,o)
+ assert.are_equal(string.len(s) - o, b:get_length())
+ end)
+
+ it("can add a UTF 8 string with item_length", function()
+ local b = harfbuzz.Buffer.new()
+ local s = "Some String"
+ local o = 5
+ local l = 2
+ b:add_utf8(s,o,l)
+ assert.are_equal(l, b:get_length())
+ end)
+
+ it("can add codepoints", function()
+ local b = harfbuzz.Buffer.new()
+ local s = { 0x06CC, 0x06C1 }
+ b:add_codepoints(s)
+ assert.are_equal(#s, b:get_length())
+ end)
+
+ it("can add codepoints with item_offset", function()
+ local b = harfbuzz.Buffer.new()
+ local s = { 0x06CC, 0x06C1 }
+ local o = 1
+ b:add_codepoints(s,o)
+ assert.are_equal(#s - o, b:get_length())
+ end)
+
+ it("can add codepoints with item_length", function()
+ local b = harfbuzz.Buffer.new()
+ local s = { 0x06CC, 0x06C1 }
+ local o = 1
+ local l = 1
+ b:add_codepoints(s,o,l)
+ assert.are_equal(l, b:get_length())
+ end)
+
+ it("can call guess_segment_properties", function()
+ local b = harfbuzz.Buffer.new()
+ b:add_utf8("Some String")
+ b:guess_segment_properties()
+ end)
+
+ it("can get and set the direction of a buffer", function()
+ local b = harfbuzz.Buffer.new()
+ b:add_utf8("abc")
+ local dir = harfbuzz.Direction.RTL
+ b:set_direction(dir)
+ assert.are_equal(dir, b:get_direction())
+ end)
+
+ it("sets direction to INVALID if direction is invalid", function()
+ local b = harfbuzz.Buffer.new()
+ b:set_direction(harfbuzz.Direction.new("invalid"))
+ assert.are_equal(harfbuzz.Direction.INVALID, b:get_direction())
+ end)
+
+ it("can get the direction correctly", function()
+ local b = harfbuzz.Buffer.new()
+ b:add_utf8("یہ")
+ b:guess_segment_properties()
+ assert.are_equal(harfbuzz.Direction.RTL, b:get_direction())
+ end)
+
+ it("can get and set the language of a buffer", function()
+ local b = harfbuzz.Buffer.new()
+ b:add_utf8("یہ")
+ local urd = harfbuzz.Language.new("urd")
+ b:set_language(urd)
+ assert.are_equal(urd, b:get_language())
+ end)
+
+ it("Sets language to INVALID if language is invalid", function()
+ local b = harfbuzz.Buffer.new()
+ b:set_language(harfbuzz.Language.INVALID)
+ assert.are_equal(harfbuzz.Language.INVALID, b:get_language())
+ end)
+
+ it("can get the language correctly", function()
+ local b = harfbuzz.Buffer.new()
+ b:add_utf8("یہ")
+ b:guess_segment_properties()
+ assert.are_not_equal(harfbuzz.Language.INVALID, b:get_language())
+ end)
+
+ it("can get and set the script of a buffer", function()
+ local b = harfbuzz.Buffer.new()
+ b:add_utf8("abc")
+ b:set_script(harfbuzz.Script.new("latn"))
+ assert.are_equal("Latn", tostring(b:get_script()))
+ end)
+
+ it("returns script as UNKNOWN if script is invalid", function()
+ local b = harfbuzz.Buffer.new()
+ b:set_script(harfbuzz.Script.new("xxx"))
+ assert.are_equal(harfbuzz.Script.UNKNOWN, b:get_script())
+ end)
+
+ it("can get the script correctly", function()
+ local b = harfbuzz.Buffer.new()
+ b:add_utf8("یہ")
+ assert.are_equal(harfbuzz.Script.new(""), b:get_script())
+ b:guess_segment_properties()
+ assert.are_equal(harfbuzz.Script.new("Arab"), b:get_script())
+ end)
+
+ it("can reverse the buffer", function()
+ local face = harfbuzz.Face.new('fonts/notonastaliq.ttf')
+ local font = harfbuzz.Font.new(face)
+ local urdu_text = "یہ" -- U+06CC U+06C1
+ local options = { language = harfbuzz.Language.new("urd"), script = harfbuzz.Script.new("Arab"), direction = harfbuzz.Direction.RTL }
+
+ local buf= harfbuzz.Buffer.new()
+ buf:add_utf8(urdu_text)
+ harfbuzz.shape(font, buf, options)
+ local orig_glyphs = buf:get_glyphs()
+ buf:reverse()
+ local reversed_glyphs = buf:get_glyphs()
+
+ assert.are_equal(#orig_glyphs, #reversed_glyphs)
+
+ for c = 1, #orig_glyphs do
+ local g = orig_glyphs[#orig_glyphs - (c - 1)]
+ local r = reversed_glyphs[c]
+ assert.are_equal(g.codepoint, r.codepoint)
+ assert.are_equal(g.cluster, r.cluster)
+ assert.are_equal(g.x_advance, r.x_advance)
+ assert.are_equal(g.y_advance, r.y_advance)
+ assert.are_equal(g.x_offset, r.x_offset)
+ assert.are_equal(g.y_offset, r.y_offset)
+ end
+
+ end)
+
+ it("can get the length of the buffer", function()
+ local b = harfbuzz.Buffer.new()
+ local s = "some string"
+ b:add_utf8(s)
+ assert.are_equal(string.len(s), b:get_length())
+ end)
+
+ it("can get the cluster level of the buffer", function()
+ local b = harfbuzz.Buffer.new()
+ assert.are_equal(harfbuzz.Buffer.CLUSTER_LEVEL_DEFAULT, b:get_cluster_level())
+ end)
+
+ it("can set the cluster level of the buffer", function()
+ local b = harfbuzz.Buffer.new()
+ b:set_cluster_level(harfbuzz.Buffer.CLUSTER_LEVEL_CHARACTERS)
+ assert.are_equal(harfbuzz.Buffer.CLUSTER_LEVEL_CHARACTERS, b:get_cluster_level())
+ end)
+end)
+
+
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/harfbuzz_spec.lua b/Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/harfbuzz_spec.lua
new file mode 100644
index 00000000000..966a1865faf
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/harfbuzz_spec.lua
@@ -0,0 +1,501 @@
+local harfbuzz = require("harfbuzz")
+
+describe("harfbuzz module", function()
+
+ it("returns a valid version string", function()
+ assert.are_equal("string", type(harfbuzz.version()))
+ end)
+
+ it("returns a valid list of shapers", function()
+ local shapers = { harfbuzz.shapers }
+ assert.is_not.True(#shapers == 0)
+ end)
+
+ describe("harfbuzz.Blob", function()
+ it("can be initialized with a string", function()
+ local s = "test string"
+ local blob = harfbuzz.Blob.new(s)
+ assert.are_equal(string.len(s), blob:get_length())
+ end)
+ end)
+
+ describe("harfbuzz.Face", function()
+ local face = harfbuzz.Face.new('fonts/notonastaliq.ttf')
+ it("can be initialized with a blob", function()
+ local fontfile = io.open('fonts/notonastaliq.ttf', "r")
+ local fontdata = fontfile:read("*all")
+ fontfile:close()
+
+ local blob = harfbuzz.Blob.new(fontdata)
+ harfbuzz.Face.new_from_blob(blob,0)
+ end)
+
+ it("can be initialized with a file and a font index", function()
+ harfbuzz.Face.new('fonts/notonastaliq.ttf',0)
+ end)
+
+ it("can be initialized with a file only", function()
+ harfbuzz.Face.new('fonts/notonastaliq.ttf')
+ end)
+
+ it("returns a valid upem value", function()
+ assert.are_equal(2048,face:get_upem())
+ end)
+
+ it("can return SFNT table", function()
+ local b = face:get_table(harfbuzz.Tag.new("OS/2"))
+ local d = b:get_data()
+ assert.are_equal(96,b:get_length())
+ assert.are_equal(96,#d)
+ assert.are_equal(4,string.unpack(">H", d, 1))
+ assert.are_equal(1155,string.unpack(">h", d, 3))
+ assert.are_equal(5,string.unpack(">H", d, -2))
+ end)
+
+ it("can return table tags", function()
+ local t = face:get_table_tags()
+ assert.are_equal(14,#t)
+ assert.are_equal("GDEF",tostring(t[1]))
+ assert.are_equal("post",tostring(t[#t]))
+ end)
+
+ it("can return glyph count", function()
+ assert.are_equal(1133,face:get_glyph_count())
+ end)
+
+ it("can return unicode characters supported by face", function()
+ local u = face:collect_unicodes()
+ assert.are_equal(267,#u)
+ assert.are_equal(0x0000,u[1])
+ assert.are_equal(0xFEFF,u[#u])
+ end)
+
+ it("can return face names", function()
+ assert.are_equal("Copyright 2014 Google Inc. All Rights Reserved.",face:get_name(harfbuzz.ot.NAME_ID_COPYRIGHT))
+ assert.are_equal("Noto Nastaliq Urdu",face:get_name(harfbuzz.ot.NAME_ID_FONT_FAMILY))
+ assert.are_equal("Regular",face:get_name(harfbuzz.ot.NAME_ID_FONT_SUBFAMILY))
+ assert.are_equal("Noto Nastaliq Urdu",face:get_name(harfbuzz.ot.NAME_ID_FULL_NAME))
+ assert.are_equal("NotoNastaliqUrdu",face:get_name(harfbuzz.ot.NAME_ID_POSTSCRIPT_NAME))
+ assert.are_equal("Noto is a trademark of Google Inc.",face:get_name(harfbuzz.ot.NAME_ID_TRADEMARK))
+ assert.are_equal(331,#face:get_name(harfbuzz.ot.NAME_ID_LICENSE))
+ assert.are_equal(nil,face:get_name(harfbuzz.ot.NAME_ID_INVALID))
+ end)
+
+ it("can return face names with language", function()
+ local f = harfbuzz.Face.new('fonts/amiri-regular.ttf')
+ local ar = harfbuzz.Language.new("ar")
+ local en = harfbuzz.Language.new("en")
+ assert.are_equal("حقوق النشر 2010-2015، خالد حسني <khaledhosny@eglug.org>.",f:get_name(harfbuzz.ot.NAME_ID_COPYRIGHT, ar))
+ assert.are_equal("Copyright (c) 2010-2015, Khaled Hosny <khaledhosny@eglug.org>.\nPortions copyright (c) 2010, Sebastian Kosch <sebastian@aldusleaf.org>.",f:get_name(harfbuzz.ot.NAME_ID_COPYRIGHT, en))
+ assert.are_equal("عادي",f:get_name(harfbuzz.ot.NAME_ID_FONT_SUBFAMILY, ar))
+ assert.are_equal("Regular",f:get_name(harfbuzz.ot.NAME_ID_FONT_SUBFAMILY, en))
+ assert.are_equal("إصدارة 000٫108",f:get_name(harfbuzz.ot.NAME_ID_VERSION_STRING, ar))
+ assert.are_equal("Version 000.108 ",f:get_name(harfbuzz.ot.NAME_ID_VERSION_STRING, en))
+ assert.are_equal("خالد حسني",f:get_name(harfbuzz.ot.NAME_ID_DESIGNER, ar))
+ assert.are_equal("Khaled Hosny",f:get_name(harfbuzz.ot.NAME_ID_DESIGNER, en))
+ assert.are_equal(512,#f:get_name(harfbuzz.ot.NAME_ID_DESCRIPTION, ar))
+ assert.are_equal(263,#f:get_name(harfbuzz.ot.NAME_ID_DESCRIPTION, en))
+ assert.are_equal("صِفْ خَلْقَ خَوْدٍ كَمِثْلِ ٱلشَّمْسِ إِذْ بَزَغَتْ يَحْظَىٰ ٱلضَّجِيعُ بِهَا نَجْلَاءَ مِعْطَارِ.",f:get_name(harfbuzz.ot.NAME_ID_SAMPLE_TEXT, ar))
+ assert.are_equal("صِفْ خَلْقَ خَوْدٍ كَمِثْلِ ٱلشَّمْسِ إِذْ بَزَغَتْ يَحْظَىٰ ٱلضَّجِيعُ بِهَا نَجْلَاءَ مِعْطَارِ.",f:get_name(harfbuzz.ot.NAME_ID_SAMPLE_TEXT, en))
+ end)
+
+ it("can check color palettes", function()
+ local f = harfbuzz.Face.new('fonts/amiriquran-colored.ttf')
+ assert.are_equal(false,face:ot_color_has_palettes())
+ assert.are_equal(true,f:ot_color_has_palettes())
+ end)
+
+ it("can return number of color palettes", function()
+ local f = harfbuzz.Face.new('fonts/amiriquran-colored.ttf')
+ assert.are_equal(0,face:ot_color_palette_get_count())
+ assert.are_equal(1,f:ot_color_palette_get_count())
+ end)
+
+ it("can return palette colors", function()
+ local f = harfbuzz.Face.new('fonts/amiriquran-colored.ttf')
+ assert.are_equal(nil,face:ot_color_palette_get_colors())
+ local colors = {
+ { alpha = 255, blue = 51, green = 51, red = 204, },
+ { alpha = 255, blue = 80, green = 165, red = 0, },
+ { alpha = 255, blue = 51, green = 153, red = 238, },
+ { alpha = 255, blue = 153, green = 102, red = 51, },
+ }
+ assert.are_same(colors,f:ot_color_palette_get_colors())
+ end)
+
+ it("can check color layers", function()
+ local f = harfbuzz.Face.new('fonts/amiriquran-colored.ttf')
+ assert.are_equal(false,face:ot_color_has_layers())
+ assert.are_equal(true,f:ot_color_has_layers())
+ end)
+
+ it("can return glyph color layers", function()
+ local f = harfbuzz.Face.new('fonts/amiriquran-colored.ttf')
+ assert.are_equal(nil,face:ot_color_glyph_get_layers(100))
+ assert.are_equal(nil,f:ot_color_glyph_get_layers(2))
+ local layers = {
+ { color_index = 65535, glyph = 1341 },
+ { color_index = 1, glyph = 1370 },
+ }
+ assert.are_same(layers,f:ot_color_glyph_get_layers(100))
+ end)
+
+ it("can check color layers", function()
+ local f = harfbuzz.Face.new('fonts/notocoloremoji-subset.ttf')
+ assert.are_equal(false,face:ot_color_has_png())
+ assert.are_equal(true,f:ot_color_has_png())
+ end)
+
+ it("can return script tags", function()
+ local t
+ local tags = {
+ harfbuzz.Tag.new("arab"),
+ harfbuzz.Tag.new("dflt"),
+ harfbuzz.Tag.new("latn"),
+ }
+ t = face:ot_layout_get_script_tags(harfbuzz.Tag.new("GSUB"))
+ assert.are_same(tags, t)
+ t = face:ot_layout_get_script_tags(harfbuzz.Tag.new("GPOS"))
+ assert.are_same({ tags[1] }, t)
+ end)
+
+ it("can return language tags", function()
+ local t
+ local tags = {
+ harfbuzz.Tag.new("ARA "),
+ harfbuzz.Tag.new("FAR "),
+ harfbuzz.Tag.new("KSH "),
+ harfbuzz.Tag.new("SND "),
+ harfbuzz.Tag.new("URD "),
+ }
+ t = face:ot_layout_get_language_tags(harfbuzz.Tag.new("GSUB"), 0)
+ assert.are_same(tags, t)
+ t = face:ot_layout_get_language_tags(harfbuzz.Tag.new("GPOS"), 0)
+ assert.are_equal(nil, t)
+ end)
+
+ it("can return feature tags", function()
+ local t, tags
+ tags = {
+ harfbuzz.Tag.new("ccmp"),
+ harfbuzz.Tag.new("isol"),
+ harfbuzz.Tag.new("init"),
+ harfbuzz.Tag.new("medi"),
+ harfbuzz.Tag.new("fina"),
+ harfbuzz.Tag.new("rlig"),
+ }
+ t = face:ot_layout_get_feature_tags(harfbuzz.Tag.new("GSUB"), 0, 0)
+ assert.are_same(tags, t)
+ tags = {
+ harfbuzz.Tag.new("curs"),
+ harfbuzz.Tag.new("mark"),
+ harfbuzz.Tag.new("mkmk"),
+ }
+ t = face:ot_layout_get_feature_tags(harfbuzz.Tag.new("GPOS"), 0, harfbuzz.ot.LAYOUT_DEFAULT_LANGUAGE_INDEX)
+ assert.are_same(tags, t)
+ end)
+
+ it("can find scripts, languages and features", function()
+ local r, i
+ r, i = face:ot_layout_find_script(harfbuzz.Tag.new("GSUB"), harfbuzz.Tag.new("latn"))
+ assert.True(r)
+ assert.are_same(2, i)
+ r, i = face:ot_layout_find_language(harfbuzz.Tag.new("GSUB"), i, harfbuzz.Tag.new("ENG "))
+ assert.False(r)
+ assert.are_same(harfbuzz.ot.LAYOUT_DEFAULT_LANGUAGE_INDEX, i)
+ r, i = face:ot_layout_find_language(harfbuzz.Tag.new("GSUB"), 0, harfbuzz.Tag.new("ARA "))
+ assert.True(r)
+ assert.are_same(0, i)
+ r, i = face:ot_layout_find_feature(harfbuzz.Tag.new("GSUB"), 0, i, harfbuzz.Tag.new("rlig"))
+ assert.True(r)
+ assert.are_same(13, i)
+
+ r, i = face:ot_layout_find_feature(harfbuzz.Tag.new("GSUB"), 1, harfbuzz.ot.LAYOUT_DEFAULT_LANGUAGE_INDEX, harfbuzz.Tag.new("rlig"))
+ assert.True(r)
+ assert.are_same(13, i)
+ end)
+ end)
+
+ describe("harfbuzz.Font", function()
+ local face = harfbuzz.Face.new('fonts/notonastaliq.ttf')
+ it("can be initialized with a face", function()
+ harfbuzz.Font.new(face)
+ end)
+
+ it("has a default scale set to the fonts upem", function()
+ local font = harfbuzz.Font.new(face)
+ local upem = face:get_upem()
+ local xs, ys = font:get_scale()
+ assert.are_equal(upem, xs)
+ assert.are_equal(upem, ys)
+ end)
+
+ it("can set the scale of the font using set_scale", function()
+ local font = harfbuzz.Font.new(face)
+ font:set_scale(1024,2048)
+ local xs, ys = font:get_scale()
+ assert.are_equal(1024, xs)
+ assert.are_equal(2048, ys)
+ end)
+
+ it("can get glyph extents using get_glyph_extents", function()
+ local font = harfbuzz.Font.new(face)
+ local extents = font:get_glyph_extents(0)
+ assert.are_equal(145, extents.x_bearing)
+ assert.are_equal(2452, extents.y_bearing)
+ assert.are_equal(1553, extents.width)
+ assert.are_equal(-2452, extents.height)
+ extents = font:get_glyph_extents(1)
+ assert.are_equal(0, extents.x_bearing)
+ assert.are_equal(0, extents.y_bearing)
+ assert.are_equal(0, extents.width)
+ assert.are_equal(0, extents.height)
+ end)
+
+ it("can get font extents", function()
+ local font = harfbuzz.Font.new(face)
+ local extents = font:get_h_extents(0)
+ assert.are_equal(3900, extents.ascender)
+ assert.are_equal(-1220, extents.descender)
+ assert.are_equal(0, extents.line_gap)
+ extents = font:get_v_extents(1)
+ assert.are_equal(nil, extents)
+ end)
+
+ it("can get glyph name using get_glyph_name", function()
+ local font = harfbuzz.Font.new(face)
+ assert.are_equal(".notdef", font:get_glyph_name(0))
+ assert.are_equal("null", font:get_glyph_name(1))
+ end)
+
+ it("can get glyph using get_glyph_from_name", function()
+ local font = harfbuzz.Font.new(face)
+ assert.are_equal(0, font:get_glyph_from_name(".notdef"))
+ assert.are_equal(1, font:get_glyph_from_name("null"))
+ end)
+
+ it("can get glyph advance using get_glyph_h_advance", function()
+ local font = harfbuzz.Font.new(face)
+ assert.are_equal(1843, font:get_glyph_h_advance(0))
+ assert.are_equal(0, font:get_glyph_h_advance(1))
+ end)
+
+ it("can get glyph advance using get_glyph_v_advance", function()
+ local font = harfbuzz.Font.new(face)
+ assert.are_equal(-2048, font:get_glyph_v_advance(0))
+ assert.are_equal(-2048, font:get_glyph_v_advance(1))
+ end)
+
+ it("can get nominal glyph for codepoint", function()
+ local font = harfbuzz.Font.new(face)
+ assert.are_equal(nil, font:get_nominal_glyph(0x0041))
+ assert.are_equal(858, font:get_nominal_glyph(0x0627))
+ end)
+
+ it("can return glyph color png", function()
+ local font = harfbuzz.Font.new(face)
+ local f = harfbuzz.Font.new(harfbuzz.Face.new('fonts/notocoloremoji-subset.ttf'))
+
+ assert.are_equal(nil,font:ot_color_glyph_get_png(100))
+ assert.are_equal(nil,f:ot_color_glyph_get_png(0))
+ assert.are_same(2233,f:ot_color_glyph_get_png(1):get_length())
+ 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)
+ end)
+
+ describe("harfbuzz.Feature", function()
+ it("can be initialised with a valid feature string", function()
+ harfbuzz.Feature.new('kern')
+ harfbuzz.Feature.new('+kern')
+ end)
+
+ it("throws an error when trying to initialise a new Feature with an invalid string", function()
+ assert.are_equal(nil, harfbuzz.Feature.new(''))
+ assert.are_equal(nil, harfbuzz.Feature.new('#kern'))
+ end)
+
+ it("has a valid tostring value", function()
+ local fs = 'kern'
+ local f = harfbuzz.Feature.new(fs)
+ assert.are_equal(fs, tostring(f))
+ end)
+ end)
+
+ describe("harfbuzz.Tag", function()
+ it("can be initialised with a valid tag string", function()
+ harfbuzz.Tag.new('Zyyy')
+ end)
+
+ it("can be initialised to NONE with nil or empty argument", function()
+ local t = harfbuzz.Tag.new()
+ assert.are_equal(harfbuzz.Tag.NONE, t)
+ t = harfbuzz.Tag.new(nil)
+ assert.are_equal(harfbuzz.Tag.NONE, t)
+ end)
+
+ it("has a valid tostring value", function()
+ local ts = 'Arab'
+ local t = harfbuzz.Tag.new(ts)
+ assert.are_equal(ts, tostring(t))
+ end)
+
+ it("has a valid equality check functions", function()
+ local ts = 'Arab'
+ local t1 = harfbuzz.Tag.new(ts)
+ local t2 = harfbuzz.Tag.new(ts)
+ local t3 = harfbuzz.Tag.new("Latn")
+ assert.are_equal(t1, t2)
+ assert.are_not_equal(t1, t3)
+ end)
+
+ it("has a preset value for NONE", function()
+ local n = harfbuzz.Tag.NONE
+ assert.is_not_nil(n)
+ assert.are_equal("", tostring(n))
+ assert.are_equal(harfbuzz.Tag.NONE, harfbuzz.Tag.new(""))
+ end)
+ end)
+
+ describe("harfbuzz.Script", function()
+ it("can be initialised with a string", function()
+ harfbuzz.Script.new('Arab')
+ end)
+
+ it("can be initialised to INVALID with nil or empty argument", function()
+ local t = harfbuzz.Script.new()
+ assert.are_equal(harfbuzz.Script.INVALID, t)
+ t = harfbuzz.Script.new(nil)
+ assert.are_equal(harfbuzz.Script.INVALID, t)
+ end)
+
+ it("can be initialised with a tag", function()
+ local ts = "Arab"
+ local s = harfbuzz.Script.from_iso15924_tag(harfbuzz.Tag.new(ts))
+ assert.are_equal(ts, tostring(s))
+ end)
+
+ it("can be converted to a tag", function()
+ local s = 'Arab'
+ local sc = harfbuzz.Script.new(s)
+ assert.are_equal(s, tostring(sc:to_iso15924_tag()))
+ end)
+
+ it("has a valid tostring value", function()
+ local ts = 'Arab'
+ local t = harfbuzz.Script.new(ts)
+ assert.are_equal(ts, tostring(t))
+ end)
+
+ it("has a valid equality check functions", function()
+ local ts = 'Arab'
+ local t1 = harfbuzz.Script.new(ts)
+ local t2 = harfbuzz.Script.new(ts)
+ local t3 = harfbuzz.Script.new("Latn")
+ assert.are_equal(t1, t2)
+ assert.are_not_equal(t1, t3)
+ end)
+ end)
+
+ describe("harfbuzz.Direction", function()
+ it("can be initialised with a valid tag string", function()
+ harfbuzz.Direction.new('LTR')
+ end)
+
+ it("can be initialised with invalid strings", function()
+ local d1 = harfbuzz.Direction.new("i")
+ local d2 = harfbuzz.Direction.new("inv")
+
+ assert.are_equal(d1, d2)
+ assert.are_equal("invalid", tostring(d1))
+ end)
+
+ it("has a valid tostring value", function()
+ local ts = 'ltr'
+ local t = harfbuzz.Direction.new(ts)
+ assert.are_equal(ts, tostring(t))
+
+ t = harfbuzz.Direction.new("LTR")
+ assert.are_equal(ts, tostring(t))
+ end)
+
+ it("has a valid equality check functions", function()
+ local ts = 'ltr'
+ local t1 = harfbuzz.Direction.new(ts)
+ local t2 = harfbuzz.Direction.new(ts)
+ local t3 = harfbuzz.Direction.new("rtl")
+ assert.are_equal(t1, t2)
+ assert.are_not_equal(t1, t3)
+ end)
+
+ it("has a is_valid function", function()
+ assert.True(harfbuzz.Direction.LTR:is_valid())
+ assert.False(harfbuzz.Direction.INVALID:is_valid())
+ end)
+
+ it("has a is_horizontal function", function()
+ assert.True(harfbuzz.Direction.LTR:is_horizontal())
+ assert.False(harfbuzz.Direction.TTB:is_horizontal())
+ end)
+
+ it("has a is_vertical function", function()
+ assert.True(harfbuzz.Direction.TTB:is_vertical())
+ assert.False(harfbuzz.Direction.LTR:is_vertical())
+ end)
+
+ it("has a is_forward function", function()
+ assert.True(harfbuzz.Direction.LTR:is_forward())
+ assert.False(harfbuzz.Direction.RTL:is_forward())
+ end)
+
+ it("has a is_backward function", function()
+ assert.True(harfbuzz.Direction.RTL:is_backward())
+ assert.False(harfbuzz.Direction.LTR:is_backward())
+ end)
+ end)
+
+ describe("harfbuzz.Language", function()
+ it("can be initialised with a valid language string", function()
+ harfbuzz.Language.new('urd')
+ end)
+
+ it("can be initialised to INVALID with nil or empty argument", function()
+ local t = harfbuzz.Language.new()
+ assert.are_equal(harfbuzz.Language.INVALID, t)
+ t = harfbuzz.Language.new(nil)
+ assert.are_equal(harfbuzz.Language.INVALID, t)
+ end)
+
+ it("has a valid tostring value", function()
+ local ts = 'urd'
+ local t = harfbuzz.Language.new(ts)
+ assert.are_equal(ts, tostring(t))
+ end)
+
+ it("has a valid equality check functions", function()
+ local ts = 'urd'
+ local t1 = harfbuzz.Language.new(ts)
+ local t2 = harfbuzz.Language.new(ts)
+ local t3 = harfbuzz.Language.new("hin")
+ assert.are_equal(t1, t2)
+ assert.are_not_equal(t1, t3)
+ end)
+
+ it("has a preset value for INVALID", function()
+ local n = harfbuzz.Language.INVALID
+ assert.is_not_nil(n)
+ assert.are_equal(harfbuzz.Language.INVALID, harfbuzz.Language.new())
+ assert.are_equal("", tostring(n))
+ end)
+ end)
+
+ describe("harfbuzz.unicode", function()
+ describe("script function returns a valid script for a codepoint",function()
+ local s = harfbuzz.unicode.script(0x0020)
+ assert.are_equal(harfbuzz.Script.COMMON, s)
+ s = harfbuzz.unicode.script(0x0041)
+ assert.are_equal(harfbuzz.Script.new("Latn"), s)
+ end)
+ end)
+end)
+
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/shaping_spec.lua b/Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/shaping_spec.lua
new file mode 100644
index 00000000000..8ab810e3da4
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/shaping_spec.lua
@@ -0,0 +1,157 @@
+local harfbuzz = require("harfbuzz")
+
+local compare_glyphs_against_fixture = function(glyphs, fixture)
+ local json = require('dkjson')
+ local f = io.open("fixtures/"..fixture)
+ local s = f:read("*all")
+ f:close()
+ local hb_shape_glyphs = json.decode(s)
+ assert.are_equal(#hb_shape_glyphs, #glyphs)
+ for c = 1, #glyphs do
+ local g = glyphs[c]
+ local h = hb_shape_glyphs[c]
+ assert.are_equal(h.g, g.codepoint)
+ assert.are_equal(h.cl, g.cluster)
+ assert.are_equal(h.ax, g.x_advance)
+ assert.are_equal(h.ay, g.y_advance)
+ assert.are_equal(h.dx, g.x_offset)
+ assert.are_equal(h.dy, g.y_offset)
+ assert.are_equal(h.fl, g.flags)
+ end
+end
+
+
+describe("harfbuzz module shaping functions", function()
+ local face = harfbuzz.Face.new('fonts/notonastaliq.ttf')
+ local font = harfbuzz.Font.new(face)
+ local urdu_text = "یہ" -- U+06CC U+06C1
+
+ it("can take a buffer and font and shape it, with output matching hb-shape", function()
+ local buf = harfbuzz.Buffer.new()
+ buf:add_utf8(urdu_text)
+
+ harfbuzz.shape(font, buf)
+ local glyphs = buf:get_glyphs()
+ assert.True(#glyphs > 0)
+
+ -- Compare against output of hb-shape
+ compare_glyphs_against_fixture(glyphs, 'notonastaliq_U06CC_U06C1.json')
+ end)
+
+ it("can take a buffer, font and an options table with script, language and direction settings.", function()
+ local buf = harfbuzz.Buffer.new()
+ buf:add_utf8(urdu_text)
+
+ harfbuzz.shape(font, buf, { language = harfbuzz.Language.new("urd"), script = harfbuzz.Script.new("Arab"), direction = harfbuzz.Direction.HB_DIRECTION_RTL })
+ local glyphs = buf:get_glyphs()
+ assert.True(#glyphs > 0)
+
+ -- Compare against output of hb-shape
+ compare_glyphs_against_fixture(glyphs, 'notonastaliq_U06CC_U06C1.json')
+ end)
+
+ it("can take codepoints, font and an options table with script, language and direction settings. #mac", function()
+ local buf = harfbuzz.Buffer.new()
+ local korean_text = { 0xAC00, 0xB098, 0xB2E4 }
+ buf:add_codepoints(korean_text)
+
+ local face_korean = harfbuzz.Face.new('/Library/Fonts/AppleGothic.ttf')
+ local font_korean = harfbuzz.Font.new(face_korean)
+
+ harfbuzz.shape(font_korean, buf, { language = harfbuzz.Language.new("KOR"), script = harfbuzz.Script.new("hang"), direction = harfbuzz.Direction.HB_DIRECTION_LTR })
+ local glyphs = buf:get_glyphs()
+ assert.True(#glyphs > 0)
+
+ -- Compare against output of hb-shape
+ compare_glyphs_against_fixture(glyphs, 'AppleGothic_korean_issue_22.json')
+ end)
+
+ it("can take a string containing a comma-delimited list of valid features", function()
+ local buf = harfbuzz.Buffer.new()
+ buf:add_utf8(urdu_text)
+
+ harfbuzz.shape(font, buf, { language = harfbuzz.Language.new("urd"), script = harfbuzz.Script.new("Arab"), direction = harfbuzz.Direction.HB_DIRECTION_RTL, features = "+kern,smcp" })
+ local glyphs = buf:get_glyphs()
+ assert.True(#glyphs > 0)
+ end)
+
+ describe("features option", function()
+ local buf
+ local options
+
+ before_each(function()
+ buf= harfbuzz.Buffer.new()
+ buf:add_utf8(urdu_text)
+ options = { language = harfbuzz.Language.new("urd"), script = harfbuzz.Script.new("Arab"), direction = harfbuzz.Direction.HB_DIRECTION_RTL }
+ end)
+
+ it("can take a table containing a valid features", function()
+ options.features = {
+ harfbuzz.Feature.new('+kern'),
+ harfbuzz.Feature.new('smcp')
+ }
+
+ harfbuzz.shape(font, buf, options)
+ local glyphs = buf:get_glyphs()
+ assert.True(#glyphs > 0)
+ end)
+
+ it("throws an error if feature string is invalid", function()
+ options.features = "#kern"
+ assert.has_error(function()
+ harfbuzz.shape(font, buf, options)
+ end, "Invalid feature string: '#kern'")
+ end)
+
+ it("throws an error if feature option is not a table or string", function()
+ options.features = 25
+ assert.has_error(function()
+ harfbuzz.shape(font, buf, options)
+ end, "Invalid features option")
+ end)
+
+ it("throws an error if features table does not contain a feature", function()
+ options.features = {
+ harfbuzz.Feature.new('+kern'),
+ 25,
+ harfbuzz.Feature.new('smcp')
+ }
+ assert.has_error(function()
+ harfbuzz.shape(font, buf, options)
+ end, "bad argument #-1 to 'shape_full' (harfbuzz.Feature expected, got number)")
+ end)
+
+ it("shapes a string appropriately with the features turned on",function()
+ buf= harfbuzz.Buffer.new()
+ buf:add_utf8("123")
+ local opts = { language = harfbuzz.Language.new("eng"), script = harfbuzz.Script.new("Latn"), direction = harfbuzz.Direction.HB_DIRECTION_LTR }
+ local amiri_face = harfbuzz.Face.new('fonts/amiri-regular.ttf')
+ local amiri_font = harfbuzz.Font.new(amiri_face)
+
+ -- Check normal shaping w/o features
+ buf= harfbuzz.Buffer.new()
+ buf:add_utf8("123")
+
+ harfbuzz.shape(amiri_font, buf, opts)
+ local glyphs = buf:get_glyphs()
+ compare_glyphs_against_fixture(glyphs, "amiri-regular_123.json")
+
+ -- Check shaping with '+numr'
+ buf= harfbuzz.Buffer.new()
+ buf:add_utf8("123")
+ opts.features = "+numr"
+ harfbuzz.shape(amiri_font, buf, opts)
+ glyphs = buf:get_glyphs()
+ compare_glyphs_against_fixture(glyphs, "amiri-regular_123_numr.json")
+ end)
+
+ it("can set specefic shaper",function()
+ options.shapers = { "fallback"}
+ harfbuzz.shape(font, buf, options)
+ local glyphs = buf:get_glyphs()
+ assert.are_equal(2, #glyphs)
+ assert.are_equal(906, glyphs[1].codepoint)
+ assert.are_equal(909, glyphs[2].codepoint)
+ end)
+ end)
+end)
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/harfbuzz.lua b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/harfbuzz.lua
new file mode 100644
index 00000000000..b7b0d7ff88c
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/harfbuzz.lua
@@ -0,0 +1,84 @@
+local hb = require("luaharfbuzz")
+
+-- special tags
+hb.Tag.NONE = hb.Tag.new()
+
+-- special script codes (ISO 15924)
+hb.Script.COMMON = hb.Script.new("Zyyy")
+hb.Script.INHERITED = hb.Script.new("Zinh")
+hb.Script.UNKNOWN = hb.Script.new("Zzzz")
+hb.Script.INVALID = hb.Script.from_iso15924_tag(hb.Tag.NONE)
+
+-- directions
+hb.Direction.INVALID = hb.Direction.new("invalid")
+hb.Direction.LTR = hb.Direction.new("ltr")
+hb.Direction.RTL = hb.Direction.new("rtl")
+hb.Direction.TTB = hb.Direction.new("ttb")
+hb.Direction.BTT = hb.Direction.new("btt")
+
+-- special languages
+hb.Language.INVALID = hb.Language.new()
+
+hb.shape = function(font, buf, options)
+ options = options or { }
+
+ -- Apply options to buffer if they are set.
+ if options.language then buf:set_language(options.language) end
+ if options.script then buf:set_script(options.script) end
+ if options.direction then buf:set_direction(options.direction) end
+
+ -- Guess segment properties, in case all steps above have failed
+ -- to set the right properties.
+ buf:guess_segment_properties()
+
+ local features = {}
+
+ -- Parse features
+ if type(options.features) == "string" then
+ for fs in string.gmatch(options.features, '([^,]+)') do
+ local feature = hb.Feature.new(fs)
+ if feature then
+ table.insert(features, hb.Feature.new(fs))
+ else
+ error(string.format("Invalid feature string: '%s'", fs))
+ end
+ end
+ elseif type(options.features) == "table" then
+ features = options.features
+ elseif options.features then -- non-nil but not a string or table
+ error("Invalid features option")
+ end
+
+ return hb.shape_full(font,buf,features,options.shapers or {})
+end
+
+-- For backward compatibility
+hb.Buffer.HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES = hb.Buffer.CLUSTER_LEVEL_MONOTONE_GRAPHEMES
+hb.Buffer.HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS = hb.Buffer.CLUSTER_LEVEL_MONOTONE_CHARACTERS
+hb.Buffer.HB_BUFFER_CLUSTER_LEVEL_CHARACTERS = hb.Buffer.CLUSTER_LEVEL_CHARACTERS
+hb.Buffer.HB_BUFFER_CLUSTER_LEVEL_DEFAULT = hb.Buffer.CLUSTER_LEVEL_DEFAULT
+
+hb.Tag.HB_TAG_NONE = hb.Tag.NONE
+
+hb.Script.HB_SCRIPT_COMMON = hb.Script.COMMON
+hb.Script.HB_SCRIPT_INHERITED = hb.Script.INHERITED
+hb.Script.HB_SCRIPT_UNKNOWN = hb.Script.UNKNOWN
+hb.Script.HB_SCRIPT_INVALID = hb.Script.INVALID
+
+hb.Language.HB_LANGUAGE_INVALID = hb.Language.INVALID
+
+hb.Direction.HB_DIRECTION_INVALID = hb.Direction.INVALID
+hb.Direction.HB_DIRECTION_LTR = hb.Direction.LTR
+hb.Direction.HB_DIRECTION_RTL = hb.Direction.RTL
+hb.Direction.HB_DIRECTION_TTB = hb.Direction.TTB
+hb.Direction.HB_DIRECTION_BTT = hb.Direction.BTT
+
+hb.Direction.HB_DIRECTION_IS_VALID = hb.Direction.is_valid
+hb.Direction.HB_DIRECTION_IS_HORIZONTAL = hb.Direction.is_horizontal
+hb.Direction.HB_DIRECTION_IS_VERTICAL = hb.Direction.is_vertical
+hb.Direction.HB_DIRECTION_IS_FORWARD = hb.Direction.is_forward
+hb.Direction.HB_DIRECTION_IS_BACKWARD = hb.Direction.is_backward
+
+hb.Buffer.get_glyph_infos_and_positions = hb.Buffer.get_glyphs
+
+return hb
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/harfbuzz.luadoc b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/harfbuzz.luadoc
new file mode 100644
index 00000000000..3b11636fae9
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/harfbuzz.luadoc
@@ -0,0 +1,535 @@
+-----------
+-- Lua bindings to Harfbuzz.
+-- * [Wiki](http://github.com/deepakjois/luaharfbuzz/wiki)
+-- * [Source on Github](https://github.com/deepakjois/luaharfbuzz)
+-- * [API Coverage Status](https://github.com/deepakjois/luaharfbuzz/blob/master/status/done.txt)
+--
+-- @author Deepak Jois <<deepak.jois@gmail.com>>
+-- @copyright 2016
+-- @license MIT
+-- @module harfbuzz
+
+--- Wraps `hb_version`
+-- @function version
+
+--- Wraps `hb_shape`.
+-- @param font `Font` to use for shaping
+--
+-- @param buffer `Buffer` to shape
+--
+-- @param[opt] options table containing one or more supported options:
+--
+-- * `direction`: A `Direction` object representing the object.
+-- * `script`: A `Script` object representing the script.
+-- * `language`: A `Language` object representing the language.
+-- * `features`: features to enable, specified as either of the following.
+-- - comma-separated list of features. See [feature string syntax reference](https://github.com/deepakjois/luaharfbuzz/wiki/Feature-Strings)
+-- - table of `Feature` objects
+-- @function shape
+
+--- Lua wrapper for `hb_blob_t` type
+-- @type Blob
+
+--- Wraps `hb_blob_create`.
+-- Initializes a new `hb_blob_t`.
+-- @param data lua string containing binary or character data.
+-- @function Blob.new
+
+--- Wraps `hb_blob_create_from_file`.
+-- Initializes a new `hb_blob_t`.
+-- @param filename lua string.
+-- @function Blob.new_from_file
+
+--- Wraps `hb_blob_get_length`.
+-- @function Blob:get_length
+
+--- Wraps `hb_blob_get_data`.
+-- @function Blob:get_data
+
+--- Lua wrapper for `hb_face_t` type
+-- @type Face
+
+--- Wraps `hb_face_create`.
+-- Initializes a new `hb_face_t` from a `Blob` object.
+-- @param blob `Blob` to read the font from.
+-- @param[opt=0] font_index index of font to read.
+-- @function Face.new_from_blob
+
+--- Create a new `Face` from a file.
+-- Makes a call to `Face:new_from_blob` after creating a `Blob` from the
+-- file contents.
+-- @param file path to font file.
+-- @param[opt=0] font_index index of font to read.
+-- @function Face.new
+
+--- Wraps `hb_face_collect_unicodes`.
+-- @return table of codepoints supported by the face.
+-- @function Face:collect_unicodes
+
+--- Wraps `hb_face_get_glyph_count`.
+-- @function Face:get_glyph_count
+
+--- Wraps `hb_face_reference_table`.
+-- @param tag `Tag` object of the table.
+-- @return `Blob` object for the face table of `tag`.
+-- @function Face:get_table
+
+--- Wraps `hb_face_get_table_tags`.
+-- @return table of `Tag`s representing face table tags.
+-- @function Face:get_table_tags
+
+--- Wraps `hb_face_get_upem`.
+-- @function Face:get_upem
+
+--- Wraps `hb_ot_color_has_palettes`.
+-- @function Face:ot_color_has_palettes
+
+--- Wraps `hb_ot_color_palette_get_count`.
+-- @function Face:ot_color_palette_get_count
+
+--- Wraps `hb_ot_color_palette_get_colors`.
+-- @function Face:ot_color_palette_get_colors
+
+--- Wraps `hb_ot_color_has_layers`.
+-- @function Face:ot_color_has_layers
+
+--- Wraps `hb_ot_color_glyph_get_layers`.
+-- @function Face:ot_color_glyph_get_layers
+
+--- Wraps `hb_ot_color_has_png`.
+-- @function Face:ot_color_has_png
+
+--- Wraps `hb_ot_layout_table_get_script_tags`.
+-- @function Face:ot_layout_get_script_tags
+
+--- Wraps `hb_ot_layout_script_get_language_tags`.
+-- @function Face:ot_layout_get_language_tags
+
+--- Wraps `hb_ot_layout_language_get_feature_tags`.
+-- @function Face:ot_layout_get_feature_tags
+
+--- Wraps `hb_ot_layout_table_find_script`.
+-- @function Face:ot_layout_find_script
+
+--- Wraps `hb_ot_layout_script_find_language`.
+-- @function Face:ot_layout_find_language
+
+--- Wraps `hb_ot_layout_language_find_feature`.
+-- @function Face:ot_layout_find_feature
+
+
+--- Lua wrapper for `hb_font_t` type
+-- @type Font
+
+--- Wraps `hb_font_create`, and sets up some defaults for scale and shaping functions.
+-- Initializes a new `hb_font_t` from a `Face` object. Sets the default scale
+-- to the face’s upem value, and sets the font shaping functions by
+-- calling `hb_ot_font_set_funcs` on it.
+-- @param face `Face` object.
+-- @function Font.new
+
+--- Wraps `hb_font_get_scale`.
+-- @return two values for the x-scale and y-scale of the font.
+-- @function Font:get_scale
+
+--- Wraps `hb_font_set_scale`.
+-- @param x_scale desired x-scale of font.
+-- @param y_scale desired y-scale of font.
+-- @function Font:set_scale
+
+--- Wraps `hb_font_get_h_extents`.
+-- @return font extents table for horizontal direction, contains the following
+-- or `nil` if HarfBuzz fails to load font extents:
+--
+-- * `ascender`: typographic ascender.
+-- * `descender`: typographic descender.
+-- * `line_gap`: line spacing gap.
+-- @function Font:get_h_extents
+
+--- Wraps `hb_font_get_v_extents`.
+-- @return font extents table for vertical direction, similar to
+-- `Font:get_h_extents`, or `nil` if HarfBuzz fails to load font extents:
+-- @function Font:get_v_extents
+
+--- Wraps `hb_font_get_glyph_extents`.
+-- @param glyph index inside the font.
+-- @return extents table contains the following or `nil` if HarfBuzz fails to
+-- load glyph extents:
+--
+-- * `x_bearing`: left side of glyph from origin.
+-- * `y_bearing`: top side of glyph from origin.
+-- * `width`: distance from left to right side.
+-- * `height`: distance from top to bottom side.
+-- @function Font:get_glyph_extents
+
+--- Wraps `hb_font_get_glyph_name`.
+-- @param glyph index inside the font.
+-- @return name of the glyph or nil.
+-- @function Font:get_glyph_name
+
+--- Wraps `hb_font_get_glyph_from_name`.
+-- @param name of the glyph.
+-- @return glyph index inside the font or nil.
+-- @function Font:get_glyph_from_name
+
+--- Wraps `hb_font_get_glyph_h_advance`.
+-- @param glyph index inside the font.
+-- @return advance glyph advance of the glyph in horizontal direction.
+-- @function Font:get_glyph_h_advance
+
+--- Wraps `hb_font_get_glyph_v_advance`.
+-- @param glyph index inside the font.
+-- @return advance glyph advance of the glyph in vertical direction.
+-- @function Font:get_glyph_v_advance
+
+--- Wraps `hb_font_get_nominal_glyph`.
+-- @param codepoint.
+-- @return glyph index or `nil` if `codepoint` is not supported by the font.
+-- @function Font:get_nominal_glyph
+
+--- Wraps `hb_ot_color_glyph_get_png`.
+-- @function Font:ot_color_glyph_get_png
+
+--- Lua wrapper for `hb_buffer_t` type.
+-- @type Buffer
+
+--- Wraps `hb_buffer_create`.
+-- @function Buffer.new
+
+--- Wraps `hb_buffer_add_utf8`.
+-- @param text UTF8 encoded string.
+-- @param[opt=0] item_offset 0-indexed offset in `text`, from where to start adding.
+-- @param[opt=-1] item_length length to add from `item_offset`. `-1` adds till end of `text`.
+-- @function Buffer:add_utf8
+
+--- Wraps `hb_buffer_add_codepoints`.
+-- @param text table with codepoints as lua numbers.
+-- @param[opt=0] item_offset 0-indexed offset in `text`, from where to start adding.
+-- @param[opt=-1] item_length length to add from `item_offset`. `-1` adds till end of&nbsp;`text`.
+-- @function Buffer:add_codepoints
+
+--- Wraps `hb_buffer_set_direction`.
+-- @param dir A `Direction` object.
+-- @function Buffer:set_direction
+
+--- Wraps `hb_buffer_get_direction`.
+-- @return A `Direction` object.
+-- @function Buffer:get_direction
+
+--- Wraps `hb_buffer_set_script`.
+-- @param script A `Script` object.
+-- @function Buffer:set_script
+
+--- Wraps `hb_buffer_get_script`.
+-- @return A `Script` object.
+-- @function Buffer:get_script
+
+--- Wraps `hb_buffer_set_language`.
+-- @param lang A `Language` object
+-- @function Buffer:set_language
+
+--- Wraps `hb_buffer_get_language`.
+-- @return A `Language` object
+-- @function Buffer:get_language
+
+--- Wraps `hb_buffer_reverse`.
+-- @function Buffer:reverse
+
+--- Wraps `hb_buffer_get_length`.
+-- @function Buffer:get_length
+
+--- Wraps `hb_buffer_get_cluster_level`.
+-- @return see [Cluster Levels](#Cluster_Levels)
+-- @function Buffer:get_cluster_level
+
+--- Wraps `hb_buffer_set_cluster_level`.
+-- @param level see [Cluster Levels](#Cluster_Levels)
+-- @function Buffer:set_cluster_level
+
+--- Wraps `hb_buffer_guess_segment_properties`.
+-- @function Buffer:guess_segment_properties
+
+--- Helper method to get shaped glyph data.
+-- Calls `hb_buffer_get_glyph_infos`, `hb_buffer_get_glyph_positions` and
+-- `hb_glyph_info_get_glyph_flags`, and assembles the data into a Lua table.
+-- @return table containing data for each glyph, in a nested table. Each nested
+-- table contains the following:
+--
+-- * `x_advance`: horizontal advance.
+-- * `y_advance`: vertical advance.
+-- * `x_offset`: horizontal displacement.
+-- * `y_offset`: vertical displacement.
+-- * `cluster`: glyph cluster index within input.
+-- * `codepoint`: glyph index inside the font _(this field name is a bit misleading, but that’s what Harfbuzz uses)_.
+-- * `flags`: glyph flags
+-- @function Buffer:get_glyphs
+
+--- Cluster Levels.
+-- See [Harfbuzz docs](http://behdad.github.io/harfbuzz/clusters.html) for more details
+-- about what each of these levels mean.
+-- @section
+
+--- Wraps `HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES`.
+-- @field Buffer.CLUSTER_LEVEL_MONOTONE_GRAPHEMES
+
+--- Wraps `HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS`.
+-- @field Buffer.CLUSTER_LEVEL_MONOTONE_CHARACTERS
+
+--- Wraps `HB_BUFFER_CLUSTER_LEVEL_CHARACTERS`.
+-- @field Buffer.CLUSTER_LEVEL_CHARACTERS
+
+--- Wraps `HB_BUFFER_CLUSTER_LEVEL_DEFAULT`.
+-- @field Buffer.CLUSTER_LEVEL_DEFAULT
+
+--- Wraps `HB_GLYPH_FLAG_UNSAFE_TO_BREAK`.
+-- @field Buffer.GLYPH_FLAG_UNSAFE_TO_BREAK
+
+--- Wraps `HB_GLYPH_FLAG_DEFINED`.
+-- @field Buffer.GLYPH_FLAG_DEFINED
+
+--- Lua wrapper for `hb_feature_t` type
+-- @type Feature
+
+--- Wraps `hb_feature_from_string`
+-- @param feature_string See [feature string syntax reference](https://github.com/deepakjois/luaharfbuzz/wiki/Feature-Strings)
+-- @function Feature.new
+
+--- Wraps `hb_feature_to_string`.
+-- Enables nice output with `tostring(…)`.
+-- @function Feature:__tostring
+
+--- Lua wrapper for `hb_tag_t` type.
+-- @type Tag
+
+--- Wraps `hb_tag_from_string`.
+-- @param string to be converted to a `Tag` object.
+-- @return a `Tag` object.
+-- @function Tag.new
+
+--- Wraps `hb_tag_to_string`. Enable nice output with `tostring(…)`.
+-- @return Returns a string representation for the tag object.
+-- @function Tag:__to_string
+
+--- Enables equality comparisions with `==` between two tags.
+-- @return `true` or `false` depending on whether the two tags are equal.
+-- @function Tag:__eq
+
+
+--- Lua wrapper for `hb_script_t` type.
+-- @type Script
+
+--- Wraps `hb_script_from_string`.
+-- @param script 4-letter script code according to the [ISO 15924 standard](http://www.unicode.org/iso15924/iso15924-num.html).
+-- @return a `Script` object.
+-- @function Script.new
+
+--- Wraps `hb_script_from_iso15924_tag`
+-- @param tag a `Tag` object representing a [ISO 15924 script](http://www.unicode.org/iso15924/iso15924-num.html).
+-- @function Script.from_iso15924_tag
+
+--- Wraps `hb_script_to_iso15924_tag`.
+-- @return a `Tag` object representing the script.
+-- @function Script:to_iso15924_tag
+
+--- Enable nice output with `tostring(…)`
+-- @return Returns a 4-letter [ISO 15924 script code](http://www.unicode.org/iso15924/iso15924-num.html) for the script object.
+-- @function Script:__to_string
+
+--- Enables equality comparisions with `==` between two scripts.
+-- @return `true` or `false` depending on whether the two scripts are equal.
+-- @function Script:__eq
+
+--- Predefined Script Codes.
+-- Predefined directions that correspond to their original definitions in Harfbuzz.
+-- @section
+
+--- Wraps `HB_SCRIPT_COMMON`.
+-- @field Script.COMMON
+
+--- Wraps `HB_SCRIPT_INHERITED`.
+-- @field Script.INHERITED
+
+--- Wraps `HB_SCRIPT_UNKNOWN`.
+-- @field Script.UNKNOWN
+
+--- Wraps `HB_SCRIPT_INVALID`.
+-- @field Script.INVALID
+
+--- Lua wrapper for `hb_direction_t` type.
+-- @type Direction
+
+--- Wraps `hb_direction_from_string`.
+-- @param dir can be one of `ltr`, `rtl`, `ttb`, `btt` or `invalid`.
+-- @return a `Direction` object.
+-- @function Direction.new
+
+--- Wraps `hb_direction_to_string`. Enable nice output with `tostring(…)`.
+-- @return Returns a string representation for direction.
+-- @function Direction:__to_string
+
+--- Enables equality comparisions with `==` between two directions.
+-- @return `true` or `false` depending on whether the two tags are equal.
+-- @function Direction:__eq
+
+--- Wraps `HB_DIRECTION_IS_VALID`.
+-- @return a boolean value
+-- @function Direction:is_valid
+
+--- Wraps `HB_DIRECTION_IS_HORIZONTAL`.
+-- @return a boolean value
+-- @function Direction:is_horizontal
+
+--- Wraps `HB_DIRECTION_IS_VERTICAL`.
+-- @return a boolean value
+-- @function Direction:is_vertical
+
+--- Wraps `HB_DIRECTION_IS_FORWARD`.
+-- @return a boolean value
+-- @function Direction:is_forward
+
+--- Wraps `HB_DIRECTION_IS_BACKWARD`.
+-- @return a boolean value
+-- @function Direction:is_backward
+
+--- Predefined directions.
+-- Predefined directions that correspond to their original definitions in Harfbuzz.
+-- @section
+
+--- Wraps `HB_DIRECTION_LTR`.
+-- @field Direction.LTR
+
+--- Wraps `HB_DIRECTION_RTL`.
+-- @field Direction.RTL
+
+--- Wraps `HB_DIRECTION_TTB`.
+-- @field Direction.TTB
+
+--- Wraps `HB_DIRECTION_LTR`.
+-- @field Direction.BTT
+
+--- Lua wrapper for `hb_language_t` type.
+-- @type Language
+
+--- Wraps `hb_language_from_string`.
+-- @param lang [three-letter language tag](http://www.microsoft.com/typography/otspec/languagetags.htm) to be converted to a `Language` object.
+-- @return a `Language` object.
+-- @function Language.new
+
+--- Wraps `hb_language_to_string`. Enable nice output with `tostring(…)`.
+-- @return Returns a string representation for the language object.
+-- @function Language:__to_string
+
+--- Enables equality comparisions with `==` between two languages.
+-- @return `true` or `false` depending on whether the two languages are equal.
+-- @function Language:__eq
+
+--- Predefined languages.
+-- Predefined languages that correspond to their original definitions in Harfbuzz.
+-- @section
+
+--- Wraps `HB_LANGUAGE_INVALID`.
+-- @field Language.INVALID
+
+
+--- Unicode functions.
+-- @section
+
+--- Wraps `hb_unicode_script`
+-- @param char Unicode codepoint
+-- @return a `Script` object.
+-- @function unicode.script
+
+
+--- Predefined Name IDs.
+-- Predefined OpenType 'name' table name identifier.
+-- @section
+
+--- Wraps `HB_OT_NAME_ID_COPYRIGHT`
+-- @field ot.NAME_ID_COPYRIGHT
+
+--- Wraps `HB_OT_NAME_ID_FONT_FAMILY`
+-- @field ot.NAME_ID_FONT_FAMILY
+
+--- Wraps `HB_OT_NAME_ID_FONT_SUBFAMILY`
+-- @field ot.NAME_ID_FONT_SUBFAMILY
+
+--- Wraps `HB_OT_NAME_ID_UNIQUE_ID`
+-- @field ot.NAME_ID_UNIQUE_ID
+
+--- Wraps `HB_OT_NAME_ID_FULL_NAME`
+-- @field ot.NAME_ID_FULL_NAME
+
+--- Wraps `HB_OT_NAME_ID_VERSION_STRING`
+-- @field ot.NAME_ID_VERSION_STRING
+
+--- Wraps `HB_OT_NAME_ID_POSTSCRIPT_NAME`
+-- @field ot.NAME_ID_POSTSCRIPT_NAME
+
+--- Wraps `HB_OT_NAME_ID_TRADEMARK`
+-- @field ot.NAME_ID_TRADEMARK
+
+--- Wraps `HB_OT_NAME_ID_MANUFACTURER`
+-- @field ot.NAME_ID_MANUFACTURER
+
+--- Wraps `HB_OT_NAME_ID_DESIGNER`
+-- @field ot.NAME_ID_DESIGNER
+
+--- Wraps `HB_OT_NAME_ID_DESCRIPTION`
+-- @field ot.NAME_ID_DESCRIPTION
+
+--- Wraps `HB_OT_NAME_ID_VENDOR_URL`
+-- @field ot.NAME_ID_VENDOR_URL
+
+--- Wraps `HB_OT_NAME_ID_DESIGNER_URL`
+-- @field ot.NAME_ID_DESIGNER_URL
+
+--- Wraps `HB_OT_NAME_ID_LICENSE`
+-- @field ot.NAME_ID_LICENSE
+
+--- Wraps `HB_OT_NAME_ID_LICENSE_URL`
+-- @field ot.NAME_ID_LICENSE_URL
+
+--- Wraps `HB_OT_NAME_ID_TYPOGRAPHIC_FAMILY`
+-- @field ot.NAME_ID_TYPOGRAPHIC_FAMILY
+
+--- Wraps `HB_OT_NAME_ID_TYPOGRAPHIC_SUBFAMILY`
+-- @field ot.NAME_ID_TYPOGRAPHIC_SUBFAMILY
+
+--- Wraps `HB_OT_NAME_ID_MAC_FULL_NAME`
+-- @field ot.NAME_ID_MAC_FULL_NAME
+
+--- Wraps `HB_OT_NAME_ID_SAMPLE_TEXT`
+-- @field ot.NAME_ID_SAMPLE_TEXT
+
+--- Wraps `HB_OT_NAME_ID_CID_FINDFONT_NAME`
+-- @field ot.NAME_ID_CID_FINDFONT_NAME
+
+--- Wraps `HB_OT_NAME_ID_WWS_FAMILY`
+-- @field ot.NAME_ID_WWS_FAMILY
+
+--- Wraps `HB_OT_NAME_ID_WWS_SUBFAMILY`
+-- @field ot.NAME_ID_WWS_SUBFAMILY
+
+--- Wraps `HB_OT_NAME_ID_LIGHT_BACKGROUND`
+-- @field ot.NAME_ID_LIGHT_BACKGROUND
+
+--- Wraps `HB_OT_NAME_ID_DARK_BACKGROUND`
+-- @field ot.NAME_ID_DARK_BACKGROUND
+
+--- Wraps `HB_OT_NAME_ID_VARIATIONS_PS_PREFIX`
+-- @field ot.NAME_ID_VARIATIONS_PS_PREFIX
+
+--- Wraps `HB_OT_NAME_ID_INVALID`
+-- @field ot.NAME_ID_INVALID
+
+--- Wraps `HB_OT_LAYOUT_NO_SCRIPT_INDEX`
+-- @field ot.LAYOUT_NO_SCRIPT_INDEX
+
+--- Wraps `HB_OT_LAYOUT_NO_FEATURE_INDEX`
+-- @field ot.LAYOUT_NO_FEATURE_INDEX
+
+--- Wraps `HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX`
+-- @field ot.LAYOUT_DEFAULT_LANGUAGE_INDEX
+
+--- Wraps `HB_OT_LAYOUT_NO_VARIATIONS_INDEX`
+-- @field ot.LAYOUT_NO_VARIATIONS_INDEX
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/blob.c b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/blob.c
new file mode 100644
index 00000000000..889f5b19742
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/blob.c
@@ -0,0 +1,60 @@
+#include "luaharfbuzz.h"
+
+static int blob_new(lua_State *L) {
+ Blob *b;
+ size_t data_l;
+ const char *data = luaL_checklstring(L, 1, &data_l);
+
+ b = (Blob *)lua_newuserdata(L, sizeof(*b));
+ luaL_getmetatable(L, "harfbuzz.Blob");
+ lua_setmetatable(L, -2);
+
+ *b = hb_blob_create(data, data_l, HB_MEMORY_MODE_DUPLICATE, (void*)data, NULL);
+ return 1;
+}
+
+static int blob_new_from_file(lua_State *L) {
+ Blob *b;
+ const char *file_name = luaL_checkstring(L, 1);
+
+ b = (Blob *)lua_newuserdata(L, sizeof(*b));
+ luaL_getmetatable(L, "harfbuzz.Blob");
+ lua_setmetatable(L, -2);
+
+ *b = hb_blob_create_from_file(file_name);
+ return 1;
+}
+
+static int blob_get_length(lua_State *L) {
+ Blob *b = (Blob *)luaL_checkudata(L, 1, "harfbuzz.Blob");
+
+ lua_pushinteger(L, hb_blob_get_length(*b));
+ return 1;
+}
+
+static int blob_get_data(lua_State *L) {
+ Blob *b = (Blob *)luaL_checkudata(L, 1, "harfbuzz.Blob");
+ unsigned int l;
+ const char *d;
+
+ d = hb_blob_get_data(*b, &l);
+ lua_pushlstring(L, d, l);
+
+ return 1;
+}
+
+static const struct luaL_Reg blob_methods[] = {
+ { "get_length", blob_get_length },
+ { "get_data", blob_get_data },
+ { NULL, NULL }
+};
+
+static const struct luaL_Reg blob_functions[] = {
+ { "new", blob_new },
+ { "new_from_file", blob_new_from_file },
+ { NULL, NULL }
+};
+
+int register_blob(lua_State *L) {
+ return register_class(L, "harfbuzz.Blob", blob_methods, blob_functions, NULL);
+}
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/buffer.c b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/buffer.c
new file mode 100644
index 00000000000..11f803693fd
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/buffer.c
@@ -0,0 +1,274 @@
+#include "luaharfbuzz.h"
+
+#ifdef LuajitTeX
+static void lua_len (lua_State *L, int i) {
+ switch (lua_type(L, i)) {
+ case LUA_TSTRING:
+ lua_pushnumber(L, (lua_Number)lua_objlen(L, i));
+ break;
+ case LUA_TTABLE:
+ if (!luaL_callmeta(L, i, "__len"))
+ lua_pushnumber(L, (lua_Number)lua_objlen(L, i));
+ break;
+ case LUA_TUSERDATA:
+ if (luaL_callmeta(L, i, "__len"))
+ break;
+ /* FALLTHROUGH */
+ default:
+ luaL_error(L, "attempt to get length of a %s value",
+ lua_typename(L, lua_type(L, i)));
+ }
+}
+#endif
+
+
+static int buffer_new(lua_State *L) {
+ Buffer *b;
+
+ b = (Buffer *)lua_newuserdata(L, sizeof(*b));
+ luaL_getmetatable(L, "harfbuzz.Buffer");
+ lua_setmetatable(L, -2);
+
+ *b = hb_buffer_create();
+ return 1;
+}
+
+static int buffer_guess_segment_properties(lua_State *L) {
+ Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
+
+ hb_buffer_guess_segment_properties(*b);
+ return 0;
+}
+
+static int buffer_get_direction(lua_State *L) {
+ Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
+
+ Direction *dp = (Direction *)lua_newuserdata(L, sizeof(*dp));
+ luaL_getmetatable(L, "harfbuzz.Direction");
+ lua_setmetatable(L, -2);
+
+ *dp = hb_buffer_get_direction(*b);
+ return 1;
+}
+
+static int buffer_set_direction(lua_State *L) {
+ Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
+ Direction* dir = (Direction *)luaL_checkudata(L, 2, "harfbuzz.Direction");
+
+ hb_buffer_set_direction(*b, *dir);
+ return 0;
+}
+
+static int buffer_get_language(lua_State *L) {
+ Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
+
+ Language *lp = (Language *)lua_newuserdata(L, sizeof(*lp));
+ luaL_getmetatable(L, "harfbuzz.Language");
+ lua_setmetatable(L, -2);
+
+ *lp = hb_buffer_get_language(*b);
+ return 1;
+}
+
+static int buffer_set_language(lua_State *L) {
+ Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
+ Language *lang = (Language *)luaL_checkudata(L, 2, "harfbuzz.Language");
+
+ hb_buffer_set_language(*b, *lang);
+ return 0;
+}
+
+static int buffer_get_script(lua_State *L) {
+ Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
+
+ Script *sp = (Script *)lua_newuserdata(L, sizeof(*sp));
+ luaL_getmetatable(L, "harfbuzz.Script");
+ lua_setmetatable(L, -2);
+
+ *sp = hb_buffer_get_script(*b);
+ return 1;
+}
+
+static int buffer_set_script(lua_State *L) {
+ Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
+ Script *script = (Script *)luaL_checkudata(L, 2, "harfbuzz.Script");
+
+ hb_buffer_set_script(*b, *script);
+ return 0;
+}
+
+static int buffer_add_codepoints(lua_State *L) {
+ Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
+ unsigned int item_offset;
+ int item_length;
+
+ luaL_checktype(L, 2, LUA_TTABLE);
+ item_offset = luaL_optinteger(L, 3, 0);
+ item_length = luaL_optinteger(L, 4, -1);
+
+ lua_len (L, 2);
+ unsigned int n = luaL_checkinteger(L, -1);
+ lua_pop(L, 1);
+
+ hb_codepoint_t *text = (hb_codepoint_t *) malloc(n * sizeof(hb_codepoint_t));
+
+ lua_pushnil(L); int i = 0;
+ while (lua_next(L, 2) != 0) {
+ hb_codepoint_t c = (hb_codepoint_t) luaL_checkinteger(L, -1);
+ text[i++] = c;
+ lua_pop(L, 1);
+ }
+
+ hb_buffer_add_codepoints(*b, text, n, item_offset, item_length);
+
+ free(text);
+
+ return 0;
+}
+
+static int buffer_add_utf8(lua_State *L) {
+ Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
+ const char *text;
+ unsigned int item_offset;
+ int item_length;
+
+ text = luaL_checkstring(L, 2);
+ item_offset = luaL_optinteger(L, 3, 0);
+ item_length = luaL_optinteger(L, 4, -1);
+
+ hb_buffer_add_utf8(*b, text, -1, item_offset, item_length);
+
+ return 0;
+}
+
+static int buffer_destroy(lua_State *L) {
+ Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
+
+ hb_buffer_destroy(*b);
+ return 0;
+}
+
+static int buffer_get_glyphs(lua_State *L) {
+ Buffer *buf = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
+
+ // Get glyph info and positions out of buffer
+ unsigned int len = hb_buffer_get_length(*buf);
+ hb_glyph_info_t *info = hb_buffer_get_glyph_infos(*buf, NULL);
+ hb_glyph_position_t *pos = hb_buffer_get_glyph_positions(*buf, NULL);
+ hb_glyph_flags_t flags;
+ unsigned int i;
+
+ // Create Lua table and push glyph data onto it.
+ lua_createtable(L, len, 0); // parent table
+
+ for (i = 0; i < len; i++) {
+ lua_pushinteger(L, i+1); // 1-indexed key parent table
+ lua_createtable(L, 0, 7); // child table
+
+ lua_pushinteger(L, info[i].codepoint);
+ lua_setfield(L, -2, "codepoint");
+
+ lua_pushinteger(L, info[i].cluster);
+ lua_setfield(L, -2, "cluster");
+
+ lua_pushnumber(L, pos[i].x_advance);
+ lua_setfield(L, -2, "x_advance");
+
+ lua_pushnumber(L, pos[i].y_advance);
+ lua_setfield(L, -2, "y_advance");
+
+ lua_pushnumber(L, pos[i].x_offset);
+ lua_setfield(L, -2, "x_offset");
+
+ lua_pushnumber(L, pos[i].y_offset);
+ lua_setfield(L, -2, "y_offset");
+
+ flags = hb_glyph_info_get_glyph_flags(&(info[i]));
+ if (flags & HB_GLYPH_FLAG_DEFINED) {
+ lua_pushnumber(L, flags);
+ lua_setfield(L, -2, "flags");
+ }
+
+ lua_settable(L, -3); // Add child table at index i+1 to parent table
+ }
+
+ return 1;
+}
+
+static int buffer_reverse(lua_State *L) {
+ Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
+
+ hb_buffer_reverse(*b);
+ return 0;
+}
+
+static int buffer_get_length(lua_State *L) {
+ Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
+
+ lua_pushinteger(L, hb_buffer_get_length(*b));
+ return 1;
+}
+
+static int buffer_get_cluster_level(lua_State *L) {
+ Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
+
+ lua_pushinteger(L, hb_buffer_get_cluster_level(*b));
+ return 1;
+}
+
+static int buffer_set_cluster_level(lua_State *L) {
+ Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
+
+ unsigned int l = luaL_checkinteger(L, 2);
+
+ hb_buffer_set_cluster_level(*b, l);
+ return 0;
+}
+
+static int buffer_pre_allocate(lua_State *L) {
+ Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
+
+ unsigned int n = luaL_checkinteger(L, 2);
+
+ lua_pushboolean(L, hb_buffer_pre_allocate(*b, n));
+ return 1;
+}
+
+static const struct luaL_Reg buffer_methods[] = {
+ { "__gc", buffer_destroy },
+ { "add_utf8", buffer_add_utf8 },
+ { "add_codepoints", buffer_add_codepoints },
+ { "set_direction", buffer_set_direction },
+ { "get_direction", buffer_get_direction },
+ { "set_language", buffer_set_language },
+ { "get_language", buffer_get_language },
+ { "set_script", buffer_set_script },
+ { "get_script", buffer_get_script },
+ { "get_glyphs", buffer_get_glyphs },
+ { "guess_segment_properties", buffer_guess_segment_properties },
+ { "reverse", buffer_reverse },
+ { "get_length", buffer_get_length },
+ { "get_cluster_level", buffer_get_cluster_level },
+ { "set_cluster_level", buffer_set_cluster_level },
+ { "pre_allocate", buffer_pre_allocate },
+ { NULL, NULL }
+};
+
+static const struct luaL_Reg buffer_functions[] = {
+ { "new", buffer_new },
+ { NULL, NULL }
+};
+
+static const struct luahb_constant_t buffer_constants[] = {
+ { "CLUSTER_LEVEL_MONOTONE_GRAPHEMES", HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES },
+ { "CLUSTER_LEVEL_MONOTONE_CHARACTERS", HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS },
+ { "CLUSTER_LEVEL_CHARACTERS", HB_BUFFER_CLUSTER_LEVEL_CHARACTERS },
+ { "CLUSTER_LEVEL_DEFAULT", HB_BUFFER_CLUSTER_LEVEL_DEFAULT },
+ { "GLYPH_FLAG_UNSAFE_TO_BREAK", HB_GLYPH_FLAG_UNSAFE_TO_BREAK },
+ { "GLYPH_FLAG_DEFINED", HB_GLYPH_FLAG_DEFINED },
+ { NULL, 0 }
+};
+
+int register_buffer(lua_State *L) {
+ return register_class(L, "harfbuzz.Buffer", buffer_methods, buffer_functions, buffer_constants);
+}
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/class_utils.c b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/class_utils.c
new file mode 100644
index 00000000000..89428526a7c
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/class_utils.c
@@ -0,0 +1,33 @@
+// Utility functions to create Lua classes.
+#include "luaharfbuzz.h"
+
+int register_class(lua_State *L, const char *name, const luaL_Reg *methods, const luaL_Reg *functions, const luahb_constant_t *constants) {
+ luaL_newmetatable(L, name);
+ lua_pushvalue(L, -1);
+ lua_setfield(L, -2, "__index");
+
+ if (constants) {
+ while (constants->name) {
+ lua_pushinteger(L, constants->value);
+ lua_setfield(L, -2, constants->name);
+ constants++;
+ }
+ }
+#ifdef LuajitTeX
+ luaL_register(L,NULL,methods);
+#else
+ luaL_setfuncs(L, methods, 0);
+#endif
+ lua_pop(L, 1);
+
+ lua_newtable(L);
+#ifdef LuajitTeX
+ luaL_register(L,NULL,functions);
+#else
+ luaL_setfuncs(L, functions, 0);
+#endif
+ luaL_getmetatable(L, name);
+ lua_setmetatable(L, -2);
+ return 1;
+}
+
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/direction.c b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/direction.c
new file mode 100644
index 00000000000..644b3af30a2
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/direction.c
@@ -0,0 +1,84 @@
+// harfbuzz.Feature
+#include "luaharfbuzz.h"
+
+static int direction_new(lua_State *L) {
+ Direction *d;
+ const char *dir = luaL_checkstring(L, 1);
+
+ d = (Direction *)lua_newuserdata(L, sizeof(*d));
+ luaL_getmetatable(L, "harfbuzz.Direction");
+ lua_setmetatable(L, -2);
+
+ *d = hb_direction_from_string(dir, -1);
+ return 1;
+}
+
+static int direction_to_string(lua_State *L) {
+ Direction* d = (Direction *)luaL_checkudata(L, 1, "harfbuzz.Direction");
+
+ lua_pushstring(L, hb_direction_to_string(*d));
+ return 1;
+}
+
+static int direction_equals(lua_State *L) {
+ Direction* lhs = (Direction *)luaL_checkudata(L, 1, "harfbuzz.Direction");
+ Direction* rhs = (Direction *)luaL_checkudata(L, 2, "harfbuzz.Direction");
+
+ lua_pushboolean(L, *lhs == *rhs);
+ return 1;
+}
+
+static int direction_is_valid(lua_State *L) {
+ Direction* d = (Direction *)luaL_checkudata(L, 1, "harfbuzz.Direction");
+
+ lua_pushboolean(L, HB_DIRECTION_IS_VALID(*d));
+ return 1;
+}
+
+static int direction_is_horizontal(lua_State *L) {
+ Direction* d = (Direction *)luaL_checkudata(L, 1, "harfbuzz.Direction");
+
+ lua_pushboolean(L, HB_DIRECTION_IS_HORIZONTAL(*d));
+ return 1;
+}
+
+static int direction_is_vertical(lua_State *L) {
+ Direction* d = (Direction *)luaL_checkudata(L, 1, "harfbuzz.Direction");
+
+ lua_pushboolean(L, HB_DIRECTION_IS_VERTICAL(*d));
+ return 1;
+}
+
+static int direction_is_forward(lua_State *L) {
+ Direction* d = (Direction *)luaL_checkudata(L, 1, "harfbuzz.Direction");
+
+ lua_pushboolean(L, HB_DIRECTION_IS_FORWARD(*d));
+ return 1;
+}
+
+static int direction_is_backward(lua_State *L) {
+ Direction* d = (Direction *)luaL_checkudata(L, 1, "harfbuzz.Direction");
+
+ lua_pushboolean(L, HB_DIRECTION_IS_BACKWARD(*d));
+ return 1;
+}
+
+static const struct luaL_Reg direction_methods[] = {
+ { "__tostring", direction_to_string },
+ { "__eq", direction_equals },
+ { "is_valid", direction_is_valid },
+ { "is_horizontal", direction_is_horizontal },
+ { "is_vertical", direction_is_vertical },
+ { "is_forward", direction_is_forward },
+ { "is_backward", direction_is_backward },
+ { NULL, NULL }
+};
+
+static const struct luaL_Reg direction_functions[] = {
+ { "new", direction_new },
+ { NULL, NULL }
+};
+
+int register_direction(lua_State *L) {
+ return register_class(L, "harfbuzz.Direction", direction_methods, direction_functions, NULL);
+}
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/face.c b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/face.c
new file mode 100644
index 00000000000..d7840ae3cd0
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/face.c
@@ -0,0 +1,439 @@
+#include "luaharfbuzz.h"
+
+/* Size of static arrays we use to avoid heap allocating memory when reading
+ * data from HarfBuzz. */
+#define STATIC_ARRAY_SIZE 128
+
+static int face_new(lua_State *L) {
+ Face *f;
+ hb_blob_t *blob;
+ hb_face_t *face;
+ const char *file_name = luaL_checkstring(L, 1);
+ unsigned int face_index = (unsigned int) luaL_optinteger(L, 2, 0);
+
+ blob = hb_blob_create_from_file(file_name);
+ face = hb_face_create(blob, face_index);
+
+ if (blob == hb_blob_get_empty() || face == hb_face_get_empty()) {
+ lua_pushnil(L);
+ } else {
+ f = (Face *)lua_newuserdata(L, sizeof(*f));
+ *f = face;
+ luaL_getmetatable(L, "harfbuzz.Face");
+ lua_setmetatable(L, -2);
+ }
+ return 1;
+}
+
+static int face_new_from_blob(lua_State *L) {
+ Face *f;
+ hb_face_t *face;
+ Blob *blob = luaL_checkudata(L, 1, "harfbuzz.Blob");
+ unsigned int face_index = (unsigned int) luaL_optinteger(L, 2, 0);
+
+ face = hb_face_create(*blob, face_index);
+
+ if (*blob == hb_blob_get_empty() || face == hb_face_get_empty()) {
+ lua_pushnil(L);
+ } else {
+ f = (Face *)lua_newuserdata(L, sizeof(*f));
+ *f = face;
+ luaL_getmetatable(L, "harfbuzz.Face");
+ lua_setmetatable(L, -2);
+ }
+ return 1;
+}
+
+static int face_get_glyph_count(lua_State *L) {
+ Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+
+ lua_pushinteger(L, hb_face_get_glyph_count(*f));
+ return 1;
+}
+
+static int face_get_name(lua_State *L) {
+ Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+ hb_ot_name_id_t name_id = (hb_ot_name_id_t) luaL_checkinteger(L, 2);
+ hb_language_t lang = HB_LANGUAGE_INVALID;
+ char name[STATIC_ARRAY_SIZE];
+ int text_size = STATIC_ARRAY_SIZE, len;
+
+ if (lua_gettop(L) > 2)
+ lang = *((Language*)luaL_checkudata(L, 3, "harfbuzz.Language"));
+
+ len = hb_ot_name_get_utf8(*f, name_id, lang, &text_size, name);
+ if (len) {
+ if (len < STATIC_ARRAY_SIZE) {
+ lua_pushstring(L, name);
+ } else {
+ char *name = malloc(len + 1);
+ text_size = len + 1;
+ hb_ot_name_get_utf8(*f, name_id, lang, &text_size, name);
+ lua_pushstring(L, name);
+ free(name);
+ }
+ } else {
+ lua_pushnil(L);
+ }
+
+ return 1;
+}
+
+static int face_get_table(lua_State *L) {
+ Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+ Tag *t = (Tag *)luaL_checkudata(L, 2, "harfbuzz.Tag");
+ Blob *b;
+
+ b = (Blob *)lua_newuserdata(L, sizeof(*b));
+ luaL_getmetatable(L, "harfbuzz.Blob");
+ lua_setmetatable(L, -2);
+
+ *b = hb_face_reference_table(*f, *t);
+
+ return 1;
+}
+
+static int face_get_table_tags(lua_State *L) {
+ Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+ hb_tag_t tags[STATIC_ARRAY_SIZE];
+ unsigned int count = hb_face_get_table_tags(*f, 0, NULL, NULL);
+
+ if (count) {
+ unsigned int i = 0, offset = 0;
+ lua_createtable(L, count, 0);
+ do {
+ count = STATIC_ARRAY_SIZE;
+ hb_face_get_table_tags(*f, offset, &count, tags);
+ for (i = 0; i < count; i++) {
+ lua_pushnumber(L, i + 1);
+
+ Tag *tp = (Tag *)lua_newuserdata(L, sizeof(*tp));
+ luaL_getmetatable(L, "harfbuzz.Tag");
+ lua_setmetatable(L, -2);
+ *tp = tags[i];
+
+ lua_rawset(L, -3);
+ }
+ offset += count;
+ } while (count == STATIC_ARRAY_SIZE);
+ } else {
+ lua_pushnil(L);
+ }
+
+ return 1;
+}
+
+static int face_ot_layout_get_script_tags(lua_State *L) {
+ Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+ Tag *table = (Tag *)luaL_checkudata(L, 2, "harfbuzz.Tag");
+
+ hb_tag_t tags[STATIC_ARRAY_SIZE];
+ unsigned int count = hb_ot_layout_table_get_script_tags(*face, *table, 0, NULL, NULL);
+
+ if (count) {
+ unsigned int i = 0, offset = 0;
+ lua_createtable(L, count, 0);
+ do {
+ count = STATIC_ARRAY_SIZE;
+ hb_ot_layout_table_get_script_tags(*face, *table, offset, &count, tags);
+ for (i = 0; i < count; i++) {
+ lua_pushnumber(L, i + 1);
+
+ Tag *tp = (Tag *)lua_newuserdata(L, sizeof(*tp));
+ luaL_getmetatable(L, "harfbuzz.Tag");
+ lua_setmetatable(L, -2);
+ *tp = tags[i];
+
+ lua_rawset(L, -3);
+ }
+ offset += count;
+ } while (count == STATIC_ARRAY_SIZE);
+ } else {
+ lua_pushnil(L);
+ }
+
+ return 1;
+}
+
+static int face_ot_layout_get_language_tags(lua_State *L) {
+ Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+ Tag *table = (Tag *)luaL_checkudata(L, 2, "harfbuzz.Tag");
+ unsigned int script_index = (unsigned int) luaL_checkinteger(L, 3);
+
+ hb_tag_t tags[STATIC_ARRAY_SIZE];
+ unsigned int count = hb_ot_layout_script_get_language_tags(*face, *table, script_index, 0, NULL, NULL);
+
+ if (count) {
+ unsigned int i = 0, offset = 0;
+ lua_createtable(L, count, 0);
+ do {
+ count = STATIC_ARRAY_SIZE;
+ hb_ot_layout_script_get_language_tags(*face, *table, script_index, offset, &count, tags);
+ for (i = 0; i < count; i++) {
+ lua_pushnumber(L, i + 1);
+
+ Tag *tp = (Tag *)lua_newuserdata(L, sizeof(*tp));
+ luaL_getmetatable(L, "harfbuzz.Tag");
+ lua_setmetatable(L, -2);
+ *tp = tags[i];
+
+ lua_rawset(L, -3);
+ }
+ offset += count;
+ } while (count == STATIC_ARRAY_SIZE);
+ } else {
+ lua_pushnil(L);
+ }
+
+ return 1;
+}
+
+static int face_ot_layout_get_feature_tags(lua_State *L) {
+ Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+ Tag *table = (Tag *)luaL_checkudata(L, 2, "harfbuzz.Tag");
+ unsigned int script_index = (unsigned int) luaL_checkinteger(L, 3);
+ unsigned int language_index = (unsigned int) luaL_checkinteger(L, 4);
+
+ hb_tag_t tags[STATIC_ARRAY_SIZE];
+ unsigned int count = hb_ot_layout_language_get_feature_tags(*face, *table, script_index, language_index, 0, NULL, NULL);
+
+ if (count) {
+ unsigned int i = 0, offset = 0;
+ lua_createtable(L, count, 0);
+ do {
+ count = STATIC_ARRAY_SIZE;
+ hb_ot_layout_language_get_feature_tags(*face, *table, script_index, language_index, offset, &count, tags);
+ for (i = 0; i < count; i++) {
+ lua_pushnumber(L, i + 1);
+
+ Tag *tp = (Tag *)lua_newuserdata(L, sizeof(*tp));
+ luaL_getmetatable(L, "harfbuzz.Tag");
+ lua_setmetatable(L, -2);
+ *tp = tags[i];
+
+ lua_rawset(L, -3);
+ }
+ offset += count;
+ } while (count == STATIC_ARRAY_SIZE);
+ } else {
+ lua_pushnil(L);
+ }
+
+ return 1;
+}
+
+static int face_ot_layout_find_script(lua_State *L) {
+ Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+ Tag *table = (Tag *)luaL_checkudata(L, 2, "harfbuzz.Tag");
+ Tag *script = (Tag *)luaL_checkudata(L, 3, "harfbuzz.Tag");
+ unsigned int index = 0;
+
+ int found = hb_ot_layout_table_find_script(*face, *table, *script, &index);
+ lua_pushboolean(L, found);
+ lua_pushinteger(L, index);
+ return 2;
+}
+
+static int face_ot_layout_find_language(lua_State *L) {
+ Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+ Tag *table = (Tag *)luaL_checkudata(L, 2, "harfbuzz.Tag");
+ unsigned int script_index = (unsigned int) luaL_checkinteger(L, 3);
+ Tag *language = (Tag *)luaL_checkudata(L, 4, "harfbuzz.Tag");
+ unsigned int index = 0;
+
+ int found = hb_ot_layout_script_find_language(*face, *table, script_index, *language, &index);
+ lua_pushboolean(L, found);
+ lua_pushinteger(L, index);
+ return 2;
+}
+
+static int face_ot_layout_find_feature(lua_State *L) {
+ Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+ Tag *table = (Tag *)luaL_checkudata(L, 2, "harfbuzz.Tag");
+ unsigned int script_index = (unsigned int) luaL_checkinteger(L, 3);
+ unsigned int language_index = (unsigned int) luaL_checkinteger(L, 4);
+ Tag *feature = (Tag *)luaL_checkudata(L, 5, "harfbuzz.Tag");
+ unsigned int index = 0;
+
+ int found = hb_ot_layout_language_find_feature(*face, *table, script_index, language_index, *feature, &index);
+ lua_pushboolean(L, found);
+ lua_pushinteger(L, index);
+ return 2;
+}
+
+static int face_collect_unicodes(lua_State *L) {
+ Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+ hb_set_t *codes = hb_set_create();
+
+ hb_face_collect_unicodes (*f, codes);
+ lua_createtable(L, hb_set_get_population(codes), 0);
+ if (!hb_set_is_empty(codes)) {
+ unsigned int i = 0;
+ hb_codepoint_t c = HB_SET_VALUE_INVALID;
+
+ while (hb_set_next(codes, &c)) {
+ lua_pushnumber(L, ++i);
+ lua_pushnumber(L, c);
+ lua_rawset(L, -3);
+ }
+ }
+
+ hb_set_destroy(codes);
+
+ return 1;
+}
+
+static int face_get_upem(lua_State *L) {
+ Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+
+ lua_pushinteger(L, hb_face_get_upem(*f));
+ return 1;
+}
+
+static int face_ot_color_has_palettes(lua_State *L) {
+ Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+
+ lua_pushboolean(L, hb_ot_color_has_palettes(*f));
+ return 1;
+}
+
+static int face_ot_color_palette_get_count(lua_State *L) {
+ Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+
+ lua_pushinteger(L, hb_ot_color_palette_get_count(*f));
+ return 1;
+}
+
+static int face_ot_color_palette_get_colors(lua_State *L) {
+ Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+ unsigned int index = (unsigned int) luaL_optinteger(L, 2, 1) - 1;
+
+ hb_color_t colors[STATIC_ARRAY_SIZE];
+ unsigned int count = hb_ot_color_palette_get_colors(*f, index, 0, NULL, NULL);
+
+ if (count) {
+ unsigned int i = 0, offset = 0;
+ lua_createtable(L, count, 0); // parent table
+ do {
+ count = STATIC_ARRAY_SIZE;
+ hb_ot_color_palette_get_colors(*f, index, offset, &count, colors);
+ for (i = 0; i < count; i++) {
+ hb_color_t color = colors[i];
+
+ lua_pushnumber(L, i+1); // 1-indexed key parent table
+ lua_createtable(L, 0, 4); // child table
+
+ lua_pushinteger(L, hb_color_get_red(color));
+ lua_setfield(L, -2, "red");
+
+ lua_pushinteger(L, hb_color_get_green(color));
+ lua_setfield(L, -2, "green");
+
+ lua_pushinteger(L, hb_color_get_blue(color));
+ lua_setfield(L, -2, "blue");
+
+ lua_pushinteger(L, hb_color_get_alpha(color));
+ lua_setfield(L, -2, "alpha");
+
+ lua_settable(L, -3); // Add child table at index i+1 to parent table
+ }
+ offset += count;
+ } while (count == STATIC_ARRAY_SIZE);
+ } else {
+ lua_pushnil(L);
+ }
+
+ return 1;
+}
+
+static int face_ot_color_has_layers(lua_State *L) {
+ Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+
+ lua_pushboolean(L, hb_ot_color_has_layers(*f));
+ return 1;
+}
+
+static int face_ot_color_glyph_get_layers(lua_State *L) {
+ Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+ hb_codepoint_t gid = (hb_codepoint_t) luaL_checkinteger(L, 2);
+ hb_ot_color_layer_t layers[STATIC_ARRAY_SIZE];
+ unsigned int count = hb_ot_color_glyph_get_layers(*f, gid, 0, NULL, NULL);
+
+ if (count) {
+ unsigned int i = 0, offset = 0;
+ lua_createtable(L, count, 0); // parent table
+ do {
+ count = STATIC_ARRAY_SIZE;
+ hb_ot_color_glyph_get_layers(*f, gid, offset, &count, layers);
+ for (i = 0; i < count; i++) {
+ hb_ot_color_layer_t layer = layers[i];
+ unsigned int color_index = layer.color_index;
+ if (color_index != 0xFFFF)
+ color_index++; // make it 1-indexed
+
+ lua_pushnumber(L, i+1); // 1-indexed key parent table
+ lua_createtable(L, 0, 2); // child table
+
+ lua_pushinteger(L, layer.glyph);
+ lua_setfield(L, -2, "glyph");
+
+ lua_pushinteger(L, color_index);
+ lua_setfield(L, -2, "color_index");
+
+ lua_settable(L, -3); // Add child table at index i+1 to parent table
+ }
+ offset += count;
+ } while (count == STATIC_ARRAY_SIZE);
+ } else {
+ lua_pushnil(L);
+ }
+
+ return 1;
+}
+
+static int face_ot_color_has_png(lua_State *L) {
+ Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+
+ lua_pushboolean(L, hb_ot_color_has_png(*f));
+ return 1;
+}
+
+static int face_destroy(lua_State *L) {
+ Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+
+ hb_face_destroy(*f);
+ return 0;
+}
+
+static const struct luaL_Reg face_methods[] = {
+ { "__gc", face_destroy },
+ { "collect_unicodes", face_collect_unicodes },
+ { "get_glyph_count", face_get_glyph_count },
+ { "get_name", face_get_name },
+ { "get_table", face_get_table },
+ { "get_table_tags", face_get_table_tags },
+ { "get_upem", face_get_upem },
+ { "ot_color_has_palettes", face_ot_color_has_palettes },
+ { "ot_color_palette_get_count", face_ot_color_palette_get_count },
+ { "ot_color_palette_get_colors", face_ot_color_palette_get_colors },
+ { "ot_color_has_layers", face_ot_color_has_layers },
+ { "ot_color_glyph_get_layers", face_ot_color_glyph_get_layers },
+ { "ot_color_has_png", face_ot_color_has_png },
+ { "ot_layout_get_script_tags", face_ot_layout_get_script_tags },
+ { "ot_layout_get_language_tags", face_ot_layout_get_language_tags },
+ { "ot_layout_get_feature_tags", face_ot_layout_get_feature_tags },
+ { "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 },
+ { NULL, NULL }
+};
+
+static const struct luaL_Reg face_functions[] = {
+ { "new", face_new },
+ { "new_from_blob", face_new_from_blob },
+ { NULL, NULL }
+};
+
+int register_face(lua_State *L) {
+ return register_class(L, "harfbuzz.Face", face_methods, face_functions, NULL);
+}
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/feature.c b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/feature.c
new file mode 100644
index 00000000000..1a3cf0a7815
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/feature.c
@@ -0,0 +1,41 @@
+// harfbuzz.Feature
+#include "luaharfbuzz.h"
+
+static int feature_new(lua_State *L) {
+ Feature f;
+ const char *feature = luaL_checkstring(L, 1);
+
+ if (hb_feature_from_string(feature, -1, &f)) {
+ Feature *fp = (Feature *)lua_newuserdata(L, sizeof(*fp));
+ luaL_getmetatable(L, "harfbuzz.Feature");
+ lua_setmetatable(L, -2);
+ *fp = f;
+ } else {
+ lua_pushnil(L);
+ }
+
+ return 1;
+}
+
+static int feature_to_string(lua_State *L) {
+ Feature* f = (Feature *)luaL_checkudata(L, 1, "harfbuzz.Feature");
+ char feature[128];
+
+ hb_feature_to_string(f, feature, 128);
+ lua_pushstring(L, feature);
+ return 1;
+}
+
+static const struct luaL_Reg feature_methods[] = {
+ { "__tostring", feature_to_string },
+ { NULL, NULL },
+};
+
+static const struct luaL_Reg feature_functions[] = {
+ { "new", feature_new },
+ { NULL, NULL }
+};
+
+int register_feature(lua_State *L) {
+ return register_class(L, "harfbuzz.Feature", feature_methods, feature_functions, 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
new file mode 100644
index 00000000000..2c59ce55a67
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/font.c
@@ -0,0 +1,218 @@
+#include "luaharfbuzz.h"
+
+static int font_new(lua_State *L) {
+ Font *f;
+ Face *face = luaL_checkudata(L, 1, "harfbuzz.Face");
+
+ f = (Font *)lua_newuserdata(L, sizeof(*f));
+ luaL_getmetatable(L, "harfbuzz.Font");
+ lua_setmetatable(L, -2);
+
+ *f = hb_font_create(*face);
+
+ // Set default scale to be the face's upem value
+ unsigned int upem = hb_face_get_upem(*face);
+ hb_font_set_scale(*f, upem, upem);
+
+ // Set shaping functions to OpenType functions
+ hb_ot_font_set_funcs(*f);
+ return 1;
+}
+
+static int font_set_scale(lua_State *L) {
+ Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
+ int x_scale = luaL_checkinteger(L, 2);
+ int y_scale = luaL_checkinteger(L, 3);
+
+ hb_font_set_scale(*f, x_scale, y_scale);
+ return 0;
+}
+
+static int font_get_scale(lua_State *L) {
+ Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
+ int x_scale, y_scale;
+
+ hb_font_get_scale(*f, &x_scale, &y_scale);
+
+ lua_pushinteger(L, x_scale);
+ lua_pushinteger(L, y_scale);
+ return 2;
+}
+
+static int font_get_h_extents(lua_State *L) {
+ Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
+ hb_font_extents_t extents;
+
+ if (hb_font_get_h_extents(*f, &extents)) {
+ lua_createtable(L, 0, 3);
+
+ lua_pushnumber(L, extents.ascender);
+ lua_setfield(L, -2, "ascender");
+
+ lua_pushnumber(L, extents.descender);
+ lua_setfield(L, -2, "descender");
+
+ lua_pushnumber(L, extents.line_gap);
+ lua_setfield(L, -2, "line_gap");
+ } else {
+ lua_pushnil(L);
+ }
+
+ return 1;
+}
+
+static int font_get_v_extents(lua_State *L) {
+ Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
+ hb_font_extents_t extents;
+
+ if (hb_font_get_v_extents(*f, &extents)) {
+ lua_createtable(L, 0, 3);
+
+ lua_pushnumber(L, extents.ascender);
+ lua_setfield(L, -2, "ascender");
+
+ lua_pushnumber(L, extents.descender);
+ lua_setfield(L, -2, "descender");
+
+ lua_pushnumber(L, extents.line_gap);
+ lua_setfield(L, -2, "line_gap");
+ } else {
+ lua_pushnil(L);
+ }
+
+ return 1;
+}
+
+static int font_get_glyph_extents(lua_State *L) {
+ Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
+ hb_codepoint_t glyph = luaL_checkinteger(L, 2);
+ hb_glyph_extents_t extents;
+
+ if (hb_font_get_glyph_extents(*f, glyph, &extents)) {
+ lua_createtable(L, 0, 4);
+
+ lua_pushnumber(L, extents.x_bearing);
+ lua_setfield(L, -2, "x_bearing");
+
+ lua_pushnumber(L, extents.y_bearing);
+ lua_setfield(L, -2, "y_bearing");
+
+ lua_pushnumber(L, extents.width);
+ lua_setfield(L, -2, "width");
+
+ lua_pushnumber(L, extents.height);
+ lua_setfield(L, -2, "height");
+ } else {
+ lua_pushnil(L);
+ }
+
+ return 1;
+}
+
+static int font_get_glyph_name(lua_State *L) {
+ Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
+ hb_codepoint_t glyph = luaL_checkinteger(L, 2);
+
+#define NAME_LEN 128
+ char name[NAME_LEN];
+ if (hb_font_get_glyph_name(*f, glyph, name, NAME_LEN))
+ lua_pushstring(L, name);
+ else
+ lua_pushnil(L);
+#undef NAME_LEN
+
+ return 1;
+}
+
+static int font_get_glyph_from_name(lua_State *L) {
+ Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
+ const char *name = luaL_checkstring(L, 2);
+ hb_codepoint_t glyph;
+
+ if (hb_font_get_glyph_from_name(*f, name, -1, &glyph))
+ lua_pushinteger(L, glyph);
+ else
+ lua_pushnil(L);
+
+ return 1;
+}
+
+static int font_get_glyph_h_advance(lua_State *L) {
+ Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
+ hb_codepoint_t glyph = luaL_checkinteger(L, 2);
+
+ lua_pushinteger(L, hb_font_get_glyph_h_advance(*f, glyph));
+ return 1;
+}
+
+static int font_get_glyph_v_advance(lua_State *L) {
+ Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
+ hb_codepoint_t glyph = luaL_checkinteger(L, 2);
+
+ lua_pushinteger(L, hb_font_get_glyph_v_advance(*f, glyph));
+ return 1;
+}
+
+static int font_get_nominal_glyph(lua_State *L) {
+ Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
+ hb_codepoint_t uni = luaL_checkinteger(L, 2);
+ hb_codepoint_t glyph;
+
+ if (hb_font_get_nominal_glyph(*f, uni, &glyph))
+ lua_pushinteger(L, glyph);
+ else
+ lua_pushnil(L);
+
+ return 1;
+}
+
+
+static int font_destroy(lua_State *L) {
+ Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
+
+ hb_font_destroy(*f);
+ return 0;
+}
+
+static int font_ot_color_glyph_get_png(lua_State *L) {
+ Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
+ hb_codepoint_t gid = (hb_codepoint_t) luaL_checkinteger(L, 2);
+ hb_blob_t* blob = hb_ot_color_glyph_reference_png(*f, gid);
+
+ if (hb_blob_get_length(blob) != 0) {
+ Blob *b = (Blob *)lua_newuserdata(L, sizeof(*b));
+ luaL_getmetatable(L, "harfbuzz.Blob");
+ lua_setmetatable(L, -2);
+
+ *b = hb_ot_color_glyph_reference_png(*f, gid);
+ } else {
+ lua_pushnil(L);
+ }
+
+ return 1;
+}
+
+static const struct luaL_Reg font_methods[] = {
+ { "__gc", font_destroy },
+ { "set_scale", font_set_scale },
+ { "get_scale", font_get_scale },
+ { "get_h_extents", font_get_h_extents },
+ { "get_v_extents", font_get_v_extents },
+ { "get_glyph_extents", font_get_glyph_extents },
+ { "get_glyph_name", font_get_glyph_name },
+ { "get_glyph_from_name", font_get_glyph_from_name },
+ { "get_glyph_h_advance", font_get_glyph_h_advance },
+ { "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 },
+ { NULL, NULL }
+};
+
+static const struct luaL_Reg font_functions[] = {
+ { "new", font_new },
+ { NULL, NULL }
+};
+
+int register_font(lua_State *L) {
+ return register_class(L, "harfbuzz.Font", font_methods, font_functions, NULL);
+}
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/language.c b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/language.c
new file mode 100644
index 00000000000..9f397e5272a
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/language.c
@@ -0,0 +1,49 @@
+// harfbuzz.Feature
+#include "luaharfbuzz.h"
+
+static int language_new(lua_State *L) {
+ Language *l;
+
+ l = (Language *)lua_newuserdata(L, sizeof(*l));
+ luaL_getmetatable(L, "harfbuzz.Language");
+ lua_setmetatable(L, -2);
+
+ if (lua_gettop(L) == 1 || lua_isnil(L, -2))
+ *l = HB_LANGUAGE_INVALID;
+ else
+ *l = hb_language_from_string(luaL_checkstring(L, -2), -1);
+
+ return 1;
+}
+
+static int language_to_string(lua_State *L) {
+ Language* l = (Language *)luaL_checkudata(L, 1, "harfbuzz.Language");
+ const char *s = hb_language_to_string(*l);
+
+ lua_pushstring(L, s ? s : "");
+ return 1;
+}
+
+static int language_equals(lua_State *L) {
+ Language* lhs = (Language *)luaL_checkudata(L, 1, "harfbuzz.Language");
+ Language* rhs = (Language *)luaL_checkudata(L, 2, "harfbuzz.Language");
+
+ lua_pushboolean(L, *lhs == *rhs);
+
+ return 1;
+}
+
+static const struct luaL_Reg language_methods[] = {
+ { "__tostring", language_to_string },
+ { "__eq", language_equals },
+ { NULL, NULL }
+};
+
+static const struct luaL_Reg language_functions[] = {
+ { "new", language_new },
+ { NULL, NULL }
+};
+
+int register_language(lua_State *L) {
+ return register_class(L, "harfbuzz.Language", language_methods, language_functions, 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
new file mode 100644
index 00000000000..c41a46bb7e9
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.c
@@ -0,0 +1,119 @@
+#include "luaharfbuzz.h"
+
+int shape_full (lua_State *L) {
+ int i = 0;
+ Font *font = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
+ Buffer *buf = (Buffer *)luaL_checkudata(L, 2, "harfbuzz.Buffer");
+ luaL_checktype(L, 3, LUA_TTABLE);
+ luaL_checktype(L, 4, LUA_TTABLE);
+
+ unsigned int num_features = lua_rawlen(L, 3);
+ Feature *features = (Feature *) malloc (num_features * sizeof(hb_feature_t));
+
+ lua_pushnil(L);
+ while (lua_next(L, 3) != 0) {
+ Feature* f = (Feature *)luaL_checkudata(L, -1, "harfbuzz.Feature");
+ features[i++] = *f;
+ lua_pop(L, 1);
+ }
+
+ const char **shapers = NULL;
+ size_t num_shapers = lua_rawlen(L, 4);
+ if (num_shapers) {
+ i = 0;
+ shapers = (const char**) calloc (num_shapers + 1, sizeof(char*));
+ lua_pushnil(L);
+ while (lua_next(L, 4) != 0) {
+ shapers[i++] = luaL_checkstring(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+
+ // Shape text
+ lua_pushboolean(L, hb_shape_full(*font, *buf, features, num_features, shapers));
+
+ free(features);
+ free(shapers);
+
+ return 1;
+}
+
+int version (lua_State *L) {
+ lua_pushstring(L, hb_version_string());
+ return 1;
+}
+
+int list_shapers (lua_State *L) {
+ const char **shaper_list = hb_shape_list_shapers ();
+ int i = 0;
+
+ for (; *shaper_list; shaper_list++) {
+ i++;
+ lua_pushstring(L, *shaper_list);
+ }
+ return i;
+}
+
+static const struct luaL_Reg lib_table [] = {
+ {"shape_full", shape_full},
+ {"version", version},
+ {"shapers", list_shapers},
+ {NULL, NULL}
+};
+
+int luaopen_luaharfbuzz (lua_State *L) {
+ lua_newtable(L);
+
+ register_blob(L);
+ lua_setfield(L, -2, "Blob");
+
+ register_face(L);
+ lua_setfield(L, -2, "Face");
+
+ register_font(L);
+ lua_setfield(L, -2, "Font");
+
+ register_buffer(L);
+ lua_setfield(L, -2, "Buffer");
+
+ register_feature(L);
+ lua_setfield(L, -2, "Feature");
+
+ register_tag(L);
+ lua_setfield(L, -2, "Tag");
+
+ register_script(L);
+ lua_setfield(L, -2, "Script");
+
+ register_direction(L);
+ lua_setfield(L, -2, "Direction");
+
+ register_language(L);
+ lua_setfield(L, -2, "Language");
+
+ register_ot(L);
+ lua_setfield(L, -2, "ot");
+
+ register_unicode(L);
+ lua_setfield(L, -2, "unicode");
+
+#ifdef LuajitTeX
+ luaL_register(L,NULL, lib_table);
+ /**/
+ lua_pushvalue(L, -1);
+ lua_setglobal(L,"luaharfbuzz");
+ /**/
+ lua_getglobal(L, "package");
+ lua_getfield(L, -1, "loaded");
+ lua_remove(L, -2);
+ lua_pushvalue(L, -2);
+ lua_setfield(L, -2, "luaharfbuzz");
+ /**/
+#else
+ luaL_setfuncs(L, lib_table, 0);
+#endif
+
+
+ return 1;
+}
+
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.h b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.h
new file mode 100644
index 00000000000..3d9d2e01906
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.h
@@ -0,0 +1,39 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <hb.h>
+#include <hb-ot.h>
+#include <string.h>
+
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+typedef hb_blob_t* Blob;
+typedef hb_face_t* Face;
+typedef hb_font_t* Font;
+typedef hb_buffer_t* Buffer;
+typedef hb_feature_t Feature;
+typedef hb_tag_t Tag;
+typedef hb_script_t Script;
+typedef hb_direction_t Direction;
+typedef hb_language_t Language;
+
+typedef struct luahb_constant_t {
+ const char *name;
+ int value;
+} luahb_constant_t;
+
+// Functions to create classes and push them onto the stack
+int register_class(lua_State *L, const char *name, const luaL_Reg * methods, const luaL_Reg *functions, const luahb_constant_t* constants);
+int register_blob(lua_State *L);
+int register_face(lua_State *L);
+int register_font(lua_State *L);
+int register_buffer(lua_State *L);
+int register_feature(lua_State *L);
+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_ot(lua_State *L);
+int register_unicode(lua_State *L);
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/ot.c b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/ot.c
new file mode 100644
index 00000000000..01041cfc9a3
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/ot.c
@@ -0,0 +1,47 @@
+#include "luaharfbuzz.h"
+
+static const struct luahb_constant_t ot_constants[] = {
+ { "NAME_ID_COPYRIGHT", HB_OT_NAME_ID_COPYRIGHT },
+ { "NAME_ID_FONT_FAMILY", HB_OT_NAME_ID_FONT_FAMILY },
+ { "NAME_ID_FONT_SUBFAMILY", HB_OT_NAME_ID_FONT_SUBFAMILY },
+ { "NAME_ID_UNIQUE_ID", HB_OT_NAME_ID_UNIQUE_ID },
+ { "NAME_ID_FULL_NAME", HB_OT_NAME_ID_FULL_NAME },
+ { "NAME_ID_VERSION_STRING", HB_OT_NAME_ID_VERSION_STRING },
+ { "NAME_ID_POSTSCRIPT_NAME", HB_OT_NAME_ID_POSTSCRIPT_NAME },
+ { "NAME_ID_TRADEMARK", HB_OT_NAME_ID_TRADEMARK },
+ { "NAME_ID_MANUFACTURER", HB_OT_NAME_ID_MANUFACTURER },
+ { "NAME_ID_DESIGNER", HB_OT_NAME_ID_DESIGNER },
+ { "NAME_ID_DESCRIPTION", HB_OT_NAME_ID_DESCRIPTION },
+ { "NAME_ID_VENDOR_URL", HB_OT_NAME_ID_VENDOR_URL },
+ { "NAME_ID_DESIGNER_URL", HB_OT_NAME_ID_DESIGNER_URL },
+ { "NAME_ID_LICENSE", HB_OT_NAME_ID_LICENSE },
+ { "NAME_ID_LICENSE_URL", HB_OT_NAME_ID_LICENSE_URL },
+ { "NAME_ID_TYPOGRAPHIC_FAMILY", HB_OT_NAME_ID_TYPOGRAPHIC_FAMILY },
+ { "NAME_ID_TYPOGRAPHIC_SUBFAMILY", HB_OT_NAME_ID_TYPOGRAPHIC_SUBFAMILY },
+ { "NAME_ID_MAC_FULL_NAME", HB_OT_NAME_ID_MAC_FULL_NAME },
+ { "NAME_ID_SAMPLE_TEXT", HB_OT_NAME_ID_SAMPLE_TEXT },
+ { "NAME_ID_CID_FINDFONT_NAME", HB_OT_NAME_ID_CID_FINDFONT_NAME },
+ { "NAME_ID_WWS_FAMILY", HB_OT_NAME_ID_WWS_FAMILY },
+ { "NAME_ID_WWS_SUBFAMILY", HB_OT_NAME_ID_WWS_SUBFAMILY },
+ { "NAME_ID_LIGHT_BACKGROUND", HB_OT_NAME_ID_LIGHT_BACKGROUND },
+ { "NAME_ID_DARK_BACKGROUND", HB_OT_NAME_ID_DARK_BACKGROUND },
+ { "NAME_ID_VARIATIONS_PS_PREFIX", HB_OT_NAME_ID_VARIATIONS_PS_PREFIX },
+ { "NAME_ID_INVALID", HB_OT_NAME_ID_INVALID },
+ { "LAYOUT_NO_SCRIPT_INDEX", HB_OT_LAYOUT_NO_SCRIPT_INDEX },
+ { "LAYOUT_NO_FEATURE_INDEX", HB_OT_LAYOUT_NO_FEATURE_INDEX },
+ { "LAYOUT_DEFAULT_LANGUAGE_INDEX", HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX },
+ { "LAYOUT_NO_VARIATIONS_INDEX", HB_OT_LAYOUT_NO_VARIATIONS_INDEX },
+ { NULL, 0 }
+};
+
+static const struct luaL_Reg ot_methods[] = {
+ { NULL, NULL }
+};
+
+static const struct luaL_Reg ot_functions[] = {
+ { NULL, NULL }
+};
+
+int register_ot(lua_State *L) {
+ return register_class(L, "harfbuzz.ot", ot_methods, ot_functions, ot_constants);
+}
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/script.c b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/script.c
new file mode 100644
index 00000000000..133cc6a0ebb
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/script.c
@@ -0,0 +1,71 @@
+#include "luaharfbuzz.h"
+
+static int new_script_from_string(lua_State *L) {
+ Script *sp = (Script *)lua_newuserdata(L, sizeof(*sp));
+ luaL_getmetatable(L, "harfbuzz.Script");
+ lua_setmetatable(L, -2);
+
+ if (lua_gettop(L) == 1 || lua_isnil(L, -2))
+ *sp = HB_SCRIPT_INVALID;
+ else
+ *sp = hb_script_from_string(luaL_checkstring(L, -2), -1);
+
+ return 1;
+}
+
+static int new_script_from_tag(lua_State *L) {
+ Tag* tp = (Tag *)luaL_checkudata(L, 1, "harfbuzz.Tag");
+
+ Script *sp = (Script *)lua_newuserdata(L, sizeof(*sp));
+ luaL_getmetatable(L, "harfbuzz.Script");
+ lua_setmetatable(L, -2);
+
+ *sp = hb_script_from_iso15924_tag(*tp);
+ return 1;
+}
+
+static int script_to_string(lua_State *L) {
+ Script *script = (Script *)luaL_checkudata(L, 1, "harfbuzz.Script");
+ char s[5];
+
+ hb_tag_to_string(hb_script_to_iso15924_tag(*script), s);
+ s[4] = '\0';
+ lua_pushstring(L, s);
+ return 1;
+}
+
+static int script_to_tag(lua_State *L) {
+ Script *script = (Script *)luaL_checkudata(L, 1, "harfbuzz.Script");
+
+ Tag *tp = (Tag *)lua_newuserdata(L, sizeof(*tp));
+ luaL_getmetatable(L, "harfbuzz.Tag");
+ lua_setmetatable(L, -2);
+
+ *tp = hb_script_to_iso15924_tag(*script);
+ return 1;
+}
+
+static int script_equals(lua_State *L) {
+ Script* lhs = (Script *)luaL_checkudata(L, 1, "harfbuzz.Script");
+ Script* rhs = (Script *)luaL_checkudata(L, 2, "harfbuzz.Script");
+
+ lua_pushboolean(L, *lhs == *rhs);
+ return 1;
+}
+
+static const struct luaL_Reg script_methods[] = {
+ { "__tostring", script_to_string },
+ { "__eq", script_equals },
+ { "to_iso15924_tag", script_to_tag },
+ { NULL, NULL }
+};
+
+static const struct luaL_Reg script_functions[] = {
+ { "new", new_script_from_string },
+ { "from_iso15924_tag", new_script_from_tag },
+ { NULL, NULL }
+};
+
+int register_script(lua_State *L) {
+ return register_class(L, "harfbuzz.Script", script_methods, script_functions, NULL);
+}
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/tag.c b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/tag.c
new file mode 100644
index 00000000000..ec7e4b172e3
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/tag.c
@@ -0,0 +1,50 @@
+// harfbuzz.Feature
+#include "luaharfbuzz.h"
+
+static int tag_new(lua_State *L) {
+ Tag *t;
+
+ t = (Tag *)lua_newuserdata(L, sizeof(*t));
+ luaL_getmetatable(L, "harfbuzz.Tag");
+ lua_setmetatable(L, -2);
+
+ if (lua_gettop(L) == 1 || lua_isnil(L, -2))
+ *t = HB_TAG_NONE;
+ else
+ *t = hb_tag_from_string(luaL_checkstring(L, -2), -1);
+
+ return 1;
+}
+
+static int tag_to_string(lua_State *L) {
+ Tag* t = (Tag *)luaL_checkudata(L, 1, "harfbuzz.Tag");
+ char tag[5];
+
+ hb_tag_to_string(*t, tag);
+ tag[4] = '\0';
+ lua_pushstring(L, tag);
+ return 1;
+}
+
+static int tag_equals(lua_State *L) {
+ Tag* lhs = (Tag *)luaL_checkudata(L, 1, "harfbuzz.Tag");
+ Tag* rhs = (Tag *)luaL_checkudata(L, 2, "harfbuzz.Tag");
+
+ lua_pushboolean(L, *lhs == *rhs);
+ return 1;
+}
+
+static const struct luaL_Reg tag_methods[] = {
+ { "__tostring", tag_to_string },
+ { "__eq", tag_equals },
+ { NULL, NULL }
+};
+
+static const struct luaL_Reg tag_functions[] = {
+ { "new", tag_new },
+ { NULL, NULL }
+};
+
+int register_tag(lua_State *L) {
+ return register_class(L, "harfbuzz.Tag", tag_methods, tag_functions, NULL);
+}
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/unicode.c b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/unicode.c
new file mode 100644
index 00000000000..4e887fcd61d
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/unicode.c
@@ -0,0 +1,22 @@
+#include "luaharfbuzz.h"
+
+static int script(lua_State *L) {
+ hb_codepoint_t c = (hb_codepoint_t) luaL_checkinteger(L, -1);
+
+ Script *sp = (Script *)lua_newuserdata(L, sizeof(*sp));
+ luaL_getmetatable(L, "harfbuzz.Script");
+ lua_setmetatable(L, -2);
+
+ *sp = hb_unicode_script(hb_unicode_funcs_get_default(), c);
+ return 1;
+}
+
+static const struct luaL_Reg unicode_functions[] = {
+ { "script", script },
+ { NULL, NULL }
+};
+
+int register_unicode(lua_State *L) {
+ luaL_newlib(L, unicode_functions);
+ return 1;
+}
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/status/done.txt b/Build/source/texk/web2c/luatexdir/luaharfbuzz/status/done.txt
new file mode 100644
index 00000000000..fff80d672fd
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/status/done.txt
@@ -0,0 +1,42 @@
+hb_blob_create
+hb_blob_destroy
+hb_blob_get_length
+hb_buffer_add_codepoints
+hb_buffer_add_utf8
+hb_buffer_create
+hb_buffer_destroy
+hb_buffer_get_cluster_level
+hb_buffer_get_direction
+hb_buffer_get_language
+hb_buffer_get_length
+hb_buffer_get_script
+hb_buffer_guess_segment_properties
+hb_buffer_reverse
+hb_buffer_set_cluster_level
+hb_buffer_set_direction
+hb_buffer_set_language
+hb_buffer_set_script
+hb_direction_from_string
+hb_direction_to_string
+hb_face_create
+hb_face_destroy
+hb_face_get_upem
+hb_feature_from_string
+hb_feature_to_string
+hb_font_create
+hb_font_destroy
+hb_font_get_scale
+hb_font_set_scale
+hb_language_from_string
+hb_language_to_string
+hb_script_from_iso15924_tag
+hb_script_from_string
+hb_script_to_iso15924_tag
+hb_shape
+hb_shape_full
+hb_shape_list_shapers
+hb_tag_from_string
+hb_tag_to_string
+hb_unicode_script
+hb_version
+
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/status/full_api.txt b/Build/source/texk/web2c/luatexdir/luaharfbuzz/status/full_api.txt
new file mode 100644
index 00000000000..d68c9b0f239
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/status/full_api.txt
@@ -0,0 +1,303 @@
+hb_blob_create
+hb_blob_create_sub_blob
+hb_blob_destroy
+hb_blob_get_data
+hb_blob_get_data_writable
+hb_blob_get_empty
+hb_blob_get_length
+hb_blob_get_user_data
+hb_blob_is_immutable
+hb_blob_make_immutable
+hb_blob_reference
+hb_blob_set_user_data
+hb_buffer_add
+hb_buffer_add_codepoints
+hb_buffer_add_latin1
+hb_buffer_add_utf16
+hb_buffer_add_utf32
+hb_buffer_add_utf8
+hb_buffer_allocation_successful
+hb_buffer_clear_contents
+hb_buffer_create
+hb_buffer_deserialize_glyphs
+hb_buffer_destroy
+hb_buffer_get_cluster_level
+hb_buffer_get_content_type
+hb_buffer_get_direction
+hb_buffer_get_empty
+hb_buffer_get_flags
+hb_buffer_get_glyph_infos
+hb_buffer_get_glyph_positions
+hb_buffer_get_language
+hb_buffer_get_length
+hb_buffer_get_replacement_codepoint
+hb_buffer_get_script
+hb_buffer_get_segment_properties
+hb_buffer_get_unicode_funcs
+hb_buffer_get_user_data
+hb_buffer_guess_segment_properties
+hb_buffer_normalize_glyphs
+hb_buffer_pre_allocate
+hb_buffer_reference
+hb_buffer_reset
+hb_buffer_reverse
+hb_buffer_reverse_clusters
+hb_buffer_reverse_range
+hb_buffer_serialize_format_from_string
+hb_buffer_serialize_format_to_string
+hb_buffer_serialize_glyphs
+hb_buffer_serialize_list_formats
+hb_buffer_set_cluster_level
+hb_buffer_set_content_type
+hb_buffer_set_direction
+hb_buffer_set_flags
+hb_buffer_set_language
+hb_buffer_set_length
+hb_buffer_set_message_func
+hb_buffer_set_replacement_codepoint
+hb_buffer_set_script
+hb_buffer_set_segment_properties
+hb_buffer_set_unicode_funcs
+hb_buffer_set_user_data
+hb_coretext_face_create
+hb_coretext_face_get_cg_font
+hb_coretext_font_get_ct_font
+hb_direction_from_string
+hb_direction_to_string
+hb_face_create
+hb_face_create_for_tables
+hb_face_destroy
+hb_face_get_empty
+hb_face_get_glyph_count
+hb_face_get_index
+hb_face_get_upem
+hb_face_get_user_data
+hb_face_is_immutable
+hb_face_make_immutable
+hb_face_reference
+hb_face_reference_blob
+hb_face_reference_table
+hb_face_set_glyph_count
+hb_face_set_index
+hb_face_set_upem
+hb_face_set_user_data
+hb_feature_from_string
+hb_feature_to_string
+hb_font_add_glyph_origin_for_direction
+hb_font_create
+hb_font_create_sub_font
+hb_font_destroy
+hb_font_funcs_create
+hb_font_funcs_destroy
+hb_font_funcs_get_empty
+hb_font_funcs_get_user_data
+hb_font_funcs_is_immutable
+hb_font_funcs_make_immutable
+hb_font_funcs_reference
+hb_font_funcs_set_font_h_extents_func
+hb_font_funcs_set_font_v_extents_func
+hb_font_funcs_set_glyph_contour_point_func
+hb_font_funcs_set_glyph_extents_func
+hb_font_funcs_set_glyph_from_name_func
+hb_font_funcs_set_glyph_func
+hb_font_funcs_set_glyph_h_advance_func
+hb_font_funcs_set_glyph_h_kerning_func
+hb_font_funcs_set_glyph_h_origin_func
+hb_font_funcs_set_glyph_name_func
+hb_font_funcs_set_glyph_v_advance_func
+hb_font_funcs_set_glyph_v_kerning_func
+hb_font_funcs_set_glyph_v_origin_func
+hb_font_funcs_set_nominal_glyph_func
+hb_font_funcs_set_user_data
+hb_font_funcs_set_variation_glyph_func
+hb_font_get_empty
+hb_font_get_extents_for_direction
+hb_font_get_face
+hb_font_get_glyph
+hb_font_get_glyph_advance_for_direction
+hb_font_get_glyph_contour_point
+hb_font_get_glyph_contour_point_for_origin
+hb_font_get_glyph_extents
+hb_font_get_glyph_extents_for_origin
+hb_font_get_glyph_from_name
+hb_font_get_glyph_h_advance
+hb_font_get_glyph_h_kerning
+hb_font_get_glyph_h_origin
+hb_font_get_glyph_kerning_for_direction
+hb_font_get_glyph_name
+hb_font_get_glyph_origin_for_direction
+hb_font_get_glyph_v_advance
+hb_font_get_glyph_v_kerning
+hb_font_get_glyph_v_origin
+hb_font_get_h_extents
+hb_font_get_nominal_glyph
+hb_font_get_parent
+hb_font_get_ppem
+hb_font_get_scale
+hb_font_get_user_data
+hb_font_get_v_extents
+hb_font_get_var_coords_normalized
+hb_font_get_variation_glyph
+hb_font_glyph_from_string
+hb_font_glyph_to_string
+hb_font_is_immutable
+hb_font_make_immutable
+hb_font_reference
+hb_font_set_face
+hb_font_set_funcs
+hb_font_set_funcs_data
+hb_font_set_parent
+hb_font_set_ppem
+hb_font_set_scale
+hb_font_set_user_data
+hb_font_set_var_coords_design
+hb_font_set_var_coords_normalized
+hb_font_set_variations
+hb_font_subtract_glyph_origin_for_direction
+hb_ft_face_create
+hb_ft_face_create_cached
+hb_ft_face_create_referenced
+hb_ft_font_create
+hb_ft_font_create_referenced
+hb_ft_font_get_face
+hb_ft_font_get_load_flags
+hb_ft_font_set_funcs
+hb_ft_font_set_load_flags
+hb_glib_blob_create
+hb_glib_get_unicode_funcs
+hb_glib_script_from_script
+hb_glib_script_to_script
+hb_icu_get_unicode_funcs
+hb_icu_script_from_script
+hb_icu_script_to_script
+hb_language_from_string
+hb_language_get_default
+hb_language_to_string
+hb_ot_font_set_funcs
+hb_ot_layout_collect_lookups
+hb_ot_layout_feature_get_lookups
+hb_ot_layout_feature_with_variations_get_lookups
+hb_ot_layout_get_attach_points
+hb_ot_layout_get_glyph_class
+hb_ot_layout_get_glyphs_in_class
+hb_ot_layout_get_ligature_carets
+hb_ot_layout_get_size_params
+hb_ot_layout_has_glyph_classes
+hb_ot_layout_has_positioning
+hb_ot_layout_has_substitution
+hb_ot_layout_language_find_feature
+hb_ot_layout_language_get_feature_indexes
+hb_ot_layout_language_get_feature_tags
+hb_ot_layout_language_get_required_feature
+hb_ot_layout_language_get_required_feature_index
+hb_ot_layout_lookup_collect_glyphs
+hb_ot_layout_lookup_substitute_closure
+hb_ot_layout_lookup_would_substitute
+hb_ot_layout_script_find_language
+hb_ot_layout_script_get_language_tags
+hb_ot_layout_table_choose_script
+hb_ot_layout_table_find_feature_variations
+hb_ot_layout_table_find_script
+hb_ot_layout_table_get_feature_tags
+hb_ot_layout_table_get_lookup_count
+hb_ot_layout_table_get_script_tags
+hb_ot_math_get_constant
+hb_ot_math_get_glyph_assembly
+hb_ot_math_get_glyph_italics_correction
+hb_ot_math_get_glyph_kerning
+hb_ot_math_get_glyph_top_accent_attachment
+hb_ot_math_get_glyph_variants
+hb_ot_math_get_min_connector_overlap
+hb_ot_math_has_data
+hb_ot_math_is_glyph_extended_shape
+hb_ot_shape_glyphs_closure
+hb_ot_shape_plan_collect_lookups
+hb_ot_tag_from_language
+hb_ot_tag_to_language
+hb_ot_tag_to_script
+hb_ot_tags_from_script
+hb_ot_var_find_axis
+hb_ot_var_get_axes
+hb_ot_var_get_axis_count
+hb_ot_var_has_data
+hb_ot_var_normalize_coords
+hb_ot_var_normalize_variations
+hb_script_from_iso15924_tag
+hb_script_from_string
+hb_script_get_horizontal_direction
+hb_script_to_iso15924_tag
+hb_segment_properties_equal
+hb_segment_properties_hash
+hb_set_add
+hb_set_add_range
+hb_set_allocation_successful
+hb_set_clear
+hb_set_create
+hb_set_del
+hb_set_del_range
+hb_set_destroy
+hb_set_get_empty
+hb_set_get_max
+hb_set_get_min
+hb_set_get_population
+hb_set_get_user_data
+hb_set_has
+hb_set_intersect
+hb_set_invert
+hb_set_is_empty
+hb_set_is_equal
+hb_set_next
+hb_set_next_range
+hb_set_reference
+hb_set_set
+hb_set_set_user_data
+hb_set_subtract
+hb_set_symmetric_difference
+hb_set_union
+hb_shape
+hb_shape_full
+hb_shape_list_shapers
+hb_shape_plan_create
+hb_shape_plan_create2
+hb_shape_plan_create_cached
+hb_shape_plan_create_cached2
+hb_shape_plan_destroy
+hb_shape_plan_execute
+hb_shape_plan_get_empty
+hb_shape_plan_get_shaper
+hb_shape_plan_get_user_data
+hb_shape_plan_reference
+hb_shape_plan_set_user_data
+hb_tag_from_string
+hb_tag_to_string
+hb_unicode_combining_class
+hb_unicode_compose
+hb_unicode_decompose
+hb_unicode_decompose_compatibility
+hb_unicode_eastasian_width
+hb_unicode_funcs_create
+hb_unicode_funcs_destroy
+hb_unicode_funcs_get_default
+hb_unicode_funcs_get_empty
+hb_unicode_funcs_get_parent
+hb_unicode_funcs_get_user_data
+hb_unicode_funcs_is_immutable
+hb_unicode_funcs_make_immutable
+hb_unicode_funcs_reference
+hb_unicode_funcs_set_combining_class_func
+hb_unicode_funcs_set_compose_func
+hb_unicode_funcs_set_decompose_compatibility_func
+hb_unicode_funcs_set_decompose_func
+hb_unicode_funcs_set_eastasian_width_func
+hb_unicode_funcs_set_general_category_func
+hb_unicode_funcs_set_mirroring_func
+hb_unicode_funcs_set_script_func
+hb_unicode_funcs_set_user_data
+hb_unicode_general_category
+hb_unicode_mirroring
+hb_unicode_script
+hb_variation_from_string
+hb_variation_to_string
+hb_version
+hb_version_atleast
+hb_version_string
diff --git a/Build/source/texk/web2c/luatexdir/luatex.c b/Build/source/texk/web2c/luatexdir/luatex.c
index 98bfd7f891f..61b8b95e171 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 = 110;
-int luatex_revision = '0';
-const char *luatex_version_string = "1.10.0";
+int luatex_version = 111;
+int luatex_revision = '1';
+const char *luatex_version_string = "1.11.1";
const char *engine_name = my_name;
#include <kpathsea/c-ctype.h>
diff --git a/Build/source/texk/web2c/luatexdir/luatex_svnversion.h b/Build/source/texk/web2c/luatexdir/luatex_svnversion.h
index 75bbf0254f9..2cf5e812739 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 7127
+#define luatex_svn_revision 7172
diff --git a/Build/source/texk/web2c/luatexdir/tex/align.c b/Build/source/texk/web2c/luatexdir/tex/align.c
index b2384cc6290..bb721856fac 100644
--- a/Build/source/texk/web2c/luatexdir/tex/align.c
+++ b/Build/source/texk/web2c/luatexdir/tex/align.c
@@ -1095,7 +1095,9 @@ void fin_align(void)
glue_set(q) = glue_set(p);
shift_amount(q) = o;
r = vlink(list_ptr(q));
- assert (type(r) == unset_node);
+ if (type(r) != unset_node) {
+ formatted_error("alignment","bad box");
+ }
s = vlink(list_ptr(p));
do {
/*tex
diff --git a/Build/source/texk/web2c/luatexdir/tex/postlinebreak.h b/Build/source/texk/web2c/luatexdir/tex/postlinebreak.h
index cd90e1f0bc5..4aee1492c71 100644
--- a/Build/source/texk/web2c/luatexdir/tex/postlinebreak.h
+++ b/Build/source/texk/web2c/luatexdir/tex/postlinebreak.h
@@ -1,5 +1,5 @@
/* postlinebreak.h
-
+
Copyright 2009 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -21,13 +21,10 @@
#ifndef POSTLINEBREAK_H
# define POSTLINEBREAK_H
-/* todo: check this macro, especially values of alink() */
-
-# define append_list(A,B) do { \
- vlink(cur_list.tail_field) = vlink((A)); \
- cur_list.tail_field = (B); \
- } while (0)
-
+# define append_list(A,B) do { \
+ couple_nodes(cur_list.tail_field,vlink((A))); \
+ cur_list.tail_field = (B); \
+} while (0)
void ext_post_line_break(int paragraph_dir,
int right_skip,
diff --git a/Build/source/texk/web2c/luatexdir/tex/texdeffont.c b/Build/source/texk/web2c/luatexdir/tex/texdeffont.c
index f0b057d40b1..1ec4b12bf06 100644
--- a/Build/source/texk/web2c/luatexdir/tex/texdeffont.c
+++ b/Build/source/texk/web2c/luatexdir/tex/texdeffont.c
@@ -99,7 +99,7 @@ void tex_def_font(small_number a)
/*tex This runs through existing fonts. */
internal_font_number f;
/*tex The name for the frozen font identifier. */
- str_number t;
+ str_number t, d;
/*tex Thos holds the |selector| setting. */
int old_setting;
/*tex Stated `at' size, or negative of scaled magnification. */
@@ -113,10 +113,6 @@ void tex_def_font(small_number a)
}
get_r_token();
u = cur_cs;
- if (u >= null_cs)
- t = cs_text(u);
- else
- t = maketexstring("FONT");
if (a >= 4) {
geq_define(u, set_font_cmd, null_font);
} else {
@@ -140,17 +136,20 @@ void tex_def_font(small_number a)
selector = new_string;
if (cur_area != get_nullstr()) {
print(cur_area);
+ flush_str(cur_area);
}
if (cur_name != get_nullstr()) {
print(cur_name);
+ flush_str(cur_name);
}
if (cur_ext != get_nullstr()) {
print(cur_ext);
+ flush_str(cur_ext);
}
selector = old_setting;
+ cur_area = get_nullstr();
cur_name = make_string();
cur_ext = get_nullstr();
- cur_area = get_nullstr();
}
} else {
back_input();
@@ -160,9 +159,9 @@ void tex_def_font(small_number a)
token_show(def_ref);
selector = old_setting;
flush_list(def_ref);
+ cur_area = get_nullstr();
cur_name = make_string();
cur_ext = get_nullstr();
- cur_area = get_nullstr();
}
/*tex
Scan the font size specification. The next variable keeps |cur_name| from
@@ -215,5 +214,34 @@ void tex_def_font(small_number a)
xfree(fn);
equiv(u) = f;
eqtb[font_id_base + f] = eqtb[u];
- cs_text(font_id_base + f) = t;
+ /*tex
+
+ This is tricky: when we redefine a string we loose the old one. So this
+ will change as it's only used to display the |\fontname| so we can store
+ that with the font.
+
+ */
+ d = cs_text(font_id_base + f);
+ t = (u >= null_cs) ? cs_text(u) : maketexstring("FONT");
+ if (!d) {
+ /*tex We have a new string. */
+ cs_text(font_id_base + f) = t;
+ } else if ((d!=t) && str_eq_str(d,t)){
+ /*tex We have a duplicate string. */
+ flush_str(t);
+ } else if (d!=t){
+ d = search_string(t);
+ if (d) {
+ /*tex We have already such a string. */
+ cs_text(font_id_base + f) = d;
+ flush_str(t);
+ } else {
+ /*tex The old value is lost but still in the pool. */
+ cs_text(font_id_base + f) = t;
+ }
+ }
+ if (cur_name == str_ptr-1) {
+ flush_str(cur_name);
+ cur_name = get_nullstr();
+ }
}
diff --git a/Build/source/texk/web2c/luatexdir/tex/texfileio.c b/Build/source/texk/web2c/luatexdir/tex/texfileio.c
index 143e694e1ba..2c37ada75e9 100644
--- a/Build/source/texk/web2c/luatexdir/tex/texfileio.c
+++ b/Build/source/texk/web2c/luatexdir/tex/texfileio.c
@@ -332,14 +332,13 @@ boolean lua_a_open_in(alpha_file * f, char *fn, int n)
boolean lua_a_open_out(alpha_file * f, char *fn, int n)
{
boolean test;
- str_number fnam;
+ char *fnam = NULL;
int callback_id;
boolean ret = false;
callback_id = callback_defined(find_write_file_callback);
if (callback_id > 0) {
- fnam = 0;
- test = run_callback(callback_id, "dS->s", n, fn, &fnam);
- if ((test) && (fnam != 0) && (str_length(fnam) > 0)) {
+ test = run_callback(callback_id, "dS->R", n, fn, &fnam);
+ if ((test) && (fnam != NULL) && (strlen(fnam) > 0)) {
/*tex
There is no message here because if that is needed the macro
@@ -347,7 +346,8 @@ boolean lua_a_open_out(alpha_file * f, char *fn, int n)
messaging is left to \LUA\ then.
*/
- ret = open_outfile(f, fn, FOPEN_W_MODE);
+ ret = open_outfile(f, fnam, FOPEN_W_MODE);
+ free(fnam);
}
} else {
if (openoutnameok(fn)) {
@@ -371,15 +371,15 @@ boolean lua_a_open_out(alpha_file * f, char *fn, int n)
boolean lua_b_open_out(alpha_file * f, char *fn)
{
boolean test;
- str_number fnam;
+ char *fnam = NULL;
int callback_id;
boolean ret = false;
callback_id = callback_defined(find_output_file_callback);
if (callback_id > 0) {
- fnam = 0;
- test = run_callback(callback_id, "S->s", fn, &fnam);
- if ((test) && (fnam != 0) && (str_length(fnam) > 0)) {
- ret = open_outfile(f, fn, FOPEN_WBIN_MODE);
+ test = run_callback(callback_id, "S->R", fn, &fnam);
+ if ((test) && (fnam != NULL) && (strlen(fnam) > 0)) {
+ ret = open_outfile(f, fnam, FOPEN_WBIN_MODE);
+ free(fnam);
}
} else {
if (openoutnameok(fn)) {
@@ -937,7 +937,7 @@ void open_log_file(void)
/*tex should be done always */
flush_loggable_info();
/*tex should be done always */
- selector = old_setting + 2;
+ selector = old_setting + 2;
}
/*tex
diff --git a/Build/source/texk/web2c/luatexdir/tex/texmath.c b/Build/source/texk/web2c/luatexdir/tex/texmath.c
index 69e58b0ea77..7f1f1296d33 100644
--- a/Build/source/texk/web2c/luatexdir/tex/texmath.c
+++ b/Build/source/texk/web2c/luatexdir/tex/texmath.c
@@ -720,7 +720,9 @@ void display_normal_noad(pointer p)
}
break;
case radical_noad:
- if (subtype(p) == 6)
+ if (subtype(p) == 7)
+ tprint_esc("Uhextensible");
+ else if (subtype(p) == 6)
tprint_esc("Udelimiterover");
else if (subtype(p) == 5)
tprint_esc("Udelimiterunder");
@@ -2618,7 +2620,8 @@ void after_math(void)
tail_append(new_dir(math_direction_par));
}
run_mlist_to_hlist(p, (mode > 0), text_style);
- vlink(tail) = vlink(temp_head);
+ try_couple_nodes(tail,vlink(temp_head));
+
while (vlink(tail) != null) {
tail = vlink(tail);
}
diff --git a/Build/source/texk/web2c/luatexdir/utils/utils.c b/Build/source/texk/web2c/luatexdir/utils/utils.c
index 230a3aaa9c5..b09371bebf2 100644
--- a/Build/source/texk/web2c/luatexdir/utils/utils.c
+++ b/Build/source/texk/web2c/luatexdir/utils/utils.c
@@ -46,6 +46,11 @@ LuaTeX; if not, see <http://www.gnu.org/licenses/>.
#include "png.h"
#include "mplib.h"
+#ifdef LUATEX_HARFBUZZ_ENABLED
+#include "hb.h"
+#endif
+
+
#define check_nprintf(size_get, size_want) \
if ((unsigned)(size_get) >= (unsigned)(size_want)) \
@@ -261,12 +266,18 @@ void initversionstring(char **versions)
#define STR2(tok) #tok
const_string fmt =
+#ifdef LUATEX_HARFBUZZ_ENABLED
+ "Compiled with libharfbuzz %s; using %s\n"
+#endif
"Compiled with libpng %s; using %s\n"
"Compiled with %s\n" /* Lua or LuaJIT */
"Compiled with mplib version %s\n"
"Compiled with zlib %s; using %s\n"
"\nDevelopment id: %s\n";
size_t len = strlen(fmt)
+#ifdef LUATEX_HARFBUZZ_ENABLED
+ + strlen(HB_VERSION_STRING) + strlen(hb_version_string())
+#endif
+ strlen(PNG_LIBPNG_VER_STRING) + strlen(png_libpng_ver)
+ strlen(LUA_VER_STRING)
+ strlen(mp_metapost_version())
@@ -280,6 +291,9 @@ void initversionstring(char **versions)
*/
*versions = xmalloc(len);
sprintf(*versions, fmt,
+#ifdef LUATEX_HARFBUZZ_ENABLED
+ HB_VERSION_STRING,hb_version_string(),
+#endif
PNG_LIBPNG_VER_STRING, png_libpng_ver, LUA_VER_STRING,
mp_metapost_version(),
ZLIB_VERSION, zlib_version,STR(luatex_svn_revision));