From 8591b56496b93eed20f638ee1ce46b11c3f7be58 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Sun, 17 Jan 2021 03:02:33 +0000 Subject: CTAN sync 202101170302 --- FILES.byname | 507 +- FILES.byname.gz | Bin 2263809 -> 2264343 bytes FILES.last07days | 1168 +- fonts/alfaslabone/README | 26 + fonts/alfaslabone/doc/LICENSE.TXT | 93 + fonts/alfaslabone/doc/alfaslabone-samples.pdf | Bin 0 -> 25187 bytes fonts/alfaslabone/doc/alfaslabone-samples.tex | 25 + fonts/alfaslabone/enc/a_5xld5w.enc | 63 + fonts/alfaslabone/enc/a_adz5lu.enc | 65 + fonts/alfaslabone/enc/a_d2anrk.enc | 65 + fonts/alfaslabone/enc/a_lzhlbi.enc | 63 + fonts/alfaslabone/enc/a_rymxky.enc | 65 + fonts/alfaslabone/enc/a_taosrr.enc | 63 + fonts/alfaslabone/enc/a_vqpkf5.enc | 63 + fonts/alfaslabone/latex/LY1AlphaSlabOne-Sup.fd | 36 + fonts/alfaslabone/latex/LY1AlphaSlabOne-TLF.fd | 36 + fonts/alfaslabone/latex/OT1AlphaSlabOne-Sup.fd | 36 + fonts/alfaslabone/latex/OT1AlphaSlabOne-TLF.fd | 36 + fonts/alfaslabone/latex/T1AlphaSlabOne-Sup.fd | 36 + fonts/alfaslabone/latex/T1AlphaSlabOne-TLF.fd | 36 + fonts/alfaslabone/latex/TS1AlphaSlabOne-TLF.fd | 36 + fonts/alfaslabone/latex/alfaslabone.sty | 62 + fonts/alfaslabone/map/AlphaSlabOne.map | 9 + .../alfaslabone/opentype/AlphaSlabOne-Regular.otf | Bin 0 -> 109148 bytes .../tfm/AlphaSlabOne-Regular-sup-ly1--base.tfm | Bin 0 -> 1860 bytes .../tfm/AlphaSlabOne-Regular-sup-ly1.tfm | Bin 0 -> 1864 bytes .../tfm/AlphaSlabOne-Regular-sup-ot1.tfm | Bin 0 -> 1332 bytes .../tfm/AlphaSlabOne-Regular-sup-t1--base.tfm | Bin 0 -> 1792 bytes .../tfm/AlphaSlabOne-Regular-sup-t1.tfm | Bin 0 -> 1800 bytes .../tfm/AlphaSlabOne-Regular-tlf-ly1--base.tfm | Bin 0 -> 1888 bytes .../tfm/AlphaSlabOne-Regular-tlf-ly1.tfm | Bin 0 -> 8040 bytes .../tfm/AlphaSlabOne-Regular-tlf-ot1.tfm | Bin 0 -> 2732 bytes .../tfm/AlphaSlabOne-Regular-tlf-t1--base.tfm | Bin 0 -> 1808 bytes .../tfm/AlphaSlabOne-Regular-tlf-t1.tfm | Bin 0 -> 9516 bytes .../tfm/AlphaSlabOne-Regular-tlf-ts1--base.tfm | Bin 0 -> 1420 bytes .../tfm/AlphaSlabOne-Regular-tlf-ts1.tfm | Bin 0 -> 1428 bytes fonts/alfaslabone/type1/AlphaSlabOne-Regular.pfb | Bin 0 -> 124025 bytes .../alfaslabone/vf/AlphaSlabOne-Regular-sup-ly1.vf | Bin 0 -> 1684 bytes .../alfaslabone/vf/AlphaSlabOne-Regular-sup-t1.vf | Bin 0 -> 1700 bytes .../alfaslabone/vf/AlphaSlabOne-Regular-tlf-ly1.vf | Bin 0 -> 1712 bytes .../alfaslabone/vf/AlphaSlabOne-Regular-tlf-t1.vf | Bin 0 -> 1728 bytes .../alfaslabone/vf/AlphaSlabOne-Regular-tlf-ts1.vf | Bin 0 -> 548 bytes fonts/stix2-type1/README.md | 2 + fonts/stix2-type1/stix2.dtx | 6 +- fonts/stix2-type1/stix2.pdf | Bin 1336168 -> 1336166 bytes graphics/pgf/contrib/tikz-bbox/README.txt | 24 + .../pgf/contrib/tikz-bbox/pgflibrarybbox.code.tex | 120 + .../tikz-bbox/pgfmanual-en-library-bbox.tex | 181 + graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.pdf | Bin 0 -> 234562 bytes graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.tex | 26 + graphics/pxpic/README.md | 2 +- graphics/pxpic/pxpic.dtx | 342 +- graphics/pxpic/pxpic.pdf | Bin 295341 -> 309853 bytes info/beginlatex/src/pslatex.sty | 458 - macros/latex/contrib/acro/README | 7 +- macros/latex/contrib/acro/acro-examples.sty | 166 + macros/latex/contrib/acro/acro-manual.pdf | Bin 884055 -> 889312 bytes macros/latex/contrib/acro/acro-manual.tex | 79 +- macros/latex/contrib/acro/acro.sty | 350 +- macros/latex/contrib/asmeconf/README.md | 43 +- macros/latex/contrib/asmeconf/asmeconf-sample.bib | 80 +- .../latex/contrib/asmeconf/asmeconf-template.pdf | Bin 588137 -> 637738 bytes .../latex/contrib/asmeconf/asmeconf-template.tex | 228 +- macros/latex/contrib/asmeconf/asmeconf.bst | 42 +- macros/latex/contrib/asmeconf/asmeconf.cls | 1536 +- .../latex/contrib/asmeconf/author-grid-style.pdf | Bin 246240 -> 0 bytes .../CONTRACTOR-copyright-asmeconf-template.pdf | Bin 0 -> 483046 bytes .../examples/GOVT-copyright-asmeconf-template.pdf | Bin 0 -> 482459 bytes .../examples/asmeconf-authorgrid-example.pdf | Bin 0 -> 610063 bytes .../examples/asmeconf-authorgrid-example.tex | 650 + .../asmeconf/examples/asmeconf-fontspec.pdf | Bin 0 -> 381077 bytes .../asmeconf/examples/asmeconf-fontspec.tex | 444 + .../examples/asmeconf-lualatex-ode-example.pdf | Bin 0 -> 275358 bytes .../examples/asmeconf-lualatex-ode-example.tex | 254 + macros/latex/contrib/translations/README | 4 +- .../translations-basic-dictionary-brazil.trsl | 11 +- .../translations-basic-dictionary-catalan.trsl | 17 +- .../dicts/translations-basic-dictionary-dutch.trsl | 11 +- .../translations-basic-dictionary-english.trsl | 11 +- .../translations-basic-dictionary-french.trsl | 11 +- .../translations-basic-dictionary-german.trsl | 11 +- .../translations-basic-dictionary-spanish.trsl | 11 +- macros/latex/contrib/translations/translations.sty | 22 +- .../latex/contrib/translations/translations_en.pdf | Bin 497802 -> 496825 bytes .../latex/contrib/translations/translations_en.tex | 19 +- macros/luatex/generic/luaotfload/NEWS | 5 + macros/luatex/generic/luaotfload/README.md | 4 +- macros/luatex/generic/luaotfload/filegraph.pdf | Bin 40030 -> 41362 bytes .../generic/luaotfload/fontloader-2020-12-30.lua | 35110 ------------------ .../generic/luaotfload/fontloader-2021-01-07.lua | 35115 +++++++++++++++++++ .../generic/luaotfload/fontloader-font-cff.lua | 15 +- .../generic/luaotfload/fontloader-font-con.lua | 16 +- .../generic/luaotfload/fontloader-font-dsp.lua | 4 +- .../luaotfload/fontloader-font-imp-italics.lua | 18 - .../generic/luaotfload/fontloader-font-otl.lua | 2 +- .../generic/luaotfload/fontloader-font-ots.lua | 3 + .../generic/luaotfload/fontloader-reference.lua | 17 +- .../generic/luaotfload/luaotfload-auxiliary.lua | 4 +- .../generic/luaotfload/luaotfload-case-el.lua | 294 + .../generic/luaotfload/luaotfload-colors.lua | 4 +- .../luatex/generic/luaotfload/luaotfload-conf.pdf | Bin 77331 -> 78522 bytes .../luaotfload/luaotfload-configuration.lua | 4 +- .../generic/luaotfload/luaotfload-database.lua | 4 +- .../generic/luaotfload/luaotfload-diagnostics.lua | 4 +- .../luatex/generic/luaotfload/luaotfload-dvi.lua | 4 +- .../generic/luaotfload/luaotfload-embolden.lua | 4 +- .../generic/luaotfload/luaotfload-fakesc.lua | 204 + .../generic/luaotfload/luaotfload-fallback.lua | 4 +- .../generic/luaotfload/luaotfload-features.lua | 4 +- .../generic/luaotfload/luaotfload-filelist.lua | 4 +- .../generic/luaotfload/luaotfload-glyphlist.lua | 4 +- .../generic/luaotfload/luaotfload-harf-define.lua | 4 +- .../generic/luaotfload/luaotfload-harf-plug.lua | 4 +- .../luatex/generic/luaotfload/luaotfload-init.lua | 4 +- .../luatex/generic/luaotfload/luaotfload-latex.pdf | Bin 493305 -> 501958 bytes .../generic/luaotfload/luaotfload-letterspace.lua | 4 +- .../generic/luaotfload/luaotfload-loaders.lua | 4 +- .../luatex/generic/luaotfload/luaotfload-log.lua | 4 +- .../luatex/generic/luaotfload/luaotfload-main.tex | 12 +- .../generic/luaotfload/luaotfload-multiscript.lua | 4 +- .../generic/luaotfload/luaotfload-notdef.lua | 4 +- .../generic/luaotfload/luaotfload-parsers.lua | 4 +- .../generic/luaotfload/luaotfload-resolvers.lua | 4 +- .../generic/luaotfload/luaotfload-scripts.lua | 4 +- .../generic/luaotfload/luaotfload-status.lua | 186 +- .../generic/luaotfload/luaotfload-suppress.lua | 4 +- .../luatex/generic/luaotfload/luaotfload-szss.lua | 4 +- macros/luatex/generic/luaotfload/luaotfload-tool.1 | 2 +- .../luatex/generic/luaotfload/luaotfload-tool.lua | 4 +- .../luatex/generic/luaotfload/luaotfload-tool.pdf | Bin 76773 -> 78960 bytes .../luatex/generic/luaotfload/luaotfload-tool.rst | 4 +- .../generic/luaotfload/luaotfload-tounicode.lua | 4 +- .../generic/luaotfload/luaotfload-unicode.lua | 4 +- macros/luatex/generic/luaotfload/luaotfload.conf.5 | 2 +- .../luatex/generic/luaotfload/luaotfload.conf.rst | 4 +- macros/luatex/generic/luaotfload/luaotfload.lua | 4 +- macros/luatex/generic/luaotfload/luaotfload.sty | 4 +- macros/luatex/generic/luaotfload/scripts-demo.pdf | Bin 21696 -> 21837 bytes .../generic/luaotfload/shaper-demo-graphite.pdf | Bin 8566 -> 8559 bytes macros/luatex/generic/luaotfload/shaper-demo.pdf | Bin 8486 -> 8479 bytes .../texlive/tlnet/tlpkg/installer/ctan-mirrors.pl | 1 + systems/texlive/tlnet/tlpkg/texlive.tlpdb | 889 +- systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 | 2 +- systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 | 2 +- .../texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc | 14 +- systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz | Bin 2267500 -> 2267336 bytes systems/texlive/tlnet/tlpkg/tltcl/tltcl.tcl | 6 +- systems/win32/w32tex/ChangeLog | 16 + timestamp | 2 +- 149 files changed, 41928 insertions(+), 37894 deletions(-) create mode 100644 fonts/alfaslabone/README create mode 100644 fonts/alfaslabone/doc/LICENSE.TXT create mode 100644 fonts/alfaslabone/doc/alfaslabone-samples.pdf create mode 100644 fonts/alfaslabone/doc/alfaslabone-samples.tex create mode 100644 fonts/alfaslabone/enc/a_5xld5w.enc create mode 100644 fonts/alfaslabone/enc/a_adz5lu.enc create mode 100644 fonts/alfaslabone/enc/a_d2anrk.enc create mode 100644 fonts/alfaslabone/enc/a_lzhlbi.enc create mode 100644 fonts/alfaslabone/enc/a_rymxky.enc create mode 100644 fonts/alfaslabone/enc/a_taosrr.enc create mode 100644 fonts/alfaslabone/enc/a_vqpkf5.enc create mode 100644 fonts/alfaslabone/latex/LY1AlphaSlabOne-Sup.fd create mode 100644 fonts/alfaslabone/latex/LY1AlphaSlabOne-TLF.fd create mode 100644 fonts/alfaslabone/latex/OT1AlphaSlabOne-Sup.fd create mode 100644 fonts/alfaslabone/latex/OT1AlphaSlabOne-TLF.fd create mode 100644 fonts/alfaslabone/latex/T1AlphaSlabOne-Sup.fd create mode 100644 fonts/alfaslabone/latex/T1AlphaSlabOne-TLF.fd create mode 100644 fonts/alfaslabone/latex/TS1AlphaSlabOne-TLF.fd create mode 100644 fonts/alfaslabone/latex/alfaslabone.sty create mode 100644 fonts/alfaslabone/map/AlphaSlabOne.map create mode 100644 fonts/alfaslabone/opentype/AlphaSlabOne-Regular.otf create mode 100644 fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-ly1--base.tfm create mode 100644 fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-ly1.tfm create mode 100644 fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-ot1.tfm create mode 100644 fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-t1--base.tfm create mode 100644 fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-t1.tfm create mode 100644 fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ly1--base.tfm create mode 100644 fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ly1.tfm create mode 100644 fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ot1.tfm create mode 100644 fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-t1--base.tfm create mode 100644 fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-t1.tfm create mode 100644 fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ts1--base.tfm create mode 100644 fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ts1.tfm create mode 100644 fonts/alfaslabone/type1/AlphaSlabOne-Regular.pfb create mode 100644 fonts/alfaslabone/vf/AlphaSlabOne-Regular-sup-ly1.vf create mode 100644 fonts/alfaslabone/vf/AlphaSlabOne-Regular-sup-t1.vf create mode 100644 fonts/alfaslabone/vf/AlphaSlabOne-Regular-tlf-ly1.vf create mode 100644 fonts/alfaslabone/vf/AlphaSlabOne-Regular-tlf-t1.vf create mode 100644 fonts/alfaslabone/vf/AlphaSlabOne-Regular-tlf-ts1.vf create mode 100644 graphics/pgf/contrib/tikz-bbox/README.txt create mode 100644 graphics/pgf/contrib/tikz-bbox/pgflibrarybbox.code.tex create mode 100644 graphics/pgf/contrib/tikz-bbox/pgfmanual-en-library-bbox.tex create mode 100644 graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.pdf create mode 100644 graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.tex delete mode 100644 info/beginlatex/src/pslatex.sty create mode 100644 macros/latex/contrib/acro/acro-examples.sty delete mode 100644 macros/latex/contrib/asmeconf/author-grid-style.pdf create mode 100644 macros/latex/contrib/asmeconf/examples/CONTRACTOR-copyright-asmeconf-template.pdf create mode 100644 macros/latex/contrib/asmeconf/examples/GOVT-copyright-asmeconf-template.pdf create mode 100644 macros/latex/contrib/asmeconf/examples/asmeconf-authorgrid-example.pdf create mode 100644 macros/latex/contrib/asmeconf/examples/asmeconf-authorgrid-example.tex create mode 100644 macros/latex/contrib/asmeconf/examples/asmeconf-fontspec.pdf create mode 100644 macros/latex/contrib/asmeconf/examples/asmeconf-fontspec.tex create mode 100644 macros/latex/contrib/asmeconf/examples/asmeconf-lualatex-ode-example.pdf create mode 100644 macros/latex/contrib/asmeconf/examples/asmeconf-lualatex-ode-example.tex delete mode 100644 macros/luatex/generic/luaotfload/fontloader-2020-12-30.lua create mode 100644 macros/luatex/generic/luaotfload/fontloader-2021-01-07.lua create mode 100644 macros/luatex/generic/luaotfload/luaotfload-case-el.lua create mode 100644 macros/luatex/generic/luaotfload/luaotfload-fakesc.lua diff --git a/FILES.byname b/FILES.byname index b35908e4d9..e31cbca987 100644 --- a/FILES.byname +++ b/FILES.byname @@ -5087,7 +5087,7 @@ 1990/10/02 | 5440 | dviware/vutex/vaxvms.hlp 1990/10/02 | 812 | dviware/vutex/vaxvms.ins 1990/10/02 | 127576 | dviware/vutex/vutex.web -2021/01/15 | 310345 | FILES.last07days +2021/01/16 | 249955 | FILES.last07days 2020/08/14 | 104065 | fonts/academicons/academicons.pdf 2020/08/14 | 17247 | fonts/academicons/academicons.sty 2020/08/14 | 6546 | fonts/academicons/academicons.tex @@ -9934,6 +9934,46 @@ 2019/10/08 | 1736 | fonts/alegreya/vf/AlegreyaSC-Regular-tosf-sc-ly1.vf 2019/10/08 | 1776 | fonts/alegreya/vf/AlegreyaSC-Regular-tosf-sc-t1.vf 2019/10/12 | 37970453 | fonts/alegreya.zip +2021/01/16 | 25187 | fonts/alfaslabone/doc/alfaslabone-samples.pdf +2021/01/16 | 423 | fonts/alfaslabone/doc/alfaslabone-samples.tex +2021/01/16 | 4430 | fonts/alfaslabone/doc/LICENSE.TXT +2021/01/16 | 2830 | fonts/alfaslabone/enc/a_5xld5w.enc +2021/01/16 | 2886 | fonts/alfaslabone/enc/a_adz5lu.enc +2021/01/16 | 2958 | fonts/alfaslabone/enc/a_d2anrk.enc +2021/01/16 | 2943 | fonts/alfaslabone/enc/a_lzhlbi.enc +2021/01/16 | 2999 | fonts/alfaslabone/enc/a_rymxky.enc +2021/01/16 | 3179 | fonts/alfaslabone/enc/a_taosrr.enc +2021/01/16 | 2902 | fonts/alfaslabone/enc/a_vqpkf5.enc +2021/01/16 | 2441 | fonts/alfaslabone/latex/alfaslabone.sty +2021/01/16 | 941 | fonts/alfaslabone/latex/LY1AlphaSlabOne-Sup.fd +2021/01/16 | 941 | fonts/alfaslabone/latex/LY1AlphaSlabOne-TLF.fd +2021/01/16 | 941 | fonts/alfaslabone/latex/OT1AlphaSlabOne-Sup.fd +2021/01/16 | 941 | fonts/alfaslabone/latex/OT1AlphaSlabOne-TLF.fd +2021/01/16 | 935 | fonts/alfaslabone/latex/T1AlphaSlabOne-Sup.fd +2021/01/16 | 935 | fonts/alfaslabone/latex/T1AlphaSlabOne-TLF.fd +2021/01/16 | 941 | fonts/alfaslabone/latex/TS1AlphaSlabOne-TLF.fd +2021/01/16 | 1087 | fonts/alfaslabone/map/AlphaSlabOne.map +2021/01/16 | 109148 | fonts/alfaslabone/opentype/AlphaSlabOne-Regular.otf +2021/01/16 | 935 | fonts/alfaslabone/README +2021/01/16 | 1860 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-ly1--base.tfm +2021/01/16 | 1864 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-ly1.tfm +2021/01/16 | 1332 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-ot1.tfm +2021/01/16 | 1792 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-t1--base.tfm +2021/01/16 | 1800 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-t1.tfm +2021/01/16 | 1888 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ly1--base.tfm +2021/01/16 | 8040 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ly1.tfm +2021/01/16 | 2732 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ot1.tfm +2021/01/16 | 1808 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-t1--base.tfm +2021/01/16 | 9516 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-t1.tfm +2021/01/16 | 1420 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ts1--base.tfm +2021/01/16 | 1428 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ts1.tfm +2021/01/16 | 124025 | fonts/alfaslabone/type1/AlphaSlabOne-Regular.pfb +2021/01/16 | 1684 | fonts/alfaslabone/vf/AlphaSlabOne-Regular-sup-ly1.vf +2021/01/16 | 1700 | fonts/alfaslabone/vf/AlphaSlabOne-Regular-sup-t1.vf +2021/01/16 | 1712 | fonts/alfaslabone/vf/AlphaSlabOne-Regular-tlf-ly1.vf +2021/01/16 | 1728 | fonts/alfaslabone/vf/AlphaSlabOne-Regular-tlf-t1.vf +2021/01/16 | 548 | fonts/alfaslabone/vf/AlphaSlabOne-Regular-tlf-ts1.vf +2021/01/16 | 241759 | fonts/alfaslabone.zip 2020/11/04 | 128064 | fonts/algolrevived/doc/algolrevived-doc.pdf 2020/11/04 | 13549 | fonts/algolrevived/doc/algolrevived-doc.tex 2020/02/01 | 58513 | fonts/algolrevived/doc/OFL-FAQ.txt @@ -126885,12 +126925,12 @@ 2018/03/30 | 7861 | fonts/stix2-type1/pl/ts1-stix2text-bold.pl 2018/03/30 | 8351 | fonts/stix2-type1/pl/ts1-stix2text-italic.pl 2018/03/30 | 7784 | fonts/stix2-type1/pl/ts1-stix2text.pl -2021/01/15 | 1716 | fonts/stix2-type1/README.md -2021/01/14 | 196011 | fonts/stix2-type1/stix2.dtx +2021/01/15 | 1780 | fonts/stix2-type1/README.md +2021/01/15 | 196013 | fonts/stix2-type1/stix2.dtx 2021/01/15 | 8800 | fonts/stix2-type1/stix2.fdd 2021/01/15 | 1096 | fonts/stix2-type1/stix2.ins 2018/03/30 | 4461 | fonts/stix2-type1/stix2.map -2021/01/15 | 1336168 | fonts/stix2-type1/stix2.pdf +2021/01/15 | 1336166 | fonts/stix2-type1/stix2.pdf 2018/03/30 | 7268 | fonts/stix2-type1/tfm/ot1-stix2text-bolditalic.tfm 2018/03/30 | 6680 | fonts/stix2-type1/tfm/ot1-stix2text-bold.tfm 2018/03/30 | 7240 | fonts/stix2-type1/tfm/ot1-stix2text-italic.tfm @@ -126930,7 +126970,7 @@ 2018/03/30 | 1480 | fonts/stix2-type1/tfm/ts1-stix2text-bold.tfm 2018/03/30 | 1556 | fonts/stix2-type1/tfm/ts1-stix2text-italic.tfm 2018/03/30 | 1460 | fonts/stix2-type1/tfm/ts1-stix2text.tfm -2021/01/15 | 4823627 | fonts/stix2-type1.zip +2021/01/16 | 4823653 | fonts/stix2-type1.zip 2014/08/01 | 422400 | fonts/stix/doc/STIX_Font_1.1.1-latex_Release_Documentation.doc 2014/08/01 | 153080 | fonts/stix/doc/STIX_Font_1.1.1-latex_Release_Documentation.pdf 2014/05/16 | 421888 | fonts/stix/doc/STIX_Font_1.1.1_Release_Documentation.doc @@ -142533,6 +142573,12 @@ 2013/01/02 | 3338 | graphics/pgf/contrib/tikz-bayesnet/README.rst 2013/01/02 | 3929 | graphics/pgf/contrib/tikz-bayesnet/tikzlibrarybayesnet.code.tex 2013/04/24 | 28716 | graphics/pgf/contrib/tikz-bayesnet.zip +2021/01/16 | 5952 | graphics/pgf/contrib/tikz-bbox/pgflibrarybbox.code.tex +2021/01/16 | 234562 | graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.pdf +2021/01/16 | 766 | graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.tex +2021/01/16 | 7119 | graphics/pgf/contrib/tikz-bbox/pgfmanual-en-library-bbox.tex +2021/01/16 | 796 | graphics/pgf/contrib/tikz-bbox/README.txt +2021/01/16 | 238560 | graphics/pgf/contrib/tikz-bbox.zip 2018/11/19 | 723 | graphics/pgf/contrib/tikz-cd/README.md 2018/11/19 | 266756 | graphics/pgf/contrib/tikz-cd/tikz-cd-doc.pdf 2018/11/19 | 50736 | graphics/pgf/contrib/tikz-cd/tikz-cd-doc.tex @@ -146541,10 +146587,10 @@ 2020/08/17 | 2939 | graphics/pstricks/scripts/pst2pdf/README.md 2020/08/24 | 92935 | graphics/pstricks/scripts/pst2pdf/script/pst2pdf.pl 2020/08/24 | 522692 | graphics/pstricks/scripts/pst2pdf.zip -2021/01/13 | 37153 | graphics/pxpic/pxpic.dtx -2021/01/13 | 295341 | graphics/pxpic/pxpic.pdf -2021/01/13 | 1145 | graphics/pxpic/README.md -2021/01/13 | 299461 | graphics/pxpic.zip +2021/01/16 | 45547 | graphics/pxpic/pxpic.dtx +2021/01/16 | 309853 | graphics/pxpic/pxpic.pdf +2021/01/16 | 1145 | graphics/pxpic/README.md +2021/01/16 | 315430 | graphics/pxpic.zip 2018/08/14 | 296507 | graphics/qcircuit/qcircuit.pdf 2018/08/14 | 13128 | graphics/qcircuit/qcircuit.sty 2018/08/10 | 4319 | graphics/qcircuit/README.md @@ -148300,7 +148346,6 @@ 2003/10/22 | 4020 | info/beginlatex/src/parbox2.png 2002/09/19 | 935 | info/beginlatex/src/practype.tex 2005/03/13 | 9584 | info/beginlatex/src/pro06.jpg -2003/10/12 | 10194 | info/beginlatex/src/pslatex.sty 2003/10/22 | 464743 | info/beginlatex/src/public.eps 2003/10/22 | 42634 | info/beginlatex/src/public.png 2005/03/05 | 469752 | info/beginlatex/src/qpdf.eps @@ -148369,7 +148414,7 @@ 2005/03/05 | 16879 | info/beginlatex/src/zedit.png 2005/03/05 | 469754 | info/beginlatex/src/zlatex.eps 2005/03/05 | 16202 | info/beginlatex/src/zlatex.png -2006/03/19 | 21223675 | info/beginlatex.zip +2021/01/16 | 23895404 | info/beginlatex.zip 2017/06/24 | 313925 | info/biblatex-cheatsheet/biblatex-cheatsheet.pdf 2017/06/24 | 27606 | info/biblatex-cheatsheet/biblatex-cheatsheet.tex 2017/06/24 | 120 | info/biblatex-cheatsheet/README @@ -171825,7 +171870,7 @@ 2015/10/01 | 154538 | install/macros/luatex/generic/ctablestack.tds.zip 2020/12/31 | 273393 | install/macros/luatex/generic/lualibs.tds.zip 2020/12/30 | 196220 | install/macros/luatex/generic/luamplib.tds.zip -2020/12/31 | 1936733 | install/macros/luatex/generic/luaotfload.tds.zip +2021/01/16 | 1950415 | install/macros/luatex/generic/luaotfload.tds.zip 2015/10/04 | 277014 | install/macros/luatex/generic/luatexbase.tds.zip 2020/03/23 | 891718 | install/macros/luatex/latex/arabluatex.tds.zip 2020/11/04 | 721353 | install/macros/luatex/latex/ekdosis.tds.zip @@ -188044,36 +188089,37 @@ 2000/05/18 | 2170 | macros/latex/contrib/acmconf/README 2000/05/18 | 30 | macros/latex/contrib/acmconf/THIS-IS-VERSION-1.3 2008/05/14 | 105778 | macros/latex/contrib/acmconf.zip -2020/12/25 | 144061 | macros/latex/contrib/acro/acro2.sty -2020/12/25 | 884055 | macros/latex/contrib/acro/acro-manual.pdf -2020/12/25 | 101133 | macros/latex/contrib/acro/acro-manual.tex -2020/12/25 | 166923 | macros/latex/contrib/acro/acro.sty -2020/12/25 | 20922 | macros/latex/contrib/acro/examples/acro.example.acflike.pdf -2020/12/25 | 315 | macros/latex/contrib/acro/examples/acro.example.acflike.tex -2020/12/25 | 125351 | macros/latex/contrib/acro/examples/acro.example.basic.pdf -2020/12/25 | 3214 | macros/latex/contrib/acro/examples/acro.example.basic.tex -2020/12/25 | 30275 | macros/latex/contrib/acro/examples/acro.example.issue-109.pdf -2020/12/25 | 329 | macros/latex/contrib/acro/examples/acro.example.issue-109.tex -2020/12/25 | 15733 | macros/latex/contrib/acro/examples/acro.example.issue-111.pdf -2020/12/25 | 706 | macros/latex/contrib/acro/examples/acro.example.issue-111.tex -2020/12/25 | 8175 | macros/latex/contrib/acro/examples/acro.example.issue-119.pdf -2020/12/25 | 983 | macros/latex/contrib/acro/examples/acro.example.issue-119.tex -2020/12/25 | 24224 | macros/latex/contrib/acro/examples/acro.example.issue-154.pdf -2020/12/25 | 286 | macros/latex/contrib/acro/examples/acro.example.issue-154.tex -2020/12/25 | 13686 | macros/latex/contrib/acro/examples/acro.example.possessive.pdf -2020/12/25 | 779 | macros/latex/contrib/acro/examples/acro.example.possessive.tex -2020/12/25 | 32432 | macros/latex/contrib/acro/examples/acro.example.texsx-505891.pdf -2020/12/25 | 1068 | macros/latex/contrib/acro/examples/acro.example.texsx-505891.tex -2020/12/25 | 33721 | macros/latex/contrib/acro/examples/acro.example.texsx-507726.pdf -2020/12/25 | 1476 | macros/latex/contrib/acro/examples/acro.example.texsx-507726.tex -2020/12/25 | 22752 | macros/latex/contrib/acro/examples/acro.example.texsx-513623.pdf -2020/12/25 | 353 | macros/latex/contrib/acro/examples/acro.example.texsx-513623.tex -2020/12/25 | 15855 | macros/latex/contrib/acro/examples/acro.example.texsx-515295.pdf -2020/12/25 | 372 | macros/latex/contrib/acro/examples/acro.example.texsx-515295.tex -2020/12/25 | 15808 | macros/latex/contrib/acro/examples/acro.example.texsx-542461.pdf -2020/12/25 | 757 | macros/latex/contrib/acro/examples/acro.example.texsx-542461.tex -2020/12/25 | 65067 | macros/latex/contrib/acro/examples/acro.example.units.pdf -2020/12/25 | 1978 | macros/latex/contrib/acro/examples/acro.example.units.tex +2021/01/16 | 144061 | macros/latex/contrib/acro/acro2.sty +2021/01/16 | 3252 | macros/latex/contrib/acro/acro-examples.sty +2021/01/16 | 889312 | macros/latex/contrib/acro/acro-manual.pdf +2021/01/16 | 104364 | macros/latex/contrib/acro/acro-manual.tex +2021/01/16 | 172864 | macros/latex/contrib/acro/acro.sty +2021/01/16 | 20922 | macros/latex/contrib/acro/examples/acro.example.acflike.pdf +2021/01/16 | 315 | macros/latex/contrib/acro/examples/acro.example.acflike.tex +2021/01/16 | 125351 | macros/latex/contrib/acro/examples/acro.example.basic.pdf +2021/01/16 | 3214 | macros/latex/contrib/acro/examples/acro.example.basic.tex +2021/01/16 | 30275 | macros/latex/contrib/acro/examples/acro.example.issue-109.pdf +2021/01/16 | 329 | macros/latex/contrib/acro/examples/acro.example.issue-109.tex +2021/01/16 | 15733 | macros/latex/contrib/acro/examples/acro.example.issue-111.pdf +2021/01/16 | 706 | macros/latex/contrib/acro/examples/acro.example.issue-111.tex +2021/01/16 | 8175 | macros/latex/contrib/acro/examples/acro.example.issue-119.pdf +2021/01/16 | 983 | macros/latex/contrib/acro/examples/acro.example.issue-119.tex +2021/01/16 | 24224 | macros/latex/contrib/acro/examples/acro.example.issue-154.pdf +2021/01/16 | 286 | macros/latex/contrib/acro/examples/acro.example.issue-154.tex +2021/01/16 | 13686 | macros/latex/contrib/acro/examples/acro.example.possessive.pdf +2021/01/16 | 779 | macros/latex/contrib/acro/examples/acro.example.possessive.tex +2021/01/16 | 32432 | macros/latex/contrib/acro/examples/acro.example.texsx-505891.pdf +2021/01/16 | 1068 | macros/latex/contrib/acro/examples/acro.example.texsx-505891.tex +2021/01/16 | 33721 | macros/latex/contrib/acro/examples/acro.example.texsx-507726.pdf +2021/01/16 | 1476 | macros/latex/contrib/acro/examples/acro.example.texsx-507726.tex +2021/01/16 | 22752 | macros/latex/contrib/acro/examples/acro.example.texsx-513623.pdf +2021/01/16 | 353 | macros/latex/contrib/acro/examples/acro.example.texsx-513623.tex +2021/01/16 | 15855 | macros/latex/contrib/acro/examples/acro.example.texsx-515295.pdf +2021/01/16 | 372 | macros/latex/contrib/acro/examples/acro.example.texsx-515295.tex +2021/01/16 | 15808 | macros/latex/contrib/acro/examples/acro.example.texsx-542461.pdf +2021/01/16 | 757 | macros/latex/contrib/acro/examples/acro.example.texsx-542461.tex +2021/01/16 | 65067 | macros/latex/contrib/acro/examples/acro.example.units.pdf +2021/01/16 | 1978 | macros/latex/contrib/acro/examples/acro.example.units.tex 2010/02/13 | 164875 | macros/latex/contrib/acromake/acromake.pdf 2010/02/15 | 4599 | macros/latex/contrib/acromake/acromake.sty 2010/02/13 | 2922 | macros/latex/contrib/acromake/acromake.tex @@ -188084,7 +188130,7 @@ 2020/04/11 | 9214 | macros/latex/contrib/acronym/CHANGES 2020/04/11 | 1017 | macros/latex/contrib/acronym/README 2020/04/11 | 295778 | macros/latex/contrib/acronym.zip -2020/12/25 | 2104 | macros/latex/contrib/acro/README +2021/01/16 | 2125 | macros/latex/contrib/acro/README 2010/11/19 | 11356 | macros/latex/contrib/acroterm/acroterm.dtx 2010/11/19 | 1394 | macros/latex/contrib/acroterm/acroterm.ins 2010/11/19 | 172447 | macros/latex/contrib/acroterm/acroterm.pdf @@ -188124,7 +188170,7 @@ 2020/07/05 | 216178 | macros/latex/contrib/acrotex/web.dtx 2018/07/14 | 2338 | macros/latex/contrib/acrotex/web.ins 2020/11/20 | 3221746 | macros/latex/contrib/acrotex.zip -2020/12/25 | 1374455 | macros/latex/contrib/acro.zip +2021/01/16 | 1382570 | macros/latex/contrib/acro.zip 2019/06/13 | 26799 | macros/latex/contrib/actuarialangle/actuarialangle.dtx 2019/06/13 | 120479 | macros/latex/contrib/actuarialangle/actuarialangle.pdf 2019/06/13 | 1176 | macros/latex/contrib/actuarialangle/README.md @@ -188954,17 +189000,24 @@ 2020/10/22 | 39241 | macros/latex/contrib/askmaps/askmaps.tex 2020/10/22 | 814 | macros/latex/contrib/askmaps/README 2020/10/22 | 385765 | macros/latex/contrib/askmaps.zip -2020/04/15 | 36936 | macros/latex/contrib/asmeconf/asmeconf.bst -2020/12/10 | 36997 | macros/latex/contrib/asmeconf/asmeconf.cls -2020/12/10 | 12774 | macros/latex/contrib/asmeconf/asmeconf-sample.bib -2020/12/10 | 588137 | macros/latex/contrib/asmeconf/asmeconf-template.pdf -2020/12/10 | 37971 | macros/latex/contrib/asmeconf/asmeconf-template.tex -2020/08/12 | 246240 | macros/latex/contrib/asmeconf/author-grid-style.pdf -2020/12/10 | 6128 | macros/latex/contrib/asmeconf/README.md +2021/01/04 | 37675 | macros/latex/contrib/asmeconf/asmeconf.bst +2021/01/16 | 71644 | macros/latex/contrib/asmeconf/asmeconf.cls +2021/01/14 | 13995 | macros/latex/contrib/asmeconf/asmeconf-sample.bib +2021/01/15 | 637738 | macros/latex/contrib/asmeconf/asmeconf-template.pdf +2021/01/15 | 41372 | macros/latex/contrib/asmeconf/asmeconf-template.tex +2021/01/15 | 610063 | macros/latex/contrib/asmeconf/examples/asmeconf-authorgrid-example.pdf +2021/01/15 | 41302 | macros/latex/contrib/asmeconf/examples/asmeconf-authorgrid-example.tex +2021/01/16 | 381077 | macros/latex/contrib/asmeconf/examples/asmeconf-fontspec.pdf +2021/01/16 | 27446 | macros/latex/contrib/asmeconf/examples/asmeconf-fontspec.tex +2021/01/16 | 275358 | macros/latex/contrib/asmeconf/examples/asmeconf-lualatex-ode-example.pdf +2021/01/16 | 9886 | macros/latex/contrib/asmeconf/examples/asmeconf-lualatex-ode-example.tex +2020/11/07 | 483046 | macros/latex/contrib/asmeconf/examples/CONTRACTOR-copyright-asmeconf-template.pdf +2020/11/07 | 482459 | macros/latex/contrib/asmeconf/examples/GOVT-copyright-asmeconf-template.pdf +2021/01/16 | 7609 | macros/latex/contrib/asmeconf/README.md 2019/03/24 | 17689 | macros/latex/contrib/asmeconf/sample-figure-1.pdf 2019/07/08 | 95556 | macros/latex/contrib/asmeconf/sample-figure-2a.pdf 2019/07/08 | 91105 | macros/latex/contrib/asmeconf/sample-figure-2b.pdf -2020/12/11 | 1024832 | macros/latex/contrib/asmeconf.zip +2021/01/16 | 2834904 | macros/latex/contrib/asmeconf.zip 2020/04/15 | 42263 | macros/latex/contrib/asmejour/asmejour.bst 2020/08/12 | 29726 | macros/latex/contrib/asmejour/asmejour.cls 2020/04/15 | 18673 | macros/latex/contrib/asmejour/asmejour-sample.bib @@ -213169,18 +213222,18 @@ 2013/04/03 | 2140 | macros/latex/contrib/tram/tram.mf 2013/04/03 | 4024 | macros/latex/contrib/tram/tram.sty 2013/04/04 | 31506 | macros/latex/contrib/tram.zip -2020/11/08 | 6174 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-brazil.trsl -2020/11/08 | 6129 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-catalan.trsl -2020/11/08 | 5864 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-dutch.trsl -2020/11/08 | 5770 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-english.trsl -2020/11/08 | 5905 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-french.trsl -2020/11/08 | 5906 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-german.trsl -2020/11/08 | 6032 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-spanish.trsl -2020/11/08 | 1692 | macros/latex/contrib/translations/README -2020/11/08 | 497802 | macros/latex/contrib/translations/translations_en.pdf -2020/11/08 | 35842 | macros/latex/contrib/translations/translations_en.tex -2020/11/08 | 43916 | macros/latex/contrib/translations/translations.sty -2020/11/08 | 525176 | macros/latex/contrib/translations.zip +2021/01/16 | 5998 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-brazil.trsl +2021/01/16 | 5816 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-catalan.trsl +2021/01/16 | 5688 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-dutch.trsl +2021/01/16 | 5594 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-english.trsl +2021/01/16 | 5729 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-french.trsl +2021/01/16 | 5730 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-german.trsl +2021/01/16 | 5856 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-spanish.trsl +2021/01/16 | 1693 | macros/latex/contrib/translations/README +2021/01/16 | 496825 | macros/latex/contrib/translations/translations_en.pdf +2021/01/16 | 35437 | macros/latex/contrib/translations/translations_en.tex +2021/01/16 | 44005 | macros/latex/contrib/translations/translations.sty +2021/01/16 | 523682 | macros/latex/contrib/translations.zip 2017/11/25 | 575 | macros/latex/contrib/translator/README.md 2019/09/16 | 4230 | macros/latex/contrib/translator/translator-basic-dictionary-Bulgarian.dict 2017/12/03 | 3529 | macros/latex/contrib/translator/translator-basic-dictionary-Catalan.dict @@ -216730,120 +216783,122 @@ 2020/12/30 | 4016 | macros/luatex/generic/luamplib/test-luamplib-latex.tex 2020/12/30 | 3872 | macros/luatex/generic/luamplib/test-luamplib-plain.tex 2020/12/30 | 182036 | macros/luatex/generic/luamplib.zip -2019/12/25 | 18714 | macros/luatex/generic/luaotfload/COPYING -2020/12/31 | 40030 | macros/luatex/generic/luaotfload/filegraph.pdf -2020/12/31 | 8597 | macros/luatex/generic/luaotfload/filegraph.tex -2020/12/31 | 863103 | macros/luatex/generic/luaotfload/fontloader-2020-12-30.lua -2019/12/25 | 46091 | macros/luatex/generic/luaotfload/fontloader-basics-chr.lua -2020/12/31 | 12745 | macros/luatex/generic/luaotfload/fontloader-basics-gen.lua -2020/12/31 | 10064 | macros/luatex/generic/luaotfload/fontloader-basics-nod.lua -2020/02/03 | 5388 | macros/luatex/generic/luaotfload/fontloader-data-con.lua -2019/12/25 | 6866 | macros/luatex/generic/luaotfload/fontloader-font-afk.lua -2020/12/31 | 89678 | macros/luatex/generic/luaotfload/fontloader-font-cff.lua -2019/12/25 | 5502 | macros/luatex/generic/luaotfload/fontloader-font-cid.lua -2020/12/31 | 63054 | macros/luatex/generic/luaotfload/fontloader-font-con.lua -2020/12/31 | 19944 | macros/luatex/generic/luaotfload/fontloader-font-def.lua -2020/12/31 | 154135 | macros/luatex/generic/luaotfload/fontloader-font-dsp.lua -2020/12/31 | 13977 | macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua -2020/12/31 | 4240 | macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua -2019/12/25 | 3580 | macros/luatex/generic/luaotfload/fontloader-font-imp-ligatures.lua -2019/12/25 | 3406 | macros/luatex/generic/luaotfload/fontloader-font-imp-tex.lua -2020/02/03 | 1794 | macros/luatex/generic/luaotfload/fontloader-font-ini.lua -2019/12/25 | 1449 | macros/luatex/generic/luaotfload/fontloader-font-lua.lua -2020/12/31 | 19570 | macros/luatex/generic/luaotfload/fontloader-font-map.lua -2020/12/31 | 24566 | macros/luatex/generic/luaotfload/fontloader-font-ocl.lua -2020/12/31 | 31298 | macros/luatex/generic/luaotfload/fontloader-font-one.lua -2020/12/31 | 18717 | macros/luatex/generic/luaotfload/fontloader-font-onr.lua -2020/12/31 | 107580 | macros/luatex/generic/luaotfload/fontloader-font-osd.lua -2020/12/31 | 18421 | macros/luatex/generic/luaotfload/fontloader-font-ota.lua -2019/12/25 | 31802 | macros/luatex/generic/luaotfload/fontloader-font-otc.lua -2019/12/25 | 7904 | macros/luatex/generic/luaotfload/fontloader-font-oti.lua -2020/12/31 | 65656 | macros/luatex/generic/luaotfload/fontloader-font-otj.lua -2020/12/31 | 33035 | macros/luatex/generic/luaotfload/fontloader-font-otl.lua -2020/02/03 | 22966 | macros/luatex/generic/luaotfload/fontloader-font-oto.lua -2020/12/31 | 94470 | macros/luatex/generic/luaotfload/fontloader-font-otr.lua -2020/12/31 | 182024 | macros/luatex/generic/luaotfload/fontloader-font-ots.lua -2020/12/31 | 34862 | macros/luatex/generic/luaotfload/fontloader-font-ott.lua -2020/12/31 | 117724 | macros/luatex/generic/luaotfload/fontloader-font-oup.lua -2019/12/25 | 3821 | macros/luatex/generic/luaotfload/fontloader-fonts-def.lua -2019/12/25 | 2315 | macros/luatex/generic/luaotfload/fontloader-fonts-enc.lua -2019/12/25 | 7260 | macros/luatex/generic/luaotfload/fontloader-fonts-ext.lua -2019/12/25 | 9875 | macros/luatex/generic/luaotfload/fontloader-fonts-gbn.lua -2020/12/31 | 13500 | macros/luatex/generic/luaotfload/fontloader-font-shp.lua -2019/12/25 | 57342 | macros/luatex/generic/luaotfload/fontloader-fonts-lig.lua -2019/12/25 | 912 | macros/luatex/generic/luaotfload/fontloader-fonts-mis.lua -2019/12/25 | 3674 | macros/luatex/generic/luaotfload/fontloader-fonts-syn.lua -2019/12/25 | 23399 | macros/luatex/generic/luaotfload/fontloader-fonts-tfm.lua -2020/12/31 | 59344 | macros/luatex/generic/luaotfload/fontloader-font-ttf.lua -2020/12/31 | 2667 | macros/luatex/generic/luaotfload/fontloader-font-vfc.lua -2019/12/25 | 1850 | macros/luatex/generic/luaotfload/fontloader-l-boolean.lua -2020/02/03 | 22175 | macros/luatex/generic/luaotfload/fontloader-l-file.lua -2019/12/25 | 361 | macros/luatex/generic/luaotfload/fontloader-l-function.lua -2020/02/03 | 11829 | macros/luatex/generic/luaotfload/fontloader-l-io.lua -2020/12/31 | 38703 | macros/luatex/generic/luaotfload/fontloader-l-lpeg.lua -2020/12/31 | 6405 | macros/luatex/generic/luaotfload/fontloader-l-lua.lua -2019/12/25 | 2555 | macros/luatex/generic/luaotfload/fontloader-l-math.lua -2019/12/25 | 6644 | macros/luatex/generic/luaotfload/fontloader-l-string.lua -2020/12/31 | 41758 | macros/luatex/generic/luaotfload/fontloader-l-table.lua -2020/12/31 | 41303 | macros/luatex/generic/luaotfload/fontloader-l-unicode.lua -2020/12/31 | 15196 | macros/luatex/generic/luaotfload/fontloader-reference-load-order.lua -2019/12/25 | 5885 | macros/luatex/generic/luaotfload/fontloader-reference-load-order.tex -2020/12/31 | 964020 | macros/luatex/generic/luaotfload/fontloader-reference.lua -2020/12/31 | 11552 | macros/luatex/generic/luaotfload/fontloader-util-fil.lua -2020/12/31 | 43947 | macros/luatex/generic/luaotfload/fontloader-util-str.lua -2020/12/31 | 32597 | macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua -2019/12/25 | 52 | macros/luatex/generic/luaotfload/luaotfload-blacklist.cnf -2020/12/31 | 6809 | macros/luatex/generic/luaotfload/luaotfload-case.lua -2020/12/31 | 3287334 | macros/luatex/generic/luaotfload/luaotfload-characters.lua -2020/12/31 | 15954 | macros/luatex/generic/luaotfload/luaotfload-colors.lua -2020/12/31 | 16548 | macros/luatex/generic/luaotfload/luaotfload.conf.5 -2019/12/25 | 735 | macros/luatex/generic/luaotfload/luaotfload.conf.example -2020/12/31 | 31151 | macros/luatex/generic/luaotfload/luaotfload-configuration.lua -2020/12/31 | 77331 | macros/luatex/generic/luaotfload/luaotfload-conf.pdf -2020/12/31 | 18074 | macros/luatex/generic/luaotfload/luaotfload.conf.rst -2020/12/31 | 134863 | macros/luatex/generic/luaotfload/luaotfload-database.lua -2020/12/31 | 21857 | macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua -2020/12/31 | 4956 | macros/luatex/generic/luaotfload/luaotfload-dvi.lua -2020/12/31 | 1004 | macros/luatex/generic/luaotfload/luaotfload-embolden.lua -2020/12/31 | 4047 | macros/luatex/generic/luaotfload/luaotfload-fallback.lua -2020/12/31 | 29002 | macros/luatex/generic/luaotfload/luaotfload-features.lua -2020/12/31 | 25336 | macros/luatex/generic/luaotfload/luaotfload-filelist.lua -2020/12/31 | 102502 | macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua -2020/12/31 | 13468 | macros/luatex/generic/luaotfload/luaotfload-harf-define.lua -2020/12/31 | 41599 | macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua -2020/12/31 | 19547 | macros/luatex/generic/luaotfload/luaotfload-init.lua -2020/12/31 | 493305 | macros/luatex/generic/luaotfload/luaotfload-latex.pdf -2020/12/31 | 16675 | macros/luatex/generic/luaotfload/luaotfload-latex.tex -2020/12/31 | 18645 | macros/luatex/generic/luaotfload/luaotfload-letterspace.lua -2020/12/31 | 8840 | macros/luatex/generic/luaotfload/luaotfload-loaders.lua -2020/12/31 | 11323 | macros/luatex/generic/luaotfload/luaotfload-log.lua -2020/12/31 | 13788 | macros/luatex/generic/luaotfload/luaotfload.lua -2020/12/31 | 275 | macros/luatex/generic/luaotfload/luaotfload-main.lua -2020/12/31 | 98669 | macros/luatex/generic/luaotfload/luaotfload-main.tex -2020/12/31 | 15068 | macros/luatex/generic/luaotfload/luaotfload-multiscript.lua -2020/12/31 | 12224 | macros/luatex/generic/luaotfload/luaotfload-notdef.lua -2020/12/31 | 30999 | macros/luatex/generic/luaotfload/luaotfload-parsers.lua -2020/12/31 | 10984 | macros/luatex/generic/luaotfload/luaotfload-resolvers.lua -2020/12/31 | 2506 | macros/luatex/generic/luaotfload/luaotfload-scripts.lua -2020/12/31 | 6325 | macros/luatex/generic/luaotfload/luaotfload-status.lua -2020/12/31 | 1812 | macros/luatex/generic/luaotfload/luaotfload.sty -2020/12/31 | 2582 | macros/luatex/generic/luaotfload/luaotfload-suppress.lua -2020/12/31 | 6259 | macros/luatex/generic/luaotfload/luaotfload-szss.lua -2020/12/31 | 12707 | macros/luatex/generic/luaotfload/luaotfload-tool.1 -2020/12/31 | 52203 | macros/luatex/generic/luaotfload/luaotfload-tool.lua -2020/12/31 | 76773 | macros/luatex/generic/luaotfload/luaotfload-tool.pdf -2020/12/31 | 15940 | macros/luatex/generic/luaotfload/luaotfload-tool.rst -2020/12/31 | 7528 | macros/luatex/generic/luaotfload/luaotfload-tounicode.lua -2020/12/31 | 7589 | macros/luatex/generic/luaotfload/luaotfload-unicode.lua -2020/12/31 | 19847 | macros/luatex/generic/luaotfload/NEWS -2020/12/31 | 3784 | macros/luatex/generic/luaotfload/README.md -2020/12/31 | 21696 | macros/luatex/generic/luaotfload/scripts-demo.pdf -2019/12/25 | 699 | macros/luatex/generic/luaotfload/scripts-demo.tex -2020/12/31 | 8566 | macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf -2019/12/25 | 191 | macros/luatex/generic/luaotfload/shaper-demo-graphite.tex -2020/12/31 | 8486 | macros/luatex/generic/luaotfload/shaper-demo.pdf -2019/12/25 | 182 | macros/luatex/generic/luaotfload/shaper-demo.tex -2020/12/31 | 1927005 | macros/luatex/generic/luaotfload.zip +2021/01/16 | 18714 | macros/luatex/generic/luaotfload/COPYING +2021/01/16 | 41362 | macros/luatex/generic/luaotfload/filegraph.pdf +2021/01/16 | 8597 | macros/luatex/generic/luaotfload/filegraph.tex +2021/01/16 | 863258 | macros/luatex/generic/luaotfload/fontloader-2021-01-07.lua +2021/01/16 | 46091 | macros/luatex/generic/luaotfload/fontloader-basics-chr.lua +2021/01/16 | 12745 | macros/luatex/generic/luaotfload/fontloader-basics-gen.lua +2021/01/16 | 10064 | macros/luatex/generic/luaotfload/fontloader-basics-nod.lua +2021/01/16 | 5388 | macros/luatex/generic/luaotfload/fontloader-data-con.lua +2021/01/16 | 6866 | macros/luatex/generic/luaotfload/fontloader-font-afk.lua +2021/01/16 | 90063 | macros/luatex/generic/luaotfload/fontloader-font-cff.lua +2021/01/16 | 5502 | macros/luatex/generic/luaotfload/fontloader-font-cid.lua +2021/01/16 | 63211 | macros/luatex/generic/luaotfload/fontloader-font-con.lua +2021/01/16 | 19944 | macros/luatex/generic/luaotfload/fontloader-font-def.lua +2021/01/16 | 154135 | macros/luatex/generic/luaotfload/fontloader-font-dsp.lua +2021/01/16 | 13977 | macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua +2021/01/16 | 3693 | macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua +2021/01/16 | 3580 | macros/luatex/generic/luaotfload/fontloader-font-imp-ligatures.lua +2021/01/16 | 3406 | macros/luatex/generic/luaotfload/fontloader-font-imp-tex.lua +2021/01/16 | 1794 | macros/luatex/generic/luaotfload/fontloader-font-ini.lua +2021/01/16 | 1449 | macros/luatex/generic/luaotfload/fontloader-font-lua.lua +2021/01/16 | 19570 | macros/luatex/generic/luaotfload/fontloader-font-map.lua +2021/01/16 | 24566 | macros/luatex/generic/luaotfload/fontloader-font-ocl.lua +2021/01/16 | 31298 | macros/luatex/generic/luaotfload/fontloader-font-one.lua +2021/01/16 | 18717 | macros/luatex/generic/luaotfload/fontloader-font-onr.lua +2021/01/16 | 107580 | macros/luatex/generic/luaotfload/fontloader-font-osd.lua +2021/01/16 | 18421 | macros/luatex/generic/luaotfload/fontloader-font-ota.lua +2021/01/16 | 31802 | macros/luatex/generic/luaotfload/fontloader-font-otc.lua +2021/01/16 | 7904 | macros/luatex/generic/luaotfload/fontloader-font-oti.lua +2021/01/16 | 65656 | macros/luatex/generic/luaotfload/fontloader-font-otj.lua +2021/01/16 | 33035 | macros/luatex/generic/luaotfload/fontloader-font-otl.lua +2021/01/16 | 22966 | macros/luatex/generic/luaotfload/fontloader-font-oto.lua +2021/01/16 | 94470 | macros/luatex/generic/luaotfload/fontloader-font-otr.lua +2021/01/16 | 182126 | macros/luatex/generic/luaotfload/fontloader-font-ots.lua +2021/01/16 | 34862 | macros/luatex/generic/luaotfload/fontloader-font-ott.lua +2021/01/16 | 117724 | macros/luatex/generic/luaotfload/fontloader-font-oup.lua +2021/01/16 | 3821 | macros/luatex/generic/luaotfload/fontloader-fonts-def.lua +2021/01/16 | 2315 | macros/luatex/generic/luaotfload/fontloader-fonts-enc.lua +2021/01/16 | 7260 | macros/luatex/generic/luaotfload/fontloader-fonts-ext.lua +2021/01/16 | 9875 | macros/luatex/generic/luaotfload/fontloader-fonts-gbn.lua +2021/01/16 | 13500 | macros/luatex/generic/luaotfload/fontloader-font-shp.lua +2021/01/16 | 57342 | macros/luatex/generic/luaotfload/fontloader-fonts-lig.lua +2021/01/16 | 912 | macros/luatex/generic/luaotfload/fontloader-fonts-mis.lua +2021/01/16 | 3674 | macros/luatex/generic/luaotfload/fontloader-fonts-syn.lua +2021/01/16 | 23399 | macros/luatex/generic/luaotfload/fontloader-fonts-tfm.lua +2021/01/16 | 59344 | macros/luatex/generic/luaotfload/fontloader-font-ttf.lua +2021/01/16 | 2667 | macros/luatex/generic/luaotfload/fontloader-font-vfc.lua +2021/01/16 | 1850 | macros/luatex/generic/luaotfload/fontloader-l-boolean.lua +2021/01/16 | 22175 | macros/luatex/generic/luaotfload/fontloader-l-file.lua +2021/01/16 | 361 | macros/luatex/generic/luaotfload/fontloader-l-function.lua +2021/01/16 | 11829 | macros/luatex/generic/luaotfload/fontloader-l-io.lua +2021/01/16 | 38703 | macros/luatex/generic/luaotfload/fontloader-l-lpeg.lua +2021/01/16 | 6405 | macros/luatex/generic/luaotfload/fontloader-l-lua.lua +2021/01/16 | 2555 | macros/luatex/generic/luaotfload/fontloader-l-math.lua +2021/01/16 | 6644 | macros/luatex/generic/luaotfload/fontloader-l-string.lua +2021/01/16 | 41758 | macros/luatex/generic/luaotfload/fontloader-l-table.lua +2021/01/16 | 41303 | macros/luatex/generic/luaotfload/fontloader-l-unicode.lua +2021/01/16 | 15196 | macros/luatex/generic/luaotfload/fontloader-reference-load-order.lua +2021/01/16 | 5885 | macros/luatex/generic/luaotfload/fontloader-reference-load-order.tex +2021/01/16 | 964175 | macros/luatex/generic/luaotfload/fontloader-reference.lua +2021/01/16 | 11552 | macros/luatex/generic/luaotfload/fontloader-util-fil.lua +2021/01/16 | 43947 | macros/luatex/generic/luaotfload/fontloader-util-str.lua +2021/01/16 | 32597 | macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua +2021/01/16 | 52 | macros/luatex/generic/luaotfload/luaotfload-blacklist.cnf +2021/01/16 | 8121 | macros/luatex/generic/luaotfload/luaotfload-case-el.lua +2021/01/16 | 6809 | macros/luatex/generic/luaotfload/luaotfload-case.lua +2021/01/16 | 3287334 | macros/luatex/generic/luaotfload/luaotfload-characters.lua +2021/01/16 | 15954 | macros/luatex/generic/luaotfload/luaotfload-colors.lua +2021/01/16 | 16548 | macros/luatex/generic/luaotfload/luaotfload.conf.5 +2021/01/16 | 735 | macros/luatex/generic/luaotfload/luaotfload.conf.example +2021/01/16 | 31151 | macros/luatex/generic/luaotfload/luaotfload-configuration.lua +2021/01/16 | 78522 | macros/luatex/generic/luaotfload/luaotfload-conf.pdf +2021/01/16 | 18074 | macros/luatex/generic/luaotfload/luaotfload.conf.rst +2021/01/16 | 134863 | macros/luatex/generic/luaotfload/luaotfload-database.lua +2021/01/16 | 21857 | macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua +2021/01/16 | 4956 | macros/luatex/generic/luaotfload/luaotfload-dvi.lua +2021/01/16 | 1004 | macros/luatex/generic/luaotfload/luaotfload-embolden.lua +2021/01/16 | 8188 | macros/luatex/generic/luaotfload/luaotfload-fakesc.lua +2021/01/16 | 4047 | macros/luatex/generic/luaotfload/luaotfload-fallback.lua +2021/01/16 | 29002 | macros/luatex/generic/luaotfload/luaotfload-features.lua +2021/01/16 | 25336 | macros/luatex/generic/luaotfload/luaotfload-filelist.lua +2021/01/16 | 102502 | macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua +2021/01/16 | 13468 | macros/luatex/generic/luaotfload/luaotfload-harf-define.lua +2021/01/16 | 41599 | macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua +2021/01/16 | 19547 | macros/luatex/generic/luaotfload/luaotfload-init.lua +2021/01/16 | 501958 | macros/luatex/generic/luaotfload/luaotfload-latex.pdf +2021/01/16 | 16675 | macros/luatex/generic/luaotfload/luaotfload-latex.tex +2021/01/16 | 18645 | macros/luatex/generic/luaotfload/luaotfload-letterspace.lua +2021/01/16 | 8840 | macros/luatex/generic/luaotfload/luaotfload-loaders.lua +2021/01/16 | 11323 | macros/luatex/generic/luaotfload/luaotfload-log.lua +2021/01/16 | 13788 | macros/luatex/generic/luaotfload/luaotfload.lua +2021/01/16 | 275 | macros/luatex/generic/luaotfload/luaotfload-main.lua +2021/01/16 | 98948 | macros/luatex/generic/luaotfload/luaotfload-main.tex +2021/01/16 | 15068 | macros/luatex/generic/luaotfload/luaotfload-multiscript.lua +2021/01/16 | 12224 | macros/luatex/generic/luaotfload/luaotfload-notdef.lua +2021/01/16 | 30999 | macros/luatex/generic/luaotfload/luaotfload-parsers.lua +2021/01/16 | 10984 | macros/luatex/generic/luaotfload/luaotfload-resolvers.lua +2021/01/16 | 2506 | macros/luatex/generic/luaotfload/luaotfload-scripts.lua +2021/01/16 | 6317 | macros/luatex/generic/luaotfload/luaotfload-status.lua +2021/01/16 | 1812 | macros/luatex/generic/luaotfload/luaotfload.sty +2021/01/16 | 2582 | macros/luatex/generic/luaotfload/luaotfload-suppress.lua +2021/01/16 | 6259 | macros/luatex/generic/luaotfload/luaotfload-szss.lua +2021/01/16 | 12707 | macros/luatex/generic/luaotfload/luaotfload-tool.1 +2021/01/16 | 52203 | macros/luatex/generic/luaotfload/luaotfload-tool.lua +2021/01/16 | 78960 | macros/luatex/generic/luaotfload/luaotfload-tool.pdf +2021/01/16 | 15940 | macros/luatex/generic/luaotfload/luaotfload-tool.rst +2021/01/16 | 7528 | macros/luatex/generic/luaotfload/luaotfload-tounicode.lua +2021/01/16 | 7589 | macros/luatex/generic/luaotfload/luaotfload-unicode.lua +2021/01/16 | 20031 | macros/luatex/generic/luaotfload/NEWS +2021/01/16 | 3784 | macros/luatex/generic/luaotfload/README.md +2021/01/16 | 21837 | macros/luatex/generic/luaotfload/scripts-demo.pdf +2021/01/16 | 699 | macros/luatex/generic/luaotfload/scripts-demo.tex +2021/01/16 | 8559 | macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf +2021/01/16 | 191 | macros/luatex/generic/luaotfload/shaper-demo-graphite.tex +2021/01/16 | 8479 | macros/luatex/generic/luaotfload/shaper-demo.pdf +2021/01/16 | 182 | macros/luatex/generic/luaotfload/shaper-demo.tex +2021/01/16 | 1946587 | macros/luatex/generic/luaotfload.zip 2019/12/22 | 2475 | macros/luatex/generic/luapackageloader/luapackageloader.lua 2019/12/22 | 33904 | macros/luatex/generic/luapackageloader/luapackageloader.pdf 2019/12/22 | 1014 | macros/luatex/generic/luapackageloader/luapackageloader.sty @@ -261143,7 +261198,7 @@ 2020/05/29 | 1224 | systems/texlive/tlnet/archive/collection-bibtexextra.r55339.tar.xz 2020/09/16 | 944 | systems/texlive/tlnet/archive/collection-binextra.r56352.tar.xz 2020/03/04 | 596 | systems/texlive/tlnet/archive/collection-context.r54074.tar.xz -2021/01/13 | 1888 | systems/texlive/tlnet/archive/collection-fontsextra.r57399.tar.xz +2021/01/16 | 1892 | systems/texlive/tlnet/archive/collection-fontsextra.r57429.tar.xz 2020/03/04 | 560 | systems/texlive/tlnet/archive/collection-fontsrecommended.r54074.tar.xz 2020/12/08 | 528 | systems/texlive/tlnet/archive/collection-fontutils.r57089.tar.xz 2020/03/04 | 568 | systems/texlive/tlnet/archive/collection-formatsextra.r54074.tar.xz @@ -262489,8 +262544,8 @@ 2019/02/28 | 1788 | systems/texlive/tlnet/archive/ean13isbn.r15878.tar.xz 2019/02/28 | 948 | systems/texlive/tlnet/archive/ean.doc.r20851.tar.xz 2019/02/28 | 3148 | systems/texlive/tlnet/archive/ean.r20851.tar.xz -2021/01/15 | 526796 | systems/texlive/tlnet/archive/easybook.doc.r57418.tar.xz -2021/01/15 | 9956 | systems/texlive/tlnet/archive/easybook.r57418.tar.xz +2021/01/16 | 527376 | systems/texlive/tlnet/archive/easybook.doc.r57431.tar.xz +2021/01/16 | 9824 | systems/texlive/tlnet/archive/easybook.r57431.tar.xz 2019/02/28 | 4540 | systems/texlive/tlnet/archive/easy.doc.r19440.tar.xz 2020/09/08 | 175976 | systems/texlive/tlnet/archive/easyfig.doc.r56291.tar.xz 2020/09/08 | 1936 | systems/texlive/tlnet/archive/easyfig.r56291.tar.xz @@ -263126,9 +263181,9 @@ 2019/02/28 | 635448 | systems/texlive/tlnet/archive/fcltxdoc.doc.r24500.tar.xz 2019/02/28 | 10404 | systems/texlive/tlnet/archive/fcltxdoc.r24500.tar.xz 2019/02/28 | 21560 | systems/texlive/tlnet/archive/fcltxdoc.source.r24500.tar.xz -2019/05/03 | 282276 | systems/texlive/tlnet/archive/fcolumn.doc.r50937.tar.xz -2019/05/03 | 3720 | systems/texlive/tlnet/archive/fcolumn.r50937.tar.xz -2019/05/03 | 18300 | systems/texlive/tlnet/archive/fcolumn.source.r50937.tar.xz +2021/01/16 | 319588 | systems/texlive/tlnet/archive/fcolumn.doc.r57428.tar.xz +2021/01/16 | 4376 | systems/texlive/tlnet/archive/fcolumn.r57428.tar.xz +2021/01/16 | 21252 | systems/texlive/tlnet/archive/fcolumn.source.r57428.tar.xz 2019/02/28 | 128300 | systems/texlive/tlnet/archive/fc.r32796.tar.xz 2019/02/28 | 461572 | systems/texlive/tlnet/archive/fdsymbol.doc.r26722.tar.xz 2019/02/28 | 920220 | systems/texlive/tlnet/archive/fdsymbol.r26722.tar.xz @@ -265970,9 +266025,9 @@ 2019/02/28 | 5636 | systems/texlive/tlnet/archive/manuscript.source.r36110.tar.xz 2019/02/28 | 157580 | systems/texlive/tlnet/archive/manyind.doc.r49874.tar.xz 2019/02/28 | 2900 | systems/texlive/tlnet/archive/manyind.r49874.tar.xz -2020/10/28 | 119856 | systems/texlive/tlnet/archive/marathi.doc.r56781.tar.xz -2020/10/28 | 4492 | systems/texlive/tlnet/archive/marathi.r56781.tar.xz -2020/10/28 | 8584 | systems/texlive/tlnet/archive/marathi.source.r56781.tar.xz +2021/01/16 | 184044 | systems/texlive/tlnet/archive/marathi.doc.r57432.tar.xz +2021/01/16 | 5240 | systems/texlive/tlnet/archive/marathi.r57432.tar.xz +2021/01/16 | 17536 | systems/texlive/tlnet/archive/marathi.source.r57432.tar.xz 2020/08/02 | 19864 | systems/texlive/tlnet/archive/marcellus.doc.r56016.tar.xz 2020/08/02 | 178120 | systems/texlive/tlnet/archive/marcellus.r56016.tar.xz 2019/02/28 | 188416 | systems/texlive/tlnet/archive/margbib.doc.r15878.tar.xz @@ -267005,6 +267060,8 @@ 2019/02/28 | 42884 | systems/texlive/tlnet/archive/numprint.source.r27498.tar.xz 2020/11/12 | 226176 | systems/texlive/tlnet/archive/numspell.doc.r56912.tar.xz 2020/11/12 | 8856 | systems/texlive/tlnet/archive/numspell.r56912.tar.xz +2021/01/16 | 182360 | systems/texlive/tlnet/archive/nunito.doc.r57429.tar.xz +2021/01/16 | 4627580 | systems/texlive/tlnet/archive/nunito.r57429.tar.xz 2020/03/19 | 1557288 | systems/texlive/tlnet/archive/nwejm.doc.r54392.tar.xz 2020/03/19 | 4059912 | systems/texlive/tlnet/archive/nwejm.r54392.tar.xz 2020/03/19 | 46916 | systems/texlive/tlnet/archive/nwejm.source.r54392.tar.xz @@ -268048,8 +268105,8 @@ 2019/02/28 | 5448 | systems/texlive/tlnet/archive/psizzl.doc.r15878.tar.xz 2019/02/28 | 23084 | systems/texlive/tlnet/archive/psizzl.r15878.tar.xz 2019/02/28 | 640 | systems/texlive/tlnet/archive/psizzl.source.r15878.tar.xz -2019/02/28 | 5748 | systems/texlive/tlnet/archive/pslatex.r16416.tar.xz -2019/02/28 | 1204 | systems/texlive/tlnet/archive/pslatex.source.r16416.tar.xz +2021/01/16 | 5824 | systems/texlive/tlnet/archive/pslatex.r57434.tar.xz +2021/01/16 | 1200 | systems/texlive/tlnet/archive/pslatex.source.r57434.tar.xz 2020/04/13 | 260860 | systems/texlive/tlnet/archive/psnfss.doc.r54694.tar.xz 2020/04/13 | 11936 | systems/texlive/tlnet/archive/psnfss.r54694.tar.xz 2020/04/13 | 8176 | systems/texlive/tlnet/archive/psnfss.source.r54694.tar.xz @@ -268595,8 +268652,8 @@ 2020/09/08 | 13580 | systems/texlive/tlnet/archive/rcs-multi.source.r56291.tar.xz 2019/02/28 | 12512 | systems/texlive/tlnet/archive/rcs.r15878.tar.xz 2019/02/28 | 23544 | systems/texlive/tlnet/archive/rcs.source.r15878.tar.xz -2020/05/18 | 166356 | systems/texlive/tlnet/archive/readablecv.doc.r55190.tar.xz -2020/05/18 | 3636 | systems/texlive/tlnet/archive/readablecv.r55190.tar.xz +2021/01/16 | 207536 | systems/texlive/tlnet/archive/readablecv.doc.r57433.tar.xz +2021/01/16 | 3896 | systems/texlive/tlnet/archive/readablecv.r57433.tar.xz 2019/02/28 | 487380 | systems/texlive/tlnet/archive/readarray.doc.r42467.tar.xz 2019/02/28 | 4252 | systems/texlive/tlnet/archive/readarray.r42467.tar.xz 2020/09/08 | 175812 | systems/texlive/tlnet/archive/realboxes.doc.r56291.tar.xz @@ -269382,11 +269439,11 @@ 2019/03/21 | 495572 | systems/texlive/tlnet/archive/stex.source.r50489.tar.xz 2020/12/22 | 557228 | systems/texlive/tlnet/archive/stickstoo.doc.r57193.tar.xz 2020/12/22 | 2667960 | systems/texlive/tlnet/archive/stickstoo.r57193.tar.xz -2020/03/04 | 1780248 | systems/texlive/tlnet/archive/stix2-otf.doc.r54080.tar.xz -2020/03/04 | 686984 | systems/texlive/tlnet/archive/stix2-otf.r54080.tar.xz -2020/03/24 | 1331724 | systems/texlive/tlnet/archive/stix2-type1.doc.r54512.tar.xz -2020/03/24 | 3171312 | systems/texlive/tlnet/archive/stix2-type1.r54512.tar.xz -2020/03/24 | 28004 | systems/texlive/tlnet/archive/stix2-type1.source.r54512.tar.xz +2021/01/16 | 1219820 | systems/texlive/tlnet/archive/stix2-otf.doc.r57427.tar.xz +2021/01/16 | 1383744 | systems/texlive/tlnet/archive/stix2-otf.r57427.tar.xz +2021/01/16 | 1393064 | systems/texlive/tlnet/archive/stix2-type1.doc.r57430.tar.xz +2021/01/16 | 3109488 | systems/texlive/tlnet/archive/stix2-type1.r57430.tar.xz +2021/01/16 | 28080 | systems/texlive/tlnet/archive/stix2-type1.source.r57430.tar.xz 2020/03/24 | 1838228 | systems/texlive/tlnet/archive/stix.doc.r54512.tar.xz 2020/03/24 | 2595396 | systems/texlive/tlnet/archive/stix.r54512.tar.xz 2020/03/24 | 27808 | systems/texlive/tlnet/archive/stix.source.r54512.tar.xz @@ -269991,7 +270048,7 @@ 2020/05/17 | 592 | systems/texlive/tlnet/archive/texlive-scripts.amd64-freebsd.r55172.tar.xz 2020/05/17 | 588 | systems/texlive/tlnet/archive/texlive-scripts.amd64-netbsd.r55172.tar.xz 2020/05/17 | 592 | systems/texlive/tlnet/archive/texlive-scripts.armhf-linux.r55172.tar.xz -2021/01/14 | 218820 | systems/texlive/tlnet/archive/texlive-scripts.doc.r57407.tar.xz +2021/01/16 | 218820 | systems/texlive/tlnet/archive/texlive-scripts.doc.r57423.tar.xz 2020/01/27 | 916 | systems/texlive/tlnet/archive/texlive-scripts-extra.aarch64-linux.r53577.tar.xz 2020/01/27 | 924 | systems/texlive/tlnet/archive/texlive-scripts-extra.amd64-freebsd.r53577.tar.xz 2020/01/27 | 916 | systems/texlive/tlnet/archive/texlive-scripts-extra.amd64-netbsd.r53577.tar.xz @@ -270015,7 +270072,7 @@ 2020/05/17 | 588 | systems/texlive/tlnet/archive/texlive-scripts.i386-linux.r55172.tar.xz 2020/05/17 | 592 | systems/texlive/tlnet/archive/texlive-scripts.i386-netbsd.r55172.tar.xz 2020/05/17 | 588 | systems/texlive/tlnet/archive/texlive-scripts.i386-solaris.r55172.tar.xz -2021/01/14 | 132172 | systems/texlive/tlnet/archive/texlive-scripts.r57407.tar.xz +2021/01/16 | 132192 | systems/texlive/tlnet/archive/texlive-scripts.r57423.tar.xz 2020/08/24 | 36336 | systems/texlive/tlnet/archive/texlive-scripts.win32.r56157.tar.xz 2020/05/17 | 588 | systems/texlive/tlnet/archive/texlive-scripts.x86_64-cygwin.r55172.tar.xz 2020/05/12 | 592 | systems/texlive/tlnet/archive/texlive-scripts.x86_64-darwinlegacy.r55117.tar.xz @@ -270484,13 +270541,13 @@ 2019/07/06 | 344 | systems/texlive/tlnet/archive/tlshell.amd64-freebsd.r45015.tar.xz 2019/07/06 | 340 | systems/texlive/tlnet/archive/tlshell.amd64-netbsd.r45015.tar.xz 2019/07/06 | 340 | systems/texlive/tlnet/archive/tlshell.armhf-linux.r45015.tar.xz -2020/09/29 | 440 | systems/texlive/tlnet/archive/tlshell.doc.r56461.tar.xz +2021/01/16 | 440 | systems/texlive/tlnet/archive/tlshell.doc.r57426.tar.xz 2019/07/06 | 340 | systems/texlive/tlnet/archive/tlshell.i386-cygwin.r45015.tar.xz 2019/07/06 | 340 | systems/texlive/tlnet/archive/tlshell.i386-freebsd.r45015.tar.xz 2019/07/06 | 340 | systems/texlive/tlnet/archive/tlshell.i386-linux.r45015.tar.xz 2019/07/06 | 340 | systems/texlive/tlnet/archive/tlshell.i386-netbsd.r45015.tar.xz 2019/07/06 | 340 | systems/texlive/tlnet/archive/tlshell.i386-solaris.r45015.tar.xz -2020/09/29 | 26836 | systems/texlive/tlnet/archive/tlshell.r56461.tar.xz +2021/01/16 | 27380 | systems/texlive/tlnet/archive/tlshell.r57426.tar.xz 2020/03/19 | 2660792 | systems/texlive/tlnet/archive/tlshell.win32.r54395.tar.xz 2019/07/06 | 340 | systems/texlive/tlnet/archive/tlshell.x86_64-cygwin.r45015.tar.xz 2019/07/06 | 348 | systems/texlive/tlnet/archive/tlshell.x86_64-darwinlegacy.r45015.tar.xz @@ -271677,16 +271734,16 @@ 2020/07/18 | 47816 | systems/texlive/tlnet/archive/zztex.doc.r55862.tar.xz 2020/07/18 | 101724 | systems/texlive/tlnet/archive/zztex.r55862.tar.xz 2021/01/06 | 106039 | systems/texlive/tlnet/install-tl -2021/01/15 | 5517800 | systems/texlive/tlnet/install-tl-unx.tar.gz -2021/01/15 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512 -2021/01/15 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc +2021/01/16 | 5518083 | systems/texlive/tlnet/install-tl-unx.tar.gz +2021/01/16 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512 +2021/01/16 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc 2020/08/23 | 4889 | systems/texlive/tlnet/install-tl-windows.bat -2021/01/15 | 19416638 | systems/texlive/tlnet/install-tl-windows.exe -2021/01/15 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512 -2021/01/15 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc -2021/01/15 | 24287700 | systems/texlive/tlnet/install-tl.zip -2021/01/15 | 145 | systems/texlive/tlnet/install-tl.zip.sha512 -2021/01/15 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc +2021/01/16 | 19418459 | systems/texlive/tlnet/install-tl-windows.exe +2021/01/16 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512 +2021/01/16 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc +2021/01/16 | 24287717 | systems/texlive/tlnet/install-tl.zip +2021/01/16 | 145 | systems/texlive/tlnet/install-tl.zip.sha512 +2021/01/16 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc 2020/03/05 | 1215 | systems/texlive/tlnet/README.md 2020/04/06 | 5961 | systems/texlive/tlnet/tlpkg/gpg/pubring.gpg 2016/04/12 | 600 | systems/texlive/tlnet/tlpkg/gpg/random_seed @@ -271695,7 +271752,7 @@ 2020/04/06 | 1280 | systems/texlive/tlnet/tlpkg/gpg/trustdb.gpg 2021/01/07 | 49448 | systems/texlive/tlnet/tlpkg/installer/config.guess 2010/11/11 | 11651 | systems/texlive/tlnet/tlpkg/installer/COPYING.MinGW-runtime.txt -2021/01/13 | 6610 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl +2021/01/15 | 6657 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl 2020/04/15 | 223687 | systems/texlive/tlnet/tlpkg/installer/curl/curl-ca-bundle.crt 2020/04/15 | 2606592 | systems/texlive/tlnet/tlpkg/installer/curl/curl.exe 2018/04/29 | 13647 | systems/texlive/tlnet/tlpkg/installer/DirSelect.pm @@ -271742,12 +271799,12 @@ 2020/05/17 | 20322 | systems/texlive/tlnet/tlpkg/TeXLive/TLCrypto.pm 2020/05/03 | 4786 | systems/texlive/tlnet/tlpkg/TeXLive/TLDownload.pm 2020/09/22 | 27563 | systems/texlive/tlnet/tlpkg/TeXLive/TLPaper.pm -2021/01/15 | 16933239 | systems/texlive/tlnet/tlpkg/texlive.tlpdb -2021/01/15 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 +2021/01/16 | 16960516 | systems/texlive/tlnet/tlpkg/texlive.tlpdb +2021/01/16 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 2020/05/13 | 86417 | systems/texlive/tlnet/tlpkg/TeXLive/TLPDB.pm -2021/01/15 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 -2021/01/15 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc -2021/01/15 | 2267500 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz +2021/01/16 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 +2021/01/16 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc +2021/01/16 | 2267336 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz 2020/04/15 | 58761 | systems/texlive/tlnet/tlpkg/TeXLive/TLPOBJ.pm 2020/03/20 | 41736 | systems/texlive/tlnet/tlpkg/TeXLive/TLPSRC.pm 2020/05/11 | 15010 | systems/texlive/tlnet/tlpkg/TeXLive/TLTREE.pm @@ -274390,7 +274447,7 @@ 2020/03/17 | 26075 | systems/texlive/tlnet/tlpkg/tltcl/lib/tk8.6/xmfbox.tcl 2020/03/17 | 3466 | systems/texlive/tlnet/tlpkg/tltcl/lib/tkConfig.sh 2018/11/30 | 1310 | systems/texlive/tlnet/tlpkg/tltcl/tlmgr.gif -2020/05/31 | 22132 | systems/texlive/tlnet/tlpkg/tltcl/tltcl.tcl +2021/01/15 | 22142 | systems/texlive/tlnet/tlpkg/tltcl/tltcl.tcl 2021/01/13 | 87013 | systems/texlive/tlnet/tlpkg/translations/cs.po 2021/01/13 | 95538 | systems/texlive/tlnet/tlpkg/translations/de.po 2021/01/13 | 86051 | systems/texlive/tlnet/tlpkg/translations/es.po @@ -279345,7 +279402,7 @@ 2021/01/13 | 5177516 | systems/win32/w32tex/aleph-w32.tar.xz 2021/01/10 | 66729544 | systems/win32/w32tex/biblatex-biber.tar.xz 2016/12/13 | 65971452 | systems/win32/w32tex/cbfonts.tar.xz -2021/01/14 | 768354 | systems/win32/w32tex/ChangeLog +2021/01/15 | 768755 | systems/win32/w32tex/ChangeLog 2009/08/03 | 141221 | systems/win32/w32tex/ChangeLog.0 2009/08/03 | 221890 | systems/win32/w32tex/ChangeLog.1 2009/08/03 | 116462 | systems/win32/w32tex/ChangeLog.2 @@ -279358,7 +279415,7 @@ 2020/09/21 | 6434128 | systems/win32/w32tex/datetime2.tar.xz 2021/01/13 | 844644 | systems/win32/w32tex/dvi2ps-w32.tar.xz 2021/01/13 | 484204 | systems/win32/w32tex/dvi2tty-w32.tar.xz -2021/01/13 | 4661312 | systems/win32/w32tex/dvipdfm-w32.tar.xz +2021/01/15 | 4662812 | systems/win32/w32tex/dvipdfm-w32.tar.xz 2021/01/13 | 4550868 | systems/win32/w32tex/dvipsk-w32.tar.xz 2021/01/13 | 2653592 | systems/win32/w32tex/dvitools-w32.tar.xz 2021/01/03 | 1179164 | systems/win32/w32tex/extractpdfmark-w32.tar.xz @@ -279369,7 +279426,7 @@ 2021/01/09 | 34772856 | systems/win32/w32tex/latex.tar.xz 2020/12/05 | 1008204 | systems/win32/w32tex/lcdf-typetools-w32.tar.xz 2020/12/18 | 403185380 | systems/win32/w32tex/ltxpkgdocs.tar.xz -2021/01/14 | 33953364 | systems/win32/w32tex/ltxpkgs.tar.xz +2021/01/15 | 33953568 | systems/win32/w32tex/ltxpkgs.tar.xz 2021/01/02 | 3852596 | systems/win32/w32tex/luajittex-dev-w32.tar.xz 2021/01/14 | 3865560 | systems/win32/w32tex/luajittex-exp-w32.tar.xz 2021/01/01 | 3859460 | systems/win32/w32tex/luajittex-w32.tar.xz @@ -279395,7 +279452,7 @@ 2020/12/05 | 1171272 | systems/win32/w32tex/pstoedit-w32.tar.xz 2020/10/25 | 274208000 | systems/win32/w32tex/pstricks.tar.xz 2021/01/13 | 517756 | systems/win32/w32tex/psutils-w32.tar.xz -2021/01/10 | 6622084 | systems/win32/w32tex/ptex-ng-w32.tar.xz +2021/01/15 | 6620960 | systems/win32/w32tex/ptex-ng-w32.tar.xz 2021/01/13 | 10633792 | systems/win32/w32tex/ptex-w32.tar.xz 2019/04/15 | 499188 | systems/win32/w32tex/sam2p-w32.tar.xz 2020/10/14 | 87958692 | systems/win32/w32tex/t1fonts.tar.xz @@ -279432,7 +279489,7 @@ 2021/01/13 | 440824 | systems/win32/w32tex/win64/cweb-w64.tar.xz 2021/01/13 | 758912 | systems/win32/w32tex/win64/dvi2ps-w64.tar.xz 2021/01/13 | 448292 | systems/win32/w32tex/win64/dvi2tty-w64.tar.xz -2021/01/13 | 807348 | systems/win32/w32tex/win64/dvipdfm-w64.tar.xz +2021/01/15 | 807960 | systems/win32/w32tex/win64/dvipdfm-w64.tar.xz 2021/01/13 | 760100 | systems/win32/w32tex/win64/dvipsk-w64.tar.xz 2021/01/13 | 2345592 | systems/win32/w32tex/win64/dvitools-w64.tar.xz 2021/01/03 | 1090564 | systems/win32/w32tex/win64/extractpdfmark-w64.tar.xz @@ -279457,7 +279514,7 @@ 2020/03/20 | 557532 | systems/win32/w32tex/win64/pmx-w64.tar.xz 2020/12/05 | 791172 | systems/win32/w32tex/win64/pstoedit-w64.tar.xz 2021/01/13 | 386240 | systems/win32/w32tex/win64/psutils-w64.tar.xz -2021/01/10 | 1712960 | systems/win32/w32tex/win64/ptex-ng-w64.tar.xz +2021/01/15 | 1714096 | systems/win32/w32tex/win64/ptex-ng-w64.tar.xz 2021/01/13 | 1871404 | systems/win32/w32tex/win64/ptex-w64.tar.xz 2021/01/03 | 329592 | systems/win32/w32tex/win64/sam2p-w64.tar.xz 2020/10/31 | 40588 | systems/win32/w32tex/win64/t1utils-w64.tar.xz @@ -279468,8 +279525,8 @@ 2020/01/18 | 42768 | systems/win32/w32tex/win64/txtutil-w64.tar.xz 2021/01/13 | 1805768 | systems/win32/w32tex/win64/uptex-w64.tar.xz 2021/01/13 | 3383744 | systems/win32/w32tex/win64/web2c-w64.tar.xz -2021/01/13 | 11078840 | systems/win32/w32tex/win64/xetex-w64.tar.xz -2021/01/13 | 49089560 | systems/win32/w32tex/xetex-w32.tar.xz +2021/01/15 | 11079052 | systems/win32/w32tex/win64/xetex-w64.tar.xz +2021/01/15 | 49060056 | systems/win32/w32tex/xetex-w32.tar.xz 2020/05/29 | 2936068 | systems/win32/w32tex/xindy-w32.tar.xz 2013/11/19 | 11356248 | systems/win32/w32tex/xymtex.tar.xz 2016/09/09 | 4334636 | systems/win32/w32tex/xypic.tar.xz @@ -279566,7 +279623,7 @@ 2004/06/04 | 404 | tds/tds.sed 2004/06/23 | 65418 | tds/tds.tex 2019/05/29 | 304264 | tds.zip -2021/01/16 | 186 | timestamp +2021/01/17 | 186 | timestamp 2002/08/26 | 61898 | usergrps/dante/antrag.pdf 2002/08/26 | 118217 | usergrps/dante/antrag.ps 2017/06/30 | 917 | usergrps/dante/dtk/doc/beispiel.bib diff --git a/FILES.byname.gz b/FILES.byname.gz index 998469d1ea..023670bf36 100644 Binary files a/FILES.byname.gz and b/FILES.byname.gz differ diff --git a/FILES.last07days b/FILES.last07days index d5a55e7235..d444dbaffd 100644 --- a/FILES.last07days +++ b/FILES.last07days @@ -1,4 +1,262 @@ -2021/01/15 | 9956 | systems/texlive/tlnet/archive/easybook.r57418.tar.xz +2021/01/16 | 98948 | macros/luatex/generic/luaotfload/luaotfload-main.tex +2021/01/16 | 9886 | macros/latex/contrib/asmeconf/examples/asmeconf-lualatex-ode-example.tex +2021/01/16 | 9875 | macros/luatex/generic/luaotfload/fontloader-fonts-gbn.lua +2021/01/16 | 983 | macros/latex/contrib/acro/examples/acro.example.issue-119.tex +2021/01/16 | 9824 | systems/texlive/tlnet/archive/easybook.r57431.tar.xz +2021/01/16 | 964175 | macros/luatex/generic/luaotfload/fontloader-reference.lua +2021/01/16 | 9516 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-t1.tfm +2021/01/16 | 94470 | macros/luatex/generic/luaotfload/fontloader-font-otr.lua +2021/01/16 | 941 | fonts/alfaslabone/latex/TS1AlphaSlabOne-TLF.fd +2021/01/16 | 941 | fonts/alfaslabone/latex/OT1AlphaSlabOne-TLF.fd +2021/01/16 | 941 | fonts/alfaslabone/latex/OT1AlphaSlabOne-Sup.fd +2021/01/16 | 941 | fonts/alfaslabone/latex/LY1AlphaSlabOne-TLF.fd +2021/01/16 | 941 | fonts/alfaslabone/latex/LY1AlphaSlabOne-Sup.fd +2021/01/16 | 935 | fonts/alfaslabone/README +2021/01/16 | 935 | fonts/alfaslabone/latex/T1AlphaSlabOne-TLF.fd +2021/01/16 | 935 | fonts/alfaslabone/latex/T1AlphaSlabOne-Sup.fd +2021/01/16 | 912 | macros/luatex/generic/luaotfload/fontloader-fonts-mis.lua +2021/01/16 | 90063 | macros/luatex/generic/luaotfload/fontloader-font-cff.lua +2021/01/16 | 889312 | macros/latex/contrib/acro/acro-manual.pdf +2021/01/16 | 8840 | macros/luatex/generic/luaotfload/luaotfload-loaders.lua +2021/01/16 | 863258 | macros/luatex/generic/luaotfload/fontloader-2021-01-07.lua +2021/01/16 | 8597 | macros/luatex/generic/luaotfload/filegraph.tex +2021/01/16 | 8559 | macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf +2021/01/16 | 8479 | macros/luatex/generic/luaotfload/shaper-demo.pdf +2021/01/16 | 8188 | macros/luatex/generic/luaotfload/luaotfload-fakesc.lua +2021/01/16 | 8175 | macros/latex/contrib/acro/examples/acro.example.issue-119.pdf +2021/01/16 | 8121 | macros/luatex/generic/luaotfload/luaotfload-case-el.lua +2021/01/16 | 8040 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ly1.tfm +2021/01/16 | 796 | graphics/pgf/contrib/tikz-bbox/README.txt +2021/01/16 | 7904 | macros/luatex/generic/luaotfload/fontloader-font-oti.lua +2021/01/16 | 78960 | macros/luatex/generic/luaotfload/luaotfload-tool.pdf +2021/01/16 | 78522 | macros/luatex/generic/luaotfload/luaotfload-conf.pdf +2021/01/16 | 779 | macros/latex/contrib/acro/examples/acro.example.possessive.tex +2021/01/16 | 766 | graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.tex +2021/01/16 | 7609 | macros/latex/contrib/asmeconf/README.md +2021/01/16 | 7589 | macros/luatex/generic/luaotfload/luaotfload-unicode.lua +2021/01/16 | 757 | macros/latex/contrib/acro/examples/acro.example.texsx-542461.tex +2021/01/16 | 7528 | macros/luatex/generic/luaotfload/luaotfload-tounicode.lua +2021/01/16 | 735 | macros/luatex/generic/luaotfload/luaotfload.conf.example +2021/01/16 | 7260 | macros/luatex/generic/luaotfload/fontloader-fonts-ext.lua +2021/01/16 | 71644 | macros/latex/contrib/asmeconf/asmeconf.cls +2021/01/16 | 7119 | graphics/pgf/contrib/tikz-bbox/pgfmanual-en-library-bbox.tex +2021/01/16 | 706 | macros/latex/contrib/acro/examples/acro.example.issue-111.tex +2021/01/16 | 699 | macros/luatex/generic/luaotfload/scripts-demo.tex +2021/01/16 | 6866 | macros/luatex/generic/luaotfload/fontloader-font-afk.lua +2021/01/16 | 6809 | macros/luatex/generic/luaotfload/luaotfload-case.lua +2021/01/16 | 6644 | macros/luatex/generic/luaotfload/fontloader-l-string.lua +2021/01/16 | 65656 | macros/luatex/generic/luaotfload/fontloader-font-otj.lua +2021/01/16 | 65067 | macros/latex/contrib/acro/examples/acro.example.units.pdf +2021/01/16 | 6405 | macros/luatex/generic/luaotfload/fontloader-l-lua.lua +2021/01/16 | 63211 | macros/luatex/generic/luaotfload/fontloader-font-con.lua +2021/01/16 | 6317 | macros/luatex/generic/luaotfload/luaotfload-status.lua +2021/01/16 | 6259 | macros/luatex/generic/luaotfload/luaotfload-szss.lua +2021/01/16 | 5998 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-brazil.trsl +2021/01/16 | 5952 | graphics/pgf/contrib/tikz-bbox/pgflibrarybbox.code.tex +2021/01/16 | 59344 | macros/luatex/generic/luaotfload/fontloader-font-ttf.lua +2021/01/16 | 5885 | macros/luatex/generic/luaotfload/fontloader-reference-load-order.tex +2021/01/16 | 5856 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-spanish.trsl +2021/01/16 | 5824 | systems/texlive/tlnet/archive/pslatex.r57434.tar.xz +2021/01/16 | 5816 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-catalan.trsl +2021/01/16 | 57342 | macros/luatex/generic/luaotfload/fontloader-fonts-lig.lua +2021/01/16 | 5730 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-german.trsl +2021/01/16 | 5729 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-french.trsl +2021/01/16 | 5688 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-dutch.trsl +2021/01/16 | 5594 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-english.trsl +2021/01/16 | 5518083 | systems/texlive/tlnet/install-tl-unx.tar.gz +2021/01/16 | 5502 | macros/luatex/generic/luaotfload/fontloader-font-cid.lua +2021/01/16 | 548 | fonts/alfaslabone/vf/AlphaSlabOne-Regular-tlf-ts1.vf +2021/01/16 | 5388 | macros/luatex/generic/luaotfload/fontloader-data-con.lua +2021/01/16 | 52 | macros/luatex/generic/luaotfload/luaotfload-blacklist.cnf +2021/01/16 | 527376 | systems/texlive/tlnet/archive/easybook.doc.r57431.tar.xz +2021/01/16 | 5240 | systems/texlive/tlnet/archive/marathi.r57432.tar.xz +2021/01/16 | 523682 | macros/latex/contrib/translations.zip +2021/01/16 | 52203 | macros/luatex/generic/luaotfload/luaotfload-tool.lua +2021/01/16 | 501958 | macros/luatex/generic/luaotfload/luaotfload-latex.pdf +2021/01/16 | 496825 | macros/latex/contrib/translations/translations_en.pdf +2021/01/16 | 4956 | macros/luatex/generic/luaotfload/luaotfload-dvi.lua +2021/01/16 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 +2021/01/16 | 4823653 | fonts/stix2-type1.zip +2021/01/16 | 4627580 | systems/texlive/tlnet/archive/nunito.r57429.tar.xz +2021/01/16 | 46091 | macros/luatex/generic/luaotfload/fontloader-basics-chr.lua +2021/01/16 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc +2021/01/16 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc +2021/01/16 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc +2021/01/16 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc +2021/01/16 | 45547 | graphics/pxpic/pxpic.dtx +2021/01/16 | 4430 | fonts/alfaslabone/doc/LICENSE.TXT +2021/01/16 | 440 | systems/texlive/tlnet/archive/tlshell.doc.r57426.tar.xz +2021/01/16 | 44005 | macros/latex/contrib/translations/translations.sty +2021/01/16 | 43947 | macros/luatex/generic/luaotfload/fontloader-util-str.lua +2021/01/16 | 4376 | systems/texlive/tlnet/archive/fcolumn.r57428.tar.xz +2021/01/16 | 423 | fonts/alfaslabone/doc/alfaslabone-samples.tex +2021/01/16 | 41758 | macros/luatex/generic/luaotfload/fontloader-l-table.lua +2021/01/16 | 41599 | macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua +2021/01/16 | 41362 | macros/luatex/generic/luaotfload/filegraph.pdf +2021/01/16 | 41303 | macros/luatex/generic/luaotfload/fontloader-l-unicode.lua +2021/01/16 | 4047 | macros/luatex/generic/luaotfload/luaotfload-fallback.lua +2021/01/16 | 3896 | systems/texlive/tlnet/archive/readablecv.r57433.tar.xz +2021/01/16 | 38703 | macros/luatex/generic/luaotfload/fontloader-l-lpeg.lua +2021/01/16 | 3821 | macros/luatex/generic/luaotfload/fontloader-fonts-def.lua +2021/01/16 | 381077 | macros/latex/contrib/asmeconf/examples/asmeconf-fontspec.pdf +2021/01/16 | 3784 | macros/luatex/generic/luaotfload/README.md +2021/01/16 | 372 | macros/latex/contrib/acro/examples/acro.example.texsx-515295.tex +2021/01/16 | 3693 | macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua +2021/01/16 | 3674 | macros/luatex/generic/luaotfload/fontloader-fonts-syn.lua +2021/01/16 | 361 | macros/luatex/generic/luaotfload/fontloader-l-function.lua +2021/01/16 | 3580 | macros/luatex/generic/luaotfload/fontloader-font-imp-ligatures.lua +2021/01/16 | 35437 | macros/latex/contrib/translations/translations_en.tex +2021/01/16 | 353 | macros/latex/contrib/acro/examples/acro.example.texsx-513623.tex +2021/01/16 | 34862 | macros/luatex/generic/luaotfload/fontloader-font-ott.lua +2021/01/16 | 3406 | macros/luatex/generic/luaotfload/fontloader-font-imp-tex.lua +2021/01/16 | 33721 | macros/latex/contrib/acro/examples/acro.example.texsx-507726.pdf +2021/01/16 | 33035 | macros/luatex/generic/luaotfload/fontloader-font-otl.lua +2021/01/16 | 329 | macros/latex/contrib/acro/examples/acro.example.issue-109.tex +2021/01/16 | 3287334 | macros/luatex/generic/luaotfload/luaotfload-characters.lua +2021/01/16 | 32597 | macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua +2021/01/16 | 3252 | macros/latex/contrib/acro/acro-examples.sty +2021/01/16 | 32432 | macros/latex/contrib/acro/examples/acro.example.texsx-505891.pdf +2021/01/16 | 3214 | macros/latex/contrib/acro/examples/acro.example.basic.tex +2021/01/16 | 319588 | systems/texlive/tlnet/archive/fcolumn.doc.r57428.tar.xz +2021/01/16 | 31802 | macros/luatex/generic/luaotfload/fontloader-font-otc.lua +2021/01/16 | 3179 | fonts/alfaslabone/enc/a_taosrr.enc +2021/01/16 | 315 | macros/latex/contrib/acro/examples/acro.example.acflike.tex +2021/01/16 | 315430 | graphics/pxpic.zip +2021/01/16 | 31298 | macros/luatex/generic/luaotfload/fontloader-font-one.lua +2021/01/16 | 31151 | macros/luatex/generic/luaotfload/luaotfload-configuration.lua +2021/01/16 | 3109488 | systems/texlive/tlnet/archive/stix2-type1.r57430.tar.xz +2021/01/16 | 30999 | macros/luatex/generic/luaotfload/luaotfload-parsers.lua +2021/01/16 | 309853 | graphics/pxpic/pxpic.pdf +2021/01/16 | 30275 | macros/latex/contrib/acro/examples/acro.example.issue-109.pdf +2021/01/16 | 2999 | fonts/alfaslabone/enc/a_rymxky.enc +2021/01/16 | 2958 | fonts/alfaslabone/enc/a_d2anrk.enc +2021/01/16 | 2943 | fonts/alfaslabone/enc/a_lzhlbi.enc +2021/01/16 | 2902 | fonts/alfaslabone/enc/a_vqpkf5.enc +2021/01/16 | 29002 | macros/luatex/generic/luaotfload/luaotfload-features.lua +2021/01/16 | 2886 | fonts/alfaslabone/enc/a_adz5lu.enc +2021/01/16 | 286 | macros/latex/contrib/acro/examples/acro.example.issue-154.tex +2021/01/16 | 2834904 | macros/latex/contrib/asmeconf.zip +2021/01/16 | 2830 | fonts/alfaslabone/enc/a_5xld5w.enc +2021/01/16 | 28080 | systems/texlive/tlnet/archive/stix2-type1.source.r57430.tar.xz +2021/01/16 | 275 | macros/luatex/generic/luaotfload/luaotfload-main.lua +2021/01/16 | 275358 | macros/latex/contrib/asmeconf/examples/asmeconf-lualatex-ode-example.pdf +2021/01/16 | 27446 | macros/latex/contrib/asmeconf/examples/asmeconf-fontspec.tex +2021/01/16 | 27380 | systems/texlive/tlnet/archive/tlshell.r57426.tar.xz +2021/01/16 | 2732 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ot1.tfm +2021/01/16 | 2667 | macros/luatex/generic/luaotfload/fontloader-font-vfc.lua +2021/01/16 | 2582 | macros/luatex/generic/luaotfload/luaotfload-suppress.lua +2021/01/16 | 2555 | macros/luatex/generic/luaotfload/fontloader-l-math.lua +2021/01/16 | 25336 | macros/luatex/generic/luaotfload/luaotfload-filelist.lua +2021/01/16 | 25187 | fonts/alfaslabone/doc/alfaslabone-samples.pdf +2021/01/16 | 2506 | macros/luatex/generic/luaotfload/luaotfload-scripts.lua +2021/01/16 | 24566 | macros/luatex/generic/luaotfload/fontloader-font-ocl.lua +2021/01/16 | 2441 | fonts/alfaslabone/latex/alfaslabone.sty +2021/01/16 | 24287717 | systems/texlive/tlnet/install-tl.zip +2021/01/16 | 24224 | macros/latex/contrib/acro/examples/acro.example.issue-154.pdf +2021/01/16 | 241759 | fonts/alfaslabone.zip +2021/01/16 | 23895404 | info/beginlatex.zip +2021/01/16 | 238560 | graphics/pgf/contrib/tikz-bbox.zip +2021/01/16 | 234562 | graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.pdf +2021/01/16 | 23399 | macros/luatex/generic/luaotfload/fontloader-fonts-tfm.lua +2021/01/16 | 2315 | macros/luatex/generic/luaotfload/fontloader-fonts-enc.lua +2021/01/16 | 22966 | macros/luatex/generic/luaotfload/fontloader-font-oto.lua +2021/01/16 | 22752 | macros/latex/contrib/acro/examples/acro.example.texsx-513623.pdf +2021/01/16 | 2267336 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz +2021/01/16 | 22175 | macros/luatex/generic/luaotfload/fontloader-l-file.lua +2021/01/16 | 218820 | systems/texlive/tlnet/archive/texlive-scripts.doc.r57423.tar.xz +2021/01/16 | 21857 | macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua +2021/01/16 | 21837 | macros/luatex/generic/luaotfload/scripts-demo.pdf +2021/01/16 | 2125 | macros/latex/contrib/acro/README +2021/01/16 | 21252 | systems/texlive/tlnet/archive/fcolumn.source.r57428.tar.xz +2021/01/16 | 20922 | macros/latex/contrib/acro/examples/acro.example.acflike.pdf +2021/01/16 | 207536 | systems/texlive/tlnet/archive/readablecv.doc.r57433.tar.xz +2021/01/16 | 20031 | macros/luatex/generic/luaotfload/NEWS +2021/01/16 | 19944 | macros/luatex/generic/luaotfload/fontloader-font-def.lua +2021/01/16 | 1978 | macros/latex/contrib/acro/examples/acro.example.units.tex +2021/01/16 | 19570 | macros/luatex/generic/luaotfload/fontloader-font-map.lua +2021/01/16 | 19547 | macros/luatex/generic/luaotfload/luaotfload-init.lua +2021/01/16 | 1950415 | install/macros/luatex/generic/luaotfload.tds.zip +2021/01/16 | 1946587 | macros/luatex/generic/luaotfload.zip +2021/01/16 | 19418459 | systems/texlive/tlnet/install-tl-windows.exe +2021/01/16 | 191 | macros/luatex/generic/luaotfload/shaper-demo-graphite.tex +2021/01/16 | 1892 | systems/texlive/tlnet/archive/collection-fontsextra.r57429.tar.xz +2021/01/16 | 1888 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ly1--base.tfm +2021/01/16 | 18717 | macros/luatex/generic/luaotfload/fontloader-font-onr.lua +2021/01/16 | 18714 | macros/luatex/generic/luaotfload/COPYING +2021/01/16 | 1864 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-ly1.tfm +2021/01/16 | 18645 | macros/luatex/generic/luaotfload/luaotfload-letterspace.lua +2021/01/16 | 1860 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-ly1--base.tfm +2021/01/16 | 1850 | macros/luatex/generic/luaotfload/fontloader-l-boolean.lua +2021/01/16 | 18421 | macros/luatex/generic/luaotfload/fontloader-font-ota.lua +2021/01/16 | 184044 | systems/texlive/tlnet/archive/marathi.doc.r57432.tar.xz +2021/01/16 | 182 | macros/luatex/generic/luaotfload/shaper-demo.tex +2021/01/16 | 182360 | systems/texlive/tlnet/archive/nunito.doc.r57429.tar.xz +2021/01/16 | 182126 | macros/luatex/generic/luaotfload/fontloader-font-ots.lua +2021/01/16 | 1812 | macros/luatex/generic/luaotfload/luaotfload.sty +2021/01/16 | 1808 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-t1--base.tfm +2021/01/16 | 18074 | macros/luatex/generic/luaotfload/luaotfload.conf.rst +2021/01/16 | 1800 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-t1.tfm +2021/01/16 | 1794 | macros/luatex/generic/luaotfload/fontloader-font-ini.lua +2021/01/16 | 1792 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-t1--base.tfm +2021/01/16 | 17536 | systems/texlive/tlnet/archive/marathi.source.r57432.tar.xz +2021/01/16 | 1728 | fonts/alfaslabone/vf/AlphaSlabOne-Regular-tlf-t1.vf +2021/01/16 | 172864 | macros/latex/contrib/acro/acro.sty +2021/01/16 | 1712 | fonts/alfaslabone/vf/AlphaSlabOne-Regular-tlf-ly1.vf +2021/01/16 | 1700 | fonts/alfaslabone/vf/AlphaSlabOne-Regular-sup-t1.vf +2021/01/16 | 16960516 | systems/texlive/tlnet/tlpkg/texlive.tlpdb +2021/01/16 | 1693 | macros/latex/contrib/translations/README +2021/01/16 | 1684 | fonts/alfaslabone/vf/AlphaSlabOne-Regular-sup-ly1.vf +2021/01/16 | 16675 | macros/luatex/generic/luaotfload/luaotfload-latex.tex +2021/01/16 | 16548 | macros/luatex/generic/luaotfload/luaotfload.conf.5 +2021/01/16 | 15954 | macros/luatex/generic/luaotfload/luaotfload-colors.lua +2021/01/16 | 15940 | macros/luatex/generic/luaotfload/luaotfload-tool.rst +2021/01/16 | 15855 | macros/latex/contrib/acro/examples/acro.example.texsx-515295.pdf +2021/01/16 | 15808 | macros/latex/contrib/acro/examples/acro.example.texsx-542461.pdf +2021/01/16 | 15733 | macros/latex/contrib/acro/examples/acro.example.issue-111.pdf +2021/01/16 | 154135 | macros/luatex/generic/luaotfload/fontloader-font-dsp.lua +2021/01/16 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512 +2021/01/16 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512 +2021/01/16 | 15196 | macros/luatex/generic/luaotfload/fontloader-reference-load-order.lua +2021/01/16 | 15068 | macros/luatex/generic/luaotfload/luaotfload-multiscript.lua +2021/01/16 | 1476 | macros/latex/contrib/acro/examples/acro.example.texsx-507726.tex +2021/01/16 | 145 | systems/texlive/tlnet/install-tl.zip.sha512 +2021/01/16 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 +2021/01/16 | 1449 | macros/luatex/generic/luaotfload/fontloader-font-lua.lua +2021/01/16 | 144061 | macros/latex/contrib/acro/acro2.sty +2021/01/16 | 1428 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ts1.tfm +2021/01/16 | 1420 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ts1--base.tfm +2021/01/16 | 13977 | macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua +2021/01/16 | 1393064 | systems/texlive/tlnet/archive/stix2-type1.doc.r57430.tar.xz +2021/01/16 | 1383744 | systems/texlive/tlnet/archive/stix2-otf.r57427.tar.xz +2021/01/16 | 1382570 | macros/latex/contrib/acro.zip +2021/01/16 | 13788 | macros/luatex/generic/luaotfload/luaotfload.lua +2021/01/16 | 13686 | macros/latex/contrib/acro/examples/acro.example.possessive.pdf +2021/01/16 | 13500 | macros/luatex/generic/luaotfload/fontloader-font-shp.lua +2021/01/16 | 134863 | macros/luatex/generic/luaotfload/luaotfload-database.lua +2021/01/16 | 13468 | macros/luatex/generic/luaotfload/luaotfload-harf-define.lua +2021/01/16 | 1332 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-ot1.tfm +2021/01/16 | 132192 | systems/texlive/tlnet/archive/texlive-scripts.r57423.tar.xz +2021/01/16 | 12745 | macros/luatex/generic/luaotfload/fontloader-basics-gen.lua +2021/01/16 | 12707 | macros/luatex/generic/luaotfload/luaotfload-tool.1 +2021/01/16 | 125351 | macros/latex/contrib/acro/examples/acro.example.basic.pdf +2021/01/16 | 124025 | fonts/alfaslabone/type1/AlphaSlabOne-Regular.pfb +2021/01/16 | 12224 | macros/luatex/generic/luaotfload/luaotfload-notdef.lua +2021/01/16 | 1219820 | systems/texlive/tlnet/archive/stix2-otf.doc.r57427.tar.xz +2021/01/16 | 1200 | systems/texlive/tlnet/archive/pslatex.source.r57434.tar.xz +2021/01/16 | 11829 | macros/luatex/generic/luaotfload/fontloader-l-io.lua +2021/01/16 | 117724 | macros/luatex/generic/luaotfload/fontloader-font-oup.lua +2021/01/16 | 11552 | macros/luatex/generic/luaotfload/fontloader-util-fil.lua +2021/01/16 | 1145 | graphics/pxpic/README.md +2021/01/16 | 11323 | macros/luatex/generic/luaotfload/luaotfload-log.lua +2021/01/16 | 10984 | macros/luatex/generic/luaotfload/luaotfload-resolvers.lua +2021/01/16 | 109148 | fonts/alfaslabone/opentype/AlphaSlabOne-Regular.otf +2021/01/16 | 1087 | fonts/alfaslabone/map/AlphaSlabOne.map +2021/01/16 | 107580 | macros/luatex/generic/luaotfload/fontloader-font-osd.lua +2021/01/16 | 1068 | macros/latex/contrib/acro/examples/acro.example.texsx-505891.tex +2021/01/16 | 104364 | macros/latex/contrib/acro/acro-manual.tex +2021/01/16 | 102502 | macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua +2021/01/16 | 10064 | macros/luatex/generic/luaotfload/fontloader-basics-nod.lua +2021/01/16 | 1004 | macros/luatex/generic/luaotfload/luaotfload-embolden.lua 2021/01/15 | 99552 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma 2021/01/15 | 99520 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-2.9.tar.lzma 2021/01/15 | 97505 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-2.9.tar.lzma @@ -18,11 +276,13 @@ 2021/01/15 | 84983 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-2.9.tar.lzma 2021/01/15 | 814143 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma 2021/01/15 | 80896 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma +2021/01/15 | 807960 | systems/win32/w32tex/win64/dvipdfm-w64.tar.xz 2021/01/15 | 78792 | systems/win32/miktex/tm/packages/next/miktex-png-bin-2.9.tar.lzma 2021/01/15 | 77920 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma 2021/01/15 | 778180 | systems/texlive/tlnet/archive/optex.r57419.tar.xz 2021/01/15 | 7752 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-2.9.tar.lzma 2021/01/15 | 77427 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma +2021/01/15 | 768755 | systems/win32/w32tex/ChangeLog 2021/01/15 | 75379 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma 2021/01/15 | 746531 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-2.9.tar.lzma 2021/01/15 | 74175 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma @@ -39,16 +299,20 @@ 2021/01/15 | 67674 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-2.9.tar.lzma 2021/01/15 | 67624 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-2.9.tar.lzma 2021/01/15 | 67416 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-2.9.tar.lzma +2021/01/15 | 6657 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl +2021/01/15 | 6620960 | systems/win32/w32tex/ptex-ng-w32.tar.xz 2021/01/15 | 65835 | systems/win32/miktex/tm/packages/next/miktex-web-bin-2.9.tar.lzma 2021/01/15 | 65372 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma 2021/01/15 | 6406619 | fonts/nunito.zip 2021/01/15 | 63952 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-2.9.tar.lzma 2021/01/15 | 63836 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-2.9.tar.lzma +2021/01/15 | 637738 | macros/latex/contrib/asmeconf/asmeconf-template.pdf 2021/01/15 | 63713 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-2.9.tar.lzma 2021/01/15 | 62819 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma 2021/01/15 | 62586 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma 2021/01/15 | 624677 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-2.9.tar.lzma 2021/01/15 | 619130 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma +2021/01/15 | 610063 | macros/latex/contrib/asmeconf/examples/asmeconf-authorgrid-example.pdf 2021/01/15 | 60629 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-2.9.tar.lzma 2021/01/15 | 59814 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma 2021/01/15 | 594721 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma @@ -92,11 +356,9 @@ 2021/01/15 | 552 | fonts/nunito/vf/Nunito-Bold-tlf-ts1.vf 2021/01/15 | 552 | fonts/nunito/vf/Nunito-Black-tlf-ts1.vf 2021/01/15 | 55186 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-2.9.tar.lzma -2021/01/15 | 5517800 | systems/texlive/tlnet/install-tl-unx.tar.gz 2021/01/15 | 541127 | macros/latex/contrib/easybook.zip 2021/01/15 | 538588 | systems/win32/miktex/tm/packages/easybook.tar.lzma 2021/01/15 | 531617 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-2.9.tar.lzma -2021/01/15 | 526796 | systems/texlive/tlnet/archive/easybook.doc.r57418.tar.xz 2021/01/15 | 52465 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-2.9.tar.lzma 2021/01/15 | 52440 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma 2021/01/15 | 52086 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma @@ -135,7 +397,7 @@ 2021/01/15 | 4913 | fonts/nunito/latex/OT1Nunito-Sup.fd 2021/01/15 | 4913 | fonts/nunito/latex/LY1Nunito-TLF.fd 2021/01/15 | 4913 | fonts/nunito/latex/LY1Nunito-Sup.fd -2021/01/15 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 +2021/01/15 | 49060056 | systems/win32/w32tex/xetex-w32.tar.xz 2021/01/15 | 4851 | fonts/nunito/latex/T1Nunito-TLF.fd 2021/01/15 | 4851 | fonts/nunito/latex/T1Nunito-Sup.fd 2021/01/15 | 4838 | language/marathi/marathi.ins @@ -144,10 +406,10 @@ 2021/01/15 | 483532 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-2.9.tar.lzma 2021/01/15 | 48264 | fonts/nunito/tfm/Nunito-Light-tosf-t1.tfm 2021/01/15 | 48264 | fonts/nunito/tfm/Nunito-Light-tlf-t1.tfm -2021/01/15 | 4823627 | fonts/stix2-type1.zip 2021/01/15 | 47896 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma 2021/01/15 | 476059 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-2.9.tar.lzma 2021/01/15 | 46959 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma +2021/01/15 | 4662812 | systems/win32/w32tex/dvipdfm-w32.tar.xz 2021/01/15 | 46324 | fonts/nunito/tfm/Nunito-ExtraLightItalic-tosf-t1.tfm 2021/01/15 | 46324 | fonts/nunito/tfm/Nunito-ExtraLightItalic-tlf-t1.tfm 2021/01/15 | 46240 | fonts/nunito/tfm/Nunito-ExtraLight-tosf-t1.tfm @@ -155,10 +417,6 @@ 2021/01/15 | 461073 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma 2021/01/15 | 45953 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-2.9.tar.lzma 2021/01/15 | 45681 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-2.9.tar.lzma -2021/01/15 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc -2021/01/15 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc -2021/01/15 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc -2021/01/15 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc 2021/01/15 | 45236 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma 2021/01/15 | 4385 | fonts/nunito/doc/LICENSE.TXT 2021/01/15 | 43597 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-2.9.tar.lzma @@ -187,8 +445,10 @@ 2021/01/15 | 41924 | fonts/nunito/tfm/Nunito-Bold-tlf-ly1.tfm 2021/01/15 | 41500 | fonts/nunito/tfm/Nunito-ExtraBoldItalic-tosf-ly1.tfm 2021/01/15 | 41500 | fonts/nunito/tfm/Nunito-ExtraBoldItalic-tlf-ly1.tfm +2021/01/15 | 41372 | macros/latex/contrib/asmeconf/asmeconf-template.tex 2021/01/15 | 41344 | fonts/nunito/tfm/Nunito-ExtraBold-tosf-ly1.tfm 2021/01/15 | 41344 | fonts/nunito/tfm/Nunito-ExtraBold-tlf-ly1.tfm +2021/01/15 | 41302 | macros/latex/contrib/asmeconf/examples/asmeconf-authorgrid-example.tex 2021/01/15 | 40993 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-2.9.tar.lzma 2021/01/15 | 40576 | fonts/nunito/tfm/Nunito-LightItalic-tosf-ly1.tfm 2021/01/15 | 40576 | fonts/nunito/tfm/Nunito-LightItalic-tlf-ly1.tfm @@ -211,6 +471,7 @@ 2021/01/15 | 345918 | systems/win32/miktex/tm/packages/fcolumn.tar.lzma 2021/01/15 | 344998 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma 2021/01/15 | 34320 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma +2021/01/15 | 33953568 | systems/win32/w32tex/ltxpkgs.tar.xz 2021/01/15 | 33466 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin.tar.lzma 2021/01/15 | 33188 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma 2021/01/15 | 330328 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-2.9.tar.lzma @@ -284,7 +545,6 @@ 2021/01/15 | 245933 | fonts/nunito/type1/Nunito-SemiBold.pfb 2021/01/15 | 245026 | fonts/nunito/type1/Nunito-Regular.pfb 2021/01/15 | 243452 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma -2021/01/15 | 24287700 | systems/texlive/tlnet/install-tl.zip 2021/01/15 | 239134 | fonts/nunito/type1/Nunito-Light.pfb 2021/01/15 | 23889 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma 2021/01/15 | 236732 | fonts/nunito/opentype/Nunito-ExtraLight.otf @@ -292,7 +552,7 @@ 2021/01/15 | 232888 | fonts/nunito/type1/Nunito-ExtraLight.pfb 2021/01/15 | 231623 | systems/win32/miktex/tm/packages/next/miktex-console-bin-2.9.tar.lzma 2021/01/15 | 231477 | macros/latex/contrib/easybook/doc/easybook.pdf -2021/01/15 | 2267500 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz +2021/01/15 | 22142 | systems/texlive/tlnet/tlpkg/tltcl/tltcl.tcl 2021/01/15 | 22036 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-2.9.tar.lzma 2021/01/15 | 2150991 | systems/win32/miktex/tm/packages/optex.tar.lzma 2021/01/15 | 213765 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma @@ -309,9 +569,9 @@ 2021/01/15 | 199597 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-2.9.tar.lzma 2021/01/15 | 1982348 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma 2021/01/15 | 198051 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-2.9.tar.lzma +2021/01/15 | 196013 | fonts/stix2-type1/stix2.dtx 2021/01/15 | 195628 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-2.9.tar.lzma 2021/01/15 | 195573 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma -2021/01/15 | 19416638 | systems/texlive/tlnet/install-tl-windows.exe 2021/01/15 | 193652 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-2.9.tar.lzma 2021/01/15 | 1872 | fonts/nunito/tfm/Nunito-BlackItalic-sup-ly1.tfm 2021/01/15 | 1868 | fonts/nunito/tfm/Nunito-BlackItalic-sup-ly1--base.tfm @@ -356,6 +616,7 @@ 2021/01/15 | 1788 | fonts/nunito/tfm/Nunito-ExtraBoldItalic-tosf-t1--base.tfm 2021/01/15 | 1788 | fonts/nunito/tfm/Nunito-ExtraBoldItalic-tlf-t1--base.tfm 2021/01/15 | 178779 | fonts/nunito/doc/nunito-samples.pdf +2021/01/15 | 1780 | fonts/stix2-type1/README.md 2021/01/15 | 1780 | fonts/nunito/tfm/Nunito-SemiBoldItalic-tlf-t1--base.tfm 2021/01/15 | 1780 | fonts/nunito/tfm/Nunito-ExtraLightItalic-sup-ly1.tfm 2021/01/15 | 1776 | fonts/nunito/tfm/Nunito-SemiBoldItalic-tosf-t1--base.tfm @@ -374,10 +635,10 @@ 2021/01/15 | 1740 | fonts/nunito/tfm/Nunito-ExtraLightItalic-sup-t1--base.tfm 2021/01/15 | 1736 | fonts/nunito/tfm/Nunito-LightItalic-tosf-t1--base.tfm 2021/01/15 | 1736 | fonts/nunito/tfm/Nunito-LightItalic-tlf-t1--base.tfm -2021/01/15 | 1716 | fonts/stix2-type1/README.md 2021/01/15 | 1716 | fonts/nunito/vf/Nunito-ExtraLightItalic-tosf-t1.vf 2021/01/15 | 1716 | fonts/nunito/tfm/Nunito-ExtraLightItalic-tosf-t1--base.tfm 2021/01/15 | 1716 | fonts/nunito/tfm/Nunito-ExtraLightItalic-tlf-t1--base.tfm +2021/01/15 | 1714096 | systems/win32/w32tex/win64/ptex-ng-w64.tar.xz 2021/01/15 | 1712 | fonts/nunito/vf/Nunito-SemiBoldItalic-tosf-t1.vf 2021/01/15 | 1712 | fonts/nunito/vf/Nunito-SemiBoldItalic-tlf-t1.vf 2021/01/15 | 1712 | fonts/nunito/vf/Nunito-ExtraLightItalic-tlf-t1.vf @@ -421,7 +682,6 @@ 2021/01/15 | 1696 | fonts/nunito/vf/Nunito-BlackItalic-sup-t1.vf 2021/01/15 | 1696 | fonts/nunito/tfm/Nunito-Black-tosf-ly1--base.tfm 2021/01/15 | 1696 | fonts/nunito/tfm/Nunito-Black-tlf-ly1--base.tfm -2021/01/15 | 16933239 | systems/texlive/tlnet/tlpkg/texlive.tlpdb 2021/01/15 | 1692 | fonts/nunito/vf/Nunito-SemiBold-tosf-ly1.vf 2021/01/15 | 1692 | fonts/nunito/vf/Nunito-SemiBold-sup-t1.vf 2021/01/15 | 1692 | fonts/nunito/vf/Nunito-Regular-sup-t1.vf @@ -525,14 +785,10 @@ 2021/01/15 | 16324 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-2.9.tar.lzma 2021/01/15 | 161937 | systems/win32/miktex/tm/packages/pixelart.tar.lzma 2021/01/15 | 159915 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma -2021/01/15 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512 2021/01/15 | 153918 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-2.9.tar.lzma -2021/01/15 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512 2021/01/15 | 152529 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma 2021/01/15 | 147204 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-2.9.tar.lzma 2021/01/15 | 147013 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-2.9.tar.lzma -2021/01/15 | 145 | systems/texlive/tlnet/install-tl.zip.sha512 -2021/01/15 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 2021/01/15 | 14330 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma 2021/01/15 | 142651 | systems/texlive/tlnet/tlpkg/TeXLive/TLUtils.pm 2021/01/15 | 1423823 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma @@ -577,7 +833,7 @@ 2021/01/15 | 1336 | fonts/nunito/tfm/Nunito-ExtraLight-tlf-ts1.tfm 2021/01/15 | 1336 | fonts/nunito/tfm/Nunito-ExtraBold-tosf-ts1.tfm 2021/01/15 | 1336 | fonts/nunito/tfm/Nunito-ExtraBold-tlf-ts1.tfm -2021/01/15 | 1336168 | fonts/stix2-type1/stix2.pdf +2021/01/15 | 1336166 | fonts/stix2-type1/stix2.pdf 2021/01/15 | 1332 | fonts/nunito/tfm/Nunito-SemiBold-tosf-ts1.tfm 2021/01/15 | 1332 | fonts/nunito/tfm/Nunito-SemiBold-tlf-ts1.tfm 2021/01/15 | 1332 | fonts/nunito/tfm/Nunito-Regular-tosf-ts1.tfm @@ -650,6 +906,7 @@ 2021/01/15 | 11448 | fonts/nunito/tfm/Nunito-Light-tlf-ot1.tfm 2021/01/15 | 113949 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma 2021/01/15 | 112193 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma +2021/01/15 | 11079052 | systems/win32/w32tex/win64/xetex-w64.tar.xz 2021/01/15 | 1096 | fonts/stix2-type1/stix2.ins 2021/01/15 | 109145 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma 2021/01/15 | 1078549 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma @@ -669,7 +926,6 @@ 2021/01/14 | 84930 | macros/luatex/optex/doc/optex-userdoc.tex 2021/01/14 | 838544 | fonts/stix2-otf/STIXTwoMath-Regular.otf 2021/01/14 | 819 | macros/latex/contrib/fcolumn/makefile -2021/01/14 | 768354 | systems/win32/w32tex/ChangeLog 2021/01/14 | 7059003 | systems/win32/miktex/tm/packages/mlmodern.tar.lzma 2021/01/14 | 7019984 | systems/texlive/tlnet/archive/mlmodern.r57411.tar.xz 2021/01/14 | 68548 | macros/latex/contrib/fcolumn/fcolumn.dtx @@ -697,7 +953,6 @@ 2021/01/14 | 3437528 | systems/win32/w32tex/win64/luajittex-exp-w64.tar.xz 2021/01/14 | 3408764 | fonts/stix2-otf.zip 2021/01/14 | 340487 | macros/latex/contrib/fcolumn.zip -2021/01/14 | 33953364 | systems/win32/w32tex/ltxpkgs.tar.xz 2021/01/14 | 33756 | systems/texlive/tlnet/archive/mlmodern.doc.r57411.tar.xz 2021/01/14 | 325284 | fonts/stix2-otf/STIXTwoText-MediumItalic.otf 2021/01/14 | 325060 | fonts/stix2-otf/STIXTwoText-SemiBoldItalic.otf @@ -722,22 +977,20 @@ 2021/01/14 | 24189 | macros/luatex/optex/base/table.opm 2021/01/14 | 2281 | macros/latex/contrib/fcolumn/fcolumn.ins 2021/01/14 | 2281399 | macros/luatex/optex.zip -2021/01/14 | 218820 | systems/texlive/tlnet/archive/texlive-scripts.doc.r57407.tar.xz 2021/01/14 | 2184 | systems/texlive/tlnet/archive/pxpic.r57412.tar.xz 2021/01/14 | 211848 | macros/latex/contrib/readablecv.zip 2021/01/14 | 2048 | language/marathi/glossaries.gls 2021/01/14 | 2031 | language/marathi/namuna-letter.tex -2021/01/14 | 196011 | fonts/stix2-type1/stix2.dtx 2021/01/14 | 18735948 | systems/win32/w32tex/luatex-exp-w32.tar.xz 2021/01/14 | 1832 | language/marathi/namuna-beamer.tex 2021/01/14 | 171168 | systems/texlive/tlnet/archive/texlive-docindex.doc.r57406.tar.xz 2021/01/14 | 16978 | macros/luatex/optex/base/unimath-codes.opm 2021/01/14 | 15182 | macros/latex/contrib/readablecv/ReadableCV.cls 2021/01/14 | 141260 | systems/texlive/tlnet/archive/texlive-msg-translations.r57409.tar.xz +2021/01/14 | 13995 | macros/latex/contrib/asmeconf/asmeconf-sample.bib 2021/01/14 | 13642 | fonts/stix2-otf/README.md 2021/01/14 | 1362584 | macros/luatex/optex/doc/optex-doc.pdf 2021/01/14 | 135615 | macros/latex/contrib/readablecv/ReadableCV.pdf -2021/01/14 | 132172 | systems/texlive/tlnet/archive/texlive-scripts.r57407.tar.xz 2021/01/14 | 1236 | language/marathi/namuna-para.tex 2021/01/14 | 12183 | macros/luatex/optex/base/if-macros.opm 2021/01/14 | 1102612 | systems/texlive/tlnet/archive/tuda-ci.doc.r57415.tar.xz @@ -817,7 +1070,6 @@ 2021/01/13 | 811716 | systems/win32/w32tex/win64/aleph-w64.tar.xz 2021/01/13 | 81118 | fonts/mlmodern/type1/mlmtk10.pfb 2021/01/13 | 808 | fonts/mlmodern/README -2021/01/13 | 807348 | systems/win32/w32tex/win64/dvipdfm-w64.tar.xz 2021/01/13 | 80716 | fonts/mlmodern/type1/mlmtt12.pfb 2021/01/13 | 80391 | fonts/mlmodern/type1/mlmtl10.pfb 2021/01/13 | 80317 | fonts/mlmodern/type1/mlmtt9.pfb @@ -843,7 +1095,6 @@ 2021/01/13 | 71722 | fonts/mlmodern/dvips/mlm-substitute.map 2021/01/13 | 6966 | fonts/erewhon/tex/erewhon.sty 2021/01/13 | 696204 | systems/win32/w32tex/win64/ttf2pt1-w64.tar.xz -2021/01/13 | 6610 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl 2021/01/13 | 6354880 | systems/win32/w32tex/win64/pdftex-w64.tar.xz 2021/01/13 | 63275 | systems/texlive/tlnet/tlpkg/translations/zh_TW.po 2021/01/13 | 627528 | macros/latex/contrib/showexpl.zip @@ -861,9 +1112,7 @@ 2021/01/13 | 517756 | systems/win32/w32tex/psutils-w32.tar.xz 2021/01/13 | 5177516 | systems/win32/w32tex/aleph-w32.tar.xz 2021/01/13 | 5117 | macros/luatex/optex/base/lists.opm -2021/01/13 | 49089560 | systems/win32/w32tex/xetex-w32.tar.xz 2021/01/13 | 484204 | systems/win32/w32tex/dvi2tty-w32.tar.xz -2021/01/13 | 4661312 | systems/win32/w32tex/dvipdfm-w32.tar.xz 2021/01/13 | 46304 | systems/texlive/tlnet/archive/curve2e.source.r57402.tar.xz 2021/01/13 | 4550868 | systems/win32/w32tex/dvipsk-w32.tar.xz 2021/01/13 | 4485516 | systems/win32/w32tex/texinfo-w32.tar.xz @@ -876,7 +1125,6 @@ 2021/01/13 | 386240 | systems/win32/w32tex/win64/psutils-w64.tar.xz 2021/01/13 | 376596 | systems/win32/w32tex/win64/mftrace-w64.tar.xz 2021/01/13 | 3724 | systems/texlive/tlnet/archive/libertinus-otf.r57398.tar.xz -2021/01/13 | 37153 | graphics/pxpic/pxpic.dtx 2021/01/13 | 36673 | macros/luatex/optex/base/fonts-select.opm 2021/01/13 | 35289 | fonts/mlmodern/type1/mlmmib5.pfb 2021/01/13 | 350534 | macros/latex/contrib/showexpl/doc/showexpl-test.pdf @@ -901,13 +1149,11 @@ 2021/01/13 | 30159 | fonts/mlmodern/type1/mlmsy6.pfb 2021/01/13 | 30055 | fonts/mlmodern/type1/mlmsy7.pfb 2021/01/13 | 30024 | fonts/mlmodern/type1/mlmsy9.pfb -2021/01/13 | 299461 | graphics/pxpic.zip 2021/01/13 | 29879 | fonts/mlmodern/type1/mlmsy10.pfb 2021/01/13 | 29825 | fonts/mlmodern/type1/mlmsy8.pfb 2021/01/13 | 2967 | fonts/mlmodern/doc/mlmodern.tex 2021/01/13 | 29626 | macros/latex/contrib/showexpl/showexpl.dtx 2021/01/13 | 2958 | macros/latex/contrib/easybook/doc/pages/chapter3.tex -2021/01/13 | 295341 | graphics/pxpic/pxpic.pdf 2021/01/13 | 2953315 | install/support/albatross.tds.zip 2021/01/13 | 2951691 | support/albatross.zip 2021/01/13 | 27370 | support/albatross/README.md @@ -921,7 +1167,6 @@ 2021/01/13 | 22787 | systems/win32/miktex/tm/packages/miktex-misc.tar.lzma 2021/01/13 | 2199628 | systems/win32/w32tex/win64/context-w64.tar.xz 2021/01/13 | 21154376 | systems/win32/w32tex/pdftex-w32.tar.xz -2021/01/13 | 1888 | systems/texlive/tlnet/archive/collection-fontsextra.r57399.tar.xz 2021/01/13 | 18751456 | systems/win32/w32tex/luatex-dev-w32.tar.xz 2021/01/13 | 18742452 | systems/win32/w32tex/luatex-w32.tar.xz 2021/01/13 | 1871404 | systems/win32/w32tex/win64/ptex-w64.tar.xz @@ -940,10 +1185,8 @@ 2021/01/13 | 1232056 | systems/win32/w32tex/omegaj-w32.tar.xz 2021/01/13 | 1226880 | systems/win32/miktex/tm/packages/curve2e.tar.lzma 2021/01/13 | 1170628 | systems/texlive/tlnet/archive/curve2e.doc.r57402.tar.xz -2021/01/13 | 1145 | graphics/pxpic/README.md 2021/01/13 | 1143280 | systems/win32/miktex/tm/packages/tuda-ci.tar.lzma 2021/01/13 | 112575 | systems/texlive/tlnet/tlpkg/translations/ru.po -2021/01/13 | 11078840 | systems/win32/w32tex/win64/xetex-w64.tar.xz 2021/01/13 | 109963 | systems/texlive/tlnet/tlpkg/translations/sr.po 2021/01/13 | 108520 | fonts/mlmodern/type1/mlmduno10.pfb 2021/01/13 | 1078524 | systems/win32/w32tex/win64/makeindex-w64.tar.xz @@ -2676,7 +2919,6 @@ 2021/01/10 | 6698 | macros/luatex/latex/hu-berlin-bundle/README.md 2021/01/10 | 66729544 | systems/win32/w32tex/biblatex-biber.tar.xz 2021/01/10 | 66273 | macros/luatex/latex/hu-berlin-bundle/hu-berlin-bundle.dtx -2021/01/10 | 6622084 | systems/win32/w32tex/ptex-ng-w32.tar.xz 2021/01/10 | 58691400 | systems/win32/w32tex/TLARM64W/tl-arm64-windows.zip 2021/01/10 | 513408 | fonts/erewhon/afm/Erewhon-RegularSlanted.afm 2021/01/10 | 509255 | fonts/erewhon/afm/Erewhon-Regular.afm @@ -2701,7 +2943,6 @@ 2021/01/10 | 1858 | macros/luatex/optex/pkg/emoji.opm 2021/01/10 | 179418 | info/digests/tugboat/hyphenex/tb0hyf.pdf 2021/01/10 | 173812 | macros/latex/contrib/babel-contrib/russian.zip -2021/01/10 | 1712960 | systems/win32/w32tex/win64/ptex-ng-w64.tar.xz 2021/01/10 | 16231 | macros/luatex/optex/base/verbatim.opm 2021/01/10 | 14903 | macros/luatex/latex/hu-berlin-bundle/img/texografie-logo.pdf 2021/01/10 | 1458 | macros/luatex/generic/luavlna/luavlna.sty @@ -2712,858 +2953,3 @@ 2021/01/10 | 1090 | macros/latex/contrib/orientation/orientation.sty 2021/01/10 | 10738 | macros/luatex/optex/base/math-unicode.opm 2021/01/10 | 103343 | macros/luatex/generic/luavlna.zip -2021/01/09 | 9999 | macros/latex/contrib/l3kernel/l3news10.tex -2021/01/09 | 996577 | macros/latex-dev/base/ltnews.pdf -2021/01/09 | 9810 | macros/latex-dev/base/ltnews21.tex -2021/01/09 | 9772 | macros/latex/contrib/l3kernel/l3docstrip.dtx -2021/01/09 | 959 | fonts/libertinus-fonts/CONTRIBUTORS.txt -2021/01/09 | 9563 | macros/latex-dev/base/ltcntrl.dtx -2021/01/09 | 9465 | macros/latex/contrib/l3kernel/l3news08.tex -2021/01/09 | 9460 | macros/latex-dev/base/format.ins -2021/01/09 | 9436 | macros/latex/contrib/l3kernel/l3flag.dtx -2021/01/09 | 9401 | macros/latex-dev/base/syntonly.dtx -2021/01/09 | 9374 | macros/latex-dev/base/preload.dtx -2021/01/09 | 934 | fonts/magra/map/Magra.map -2021/01/09 | 9297 | macros/latex/contrib/biblatex-contrib/biblatex-software/software.bbx -2021/01/09 | 929157 | macros/latex-dev/base/lthooks-code.pdf -2021/01/09 | 9216 | macros/latex/contrib/l3kernel/l3unicode.dtx -2021/01/09 | 91660 | fonts/libertinus-fonts/documentation/Opentype-Features.pdf -2021/01/09 | 909 | fonts/hindmadurai/README -2021/01/09 | 90768 | macros/latex-dev/base/fntguide.tex -2021/01/09 | 9068 | macros/latex-dev/base/lppl-1-0.txt -2021/01/09 | 9012 | systems/texlive/tlnet/archive/musixtex.source.r57353.tar.xz -2021/01/09 | 89720 | macros/latex-dev/base/slides.dtx -2021/01/09 | 89393 | macros/latex-dev/base/utf8ienc.dtx -2021/01/09 | 89226 | macros/latex/contrib/l3kernel/l3int.dtx -2021/01/09 | 8864 | macros/latex-dev/base/ltnews17.tex -2021/01/09 | 88413 | macros/latex-dev/base/lttextcomp.dtx -2021/01/09 | 87967 | macros/latex/contrib/l3kernel/l3seq.dtx -2021/01/09 | 874 | fonts/gudea/README -2021/01/09 | 87393 | fonts/magra/type1/Magra-Bold.pfb -2021/01/09 | 8737 | macros/latex-dev/base/ltthm.dtx -2021/01/09 | 866 | fonts/play-font/README -2021/01/09 | 866 | fonts/magra/README -2021/01/09 | 86520 | info/docsurvey/docsurvey.tex -2021/01/09 | 8632 | macros/latex-dev/base/oldlfont.dtx -2021/01/09 | 86151 | macros/latex/contrib/l3kernel/l3coffins.dtx -2021/01/09 | 85745 | macros/latex-dev/base/ltdefns.dtx -2021/01/09 | 85168 | systems/texlive/tlnet/archive/nicematrix.source.r57352.tar.xz -2021/01/09 | 8493 | macros/latex-dev/base/texpert.txt -2021/01/09 | 848 | fonts/play-font/vf/Play-Regular-tosf-sc-ot1.vf -2021/01/09 | 848 | fonts/play-font/vf/Play-Regular-tlf-sc-ot1.vf -2021/01/09 | 848 | fonts/play-font/vf/Play-Regular-osf-sc-ot1.vf -2021/01/09 | 848 | fonts/play-font/vf/Play-Regular-lf-sc-ot1.vf -2021/01/09 | 848 | fonts/play-font/vf/Play-Bold-tosf-sc-ot1.vf -2021/01/09 | 8481 | macros/latex/contrib/l3kernel/l3news11.tex -2021/01/09 | 84816 | macros/latex/contrib/l3kernel/l3fp-basics.dtx -2021/01/09 | 844 | fonts/play-font/vf/Play-Bold-tlf-sc-ot1.vf -2021/01/09 | 844 | fonts/play-font/vf/Play-Bold-osf-sc-ot1.vf -2021/01/09 | 844 | fonts/play-font/vf/Play-Bold-lf-sc-ot1.vf -2021/01/09 | 84356 | fonts/libertinus-fonts/otf/LibertinusSerifInitials-Regular.otf -2021/01/09 | 841217 | install/macros/latex/contrib/l3backend.tds.zip -2021/01/09 | 82645 | fonts/hindmadurai/doc/HindMadurai-samples.pdf -2021/01/09 | 813 | fonts/libertinus-fonts/AUTHORS.txt -2021/01/09 | 812 | fonts/hindmadurai/vf/HindMadurai-SemiBold-tlf-ot1.vf -2021/01/09 | 812 | fonts/hindmadurai/vf/HindMadurai-Regular-tlf-ot1.vf -2021/01/09 | 8100 | macros/latex-dev/base/ltnews.tex -2021/01/09 | 808 | fonts/hindmadurai/vf/HindMadurai-Medium-tlf-ot1.vf -2021/01/09 | 808 | fonts/hindmadurai/vf/HindMadurai-Light-tlf-ot1.vf -2021/01/09 | 808389 | macros/latex/contrib/l3backend.zip -2021/01/09 | 804 | info/docsurvey/README.txt -2021/01/09 | 804 | fonts/hindmadurai/vf/HindMadurai-Bold-tlf-ot1.vf -2021/01/09 | 79874 | macros/latex-dev/base/ltfssbas.dtx -2021/01/09 | 796 | fonts/gudea/vf/Gudea-Italic-tlf-ot1.vf -2021/01/09 | 79653 | macros/latex/contrib/l3kernel/l3names.dtx -2021/01/09 | 792 | fonts/gudea/vf/Gudea-Bold-tlf-ot1.vf -2021/01/09 | 792635 | fonts/play-font.zip -2021/01/09 | 79032 | fonts/magra/type1/Magra.pfb -2021/01/09 | 786373 | macros/latex/contrib/l3backend/l3backend-code.pdf -2021/01/09 | 784 | fonts/gudea/vf/Gudea-tlf-ot1.vf -2021/01/09 | 77528 | macros/latex/contrib/l3kernel/l3box.dtx -2021/01/09 | 77434 | macros/latex/contrib/l3kernel/l3msg.dtx -2021/01/09 | 76428 | macros/latex/contrib/l3kernel/l3skip.dtx -2021/01/09 | 7627 | macros/latex-dev/base/source2edoc.cls -2021/01/09 | 76251 | macros/latex/contrib/l3kernel/l3prefixes.pdf -2021/01/09 | 75662 | macros/latex/contrib/l3kernel/l3clist.dtx -2021/01/09 | 756536 | macros/latex-dev/base/ltshipout-code.pdf -2021/01/09 | 7526 | macros/latex-dev/base/ltxguide.cls -2021/01/09 | 747843 | macros/latex-dev/base/ltfilehook-code.pdf -2021/01/09 | 74696 | macros/latex-dev/base/ltfssini.dtx -2021/01/09 | 7413 | fonts/play-font/map/Play.map -2021/01/09 | 73845 | macros/latex/contrib/l3kernel/l3fp-trig.dtx -2021/01/09 | 7326 | macros/latex-dev/base/ltnews20.tex -2021/01/09 | 73140 | macros/latex/contrib/l3kernel/l3str.dtx -2021/01/09 | 7262 | fonts/hindmadurai/type1/HindMadurai-SemiBoldLCDFJ.pfb -2021/01/09 | 72593 | fonts/libertinus-fonts/documentation/preview.pdf -2021/01/09 | 7257 | fonts/hindmadurai/type1/HindMadurai-MediumLCDFJ.pfb -2021/01/09 | 7240 | fonts/hindmadurai/type1/HindMadurai-BoldLCDFJ.pfb -2021/01/09 | 7239 | fonts/hindmadurai/type1/HindMadurai-RegularLCDFJ.pfb -2021/01/09 | 7239 | fonts/hindmadurai/type1/HindMadurai-LightLCDFJ.pfb -2021/01/09 | 7222 | macros/latex-dev/base/exscale.dtx -2021/01/09 | 72154 | macros/latex-dev/base/ltfsstrc.dtx -2021/01/09 | 7200 | macros/latex-dev/base/sample2e.tex -2021/01/09 | 70908 | macros/latex/contrib/l3kernel/expl3.dtx -2021/01/09 | 70350 | macros/latex/contrib/l3kernel/l3fp.dtx -2021/01/09 | 6974 | macros/latex/contrib/l3kernel/l3fp-assign.dtx -2021/01/09 | 6914 | fonts/gudea/type1/Gudea-ItalicLCDFJ.pfb -2021/01/09 | 69051 | macros/latex-dev/base/clsguide.tex -2021/01/09 | 6893 | fonts/gudea/type1/Gudea-BoldLCDFJ.pfb -2021/01/09 | 6892 | fonts/gudea/type1/GudeaLCDFJ.pfb -2021/01/09 | 68914 | macros/latex-dev/base/ltpictur.dtx -2021/01/09 | 6872 | macros/latex-dev/base/ltnews13.tex -2021/01/09 | 68545 | macros/latex/contrib/l3kernel/l3text-case.dtx -2021/01/09 | 68428 | macros/latex-dev/base/usrguide.tex -2021/01/09 | 6764 | macros/latex-dev/base/slides.ins -2021/01/09 | 6715 | macros/latex-dev/base/latexsym.dtx -2021/01/09 | 6677 | macros/latex/contrib/l3kernel/l3news02.tex -2021/01/09 | 6655 | macros/latex-dev/base/alltt.dtx -2021/01/09 | 6624 | fonts/libertinus-fonts/README.md -2021/01/09 | 64938 | macros/latex/contrib/l3kernel/l3prg.dtx -2021/01/09 | 6482 | macros/latex/contrib/l3kernel/l3news03.tex -2021/01/09 | 6450 | macros/latex/contrib/l3kernel/l3term-glossary.tex -2021/01/09 | 64481 | macros/latex-dev/base/ltluatex.dtx -2021/01/09 | 64471 | macros/latex-dev/base/ltshipout.dtx -2021/01/09 | 6431 | macros/latex/contrib/l3kernel/l3news06.tex -2021/01/09 | 6363 | macros/latex-dev/base/newlfont.dtx -2021/01/09 | 63267 | macros/latex-dev/base/letter.dtx -2021/01/09 | 631310 | macros/latex-dev/base/doc.pdf -2021/01/09 | 6274 | macros/latex-dev/base/ltnews14.tex -2021/01/09 | 6267 | macros/latex/contrib/l3kernel/l3syntax-changes.tex -2021/01/09 | 626773 | macros/latex-dev/base/lthooks-doc.pdf -2021/01/09 | 6192 | macros/latex/contrib/l3kernel/l3.ins -2021/01/09 | 61801 | macros/latex/contrib/l3kernel/l3candidates.dtx -2021/01/09 | 61222 | macros/latex-dev/base/ltfssdcl.dtx -2021/01/09 | 6119 | macros/latex-dev/base/ltnews33.tex -2021/01/09 | 60873 | macros/latex-dev/base/ltfilehook.dtx -2021/01/09 | 60586 | language/japanese/jlreq-deluxe/jlreq-deluxe.pdf -2021/01/09 | 604512 | systems/texlive/tlnet/archive/latex.source.r57354.tar.xz -2021/01/09 | 60327 | macros/latex-dev/base/fontdef.dtx -2021/01/09 | 5995281 | macros/latex/contrib/l3kernel/source3.pdf -2021/01/09 | 590320 | macros/latex/contrib/l3kernel/expl3.pdf -2021/01/09 | 59028 | fonts/libertinus-fonts/otf/LibertinusMono-Regular.otf -2021/01/09 | 5865 | macros/latex-dev/base/ltidxglo.dtx -2021/01/09 | 5854 | macros/latex-dev/base/ltpar.dtx -2021/01/09 | 58411 | macros/latex-dev/base/ltfssaxes.dtx -2021/01/09 | 5840 | macros/latex-dev/base/ltnews15.tex -2021/01/09 | 58262 | macros/latex-dev/base/ltmiscen.dtx -2021/01/09 | 5777 | macros/latex-dev/base/ltnews16.tex -2021/01/09 | 5725 | macros/latex-dev/base/latexrelease.ins -2021/01/09 | 5716 | macros/latex-dev/base/inputenc.ins -2021/01/09 | 5696 | macros/latex-dev/base/ltnews08.tex -2021/01/09 | 5660 | macros/latex-dev/base/ltnews10.tex -2021/01/09 | 56546 | macros/latex/contrib/l3kernel/l3tl-analysis.dtx -2021/01/09 | 5653 | macros/latex/contrib/l3kernel/l3color-base.dtx -2021/01/09 | 5609 | macros/latex-dev/base/ltnews05.tex -2021/01/09 | 55800 | fonts/gudea/type1/Gudea-Italic.pfb -2021/01/09 | 5530 | macros/latex-dev/base/ltnews11.tex -2021/01/09 | 5515 | macros/latex-dev/base/graphpap.dtx -2021/01/09 | 550 | macros/latex/contrib/l3backend/README.md -2021/01/09 | 5507 | macros/latex-dev/base/ltnews27.tex -2021/01/09 | 5507 | macros/latex-dev/base/ltnews04.tex -2021/01/09 | 5474 | macros/latex-dev/base/ltnews25.tex -2021/01/09 | 5429 | macros/latex/contrib/l3kernel/l3news04.tex -2021/01/09 | 5426 | macros/latex-dev/base/ltnews07.tex -2021/01/09 | 5418 | macros/latex-dev/base/ltnews12.tex -2021/01/09 | 53984 | fonts/libertinus-fonts/otf/LibertinusKeyboard-Regular.otf -2021/01/09 | 5391 | macros/latex-dev/base/ltnews06.tex -2021/01/09 | 5294 | macros/latex-dev/base/ltnews09.tex -2021/01/09 | 5284 | macros/latex-dev/base/ltnews02.tex -2021/01/09 | 528458 | macros/latex-dev/base/ltshipout-doc.pdf -2021/01/09 | 52814 | macros/latex-dev/base/encguide.tex -2021/01/09 | 5275 | macros/latex-dev/base/cmextra.ins -2021/01/09 | 52647 | macros/latex-dev/base/ltfiles.dtx -2021/01/09 | 52532 | macros/latex-dev/base/lb2.err -2021/01/09 | 524 | fonts/gudea/vf/Gudea-Italic-tlf-ts1.vf -2021/01/09 | 5239 | macros/latex-dev/base/ltnews01.tex -2021/01/09 | 520 | fonts/gudea/vf/Gudea-Bold-tlf-ts1.vf -2021/01/09 | 520917 | macros/latex-dev/base/ltnews32.pdf -2021/01/09 | 520832 | macros/latex-dev/base/classes.pdf -2021/01/09 | 5201 | macros/latex-dev/base/ltnews03.tex -2021/01/09 | 519348 | fonts/libertinus-fonts/otf/LibertinusMath-Regular.otf -2021/01/09 | 518920 | macros/latex-dev/base/ltfilehook-doc.pdf -2021/01/09 | 516 | fonts/play-font/vf/Play-Regular-tosf-ts1.vf -2021/01/09 | 516 | fonts/gudea/vf/Gudea-tlf-ts1.vf -2021/01/09 | 51319 | macros/latex-dev/base/ltfloat.dtx -2021/01/09 | 512 | fonts/play-font/vf/Play-Regular-tlf-ts1.vf -2021/01/09 | 512 | fonts/play-font/vf/Play-Regular-osf-ts1.vf -2021/01/09 | 512 | fonts/play-font/vf/Play-Regular-lf-ts1.vf -2021/01/09 | 512 | fonts/play-font/vf/Play-Bold-tosf-ts1.vf -2021/01/09 | 512 | fonts/play-font/vf/Play-Bold-tlf-ts1.vf -2021/01/09 | 512 | fonts/play-font/vf/Play-Bold-osf-ts1.vf -2021/01/09 | 51061 | macros/latex/contrib/l3kernel/l3prop.dtx -2021/01/09 | 51059 | macros/latex/contrib/l3kernel/l3fp-extended.dtx -2021/01/09 | 510180 | fonts/libertinus-fonts/preview.svg -2021/01/09 | 508 | fonts/play-font/vf/Play-Bold-lf-ts1.vf -2021/01/09 | 508 | fonts/hindmadurai/vf/HindMadurai-SemiBold-tlf-ts1.vf -2021/01/09 | 508 | fonts/hindmadurai/vf/HindMadurai-Regular-tlf-ts1.vf -2021/01/09 | 504 | fonts/hindmadurai/vf/HindMadurai-Medium-tlf-ts1.vf -2021/01/09 | 504 | fonts/hindmadurai/vf/HindMadurai-Light-tlf-ts1.vf -2021/01/09 | 504 | fonts/hindmadurai/vf/HindMadurai-Bold-tlf-ts1.vf -2021/01/09 | 5044 | macros/latex-dev/base/latexsym.ins -2021/01/09 | 500 | fonts/magra/vf/Magra-Bold-tlf-ts1.vf -2021/01/09 | 500928 | macros/latex-dev/base/ltnews31.pdf -2021/01/09 | 4977 | macros/latex/contrib/l3kernel/l3news07.tex -2021/01/09 | 4952 | macros/latex-dev/base/lthyphen.dtx -2021/01/09 | 49386 | macros/latex/contrib/l3kernel/l3fp-expo.dtx -2021/01/09 | 4935 | macros/latex/contrib/l3kernel/l3news01.tex -2021/01/09 | 492 | fonts/magra/vf/Magra-tlf-ts1.vf -2021/01/09 | 49251 | macros/latex/contrib/l3backend/l3backend-pdf.dtx -2021/01/09 | 491245 | macros/latex-dev/base/ltnews30.pdf -2021/01/09 | 4891 | macros/latex/contrib/l3kernel/l3news.tex -2021/01/09 | 48647 | macros/latex-dev/base/ltplain.dtx -2021/01/09 | 48180 | fonts/gudea/type1/Gudea-Bold.pfb -2021/01/09 | 479297 | macros/latex-dev/base/docstrip.pdf -2021/01/09 | 47799 | fonts/gudea/type1/Gudea.pfb -2021/01/09 | 47704 | macros/latex-dev/base/lttab.dtx -2021/01/09 | 4763 | macros/latex-dev/base/ltlength.dtx -2021/01/09 | 4716 | macros/latex/contrib/l3kernel/l3news05.tex -2021/01/09 | 47145 | macros/latex/contrib/l3kernel/l3fp-aux.dtx -2021/01/09 | 46637 | fonts/gudea/doc/Gudea-samples.pdf -2021/01/09 | 45246 | macros/latex-dev/base/ltspace.dtx -2021/01/09 | 4443 | fonts/play-font/doc/LICENSE.TXT -2021/01/09 | 442 | fonts/hindmadurai/doc/HindMadurai-samples.tex -2021/01/09 | 4426 | fonts/libertinus-fonts/OFL.txt -2021/01/09 | 4405 | fonts/magra/doc/LICENSE.TXT -2021/01/09 | 4402 | fonts/gudea/doc/LICENSE.TXT -2021/01/09 | 4392 | macros/latex-dev/base/ec.ins -2021/01/09 | 4392016 | macros/latex-dev/base/source2e.pdf -2021/01/09 | 4371 | fonts/hindmadurai/doc/LICENSE.TXT -2021/01/09 | 43637 | macros/latex-dev/base/cmfonts.fdd -2021/01/09 | 43333 | macros/latex/contrib/l3kernel/l3debug.dtx -2021/01/09 | 433003 | macros/latex-dev/base/ltnews29.pdf -2021/01/09 | 4326 | macros/latex-dev/base/cmfonts.ins -2021/01/09 | 4304 | macros/latex-dev/base/ltalloc.dtx -2021/01/09 | 42708 | macros/latex-dev/base/changes.old.txt -2021/01/09 | 4256 | macros/latex-dev/base/newdc.ins -2021/01/09 | 4232 | fonts/hindmadurai/map/HindMadurai.map -2021/01/09 | 4223 | macros/latex-dev/base/docstrip.ins -2021/01/09 | 4221 | macros/latex-dev/base/latex209.ins -2021/01/09 | 4213 | macros/latex/contrib/l3backend/CHANGELOG.md -2021/01/09 | 418347 | macros/latex-dev/base/fntguide.pdf -2021/01/09 | 4171 | macros/latex-dev/base/ltnews19.tex -2021/01/09 | 41588 | macros/latex-dev/base/ltboxes.dtx -2021/01/09 | 41146 | fonts/play-font/doc/Play-samples.pdf -2021/01/09 | 4089 | macros/latex-dev/base/classes.ins -2021/01/09 | 40885 | macros/latex-dev/base/ltfinal.dtx -2021/01/09 | 4080 | macros/latex-dev/base/lablst.tex -2021/01/09 | 40796 | macros/latex-dev/base/latexchanges.tex -2021/01/09 | 40672 | macros/latex/contrib/l3kernel/l3sort.dtx -2021/01/09 | 399074 | macros/latex-dev/base/usrguide.pdf -2021/01/09 | 3962 | macros/latex-dev/base/olddc.ins -2021/01/09 | 3946 | macros/latex/contrib/l3backend/l3backend.ins -2021/01/09 | 39244 | macros/latex-dev/base/ltmath.dtx -2021/01/09 | 38736 | macros/latex-dev/base/latex209.dtx -2021/01/09 | 384459 | macros/latex/contrib/l3kernel/l3news.pdf -2021/01/09 | 383007 | install/macros/latex/contrib/pdfpages.tds.zip -2021/01/09 | 3808 | language/japanese/jlreq-deluxe/jlreq-deluxe.sty -2021/01/09 | 3783 | macros/latex-dev/base/tulm.ins -2021/01/09 | 3731 | macros/latex-dev/base/ltlogos.dtx -2021/01/09 | 3726 | fonts/play-font/enc/a_tnjomm.enc -2021/01/09 | 372576 | macros/latex-dev/base/clsguide.pdf -2021/01/09 | 3708 | fonts/play-font/enc/a_zkm5uj.enc -2021/01/09 | 3703 | language/japanese/jlreq-deluxe/jlreq-deluxe.tex -2021/01/09 | 36996 | macros/latex/contrib/l3kernel/l3prefixes.csv -2021/01/09 | 3689 | fonts/play-font/enc/a_af5aai.enc -2021/01/09 | 368231 | macros/latex-dev/base/ltnews28.pdf -2021/01/09 | 3671 | fonts/play-font/enc/a_i2o4el.enc -2021/01/09 | 365994 | macros/latex-dev/base/changes.txt -2021/01/09 | 3633 | language/japanese/jlreq-deluxe/README-ja.md -2021/01/09 | 362839 | macros/latex-dev/base/ltnews26.pdf -2021/01/09 | 36158 | macros/latex-dev/base/ltlists.dtx -2021/01/09 | 36004 | macros/latex-dev/base/ltnews18.pdf -2021/01/09 | 359183 | info/docsurvey.zip -2021/01/09 | 35831 | macros/latex/contrib/l3kernel/l3quark.dtx -2021/01/09 | 35550 | fonts/magra/doc/Magra-samples.pdf -2021/01/09 | 352797 | macros/latex/contrib/pdfpages.zip -2021/01/09 | 35220 | macros/latex-dev/base/ltdirchk.dtx -2021/01/09 | 351910 | macros/latex-dev/base/slides.pdf -2021/01/09 | 3514 | macros/latex-dev/base/README.md -2021/01/09 | 35103 | macros/latex/contrib/l3kernel/l3text.dtx -2021/01/09 | 34772856 | systems/win32/w32tex/latex.tar.xz -2021/01/09 | 34439 | macros/latex/contrib/l3backend/l3backend-color.dtx -2021/01/09 | 3436 | macros/latex-dev/base/makeindx.ins -2021/01/09 | 3403 | macros/latex-dev/base/proc.ins -2021/01/09 | 34005 | macros/latex/contrib/l3backend/l3backend-draw.dtx -2021/01/09 | 338597 | info/docsurvey/docsurvey.pdf -2021/01/09 | 3374 | macros/latex-dev/base/letter.ins -2021/01/09 | 3369 | macros/latex-dev/base/ltoutenc.ins -2021/01/09 | 3340 | macros/latex-dev/base/exscale.ins -2021/01/09 | 3327 | fonts/play-font/enc/a_kv5kmu.enc -2021/01/09 | 33256 | macros/latex-dev/base/ltnews32.tex -2021/01/09 | 3311 | fonts/play-font/enc/a_znkizw.enc -2021/01/09 | 330863 | macros/latex-dev/base/utf8ienc.pdf -2021/01/09 | 3294 | macros/latex-dev/base/bugs.txt -2021/01/09 | 328712 | fonts/libertinus-fonts/otf/LibertinusSerif-SemiboldItalic.otf -2021/01/09 | 32649 | macros/latex-dev/base/ltsect.dtx -2021/01/09 | 325333 | macros/latex-dev/base/ltnews33.pdf -2021/01/09 | 32166 | macros/latex-dev/base/latexrelease.dtx -2021/01/09 | 321457 | macros/latex/contrib/biblatex-contrib/biblatex-software.zip -2021/01/09 | 3182 | macros/latex-dev/base/unpack.ins -2021/01/09 | 3182 | fonts/hindmadurai/enc/a_ym6dij.enc -2021/01/09 | 318140 | fonts/libertinus-fonts/otf/LibertinusSerif-Italic.otf -2021/01/09 | 31475 | macros/latex/contrib/l3kernel/l3sys.dtx -2021/01/09 | 3145 | fonts/play-font/enc/a_r34yaf.enc -2021/01/09 | 3134 | fonts/gudea/enc/a_lksl5v.enc -2021/01/09 | 3119 | fonts/magra/enc/a_va7yvq.enc -2021/01/09 | 31120 | macros/latex/contrib/l3kernel/l3cctab.dtx -2021/01/09 | 30894 | macros/latex/contrib/pdfpages/dummy.pdf -2021/01/09 | 307271 | macros/latex-dev/base/letter.pdf -2021/01/09 | 305260 | macros/latex-dev/base/ltluatex.pdf -2021/01/09 | 30457 | macros/latex-dev/base/ltnews31.tex -2021/01/09 | 30363 | macros/latex/contrib/l3kernel/l3deprecation.dtx -2021/01/09 | 302831 | macros/latex-dev/base/ltnews22.pdf -2021/01/09 | 3010 | fonts/play-font/enc/a_s4hlxc.enc -2021/01/09 | 30006 | macros/latex-dev/base/usrguide3.tex -2021/01/09 | 2997 | macros/latex/contrib/l3kernel/README.md -2021/01/09 | 2983 | macros/latex/contrib/pdfpages/pdfpages.ins -2021/01/09 | 298152 | fonts/libertinus-fonts/otf/LibertinusSerif-Regular.otf -2021/01/09 | 2969 | fonts/play-font/enc/a_q2ckjx.enc -2021/01/09 | 294928 | macros/latex-dev/base/inputenc.pdf -2021/01/09 | 2944 | fonts/play-font/enc/a_rtke6c.enc -2021/01/09 | 29370 | macros/latex/contrib/l3kernel/l3kernel-functions.dtx -2021/01/09 | 292336 | macros/latex/contrib/pdfpages/pdfpages.pdf -2021/01/09 | 29192 | macros/latex-dev/base/ltfntcmd.dtx -2021/01/09 | 2906 | fonts/hindmadurai/enc/a_4f5hpf.enc -2021/01/09 | 2903 | fonts/play-font/enc/a_xroktn.enc -2021/01/09 | 2898 | macros/latex-dev/base/syntonly.ins -2021/01/09 | 28968670 | install/macros/latex-dev/latex-base-dev.tds.zip -2021/01/09 | 2895 | macros/latex-dev/base/nfssfont.ins -2021/01/09 | 2894 | macros/latex-dev/base/graphpap.ins -2021/01/09 | 2894 | macros/latex-dev/base/fix-cm.ins -2021/01/09 | 2892 | macros/latex-dev/base/alltt.ins -2021/01/09 | 2890 | macros/latex-dev/base/ifthen.ins -2021/01/09 | 288752 | fonts/libertinus-fonts/otf/LibertinusSans-Italic.otf -2021/01/09 | 287 | fonts/gudea/doc/Gudea-samples.tex -2021/01/09 | 2878 | fonts/play-font/enc/a_lzhlbi.enc -2021/01/09 | 2872 | fonts/play-font/enc/a_n7ssx7.enc -2021/01/09 | 2856 | fonts/hindmadurai/enc/a_u5lxld.enc -2021/01/09 | 28513086 | macros/latex-dev/base.zip -2021/01/09 | 2846 | fonts/gudea/enc/a_qnu4g5.enc -2021/01/09 | 2837 | fonts/play-font/enc/a_vqpkf5.enc -2021/01/09 | 283324 | macros/latex-dev/base/ltnews20.pdf -2021/01/09 | 2828 | fonts/magra/enc/a_jqnft2.enc -2021/01/09 | 2817 | macros/latex/contrib/l3kernel/l3prefixes.tex -2021/01/09 | 2804 | fonts/play-font/enc/a_xfzpyq.enc -2021/01/09 | 2804 | fonts/gudea/enc/a_ys4752.enc -2021/01/09 | 279972 | macros/latex/contrib/l3kernel/l3styleguide.pdf -2021/01/09 | 279492 | fonts/libertinus-fonts/otf/LibertinusSerif-Bold.otf -2021/01/09 | 2784 | fonts/magra/enc/a_radyzq.enc -2021/01/09 | 276424 | fonts/libertinus-fonts/otf/LibertinusSerif-Semibold.otf -2021/01/09 | 2757 | fonts/hindmadurai/enc/a_mlnerp.enc -2021/01/09 | 275416 | fonts/libertinus-fonts/otf/LibertinusSans-Bold.otf -2021/01/09 | 274456 | macros/latex-dev/base/ltnews23.pdf -2021/01/09 | 2740 | fonts/play-font/enc/a_rzdm5y.enc -2021/01/09 | 2738 | macros/latex-dev/base/tex2.txt -2021/01/09 | 2734 | macros/latex-dev/base/ltpageno.dtx -2021/01/09 | 2718 | fonts/gudea/enc/a_i65yxe.enc -2021/01/09 | 27124 | macros/latex-dev/base/ltxcheck.tex -2021/01/09 | 2708 | fonts/magra/enc/a_dip3eq.enc -2021/01/09 | 2706 | macros/latex-dev/base/idx.tex -2021/01/09 | 270258 | fonts/gudea.zip -2021/01/09 | 267776 | macros/latex/contrib/l3kernel/l3regex.dtx -2021/01/09 | 26672 | macros/latex/contrib/l3kernel/CHANGELOG.md -2021/01/09 | 264510 | macros/latex-dev/base/cmfonts.pdf -2021/01/09 | 263275 | macros/latex/contrib/l3kernel/l3docstrip.pdf -2021/01/09 | 261622 | macros/latex-dev/base/fix-cm.pdf -2021/01/09 | 25739 | macros/latex/contrib/l3kernel/l3fp-random.dtx -2021/01/09 | 256848 | fonts/libertinus-fonts/otf/LibertinusSans-Regular.otf -2021/01/09 | 254796 | fonts/libertinus-fonts/otf/LibertinusSerifDisplay-Regular.otf -2021/01/09 | 252643 | macros/latex-dev/base/ltnews24.pdf -2021/01/09 | 2484 | macros/latex/contrib/l3kernel/l3legacy.dtx -2021/01/09 | 247704 | macros/latex-dev/base/latexchanges.pdf -2021/01/09 | 245786 | macros/latex-dev/base/latexrelease.pdf -2021/01/09 | 244 | fonts/magra/doc/Magra-samples.tex -2021/01/09 | 243 | fonts/play-font/doc/Play-samples.tex -2021/01/09 | 24288 | systems/texlive/tlnet/archive/nicematrix.r57352.tar.xz -2021/01/09 | 241016 | macros/latex/contrib/l3kernel/l3news09.pdf -2021/01/09 | 24016 | macros/latex-dev/base/lterror.dtx -2021/01/09 | 239759 | macros/latex-dev/base/ltnews27.pdf -2021/01/09 | 237848 | fonts/libertinus-fonts/otf/LibertinusSerif-BoldItalic.otf -2021/01/09 | 23652 | macros/latex-dev/base/ltnews30.tex -2021/01/09 | 235597 | fonts/magra.zip -2021/01/09 | 23522 | macros/latex-dev/base/fix-cm.dtx -2021/01/09 | 235075 | macros/latex-dev/base/ltnews19.pdf -2021/01/09 | 23386 | macros/latex-dev/base/lppl.tex -2021/01/09 | 233489 | macros/latex-dev/base/ltnews21.pdf -2021/01/09 | 23107 | macros/latex/contrib/l3kernel/l3fp-logic.dtx -2021/01/09 | 22967836 | systems/texlive/tlnet/archive/latex.doc.r57354.tar.xz -2021/01/09 | 2287 | fonts/play-font/latex/Play.sty -2021/01/09 | 228269 | macros/latex/contrib/l3kernel/l3syntax-changes.pdf -2021/01/09 | 22677 | macros/latex-dev/base/ltcounts.dtx -2021/01/09 | 22457 | macros/latex-dev/base/cfgguide.tex -2021/01/09 | 220389 | macros/latex-dev/base/modguide.pdf -2021/01/09 | 220226 | macros/latex-dev/base/cfgguide.pdf -2021/01/09 | 21926 | macros/latex/contrib/l3kernel/source3body.tex -2021/01/09 | 217632 | macros/latex/contrib/l3kernel/l3term-glossary.pdf -2021/01/09 | 216995 | macros/latex-dev/base/cyrguide.pdf -2021/01/09 | 21643 | macros/latex/contrib/l3kernel/l3text-purify.dtx -2021/01/09 | 216401 | macros/latex-dev/base/proc.pdf -2021/01/09 | 2160 | fonts/gudea/tfm/Gudea-Italic-tlf-ly1.tfm -2021/01/09 | 2153 | macros/latex/contrib/l3kernel/source3.tex -2021/01/09 | 215243 | macros/latex-dev/base/ltxdoc.pdf -2021/01/09 | 214706 | macros/latex-dev/base/slifonts.pdf -2021/01/09 | 21168 | macros/latex/contrib/l3kernel/l3luatex.dtx -2021/01/09 | 21004 | macros/latex/contrib/l3kernel/l3intarray.dtx -2021/01/09 | 20962 | macros/latex/contrib/l3backend/l3backend-graphics.dtx -2021/01/09 | 2074 | fonts/hindmadurai/latex/HindMadurai.sty -2021/01/09 | 2064 | fonts/gudea/tfm/Gudea-Italic-tlf-t1.tfm -2021/01/09 | 2057608 | systems/texlive/tlnet/archive/musixtex.doc.r57353.tar.xz -2021/01/09 | 204833 | macros/latex-dev/base/ifthen.pdf -2021/01/09 | 20471 | macros/latex-dev/base/ltnews.cls -2021/01/09 | 20434 | macros/latex-dev/base/lgc2.err -2021/01/09 | 204008 | macros/latex-dev/base/doc.dtx -2021/01/09 | 202681 | fonts/libertinus-fonts/documentation/Sample.pdf -2021/01/09 | 202445 | macros/latex-dev/base/nfssfont.pdf -2021/01/09 | 2016 | fonts/gudea/tfm/Gudea-Bold-tlf-ly1.tfm -2021/01/09 | 2008 | fonts/gudea/tfm/Gudea-tlf-ly1.tfm -2021/01/09 | 2001 | fonts/gudea/map/Gudea.map -2021/01/09 | 1988 | fonts/gudea/tfm/Gudea-Italic-tlf-ly1--base.tfm -2021/01/09 | 197648 | macros/latex/contrib/l3kernel/l3news12.pdf -2021/01/09 | 1968 | macros/latex/contrib/biblatex-contrib/biblatex-software/history.tex -2021/01/09 | 19653 | macros/latex/contrib/l3kernel/l3fp-convert.dtx -2021/01/09 | 196325 | macros/latex-dev/base/ltnews25.pdf -2021/01/09 | 196100 | systems/texlive/tlnet/archive/latex.r57354.tar.xz -2021/01/09 | 195882 | macros/latex-dev/base/exscale.pdf -2021/01/09 | 1938 | macros/latex-dev/base/minimal.cls -2021/01/09 | 1924 | fonts/magra/tfm/Magra-Bold-tlf-ly1.tfm -2021/01/09 | 1924 | fonts/gudea/tfm/Gudea-Bold-tlf-t1.tfm -2021/01/09 | 192295 | macros/latex-dev/base/latexsym.pdf -2021/01/09 | 1916 | fonts/gudea/tfm/Gudea-tlf-t1.tfm -2021/01/09 | 191531 | macros/latex-dev/base/ltx3info.pdf -2021/01/09 | 1909 | macros/latex/contrib/l3kernel/interface3.tex -2021/01/09 | 19065 | macros/latex-dev/base/ltxdoc.dtx -2021/01/09 | 19040 | macros/latex-dev/base/lppl.txt -2021/01/09 | 1896 | fonts/magra/tfm/Magra-tlf-ly1.tfm -2021/01/09 | 18941 | macros/latex-dev/base/ltnews29.tex -2021/01/09 | 1892 | fonts/magra/tfm/Magra-Bold-tlf-t1.tfm -2021/01/09 | 1892 | fonts/gudea/tfm/Gudea-Italic-tlf-t1--base.tfm -2021/01/09 | 188553 | fonts/hindmadurai/type1/HindMadurai-Regular.pfb -2021/01/09 | 1884 | fonts/hindmadurai/tfm/HindMadurai-Regular-tlf-ly1.tfm -2021/01/09 | 1884 | fonts/hindmadurai/tfm/HindMadurai-Light-tlf-ly1.tfm -2021/01/09 | 188450 | fonts/hindmadurai/type1/HindMadurai-Light.pfb -2021/01/09 | 187896 | fonts/play-font/type1/Play-Bold.pfb -2021/01/09 | 1876 | fonts/magra/tfm/Magra-Bold-tlf-ly1--base.tfm -2021/01/09 | 186913 | fonts/hindmadurai/type1/HindMadurai-Medium.pfb -2021/01/09 | 186250 | fonts/hindmadurai/type1/HindMadurai-SemiBold.pfb -2021/01/09 | 1860 | fonts/hindmadurai/tfm/HindMadurai-Bold-tlf-ly1.tfm -2021/01/09 | 18591 | macros/latex/contrib/l3kernel/l3fp-round.dtx -2021/01/09 | 1857 | fonts/hindmadurai/latex/TS1HindMadurai-TLF.fd -2021/01/09 | 1857 | fonts/hindmadurai/latex/OT1HindMadurai-TLF.fd -2021/01/09 | 1857 | fonts/hindmadurai/latex/LY1HindMadurai-TLF.fd -2021/01/09 | 1852 | fonts/hindmadurai/tfm/HindMadurai-SemiBold-tlf-ly1.tfm -2021/01/09 | 1852 | fonts/hindmadurai/tfm/HindMadurai-Medium-tlf-ly1.tfm -2021/01/09 | 1848 | fonts/magra/tfm/Magra-tlf-ly1--base.tfm -2021/01/09 | 1844 | fonts/gudea/tfm/Gudea-Bold-tlf-ly1--base.tfm -2021/01/09 | 1840 | fonts/magra/tfm/Magra-Bold-tlf-t1--base.tfm -2021/01/09 | 1840 | fonts/hindmadurai/tfm/HindMadurai-Regular-tlf-ly1--base.tfm -2021/01/09 | 1840 | fonts/hindmadurai/tfm/HindMadurai-Light-tlf-ly1--base.tfm -2021/01/09 | 18405 | macros/latex-dev/base/nfssfont.dtx -2021/01/09 | 1839 | fonts/hindmadurai/latex/T1HindMadurai-TLF.fd -2021/01/09 | 1836 | fonts/magra/tfm/Magra-tlf-t1.tfm -2021/01/09 | 1836 | fonts/hindmadurai/tfm/HindMadurai-Light-tlf-t1.tfm -2021/01/09 | 1836 | fonts/gudea/tfm/Gudea-tlf-ly1--base.tfm -2021/01/09 | 1834 | fonts/magra/latex/Magra.sty -2021/01/09 | 1834 | fonts/gudea/latex/Gudea.sty -2021/01/09 | 18305 | macros/latex-dev/base/ifthen.dtx -2021/01/09 | 18300 | macros/latex-dev/base/ltx3info.tex -2021/01/09 | 1824 | fonts/play-font/tfm/Play-Bold-tlf-sc-ly1.tfm -2021/01/09 | 1824 | fonts/play-font/tfm/Play-Bold-lf-sc-ly1.tfm -2021/01/09 | 182272 | fonts/play-font/type1/Play-Regular.pfb -2021/01/09 | 1820 | fonts/hindmadurai/tfm/HindMadurai-Regular-tlf-t1.tfm -2021/01/09 | 181871 | macros/latex-dev/base/syntonly.pdf -2021/01/09 | 181816 | macros/latex-dev/base/usrguide3.pdf -2021/01/09 | 1816 | fonts/hindmadurai/tfm/HindMadurai-Bold-tlf-ly1--base.tfm -2021/01/09 | 1812 | fonts/play-font/tfm/Play-Bold-tosf-sc-ly1.tfm -2021/01/09 | 1812 | fonts/play-font/tfm/Play-Bold-osf-sc-ly1.tfm -2021/01/09 | 180 | macros/latex-dev/base/ltfilehook-doc.tex -2021/01/09 | 1808 | fonts/hindmadurai/tfm/HindMadurai-SemiBold-tlf-ly1--base.tfm -2021/01/09 | 1808 | fonts/hindmadurai/tfm/HindMadurai-Medium-tlf-ly1--base.tfm -2021/01/09 | 1808 | fonts/hindmadurai/tfm/HindMadurai-Bold-tlf-t1.tfm -2021/01/09 | 1804 | fonts/hindmadurai/tfm/HindMadurai-SemiBold-tlf-t1.tfm -2021/01/09 | 1804 | fonts/hindmadurai/tfm/HindMadurai-Medium-tlf-t1.tfm -2021/01/09 | 180251 | fonts/hindmadurai/type1/HindMadurai-Bold.pfb -2021/01/09 | 179 | macros/latex-dev/base/ltshipout-doc.tex -2021/01/09 | 1784 | fonts/play-font/tfm/Play-Regular-tlf-sc-ly1.tfm -2021/01/09 | 1784 | fonts/play-font/tfm/Play-Regular-lf-sc-ly1.tfm -2021/01/09 | 1784 | fonts/play-font/tfm/Play-Bold-tosf-ly1.tfm -2021/01/09 | 1784 | fonts/play-font/tfm/Play-Bold-tlf-ly1.tfm -2021/01/09 | 1784 | fonts/play-font/tfm/Play-Bold-osf-ly1.tfm -2021/01/09 | 1784 | fonts/play-font/tfm/Play-Bold-lf-ly1.tfm -2021/01/09 | 1784 | fonts/magra/tfm/Magra-tlf-t1--base.tfm -2021/01/09 | 1780 | fonts/hindmadurai/tfm/HindMadurai-Light-tlf-t1--base.tfm -2021/01/09 | 177 | macros/latex-dev/base/lthooks-doc.tex -2021/01/09 | 1776 | fonts/play-font/tfm/Play-Bold-tlf-sc-t1.tfm -2021/01/09 | 1776 | fonts/play-font/tfm/Play-Bold-lf-sc-t1.tfm -2021/01/09 | 1768 | fonts/play-font/tfm/Play-Bold-tosf-sc-t1.tfm -2021/01/09 | 1768 | fonts/play-font/tfm/Play-Bold-osf-sc-t1.tfm -2021/01/09 | 1768 | fonts/hindmadurai/tfm/HindMadurai-Regular-tlf-t1--base.tfm -2021/01/09 | 176141 | macros/latex/contrib/pdfpages/pdfpages.dtx -2021/01/09 | 175626 | macros/latex-dev/base/ltoutput.dtx -2021/01/09 | 1752 | fonts/play-font/tfm/Play-Regular-tosf-sc-ly1.tfm -2021/01/09 | 1752 | fonts/play-font/tfm/Play-Regular-tlf-sc-t1.tfm -2021/01/09 | 1752 | fonts/play-font/tfm/Play-Regular-osf-sc-ly1.tfm -2021/01/09 | 1752 | fonts/play-font/tfm/Play-Regular-lf-sc-t1.tfm -2021/01/09 | 1752 | fonts/play-font/tfm/Play-Bold-tosf-t1.tfm -2021/01/09 | 1752 | fonts/play-font/tfm/Play-Bold-tlf-t1.tfm -2021/01/09 | 1752 | fonts/play-font/tfm/Play-Bold-osf-t1.tfm -2021/01/09 | 1752 | fonts/play-font/tfm/Play-Bold-lf-t1.tfm -2021/01/09 | 1752 | fonts/hindmadurai/tfm/HindMadurai-SemiBold-tlf-t1--base.tfm -2021/01/09 | 1752 | fonts/hindmadurai/tfm/HindMadurai-Bold-tlf-t1--base.tfm -2021/01/09 | 1752 | fonts/gudea/tfm/Gudea-Bold-tlf-t1--base.tfm -2021/01/09 | 17496 | macros/latex-dev/base/cyrguide.tex -2021/01/09 | 1748 | fonts/hindmadurai/tfm/HindMadurai-Medium-tlf-t1--base.tfm -2021/01/09 | 1744 | fonts/gudea/tfm/Gudea-tlf-t1--base.tfm -2021/01/09 | 173772 | fonts/play-font/opentype/Play-Bold.otf -2021/01/09 | 1736 | fonts/play-font/tfm/Play-Regular-tosf-t1.tfm -2021/01/09 | 1736 | fonts/play-font/tfm/Play-Regular-tosf-ly1.tfm -2021/01/09 | 1736 | fonts/play-font/tfm/Play-Regular-tlf-t1.tfm -2021/01/09 | 1736 | fonts/play-font/tfm/Play-Regular-tlf-ly1.tfm -2021/01/09 | 1736 | fonts/play-font/tfm/Play-Regular-osf-t1.tfm -2021/01/09 | 1736 | fonts/play-font/tfm/Play-Regular-osf-ly1.tfm -2021/01/09 | 1736 | fonts/play-font/tfm/Play-Regular-lf-t1.tfm -2021/01/09 | 1736 | fonts/play-font/tfm/Play-Regular-lf-ly1.tfm -2021/01/09 | 1732 | fonts/play-font/vf/Play-Regular-tosf-sc-t1.vf -2021/01/09 | 1732 | fonts/play-font/vf/Play-Regular-tlf-sc-t1.vf -2021/01/09 | 1732 | fonts/play-font/vf/Play-Regular-osf-sc-t1.vf -2021/01/09 | 1732 | fonts/play-font/tfm/Play-Bold-tlf-sc-ly1--base.tfm -2021/01/09 | 1732 | fonts/play-font/tfm/Play-Bold-lf-sc-ly1--base.tfm -2021/01/09 | 172976 | fonts/play-font/opentype/Play-Regular.otf -2021/01/09 | 1728 | fonts/play-font/vf/Play-Regular-lf-sc-t1.vf -2021/01/09 | 1728 | fonts/play-font/vf/Play-Bold-tosf-sc-t1.vf -2021/01/09 | 1728 | fonts/play-font/vf/Play-Bold-tlf-sc-t1.vf -2021/01/09 | 1728 | fonts/play-font/vf/Play-Bold-osf-sc-t1.vf -2021/01/09 | 1728 | fonts/play-font/vf/Play-Bold-lf-sc-t1.vf -2021/01/09 | 1728 | fonts/hindmadurai/vf/HindMadurai-SemiBold-tlf-t1.vf -2021/01/09 | 172584 | macros/latex-dev/base/alltt.pdf -2021/01/09 | 1724 | fonts/play-font/tfm/Play-Regular-tosf-sc-t1.tfm -2021/01/09 | 1724 | fonts/play-font/tfm/Play-Regular-osf-sc-t1.tfm -2021/01/09 | 1724 | fonts/hindmadurai/vf/HindMadurai-Regular-tlf-t1.vf -2021/01/09 | 1724 | fonts/hindmadurai/vf/HindMadurai-Medium-tlf-t1.vf -2021/01/09 | 172216 | macros/latex-dev/base/tlc2.err -2021/01/09 | 172216 | fonts/hindmadurai/opentype/HindMadurai-Medium.otf -2021/01/09 | 1720 | fonts/play-font/vf/Play-Regular-tosf-t1.vf -2021/01/09 | 1720 | fonts/play-font/vf/Play-Regular-tlf-t1.vf -2021/01/09 | 1720 | fonts/play-font/vf/Play-Regular-osf-t1.vf -2021/01/09 | 1720 | fonts/play-font/vf/Play-Regular-lf-t1.vf -2021/01/09 | 1720 | fonts/play-font/vf/Play-Bold-tosf-t1.vf -2021/01/09 | 1720 | fonts/play-font/tfm/Play-Bold-tosf-sc-ly1--base.tfm -2021/01/09 | 1720 | fonts/play-font/tfm/Play-Bold-osf-sc-ly1--base.tfm -2021/01/09 | 1720 | fonts/hindmadurai/vf/HindMadurai-SemiBold-tlf-ly1.vf -2021/01/09 | 1720 | fonts/hindmadurai/vf/HindMadurai-Light-tlf-t1.vf -2021/01/09 | 1720 | fonts/hindmadurai/vf/HindMadurai-Bold-tlf-t1.vf -2021/01/09 | 1720 | fonts/gudea/vf/Gudea-Italic-tlf-ly1.vf -2021/01/09 | 1716 | fonts/play-font/vf/Play-Regular-tosf-sc-ly1.vf -2021/01/09 | 1716 | fonts/play-font/vf/Play-Regular-tlf-sc-ly1.vf -2021/01/09 | 1716 | fonts/play-font/vf/Play-Regular-osf-sc-ly1.vf -2021/01/09 | 1716 | fonts/play-font/vf/Play-Regular-lf-sc-ly1.vf -2021/01/09 | 1716 | fonts/play-font/vf/Play-Bold-tlf-t1.vf -2021/01/09 | 1716 | fonts/play-font/vf/Play-Bold-osf-t1.vf -2021/01/09 | 1716 | fonts/play-font/vf/Play-Bold-lf-t1.vf -2021/01/09 | 1716 | fonts/play-font/tfm/Play-Bold-tosf-ly1--base.tfm -2021/01/09 | 1716 | fonts/play-font/tfm/Play-Bold-tlf-ly1--base.tfm -2021/01/09 | 1716 | fonts/play-font/tfm/Play-Bold-osf-ly1--base.tfm -2021/01/09 | 1716 | fonts/play-font/tfm/Play-Bold-lf-ly1--base.tfm -2021/01/09 | 1716 | fonts/hindmadurai/vf/HindMadurai-Regular-tlf-ly1.vf -2021/01/09 | 1716 | fonts/hindmadurai/vf/HindMadurai-Medium-tlf-ly1.vf -2021/01/09 | 1716 | fonts/gudea/vf/Gudea-Bold-tlf-ly1.vf -2021/01/09 | 171452 | fonts/hindmadurai/opentype/HindMadurai-SemiBold.otf -2021/01/09 | 171367 | macros/latex/contrib/biblatex-contrib/biblatex-software/software-biblatex.pdf -2021/01/09 | 1712 | fonts/play-font/vf/Play-Bold-tosf-sc-ly1.vf -2021/01/09 | 1712 | fonts/play-font/vf/Play-Bold-tlf-sc-ly1.vf -2021/01/09 | 1712 | fonts/play-font/vf/Play-Bold-osf-sc-ly1.vf -2021/01/09 | 1712 | fonts/play-font/vf/Play-Bold-lf-sc-ly1.vf -2021/01/09 | 1712 | fonts/hindmadurai/vf/HindMadurai-Light-tlf-ly1.vf -2021/01/09 | 1712 | fonts/hindmadurai/vf/HindMadurai-Bold-tlf-ly1.vf -2021/01/09 | 171012 | fonts/hindmadurai/opentype/HindMadurai-Regular.otf -2021/01/09 | 1708 | fonts/play-font/tfm/Play-Bold-sup-ly1.tfm -2021/01/09 | 1704 | fonts/play-font/vf/Play-Regular-tosf-ly1.vf -2021/01/09 | 1704 | fonts/play-font/vf/Play-Regular-tlf-ly1.vf -2021/01/09 | 1704 | fonts/play-font/vf/Play-Regular-osf-ly1.vf -2021/01/09 | 1704 | fonts/play-font/vf/Play-Regular-lf-ly1.vf -2021/01/09 | 1704 | fonts/play-font/vf/Play-Bold-tosf-ly1.vf -2021/01/09 | 1704 | fonts/play-font/tfm/Play-Bold-sup-ly1--base.tfm -2021/01/09 | 1704 | fonts/gudea/vf/Gudea-tlf-ly1.vf -2021/01/09 | 170215 | macros/latex-dev/base/docstrip.dtx -2021/01/09 | 1700 | fonts/play-font/vf/Play-Bold-tlf-ly1.vf -2021/01/09 | 1700 | fonts/play-font/vf/Play-Bold-osf-ly1.vf -2021/01/09 | 1700 | fonts/play-font/vf/Play-Bold-lf-ly1.vf -2021/01/09 | 1694 | macros/latex-dev/base/small2e.tex -2021/01/09 | 1692 | fonts/play-font/vf/Play-Regular-sup-t1.vf -2021/01/09 | 1692 | fonts/play-font/tfm/Play-Regular-tlf-sc-ly1--base.tfm -2021/01/09 | 1692 | fonts/play-font/tfm/Play-Regular-lf-sc-ly1--base.tfm -2021/01/09 | 1688 | fonts/play-font/vf/Play-Bold-sup-t1.vf -2021/01/09 | 1688 | fonts/magra/vf/Magra-Bold-tlf-t1.vf -2021/01/09 | 1684 | fonts/magra/vf/Magra-tlf-t1.vf -2021/01/09 | 1680 | fonts/play-font/tfm/Play-Bold-tosf-t1--base.tfm -2021/01/09 | 1680 | fonts/play-font/tfm/Play-Bold-tlf-t1--base.tfm -2021/01/09 | 1680 | fonts/play-font/tfm/Play-Bold-sup-t1.tfm -2021/01/09 | 1680 | fonts/play-font/tfm/Play-Bold-osf-t1--base.tfm -2021/01/09 | 1680 | fonts/play-font/tfm/Play-Bold-lf-t1--base.tfm -2021/01/09 | 1676 | fonts/play-font/vf/Play-Regular-sup-ly1.vf -2021/01/09 | 1676 | fonts/play-font/tfm/Play-Bold-tlf-sc-t1--base.tfm -2021/01/09 | 1676 | fonts/play-font/tfm/Play-Bold-lf-sc-t1--base.tfm -2021/01/09 | 167448 | macros/latex-dev/base/lthooks.dtx -2021/01/09 | 1672 | fonts/play-font/vf/Play-Bold-sup-ly1.vf -2021/01/09 | 1672 | fonts/play-font/tfm/Play-Bold-sup-t1--base.tfm -2021/01/09 | 1668 | fonts/play-font/tfm/Play-Regular-tosf-ly1--base.tfm -2021/01/09 | 1668 | fonts/play-font/tfm/Play-Regular-tlf-ly1--base.tfm -2021/01/09 | 1668 | fonts/play-font/tfm/Play-Regular-osf-ly1--base.tfm -2021/01/09 | 1668 | fonts/play-font/tfm/Play-Regular-lf-ly1--base.tfm -2021/01/09 | 1668 | fonts/play-font/tfm/Play-Bold-tosf-sc-t1--base.tfm -2021/01/09 | 1668 | fonts/play-font/tfm/Play-Bold-osf-sc-t1--base.tfm -2021/01/09 | 166680 | fonts/hindmadurai/opentype/HindMadurai-Light.otf -2021/01/09 | 1664 | fonts/play-font/tfm/Play-Regular-tosf-t1--base.tfm -2021/01/09 | 1664 | fonts/play-font/tfm/Play-Regular-tlf-t1--base.tfm -2021/01/09 | 1664 | fonts/play-font/tfm/Play-Regular-sup-t1.tfm -2021/01/09 | 1664 | fonts/play-font/tfm/Play-Regular-osf-t1--base.tfm -2021/01/09 | 1664 | fonts/play-font/tfm/Play-Regular-lf-t1--base.tfm -2021/01/09 | 1660 | fonts/play-font/tfm/Play-Regular-tosf-sc-ly1--base.tfm -2021/01/09 | 1660 | fonts/play-font/tfm/Play-Regular-sup-ly1.tfm -2021/01/09 | 1660 | fonts/play-font/tfm/Play-Regular-osf-sc-ly1--base.tfm -2021/01/09 | 1660 | fonts/magra/vf/Magra-Bold-tlf-ly1.vf -2021/01/09 | 1656 | fonts/play-font/tfm/Play-Regular-sup-t1--base.tfm -2021/01/09 | 1656 | fonts/play-font/tfm/Play-Regular-sup-ly1--base.tfm -2021/01/09 | 1652 | fonts/play-font/tfm/Play-Regular-tlf-sc-t1--base.tfm -2021/01/09 | 1652 | fonts/play-font/tfm/Play-Regular-lf-sc-t1--base.tfm -2021/01/09 | 1652 | fonts/magra/vf/Magra-tlf-ly1.vf -2021/01/09 | 164952 | macros/latex-dev/base/tlc2.pdf -2021/01/09 | 164409 | macros/latex/contrib/l3kernel/l3news11.pdf -2021/01/09 | 16276 | macros/latex/contrib/l3backend/l3backend-basics.dtx -2021/01/09 | 1624 | fonts/play-font/tfm/Play-Regular-tosf-sc-t1--base.tfm -2021/01/09 | 1624 | fonts/play-font/tfm/Play-Regular-osf-sc-t1--base.tfm -2021/01/09 | 16234 | macros/latex-dev/base/modguide.tex -2021/01/09 | 16106 | macros/latex-dev/base/ltbibl.dtx -2021/01/09 | 161063 | macros/latex-dev/base/ltnews13.pdf -2021/01/09 | 160868 | fonts/hindmadurai/opentype/HindMadurai-Bold.otf -2021/01/09 | 160836 | fonts/libertinus-fonts/documentation/Math-Sample.pdf -2021/01/09 | 160668 | macros/latex-dev/base/makeindx.pdf -2021/01/09 | 1592 | fonts/gudea/tfm/Gudea-Italic-tlf-ot1.tfm -2021/01/09 | 15758 | fonts/libertinus-fonts/FONTLOG.txt -2021/01/09 | 1573631 | macros/latex/contrib/l3kernel/interface3.pdf -2021/01/09 | 157182 | macros/latex-dev/base/ltnews05.pdf -2021/01/09 | 15701 | macros/latex-dev/base/slifonts.fdd -2021/01/09 | 156 | fonts/hindmadurai/tfm/HindMadurai-SemiBold-tlf-t1--lcdfj.tfm -2021/01/09 | 156 | fonts/hindmadurai/tfm/HindMadurai-SemiBold-tlf-ot1--lcdfj.tfm -2021/01/09 | 156 | fonts/hindmadurai/tfm/HindMadurai-SemiBold-tlf-ly1--lcdfj.tfm -2021/01/09 | 156 | fonts/hindmadurai/tfm/HindMadurai-Regular-tlf-t1--lcdfj.tfm -2021/01/09 | 156 | fonts/hindmadurai/tfm/HindMadurai-Regular-tlf-ot1--lcdfj.tfm -2021/01/09 | 156 | fonts/hindmadurai/tfm/HindMadurai-Regular-tlf-ly1--lcdfj.tfm -2021/01/09 | 156 | fonts/hindmadurai/tfm/HindMadurai-Medium-tlf-t1--lcdfj.tfm -2021/01/09 | 156 | fonts/hindmadurai/tfm/HindMadurai-Medium-tlf-ot1--lcdfj.tfm -2021/01/09 | 156 | fonts/hindmadurai/tfm/HindMadurai-Medium-tlf-ly1--lcdfj.tfm -2021/01/09 | 156 | fonts/hindmadurai/tfm/HindMadurai-Light-tlf-t1--lcdfj.tfm -2021/01/09 | 156 | fonts/hindmadurai/tfm/HindMadurai-Light-tlf-ot1--lcdfj.tfm -2021/01/09 | 156 | fonts/hindmadurai/tfm/HindMadurai-Light-tlf-ly1--lcdfj.tfm -2021/01/09 | 156 | fonts/hindmadurai/tfm/HindMadurai-Bold-tlf-t1--lcdfj.tfm -2021/01/09 | 156 | fonts/hindmadurai/tfm/HindMadurai-Bold-tlf-ot1--lcdfj.tfm -2021/01/09 | 156 | fonts/hindmadurai/tfm/HindMadurai-Bold-tlf-ly1--lcdfj.tfm -2021/01/09 | 156546 | macros/latex-dev/base/tulm.pdf -2021/01/09 | 1562 | fonts/play-font/latex/OT1Play-TOsF.fd -2021/01/09 | 1562 | fonts/play-font/latex/LY1Play-TOsF.fd -2021/01/09 | 156276 | macros/latex-dev/base/graphpap.pdf -2021/01/09 | 15626 | macros/latex-dev/base/ltxref.dtx -2021/01/09 | 155946 | macros/latex-dev/base/classes.dtx -2021/01/09 | 1545 | fonts/play-font/latex/T1Play-TOsF.fd -2021/01/09 | 1539 | fonts/play-font/latex/OT1Play-TLF.fd -2021/01/09 | 1539 | fonts/play-font/latex/OT1Play-OsF.fd -2021/01/09 | 1539 | fonts/play-font/latex/LY1Play-TLF.fd -2021/01/09 | 1539 | fonts/play-font/latex/LY1Play-OsF.fd -2021/01/09 | 1532142 | macros/latex-dev/base/encguide.pdf -2021/01/09 | 152504 | macros/latex/contrib/l3kernel/l3news08.pdf -2021/01/09 | 1522 | fonts/play-font/latex/T1Play-TLF.fd -2021/01/09 | 1522 | fonts/play-font/latex/T1Play-OsF.fd -2021/01/09 | 1516 | fonts/play-font/latex/OT1Play-LF.fd -2021/01/09 | 1516 | fonts/play-font/latex/LY1Play-LF.fd -2021/01/09 | 151352 | macros/latex-dev/base/manual.pdf -2021/01/09 | 150913 | macros/latex-dev/base/ltnews14.pdf -2021/01/09 | 150020 | macros/latex-dev/base/ltnews01.pdf -2021/01/09 | 1499 | fonts/play-font/latex/T1Play-LF.fd -2021/01/09 | 149848 | macros/latex-dev/base/ltnews17.pdf -2021/01/09 | 149377 | macros/latex/contrib/l3kernel/l3doc.dtx -2021/01/09 | 14918 | macros/latex-dev/base/source2e.tex -2021/01/09 | 14913 | macros/latex/contrib/l3kernel/l3news12.tex -2021/01/09 | 148 | fonts/gudea/tfm/Gudea-tlf-t1--lcdfj.tfm -2021/01/09 | 148 | fonts/gudea/tfm/Gudea-tlf-ot1--lcdfj.tfm -2021/01/09 | 148 | fonts/gudea/tfm/Gudea-tlf-ly1--lcdfj.tfm -2021/01/09 | 148 | fonts/gudea/tfm/Gudea-Italic-tlf-t1--lcdfj.tfm -2021/01/09 | 148 | fonts/gudea/tfm/Gudea-Italic-tlf-ot1--lcdfj.tfm -2021/01/09 | 148 | fonts/gudea/tfm/Gudea-Italic-tlf-ly1--lcdfj.tfm -2021/01/09 | 148 | fonts/gudea/tfm/Gudea-Bold-tlf-t1--lcdfj.tfm -2021/01/09 | 148 | fonts/gudea/tfm/Gudea-Bold-tlf-ot1--lcdfj.tfm -2021/01/09 | 148 | fonts/gudea/tfm/Gudea-Bold-tlf-ly1--lcdfj.tfm -2021/01/09 | 1489756 | systems/texlive/tlnet/archive/nicematrix.doc.r57352.tar.xz -2021/01/09 | 14892 | macros/latex-dev/base/ltnews28.tex -2021/01/09 | 1480 | fonts/gudea/tfm/Gudea-Bold-tlf-ot1.tfm -2021/01/09 | 147944 | macros/latex-dev/base/ltnews10.pdf -2021/01/09 | 14708 | macros/latex/contrib/l3kernel/l3bootstrap.dtx -2021/01/09 | 14699 | macros/latex/contrib/l3backend/l3backend-header.dtx -2021/01/09 | 1468 | fonts/gudea/tfm/Gudea-tlf-ot1.tfm -2021/01/09 | 1468 | fonts/gudea/latex/TS1Gudea-TLF.fd -2021/01/09 | 1468 | fonts/gudea/latex/OT1Gudea-TLF.fd -2021/01/09 | 1468 | fonts/gudea/latex/LY1Gudea-TLF.fd -2021/01/09 | 1460 | fonts/gudea/tfm/Gudea-Italic-tlf-ts1.tfm -2021/01/09 | 145548 | macros/latex/contrib/l3kernel/l3news10.pdf -2021/01/09 | 1453 | fonts/gudea/latex/T1Gudea-TLF.fd -2021/01/09 | 1452 | fonts/gudea/tfm/Gudea-Italic-tlf-ts1--base.tfm -2021/01/09 | 145164 | macros/latex-dev/base/ltoutenc.dtx -2021/01/09 | 1444 | fonts/gudea/tfm/Gudea-Italic-tlf-ot1--base.tfm -2021/01/09 | 144483 | macros/latex-dev/base/ltnews08.pdf -2021/01/09 | 14421 | macros/latex-dev/base/lppl-1-2.txt -2021/01/09 | 14406 | macros/latex/contrib/l3backend/l3backend-box.dtx -2021/01/09 | 14341 | macros/latex-dev/base/lppl-1-1.txt -2021/01/09 | 1432 | fonts/magra/tfm/Magra-Bold-tlf-ts1.tfm -2021/01/09 | 1432824 | fonts/hindmadurai.zip -2021/01/09 | 143207 | macros/latex/contrib/l3kernel/l3news03.pdf -2021/01/09 | 1428 | fonts/magra/tfm/Magra-Bold-tlf-ts1--base.tfm -2021/01/09 | 1424 | fonts/magra/tfm/Magra-tlf-ts1.tfm -2021/01/09 | 1420 | fonts/gudea/vf/Gudea-Italic-tlf-t1.vf -2021/01/09 | 1416 | fonts/gudea/vf/Gudea-Bold-tlf-t1.vf -2021/01/09 | 1412 | fonts/hindmadurai/tfm/HindMadurai-Regular-tlf-ts1.tfm -2021/01/09 | 140905 | macros/latex/contrib/l3kernel/l3news06.pdf -2021/01/09 | 1408 | fonts/magra/tfm/Magra-tlf-ts1--base.tfm -2021/01/09 | 1408 | fonts/gudea/tfm/Gudea-tlf-ts1.tfm -2021/01/09 | 1408 | fonts/gudea/tfm/Gudea-Bold-tlf-ts1.tfm -2021/01/09 | 140873 | macros/latex/contrib/l3kernel/l3news02.pdf -2021/01/09 | 1404 | fonts/hindmadurai/tfm/HindMadurai-Medium-tlf-ts1.tfm -2021/01/09 | 1404 | fonts/hindmadurai/tfm/HindMadurai-Light-tlf-ts1.tfm -2021/01/09 | 1404 | fonts/gudea/vf/Gudea-tlf-t1.vf -2021/01/09 | 1404 | fonts/gudea/tfm/Gudea-tlf-ts1--base.tfm -2021/01/09 | 140409 | macros/latex/contrib/l3kernel/l3tl.dtx -2021/01/09 | 1402 | fonts/libertinus-fonts/CONTRIBUTING.md -2021/01/09 | 1400 | fonts/play-font/tfm/Play-Bold-tlf-sc-ot1.tfm -2021/01/09 | 1400 | fonts/play-font/tfm/Play-Bold-lf-sc-ot1.tfm -2021/01/09 | 1400 | fonts/hindmadurai/tfm/HindMadurai-Regular-tlf-ts1--base.tfm -2021/01/09 | 1400 | fonts/hindmadurai/tfm/HindMadurai-Bold-tlf-ts1.tfm -2021/01/09 | 1400 | fonts/gudea/tfm/Gudea-Bold-tlf-ts1--base.tfm -2021/01/09 | 1396 | fonts/play-font/tfm/Play-Regular-tlf-sc-ot1.tfm -2021/01/09 | 1396 | fonts/play-font/tfm/Play-Regular-lf-sc-ot1.tfm -2021/01/09 | 1396 | fonts/play-font/tfm/Play-Bold-tosf-sc-ot1.tfm -2021/01/09 | 1396 | fonts/play-font/tfm/Play-Bold-osf-sc-ot1.tfm -2021/01/09 | 1392 | fonts/hindmadurai/tfm/HindMadurai-Medium-tlf-ts1--base.tfm -2021/01/09 | 1392 | fonts/hindmadurai/tfm/HindMadurai-Light-tlf-ts1--base.tfm -2021/01/09 | 1388 | fonts/hindmadurai/tfm/HindMadurai-SemiBold-tlf-ts1.tfm -2021/01/09 | 1388 | fonts/hindmadurai/tfm/HindMadurai-Bold-tlf-ts1--base.tfm -2021/01/09 | 1382 | macros/latex/contrib/pdfpages/README -2021/01/09 | 138221 | macros/latex-dev/base/lb2.pdf -2021/01/09 | 1381 | macros/latex-dev/base/legal.txt -2021/01/09 | 1380 | fonts/play-font/tfm/Play-Regular-tosf-sc-ot1.tfm -2021/01/09 | 1380 | fonts/play-font/tfm/Play-Regular-osf-sc-ot1.tfm -2021/01/09 | 1380 | fonts/hindmadurai/tfm/HindMadurai-SemiBold-tlf-ts1--base.tfm -2021/01/09 | 137922 | macros/latex-dev/base/ltnews12.pdf -2021/01/09 | 1372 | fonts/play-font/tfm/Play-Regular-tosf-ot1.tfm -2021/01/09 | 1372 | fonts/play-font/tfm/Play-Regular-osf-ot1.tfm -2021/01/09 | 1372 | fonts/play-font/tfm/Play-Bold-tosf-ot1.tfm -2021/01/09 | 1372 | fonts/play-font/tfm/Play-Bold-osf-ot1.tfm -2021/01/09 | 13703 | macros/latex-dev/base/ltexpl.dtx -2021/01/09 | 1368 | fonts/play-font/tfm/Play-Bold-tlf-ot1.tfm -2021/01/09 | 1368 | fonts/play-font/tfm/Play-Bold-lf-ot1.tfm -2021/01/09 | 1364 | fonts/play-font/tfm/Play-Regular-tlf-ot1.tfm -2021/01/09 | 1364 | fonts/play-font/tfm/Play-Regular-lf-ot1.tfm -2021/01/09 | 136162 | macros/latex-dev/base/webcomp.pdf -2021/01/09 | 1352 | fonts/play-font/tfm/Play-Bold-tosf-ts1.tfm -2021/01/09 | 1352 | fonts/play-font/tfm/Play-Bold-tlf-ts1.tfm -2021/01/09 | 1352 | fonts/play-font/tfm/Play-Bold-osf-ts1.tfm -2021/01/09 | 1352 | fonts/play-font/tfm/Play-Bold-lf-ts1.tfm -2021/01/09 | 1352 | fonts/hindmadurai/tfm/HindMadurai-Light-tlf-ot1.tfm -2021/01/09 | 134751 | macros/latex-dev/base/ltnews02.pdf -2021/01/09 | 134739 | macros/latex-dev/base/ltnews03.pdf -2021/01/09 | 1342 | macros/latex-dev/base/ltnews18.tex -2021/01/09 | 1340 | fonts/hindmadurai/tfm/HindMadurai-Regular-tlf-ot1.tfm -2021/01/09 | 1332 | fonts/play-font/tfm/Play-Bold-tosf-ts1--base.tfm -2021/01/09 | 1332 | fonts/play-font/tfm/Play-Bold-tlf-ts1--base.tfm -2021/01/09 | 1332 | fonts/play-font/tfm/Play-Bold-osf-ts1--base.tfm -2021/01/09 | 1332 | fonts/play-font/tfm/Play-Bold-lf-ts1--base.tfm -2021/01/09 | 1332 | fonts/gudea/tfm/Gudea-Bold-tlf-ot1--base.tfm -2021/01/09 | 133141 | macros/latex-dev/base/ltnews06.pdf -2021/01/09 | 13306 | macros/latex-dev/base/proc.dtx -2021/01/09 | 1328 | fonts/play-font/tfm/Play-Regular-tosf-ts1.tfm -2021/01/09 | 1328 | fonts/play-font/tfm/Play-Regular-tlf-ts1.tfm -2021/01/09 | 1328 | fonts/play-font/tfm/Play-Regular-osf-ts1.tfm -2021/01/09 | 1328 | fonts/play-font/tfm/Play-Regular-lf-ts1.tfm -2021/01/09 | 1328 | fonts/hindmadurai/tfm/HindMadurai-SemiBold-tlf-ot1.tfm -2021/01/09 | 1328 | fonts/hindmadurai/tfm/HindMadurai-Medium-tlf-ot1.tfm -2021/01/09 | 1324 | fonts/hindmadurai/tfm/HindMadurai-Bold-tlf-ot1.tfm -2021/01/09 | 132352 | macros/latex/contrib/l3kernel/l3file.dtx -2021/01/09 | 1320 | fonts/hindmadurai/tfm/HindMadurai-Light-tlf-ot1--base.tfm -2021/01/09 | 1320 | fonts/gudea/tfm/Gudea-tlf-ot1--base.tfm -2021/01/09 | 1316 | fonts/magra/tfm/Magra-tlf-ot1.tfm -2021/01/09 | 1316 | fonts/magra/tfm/Magra-Bold-tlf-ot1.tfm -2021/01/09 | 1312 | fonts/play-font/tfm/Play-Regular-tosf-ts1--base.tfm -2021/01/09 | 1312 | fonts/play-font/tfm/Play-Regular-tlf-ts1--base.tfm -2021/01/09 | 1312 | fonts/play-font/tfm/Play-Regular-osf-ts1--base.tfm -2021/01/09 | 1312 | fonts/play-font/tfm/Play-Regular-lf-ts1--base.tfm -2021/01/09 | 1308 | fonts/hindmadurai/tfm/HindMadurai-Regular-tlf-ot1--base.tfm -2021/01/09 | 130689 | macros/latex-dev/base/ltnews16.pdf -2021/01/09 | 1298 | macros/latex/contrib/l3backend/l3backend-code.tex -2021/01/09 | 1296 | fonts/hindmadurai/tfm/HindMadurai-SemiBold-tlf-ot1--base.tfm -2021/01/09 | 1296 | fonts/hindmadurai/tfm/HindMadurai-Medium-tlf-ot1--base.tfm -2021/01/09 | 12965 | macros/latex/contrib/l3kernel/l3fp-traps.dtx -2021/01/09 | 12946 | macros/latex-dev/base/manual.err -2021/01/09 | 1292 | fonts/hindmadurai/tfm/HindMadurai-Bold-tlf-ot1--base.tfm -2021/01/09 | 128867 | macros/latex-dev/base/ltclass.dtx -2021/01/09 | 128773 | macros/latex-dev/base/ltnews04.pdf -2021/01/09 | 128718 | macros/latex/contrib/biblatex-contrib/biblatex-software/sample-use-sty.pdf -2021/01/09 | 127477 | macros/latex/contrib/l3kernel/l3basics.dtx -2021/01/09 | 1268 | fonts/play-font/tfm/Play-Bold-tlf-sc-ot1--base.tfm -2021/01/09 | 1268 | fonts/play-font/tfm/Play-Bold-lf-sc-ot1--base.tfm -2021/01/09 | 1264 | fonts/play-font/tfm/Play-Regular-tlf-sc-ot1--base.tfm -2021/01/09 | 1264 | fonts/play-font/tfm/Play-Regular-lf-sc-ot1--base.tfm -2021/01/09 | 1264 | fonts/play-font/tfm/Play-Bold-tosf-sc-ot1--base.tfm -2021/01/09 | 1264 | fonts/play-font/tfm/Play-Bold-osf-sc-ot1--base.tfm -2021/01/09 | 125830 | macros/latex-dev/base/lppl.pdf -2021/01/09 | 1252 | fonts/play-font/tfm/Play-Bold-sup-ot1.tfm -2021/01/09 | 12521 | macros/latex-dev/base/testpage.tex -2021/01/09 | 1248 | fonts/play-font/tfm/Play-Regular-tosf-sc-ot1--base.tfm -2021/01/09 | 1248 | fonts/play-font/tfm/Play-Regular-sup-ot1.tfm -2021/01/09 | 1248 | fonts/play-font/tfm/Play-Regular-osf-sc-ot1--base.tfm -2021/01/09 | 12470 | macros/latex/contrib/pdfpages/dummy-l.pdf -2021/01/09 | 124692 | macros/latex/contrib/l3kernel/l3token.dtx -2021/01/09 | 124030 | macros/latex-dev/base/ltnews07.pdf -2021/01/09 | 12225 | macros/latex-dev/base/ltnews24.tex -2021/01/09 | 122092 | macros/latex-dev/base/ltnews15.pdf -2021/01/09 | 12120 | macros/latex-dev/base/tulm.fdd -2021/01/09 | 12073412 | install/macros/latex/contrib/l3kernel.tds.zip -2021/01/09 | 120221 | macros/latex-dev/base/ltnews09.pdf -2021/01/09 | 119094 | macros/latex/contrib/l3kernel/l3news07.pdf -2021/01/09 | 11884 | macros/latex/contrib/l3kernel/l3styleguide.tex -2021/01/09 | 11846251 | macros/latex/contrib/l3kernel.zip -2021/01/09 | 11812 | macros/latex/contrib/l3kernel/l3fparray.dtx -2021/01/09 | 11591 | macros/latex-dev/base/ltpage.dtx -2021/01/09 | 115600158 | language/japanese/jlreq-deluxe.zip -2021/01/09 | 115125 | macros/latex/contrib/l3kernel/l3keys.dtx -2021/01/09 | 1144 | language/japanese/jlreq-deluxe/README.md -2021/01/09 | 114026 | macros/latex/contrib/l3kernel/l3str-convert.dtx -2021/01/09 | 113533 | macros/latex/contrib/l3kernel/l3news01.pdf -2021/01/09 | 1126 | fonts/play-font/latex/TS1Play-TOsF.fd -2021/01/09 | 1124 | fonts/magra/latex/TS1Magra-TLF.fd -2021/01/09 | 1124 | fonts/magra/latex/OT1Magra-TLF.fd -2021/01/09 | 1124 | fonts/magra/latex/LY1Magra-TLF.fd -2021/01/09 | 1114 | fonts/magra/latex/T1Magra-TLF.fd -2021/01/09 | 1113 | fonts/play-font/latex/TS1Play-TLF.fd -2021/01/09 | 1113 | fonts/play-font/latex/TS1Play-OsF.fd -2021/01/09 | 1113 | fonts/play-font/latex/OT1Play-Sup.fd -2021/01/09 | 1113 | fonts/play-font/latex/LY1Play-Sup.fd -2021/01/09 | 1103 | fonts/play-font/latex/T1Play-Sup.fd -2021/01/09 | 1100 | fonts/play-font/latex/TS1Play-LF.fd -2021/01/09 | 10896 | macros/latex/contrib/biblatex-contrib/biblatex-software/software-biblatex.tex -2021/01/09 | 1086 | language/japanese/jlreq-deluxe/LICENSE -2021/01/09 | 107921 | macros/latex/contrib/l3kernel/l3expan.dtx -2021/01/09 | 10748 | macros/latex-dev/base/manifest.txt -2021/01/09 | 107379 | macros/latex/contrib/l3kernel/l3news09.tex -2021/01/09 | 107122 | macros/latex/contrib/l3kernel/l3news04.pdf -2021/01/09 | 10698 | macros/latex-dev/base/ltnews26.tex -2021/01/09 | 106911 | macros/latex-dev/base/inputenc.dtx -2021/01/09 | 10688 | macros/latex-dev/base/ltnews23.tex -2021/01/09 | 10669 | macros/latex-dev/base/ltnews22.tex -2021/01/09 | 10606 | macros/latex-dev/base/makeindx.dtx -2021/01/09 | 105 | macros/latex-dev/base/ltfilehook-code.tex -2021/01/09 | 105735 | macros/latex/contrib/l3kernel/l3fp-parse.dtx -2021/01/09 | 105090 | macros/latex/contrib/l3kernel/l3news05.pdf -2021/01/09 | 104 | macros/latex-dev/base/ltshipout-code.tex -2021/01/09 | 104939 | macros/latex-dev/base/ltnews11.pdf -2021/01/09 | 10376 | macros/latex-dev/base/ltfsscmp.dtx -2021/01/09 | 10366 | macros/latex-dev/base/ltvers.dtx -2021/01/09 | 102 | macros/latex-dev/base/lthooks-code.tex -2021/01/09 | 101335 | macros/latex-dev/base/lgc2.pdf -2021/01/09 | 101288 | systems/texlive/tlnet/archive/musixtex.r57353.tar.xz -2021/01/09 | 10053 | macros/latex-dev/base/webcomp.err diff --git a/fonts/alfaslabone/README b/fonts/alfaslabone/README new file mode 100644 index 0000000000..b93f014f63 --- /dev/null +++ b/fonts/alfaslabone/README @@ -0,0 +1,26 @@ +This is the README for the alfaslabone package, version 0.0.1 (2021/01/16). + +This package provides LaTeX, pdfLaTeX support for the Alfa Slab One Regular +Font, designed by JM Solé. + +To use, add + + \usepackage{alfaslabone} + +to the preamble of your document. These will activate Alfa Slab One as the text font. + +Options scaled= or scale= may be used to scale the fonts. + +For example see at alfaslabone-samples.tex. + +Font encodings supported are OT1, T1, LY1. + +The original TrueType fonts were obtained from + + https://fonts.google.com/specimen/Alfa+Slab+One + +and are licensed under the SIL Open Font License, version 1.1; the text may be +found in the doc directory. The type1 versions were created using cfftot1. The +support files were created using autoinst and are licensed under the terms of +the LaTeX Project Public License. The maintainer of this package is Carl-Clemens +Ebinger at post(at)ebinger(dot)cc. diff --git a/fonts/alfaslabone/doc/LICENSE.TXT b/fonts/alfaslabone/doc/LICENSE.TXT new file mode 100644 index 0000000000..a12ec019f4 --- /dev/null +++ b/fonts/alfaslabone/doc/LICENSE.TXT @@ -0,0 +1,93 @@ +Copyright 2016 The Alfa Slab One Project Authors (http://www.jmsole.cl | info@jmsole.cl), with Reserved Font Name "Alfa Slab". + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/fonts/alfaslabone/doc/alfaslabone-samples.pdf b/fonts/alfaslabone/doc/alfaslabone-samples.pdf new file mode 100644 index 0000000000..b0d70132b1 Binary files /dev/null and b/fonts/alfaslabone/doc/alfaslabone-samples.pdf differ diff --git a/fonts/alfaslabone/doc/alfaslabone-samples.tex b/fonts/alfaslabone/doc/alfaslabone-samples.tex new file mode 100644 index 0000000000..307cf4b34e --- /dev/null +++ b/fonts/alfaslabone/doc/alfaslabone-samples.tex @@ -0,0 +1,25 @@ +\documentclass{article} +\usepackage[T1]{fontenc} +\usepackage[scaled=0.8]{alfaslabone} + +\usepackage{lipsum} +\begin{document} + +\subsection*{Regular} +\lipsum[1] + +\subsection*{Default Numbers} +1234567890 + +\subsection*{Tabular Numbers} +{\alfaslabonetabular 1234567890} + +%%NOT AVAILABLE +%%\subsection*{Proportional Numbers} +%%{\nunitoproportional 1234567890} + +\subsection*{Superscripts} +X{\sufigures 1234567890} + +\end{document} + diff --git a/fonts/alfaslabone/enc/a_5xld5w.enc b/fonts/alfaslabone/enc/a_5xld5w.enc new file mode 100644 index 0000000000..2a6cf23796 --- /dev/null +++ b/fonts/alfaslabone/enc/a_5xld5w.enc @@ -0,0 +1,63 @@ +% THIS FILE WAS AUTOMATICALLY GENERATED -- DO NOT EDIT + +%%AutoEnc_5xld5wrmxukokwwc7xt2m6qv4c +% Encoding created by otftotfm on Sat Jan 16 18:48:20 2021 +% Command line follows encoding +/AutoEnc_5xld5wrmxukokwwc7xt2m6qv4c [ +%00 + /.notdef /uni2206 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /uni2126 /.notdef /.notdef /.notdef /.notdef /.notdef +%10 + /dotlessi /uni0237 /grave /acute /caron /breve /macron /ring + /cedilla /germandbls /ae /oe /oslash /AE /OE /Oslash +%20 + /space /exclam /quotedblright /numbersign /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +%30 + /uni2070 /uni00B9 /uni00B2 /uni00B3 /uni2074 /uni2075 /uni2076 /uni2077 + /uni2078 /uni2079 /colon /semicolon /exclamdown /equal /questiondown /question +%40 + /at /A /B /C /D /E /F /G + /H /I /J /K /L /M /N /O +%50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /quotedblleft /bracketright /circumflex /dotaccent +%60 + /quoteleft /a /b /c /d /e /f /g + /h /i /j /k /l /m /n /o +%70 + /p /q /r /s /t /u /v /w + /x /y /z /endash /emdash /hungarumlaut /tilde /dieresis +%80 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /Lslash /.notdef /.notdef /.notdef /.notdef /.notdef +%90 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%A0 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /lslash /.notdef /.notdef /.notdef /.notdef /.notdef +%B0 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%C0 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%D0 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%E0 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%F0 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +] def +% Command line: 'otftotfm --automatic --encoding=fontools_ot1 +% --tfm-directory=texmf/fonts/tfm/public/alfaslabone +% --vf-directory=texmf/fonts/vf/public/alfaslabone +% --type1-directory=texmf/fonts/type1/public/alfaslabone +% --encoding-directory=texmf/fonts/enc/dvips/alfaslabone +% --map-file=texmf/fonts/map/dvips/alfaslabone/AlphaSlabOne.map --no-updmap +% --force --coding-scheme=TEX TEXT --feature=sups --ligkern=* {KL} * +% AlphaSlabOne-Regular.otf AlphaSlabOne-Regular-sup-ot1' diff --git a/fonts/alfaslabone/enc/a_adz5lu.enc b/fonts/alfaslabone/enc/a_adz5lu.enc new file mode 100644 index 0000000000..b753de9024 --- /dev/null +++ b/fonts/alfaslabone/enc/a_adz5lu.enc @@ -0,0 +1,65 @@ +% THIS FILE WAS AUTOMATICALLY GENERATED -- DO NOT EDIT + +%%AutoEnc_adz5lu2pubiora2jv2qajnuogc +% Encoding created by otftotfm on Sat Jan 16 18:48:19 2021 +% Command line follows encoding +/AutoEnc_adz5lu2pubiora2jv2qajnuogc [ +%00 + /.notdef /uni2206 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /uni2126 /.notdef /fi /fl /.notdef /.notdef +%10 + /dotlessi /uni0237 /grave /acute /caron /breve /macron /ring + /cedilla /germandbls /ae /oe /oslash /AE /OE /Oslash +%20 + /space /exclam /quotedblright /numbersign /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +%30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /exclamdown /equal /questiondown /question +%40 + /at /A /B /C /D /E /F /G + /H /I /J /K /L /M /N /O +%50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /quotedblleft /bracketright /circumflex /dotaccent +%60 + /quoteleft /a /b /c /d /e /f /g + /h /i /j /k /l /m /n /o +%70 + /p /q /r /s /t /u /v /w + /x /y /z /endash /emdash /hungarumlaut /tilde /dieresis +%80 + /f_f /f_f_i /f_f_l /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /Lslash /.notdef /.notdef /.notdef /.notdef /.notdef +%90 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%A0 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /lslash /.notdef /.notdef /.notdef /.notdef /.notdef +%B0 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%C0 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%D0 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%E0 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%F0 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +] def +% Command line: 'otftotfm --automatic --encoding=fontools_ot1 +% --tfm-directory=texmf/fonts/tfm/public/alfaslabone +% --vf-directory=texmf/fonts/vf/public/alfaslabone +% --type1-directory=texmf/fonts/type1/public/alfaslabone +% --encoding-directory=texmf/fonts/enc/dvips/alfaslabone +% --map-file=texmf/fonts/map/dvips/alfaslabone/AlphaSlabOne.map --no-updmap +% --force --coding-scheme=TEX TEXT --feature=kern --feature=liga --ligkern=f +% i =: fi --ligkern=f l =: fl --ligkern=f f =: ff --ligkern=ff i =: ffi +% --ligkern=ff l =: ffl AlphaSlabOne-Regular.otf +% AlphaSlabOne-Regular-tlf-ot1' diff --git a/fonts/alfaslabone/enc/a_d2anrk.enc b/fonts/alfaslabone/enc/a_d2anrk.enc new file mode 100644 index 0000000000..5d968e8275 --- /dev/null +++ b/fonts/alfaslabone/enc/a_d2anrk.enc @@ -0,0 +1,65 @@ +% THIS FILE WAS AUTOMATICALLY GENERATED -- DO NOT EDIT + +%%AutoEnc_d2anrk7dedw3rpwqsv7r3q7jag +% Encoding created by otftotfm on Sat Jan 16 18:48:20 2021 +% Command line follows encoding +/AutoEnc_d2anrk7dedw3rpwqsv7r3q7jag [ +%00 + /grave /acute /circumflex /tilde /dieresis /hungarumlaut /ring /caron + /breve /macron /dotaccent /cedilla /ogonek /quotesinglbase /guilsinglleft /guilsinglright +%10 + /quotedblleft /quotedblright /quotedblbase /guillemotleft /guillemotright /endash /emdash /.notdef + /f_f /dotlessi /uni0237 /f_f_i /fi /fl /f_f_l /.notdef +%20 + /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +%30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question +%40 + /at /A /B /C /D /E /F /G + /H /I /J /K /L /M /N /O +%50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +%60 + /quoteleft /a /b /c /d /e /f /g + /h /i /j /k /l /m /n /o +%70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde /hyphen +%80 + /Abreve /Aogonek /Cacute /Ccaron /Dcaron /Ecaron /Eogonek /Gbreve + /Lacute /Lcaron /Lslash /Nacute /Ncaron /Eng /Ohungarumlaut /Racute +%90 + /Rcaron /Sacute /Scaron /Scedilla /Tcaron /uni0162 /Uhungarumlaut /Uring + /Ydieresis /Zacute /Zcaron /Zdotaccent /IJ /Idotaccent /dcroat /section +%A0 + /abreve /aogonek /cacute /ccaron /dcaron /ecaron /eogonek /gbreve + /lacute /lcaron /lslash /nacute /ncaron /eng /ohungarumlaut /racute +%B0 + /rcaron /sacute /scaron /scedilla /tcaron /uni0163 /uhungarumlaut /uring + /ydieresis /zacute /zcaron /zdotaccent /ij /exclamdown /questiondown /sterling +%C0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis +%D0 + /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /OE + /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /.notdef +%E0 + /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis +%F0 + /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /oe + /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /germandbls +] def +% Command line: 'otftotfm --automatic --encoding=fontools_t1 +% --tfm-directory=texmf/fonts/tfm/public/alfaslabone +% --vf-directory=texmf/fonts/vf/public/alfaslabone +% --type1-directory=texmf/fonts/type1/public/alfaslabone +% --encoding-directory=texmf/fonts/enc/dvips/alfaslabone +% --map-file=texmf/fonts/map/dvips/alfaslabone/AlphaSlabOne.map --no-updmap +% --force --coding-scheme=EXTENDED TEX FONT ENCODING - LATIN --feature=kern +% --feature=liga --ligkern=f i =: fi --ligkern=f l =: fl --ligkern=f f =: ff +% --ligkern=ff i =: ffi --ligkern=ff l =: ffl AlphaSlabOne-Regular.otf +% AlphaSlabOne-Regular-tlf-t1' diff --git a/fonts/alfaslabone/enc/a_lzhlbi.enc b/fonts/alfaslabone/enc/a_lzhlbi.enc new file mode 100644 index 0000000000..921ac3153f --- /dev/null +++ b/fonts/alfaslabone/enc/a_lzhlbi.enc @@ -0,0 +1,63 @@ +% THIS FILE WAS AUTOMATICALLY GENERATED -- DO NOT EDIT + +%%AutoEnc_lzhlbizugmi4upaj5j2bz4givg +% Encoding created by otftotfm on Sat Jan 16 18:48:21 2021 +% Command line follows encoding +/AutoEnc_lzhlbizugmi4upaj5j2bz4givg [ +%00 + /.notdef /Euro /.notdef /.notdef /fraction /dotaccent /hungarumlaut /ogonek + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%10 + /dotlessi /uni0237 /grave /acute /caron /breve /macron /ring + /cedilla /germandbls /ae /oe /oslash /AE /OE /Oslash +%20 + /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +%30 + /uni2070 /uni00B9 /uni00B2 /uni00B3 /uni2074 /uni2075 /uni2076 /uni2077 + /uni2078 /uni2079 /colon /semicolon /less /equal /greater /question +%40 + /at /A /B /C /D /E /F /G + /H /I /J /K /L /M /N /O +%50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /circumflex /underscore +%60 + /quoteleft /a /b /c /d /e /f /g + /h /i /j /k /l /m /n /o +%70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /tilde /dieresis +%80 + /Lslash /quotesingle /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft /OE /Zcaron /asciicircum /minus +%90 + /lslash /quoteleft /quoteright /quotedblleft /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright /oe /zcaron /asciitilde /Ydieresis +%A0 + /.notdef /exclamdown /cent /sterling /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /uni00AD /registered /macron +%B0 + /degree /plusminus /uni00B2 /uni00B3 /acute /uni00B5 /paragraph /periodcentered + /cedilla /uni00B9 /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown +%C0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis +%D0 + /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls +%E0 + /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis +%F0 + /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis +] def +% Command line: 'otftotfm --automatic --encoding=fontools_ly1 +% --tfm-directory=texmf/fonts/tfm/public/alfaslabone +% --vf-directory=texmf/fonts/vf/public/alfaslabone +% --type1-directory=texmf/fonts/type1/public/alfaslabone +% --encoding-directory=texmf/fonts/enc/dvips/alfaslabone +% --map-file=texmf/fonts/map/dvips/alfaslabone/AlphaSlabOne.map --no-updmap +% --force --coding-scheme=TEX TYPEWRITER AND WINDOWS ANSI --feature=sups +% --ligkern=* {KL} * AlphaSlabOne-Regular.otf AlphaSlabOne-Regular-sup-ly1' diff --git a/fonts/alfaslabone/enc/a_rymxky.enc b/fonts/alfaslabone/enc/a_rymxky.enc new file mode 100644 index 0000000000..d94ca3997d --- /dev/null +++ b/fonts/alfaslabone/enc/a_rymxky.enc @@ -0,0 +1,65 @@ +% THIS FILE WAS AUTOMATICALLY GENERATED -- DO NOT EDIT + +%%AutoEnc_rymxkygdncozyxzjo3nxlifvfh +% Encoding created by otftotfm on Sat Jan 16 18:48:20 2021 +% Command line follows encoding +/AutoEnc_rymxkygdncozyxzjo3nxlifvfh [ +%00 + /f_f /Euro /f_f_i /f_f_l /fraction /dotaccent /hungarumlaut /ogonek + /.notdef /.notdef /.notdef /.notdef /fi /fl /.notdef /.notdef +%10 + /dotlessi /uni0237 /grave /acute /caron /breve /macron /ring + /cedilla /germandbls /ae /oe /oslash /AE /OE /Oslash +%20 + /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +%30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question +%40 + /at /A /B /C /D /E /F /G + /H /I /J /K /L /M /N /O +%50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /circumflex /underscore +%60 + /quoteleft /a /b /c /d /e /f /g + /h /i /j /k /l /m /n /o +%70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /tilde /dieresis +%80 + /Lslash /quotesingle /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft /OE /Zcaron /asciicircum /minus +%90 + /lslash /quoteleft /quoteright /quotedblleft /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright /oe /zcaron /asciitilde /Ydieresis +%A0 + /.notdef /exclamdown /cent /sterling /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /uni00AD /registered /macron +%B0 + /degree /plusminus /uni00B2 /uni00B3 /acute /uni00B5 /paragraph /periodcentered + /cedilla /uni00B9 /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown +%C0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis +%D0 + /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls +%E0 + /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis +%F0 + /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis +] def +% Command line: 'otftotfm --automatic --encoding=fontools_ly1 +% --tfm-directory=texmf/fonts/tfm/public/alfaslabone +% --vf-directory=texmf/fonts/vf/public/alfaslabone +% --type1-directory=texmf/fonts/type1/public/alfaslabone +% --encoding-directory=texmf/fonts/enc/dvips/alfaslabone +% --map-file=texmf/fonts/map/dvips/alfaslabone/AlphaSlabOne.map --no-updmap +% --force --coding-scheme=TEX TYPEWRITER AND WINDOWS ANSI --feature=kern +% --feature=liga --ligkern=f i =: fi --ligkern=f l =: fl --ligkern=f f =: ff +% --ligkern=ff i =: ffi --ligkern=ff l =: ffl AlphaSlabOne-Regular.otf +% AlphaSlabOne-Regular-tlf-ly1' diff --git a/fonts/alfaslabone/enc/a_taosrr.enc b/fonts/alfaslabone/enc/a_taosrr.enc new file mode 100644 index 0000000000..26904ead02 --- /dev/null +++ b/fonts/alfaslabone/enc/a_taosrr.enc @@ -0,0 +1,63 @@ +% THIS FILE WAS AUTOMATICALLY GENERATED -- DO NOT EDIT + +%%AutoEnc_taosrrygdoo3kyb3irmctifjkf +% Encoding created by otftotfm on Sat Jan 16 18:48:20 2021 +% Command line follows encoding +/AutoEnc_taosrrygdoo3kyb3irmctifjkf [ +%00 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /cedilla /ogonek /quotesinglbase /exclam /asterisk +%10 + /question /C /quotedblbase /bar /exclamdown /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /questiondown /.notdef +%20 + /.notdef /endash /.notdef /.notdef /dollar /.notdef /.notdef /quotesingle + /.notdef /.notdef /.notdef /.notdef /comma /.notdef /period /fraction +%30 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /minus /.notdef /.notdef +%40 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%50 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /uni2126 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%60 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%70 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%80 + /.notdef /.notdef /.notdef /.notdef /dagger /daggerdbl /.notdef /perthousand + /bullet /.notdef /.notdef /.notdef /florin /colonmonetary /uni20A9 /.notdef +%90 + /.notdef /.notdef /lira /.notdef /.notdef /.notdef /dong /trademark + /.notdef /.notdef /.notdef /uni2116 /.notdef /estimated /.notdef /.notdef +%A0 + /.notdef /.notdef /cent /sterling /currency /yen /brokenbar /section + /.notdef /copyright /ordfeminine /.notdef /logicalnot /.notdef /registered /.notdef +%B0 + /degree /plusminus /uni00B2 /uni00B3 /.notdef /uni00B5 /paragraph /periodcentered + /.notdef /uni00B9 /ordmasculine /radical /onequarter /onehalf /threequarters /Euro +%C0 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%D0 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /multiply /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%E0 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%F0 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /divide /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +] def +% Command line: 'otftotfm --automatic --encoding=fontools_ts1 +% --tfm-directory=texmf/fonts/tfm/public/alfaslabone +% --vf-directory=texmf/fonts/vf/public/alfaslabone +% --type1-directory=texmf/fonts/type1/public/alfaslabone +% --encoding-directory=texmf/fonts/enc/dvips/alfaslabone +% --map-file=texmf/fonts/map/dvips/alfaslabone/AlphaSlabOne.map --no-updmap +% --force --coding-scheme=TEX TEXT COMPANION SYMBOLS 1---TS1 +% AlphaSlabOne-Regular.otf AlphaSlabOne-Regular-tlf-ts1' diff --git a/fonts/alfaslabone/enc/a_vqpkf5.enc b/fonts/alfaslabone/enc/a_vqpkf5.enc new file mode 100644 index 0000000000..1dc82faa7c --- /dev/null +++ b/fonts/alfaslabone/enc/a_vqpkf5.enc @@ -0,0 +1,63 @@ +% THIS FILE WAS AUTOMATICALLY GENERATED -- DO NOT EDIT + +%%AutoEnc_vqpkf5uszgaieumdtwmphcxlcb +% Encoding created by otftotfm on Sat Jan 16 18:48:21 2021 +% Command line follows encoding +/AutoEnc_vqpkf5uszgaieumdtwmphcxlcb [ +%00 + /grave /acute /circumflex /tilde /dieresis /hungarumlaut /ring /caron + /breve /macron /dotaccent /cedilla /ogonek /quotesinglbase /guilsinglleft /guilsinglright +%10 + /quotedblleft /quotedblright /quotedblbase /guillemotleft /guillemotright /endash /emdash /.notdef + /.notdef /dotlessi /uni0237 /.notdef /.notdef /.notdef /.notdef /.notdef +%20 + /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +%30 + /uni2070 /uni00B9 /uni00B2 /uni00B3 /uni2074 /uni2075 /uni2076 /uni2077 + /uni2078 /uni2079 /colon /semicolon /less /equal /greater /question +%40 + /at /A /B /C /D /E /F /G + /H /I /J /K /L /M /N /O +%50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +%60 + /quoteleft /a /b /c /d /e /f /g + /h /i /j /k /l /m /n /o +%70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde /hyphen +%80 + /Abreve /Aogonek /Cacute /Ccaron /Dcaron /Ecaron /Eogonek /Gbreve + /Lacute /Lcaron /Lslash /Nacute /Ncaron /Eng /Ohungarumlaut /Racute +%90 + /Rcaron /Sacute /Scaron /Scedilla /Tcaron /uni0162 /Uhungarumlaut /Uring + /Ydieresis /Zacute /Zcaron /Zdotaccent /IJ /Idotaccent /dcroat /section +%A0 + /abreve /aogonek /cacute /ccaron /dcaron /ecaron /eogonek /gbreve + /lacute /lcaron /lslash /nacute /ncaron /eng /ohungarumlaut /racute +%B0 + /rcaron /sacute /scaron /scedilla /tcaron /uni0163 /uhungarumlaut /uring + /ydieresis /zacute /zcaron /zdotaccent /ij /exclamdown /questiondown /sterling +%C0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis +%D0 + /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /OE + /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /.notdef +%E0 + /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis +%F0 + /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /oe + /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /germandbls +] def +% Command line: 'otftotfm --automatic --encoding=fontools_t1 +% --tfm-directory=texmf/fonts/tfm/public/alfaslabone +% --vf-directory=texmf/fonts/vf/public/alfaslabone +% --type1-directory=texmf/fonts/type1/public/alfaslabone +% --encoding-directory=texmf/fonts/enc/dvips/alfaslabone +% --map-file=texmf/fonts/map/dvips/alfaslabone/AlphaSlabOne.map --no-updmap +% --force --coding-scheme=EXTENDED TEX FONT ENCODING - LATIN --feature=sups +% --ligkern=* {KL} * AlphaSlabOne-Regular.otf AlphaSlabOne-Regular-sup-t1' diff --git a/fonts/alfaslabone/latex/LY1AlphaSlabOne-Sup.fd b/fonts/alfaslabone/latex/LY1AlphaSlabOne-Sup.fd new file mode 100644 index 0000000000..61ef37332d --- /dev/null +++ b/fonts/alfaslabone/latex/LY1AlphaSlabOne-Sup.fd @@ -0,0 +1,36 @@ +%% Generated by autoinst on 2021/01/16 +%% +\ProvidesFile{LY1AlphaSlabOne-Sup.fd} + [2021/01/16 (autoinst) Font definitions for LY1/AlphaSlabOne-Sup.] + +\ifcsname s@fct@alias\endcsname\else +\gdef\s@fct@alias{\sub@sfcnt\@font@aliasinfo} +\gdef\@font@aliasinfo#1{% + \@font@info{Font\space shape\space `\curr@fontshape'\space will + \space be\space aliased\MessageBreak to\space `\mandatory@arg'}% +} +\fi + +\expandafter\ifx\csname AlphaSlabOne@scale\endcsname\relax + \let\AlphaSlabOne@@scale\@empty +\else + \edef\AlphaSlabOne@@scale{s*[\csname AlphaSlabOne@scale\endcsname]}% +\fi + +\DeclareFontFamily{LY1}{AlphaSlabOne-Sup}{} + + +% ---- m = regular ---- + +\DeclareFontShape{LY1}{AlphaSlabOne-Sup}{m}{n}{ + <-> \AlphaSlabOne@@scale AlphaSlabOne-Regular-sup-ly1 +}{} + +\DeclareFontShape{LY1}{AlphaSlabOne-Sup}{regular}{n}{ + <-> alias * AlphaSlabOne-Sup/m/n +}{} + + +% ---- Extra 'ssub' rules to map 'bx' to 'b' ---- + +\endinput diff --git a/fonts/alfaslabone/latex/LY1AlphaSlabOne-TLF.fd b/fonts/alfaslabone/latex/LY1AlphaSlabOne-TLF.fd new file mode 100644 index 0000000000..b013c767ac --- /dev/null +++ b/fonts/alfaslabone/latex/LY1AlphaSlabOne-TLF.fd @@ -0,0 +1,36 @@ +%% Generated by autoinst on 2021/01/16 +%% +\ProvidesFile{LY1AlphaSlabOne-TLF.fd} + [2021/01/16 (autoinst) Font definitions for LY1/AlphaSlabOne-TLF.] + +\ifcsname s@fct@alias\endcsname\else +\gdef\s@fct@alias{\sub@sfcnt\@font@aliasinfo} +\gdef\@font@aliasinfo#1{% + \@font@info{Font\space shape\space `\curr@fontshape'\space will + \space be\space aliased\MessageBreak to\space `\mandatory@arg'}% +} +\fi + +\expandafter\ifx\csname AlphaSlabOne@scale\endcsname\relax + \let\AlphaSlabOne@@scale\@empty +\else + \edef\AlphaSlabOne@@scale{s*[\csname AlphaSlabOne@scale\endcsname]}% +\fi + +\DeclareFontFamily{LY1}{AlphaSlabOne-TLF}{} + + +% ---- m = regular ---- + +\DeclareFontShape{LY1}{AlphaSlabOne-TLF}{m}{n}{ + <-> \AlphaSlabOne@@scale AlphaSlabOne-Regular-tlf-ly1 +}{} + +\DeclareFontShape{LY1}{AlphaSlabOne-TLF}{regular}{n}{ + <-> alias * AlphaSlabOne-TLF/m/n +}{} + + +% ---- Extra 'ssub' rules to map 'bx' to 'b' ---- + +\endinput diff --git a/fonts/alfaslabone/latex/OT1AlphaSlabOne-Sup.fd b/fonts/alfaslabone/latex/OT1AlphaSlabOne-Sup.fd new file mode 100644 index 0000000000..91a96e08b5 --- /dev/null +++ b/fonts/alfaslabone/latex/OT1AlphaSlabOne-Sup.fd @@ -0,0 +1,36 @@ +%% Generated by autoinst on 2021/01/16 +%% +\ProvidesFile{OT1AlphaSlabOne-Sup.fd} + [2021/01/16 (autoinst) Font definitions for OT1/AlphaSlabOne-Sup.] + +\ifcsname s@fct@alias\endcsname\else +\gdef\s@fct@alias{\sub@sfcnt\@font@aliasinfo} +\gdef\@font@aliasinfo#1{% + \@font@info{Font\space shape\space `\curr@fontshape'\space will + \space be\space aliased\MessageBreak to\space `\mandatory@arg'}% +} +\fi + +\expandafter\ifx\csname AlphaSlabOne@scale\endcsname\relax + \let\AlphaSlabOne@@scale\@empty +\else + \edef\AlphaSlabOne@@scale{s*[\csname AlphaSlabOne@scale\endcsname]}% +\fi + +\DeclareFontFamily{OT1}{AlphaSlabOne-Sup}{} + + +% ---- m = regular ---- + +\DeclareFontShape{OT1}{AlphaSlabOne-Sup}{m}{n}{ + <-> \AlphaSlabOne@@scale AlphaSlabOne-Regular-sup-ot1 +}{} + +\DeclareFontShape{OT1}{AlphaSlabOne-Sup}{regular}{n}{ + <-> alias * AlphaSlabOne-Sup/m/n +}{} + + +% ---- Extra 'ssub' rules to map 'bx' to 'b' ---- + +\endinput diff --git a/fonts/alfaslabone/latex/OT1AlphaSlabOne-TLF.fd b/fonts/alfaslabone/latex/OT1AlphaSlabOne-TLF.fd new file mode 100644 index 0000000000..f666782440 --- /dev/null +++ b/fonts/alfaslabone/latex/OT1AlphaSlabOne-TLF.fd @@ -0,0 +1,36 @@ +%% Generated by autoinst on 2021/01/16 +%% +\ProvidesFile{OT1AlphaSlabOne-TLF.fd} + [2021/01/16 (autoinst) Font definitions for OT1/AlphaSlabOne-TLF.] + +\ifcsname s@fct@alias\endcsname\else +\gdef\s@fct@alias{\sub@sfcnt\@font@aliasinfo} +\gdef\@font@aliasinfo#1{% + \@font@info{Font\space shape\space `\curr@fontshape'\space will + \space be\space aliased\MessageBreak to\space `\mandatory@arg'}% +} +\fi + +\expandafter\ifx\csname AlphaSlabOne@scale\endcsname\relax + \let\AlphaSlabOne@@scale\@empty +\else + \edef\AlphaSlabOne@@scale{s*[\csname AlphaSlabOne@scale\endcsname]}% +\fi + +\DeclareFontFamily{OT1}{AlphaSlabOne-TLF}{} + + +% ---- m = regular ---- + +\DeclareFontShape{OT1}{AlphaSlabOne-TLF}{m}{n}{ + <-> \AlphaSlabOne@@scale AlphaSlabOne-Regular-tlf-ot1 +}{} + +\DeclareFontShape{OT1}{AlphaSlabOne-TLF}{regular}{n}{ + <-> alias * AlphaSlabOne-TLF/m/n +}{} + + +% ---- Extra 'ssub' rules to map 'bx' to 'b' ---- + +\endinput diff --git a/fonts/alfaslabone/latex/T1AlphaSlabOne-Sup.fd b/fonts/alfaslabone/latex/T1AlphaSlabOne-Sup.fd new file mode 100644 index 0000000000..12718feabe --- /dev/null +++ b/fonts/alfaslabone/latex/T1AlphaSlabOne-Sup.fd @@ -0,0 +1,36 @@ +%% Generated by autoinst on 2021/01/16 +%% +\ProvidesFile{T1AlphaSlabOne-Sup.fd} + [2021/01/16 (autoinst) Font definitions for T1/AlphaSlabOne-Sup.] + +\ifcsname s@fct@alias\endcsname\else +\gdef\s@fct@alias{\sub@sfcnt\@font@aliasinfo} +\gdef\@font@aliasinfo#1{% + \@font@info{Font\space shape\space `\curr@fontshape'\space will + \space be\space aliased\MessageBreak to\space `\mandatory@arg'}% +} +\fi + +\expandafter\ifx\csname AlphaSlabOne@scale\endcsname\relax + \let\AlphaSlabOne@@scale\@empty +\else + \edef\AlphaSlabOne@@scale{s*[\csname AlphaSlabOne@scale\endcsname]}% +\fi + +\DeclareFontFamily{T1}{AlphaSlabOne-Sup}{} + + +% ---- m = regular ---- + +\DeclareFontShape{T1}{AlphaSlabOne-Sup}{m}{n}{ + <-> \AlphaSlabOne@@scale AlphaSlabOne-Regular-sup-t1 +}{} + +\DeclareFontShape{T1}{AlphaSlabOne-Sup}{regular}{n}{ + <-> alias * AlphaSlabOne-Sup/m/n +}{} + + +% ---- Extra 'ssub' rules to map 'bx' to 'b' ---- + +\endinput diff --git a/fonts/alfaslabone/latex/T1AlphaSlabOne-TLF.fd b/fonts/alfaslabone/latex/T1AlphaSlabOne-TLF.fd new file mode 100644 index 0000000000..7eb488f690 --- /dev/null +++ b/fonts/alfaslabone/latex/T1AlphaSlabOne-TLF.fd @@ -0,0 +1,36 @@ +%% Generated by autoinst on 2021/01/16 +%% +\ProvidesFile{T1AlphaSlabOne-TLF.fd} + [2021/01/16 (autoinst) Font definitions for T1/AlphaSlabOne-TLF.] + +\ifcsname s@fct@alias\endcsname\else +\gdef\s@fct@alias{\sub@sfcnt\@font@aliasinfo} +\gdef\@font@aliasinfo#1{% + \@font@info{Font\space shape\space `\curr@fontshape'\space will + \space be\space aliased\MessageBreak to\space `\mandatory@arg'}% +} +\fi + +\expandafter\ifx\csname AlphaSlabOne@scale\endcsname\relax + \let\AlphaSlabOne@@scale\@empty +\else + \edef\AlphaSlabOne@@scale{s*[\csname AlphaSlabOne@scale\endcsname]}% +\fi + +\DeclareFontFamily{T1}{AlphaSlabOne-TLF}{} + + +% ---- m = regular ---- + +\DeclareFontShape{T1}{AlphaSlabOne-TLF}{m}{n}{ + <-> \AlphaSlabOne@@scale AlphaSlabOne-Regular-tlf-t1 +}{} + +\DeclareFontShape{T1}{AlphaSlabOne-TLF}{regular}{n}{ + <-> alias * AlphaSlabOne-TLF/m/n +}{} + + +% ---- Extra 'ssub' rules to map 'bx' to 'b' ---- + +\endinput diff --git a/fonts/alfaslabone/latex/TS1AlphaSlabOne-TLF.fd b/fonts/alfaslabone/latex/TS1AlphaSlabOne-TLF.fd new file mode 100644 index 0000000000..4cfa6af299 --- /dev/null +++ b/fonts/alfaslabone/latex/TS1AlphaSlabOne-TLF.fd @@ -0,0 +1,36 @@ +%% Generated by autoinst on 2021/01/16 +%% +\ProvidesFile{TS1AlphaSlabOne-TLF.fd} + [2021/01/16 (autoinst) Font definitions for TS1/AlphaSlabOne-TLF.] + +\ifcsname s@fct@alias\endcsname\else +\gdef\s@fct@alias{\sub@sfcnt\@font@aliasinfo} +\gdef\@font@aliasinfo#1{% + \@font@info{Font\space shape\space `\curr@fontshape'\space will + \space be\space aliased\MessageBreak to\space `\mandatory@arg'}% +} +\fi + +\expandafter\ifx\csname AlphaSlabOne@scale\endcsname\relax + \let\AlphaSlabOne@@scale\@empty +\else + \edef\AlphaSlabOne@@scale{s*[\csname AlphaSlabOne@scale\endcsname]}% +\fi + +\DeclareFontFamily{TS1}{AlphaSlabOne-TLF}{} + + +% ---- m = regular ---- + +\DeclareFontShape{TS1}{AlphaSlabOne-TLF}{m}{n}{ + <-> \AlphaSlabOne@@scale AlphaSlabOne-Regular-tlf-ts1 +}{} + +\DeclareFontShape{TS1}{AlphaSlabOne-TLF}{regular}{n}{ + <-> alias * AlphaSlabOne-TLF/m/n +}{} + + +% ---- Extra 'ssub' rules to map 'bx' to 'b' ---- + +\endinput diff --git a/fonts/alfaslabone/latex/alfaslabone.sty b/fonts/alfaslabone/latex/alfaslabone.sty new file mode 100644 index 0000000000..0aba57b587 --- /dev/null +++ b/fonts/alfaslabone/latex/alfaslabone.sty @@ -0,0 +1,62 @@ +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{alfaslabone} + [2021/01/16 v.0.0.1 (Carl-Clemens Ebinger & autoinst) Style file for AlphaSlabOne fonts.] + +\RequirePackage{xkeyval} +\newcommand*{\AlphaSlabOne@scale}{1} +\DeclareOptionX{scale}{\renewcommand*{\AlphaSlabOne@scale}{#1}} +\DeclareOptionX{scaled}{\renewcommand*{\AlphaSlabOne@scale}{#1}} + +\DeclareOptionX{lining}{\edef\AlphaSlabOne@figurestyle{LF}} +\DeclareOptionX{tabular}{\edef\AlphaSlabOne@figurealign{T}} +\DeclareOptionX{mainfont}{ + \renewcommand{\familydefault}{\rmdefault} +} +\DeclareOptionX{regular}{\edef\mdseries@rm{regular}} +\ExecuteOptionsX{lining,tabular} +\ProcessOptionsX\relax + +\RequirePackage{fontenc,textcomp} +\RequirePackage{ifthen} +\RequirePackage{mweights} + +\IfFileExists{fontaxes.sty}{ + \RequirePackage{fontaxes} + \fa@naming@exception{figures}{{superior}{proportional}}{Sup} + \fa@naming@exception{figures}{{superior}{tabular}}{Sup} + \def\supfigures{\@nomath\supfigures + \fontfigurestyle{superior}\selectfont} + \let\sufigures\supfigures + \DeclareTextFontCommand{\textsup}{\supfigures} + \let\textsu\textsup + \let\textsuperior\textsup + +}{} + +% Here we implement the scale=MatchLowercase option. +% If this is given, we must compute the correct value of +% the "\AlphaSlabOne@scale" parameter before loading the .fd files; +% but to determine that value we of course need the font's x-height. +% To avoid triggering the loading of .fd files, +% we use plain TeX's \font primitive to load the testfont. +% We then compute the ratio of the current x-height to our font's x-height; +% this is the "\AlphaSlabOne@scale" we will pass to the .fd files. +\ifthenelse{\equal{\AlphaSlabOne@scale}{MatchLowercase}} + { \newlength{\AlphaSlabOne@currentx} + \settoheight{\AlphaSlabOne@currentx}{x} + \newlength{\AlphaSlabOne@xheight} + \settoheight{\AlphaSlabOne@xheight} + {{\font\testfont=AlphaSlabOne-Regular-tlf-ot1 at \f@size pt\testfont x}} + \renewcommand*{\AlphaSlabOne@scale} + {\strip@pt\dimexpr\number\numexpr\number\dimexpr\AlphaSlabOne@currentx\relax*65536/\number\dimexpr\AlphaSlabOne@xheight\relax\relax sp\relax}} + {} + + \def\sufigures{\@nomath\sufigures\fontfigurestyle{superior}\selectfont} + + \def\alfaslabonetabular{\fontfamily{AlphaSlabOne-TLF}\selectfont} + +\renewcommand* + {\rmdefault} + {AlphaSlabOne-\AlphaSlabOne@figurealign\AlphaSlabOne@figurestyle} + +\endinput diff --git a/fonts/alfaslabone/map/AlphaSlabOne.map b/fonts/alfaslabone/map/AlphaSlabOne.map new file mode 100644 index 0000000000..6b42062bbe --- /dev/null +++ b/fonts/alfaslabone/map/AlphaSlabOne.map @@ -0,0 +1,9 @@ +% Automatically maintained by otftotfm or other programs. Do not edit. + +AlphaSlabOne-Regular-tlf-ot1 AlphaSlabOne-Regular "AutoEnc_adz5lu2pubiora2jv2qajnuogc ReEncodeFont" <[a_adz5lu.enc 0.1?1:0)}% + \ifnum\pgf@temp@c=1\relax + % second discriminant d2, must be \ge 0 + \pgfmathsetmacro{\pgf@temp@b}{(\pgf@path@lastx)*(#5)-(#5)*(#1)+(#1)*(#1)-(\pgf@path@lastx)*(#3)-(#1)*(#3)+(#3)*(#3)}% + \pgfmathtruncatemacro{\pgf@temp@c}{sign(\pgf@temp@b)}% + \ifnum\pgf@temp@c<0 + \else + \pgfmathsetmacro{\pgf@temp@b}{sqrt(abs(\pgf@temp@b))}% + \pgfmathsetmacro{\pgf@temp@c}{max(0,min(1,((\pgf@path@lastx)-2*(#1)+(#3)-\pgf@temp@b)/\pgf@temp@a))}% + \pgfmathparse{(\pgf@path@lastx)*pow((1-\pgf@temp@c),3)+3*(#1)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#3)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#5)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}% + \pgfutil@tempdimb=\pgfmathresult pt\relax% + \pgf@protocolsizes{\pgfutil@tempdimb}{\pgf@path@lasty}% + \pgfmathsetmacro{\pgf@temp@c}{max(0,min(1,((\pgf@path@lastx)-2*(#1)+(#3)+\pgf@temp@b)/\pgf@temp@a))}% + \pgfmathparse{(\pgf@path@lastx)*pow((1-\pgf@temp@c),3)+3*(#1)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#3)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#5)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}% + \pgfutil@tempdimb=\pgfmathresult pt\relax% + \pgf@protocolsizes{\pgfutil@tempdimb}{\pgf@path@lasty}% + \fi + \else + % third discriminant d3, must be \ne 0 + \pgfmathsetmacro{\pgf@temp@b}{abs((#5)+(#1)-2*(#3))}% + \pgfmathtruncatemacro{\pgf@temp@c}{(abs(\pgf@temp@b)>0.1?1:0)}% + \ifnum\pgf@temp@c=1\relax + \pgfmathsetmacro{\pgf@temp@c}{((#5)+2*(#1)-3*(#3))/((#5)+(#1)-2*(#3))}% + \pgfmathparse{(\pgf@path@lastx)*pow((1-\pgf@temp@c),3)+3*(#1)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#3)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#5)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}% + \pgfutil@tempdimb=\pgfmathresult pt\relax% + \pgf@protocolsizes{\pgfutil@tempdimb}{\pgf@path@lasty}% + \fi + \fi + % 0/0 + \pgfmathsetmacro{\pgf@temp@a}{(#5)+(#1)-2*(#3)}% + \pgfmathtruncatemacro{\pgf@temp@b}{(abs(\pgf@temp@a)>0.1?1:0)}% + \ifnum\pgf@temp@b=1\relax + \pgfmathsetmacro{\pgf@temp@c}{max(0,min(1,((#5)+2*(#1)-3*(#3))/(2*\pgf@temp@a)))}% + \else + \pgfmathsetmacro{\pgf@temp@c}{0.5}% + \fi + \pgfmathparse{(\pgf@path@lastx)*pow((1-\pgf@temp@c),3)+3*(#1)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#3)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#5)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}% + \pgfutil@tempdimb=\pgfmathresult pt\relax% + \pgf@protocolsizes{\pgfutil@tempdimb}{\pgf@path@lasty}% +% +% y code + % first discriminant d1, must be \ne 0 + \pgfmathsetmacro{\pgf@temp@a}{(\pgf@path@lasty)-(#6)-3*(#2)+3*(#4)}% + \pgfmathtruncatemacro{\pgf@temp@c}{(abs(\pgf@temp@a)>0.1?1:0)}% + \ifnum\pgf@temp@c=1\relax + % second discriminant d2, must be \ge 0 + \pgfmathsetmacro{\pgf@temp@b}{(\pgf@path@lasty)*(#6)-(#6)*(#2)+(#2)*(#2)-(\pgf@path@lasty)*(#4)-(#2)*(#4)+(#4)*(#4)}% + \pgfmathtruncatemacro{\pgf@temp@c}{sign(\pgf@temp@b)}% + \ifnum\pgf@temp@c<0 + \else + \pgfmathsetmacro{\pgf@temp@b}{sqrt(abs(\pgf@temp@b))}% + \pgfmathsetmacro{\pgf@temp@c}{max(0,min(1,((\pgf@path@lasty)-2*(#2)+(#4)-\pgf@temp@b)/\pgf@temp@a))}% + \pgfmathparse{(\pgf@path@lasty)*pow((1-\pgf@temp@c),3)+3*(#2)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#4)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#6)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}% + \pgfutil@tempdimb=\pgfmathresult pt\relax% + \pgf@protocolsizes{\pgf@path@lastx}{\pgfutil@tempdimb}% + \pgfmathsetmacro{\pgf@temp@c}{max(0,min(1,((\pgf@path@lasty)-2*(#2)+(#4)+\pgf@temp@b)/\pgf@temp@a))}% + \pgfmathparse{(\pgf@path@lasty)*pow((1-\pgf@temp@c),3)+3*(#2)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#4)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#6)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}% + \pgfutil@tempdimb=\pgfmathresult pt\relax% + \pgf@protocolsizes{\pgf@path@lastx}{\pgfutil@tempdimb}% + \fi + \else + % third discriminant d3, must be \ne 0 + \pgfmathsetmacro{\pgf@temp@b}{abs((#6)+(#2)-2*(#4))}% + \pgfmathtruncatemacro{\pgf@temp@c}{(abs(\pgf@temp@b)>0.1?1:0)}% + \ifnum\pgf@temp@c=1\relax + \pgfmathsetmacro{\pgf@temp@c}{((#6)+2*(#2)-3*(#4))/((#6)+(#2)-2*(#4))}% + \pgfmathparse{(\pgf@path@lasty)*pow((1-\pgf@temp@c),3)+3*(#2)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#4)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#6)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}% + \pgfutil@tempdimb=\pgfmathresult pt\relax% + \pgf@protocolsizes{\pgf@path@lastx}{\pgfutil@tempdimb}% + \fi + \fi + % 0/0 + \pgfmathsetmacro{\pgf@temp@a}{(#6)+(#2)-2*(#4)}% + \pgfmathtruncatemacro{\pgf@temp@b}{(abs(\pgf@temp@a)>0.1?1:0)}% + \ifnum\pgf@temp@b=1\relax + \pgfmathsetmacro{\pgf@temp@c}{max(0,min(1,((#6)+2*(#2)-3*(#4))/(2*\pgf@temp@a)))}% + \else + \pgfmathsetmacro{\pgf@temp@c}{0.5}% + \fi + \pgfmathparse{(\pgf@path@lasty)*pow((1-\pgf@temp@c),3)+3*(#2)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#4)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#6)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}% + \pgfutil@tempdimb=\pgfmathresult pt\relax% + \pgf@protocolsizes{\pgf@path@lastx}{\pgfutil@tempdimb}% +% + \pgf@protocolsizes{\pgf@path@lastx}{\pgf@path@lasty}% + \pgf@protocolsizes{#5}{#6}% + \endgroup + \pgfsyssoftpath@curveto{\the#1}{\the#2}{\the#3}{\the#4}{\the#5}{\the#6}% +} +\endinput diff --git a/graphics/pgf/contrib/tikz-bbox/pgfmanual-en-library-bbox.tex b/graphics/pgf/contrib/tikz-bbox/pgfmanual-en-library-bbox.tex new file mode 100644 index 0000000000..9d42ae0dd5 --- /dev/null +++ b/graphics/pgf/contrib/tikz-bbox/pgfmanual-en-library-bbox.tex @@ -0,0 +1,181 @@ +% Copyright 2021 by marmotghost +% v0.1 +% +% This file may be distributed and/or modified under the +% LaTeX project public license (LPPL), version 1.3c +% see +% https://www.latex-project.org/lppl/lppl-1-3c/ +% +% It has been claimed that the license of this library had been changed so that this +% library is no longer part of pgf. This claim is a lie. There was no license change +% at all. Now, in 2021, the license got changed to LaTeX project public license +% (LPPL), version 1.3c. + +\section{Bounding Boxes for B\'ezier Curves} + + +\begin{pgflibrary}{bbox} + This library provides methods to determine tight bounding boxes for + B\'ezier curves. This library loads and uses the + |fpu| library. While this library might + possibly work with |TeX| or |ConTeXt|, this has never been tested. +\end{pgflibrary} + +\subsection{Bounding box without the library} + +\tikzname\ determines the bounding box of (cubic) Bezier curves by establishing the +smallest rectangle that contains the end point and the two control points of the +curve. + +\begin{codeexample}[width=5cm] +\begin{tikzpicture}[% + bullet/.style={circle,fill, + inner sep=1pt}] + \draw (0,0) .. controls (-1,1) + and (1,2) .. (2,0); + \draw (current bounding box.south west) + rectangle + (current bounding box.north east); + \draw[red,dashed] + (0,0) -- (-1,1) + node[bullet,label=above:{$(x_a,y_a)$}]{} + (2,0) -- (1,2) + node[bullet,label=above:{$(x_b,y_b)$}]{}; + \path (0,0) + node[bullet,label=below:{$(x_0,y_0)$}]{} + (2,0) + node[bullet,label=below:{$(x_1,y_1)$}]{}; +\end{tikzpicture} +\end{codeexample} + +As one can see from this illustration, this may lead to drastic overestimates of +the bounding box. + +\subsection{Computing the bounding box} + +Establishing the precise bounding box has been discussed in various places, the +following discussion uses in part the results from +\url{https://pomax.github.io/bezierinfo/}. What is a cubic B\'ezier curve? A +cubic B\'ezier curve running from $(x_0,y_0)$ to $(x_1,y_1)$ with control points +$(x_a,y_a)$ and $(x_b,y_b)$ can be parametrized by +\begin{equation} + \gamma(t)~=~ + \begin{pmatrix} x(t)\\ y(t) \end{pmatrix}~=~ + \begin{pmatrix}t^3 x_{1}+3 t^2 (1-t) x_{b}+(1-t)^3 + x_{0}+3 t (1-t)^2 x_{a}\\ + t^3 y_{1}+3 + t^2 (1-t) y_{b}+(1-t)^3 y_{0}+3 t (1-t)^2 + y_{a}\end{pmatrix}\;,\label{eq:gammaBezier} +\end{equation} +where $t$ runs from $0$ to $1$ (and $\gamma(0)=(x_0,y_0)$ and +$\gamma(1)=(x_1,y_1)$). Surely, the bounding box has to contain +$(x_0,y_0)$ and $(x_1,y_1)$. If the functions $x(t)$ and $y(t)$ have extrema in +the interval $[0,1]$, then the bounding box will in general be larger than that. +In order to determine the extrema of the curve, all +we need to find the extrema of the functions $x(t)$ and $y(t)$ for $0\le t\le +1$. That is, we need to find the solutions of the quadratic equations +\begin{equation} + \frac{\mathrm{d}x}{\mathrm{d}t}(t)~=~0\quad\text{and}\quad + \frac{\mathrm{d}y}{\mathrm{d}t}(t)~=~0\;. +\end{equation} +% (*parametrization of x:*) +% myx = x0 (1 - t)^3 + 3 xa (1 - t)^2 t + 3 xb (1 - t) t^2 + x1 t^3 +% (*d1\ne0 condition for t1 and t2 to exist*) +% === (*case d1\ne0*) == +% d1 = x0 - x1 - 3 xa + 3 xb +% (*square root, d2=0 \[Rule] only one solution,d2<0 \[Rule] no solution*) +% d2 = x0*x1 - x1*xa + xa*xa - x0*xb - xa xb + xb*xb +% (*first t*) +% t1 = (x0 - 2*xa + xb - sqrt(d2))/(x0 - x1 - 3*xa + 3*xb) +% = (x0 - 2*xa + xb - sqrt(d2))/d1 +% (*second t*) +% t2 = (x0 - 2*xa + xb + sqrt(d2))/(x0 - x1 - 3*xa + 3*xb) +% = (x0 - 2*xa + xb + sqrt(d2))/d1 +% === (*case d1=0*) == +% (*2nd condition for extra condition: d3\ne0*) +% d3 = x1 + xa - 2 xb +% (*third t*) +% t3 = (x1 + 2*xa - 3*xb)/(2*d3)% d3 = x1 + 3 xa - 3 xb - x0 +Let's discuss $x$ first. If the discriminant +\begin{equation} + d~:=~x_0\,x_1 - x_1\,x_a + x_a\,x_a - x_0\,x_b - x_a x_b + x_b\,x_b +\end{equation} +is greater than 0, there are two solutions +\begin{equation} + t_\pm~=~\frac{x_{0}-2x_{a}+x_{b}\pm\sqrt{d}}{% + x_{0}-x_{1}-3(x_{a}- x_{b})} \;. +\end{equation} +If the denominator $x_{0}-x_{1}-3(x_{a}- x_{b})$ vanishes, one may use the +l'Hospital rule to determine the solutions. +In this case, we need to make sure that the bounding box contains, say +$(x(t_-),y_0)$ and $(x(t_+),y_0)$. If $d\le0$, the bounding box does not need to +be increased in the $x$ direction. On the other hand, if there are solutions, +one needs include the points $\bigl(x(t_\pm),y_0\bigr)$ with $x(t)$ from +\eqref{eq:gammaBezier} in the bounding box. + +The analogous statements apply to $y(t)$. + +\subsection{Using the library} + +\begin{key}{/pgf/bezier bounding box=\meta{boolean} (default true)} + Turn the tight bounding box algorithm on and off. The initial value is + |false|. + + \emph{Caveat:} As can be seen from the derivations, the necessary + computations involve the squaring of lengths and taking ratios of lengths, + which can easily lead to |dimension too large| errors. The library uses + |fpu| to account for that, but errors may still occur. +\end{key} + + +\begin{codeexample}[width=5cm] +\begin{tikzpicture}[bezier bounding box,% + bullet/.style={circle,fill, + inner sep=1pt}] + \draw (0,0) .. controls (-1,1) + and (1,2) .. (2,0); + \draw (current bounding box.south west) + rectangle + (current bounding box.north east); + \draw[red,dashed] + (0,0) -- (-1,1) + node[bullet,label=above:{$(x_a,y_a)$}]{} + (2,0) -- (1,2) + node[bullet,label=above:{$(x_b,y_b)$}]{}; + \path (0,0) + node[bullet,label=below:{$(x_0,y_0)$}]{} + (2,0) + node[bullet,label=below:{$(x_1,y_1)$}]{}; +\end{tikzpicture} +\end{codeexample} + +A few comments are in order. +\begin{enumerate} +\item For paths with arrow heads one may need to load the \texttt{bending} + library. This is because otherwise the quick arrow head distorts the path, and + this happens after the bounding box has been computed. Even worse, arrow heads + could get deformed. +\item If you shorten a path by some negative length, the bounding box will not + be accurate either. However, this has nothing to do with curves, it also + applies to straight lines. So this is not specific to the |bbox| library but + something that one may want to keep in mind. +\item Let us also note that the computations can lead to |Dimension too large| + errors. These errors do not come directly from the computations done by the + library, which uses |fpu| for its computations, but from the aftermath. Many of + these problems can be avoided by using the |fpu| library also for computing + reciprocals, which can be achieved using the key + |/pgf/fpu/install only={reciprocal}|. This allows one to fix many + |Dimension too large| errors in other libraries, which are not related to the + present one, and also fixes inaccuracies of (inverse) transformations when the + scale factors are not integer. +\end{enumerate} + +\subsection{Reporting a bug} + +This library is maintained at the GitHub repository +\href{https://github.com/marmotghost/tikz-bbox}{tikz-bbox}, where issues can get +reported. The author is also active on the noncommercial \TeX\ Q\,\&\,A site +\href{https://topanswers.xyz/tex}{topanswers.xyz/tex}, where requests that are not +issues in the strict sense can be discussed. + +\endinput diff --git a/graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.pdf b/graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.pdf new file mode 100644 index 0000000000..69630c5964 Binary files /dev/null and b/graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.pdf differ diff --git a/graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.tex b/graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.tex new file mode 100644 index 0000000000..465bc22bea --- /dev/null +++ b/graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.tex @@ -0,0 +1,26 @@ +\documentclass[a4paper]{ltxdoc} +\usepackage[version=latest]{pgf} +\usepackage{xkeyval,calc,listings,tikz,fp,amsmath,amssymb} +\usepackage[T1]{fontenc}% +\usepackage{makeidx} +\makeindex +\usepackage{hyperref} +\hypersetup{% + colorlinks=true, + linkcolor=blue, + filecolor=blue, + urlcolor=blue, + citecolor=blue, + pdfborder=0 0 0, +} +\makeatletter % see https://tex.stackexchange.com/q/33946 +\input{pgfmanual.code} % +\makeatother % +\input{pgfmanual-en-macros.tex} % link from +% /usr/local/texlive/2019/texmf-dist/doc/generic/pgf/macros/pgfmanual-en-macros.tex +% or the equivalent on your installation +\def\pgfautoxrefs{1} +\usetikzlibrary{bbox} +\begin{document} +\input{pgfmanual-en-library-bbox.tex} +\end{document} diff --git a/graphics/pxpic/README.md b/graphics/pxpic/README.md index e4e78efbb4..32e7cd516a 100644 --- a/graphics/pxpic/README.md +++ b/graphics/pxpic/README.md @@ -2,7 +2,7 @@ ------------------------------------------------------------------------------- # pxpic -- draw pixel pictures -Version 2021-01-13 v1.1 +Version 2021-01-16 v1.2 Released under the LaTeX Project Public License v1.3c or later See http://www.latex-project.org/lppl.txt diff --git a/graphics/pxpic/pxpic.dtx b/graphics/pxpic/pxpic.dtx index f06454e842..9bb8f81097 100644 --- a/graphics/pxpic/pxpic.dtx +++ b/graphics/pxpic/pxpic.dtx @@ -54,7 +54,7 @@ and the derived files pxpic.pdf \expandafter\endgroup \fi % -\ProvidesFile{pxpic.dtx}[2021-01-13 v1.1 draw pixel pictures] +\ProvidesFile{pxpic.dtx}[2021-01-16 v1.2 draw pixel pictures] \PassOptionsToPackage{full}{textcomp} \documentclass{l3doc} \RequirePackage[oldstylenums,nott]{kpfonts} @@ -78,7 +78,9 @@ and the derived files pxpic.pdf ,basicstyle=\fontfamily{jkp}\itshape ,morekeywords=^^A {^^A - \pxpic,\pxpicsetup + \pxpic,\pxpicsetup,\pxpicnewmode,\pxpicsetmode,\pxpicnewcolorlist, + \pxpicsetcolorlist,\pxpicaddcolorlist,\pxpicforget,\px,\pxskip,\pxpicHT, + \pxpicWD,\pxpiclogo } ,morecomment=[l]\% ,commentstyle=\color[gray]{0.4} @@ -132,20 +134,23 @@ and the derived files pxpic.pdf {expkv}^^A } \hypersetup{linkcolor=red!80!black,urlcolor=purple!80!black} +\DoNotIndex{\advance} \DoNotIndex{\baselineskip,\begingroup,\bgroup} \DoNotIndex{\csname} \DoNotIndex{\def,\detokenize,\dimexpr} -\DoNotIndex{\egroup,\ekvdef,\ekvdefNoVal,\ekvifdefinedNoVal,\ekvletkv,\ekvparse} -\DoNotIndex{\ekvsetdef,\endcsname,\endgroup,\expandafter} +\DoNotIndex{\edef,\egroup,\ekvdef,\ekvdefNoVal,\ekvifdefinedNoVal,\ekvletkv} +\DoNotIndex{\ekvparse,\ekvsetdef,\endcsname,\endgroup,\expandafter} \DoNotIndex{\hbox,\hskip} +\DoNotIndex{\iffalse,\fi} \DoNotIndex{\kern} \DoNotIndex{\leavevmode,\let,\long,\lower} \DoNotIndex{\newcommand,\newdimen} \DoNotIndex{\PackageError,\protected,\ProvidesPackage} \DoNotIndex{\relax,\RequirePackage} -\DoNotIndex{\@depth,\@height,\@ifdefinable,\@ifnextchar,\@ifundefined,\@width} +\DoNotIndex{\@declaredcolor,\@firstofone,\@gobble,\@ifdefinable,\@ifnextchar} +\DoNotIndex{\@ifundefined,\@undeclaredcolor} \DoNotIndex{\ekv@ifempty,\ekv@name,\z@} -\DoNotIndex{\color} +\DoNotIndex{\unexpanded} \DoNotIndex{\vbox,\vrule} \@ifdefinable\gobbledocstriptag{\def\gobbledocstriptag#1>{}} \makeatother @@ -207,7 +212,7 @@ and the derived files pxpic.pdf \Large draw pixel pictures^^A }{pxpic - draw pixel pictures}^^A } - \date{2021-01-13 v1.1} + \date{2021-01-16 v1.2} \author{Jonathan P. Spratte\thanks{\protect\randomize{jspratte@yahoo.de}}} \DocInput{pxpic.dtx} \end{document} @@ -570,24 +575,37 @@ and the derived files pxpic.pdf % The available options are % % \begin{options} -% \item[colors] Define pixel colours for |mode=px|, see \autoref{sec:colours} -% for a description of the value's syntax. No pixel definitions are made by -% the package. -% \item[colours] \emph{see \texttt{colors}.} -% \item[gap-hack] To fix the issues with visible gaps in \textsc{pdf} viewers -% you can introduce some negative kerns to make the pixels overlap (lines -% overlap to the top, pixels to the left). This option expects a dimension -% as its value. A positive value will (maybe) close the gaps, a negative -% value will introduce real gaps. In any case the outermost pixels' borders -% still coincide with the borders of the surrounding \CS{hbox}. Take a look -% at my babbling about this issue in \autoref{sec:misc}. -% \item[ht] Set the height of the pixels. -% \item[mode] Set the used mode, see \autoref{sec:modes} for available modes. -% Initial value is |px|. -% \item[size] Set both |ht| and |wd|. Initial value is \the\pxpicHT. -% \item[skip] Define the value to be a skip (an empty space of width |wd|) in -% |mode=px|. No skip definitions are made by the package. -% \item[wd] Set the width of the pixels. +% \item[colors=\meta{colour list}] +% Define pixel colours for |mode=px|, see \autoref{sec:colours} for a +% description of the value's syntax. No pixel definitions are made by the +% package. +% \item[colours] +% \emph{see \texttt{colors}.} +% \item[color-list=\meta{choice}] +% loads a previously through \CS{pxpicnewcolorlist} defined colour list. No +% colour lists are defined by the package. +% \item[colour-list] +% \emph{see \texttt{color-list}.} +% \item[gap-hack=\meta{dimen}] +% To fix the issues with visible gaps in \textsc{pdf} viewers you can +% introduce some negative kerns to make the pixels overlap (lines overlap to +% the top, pixels to the left). This option expects a dimension as its +% value. A positive value will (maybe) close the gaps, a negative value will +% introduce real gaps. In any case the outermost pixels' borders still +% coincide with the borders of the surrounding \CS{hbox}. Take a look at my +% babbling about this issue in \autoref{sec:misc}. +% \item[ht=\meta{dimen}] +% Set the height of the pixels. +% \item[mode=\meta{choice}] +% Set the used mode, see \autoref{sec:modes} for available modes. Initial +% value is |px|. +% \item[size=\meta{dimen}] +% Set both |ht| and |wd|. Initial value is \the\pxpicHT. +% \item[skip=\meta{dimen}] +% Define the value to be a skip (an empty space of width |wd|) in |mode=px|. +% No skip definitions are made by the package. +% \item[wd=\meta{dimen}] +% Set the width of the pixels. % \end{options} % % \subsubsection{Colour syntax}\label{sec:colours} @@ -649,6 +667,28 @@ and the derived files pxpic.pdf % already exists, \cs{pxpicsetmode} has no checks on the name. % \end{function} % +% \begin{function}{\pxpicnewcolorlist,\pxpicsetcolorlist,\pxpicaddcolorlist} +% \begin{syntax} +% \cs{pxpicnewcolorlist}\marg{name}\marg{colour list} +% \end{syntax} +% This defines a colour list (to be used with the |colour-list| option). The +% syntax of \meta{colour list} is the same as for the |colours| option. The +% pixels aren't directly defined, but only by the use of +% |colour-list=|\meta{name}. So +% \begin{lstlisting} +% \pxpicnewcolorlist{example}{r=red,b=blue,g=green,k=black,w=white} +% \pxpicsetup{colour-list=example} +% \end{lstlisting} +% would have the same effect as +% \begin{lstlisting} +% \pxpicsetup{colours={r=red,b=blue,g=green,k=black,w=white}} +% \end{lstlisting} +% but a |colour-list| is more efficient if used multiple times. The |new| +% variant will only throw an error if the colour list \meta{name} is already +% defined. The |set| variant has no such tests, and the |add| variant will add +% additional colours to an existing list. +% \end{function} +% % \begin{function}{\pxpicforget} % \begin{syntax} % \cs{pxpicforget}\marg{px} @@ -695,14 +735,77 @@ and the derived files pxpic.pdf % \textsc{pdf} viewers and tools will display such a gap. To make things even % worse, the effect depends on the viewers current magnification. % \pxpicname\ has the |gap-hack| option to provide some crude hack that might -% fix the issue, at the cost that the pixels are smaller than they were -% specified to be, except for the pixels at the right and bottom border. Also -% pixels next to skipped pixels have a different size (skipped pixels don't -% cover pixels to their left or top as they are transparent). You'll want to -% find a good trade-off value if you want to use |gap-hack|, that mitigates the -% effect but isn't too big (to make the errors less obvious). You can play with -% the value and decide for yourself what's the lesser evil. Or you do like me, -% don't use |gap-hack| and blame the viewers. +% fix the issue, at the cost that the pixels on the far right and bottom are +% bigger than they were specified to be. Also pixels next to skipped pixels have +% a different size (skipped pixels don't cover pixels to their left or top as +% they are transparent). You'll want to find a good trade-off value if you want +% to use |gap-hack|, that mitigates the effect but isn't too big (to make the +% errors less obvious). You can play with the value and decide for yourself +% what's the lesser evil. Or you do like me, don't use |gap-hack| and blame the +% viewers. Here are examples in which you can compare (the |gap-hack| is chosen +% way too big in this example and skips are used close to white pixels on +% purpose, but it illustrates the effects; the third output, not shown in the +% code, uses a more reasonable |gap-hack=.2pt|):\par\nobreak +% \noindent +% \begin{minipage}[c]{.5\linewidth}\footnotesize +% \begin{lstlisting} +% \pxpicsetup +% { +% colours={k=black,g=green,w=white} +% ,skip=. +% ,size=10pt +% } +% \pxpic[gap-hack=2pt] +% { +% {kkkkk} +% {kgggk} +% {kwg.k} +% {kg.gk} +% {kgwk} +% {kkkw} +% } +% \raise2pt\pxpic +% { +% {kkkkk} +% {kgggk} +% {kwg.k} +% {kg.gk} +% {kgwk} +% {kkkw} +% } +% \end{lstlisting} +% \end{minipage} +% \begin{minipage}[c]{.45\linewidth} +% \pxpicsetup{colours={k=black,g=green,w=white},skip=.,size=10pt} +% \leavevmode +% \pxpic[gap-hack=2pt] +% { +% {kkkkk} +% {kgggk} +% {kwg.k} +% {kg.gk} +% {kgwk} +% {kkkw} +% } +% \raise2pt\pxpic +% { +% {kkkkk} +% {kgggk} +% {kwg.k} +% {kg.gk} +% {kgwk} +% {kkkw} +% } +% \raise1.8pt\pxpic[gap-hack=.2pt] +% { +% {kkkkk} +% {kgggk} +% {kwg.k} +% {kg.gk} +% {kgwk} +% {kkkw} +% } +% \end{minipage} % % % \end{documentation}^^A=<< @@ -718,7 +821,7 @@ and the derived files pxpic.pdf % % Report who we are % \begin{macrocode} -\ProvidesPackage{pxpic}[2021-01-13 v1.1 draw pixel pictures] +\ProvidesPackage{pxpic}[2021-01-16 v1.2 draw pixel pictures] % \end{macrocode} % and load dependencies % \begin{macrocode} @@ -764,7 +867,7 @@ and the derived files pxpic.pdf % \end{macrocode} % The |colours| option is parsed using \CS{ekvparse} and \CS{pxpic@setcolor}. % \begin{macrocode} -\protected\ekvdef{pxpic}{colors}{\ekvparse\pxpic@noval\pxpic@setcolor{#1}} +\protected\ekvdef{pxpic}{colors}{\ekvparse\pxpic@err@noval\pxpic@setcolor{#1}} \ekvletkv{pxpic}{colours}{pxpic}{colors} % \end{macrocode} % And the |mode| just checks whether the |mode| macro is defined and lets the @@ -773,13 +876,23 @@ and the derived files pxpic.pdf \protected\ekvdef{pxpic}{mode} {% \@ifundefined{pxpic@parse@px@#1}% - {\pxpic@unknown@mode{#1}}% + {\pxpic@err@unknown@mode{#1}}% {% \expandafter\let\expandafter\pxpic@parse@px \csname pxpic@parse@px@#1\endcsname }% } % \end{macrocode} +% A similar check is done for the |colour-list| option. +% \begin{macrocode} +\protected\ekvdef{pxpic}{color-list} + {% + \@ifundefined{pxpic@colorlist@#1}% + {\pxpic@err@unknown@colorlist{#1}} + {\csname pxpic@colorlist@#1\endcsname}% + } +\ekvletkv{pxpic}{colour-list}{pxpic}{color-list} +% \end{macrocode} % % % \subsection{User macros}\label{sec:implementation:pxpiclogo} @@ -795,7 +908,7 @@ and the derived files pxpic.pdf % pixel row will be wrapped inside an \CS{hbox}. The \CS{kern} negates a % negative \CS{kern} in \CS{pxpic@parse} so that the first line isn't moved. % \begin{macrocode} -\newcommand*\pxpic{\hbox\bgroup\pxpic@} +\@ifdefinable\pxpic{\protected\def\pxpic{\hbox\bgroup\pxpic@}} \newcommand\pxpic@[2][] {% \vbox @@ -803,6 +916,8 @@ and the derived files pxpic.pdf \pxpicsetup{#1}% \let\px\pxpic@px \let\pxskip\pxpic@skip + \advance\pxpicHT\pxpic@kern + \advance\pxpicWD\pxpic@kern \baselineskip\pxpicHT \kern\pxpic@kern \pxpic@parse#2\pxpic@end @@ -832,6 +947,7 @@ and the derived files pxpic.pdf \begingroup \pxpicHT\dimexpr#1\relax \pxpicWD\pxpicHT + \pxpic@kern\z@ \leavevmode \lower3.2\pxpicHT\pxpic [mode=px,colours={o=[HTML]{9F393D},g=black!75},skip=.] @@ -869,13 +985,64 @@ and the derived files pxpic.pdf % These are pretty simple as well, the |new| variant will use \CS{newcommand} % which will do the testing for us, the |set| variant uses \CS{def}. % \begin{macrocode} -\protected\def\pxpicnewmode#1#2% +\protected\long\def\pxpicnewmode#1#2% {\expandafter\newcommand\csname pxpic@parse@px@#1\endcsname[1]{#2}} -\protected\def\pxpicsetmode#1#2% +\protected\long\def\pxpicsetmode#1#2% {\long\expandafter\def\csname pxpic@parse@px@#1\endcsname##1{#2}} % \end{macrocode} % \end{macro} % +% \begin{macro}{\pxpicnewcolorlist,\pxpicsetcolorlist,\pxpicaddcolorlist} +% \begin{macro}[internal]{\pxpicsetcolorlist@,\pxpicaddcolorlist@} +% The colour list is first parsed with \CS{ekvparse} inside an \CS{edef}. +% \CS{ekvparse} will prevent the parsed list from further expanding, leaving +% each list element and \CS{pxpic@experr@noval} or +% \CS{pxpic@setcolor@colorlist} before it. In a second \CS{edef} these will be +% expanded, \CS{pxpic@experr@noval} throwing an error for each element missing +% a colour definition, and \CS{pxpic@setcolor@colorlist} testing for an +% opening bracket (which we do expandably) and leaving the correct definition +% protected against further expansion. The |add| variant uses a temporary +% macro for the parsing part and adds the result to the list holding macro. +% The second expansion step in |set| and both in |add| are done inside a group +% to revert any definition (also those letting tokens to \CS{relax} by +% \CS{csname}) made at this point except for the list macro itself. +% \begin{macrocode} +\protected\def\pxpicnewcolorlist#1% + {% + \@ifundefined{pxpic@colorlist@#1} + {\pxpicsetcolorlist{#1}} + {\pxpic@err@defined@colorlist{#1}\@gobble}% + } +\protected\def\pxpicsetcolorlist#1% + {\expandafter\pxpicsetcolorlist@\csname pxpic@colorlist@#1\endcsname} +\protected\long\def\pxpicsetcolorlist@#1#2% + {% + \edef#1{\ekvparse\pxpic@experr@noval\pxpic@setcolor@colorlist{#2}}% + \begingroup\edef#1{\endgroup\protected\def\unexpanded{#1}{#1}}% + #1% + } +\protected\def\pxpicaddcolorlist#1% + {% + \@ifundefined{pxpic@colorlist@#1} + {\pxpic@err@unknown@colorlist{#1}\@gobble} + {\expandafter\pxpicaddcolorlist@\csname pxpic@colorlist@#1\endcsname}% + } +\protected\long\def\pxpicaddcolorlist@#1#2% + {% + \begingroup + \edef\pxpic@tmp + {\ekvparse\pxpic@experr@noval\pxpic@setcolor@colorlist{#2}}% + \edef\pxpic@tmp + {% + \endgroup + \protected\def\unexpanded{#1}{\unexpanded\expandafter{#1}\pxpic@tmp}% + }% + \pxpic@tmp + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % % \subsection{Parser} % @@ -892,6 +1059,15 @@ and the derived files pxpic.pdf % \end{macrocode} % \end{macro} % +% \begin{macro}[internal]{\pxpic@openbrace} +% For some weirder \TeX\ programming it is sometimes necessary to insert an +% unmatched opening brace. This code does exactly that if it's expanded twice. +% It is put into a single macro so that one can \CS{expandafter} it easier. +% \begin{macrocode} +\newcommand*\pxpic@openbrace{\expandafter{\iffalse}\fi} +% \end{macrocode} +% \end{macro} +% % \begin{macro}[internal]{\pxpic@parse,\pxpic@done} % The parsing loop is pretty simple, first check whether we're done, else open % a new \CS{hbox} (which will form a row in the \CS{vbox} placed by @@ -949,7 +1125,7 @@ and the derived files pxpic.pdf \ekvifdefinedNoVal{pxpic@px}{#1} {\csname\ekv@name{pxpic@px}{#1}N\endcsname}% {% - \pxpic@unknown@px{#1}% + \pxpic@err@unknown@px{#1}% \pxskip }% } @@ -965,7 +1141,7 @@ and the derived files pxpic.pdf {% \pxpic@ifempty{#1} {\pxskip} - {{\color{#1}\px}}% + {{\@declaredcolor{#1}\px}}% } % \end{macrocode} % \end{macro} @@ -996,7 +1172,7 @@ and the derived files pxpic.pdf {% \pxpic@ifempty{##1} {\pxskip} - {{\color[#1]{##1}\px}}% + {{\@undeclaredcolor[#1]{##1}\px}}% }% } \pxpic@tmp{rgb} @@ -1022,7 +1198,7 @@ and the derived files pxpic.pdf % The actual definition of pixels and skips is stored in macros to which the % frontend macros \CS{px} and \CS{pxskip} will be let inside of \CS{pxpic}. % \begin{macrocode} -\newcommand\pxpic@px{\vrule\@height\pxpicHT\@width\pxpicWD\@depth\z@} +\newcommand\pxpic@px{\vrule height\pxpicHT width\pxpicWD depth\z@} \newcommand\pxpic@skip{\hskip\pxpicWD} % \end{macrocode} % \end{macro} @@ -1046,24 +1222,92 @@ and the derived files pxpic.pdf {#1}{#2}% } \newcommand\pxpic@setcolor@a[2] - {\ekvdefNoVal{pxpic@px}{#1}{{\color{#2}\px}}} + {% + \expandafter\def\csname\ekv@name{pxpic@px}{#1}N\endcsname + {{\@declaredcolor{#2}\px}}% + } \newcommand\pxpic@setcolor@b[2] - {\ekvdefNoVal{pxpic@px}{#1}{{\color#2\px}}} + {% + \expandafter\def\csname\ekv@name{pxpic@px}{#1}N\endcsname + {{\@undeclaredcolor#2\px}}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\pxpic@setcolor@colorlist} +% This macro should leave the correct code in the input stream to define a +% single pixel. It is to be used inside of \CS{edef}, hence using +% \CS{unexpanded}, which doesn't have an opening brace directly after it +% so that the \CS{pxpic@ifbracket} test is fully expanded. Next we expand +% \CS{pxpic@setcolor@a}/|b| twice (which will expand the \CS{csname} +% contained in it) and then leave the opening bracket for \CS{unexpanded} in +% the input stream. The code should be used inside a group so that all the +% implicit definitions to \CS{relax} done by \CS{csname} are reverted. +% \begin{macrocode} +\newcommand\pxpic@setcolor@colorlist[2] + {% + \unexpanded\iffalse{\fi + \pxpic@ifbracket\pxpic@end#2.\pxpic@end[]\pxpic@end + {\expandafter\expandafter\expandafter\pxpic@openbrace\pxpic@setcolor@a} + {\expandafter\expandafter\expandafter\pxpic@openbrace\pxpic@setcolor@b} + {#1}{#2}% + }% + } % \end{macrocode} % \end{macro} % % % \subsection{Messages} % -% \begin{macro}[internal]{\pxpic@noval,\pxpic@unknown@px,\pxpic@unknown@mode} +% \begin{macro}[internal] +% { +% \pxpic@err@noval,\pxpic@err@unknown@px,\pxpic@err@unknown@mode, +% \pxpic@err@unknown@colorlist,\pxpic@err@defined@colorlist +% } % These are just some macros throwing errors, nothing special here. % \begin{macrocode} -\newcommand\pxpic@noval[1] +\newcommand\pxpic@err@noval[1] {\PackageError{pxpic}{Missing colour definition for name `\detokenize{#1}'}{}} -\newcommand\pxpic@unknown@px[1] +\newcommand\pxpic@err@unknown@px[1] {\PackageError{pxpic}{Unknown pixel `\detokenize{#1}'. Skipping}{}} -\newcommand\pxpic@unknown@mode[1] +\newcommand\pxpic@err@unknown@mode[1] {\PackageError{pxpic}{Unknown mode `#1'}{}} +\newcommand\pxpic@err@unknown@colorlist[1] + {\PackageError{pxpic}{Unknown colour list `#1'}{}} +\newcommand\pxpic@err@defined@colorlist[1] + {\PackageError{pxpic}{Colour list `#1' already defined}{}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\pxpic@experr} +% This macro can be used to throw an error expandably. For this an undefined +% control sequence \verb*|\pxpic Error:| is used. The group containing +% \CS{expandafter} keeps the definition of \verb*|\pxpic Error:| local (it is +% \CS{relax} after the \CS{csname}) so that it is undefined when it's used. +% The \CS{@firstofone} is needed to get the readable output (now the undefined +% macro and actual message are always the same argument). +% \begin{macrocode} +\def\pxpic@experr#1% + {% + \long\def\pxpic@experr##1% + {% + \expandafter\expandafter\expandafter + \pxpic@ifend + \@firstofone{#1##1}% + \pxpic@end + }% + } +\begingroup\expandafter\endgroup +\expandafter\pxpic@experr\csname pxpic Error:\endcsname +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\pxpic@experr@noval} +% With the expandable error throwing mechanism out of the way, the following +% is straight forward again. +% \begin{macrocode} +\newcommand\pxpic@experr@noval[1] + {\pxpic@experr{Missing colour definition for `#1'}} % \end{macrocode} % \end{macro} % diff --git a/graphics/pxpic/pxpic.pdf b/graphics/pxpic/pxpic.pdf index 2148303a47..075ce07723 100644 Binary files a/graphics/pxpic/pxpic.pdf and b/graphics/pxpic/pxpic.pdf differ diff --git a/info/beginlatex/src/pslatex.sty b/info/beginlatex/src/pslatex.sty deleted file mode 100644 index 2a0ea334f1..0000000000 --- a/info/beginlatex/src/pslatex.sty +++ /dev/null @@ -1,458 +0,0 @@ - -\ProvidesPackage{pslatex}[1996/07/24 v1.2 pslatex emulation (DPC)] - -% Copyright 1994 1996 David Carlisle -% This file may be distributed under the terms of the LPPL. -% See 00readme.txt for details. - -% 1994/06/28 v1.0 -% 1996/07/22 v1.1 update to `8r' encoded base fonts. -% 1996/07/24 v1.2 New way of resolving \pounds/\$ problem - -%%% pslatex emulation for LaTeX2e -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -% This file consists of verbatim copies of times.sty and mathptm.sty -% to get a basic times/helvetica/courier setup. -% -% It then has a copy of OT1pcr.fd -% modified to load a narrowed version of courier. -% and make the ui substitution silent (ui now removed v1.2) -% -% It then has a copy of OT1phv.fd -% modified to load helvetica at 90%. -% and make the ui substitution silent (ui now removed v1.2) -% -% It then has a copy of OT1ptm.fd -% modified to make the ui substitution silent (ui now removed v1.2) -% -% -% It finally runs \normalfont (if run by the pslatex script -% it is loaded after \begin{document} has run \normalfont). - - -% (Not) supporting \pounds in OT1 -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% But before that it tells LaTeX that OT1 fonts have not got -% a pound sign, and that if any encoding has not got a pound sign, -% to use the one from the T1 encoding. -% -% NOTE!!! This means that any font in which you want a \pounds must -% be available in T1 encoded form. This is no problem for all the -% PostScript fonts as they are distributed in T1 and OT1. But if -% you mix postscript fonts with Computer Modern, you'll need the T1 -% encoded Computer Modern (dc) fonts available. -% Because of this change all substitutions for the ui font shape -% (which is only ever used for \pounds) are removed. - - -\DeclareTextSymbolDefault{\textsterling}{T1} - -\expandafter\let - \csname OT1\string\textsterling\endcsname\@undefined - - -%%%% TIMES.STY - -\renewcommand{\sfdefault}{phv} -\renewcommand{\rmdefault}{ptm} -\renewcommand{\ttdefault}{pcr} - - -%%%% MATHPTM.STY - -\DeclareSymbolFont{operators} {OT1}{ptmcm}{m}{n} -\DeclareSymbolFont{letters} {OML}{ptmcm}{m}{it} -\DeclareSymbolFont{symbols} {OMS}{pzccm}{m}{n} -\DeclareSymbolFont{largesymbols}{OMX}{psycm}{m}{n} -\DeclareSymbolFont{bold} {OT1}{ptm}{bx}{n} -\DeclareSymbolFont{italic} {OT1}{ptm}{m}{it} - -% If we're in compatibility mode, defined \mathbf and \mathit. - -\@ifundefined{mathbf}{}{\DeclareMathAlphabet{\mathbf}{OT1}{ptm}{bx}{n}} -\@ifundefined{mathit}{}{\DeclareMathAlphabet{\mathit}{OT1}{ptm}{m}{it}} - -% An \omicron command, to fill the gap. - -\DeclareMathSymbol{\omicron}{0}{operators}{`\o} - -% Reduce the space around math operators - -\thinmuskip=2mu -\medmuskip=2.5mu plus 1mu minus 1mu -\thickmuskip=4mu plus 1.5mu minus 1mu - -% No bold math. - -\def\boldmath{% - \@warning{there is no bold Symbol font}% - \global\let\boldmath=\relax -} - -% Larger scripts. - -\DeclareMathSizes{5}{5}{5}{5} -\DeclareMathSizes{6}{6}{5}{5} -\DeclareMathSizes{7}{7}{5}{5} -\DeclareMathSizes{8}{8}{6}{5} -\DeclareMathSizes{9}{9}{7}{5} -\DeclareMathSizes{10}{10}{7.4}{6} -\DeclareMathSizes{10.95}{10.95}{8}{6} -\DeclareMathSizes{12}{12}{9}{7} -\DeclareMathSizes{14.4}{14.4}{10.95}{8} -\DeclareMathSizes{17.28}{17.28}{12}{10} -\DeclareMathSizes{20.74}{20.74}{14.4}{12} -\DeclareMathSizes{24.88}{24.88}{17.28}{14.4} - - -\DeclareFontSubstitution{OMS}{pzccm}{m}{n} - -\begingroup -\nfss@catcodes - -%%%%% ``OMSptm.fd'' -\DeclareFontFamily{OMS}{ptm}{} -\DeclareFontShape{OMS}{ptm}{m}{n} - {<-> ssub * pzccm/m/n}{} -\DeclareFontShape{OMS}{ptm}{m}{it} - {<-> ssub * pzccm/m/n}{} -\DeclareFontShape{OMS}{ptm}{m}{sl} - {<-> ssub * pzccm/m/n}{} -\DeclareFontShape{OMS}{ptm}{m}{sc} - {<-> ssub * pzccm/m/n}{} -\DeclareFontShape{OMS}{ptm}{bx}{n} - {<-> ssub * pzccm/b/n}{} -\DeclareFontShape{OMS}{ptm}{bx}{it} - {<-> ssub * pzccm/b/n}{} -\DeclareFontShape{OMS}{ptm}{bx}{sl} - {<-> ssub * pzccm/b/n}{} -\DeclareFontShape{OMS}{ptm}{bx}{sc} - {<-> ssub * pzccm/b/n}{} - - - -%%%% OT1pcr.fd -% -\DeclareFontFamily{OT1}{pcr}{\hyphenchar \font =-1}% -% -\DeclareFontShape{OT1}{pcr}{b}{n}{% - <-> s * [1.1] pcrb7t% -}{}% -% -\DeclareFontShape{OT1}{pcr}{b}{sc}{% - <-> s * [1.1] pcrbc7t% -}{}% -% -\DeclareFontShape{OT1}{pcr}{b}{sl}{% - <-> s * [1.1] pcrbo7t% -}{}% -% -%%%% pslatex's condenced courier -\DeclareFontShape{OT1}{pcr}{m}{n}{% - <-> s * [1.1] pcrr7tn% -}{}% -% -\DeclareFontShape{OT1}{pcr}{m}{sc}{% - <-> s * [1.1] pcrrc7t% -}{}% -% -\DeclareFontShape{OT1}{pcr}{m}{sl}{% - <-> s * [1.1] pcrro7t% -}{}% - -% -\DeclareFontShape{OT1}{pcr}{bx}{n}{<->ssub * pcr/b/n}{}% -\DeclareFontShape{OT1}{pcr}{bx}{sc}{<->ssub * pcr/b/sc}{}% -\DeclareFontShape{OT1}{pcr}{bx}{sl}{<->ssub * pcr/b/sl}{}% -\DeclareFontShape{OT1}{pcr}{b}{it}{<->ssub * pcr/b/sl}{}% -\DeclareFontShape{OT1}{pcr}{bx}{it}{<->ssub * pcr/b/it}{}% -\DeclareFontShape{OT1}{pcr}{m}{it}{<->ssub * pcr/m/sl}{}% - -% - - - - -%%%% OT1phv.fd - -%%Filename: OT1phv.fd -%%Created by: tex 16273helvetic -%%Created using fontinst v1.328 - -%%THIS FILE SHOULD BE PUT IN A TEX INPUTS DIRECTORY - -\DeclareFontFamily{OT1}{phv}{} - -\DeclareFontShape{OT1}{phv}{b}{n}{ - <-> s * [.9] phvb7t -}{} - -\DeclareFontShape{OT1}{phv}{b}{sc}{ - <-> s * [.9] phvbc7t -}{} - -\DeclareFontShape{OT1}{phv}{b}{sl}{ - <-> s * [.9] phvbo7t -}{} - -\DeclareFontShape{OT1}{phv}{bc}{n}{ - <-> s * [.9] phvbrn7t -}{} - -\DeclareFontShape{OT1}{phv}{bc}{sc}{ - <-> s * [.9] phvbcn7t -}{} - -\DeclareFontShape{OT1}{phv}{bc}{sl}{ - <-> s * [.9] phvbon7t -}{} - -\DeclareFontShape{OT1}{phv}{m}{n}{ - <-> s * [.9] phvr7t -}{} - -\DeclareFontShape{OT1}{phv}{m}{sc}{ - <-> s * [.9] phvrc7t -}{} - -\DeclareFontShape{OT1}{phv}{m}{sl}{ - <-> s * [.9] phvro7t -}{} - -\DeclareFontShape{OT1}{phv}{mc}{n}{ - <-> s * [.9] phvrrn7t -}{} - -\DeclareFontShape{OT1}{phv}{mc}{sc}{ - <-> s * [.9] phvrcn7t -}{} - -\DeclareFontShape{OT1}{phv}{mc}{sl}{ - <-> s * [.9] phvron7t -}{} - -\DeclareFontShape{OT1}{phv}{bx}{n}{<->ssub * phv/b/n}{} -\DeclareFontShape{OT1}{phv}{bx}{sc}{<->ssub * phv/b/sc}{} -\DeclareFontShape{OT1}{phv}{bx}{sl}{<->ssub * phv/b/sl}{} -\DeclareFontShape{OT1}{phv}{b}{it}{<->ssub * phv/b/sl}{} -\DeclareFontShape{OT1}{phv}{bx}{it}{<->ssub * phv/b/it}{} -\DeclareFontShape{OT1}{phv}{bc}{it}{<->ssub * phv/bc/sl}{} -\DeclareFontShape{OT1}{phv}{m}{it}{<->ssub * phv/m/sl}{} -\DeclareFontShape{OT1}{phv}{mc}{it}{<->ssub * phv/mc/sl}{} - - - -%%%% OT1ptm.fd - -%Filename: OT1ptm.fd -%Created by: tex 16594times -%Created using fontinst v1.328 - -%THIS FILE SHOULD BE PUT IN A TEX INPUTS DIRECTORY - -\DeclareFontFamily{OT1}{ptm}{} - -\DeclareFontShape{OT1}{ptm}{b}{n}{ - <-> ptmb7t -}{} - -\DeclareFontShape{OT1}{ptm}{b}{sc}{ - <-> ptmbc7t -}{} - -\DeclareFontShape{OT1}{ptm}{b}{it}{ - <-> ptmbi7t -}{} - -\DeclareFontShape{OT1}{ptm}{b}{sl}{ - <-> ptmbo7t -}{} - -\DeclareFontShape{OT1}{ptm}{m}{n}{ - <-> ptmr7t -}{} - -\DeclareFontShape{OT1}{ptm}{m}{sc}{ - <-> ptmrc7t -}{} - -\DeclareFontShape{OT1}{ptm}{m}{it}{ - <-> ptmri7t -}{} - -\DeclareFontShape{OT1}{ptm}{m}{sl}{ - <-> ptmro7t -}{} - -\DeclareFontShape{OT1}{ptm}{bx}{n}{<->ssub * ptm/b/n}{} -\DeclareFontShape{OT1}{ptm}{bx}{sc}{<->ssub * ptm/b/sc}{} -\DeclareFontShape{OT1}{ptm}{bx}{it}{<->ssub * ptm/b/it}{} -\DeclareFontShape{OT1}{ptm}{bx}{sl}{<->ssub * ptm/b/sl}{} - - - -%%%% T1pcr.fd -% -\DeclareFontFamily{T1}{pcr}{\hyphenchar \font =-1}% -% -\DeclareFontShape{T1}{pcr}{b}{n}{% - <-> pcrb8t% -}{}% -% -\DeclareFontShape{T1}{pcr}{b}{sc}{% - <-> pcrbc8t% -}{}% -% -\DeclareFontShape{T1}{pcr}{b}{sl}{% - <-> pcrbo8t% -}{}% -% -%%%% pslatex's condensed courier -\DeclareFontShape{T1}{pcr}{m}{n}{% - <-> pcrr8tn% -}{}% -% -\DeclareFontShape{T1}{pcr}{m}{sc}{% - <-> pcrrc8t% -}{}% -% -\DeclareFontShape{T1}{pcr}{m}{sl}{% - <-> pcrro8t% -}{}% -% -\DeclareFontShape{T1}{pcr}{bx}{n}{<->ssub * pcr/b/n}{}% -\DeclareFontShape{T1}{pcr}{bx}{sc}{<->ssub * pcr/b/sc}{}% -\DeclareFontShape{T1}{pcr}{bx}{sl}{<->ssub * pcr/b/sl}{}% -\DeclareFontShape{T1}{pcr}{b}{it}{<->ssub * pcr/b/sl}{}% -\DeclareFontShape{T1}{pcr}{bx}{it}{<->ssub * pcr/b/it}{}% -\DeclareFontShape{T1}{pcr}{m}{it}{<->ssub * pcr/m/sl}{}% -% - - - - -%%%% T1phv.fd - -%%Filename: T1phv.fd -%%Created by: tex 16273helvetic -%%Created using fontinst v1.328 - -%%THIS FILE SHOULD BE PUT IN A TEX INPUTS DIRECTORY - -\DeclareFontFamily{T1}{phv}{} - -\DeclareFontShape{T1}{phv}{b}{n}{ - <-> s * [.9] phvb8t -}{} - -\DeclareFontShape{T1}{phv}{b}{sc}{ - <-> s * [.9] phvbc8t -}{} - -\DeclareFontShape{T1}{phv}{b}{sl}{ - <-> s * [.9] phvbo8t -}{} - -\DeclareFontShape{T1}{phv}{bc}{n}{ - <-> s * [.9] phvbrn8t -}{} - -\DeclareFontShape{T1}{phv}{bc}{sc}{ - <-> s * [.9] phvbcn8t -}{} - -\DeclareFontShape{T1}{phv}{bc}{sl}{ - <-> s * [.9] phvbon8t -}{} - -\DeclareFontShape{T1}{phv}{m}{n}{ - <-> s * [.9] phvr8t -}{} - -\DeclareFontShape{T1}{phv}{m}{sc}{ - <-> s * [.9] phvrc8t -}{} - -\DeclareFontShape{T1}{phv}{m}{sl}{ - <-> s * [.9] phvro8t -}{} - -\DeclareFontShape{T1}{phv}{mc}{n}{ - <-> s * [.9] phvrrn8t -}{} - -\DeclareFontShape{T1}{phv}{mc}{sc}{ - <-> s * [.9] phvrcn8t -}{} - -\DeclareFontShape{T1}{phv}{mc}{sl}{ - <-> s * [.9] phvron8t -}{} - -\DeclareFontShape{T1}{phv}{bx}{n}{<->ssub * phv/b/n}{} -\DeclareFontShape{T1}{phv}{bx}{sc}{<->ssub * phv/b/sc}{} -\DeclareFontShape{T1}{phv}{bx}{sl}{<->ssub * phv/b/sl}{} -\DeclareFontShape{T1}{phv}{b}{it}{<->ssub * phv/b/sl}{} -\DeclareFontShape{T1}{phv}{bx}{it}{<->ssub * phv/b/it}{} -\DeclareFontShape{T1}{phv}{bc}{it}{<->ssub * phv/bc/sl}{} -\DeclareFontShape{T1}{phv}{m}{it}{<->ssub * phv/m/sl}{} -\DeclareFontShape{T1}{phv}{mc}{it}{<->ssub * phv/mc/sl}{} - - - -%%%% T1ptm.fd - -%Filename: T1ptm.fd -%Created by: tex 16594times -%Created using fontinst v1.328 - -%THIS FILE SHOULD BE PUT IN A TEX INPUTS DIRECTORY - -\DeclareFontFamily{T1}{ptm}{} - -\DeclareFontShape{T1}{ptm}{b}{n}{ - <-> ptmb8t -}{} - -\DeclareFontShape{T1}{ptm}{b}{sc}{ - <-> ptmbc8t -}{} - -\DeclareFontShape{T1}{ptm}{b}{it}{ - <-> ptmbi8t -}{} - -\DeclareFontShape{T1}{ptm}{b}{sl}{ - <-> ptmbo8t -}{} - -\DeclareFontShape{T1}{ptm}{m}{n}{ - <-> ptmr8t -}{} - -\DeclareFontShape{T1}{ptm}{m}{sc}{ - <-> ptmrc8t -}{} - -\DeclareFontShape{T1}{ptm}{m}{it}{ - <-> ptmri8t -}{} - -\DeclareFontShape{T1}{ptm}{m}{sl}{ - <-> ptmro8t -}{} - -\DeclareFontShape{T1}{ptm}{bx}{n}{<->ssub * ptm/b/n}{} -\DeclareFontShape{T1}{ptm}{bx}{sc}{<->ssub * ptm/b/sc}{} -\DeclareFontShape{T1}{ptm}{bx}{it}{<->ssub * ptm/b/it}{} -\DeclareFontShape{T1}{ptm}{bx}{sl}{<->ssub * ptm/b/sl}{} - -\endgroup - -% And finally... - -\normalfont - -\endinput diff --git a/macros/latex/contrib/acro/README b/macros/latex/contrib/acro/README index 8f09cc322b..b0382e1302 100644 --- a/macros/latex/contrib/acro/README +++ b/macros/latex/contrib/acro/README @@ -1,5 +1,5 @@ --------------------------------------------------------------------------- -the ACRO package v3.4 2020/12/25 +#-------------------------------------------------------------------------- +the ACRO package v3.5 2021/01/16 Typeset Acronyms @@ -8,7 +8,7 @@ Clemens Niederberger Web: https://github.com/cgnieder/acro E-Mail: contact@mychemistry.eu -------------------------------------------------------------------------- -Copyright 2012--2020 Clemens Niederberger +Copyright 2012--2021 Clemens Niederberger This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c @@ -26,6 +26,7 @@ The acro package consists of code files: acro.sty acro2.sty + acro-examples.sty The acro package consists of documentation files: diff --git a/macros/latex/contrib/acro/acro-examples.sty b/macros/latex/contrib/acro/acro-examples.sty new file mode 100644 index 0000000000..01fca6ada3 --- /dev/null +++ b/macros/latex/contrib/acro/acro-examples.sty @@ -0,0 +1,166 @@ +\RequirePackage{acro} +\ProvidesPackage{acro-examples}[\csname c_acro_date_tl\endcsname\space v0.1 +example definitions with acro (CN)] + +\DeclareAcronym{afaik}{ + short = AFAIK , + long = as far as I know +} +\DeclareAcronym{afk}{ + short = AFK , + long = away from keyboard +} +\DeclareAcronym{asap}{ + short = ASAP , + long = as soon as possible +} +\DeclareAcronym{ba}{ + short = BA , + long = Bachelor of Arts +} +\DeclareAcronym{bnd}{ + short = BND , + long = Bundesnachrichtendienst +} +\DeclareAcronym{bs}{ + short = BS , + long = Bachelor of Science +} +\DeclareAcronym{cd}{ + short = CD , + long = compact disc +} +\DeclareAcronym{cdu}{ + short = CDU , + long = Christlich-Demokratische Union +} +\DeclareAcronym{ceo}{ + short = CEO , + long = chief executive officer +} +\DeclareAcronym{cia}{ + short = CIA , + long = Central Intelligence Agency +} +\DeclareAcronym{csu}{ + short = CSU , + long = Christlich-Soziale Union +} +\DeclareAcronym{ctan}{ + short = CTAN , + long = Comprehensive \TeX\ Archive Network +} +\DeclareAcronym{dea}{ + short = DEA , + long = Drug Enforcement Administration +} +\DeclareAcronym{diy}{ + short = DIY , + long = do it yourself +} +\DeclareAcronym{dpa}{ + short = DPA , + long = Deutsche Presseagentur +} +\DeclareAcronym{eta}{ + short = ETA , + long = estimated time of arrival +} +\DeclareAcronym{fbi}{ + short = FBI , + long = Federal Bureau of Investigation +} +\acroifpropertyTF{ + \DeclareAcronym{hadopi}{ + short = HADOPI , + long = Haute Autorité pour la diffusion des œuvres et la protection des + droits sur l’Internet , + short-definite = l'\nospace , + long-definite = la + } +}{ + \DeclareAcronym{hadopi}{ + short = HADOPI , + long = Haute Autorité pour la diffusion des œuvres et la protection des + droits sur l’Internet + } +} +\DeclareAcronym{iirc}{ + short = IIRC , + long = if I remember correctly +} +\DeclareAcronym{imho}{ + short = IMHO , + long = in my humble opinion +} +\DeclareAcronym{jpg}{ + short = JPEG , + sort = jpeg , + alt = JPG , + long = joint photographic experts group +} +\DeclareAcronym{ksk}{ + short = KSK , + long = Kommando Spezialkräfte +} +\DeclareAcronym{lol}{ + short = LOL , + long = loughing out loud +} +\DeclareAcronym{lppl}{ + short = LPPL , + long = \unexpanded{\LaTeX} Project Public License +} +\DeclareAcronym{ma}{ + short = MA , + long = Master of Arts +} +\DeclareAcronym{nato}{ + short = NATO , + long = North Atlantic Treaty Organization +} +\DeclareAcronym{nsa}{ + short = NSA , + long = National Security Agency +} +\DeclareAcronym{omg}{ + short = OMG , + long = oh my god +} +\DeclareAcronym{otan}{ + short = OTAN , + long = Organisation du Traité de l'Atlantique Nord +} +\DeclareAcronym{pdf}{ + short = PDF , + long = portable document format +} +\DeclareAcronym{png}{ + short = PNG , + long = portable network graphics +} +\DeclareAcronym{rofl}{ + short = ROFL , + long = rolling on the floor laughing +} +\DeclareAcronym{spd}{ + short = SPD , + long = Sozialdemokratische Partei Deutschlands +} +\DeclareAcronym{tiff}{ + short = TIFF , + long = tagged image file format +} +\DeclareAcronym{ufo}{ + short = UFO , + long = unidentified flying object , + long-indefinite = an +} +\DeclareAcronym{yolo}{ + short = YOLO , + long = you only live once +} + +\endinput + +2021/01/13 - first version diff --git a/macros/latex/contrib/acro/acro-manual.pdf b/macros/latex/contrib/acro/acro-manual.pdf index 24026d28a3..54c8b151c6 100644 Binary files a/macros/latex/contrib/acro/acro-manual.pdf and b/macros/latex/contrib/acro/acro-manual.pdf differ diff --git a/macros/latex/contrib/acro/acro-manual.tex b/macros/latex/contrib/acro/acro-manual.tex index 4f2a5d2442..b8288eb6ca 100644 --- a/macros/latex/contrib/acro/acro-manual.tex +++ b/macros/latex/contrib/acro/acro-manual.tex @@ -1,3 +1,5 @@ +% arara: pdflatex +% arara: pdflatex % -------------------------------------------------------------------------- % the ACRO package % @@ -8,7 +10,7 @@ % Web: https://github.com/cgnieder/acro/ % E-Mail: contact@mychemistry.eu % -------------------------------------------------------------------------- -% Copyright 2011--2020 Clemens Niederberger +% Copyright 2011--2021 Clemens Niederberger % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c @@ -218,7 +220,7 @@ \clearpage \part{Get started with \acro}\label{part:get-started-with} -\section{Licence and requirements}\label{sec:licence-requirements} +\section{Licence}\label{sec:licence} \license \section{Glossary} @@ -409,7 +411,7 @@ the same. In that case you can use %% sort \propval{sort}{text}\Default={short} If used the acronym will be sorted according to this property instead of - its \ac{id}. + its short form. %% tag \propval{tag}{csv list}\Default The tag(s) of an acronym. @@ -432,6 +434,11 @@ the same. In that case you can use value of the \property{sort} property. This property allows to set an individual sorting option for the index. See section~\vref{sec:indexing} for details. + %% index-cmd + \propval{index-cmd}{index command}\Default + This sets the indexing command for the acronym. If unused then the + command set by the corresponding option is used. See + section~\vref{sec:indexing} for details. \end{properties} \subsection{Properties related to plural and indefinite forms}\label{sec:prop-relat-plur} @@ -585,8 +592,32 @@ the same. In that case you can use set then the appropriate value might be derived from \property{foreign-babel}. See section~\vref{sec:fore-lang-acronyms} for details. + %% preset + \propval{preset}{set name}\Default + \sinceversion{3.5}Enables to load a set of properties that has been + defined earlier with \cs{NewAcroPreset}, siehe + section~\vref{sec:presets}. + %% uselist + \propval{uselist}{csv list of acronym ids}\Default + \sinceversion{3.5}If this property is given and all acronyms specified in + this property have been used before the first time the current acronym is + used it behaves as if it has been used before. \end{properties} +\subsection{Presets}\label{sec:presets} +\sinceversion{3.5}Sometimes it can be useful to have different kinds of +acronyms or abbreviations or similar which share a common set of properties. +Such sets can be defined with these commands: +\begin{commands} + \command{NewAcroPreset}[\marg{set name}\marg{csv list of properties}] + Defines the property set \meta{set name}. Any valid property can be set + in \meta{csv list of properties}. + \command{RenewAcroPreset}[\marg{set name}\marg{csv list of properties}] + Redefines the property set \meta{set name}. + \command{DeclareAcroPreset}[\marg{set name}\marg{csv list of properties}] + Defines or redefines the property set \meta{set name} without checking. +\end{commands} + \section{Using acronyms}\label{sec:using-acronyms} There are a number of commands to use acronyms with. Their names always follow the same pattern which should make their usage intuitive immediately. @@ -883,12 +914,18 @@ the list of acronym you can use these options: The threshold for a page range to be turned into \latin{sequentes}. A page range above the threshold is still typeset as a range: \meta{num1}--\meta{num2}. - \keyval{fill}{code}\Module{pages}\Default{\cs*{dotfill}} + \keyval{fill}{code}\Module{pages}\Default{\cs*{acrdotfill}} This is the code that is placed between acronym description and actual page numbers. \keybool{name}\Module{pages}\Default{false} If set to true the page numbers are preceded with p.\ or pp. \end{options} +\begin{commands} + \command{acrodotfill} + \sinceversion{3.5}Creates a dotted line like those in the table of + contents. If the macro \cs*{cftdotfill} is defined it is equal to + \cs*{cftdotfill}\Marg{\cs*{cftdotsep}}. +\end{commands} Additionally\sinceversion{3.3} to setting these options with \cs{acsetup} they can be set as options to \cs{printacronyms}: \begin{sourcecode} @@ -1274,7 +1311,7 @@ have no effect, of course. } \end{sourcecode} -\pagebreak +% \pagebreak There are a number of options to control the uppercasing behavior: \begin{options} @@ -1370,8 +1407,10 @@ Maybe you want to add your acronyms to an index. In that case it is probably desirable to let \acro\ make this automatically. In the simplest case just enable it: \begin{options} - \keybool{use}\Module{index}\Default{false} - Enable indexing. + \keychoice{use}{\default{true},false,indexed}\Module{index}\Default{false} + \changedversion{3.5}Enable indexing. If \code{indexed} is chosen only the + acronyms for which the property \property{index} has been set are indexed. + With \code{true} \emph{all} acronyms are indexed. \keyval{cmd}{index command}\Module{index}\Default{\cs*{index}} Choose a command for indexing. \keyval{disable}{code}\Module{index}\Default{\cs*{def}\cs*{@}\{\}} @@ -1568,6 +1607,10 @@ option: \keybool{make-links}\Default{false} If this is activated then every short or alternative appearance of an acronym will be linked to its description in the list of acronyms. + \keybool{link-only-first}\Default{false} + \sinceversion{3.5}If this is activated in addition to \option{make-links} + then \emph{only the first} short or alternative appearance of an acronym + will be linked to its description in the list of acronyms. \end{options} \begin{bewareofthedog} This will fail miserably together with local lists if an acronym appears in @@ -1883,7 +1926,7 @@ to defines own such objects: page ranges. \end{templates} -\subsubsection{Header templates} +\subsubsection{Heading templates} \begin{templates} \tmpl{addchap} Only defined in a \KOMAScript\ class and if \cs*{chapter} is defined. Uses @@ -1985,9 +2028,22 @@ and \cs*{acroifF} each have an argument less than \cs*{acroifTF}. \command{acroiftag\TF}[\marg{tag}\marg{true}\marg{false}] Checks if the current acronym has been given the tag \meta{tag} and either leaves \meta{true} or \meta{false} in the input stream. + \command{acroifstarred\TF}[\marg{true}\marg{false}] + \sinceversion{3.5}Checks if the current call of the acronym is a starred + command or not and either leaves \meta{true} or \meta{false} in the input + stream. \command{AcroPropertiesMap}[\marg{code}] Maps over all defined acronym properties. Within \meta{code} you can refer to the current property with \code{\#1}. + \command{AcroAcronymsMap}[\marg{code}] + \sinceversion{3.5}Maps over all defined acronyms. Within \meta{code} you + can refer to the current property with \code{\#1} or with \cs{AcronymID}. + \command{AcroMapBreak} + \sinceversion{3.5}Stops the map \cs{AcroAcronymsMap} and is usually used + in combination with a boolean check. + \command{AcroPropertiesSet}[\marg{id}\marg{csv list of properties}] + \sinceversion{3.5}Allows the setting of properties of acronym \meta{id} + outside of \cs{declareAcronym}. \end{commands} \subsubsection{Commands for usage in acronym templates} @@ -2173,6 +2229,13 @@ first the table body is built and only then the table itself is printed: \end{sourcecode} \subsection{New heading templates}\label{sec:new-head-templ} +Let's take a look at the two templates \template{section} and +\template{section*} which should give you enough information to build your +own: +\begin{sourcecode} + \NewAcroTemplate[heading]{section} {\section {\acrolistname}} + \NewAcroTemplate[heading]{section*}{\section*{\acrolistname}} +\end{sourcecode} \section{Endings}\label{sec:endings} Referring to section~\vref{sec:other-endings} this section explains how to diff --git a/macros/latex/contrib/acro/acro.sty b/macros/latex/contrib/acro/acro.sty index 8efd343d1d..cfa5193f85 100644 --- a/macros/latex/contrib/acro/acro.sty +++ b/macros/latex/contrib/acro/acro.sty @@ -8,7 +8,7 @@ % Web: https://github.com/cgnieder/acro/ % E-Mail: contact@mychemistry.eu % -------------------------------------------------------------------------- -% Copyright 2011--2020 Clemens Niederberger +% Copyright 2011--2021 Clemens Niederberger % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c @@ -22,14 +22,14 @@ % % The Current Maintainer of this work is Clemens Niederberger. % -------------------------------------------------------------------------- -\RequirePackage{l3keys2e} +\RequirePackage {l3keys2e} \ExplSyntaxOn % setup package: \tl_const:Nn \c_acro_package_name_tl {acro} -\tl_const:Nn \c_acro_date_tl {2020/12/25} +\tl_const:Nn \c_acro_date_tl {2021/01/16} \tl_const:Nn \c_acro_version_major_number_tl {3} -\tl_const:Nn \c_acro_version_minor_number_tl {4} +\tl_const:Nn \c_acro_version_minor_number_tl {5} \tl_const:Nn \c_acro_version_subrelease_tl {} \tl_const:Nx \c_acro_version_number_tl { @@ -47,7 +47,7 @@ {\c_acro_package_name_tl} {\c_acro_date_tl} {\c_acro_version_tl} - {\c_acro_info_tl} + {\c_acro_info_tl \c_space_tl (CN)} % -------------------------------------------------------------------------- % document hooks: @@ -84,23 +84,23 @@ \bool_new:N \g__acro_rerun_bool \tl_new:N \g__acro_rerun_message_tl -\tl_const:Nn \l__acro_rerun_general_tl +\tl_const:Nn \c__acro_rerun_general_tl { Rerun~ to~ get~ `acro'~ synchronized. } -\tl_const:Nn \l__acro_rerun_property_tl +\tl_const:Nn \c__acro_rerun_property_tl { Acronym~ properties~ may~ have~ changed.~ Rerun~ to~ get~ them~ synchronized. } -\tl_const:Nn \l__acro_rerun_list_tl +\tl_const:Nn \c__acro_rerun_list_tl { Empty~ acronym~ list.~ If~ you~ have~ used~ acronyms~ then~ re-compile~ to~ get~ the~ list~ filled.~ Otherwise~ remove~ \token_to_str:N \printacronyms } -\msg_new:nnn {acro} {rerun} { \use:c {l__acro_rerun_#1_tl} } +\msg_new:nnn {acro} {rerun} { \use:c {c__acro_rerun_#1_tl} } \prg_new_conditional:Npnn \acro_if_rerun: {p,T,F,TF} { @@ -191,11 +191,11 @@ debug .initial:n = false , upgrade .bool_gset:N = \g__acro_upgrade_bool , upgrade .initial:n = true , - final .bool_set:N = \g__acro_final_bool , + final .bool_gset:N = \g__acro_final_bool , final .initial:n = false , version .choice: , - version / 2 .code:n = \int_set:Nn \g__acro_version_int {2} , - version / 3 .code:n = \int_set:Nn \g__acro_version_int {3} , + version / 2 .code:n = \int_gset:Nn \g__acro_version_int {2} , + version / 3 .code:n = \int_gset:Nn \g__acro_version_int {3} , version .initial:n = 3 , unknown .code:n = \__acro_loadtime_warning:n {unknown-option} } @@ -486,10 +486,11 @@ \cs_generate_variant:Nn \tl_remove_all:Nn {NV} \cs_generate_variant:Nn \tl_remove_once:Nn {NV} \cs_generate_variant:Nn \tl_if_in:NnF {NV} +\cs_generate_variant:Nn \tl_if_eq:nnTF {VV} \cs_generate_variant:Nn \tl_put_right:Nn {Ne} \cs_generate_variant:Nn \clist_set:Nn {Ne} \cs_generate_variant:Nn \str_if_eq:nnT {x} -\cs_generate_variant:Nn \str_fold_case:n {e} +\cs_generate_variant:Nn \str_foldcase:n {e} \cs_generate_variant:Nn \str_lowercase:n {e} \cs_generate_variant:Nn \msg_error:nnnnn {nnnxx} \cs_generate_variant:Nn \msg_warning:nn {nV} @@ -648,6 +649,14 @@ \NewDocumentCommand \AcroPropertiesMap {+m} { \acro_properties_map:n {#1} } +\NewDocumentCommand \AcroAcronymsMap {+m} + { \acro_map_acronyms:n { \tl_set:Nn \AcronymID {##1} #1 } } + +\NewExpandableDocumentCommand \AcroMapBreak {} { \acro_map_break: } + +\NewDocumentCommand \AcroPropertiesSet {m+m} + { \acro_properties_set:nn {#1} {#2} } + \NewDocumentCommand \AcroMap {m+m} { \acro_list_map:nn {#1} {#2} } @@ -668,9 +677,24 @@ \NewDocumentCommand \acroloadstyle {m} { \acro_style_load:n {#1} } +\NewExpandableDocumentCommand \acroifstarredTF {} + { \bool_if:NTF \l__acro_star_bool } + +\NewExpandableDocumentCommand \acroifstarredT {} + { \bool_if:NT \l__acro_star_bool } + +\NewExpandableDocumentCommand \acroifstarredF {} + { \bool_if:NF \l__acro_star_bool } + \NewExpandableDocumentCommand \acroifusedTF {m} { \acro_boolean_property_if:nnTF {#1} {used} } +\NewExpandableDocumentCommand \acroifusedT {m} + { \acro_boolean_property_if:nnT {#1} {used} } + +\NewExpandableDocumentCommand \acroifusedF {m} + { \acro_boolean_property_if:nnF {#1} {used} } + \NewDocumentCommand \acuse {m} { \acro_use:n {#1} } @@ -726,6 +750,16 @@ \NewDocumentCommand \MakeAcroPropertyAlias {mm} { \acro_property_make_alias:nn {#1} {#2} } +\NewDocumentCommand \NewAcroPreset {m+m} + { \acro_preset_new:nn {#1} {#2} } + +\NewDocumentCommand \RenewAcroPreset {m+m} + { \acro_preset_renew:nn {#1} {#2} } + +\NewDocumentCommand \DeclareAcroPreset {m+m} + { \acro_preset_declare:nn {#1} {#2} } + +% -------------------------------------------------------------------------- \NewDocumentCommand \UseAcroTemplate {O{acronym}mO{1}} { \acro_template_use:nnn {#3} {#1} {#2} } @@ -828,7 +862,7 @@ { \acro_write:en {#1} {#2} } } -\NewExpandableDocumentCommand \acrofieldifTF {+m+m+m+m} +\NewExpandableDocumentCommand \acroiffieldTF {+m+m+m+m} { \acro_property_if_set:nnTF {#1} {#2} {#3} {#4} } \NewDocumentCommand \acroifanyfieldTF {mm+m+m} @@ -866,6 +900,15 @@ \NewDocumentCommand \acrocite {} { \bool_set_true:N \l__acro_cite_always_bool } +\NewExpandableDocumentCommand \acroifpropertyTF {m} + { \acro_property_if_exist:nTF {#1} } + +\NewExpandableDocumentCommand \acroifpropertyT {m} + { \acro_property_if_exist:nT {#1} } + +\NewExpandableDocumentCommand \acroifpropertyF {m} + { \acro_property_if_exist:nF {#1} } + \NewExpandableDocumentCommand \acroifbooleanTF {m} { \acro_boolean_property_if:enTF { \AcronymID } {#1} } @@ -911,11 +954,11 @@ { \acro_if_first:eTF { \AcronymID } {} {#1} } \NewDocumentCommand \acroiftagTF {m+m+m} - { \acro_if_tag:enTF { \AcronymID } {#1} {#2} {#3} } + { \acro_tag_if:enTF { \AcronymID } {#1} {#2} {#3} } \NewDocumentCommand \acroiftagT {m+m} - { \acro_if_tag:enT { \AcronymID } {#1} {#2} } + { \acro_tag_if:enT { \AcronymID } {#1} {#2} } \NewDocumentCommand \acroiftagF {m+m} - { \acro_if_tag:enF { \AcronymID } {#1} {#2} } + { \acro_tag_if:enF { \AcronymID } {#1} {#2} } \NewDocumentCommand \acropages {mm} { \acro_print_pages:enn { \AcronymID } {#1} {#2} } @@ -929,6 +972,8 @@ \NewDocumentCommand \acropagefill {} { \acro_if_pages:eT { \AcronymID } { \tl_use:N \l__acro_pages_fill_tl } } +\NewDocumentCommand \acrodotfill {} { \acro_dot_fill: } + \NewExpandableDocumentCommand \acroifpagesTF {} { \acro_if_pages:eTF { \AcronymID } } @@ -962,7 +1007,7 @@ \tl_const:Nx \c_acro_auxfile_tl { \c_sys_jobname_str .acr } \iow_new:N \l__acro_aux_file_iow -\tl_new:N \g__acro_mdfive_hash_tl +\tl_new:N \l__acro_mdfive_hash_tl \acro_at_begin_document:n { @@ -973,7 +1018,7 @@ } \file_get_mdfive_hash:VN \c_acro_auxfile_tl - \g__acro_mdfive_hash_tl + \l__acro_mdfive_hash_tl \iow_open:NV \l__acro_aux_file_iow \c_acro_auxfile_tl } @@ -983,7 +1028,7 @@ \file_get_mdfive_hash:VN \c_acro_auxfile_tl \l__acro_tmpa_tl - \tl_if_eq:NNF \g__acro_mdfive_hash_tl \l__acro_tmpa_tl + \tl_if_eq:NNF \l__acro_mdfive_hash_tl \l__acro_tmpa_tl { \acro_rerun:n {general} } \legacy_if:nT {@filesw} { \iow_now:Nx \@auxout { \token_to_str:N \ACRO {readaux} } } @@ -1092,8 +1137,8 @@ % #1: name \cs_new_protected:Npn \__acro_auxlist_update:n #1 { - \seq_remove_duplicates:c {g__acro_auxlist_#1_seq} - \seq_remove_duplicates:c {g__acro_auxlist_recorded_#1_seq} + \seq_gremove_duplicates:c {g__acro_auxlist_#1_seq} + \seq_gremove_duplicates:c {g__acro_auxlist_recorded_#1_seq} \str_set:Nx \l__acro_tmpa_str { \seq_use:cn {g__acro_auxlist_#1_seq} {} } \str_set:Nx \l__acro_tmpb_str @@ -1167,6 +1212,17 @@ needs~ a~ (possibly~ empty)~ value! } +\msg_new:nnn {acro} {preset-defined} + { + The~ acronym~ preset~ `#1'~ is~ already~ defined~ \msg_line_context: . \\ + Try~ \RenewAcroPreset ~ or~ \DeclareAcroPreset ~ instead. + } + +\msg_new:nnn {acro} {preset-not-defined} + { + The~ acronym~ preset~ `#1'~ is~ not~ defined~ \msg_line_context: , yet. \\ + Try~ \NewAcroPreset ~ or~ \DeclareAcroPreset ~ instead. + } % ---------------------------------------------------------------------------- % declare properties: @@ -1549,7 +1605,68 @@ \__acro_parse_property:nn {#2} } -\cs_generate_variant:Nn \acro_properties_set:nnn {nnx,nxx,nV,nVx} +\cs_generate_variant:Nn \acro_properties_set:nn {nV} + +% -------------------------------------------------------------------------- +% define a set of properties that can be assigned to acronyms +% #1: preset name +\prg_new_conditional:Npnn \acro_preset_if_defined:n #1 {p,T,F,TF} + { + \tl_if_exist:cTF {l__acro_preset_#1_tl} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: preset name +\cs_new_protected:Npn \acro_preset_define:n #1 + { \tl_new:c {l__acro_preset_#1_tl} } + +% #1: preset name +% #2: properties +\cs_new_protected:Npn \acro_preset_set:nn #1#2 + { \tl_set:cn {l__acro_preset_#1_tl} {#2} } + +% #1: preset name +% #2: properties +\cs_new_protected:Npn \acro_preset_declare:nn #1#2 + { + \acro_preset_if_defined:nF {#1} + { \acro_preset_define:n {#1} } + \acro_preset_set:nn {#1} {#2} + } + +% #1: preset name +% #2: properties +\cs_new_protected:Npn \acro_preset_new:nn #1#2 + { + \acro_preset_if_defined:nTF {#1} + { \msg_error:nnn {acro} {preset-defined} {#1} } + { + \acro_preset_define:n {#1} + \acro_preset_set:nn {#1} {#2} + } + } + +% #1: preset name +% #2: properties +\cs_new_protected:Npn \acro_preset_renew:nn #1#2 + { + \acro_preset_if_defined:nTF {#1} + { \acro_preset_set:nn {#1} {#2} } + { \msg_error:nnn {acro} {preset-not-defined} {#1} } + } + +% #1: ID +\cs_new_protected:Npn \acro_preset_set_properties:n #1 + { + \acro_property_if_set:nnT {#1} {preset} + { + \tl_set_eq:Nc + \l__acro_tmpa_tl + {l__acro_preset_ \acro_property_get:nn {#1} {preset} _tl} + \acro_properties_set:nV {#1} \l__acro_tmpa_tl + } + } % ---------------------------------------------------------------------------- % inspect properties: @@ -1703,6 +1820,9 @@ \DeclareAcroProperty {alt} \DeclareAcroProperty !{long} +\DeclareAcroProperty{uselist} +\DeclareAcroProperty{preset} + % sorting, indexing, ... : \DeclareAcroPropertyAlias {sort} {short} \DeclareAcroProperty {index} @@ -1771,7 +1891,7 @@ % -------------------------------------------------------------------------- % declaration of acronyms: -\seq_new:N \g__acro_acronyms_seq +\seq_new:N \g_acro_acronyms_seq \tl_new:N \l__acro_first_style_tl @@ -1801,7 +1921,7 @@ {g__acro_#1_barriers_intarray} { \g_acro_barrier_total_int } } - \seq_gput_right:Nn \g__acro_acronyms_seq {#1} + \seq_gput_right:Nn \g_acro_acronyms_seq {#1} \acro_attribute_set:nnn {acronyms} {#1} {} % set defaults: \__acro_set_article_defaults:n {#1} @@ -1814,6 +1934,7 @@ { !\acro_property_if_set_p:nn {#1} {short} } { \acro_property_set:nnn {#1} {short} {#1} } \acro_property_set:nnn {#1} {id} {#1} + \acro_preset_set_properties:n {#1} \acro_property_set_aliases:n {#1} % check mandatory properties: \acro_property_foreach_mandatory:n @@ -1838,10 +1959,31 @@ { \prg_return_false: } } +\prg_new_protected_conditional:Npnn \__acro_uselist_if_used:n #1 {T,F,TF} + { + \acro_property_if_set:nnTF {#1} {uselist} + { + \clist_set:Nx \l__acro_tmpa_clist + { \acro_property_get:nn {#1} {uselist} } + \clist_clear:N \l__acro_tmpb_clist + \clist_map_inline:Nn \l__acro_tmpa_clist + { + \acro_boolean_property_if:nnT {##1} {used} + { \clist_put_right:Nn \l__acro_tmpb_clist {##1} } + } + \tl_if_eq:VVTF \l__acro_tmpa_clist \l__acro_tmpb_clist + { \prg_return_true: } + { \prg_return_false: } + } + { \prg_return_false: } + } + \cs_new_protected:Npn \acro_check_definition:n #1 { \acro_if_defined:nF {#1} { \msg_error:nnn {acro} {undefined} {#1} } + \acro_boolean_property_if:nnF {#1} {used} + { \__acro_uselist_if_used:nT {#1} { \acro_use:n {#1} } } } % -------------------------------------------------------------------------- @@ -1849,6 +1991,12 @@ \bool_new:N \l__acro_use_bool \bool_set_true:N \l__acro_use_bool +\cs_new_protected:Npn \acro_map_acronyms:n #1 + { \seq_map_inline:Nn \g_acro_acronyms_seq {#1} } + +\cs_new:Npn \acro_map_break: { \seq_map_break: } +\cs_new:Npn \acro_map_break:n { \seq_map_break:n } + \cs_new_protected:Npn \acro_use_false: { \bool_set_false:N \l__acro_use_bool } @@ -1867,7 +2015,7 @@ \cs_generate_variant:Nn \acro_use:n {e} \cs_new_protected:Npn \acro_use_all: - { \seq_map_inline:Nn \g__acro_acronyms_seq { \__acro_use:n {##1} } } + { \seq_map_inline:Nn \g_acro_acronyms_seq { \__acro_use:n {##1} } } \cs_new_protected:Npn \__acro_reset:n #1 { @@ -1882,7 +2030,7 @@ { \clist_map_inline:nn {#1} { \__acro_reset:n {##1} } } \cs_new_protected:Npn \acro_reset_all: - { \seq_map_inline:Nn \g__acro_acronyms_seq { \__acro_reset:n {##1} } } + { \seq_map_inline:Nn \g_acro_acronyms_seq { \__acro_reset:n {##1} } } \cs_new_protected:Npn \acro_switch_off: { \bool_set_false:N \l__acro_use_bool } @@ -2196,6 +2344,16 @@ \__acro_set_endings:nn {#1} {long} } +% #1: ending +\cs_new_protected:Npn \acro_unset_ending:n #1 + { \bool_set_false:c {l__acro_ending_#1_bool} } + +\cs_new_protected:Npn \acro_reset_endings: + { + \tl_map_tokens:Nn \l__acro_endings_tl { \acro_unset_ending:n } + \bool_set_false:N \l__acro_ending_bool + } + % ---------------------------------------------------------------------------- \AcroModuleEnd \AcroModule{tools}{tools for treating different aspects} @@ -2460,6 +2618,7 @@ % -------------------------------------------------------------------------- % indexing \bool_new:N \l__acro_index_bool +\bool_new:N \l__acro_index_prop_bool \tl_new:N \l_acro_index_disable_tl \cs_new_protected:Npn \__acro_index:n {} @@ -2468,9 +2627,16 @@ % #1: id \cs_new_protected:Npn \acro_index:n #1 { - \bool_lazy_and:nnT - { \l__acro_index_bool } - { !\acro_boolean_property_if_p:nn {#1} {no-index} } + \bool_lazy_all:nT + { + { \l__acro_index_bool } + { !\acro_boolean_property_if_p:nn {#1} {no-index} } + { + \bool_if:NTF \l__acro_index_prop_bool + { \acro_property_if_set_p:nn {#1} {index} } + { !\acro_property_if_set_p:nn {#1} {index} } + } + } { \group_begin: \acro_trailing_map:n @@ -2500,15 +2666,26 @@ \keys_define:nn {acro/index} { - use .bool_set:N = \l__acro_index_bool , - use .initial:n = false , - cmd .cs_set:Np = \__acro_index:n , - cmd .initial:n = \index , - cmd .value_required:n = true , - disable .code:n = \tl_put_right:Nn \l_acro_index_disable_tl {#1} , - disable .value_required:n = true , - clear .code:n = \tl_clear:N \l_acro_index_disable_tl , - clear .value_forbidden:n = true + use .choice: , + use / true .code:n = + \bool_set_true:N \l__acro_index_bool + \bool_set_false:N \l__acro_index_prop_bool , + use / false .code:n = + \bool_set_false:N \l__acro_index_bool + \bool_set_false:N \l__acro_index_prop_bool , + use / indexed .code:n = + \bool_set_true:N \l__acro_index_bool + \bool_set_true:N \l__acro_index_prop_bool , + use .initial:n = false , + use .default:n = true , + use .initial:n = false , + cmd .cs_set:Np = \__acro_index:n , + cmd .initial:n = \index , + cmd .value_required:n = true , + disable .code:n = \tl_put_right:Nn \l_acro_index_disable_tl {#1} , + disable .value_required:n = true , + clear .code:n = \tl_clear:N \l_acro_index_disable_tl , + clear .value_forbidden:n = true } \keys_set:nn {acro/index} { disable = \def\@{} } @@ -2601,13 +2778,10 @@ } \int_new:N \l__acro_nest_int -\bool_new:N \g__acro_nested_bool \prg_new_conditional:Npnn \acro_if_nested: {p,T,F,TF} { - \bool_lazy_and:nnTF - { \int_compare_p:n { \l__acro_nest_int = 1 } } - { \g__acro_nested_bool } + \int_compare:nNnTF \l__acro_nest_int > 1 { \prg_return_true: } { \prg_return_false: } } @@ -2615,9 +2789,8 @@ \cs_new_protected:Npn \acro_begin: { \group_begin: - \int_compare:nNnT \l__acro_nest_int > 0 - { \bool_gset_true:N \g__acro_nested_bool } \int_incr:N \l__acro_nest_int + \acro_reset_endings: \__acro_check_after_end:w } @@ -2636,7 +2809,6 @@ \cs_new_protected:Npn \acro_end: { - \acro_if_nested:T { \bool_gset_false:N \g__acro_nested_bool } \bool_if:NT \g__acro_gobble_trail_bool { \bool_gset_false:N \g__acro_gobble_trail_bool @@ -2714,8 +2886,8 @@ \int_compare:nNnTF { \__acro_strcmp:nn - { \str_fold_case:e { \acro_property_get:nn {##1} {sort} } } - { \str_fold_case:e { \acro_property_get:nn {##2} {sort} } } + { \str_foldcase:e { \acro_property_get:nn {##1} {sort} } } + { \str_foldcase:e { \acro_property_get:nn {##2} {sort} } } } = {-1} { \sort_return_same: } { \sort_return_swapped: } @@ -2850,8 +3022,8 @@ \keys_define:nn {acro} { - case-sensitive .bool_set:N = \g__acro_case_sensitive_bool , - case-sensitive .initial:n = true , + case-sensitive .bool_gset:N = \g__acro_case_sensitive_bool , + case-sensitive .initial:n = true , } % ---------------------------------------------------------------------------- @@ -3028,9 +3200,7 @@ \acro_locale:nnn {#1} {#2} { \__acro_write:nn {#1} {#2} - \bool_lazy_and:nnT - { !\acro_if_nested_p: } - { \l__acro_include_endings_bool } + \bool_if:NT \l__acro_include_endings_bool { \acro_if_ending_form:nnF {#1} {#2} { \__acro_ending:nn {#1} {#2} } @@ -3038,9 +3208,7 @@ } } \group_end: - \bool_lazy_or:nnF - { \acro_if_nested_p: } - { \l__acro_include_endings_bool } + \bool_if:NF \l__acro_include_endings_bool { \acro_if_ending_form:nnF {#1} {#2} { \__acro_ending:nn {#1} {#2} } @@ -3092,7 +3260,6 @@ { \acro_use:n {#2} \acro_record_page:n {#2} - % \acro_record_barrier:n {#2} \acro_index:n {#2} } } @@ -3108,6 +3275,8 @@ \tl_new:N \l__acro_begin_command_hook_tl \tl_new:N \l__acro_end_command_hook_tl +\tl_new:N \l_acro_id_tl +\tl_new:N \AcronymID % #1: csname % #2: xparse csname @@ -3128,8 +3297,8 @@ \cs_set:Npn \nospace { \exp:w \exp_end_continue_f:w } \acro_check_definition:n {####1} \keys_set:nV {acro} \l__acro_options_tl - \tl_set:Ne \AcronymID { \acro_case_insensitive:n {####1} } \tl_set:Ne \l_acro_id_tl { \acro_case_insensitive:n {####1} } + \tl_set_eq:NN \AcronymID \l_acro_id_tl ##3 \acro_finalize:ne { \l__acro_star_bool } @@ -3511,10 +3680,10 @@ \cs_new_protected:Npn \acro_list_choose_set: { \bool_if:NTF \l__acro_list_display_all_bool - { \seq_gset_eq:NN \g__acro_list_seq \g__acro_acronyms_seq } + { \seq_gset_eq:NN \g__acro_list_seq \g_acro_acronyms_seq } { \seq_gclear:N \g__acro_list_seq - \seq_map_inline:Nn \g__acro_acronyms_seq + \seq_map_inline:Nn \g_acro_acronyms_seq { \acro_if_single:nTF {##1} { @@ -3687,8 +3856,6 @@ \AcroModule{pages}{recording and printing of pages} % ---------------------------------------------------------------------------- % record page numbers: -\RequirePackage {zref-abspage} - \msg_new:nnn {acro} {no-page-range} { The~ list~ template~ `#1'~ cannot~ display~ a~ page~ range. @@ -3704,10 +3871,18 @@ \cs_new_protected:Npn \acro_record_page:n #1 { \seq_if_in:ceF {g__acro_#1_pages_seq} - { \arabic{abspage} @ \int_use:N \g_acro_barrier_int @ \thepage } + { + \int_use:N \g_shipout_totalpages_int + @ \int_use:N \g_acro_barrier_int + @ \thepage + } { \seq_gput_right:ce {g__acro_#1_pages_seq} - { \arabic{abspage} @ \int_use:N \g_acro_barrier_int @ \thepage } + { + \int_use:N \g_shipout_totalpages_int + @ \int_use:N \g_acro_barrier_int + @ \thepage + } } \seq_gremove_duplicates:c {g__acro_#1_pages_seq} \acro_at_end_document:n @@ -3730,10 +3905,8 @@ \group_end: -\RequirePackage {zref-totpages} - \acro_at_begin_document:n - { \intarray_new:Nn \g__acro_pages_intarray { \ztotpages } } + { \intarray_new:Nn \g__acro_pages_intarray { \PreviousTotalPages } } % #1: id % #2: one page @@ -3761,8 +3934,13 @@ { \seq_set_split:Nnx \l__acro_tmpa_seq {|} { \acro_property_get:nn {#1} {pages} } - \exp_last_unbraced:Ne - \__acro_page_name:w { \seq_item:Nn \l__acro_tmpa_seq {1} } \q_stop + \use:e + { + \exp_last_unbraced:Ne + \__acro_page_name:w + { \seq_item:Nn \l__acro_tmpa_seq {1} } + \q_stop + } } % #1: id @@ -3946,6 +4124,25 @@ \int_new:N \l__acro_pages_seq_threshold_int +% ---------------------------------------------------------------------------- +\cs_new_protected:Npn \acro_dot_fill: + { + \leaders \hbox + { + $\m@th + \mkern \@dotsep mu + \hbox {.} + \mkern \@dotsep mu$ + } + \hfill + } + +\hook_gput_code:nnn {begindocument} {xsim} + { + \cs_if_exist:NT \cftdotfill + { \cs_set_protected:Npn \acro_dot_fill: { \cftdotfill { \cftdotsep } } } + } + \keys_define:nn {acro/pages} { display .choice: , @@ -3967,7 +4164,7 @@ { \int_set:Nn \l__acro_pages_seq_threshold_int {#1} } , seq / threshold .initial:n = 3 , fill .tl_set:N = \l__acro_pages_fill_tl , - fill .initial:n = \dotfill , + fill .initial:n = \acro_dot_fill: , sep .tl_set:N = \l__acro_pages_sep_tl , sep .initial:n = {,~} , name .bool_set:N = \l__acro_pages_name_display_bool , @@ -4213,6 +4410,7 @@ % -------------------------------------------------------------------------- % hyper linking \bool_new:N \l__acro_hyperref_use_bool +\bool_new:N \l__acro_link_only_first_bool \cs_new_eq:NN \__acro_hyper_target:nn \use_ii:nn \cs_new_eq:NN \__acro_hyper_link:nn \use_ii:nn @@ -4249,6 +4447,11 @@ { \acro_package_if_loaded_p:n {hyperref} } { \l__acro_hyperref_use_bool } { !\acro_if_single_p:n {#1} } + { + \bool_lazy_or_p:nn + { !\l__acro_link_only_first_bool } + { \l__acro_link_only_first_bool && \acro_if_first_p:n {#1} } + } } { \bool_if:NTF \l__acro_list_bool @@ -4312,13 +4515,16 @@ \keys_define:nn {acro} { - make-links .bool_set:N = \l__acro_hyperref_use_bool , - make-links .initial:n = false + make-links .bool_set:N = \l__acro_hyperref_use_bool , + make-links .initial:n = false , + link-only-first .bool_set:N = \l__acro_link_only_first_bool , + link-only-first .initial:n = false } % -------------------------------------------------------------------------- % accessibility support \bool_new:N \l__acro_accsupp_bool +\bool_new:N \l__acro_use_accsupp_bool \tl_new:N \l__acro_accsupp_options_tl \tl_new:N \l__acro_accsupp_method_tl diff --git a/macros/latex/contrib/asmeconf/README.md b/macros/latex/contrib/asmeconf/README.md index af7db56372..e9385d88d1 100644 --- a/macros/latex/contrib/asmeconf/README.md +++ b/macros/latex/contrib/asmeconf/README.md @@ -1,11 +1,11 @@ #asmeconf: A template for ASME conference papers# - Version 1.21 dated 2020/12/10. + Version 1.22 dated 2021/01/14. ####Overview#### This class provides a template to format ASME Conference papers according to - the requirements on ASME's web pages (as posted in 2020). + the requirements on ASME's web pages (as posted in 2021). [www.asme.org/publications-submissions/proceedings/formatting-the-paper](https://www.asme.org/publications-submissions/proceedings/formatting-the-paper) @@ -21,12 +21,6 @@ - set author names and addresses in either the traditional grid or the more recent inline style -- enable various math and text features with newtxmath and newtxtext packages - -- support bold face, sans serif math in section headings - -- support footnotes in section headings - - provide line numbers for editing and review - support balancing of columns on last page @@ -35,6 +29,16 @@ - support copyright footer for federal employees and contractors +- enable various math and text features with newtxmath and newtxtext packages + +- support bold face, sans serif math in section headings + +- support footnotes in section headings + +- enable passages in other languages, e.g., for a translation of the abstract or a quotation + +- support for many scripts: Latin, Arabic, Bengali, Chinese, Cyrillic, Devanagari, Greek, Hangul, Japanese, Tamil + The .tex and .cls files are commented and should be self-explanatory. The files in this distribution are: @@ -48,9 +52,13 @@ * sample-figure-1.pdf, sample-figure-2a.pdf, - sample-figure-2b.pdf -- figures for the example + sample-figure-2b.pdf -- figures for the sample paper * - author-grid-style.pdf -- example of title page with "authorgrid" option + examples/ -- a directory of examples: + -- nonlinear ode integration within LaTeX using Lua code + -- fontspec for abstracts in 25 languages in one paper + -- grid-style layout of author names/addresses + -- footers for government employees This work is not a publication of ASME itself. @@ -69,6 +77,19 @@ ####Change log#### + v1.22 (2021/01/14): + - New command \\EntryHeading to produce subheadings in the nomenclature list; + - New syntax for \\CorrespondingAuthor command with the authorgrid option (**not backward compatible**) + - Add version field to the .bst file for publications online, manuals, and books; + - Revise sample .bib file; + - Enable language-specific fonts under pdflatex for Greek, Vietnamese, and cyrillic languages, with examples of abstracts in these languages; + - Enable fontspec support for many scripts and languages under LuaLaTeX, including also Arabic, Bengali, Chinese, Japanese, Korean, and Tamil; + - Provide example files for: authorgrid layout; integration of nonlinear ODE by LuaLaTeX; abstracts in 25 languages with fontspec+LuaLaTeX; + - Extensively revise code that handles class options and keys, also add additional warning and error messages; + - Create github issue tracker; + - Fix several minor bugs; + - Edit documentation. + v1.21 (2020/12/10): Edit documentation; update some usage of xparse under the hood; confirm compliance with substitutefont package. v1.20 (2020/11/08): Add options to change copyright notice for federal employees and contractors; rename option "oldauthors" as "authorgrid"; other minor edits. Thanks to Bret Van Poppel for suggesting the federal copyright. @@ -106,7 +127,7 @@ ####License#### - Copyright (c) 2020 John H. Lienhard + Copyright (c) 2021 John H. Lienhard 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, diff --git a/macros/latex/contrib/asmeconf/asmeconf-sample.bib b/macros/latex/contrib/asmeconf/asmeconf-sample.bib index 7fa393f413..0085c89e57 100644 --- a/macros/latex/contrib/asmeconf/asmeconf-sample.bib +++ b/macros/latex/contrib/asmeconf/asmeconf-sample.bib @@ -1,6 +1,6 @@ %% Sample bibliography file for asmeconf.bst and asmeconf.cls %% -%% Revised 10 December 2020 +%% Revised 14 January 2021 %% Copyright John H. Lienhard, MIT %% Offered under the MIT license: https://ctan.org/license/mit @@ -28,7 +28,8 @@ address = {New York}, } %% book supports these fields: author OR editor, year, title, edition, series, volume OR number -%% publisher, address, doi, url, eprint with archive, note. +%% publisher, address, doi, url, eprint with archive, version, versiontype, note. +%% You can change "Version" with "versiontype, e.g., versiontype = {Release}, @INCOLLECTION{stevens1999, author = {Thomas T. Stevens}, @@ -163,17 +164,29 @@ %% May include numpages = {} to get "eid (numpages pages)" %% Note use of jht macro for title title (produces "ASME J. Heat Transfer"). All ASME journals have macros. -@online{milde, - author = {G\"{u}nter Milde}, - title = {{\texttt{substitutefont}}---Easy font substitution, Version 0.1.4}, +@online{bezos2020, + author = {Johannes L. Braams and Javier Bezos}, + title = {{\texttt{babel}}: Localization and internationalization}, organization = {Comprehensive \TeX\ Archive Network}, - year = {2013}, - url = {https://www.ctan.org/pkg/substitutefont}, - urldate = {December 9, 2020}, + version = {3.52}, + year = {2020}, + url = {https://ctan.org/pkg/babel}, + urldate = {January 3, 2021}, } -%% online supports these fields: author OR editor, year, title, organization, address, +%% online supports these fields: author OR editor, year, title, version, versiontype, organization, address, %% note, url OR eprint with archive, urldate, urltype %% You can change "Accessed" with "urltype", e.g., urltype = {retrieved}, +%% You can change "Version" with "versiontype, e.g., versiontype = {Release}, + +@online{lienhard2021, + author = {Lienhard, V, John H.}, + title = {Language Support in {\texttt{asmeconf}}: non-latin alphabets, {\LuaLaTeX}, and {\texttt{fontspec}}}, + version = {1.0}, + organization = {Comprehensive \TeX\ Archive Network}, + year = {2021}, + url = {https://www.ctan.org/pkg/asmeconf}, + urldate = {Pre-publication}, +} @book{fourier1822, author = {Jean Baptiste Joseph Fourier}, @@ -234,7 +247,7 @@ %% eprint + arxiv produces the same result as: url = {https://arxiv.org/abs/1509.06344v3}, @manual{GSL, - title = {{GNU} Scientific Library Release 2.4}, + title = {{GNU} Scientific Library}, author = {Mark Galassi and Jim Davies and James Theiler @@ -244,18 +257,23 @@ and Michael Booth and Fabrice Rossi and Rhys Ulerich}, + version = {2.4}, + versiontype = {Release}, organization = {Free Software Foundation}, address = {Boston, MA}, year = 2017, url = {https://www.gnu.org/software/gsl/}, } %% manual supports these fields: author, year, title, edition, organization, address, -%% doi, eprint with archive, urldate, url, note. +%% doi, eprint with archive, urldate, url, version, versiontype, note. +%% You can change "Accessed" with "urltype", e.g., urltype = {retrieved}, +%% You can change "Version" with "versiontype, e.g., versiontype = {Release}, @online{amsmath, author = {{American Mathematical Society} and {LATEX3 Project}}, - title = {User's Guide for the \textsf{amsmath} Package, Version 2.1}, + title = {User's Guide for the \textsf{amsmath} Package}, + version = {2.1}, organization = {Comprehensive \TeX\ Archive Network}, year = {2018}, url = {https://ctan.org/tex-archive/macros/latex/required/amsmath/amsldoc.pdf}, @@ -264,16 +282,18 @@ @online{sharpe1, author = {Michael Sharpe}, - title = {New {TX} Font Package, Version 1.554}, + title = {New {TX} Font Package}, + version = {1.640}, organization = {Comprehensive \TeX\ Archive Network}, - year = {2018}, + year = {2020}, url = {https://ctan.org/pkg/newtx}, - urldate = {April 27, 2019}, + urldate = {January 4, 2021}, } @online{sharpe2, author = {Michael Sharpe}, - title = {The \textsf{mathalfa} Package, Version 1.10}, + title = {The \textsf{mathalfa} Package}, + version = {1.10}, organization = {Comprehensive \TeX\ Archive Network}, year = {2018}, url = {https://ctan.org/pkg/mathalfa}, @@ -282,7 +302,8 @@ @online{tolusis, author = {Sigitas Tolu{\v{s}}is}, - title = {The \textsf{flushend} Package, Version 3.3}, + title = {The \textsf{flushend} Package}, + version = {3.3}, organization = {Comprehensive \TeX\ Archive Network}, year = {2017}, url = {https://www.ctan.org/pkg/flushend}, @@ -291,7 +312,8 @@ @online{bottcher, author = {Stephan I. B{\"o}ttcher and Uwe L{\"u}ck}, - title = {\textsf{lineno.sty}: A {\LaTeX} Package to Attach Line Numbers to Paragraphs, Version 4.41}, + title = {\textsf{lineno.sty}: A {\LaTeX} Package to Attach Line Numbers to Paragraphs}, + version = {4.41}, organization = {Comprehensive \TeX\ Archive Network}, year = {2005}, url = {https://www.ctan.org/pkg/lineno}, @@ -300,7 +322,8 @@ @online{oostrum, author = {Piet van Oostrum}, - title = {The \textsf{fancyhdr} and \textsf{extramarks} Packages, Version 3.10}, + title = {The \textsf{fancyhdr} and \textsf{extramarks} Packages}, + version = {3.10}, organization = {Comprehensive \TeX\ Archive Network}, year = {2019}, url = {https://www.ctan.org/pkg/fancyhdr}, @@ -309,13 +332,14 @@ @online{fairbairns, author = {Robin Fairbairns and Sebastian Rahtz and Leonor Barroca}, - title = {A Package for Rotated Objects in \LaTeX, Version 2.16d}, + title = {A Package for Rotated Objects in \LaTeX}, + version = {2.16d}, organization = {Comprehensive \TeX\ Archive Network}, year = {2016}, url = {https://www.ctan.org/pkg/rotating}, urldate = {October 2, 2019}, } - + @online{mpl, title = {mpl colormaps}, author = {St{\'e}fan {van der Walt} and Nathaniel Smith}, @@ -339,11 +363,12 @@ address = {Boston}, note = {{``The Locust Years''}}, } -%% inbook supports these fields: author OR editor, year, title, edition, version, series, +%% inbook supports these fields: author OR editor, year, title, edition, series, %% volume OR number, doi, url, eprint with archive, publisher, -%% address, note. +%% address, version, versiontype, note. %% %% type={} field changes "Chap." to something else. +%% You can change "Version" with "versiontype, e.g., versiontype = {Release}, @BOOK{book, @@ -359,3 +384,12 @@ note = {to appear}, } +% not currently citing this one + author = {G\"{u}nter Milde}, + title = {{\texttt{substitutefont}}---Easy font substitution}, + version = {0.1.4}, + organization = {Comprehensive \TeX\ Archive Network}, + year = {2013}, + url = {https://www.ctan.org/pkg/substitutefont}, + urldate = {December 9, 2020}, + diff --git a/macros/latex/contrib/asmeconf/asmeconf-template.pdf b/macros/latex/contrib/asmeconf/asmeconf-template.pdf index 3e1a594226..883948a8b9 100644 Binary files a/macros/latex/contrib/asmeconf/asmeconf-template.pdf and b/macros/latex/contrib/asmeconf/asmeconf-template.pdf differ diff --git a/macros/latex/contrib/asmeconf/asmeconf-template.tex b/macros/latex/contrib/asmeconf/asmeconf-template.tex index f9860ccbc8..638a8e11f0 100644 --- a/macros/latex/contrib/asmeconf/asmeconf-template.tex +++ b/macros/latex/contrib/asmeconf/asmeconf-template.tex @@ -1,44 +1,43 @@ % !TEX encoding = UTF-8 Unicode -%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% %% This file is asmeconf-template.tex, a template to format ASME Conference papers according to -%% the requirements on ASME's conference web pages. +%% the requirements on ASME's conference web pages, and including hypertext support for the pdf. %% -%% This file is version 1.21 dated 2020/12/10 +%% This file is version 1.22 dated 2021/1/14 %% %% As of version 1.11, this template follows ASME's newer conference guidelines first posted July 2019. %% The new guidelines have changed the requested author block formatting to be inline. %% (This template continues to support the traditional grid format as a package option.) -%% Nomenclature now follows the abstract. Abstract is in italics. +%% Nomenclature now follows the abstract. Abstract text is set in italics. %% %% Author: John H. Lienhard V %% Department of Mechanical Engineering %% Massachusetts Institute of Technology %% Cambridge, MA 02139-4307 USA %% -%% Class options are set up in the asmeconf.cls file. These include: +%% Class options include: %% -%% * Math options from M. Sharpe's newtxmath package: upright integrals [upint]; and +%% * Math options from M. Sharpe's newtxmath package: upright integrals [upint]; %% * [varvw] for a v and w that are better distinguished from greek nu; and also -%% * [smallerops, varg, slantedGreek, frenchmath, varbb, cmbraces]. -%% * newtx version 1.5 or higher is recommended. +%% * [subscriptcorrection, smallerops, varg, frenchmath, varbb, cmbraces, slantedGreek,...] +%% * See newtx documentation for descriptions (at CTAN: http://ctan.org, v1.6 or higher best). %% %% * Many options for calligraphic, script, and fraktur fonts from the mathalfa package; the -%% * example value used is: [mathalfa=cal=euler] (to use Euler font for \mathcal) -%% * some other options for cal are: dutchcal, zapfc, cm (default), boondox,... -%% * frak (fraktur), bb (blackboard bold), scr (script) may also be controlled. +%% * example shown here is: [mathalfa=cal=euler] to use Euler font for \mathcal. +%% * Some other options for cal are: dutchcal, zapfc, cm (default), boondox,... +%% * frak (fraktur), bb (blackboard bold), scr (script) may also be chosen this way. +%% * For details, refer to mathalfa documentation (at CTAN: http://ctan.org). %% %% * Options to: omit the ASME copyright footer [nofoot]; %% use government employee copyright notice [govt]; %% use government contractor copyright notice [contractor] %% -%% * An optional to use newtxtext's superiors font for footnotes [nodefaultsups] and an option -%% * for slightly larger small capitals [largesc] -%% %% * An option to balance the heights of columns on the last page [balance]. %% * This option is NOT compatible with the [lineno] option. %% -%% * An option to include line numbers [lineno]. The lineno package does not number equation -%% * lines, captions, tables, etc. You must *run twice* for proper placement of the line numbers. +%% * An option to include line numbers [lineno]. You must *run twice* for proper placement of the line numbers. +%% * The lineno package does not number titles, footnotes, captions, or tables. %% * This option will disable balancing column height on final page if that option has been invoked. %% * The lineno package won't always number the lines preceding displayed math in a paragraph because %% * paragraph has not ended. See that package's documentation for macros to address this problem, or @@ -48,40 +47,42 @@ %% * An option to use the traditional grid arrangement of author names [authorgrid]. See Appendix B for usage, %% * because the authors and affiliations must be entered differently in this case. (Same as former option [oldauthors]) %% -%% * An option to allow hyphenation of the typewriter font [hyphenate] -%% * Hyphenation is normally suppressed for typewriter mode because it is often used for code. +%% * Options for PDF/A compliance. [pdf-a] will produce PDF/A-3u compliance with sRGB OutputIntent. +%% * [pdfapart= 1 or 2 or 3] and [pdfaconformance= b or u] can enable levels 1b, 2b, 2u, and 3b. %% -%% * Options to set (for the babel package) a primary language [lang= ], and secondary or tertiary -%% * languages, [lang-second] and [lang-third]. English is the default when no language is set. -%% * If a secondary or tertiary language is set, the main language must also be set. -%% * The spanish module makes "." active, clashing with some code; \spanishdeactivate{.} stops this. +%% * Option to use superiors font from newtxtext for footnotes [nodefaultsups] and +%% * for slightly larger small capitals, [largesc], also from newtxtext. %% -%% * Options for PDF/A compliance. [pdf-a] will produce PDF/A-3u compliance with sRGB OutputIntent. -%% * [pdfapart= 1 or 2 or 3] and [pdfaconformance= b or u] allow other levels: 1b, 2b, 2u, and 3b. +%% * An option to allow hyphenation of the typewriter font [hyphenate], from inconsolata package. +%% * Hyphenation is normally suppressed for typewriter mode because it is often used for code. +%% * To replace the default variable word spacing by monospacing, use the option [mono]. +%% * To get a zero without a slash, use [var0] %% -%% For details of newtxmath and mathalfa, refer to their documentation (available on CTAN: http://ctan.org). +%% * Options (used by the babel package) to include passages in languages other than English (e.g., a translation +%% * of the abstract). Languages are called as options, e.g. [french], [spanish], [greek], [russian], etc. +%% * See Appendix C for details. %% -%% The use of commands defined or modified by the asmeconf class is illustrated below. In particular, -%% ASME requires capitalized, sans-serif section headings, and as a result some care is needed -%% when using macros in section headings, as also illustrated below. +%% The use of commands defined or modified by the asmeconf class is illustrated throughout this file. In particular, +%% ASME requires capitalized, sans-serif section headings, and as a result some care is needed when using macros +%% in section headings, as also illustrated below. %% %========================================================= %% -%% LICENSE: +%% LICENSE: %% -%% Copyright (c) 2020 John Lienhard +%% Copyright (c) 2021 John H. Lienhard %% %% Offered under the MIT license: https://ctan.org/license/mit %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Class options are described above. +%% Class options are described above. If you are not using the languages options, remove them. -\documentclass[varvw,largesc,upint,mathalfa=cal=euler,hyphenate,balance,lang-second=french,lang=english,colorlinks,pdf-a]{asmeconf} % <=== remove colorlinks before submission to ASME! +\documentclass[upint,subscriptcorrection,varvw,mathalfa=cal=euler,pdf-a,balance,spanish,french,greek,russian,vietnamese,colorlinks]{asmeconf} % <=== remove colorlinks before your *final* submission to ASME! But keep it for other purposes. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%% Fields to be completed %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%% Fields to be completed %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%% pdf metadata %%%%%%%%%%%% %%%%% The user should edit %%%%%%%%%%%% @@ -89,27 +90,26 @@ \hypersetup{% pdftitle={ASME Conference Paper Template}, % <=== change to YOUR pdf file title pdfkeywords={ASME, Paper, Template, \LaTeX, Research}, % <=== change to YOUR pdf keywords - pdfauthor={John H. Lienhard}, % <=== change to YOUR name[s]!!! + pdfauthor={John H. Lienhard}, % <=== change to YOUR name[s]! } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} - % Change these fields to the right content for your conference. % You can comment these out if for some reason you don't want a header. % Use title case (first letters capitalized), not all capitals -\ConfName{Proceedings of the ASME 2020\linebreak International Mechanical Engineering Congress and Exposition} -\ConfAcronym{IMECE20} -\ConfDate{November 14-19, 2020} -\ConfCity{Portland, OR, USA} -\PaperNo{IMECE2020-XXXX} +\ConfName{Proceedings of the ASME 2021\linebreak International Mechanical Engineering Congress and Exposition} +\ConfAcronym{IMECE21} +\ConfDate{November 1-4, 2021} +\ConfCity{Virtual Conference, Online} +\PaperNo{IMECE2021-XXXX} % Units of measure and other specialty lowercase terms in the title should be % enclosed in \NoCaseChange{...} to maintain lower case type -% LaTeX will automatically set the title in all capital letters. +% LaTeX will automatically set the rest of the title in all capital letters. \title{Place Title Here: Place Subtitle After Colon} % <=== change to YOUR title @@ -122,24 +122,30 @@ % % \JointFirstAuthor, if applicable, follows the affiliation of the relevant authors, no spaces. -\SetAuthors{Luis Hern\'andez\affil{1}\JointFirstAuthor , Maria Silva\affil{2}\JointFirstAuthor, Henry Tudor\affil{3}, Catherine~Parr\affil{3}, John H.\ Lienhard V\affil{4}\CorrespondingAuthor{lienhard@mit.edu}} +\SetAuthors{Luis Hern\'andez\affil{1}\JointFirstAuthor , Maria Silva\affil{2}\JointFirstAuthor, Henry Tudor\affil{3}, Catherine~Parr\affil{3}\CorrespondingAuthor{}, John H.\ Lienhard V\affil{4}\CorrespondingAuthor{lienhard@mit.edu, kate@thepalace.gov}} \SetAffiliation{1}{Institution or Company Name, City, State} \SetAffiliation{2}{Institution or Company Name, City, Province, Canada} \SetAffiliation{3}{Hampton Court Palace, Richmond, England} \SetAffiliation{4}{Massachusetts Institute of Technology, Cambridge, MA } +% Note: Luis and Maria are not real people. Henry and Catherine have been dead for >450 years. + + +% To instead use the [authorgrid] option, follow the syntax in Appendix B. + \maketitle %%% Use this footnote for tracking various versions of your draft. Change text to suit your own needs. -%%% Remove from final version. +%%% REMOVE from final version of your paper. %%% \date{..} calls the same command. + \versionfootnote{Documentation for \texttt{asmeconf.cls}. Version \versionno; \today.}% <=== Delete before final submission. %%% Change these to your keywords. Keywords are automatically printed at the end of the abstract. -%%% This command must come BEFORE the end of the abstract. -%%% If you don't want keywords, delete the command. +%%% This command MUST COME BEFORE the end of the abstract. +%%% If you don't want keywords, leave the argument of \keywords{} empty (or use the abstract* environment) \keywords{ASME, Paper, Template, \LaTeX, Research} @@ -159,22 +165,23 @@ This paper is an example of and a template for typesetting ASME Conference Paper %% The unit cm can be replaced by any LaTeX unit of dimension: pt, in, ex, em, pc, etc. %% Default is 2em. -%% Leave off second argument of \entry to produce a subheading (e.g., \entry{Greek letters} ) +%% \EntryHeading{Greek letters} produces an italicized subheading, e.g., \EntryHeading{Greek letters} +%% (Leaving off the second argument of \entry, e.g. \entry{Greek letters}, has the same effect) \begin{nomenclature} -\entry{Roman letters} +\EntryHeading{Roman letters} \entry{$k$}{Thermal conductivity [W m$^{-1}$ K$^{-1}$]} \entry{$\vec{q}$}{Heat flux vector [W m$^{-2}$]} -\entry{Greek letters} +\EntryHeading{Greek letters} \entry{$\alpha$}{Thermal diffusivity [m$^2$ s$^{-1}$]} \entry{$\nu$}{Kinematic viscosity [m$^2$ s$^{-1}$]} -\entry{Dimensionless groups} +\EntryHeading{Dimensionless groups} \entry{Pr}{Prandtl number, $\nu/\alpha$} \entry{Sc}{Schmidt number, $\nu/\mathcal{D}_{1,2}$} -\entry{Superscripts and subscripts} +\EntryHeading{Superscripts and subscripts} \entry{b}{bulk value} \entry{$\infty$}{free stream value} \end{nomenclature} @@ -185,7 +192,7 @@ This paper is an example of and a template for typesetting ASME Conference Paper \section{Introduction} The \texttt{asmeconf} class typesets papers with margins, fonts, headings, captions, and reference formats that follow the specifications for conference papers of the American Society of Mechanical Engineers (ASME). In contrast to older ASME \LaTeX\ templates, \texttt{asmeconf} will set internal and external hyperlinks, and the pdf file will contain bookmarks and metadata. Many other useful features have been incorporated. This class is not a publication of ASME, but the author has published in ASME conferences since 1983. -The \texttt{.tex} file may be written using standard \LaTeX\ commands, although some specific initial commands are needed to format the blocks containing the author[s], title, and abstract. This class loads a number of other packages, all of which are contained in up-to-date versions of \href{https://www.tug.org/texlive/}{\TeX\ Live}, \href{http://www.tug.org/mactex/}{Mac\TeX}, and similar platforms. If you find that you are missing one of these packages, you may obtain it at no cost from CTAN (\href{http://ctan.org}{ctan.org}). +The \texttt{.tex} file may be written using standard \LaTeX\ commands, although some specific initial commands are needed to format the blocks containing the author[s], title, and abstract. This class loads a number of other packages, all of which are contained in up-to-date versions of \href{https://www.tug.org/texlive/}{\TeX\ Live}, \href{http://www.tug.org/mactex/}{Mac\TeX}, and similar platforms. If you find that you are missing one of these packages, you may obtain it at no cost from CTAN (\href{http://ctan.org}{ctan.org}). \subsection{Essential Initial Commands} To begin, fill in the fields to be completed at top of the \texttt{asmeconf-template.tex} file. These fields include the headers for your conference and your paper number. Specified metadata will be placed into the pdf file itself. @@ -359,7 +366,7 @@ Elementary support for \texttt{eprint} numbers is also included, generating a ur %%%%%%%%%%%%%%%%% begin two column figure %%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{figure*} -\begin{subfigure}[t]{0.5\textwidth} %subfigure is basically the same as minipage +\begin{subfigure}[t]{0.5\textwidth} % subfigure is basically the same as minipage \vbox{ \vspace*{1.7em} \centering{ @@ -406,7 +413,7 @@ Math italics are used for roman and greek letters by default. If you want an up \begin{equation}\label{eqn:dw} \vec{F} = m \vec{a} \quad\textrm{or}\quad \vec{\mathrm{F}} = m \vec{\mathrm{a}} \quad\textrm{or}\quad \mathbf{F} = m \mathbf{a} \quad\textrm{or}\quad \vec{\mathsf{F}} = m \vec{\mathsf{a}} \end{equation} -To get additional symbols in bold math, you can use the \verb|\bm{..}| macro from the \texttt{bm} package, which is loaded by the class. +To get additional symbols in bold math, you can use \verb|\mathversion{bold}| or the \verb|\bm{..}| macro from the \texttt{bm} package, which is loaded by the class. The class file also provides upright sans-serif greek letters with \verb|\sfalpha| and similar expressions (e.g., $\sfalpha, \sfbeta, \sfgamma, \sfdelta$ \ldots $\bm{\sfalpha, \sfbeta, \sfgamma, \sfdelta \ldots}$), in case they are needed (but note that the \verb|newtxmath| options \verb|frenchmath| and \verb|slantedGreek| also affect how greek letters are presented). @@ -414,7 +421,7 @@ The class file also provides upright sans-serif greek letters with \verb|\sfalph \begin{quote} \verb|\documentclass[upint]{asmeconf}|. \end{quote} -These math options are discussed further in the \texttt{asmejour-template.tex} file. +The option \verb|subscriptcorrection| improves the spacing of math subscripts. These math options are discussed further in the \texttt{asmeconf-template.tex} file. In addition, many options for calligraphic, fraktur, and script fonts are available as options to the \texttt{mathalfa} package, which is also loaded. These may be invoked, for example, as \begin{center} @@ -422,9 +429,7 @@ In addition, many options for calligraphic, fraktur, and script fonts are availa \end{center} which selects the Euler font for \verb|\mathcal| (this is our default). To find all the font options, refer to the \texttt{mathalfa} package documentation \cite{sharpe2}. -The typewriter font loaded is \texttt{inconsolata} (which is sans serif), as suggested by the \texttt{newtx} package documentation. - -The \texttt{asmeconf} class is not set up for use with the \texttt{fontspec} or \texttt{unicode-math} packages. +The \texttt{asmeconf} class is designed to be used with \texttt{newtxmath} and does not support the \texttt{unicode-math} package. %%%%%%%%%%%%%%% ADDITIONAL PACKAGE OPTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -457,8 +462,7 @@ If levels 1b, 2b, 2u, or 3b are preferred, use the options \texttt{[pdfapart=1 o \subsection{Superiors Font} The \texttt{newtxtext} package includes a superiors font (both numbers and letters) for use in footnote markers and superscripts. To enable this font, use the option \texttt{[nodefaultsups]}. -\subsection{Hyphenation of Typewriter Font} The option \texttt{[hyphenate]} will allow hyphenation of the typewriter font. -Hyphenation is normally suppressed for typewriter mode because this font is often used for computer code. +\subsection{Typewriter Font Options} This font is the sans-serif \texttt{inconsolata}. By default, the word spacing is variable, but option \texttt{[mono]} ends this behavior. A slashed zero is default; option \texttt{[var0]} removes the slash. Option \texttt{[hyphenate]} enables hyphenation. (This option is not available if the \texttt{[fontspec]} option is used.) \subsection{Support for Other Languages} The package can be adapted to incorporate (or entirely use) languages other than English. See Appendix \ref{appendix:c} for details. @@ -495,7 +499,7 @@ Place any acknowledgments here. %% Note that appendices will be "numbered" A, B, C, ... etc. Use \section, not \section* %% Equations will be numbered sequentially following those in the paper. Do not reset the equation counter. -%% Here we use the optional argument for the pdf bookmark. +%% Here we use the optional argument to control the pdf bookmark and prevent errors. \section[The Vector Product A\times B]{The vector product $\vec{A}\times\vec{B}$}\label{appendix:a} This brief illustration of an appendix shows the numbering of the appendix and equations. Equations are numbered @@ -521,9 +525,9 @@ the option [\texttt{authorgrid}]. When using this form, the author names and ad \verb|\SetAuthorBlock{Name\JointFirstAuthor}{%| \hbox{}\hfil\verb|Institution \\ City, Country}| \verb|\SetAuthorBlock{Name, Name}{%|\hfil\hbox{} - \noindent\hbox{}\hfil\verb|Institution \\ City, Country}| -\verb|\SetAuthorBlock{\CorrespondingAuthor{John Lienhard%| - \hbox{}\hfil\verb|}{lienhard@mit.edu}}{Institution \\ City, State}| + \hbox{}\hfil\verb|Institution \\ City, Country}| +\verb|\SetAuthorBlock{John Lienhard\CorrespondingAuthor{%| + \hbox{\qquad}\hfil\verb|lienhard@mit.edu}}{Institution \\ City, State}| \smallskip Directly usable code is contained at the very end of the \texttt{asmeconf-template.tex} file. @@ -533,38 +537,90 @@ subsequent row. %% directly usable code follows the \end{document} command below. - +%\end{document} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\section{Language Support}\label{appendix:c} +\section{Multilingual Support}\label{appendix:c} ASME publishes in English, but the \texttt{babel} package is loaded for -users who may wish to include other languages. Class options allow loading a primary language, \texttt{lang=}, -as well as secondary and tertiary languages, \texttt{lang-second} and \texttt{lang-third}. -The primary language must be specified explicitly if a secondary language is loaded. -If no language option is given, the package defaults to English. An example of including a passage in French is -shown in \selectlanguage{french}{\appendixname\ \ref{app:fourier}.\selectlanguage{english} +users who may wish to include other languages. For example, an author might wish to include an appendix that provides the +abstract in another language. -The standard caption and section names will follow \texttt{babel}'s dictionary for primary languages other than English. Users may additionally change ``Keywords'', ``Nomenclature'', ``Corresponding author'', and ``Joint first authors'' by renewing the commands \verb|\keywordname|, \verb|\nomname|, \verb|\CAwords|, and \verb|\JAwords|. Changes to the page footer were described earlier. The pdf bookmark for ``Appendices'' may be changed by renewing \verb|\appendicesname|. +When more than one language option is included in \verb|\documentclass[..]{asmeconf}|, English will be +assumed to be the main language of the document. (To choose a different main language, set \texttt{[main=..]}). +If no language options are given, the package defaults to English. As examples, a passage in French is +shown in \selectlanguage{french}\appendixname~\ref{app:fourier}\selectlanguage{english}, followed by +\ifpdftex abstracts in Spanish, Greek, Russian, and Vietnamese.\else abstracts in other languages.\fi Font encoding is set to T1 with utf-8 input supported: %% If you have trouble with the next line, your file may not be saved in utf-8 format. You can delete that line to resolve the issue. \typeout{If you have trouble with the next line, your file may not be saved in utf-8 format. You can delete that line to resolve the issue.} àáâäæãåā èéęëêēė îïíīįì ôöòóœøōõ ûüùúū çćč ł ñń ßśš ÿ žźż. -The \texttt{substitutefont} package \cite{milde} may be loaded in the preamble to enable the selection of language-specific fonts. Examples for Greek and Cyrillic are included in that package's documentation. The bibliography style, \texttt{asmeconf.bst}, is designed in English and aimed at \hologo{BibTeX}. Multilingual bibliographies can be supported using \texttt{BibLaTeX}. +Fonts similar to Times/Helvetica are automatically used when the Greek, Vietnamese, or selected cyrillic-alphabet languages are called as options under {\upshape\hologo{pdfLaTeX}}. Using {\upshape\hologo{LuaLaTeX}} with the \texttt{[fontspec]} option, many additional scripts are available; see the supplemental notes for such usage~\cite{lienhard2021}. Possibilities include Arabic, Bengali, Chinese, Devanagari (e.g., for Hindi), Hangul (for Korean), Kana (for Japanese), and Tamil. -\selectlanguage{french} -\section{Discours Préliminaire de Fourier}\label{app:fourier} +The bibliography style, \texttt{asmeconf.bst}, is designed in English and aimed at \hologo{BibTeX}. Multilingual bibliographies +can be supported using \texttt{BibLaTeX}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{selectlanguage}{french} +\section{Discours Préliminaire de Fourier}\label{app:fourier} Les causes primordiales ne nous sont point con­nues; mais elles sont assujetties à des lois simples et constantes, que l'on peut découvrir par l'obser­vation, et dont l'étude est l'objet de la philosophie naturelle. La chale ur pénètre, comme la gravité, toutes les substances de l'univers, ses rayons occupent toutes les parties de l'espace. Le but de notre ouvrage est d'exposer les lois mathématiques que suit cet élé­ment. Cette théorie formera désormais une des branches les plus importantes de la physique gé­nérale~\cite{fourier1822}. +\end{selectlanguage} + +\begin{selectlanguage}{spanish} +\begin{abstract*} +Este es el resumen del artículo. Escribimos en español. Se describen el problema, los métodos y los resultados. También se incluyen referencias. +\end{abstract*} +\end{selectlanguage}% edited by Aarón Montoya-Moraga + +%% If you have trouble with the passages, your file may not be saved in utf-8 format. You can delete this stuff to resolve the issue. + +%% Examples of abstracts in other languages. The first three are intended for pdflatex, not lualatex. +\begin{selectlanguage}{greek}% +\begin{abstract*} +Αυτή είναι η περίληψη του άρθρου. Χρησιμοποιούμε την ελληνική γλώσσα. Περιγράφεται το πρόβλημα, οι μέθοδοι και τα αποτελέσματα. Περιλαμβάνονται επίσης αναφορές. +\end{abstract*} +\end{selectlanguage}% Edited by George Barbastathis + +\begin{selectlanguage}{russian} +\begin{abstract*} +Это резюме статьи. Пишем по русски. Описаны проблема, методы и результаты. Библиография также включена.% +\end{abstract*} +\end{selectlanguage}% edited by Steven Gerasimoff + +\begin{selectlanguage}{vietnamese} +\begin{abstract*} +Đây là phần tóm tắt của bài báo khoa học. Chúng tôi viết bằng tiếng Việt. Vấn đề, các phương pháp và các kết quả được mô tả trong phần này. Tài liệu tham khảo cũng được bao gồm. +\end{abstract*} +\end{selectlanguage}% Checked and edited by Nguyen Le and Thao Nguyen + +\iffontspecloaded +% + \begin{selectlanguage}{japanese} + \begin{abstract*} + %論文の要約です。日本語で記述します。問題、方法、および結果について説明します。また、参考文献も含めます。 + この論文の日本語での要約は以下のとおりです。問題、方法、および結果が説明されています。参考資料も添付してあります。 + \end{abstract*} + \end{selectlanguage}% Edited by Keiji Yano and Yoshiki Okamoto +% + \begin{selectlanguage}{korean} + \begin{abstract*} + 이것은 한국어로 쓰인 논문의 초록입니다. 문제, 방법 및 결과가 설명되어 있습니다. 참조도 포함됩니다. + \end{abstract*} + \end{selectlanguage}% Edited by Hyung Won Chung. +% + \begin{selectlanguage}{chinese-simplified} + \begin{abstract*} + 这是文章的摘要。我们用中文书写,描述了问题,方法和结果,还包括了参考文献。 + \end{abstract*} + \end{selectlanguage}% edited by Zi Hao Foo +% +\fi -\selectlanguage{english} - -\textsc{Translation:} \textit{Primary causes are unknown to us; but are subject to simple and constant laws, which may be discovered by observation, the study of them being the object of natural philosophy}. - -\textit{Heat, like gravity, penetrates every substance of the universe, its rays occupy all parts of space. The object of our work is to set forth the mathematical laws which this element obeys. The theory of heat will hereafter form one of the most important branches of general physics}. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \end{document} @@ -575,19 +631,21 @@ La chale ur pénètre, comme la gravité, toutes les substances de l'univers, se % Note usage below for joint first authors and for corresponding author. % First name, middle initial, last name % Use title case (upper and lower case letters) -% (Most of the example names below are not real people, just very common names.) +% (Most of the names below are not real people, just very common names.) \SetAuthorBlock{Luis Hern\'{a}ndez\JointFirstAuthor}{Institution or Company Name \\ City, State} \SetAuthorBlock{Maria Silva\JointFirstAuthor}{Institution or Company Name \\ City, Province, Canada} -\SetAuthorBlock{Henry Tudor, Catherine Parr}{Hampton Court Palace \\ Richmond, England} +\SetAuthorBlock{Henry Tudor, Catherine Parr\CorrespondingAuthor{}}{Hampton Court Palace \\ Richmond, England} \SetAuthorBlock{Jinsoo Kim}{Institution or Company Name \\ City, Country} \SetAuthorBlock{Yusuf Yilmaz}{Institution or Company Name \\ City, Country} -% Can omit second argument of \CorrespondingAuthor if putting email into address block -% i.e., can just use \CorrespondingAuthor{name}. -% Can also put multiple emails in this command and use it more than once for multiple corresponding authors. +% Give an empty argument for \CorrespondingAuthor{} if you are putting email into address block. +% Can also put multiple emails into the argument and use command more than once for multiple +% corresponding authors. Only the *last* set of emails issued will be printed. -\SetAuthorBlock{\CorrespondingAuthor{John H.\ Lienhard V}{lienhard@mit.edu}}{% +\SetAuthorBlock{John H.\ Lienhard V\CorrespondingAuthor{lienhard@mit.edu, kate@thepalace.com}\JointFirstAuthor}{% Massachusetts Institute of Technology \\ Cambridge, MA} +% be sure to issue [authorgrid] option when using this (otherwise your authorblock will not display!) + diff --git a/macros/latex/contrib/asmeconf/asmeconf.bst b/macros/latex/contrib/asmeconf/asmeconf.bst index 2882591d68..1dcbf48a66 100644 --- a/macros/latex/contrib/asmeconf/asmeconf.bst +++ b/macros/latex/contrib/asmeconf/asmeconf.bst @@ -1,10 +1,10 @@ %%%%% -%%%%% *** This .bst produces the reference format for ASME conference papers. *** -%%%%% *** Follows the examples given on ASME's conference web pages in early 2020. *** -%%%%% *** https://www.asme.org/shop/proceedings/conference-publications/references *** -%%%%% *** The examples given by ASME do *not* cover all possibilities *** +%%%%% *** This .bst produces the reference format for ASME conference papers. *** +%%%%% *** Follows the examples given on ASME's conference web pages in early 2021. *** +%%%%% *** https://www.asme.org/publications-submissions/proceedings/author-guidelines/elements-of-a-paper/references *** +%%%%% *** The examples given by ASME do *not* cover all possibilities *** %%%%% -%%%%% This file is version 1.11 dated 2020/04/14 +%%%%% This file is version 1.12 dated 2021/01/04 %%%%% %%%%% Author: John H. Lienhard V %%%%% Department of Mechanical Engineering @@ -26,6 +26,10 @@ %%%%% Added: urlprefix = {}, format.web.urldate, bbl.urldate; urltype field changes "accessed" to something else. %%%%% Added: venue and eventdate to @inproceedings %%%%% +%%%%% Edits in version 1.12, 2021/01/04: +%%%%% Added fields: version={}, format.version, to @book, @inbook, @online, @manual; +%%%%% versiontype = {}, with bbl.version, changes "Version" to other +%%%%% %%%%% Edits in version 1.11, 2020/04/14: %%%%% correct error in journal eid code. %%%%% remove comma between Vol. and No. in article, per ASME style @@ -136,7 +140,9 @@ ENTRY url urldate urltype - venue + venue + version + versiontype volume year } @@ -389,6 +395,8 @@ FUNCTION {bbl.th} FUNCTION {bbl.urldate} { "Accessed" } +FUNCTION {bbl.version} + { "Version" } MACRO {jan} {"Jan."} @@ -617,6 +625,23 @@ FUNCTION {format.eprint} if$ } +FUNCTION {format.version} +{ version empty$ + {""} +{version "version" bibinfo.check + versiontype duplicate$ empty$ + { pop$ bbl.version } + 'skip$ + if$ + "versiontype" bibinfo.check + swap$ duplicate$ empty$ + { pop$ "t" change.case$ } + { tie.or.space.prefix * * } + if$ +} +if$ +} + FUNCTION {format.url} { url @@ -1303,6 +1328,7 @@ FUNCTION {book} new.block format.btitle "title" output.check format.edition output + format.version output new.block crossref missing$ { format.bvolume output @@ -1359,6 +1385,7 @@ FUNCTION {inbook} new.block format.btitle "title" output.check format.edition output + format.version output new.block crossref missing$ { @@ -1476,6 +1503,7 @@ FUNCTION {manual} new.block format.btitle "title" output.check format.edition output + format.version output new.block author empty$ { organization empty$ @@ -1557,6 +1585,8 @@ FUNCTION {online} format.title "title" output.check new.block + format.version output + new.block organization "organization" bibinfo.warn output address "address" bibinfo.check output format.date "year" output.check diff --git a/macros/latex/contrib/asmeconf/asmeconf.cls b/macros/latex/contrib/asmeconf/asmeconf.cls index 987fa06e91..e7de2c9dfb 100644 --- a/macros/latex/contrib/asmeconf/asmeconf.cls +++ b/macros/latex/contrib/asmeconf/asmeconf.cls @@ -1,56 +1,50 @@ +% !TEX encoding = UTF-8 Unicode %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% This file provides the asmeconf class for formatting conference papers according to %% ASME conference requirements as represented on ASME's conference web pages in 2020. %% -%% Please note that ASME's journals follow specifications different from ASME conference papers. -%% %% This file's version and date: - \def\versionno{1.21} - \def\versiondate{2020/12/10\space} + \def\versionno{1.22} + \def\versiondate{2021/01/14\space} %% -%% Author: John H. Lienhard V +%% Author: John H. Lienhard, V %% Department of Mechanical Engineering %% Massachusetts Institute of Technology %% Cambridge, MA 02139-4307 USA %% %% This class was designed to approach the following aims: %% -%% 1. Match ASME's font specifications and layout -%% 2. With the associated amseconf.bst, match ASME's reference formats -%% 3. Maintain hyperref compatibility for pdf bookmarks and hyperlinks -%% 4. Use the newtxtext and newtxmath font packages, including relevant features -%% 5. Provide automatic layout of author names and addresses -%% 6. Support bold face, sans serif math in headings -%% 7. Support the archival PDF/A standards 1b, 2b, 2u, 3b, and 3u -%% -%% This class is compatible with either pdfLaTeX or LuaLaTeX. The class uses a number of packages, -%% many of which are part of the standard LaTeX distribution, and all of which are in TeXLive and -%% CTAN (https://ctan.org/). -%% -%% The Times/Helvetica style fonts are from Michael Sharpe's excellent newtxtext and newtxmath packages; -%% version 1.60 or higher of newtxmath is recommended. -%% -%% This class is not designed for unicode-math or fontspec, given that the ASME conference style is -%% specific with respect to the font selections. +%% 1. Match ASME's current layout and font specifications +%% 2. With amseconf.bst, match ASME's reference formats and support DOI & URL fields +%% 3. Provide hyperref compatibility for hyperlinks, pdf bookmarks, and metadata +%% 4. Set author names in either the traditional grid or the more recent inline style +%% 5. Support citations, footnotes, and bold face, sans serif math in section headings +%% 6. Provide line numbers for editing and review +%% 7. Support balancing length of columns on last page +%% 8. Provide copyright footer for federal employees and contractors +%% 9. Support the archival PDF/A standards 1b, 2b, 2u, 3b, and 3u +%% 10. Enable various math and text features from the newtxmath and newtxtext packages +%% 11. Support inclusion of passages in languages other than English %% -%% Options for the class are configured on lines 79-216. -%% -%% The class defines two environments: abstract and nomenclature. The latter has an optional argument to -%% control the space between the entries and the definitions. -%% -%% New commands are described in the asmeconf-template.tex file. The \section[]{} command's optional -%% argument is changed to better support pdf bookmarks, and \section* is modified similarly. +%% This class is compatible with either pdfLaTeX or LuaLaTeX. FontSpec may be loaded as an option (to +%% access language-specific fonts), but the class does not support unicode-math. All packages required +%% by the class are in TeXLive and CTAN (https://ctan.org/). %% %% Commands for entering conference headers and author names are specific to this class. %% See asmeconf-template.tex for details. %% +%% The \section[]{} command's optional argument is changed to better support pdf bookmarks, +%% and \section* is modified similarly. +%% +%% The class defines abstract (with keywords), abstract* (no keywords), and nomenclature environments. +%% The latter has an optional argument to control the space between the entries and the definitions. %% % ========================================================= %% %% LICENSE: %% -%% Copyright (c) 2020 John H. Lienhard +%% Copyright (c) 2021 John H. Lienhard %% %% 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, @@ -67,29 +61,21 @@ %% 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. %% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \NeedsTeXFormat{LaTeX2e} \ProvidesClass{asmeconf}[\versiondate ASME Conference Paper Format (JHL)] \LoadClass[twoside,twocolumn,10pt]{article} -% Two-sided layout not used in ASME's specs, although that's how the papers are printed +% Even/odd page layout is not used in ASME's specs, although the papers are printed in two-sided format. +%%%%%%%%%%%%%% Options for the class %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%% Options for the class %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - +\RequirePackage{xparse} % access features not yet moved into the LaTeX kernel +\RequirePackage{etoolbox} \RequirePackage{ifthen} \RequirePackage{iftex} % check whether pdftex or another engine is used -\newboolean{Balance}\setboolean{Balance}{false} -\newboolean{DefaultSups}\setboolean{DefaultSups}{true} -\newboolean{contractor}\setboolean{contractor}{false} -\newboolean{govt}\setboolean{govt}{false} -\newboolean{lineno}\setboolean{lineno}{false} -\newboolean{Oldauthors}\setboolean{Oldauthors}{false} -\newboolean{pdfaone}\setboolean{pdfaone}{false} -\newboolean{setpdfa}\setboolean{setpdfa}{false} - \RequirePackage{kvoptions} \SetupKeyvalOptions{ family=asmeconf, @@ -99,121 +85,281 @@ setkeys=\kvsetkeys, } -%%% set key [balance] to balance column height on last page. -\define@key{asmeconf}{balance}[true]{% - \setboolean{Balance}{#1} - \ClassWarningNoLine{asmeconf}{Loading flushend package to balance column height on last page}% -} - -%%% set key [contractor] to obtain government contractor copyright notice. -\define@key{asmeconf}{contractor}[true]{% - \setboolean{contractor}{#1} -} - -%%% set key [govt] to obtain government employee copyright notice. -\define@key{asmeconf}{govt}[true]{% - \setboolean{govt}{#1} -} - -%%% set key [lineno] to obtain line numbers. -\define@key{asmeconf}{lineno}[true]{% - \setboolean{lineno}{#1} -} - %%% for mathalfa, we may now pass options in this format: mathalfa=cal=euler, mathalfa=frak=boondox \define@key{asmeconf}{mathalfa}{% - \PassOptionsToPackage{#1}{mathalfa}% + \PassOptionsToPackage{#1}{mathalfa}% } %%% set key [nodefaultsups] to obtain newtx superiors font for footnotes. +\newboolean{DefaultSups}\setboolean{DefaultSups}{true} \define@key{asmeconf}{nodefaultsups}[false]{% \setboolean{DefaultSups}{#1} } +%%% Use these switches to load other alphabets for Cyrillic, Greek, Japanese, and Vietnamese text +\newif\ifac@cyrillic\ac@cyrillicfalse +\newif\ifac@greek\ac@greekfalse +\newif\ifac@japanese\ac@japanesefalse +\newif\ifac@vietnamese\ac@vietnamesefalse +\newif\ifac@mainset\ac@mainsetfalse + +\providecommand\ac@TtwoA{} +\providecommand\ac@LGR{} +\providecommand\ac@Tfive{} + +%%% Test whether main language is from a group that use the Cyrillic alphabet +\NewDocumentCommand\@FindCyr{>{\SplitList{;}}m}{\ProcessList{#1}{\@FlagCyr}} +\providecommand{\ac@main}{\relax} +\NewDocumentCommand\@FlagCyr{m}{% + \ifthenelse{\equal{#1}{\ac@main}}{\ac@cyrillictrue\def\ac@TtwoA{T2A}}{\relax}% comparing strings +} -%%% set key [lang,lang-second,lang-third] to pass languages to babel. - -%% In case language options are dropped during editing, include this. Subsequent choice of lang= will override it. -\PassOptionsToPackage{english}{babel} +\define@key{asmeconf}{main}[english]{% + \PassOptionsToPackage{main=#1,#1}{babel}% added #1 resolves conflict of russianb.ldf & ukrainianb.ldf under "main=". + \ac@mainsettrue + \ifthenelse{\equal{#1}{english}}{% + \PassOptionsToPackage{pdflang=en}{hyperref}}{% + \ClassWarningNoLine{asmeconf}{Selecting #1 as the primary language}% + \ifthenelse{\equal{#1}{greek}}{% + \ac@greektrue + \def\ac@LGR{LGR}% + }{\relax}% + \ifthenelse{\equal{#1}{vietnamese}}{% + \ac@vietnamesetrue + \def\ac@Tfive{T5}% + \RequirePackage[vietnamese=nohyphenation]{hyphsubst}% Eliminates babel warning + }{\relax}% + \def\ac@main{#1}% + \@FindCyr{russian;belarusian;bulgarian;macedonian;serbianc;ukrainian} + }% +} +\define@key{asmeconf}{vietnamese}[]{% + \RequirePackage[vietnamese=nohyphenation]{hyphsubst}% using key, not option, to allow loading package w/o babel warning. + \PassOptionsToPackage{vietnamese}{babel}% + \ac@vietnamesetrue + \def\ac@Tfive{T5}% +} -\define@key{asmeconf}{lang}[english]{% - \PassOptionsToPackage{main=#1}{babel}% +%%% only main= is actually needed, but keeping these legacy commands for backward compatibility +\define@key{asmeconf}{lang}[english]{% deprecated option + \PassOptionsToPackage{main=#1,#1}{babel}% + \PassOptionsToPackage{pdflang=en}{hyperref} + \ac@mainsettrue% + \ifthenelse{\equal{#1}{english}}{% + \relax}{% + \ClassWarningNoLine{asmeconf}{Selecting #1 as the primary language}% + }% } -\define@key{asmeconf}{lang-second}[english]{% +\define@key{asmeconf}{lang-second}[english]{% deprecated option \PassOptionsToPackage{#1}{babel}% } -\define@key{asmeconf}{lang-third}[english]{% +\define@key{asmeconf}{lang-third}[english]{% deprecated option \PassOptionsToPackage{#1}{babel}% } \ProcessKeyvalOptions{asmeconf} +%% % if main language was not chosen explicitly, default to English +\ifac@mainset\relax\else + \PassOptionsToPackage{main=english}{babel}% + \PassOptionsToPackage{pdflang=en}{hyperref} + %\ClassWarningNoLine{asmeconf}{Selecting English as the primary language, since main= not set}% +\fi + +%% Turn off these keys now that we're done with them +\def\@KeyFamily{asmeconf} +\NewDocumentCommand\ac@DisableOption{m}{% + \DisableKeyvalOption[% + action=ignore,% + class=asmeconf% + ]{#1}{\@KeyFamily}% +} +\NewDocumentCommand\@DisableKeys{>{\SplitList{;}}m}{\ProcessList{#1}{\ac@DisableOption}} + +\@DisableKeys{main;lang;nodefaultsups;mathalfa;lang-second;lang-third} + +%%%%%%%%%%%%% More Language options %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%% option to use fontspec [fontspec] (e.g, if you need complex language-specific fonts) +\newif\ifac@fontspec\ac@fontspecfalse +\newif\iffontspecloaded\fontspecloadedfalse% so user can test in .tex file +\DeclareOption{fontspec}{% + \ifpdftex + \ClassWarningNoLine{asmeconf}{fontspec option requires LuaLaTeX, will be ignored under pdfLaTeX}% + \else + \ac@fontspectrue + \fontspecloadedtrue + \def\ssztwo{}% for Inconsolatazi4; default uses slashed zero, +ss02 uses regular zero + \def\MonoNotMono{WordSpace={1,1.33,1.67}}% for Inconsolatazi4; default allows word spacing (is not mono) + \fi +} + +\DeclareOption{greek}{% + \PassOptionsToPackage{greek}{babel}% + \ac@greektrue + \def\ac@LGR{LGR}% +} + +\DeclareOption{japanese}{% mainly to control loading of fontspec options + \ifac@fontspec + \PassOptionsToPackage{japanese}{babel}% + \ac@japanesetrue + \else + \ClassWarningNoLine{asmeconf}{japanese option is supported only with the [fontspec] option + LuaLaTeX. It will be ignored.}% + \fi +} + +%% Cyrillic languages +\NewDocumentCommand\@CyrOptions{>{\SplitList{;}}m}{\ProcessList{#1}{\@CyrOptSet}} +\NewDocumentCommand\@CyrOptSet{m}{% + \DeclareOption{#1}{% + \PassOptionsToPackage{#1}{babel}% + \ac@cyrillictrue + \def\ac@TtwoA{T2A}% + } +} +\@CyrOptions{russian;belarusian;bulgarian;macedonian;serbianc;ukrainian} + +% Several languages do not have .ldf files to load. Babel will call these on demand. +% +\DeclareOption{arabic}{\ClassError{asmeconf}{Do not specify "arabic" as a class option.}{Instead, give the option [bidi=basic] and specify "arabic" when you call the language within your document.}} +% +\DeclareOption{bengali}{\ClassError{asmeconf}{Do not specify "bengali" as a class option.}{Babel does not have an ldf file for Bengali. Instead, specify "bengali" when you call the language within your document. No class option is needed.}} +% +\DeclareOption{chinese-simplified}{\ClassError{asmeconf}{Do not specify "chinese-simplified" as class option}{Babel does not have an ldf file for simplified Chinese. Instead, specify "chinese-simplified" when you call the language within your document. No class option is needed.}} +% +\DeclareOption{chinese-traditional}{\ClassError{asmeconf}{Do not specify "chinese-traditional" as class option}{Babel does not have an ldf file for traditional Chinese. Instead, specify "chinese-traditional" when you call the language within your document. No class option is needed.}} +% +\DeclareOption{chinese}{\ClassError{asmeconf}{Do not specify "chinese" as a class option.}{Instead, specify either "chinese-simplified" or "chinese-traditional" when you call the language within your document. No class option is needed.}} +% +\DeclareOption{hindi}{\ClassError{asmeconf}{Do not specify "hindi" as a class option.}{Babel does not have an ldf file for Hindi. Instead, specify "hindi" when you call the language within your document. No class option is needed.}} +% +\DeclareOption{marathi}{\ClassError{asmeconf}{Do not specify "marathi" as a class option.}{Babel does not have an ldf file for Marathi. Instead, specify "marathi" when you call the language within your document. No class option is needed.}} +% +\DeclareOption{korean}{\ClassError{asmeconf}{Do not specify "korean" as class option}{Babel does not have an ldf file for Korean. Instead, specify "korean"when you call the language within your document. No class option is needed.}} +% +\DeclareOption{tamil}{\ClassError{asmeconf}{Do not specify "tamil" as a class option.}{Babel does not have an ldf file for Tamil. Instead, specify "tamil" when you call the language within your document. No class option is needed.}} + + +%%%%%%% PDF/A Compliance Options %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newif\ifac@setpdfa\ac@setpdfafalse +\newif\ifac@pdfaone\ac@pdfaonefalse \ifpdftex %% PDF/A compliance has only been configured for pdflatex % %%% set key [pdfa] to activate pdf/a compliance (default is pdf/A-3u) \define@key{pdfaopt}{pdf-a}[true]{% - \setboolean{setpdfa}{#1}% + \ac@setpdfatrue \PassOptionsToPackage{pdfa,pdfapart=3,pdfaconformance=u}{hyperref}% } %%% to select part 1, 2 or 3 \define@key{pdfaopt}{pdfapart}[3]{% \PassOptionsToPackage{pdfapart=#1}{hyperref}% - \ifthenelse{\equal{#1}{1}}{\setboolean{pdfaone}{true}}{\relax}% + \ifthenelse{\equal{#1}{1}}{\ac@pdfaonetrue}{\relax}% } %%% to select conformance b or u. NB: a is not possible with pdfLaTeX, and u is not possible with 1. \define@key{pdfaopt}{pdfaconformance}[u]{% \PassOptionsToPackage{pdfaconformance=#1}{hyperref}% } - \ProcessKeyvalOptions{pdfaopt} + \ProcessKeyvalOptions{pdfaopt}% \else - \ClassWarningNoLine{asmejour}{PDF/A compliance option requires pdfLaTeX engine}% + \ifac@pdfaone\ClassWarningNoLine{asmeconf}{PDF/A compliance option requires pdfLaTeX engine}\fi \fi -%%%%%%%%%%%%%%%%%%% +%% Done with these keys, so we can now disable them +\def\@KeyFamily{pdfaopt} +\@DisableKeys{pdf-a;pdfapart;pdfaconformance} -%% option to have colored hyperlinks -\DeclareOption{colorlinks}{% - \PassOptionsToPackage{colorlinks=true}{hyperref}% + +%%%%%%%%% Miscellaneous options %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%% option to balance column height on last page [balance] +\newif\ifac@balance\ac@balancefalse +\DeclareOption{balance}{% + \ac@balancetrue + \ClassWarningNoLine{asmeconf}{Loading flushend package to balance column height on last page}% } -%% option to omit ASME footer +%%% option to obtain line numbers [lineno] +\newif\ifac@lineno\ac@linenofalse +\DeclareOption{lineno}{\ac@linenotrue} + +%% option to omit ASME footer [nofoot] \DeclareOption{nofoot}{% \AtBeginDocument{\pagestyle{plain}}% } -%% Access many options from newtxmath. See newtx documentation for details. -\DeclareOption{upint,smallerops,varvw,varg,uprightGreek,slantedGreek,frenchmath,varbb,cmbraces}{\PassOptionsToPackage{}{newtxmath}} - -%% Option for slightly larger small capitals font -\DeclareOption{largesc}{\PassOptionsToPackage{largesc}{newtxtext}} +%%% option [contractor] to obtain government contractor copyright notice. +\newif\ifac@contractor\ac@contractorfalse +\DeclareOption{contractor}{\ac@contractortrue} -%% Option not to use latex default superscripts, instead using the newtxtext superiors font [nodefaultsups] -\ifthenelse{\boolean{DefaultSups}}{\PassOptionsToPackage{defaultsups}{newtxtext}}{\relax} +%%% option [govt] to obtain government employee copyright notice. +\newif\ifac@govt\ac@govtfalse +\DeclareOption{govt}{\ac@govttrue} %% option to use grid of authors +\newboolean{Oldauthors}\setboolean{Oldauthors}{false} \DeclareOption{authorgrid}{% \setboolean{Oldauthors}{true}% \ClassWarningNoLine{asmeconf}{Selected option for a grid of author blocks}% } -%% retained for backward compatibility -\DeclareOption{oldauthors}{% +\DeclareOption{oldauthors}{%% deprecated, but retained for backward compatibility \setboolean{Oldauthors}{true}% \ClassWarningNoLine{asmeconf}{Selected option for a grid of author blocks}% } -%% Option to hyphenate the typewriter font [hyphenate] +%% option for slightly larger small capitals font, via newtxtext +\DeclareOption{largesc}{% + \ifac@fontspec + \ClassWarningNoLine{asmeconf}{largesc option is not available under fontspec, will be ignored}% + \else + \PassOptionsToPackage{largesc=true}{newtxtext}% largesc is a boolean key in newtxtext + \fi +} + +%% Disable newtxtext osf option, which is not appropriate for documents in this class +\DeclareOption{osf}{% + \PassOptionsToPackage{lining}{newtxtext}% +} + +%% option to hyphenate the typewriter font [hyphenate] and to issue a warning when that's done. \DeclareOption{hyphenate}{% - \PassOptionsToPackage{hyphenate}{inconsolata}% - \ClassWarningNoLine{asmeconf}{Allowing hyphenation of typewriter font}% + \ifac@fontspec + \ClassWarningNoLine{asmeconf}{hyphenate option is not supported by fontspec, will be ignored}% + \else + \PassOptionsToPackage{hyphenate}{inconsolata}% hyphenate is a key via xkeyval in inconsolata + \ClassWarningNoLine{asmeconf}{Allowing hyphenation of typewriter font}% + \fi } +%% option for monospacing in typewriter font [mono]. +\DeclareOption{mono}{% + \ifac@fontspec + \def\MonoNotMono{}% + \else + \PassOptionsToPackage{mono}{inconsolata}% mono is a key via xkeyval in inconsolata + \fi +} +%% option for unslashed zero typewriter font [var0]. +\DeclareOption{var0}{% + \ifac@fontspec + \def\ssztwo{+ss02}% stylistic alternate for regular zero + \else + \PassOptionsToPackage{var0}{inconsolata}% var0 is a key via xkeyval in inconsolata + \fi +} + +\ifthenelse{\boolean{DefaultSups}}{% + \ifac@fontspec\relax\else + \PassOptionsToPackage{defaultsups=true}{newtxtext}% defaultsups is a boolean key in newtxtext + \fi}{\relax} -%% Suppress warnings about mathalfa keys as unused global options +%% Suppress warnings about unused global options \DeclareOption*{} \ProcessOptions \relax -%%%%%%%%%%%%% end options %%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%% Geometry, bibliography, graphics, colors %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \RequirePackage[letterpaper, left=0.5in, right=0.5in, top=0.5in, bottom = 1.in, footskip=0.5in, columnsep=0.38in]{geometry} % conforms to ASME required margins @@ -223,65 +369,381 @@ \setlength\bibsep{1pt plus 1pt minus 1pt} \RequirePackage{graphicx} -\RequirePackage[hyperref,fixpdftex,dvipsnames,svgnames,x11names]{xcolor} -\RequirePackage{xparse} -\RequirePackage{metalogo,hologo} % Access various LaTeX logos if needed +\ifpdf\def\MyColorOption{fixpdftex}\else\ifluatex\def\MyColorOption{luatex}\else\def\MyColorOption{}\fi\fi +\RequirePackage[hyperref,\MyColorOption,dvipsnames,svgnames,x11names]{xcolor} -%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%% Table related %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \RequirePackage{booktabs} \RequirePackage{array} -\RequirePackage{dcolumn} %%% alignment on decimal places -\newcolumntype{d}[1]{D{.}{.}{#1}} %% conflicts with babel's spanish language option. +\RequirePackage{dcolumn}% alignment on decimal places +\newcolumntype{d}[1]{D{.}{.}{#1}}% NB: This conflicts with babel's spanish language option which makes "." an active character. + % To use "," separator, put this in preamble: \newcolumntype{d}[1]{D{,}{,}{#1}} -%%%% FONT related %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%% Font related %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\RequirePackage[T1]{fontenc} +\RequirePackage[T1,\ac@TtwoA,\ac@LGR,\ac@Tfive]{fontenc}% T2A to support Cyrillic (w/o babel warning); LGR - Greek; T5 - Vietnamese \ifpdftex - \ifthenelse{\boolean{pdfaone}}{ - \pdfminorversion=4}{% for pdf/a-1 need version 4, not 7 - \pdfminorversion=7 % this selection is not really required. - } - \RequirePackage[utf8]{inputenc} % for backward compatibility with pre-2018 distributions + \ifac@pdfaone + \pdfminorversion=4 % for pdf/a-1 need version 4, not 7 + \else + \pdfminorversion=7 % this selection is not essential. + \fi + \RequirePackage[utf8]{inputenc} % for backward compatibility with pre-2018 LaTeX distributions \else - \relax + \ifluatex + \relax + \else + \ClassError{asmeconf}{Please use either pdfLaTeX or LuaLaTeX}{This class has NOT been configured to support other engines, and the results will be unpredictable. Your best course of action is to exit and rerun using either pdfLaTeX or LuaLaTeX.}% + \fi \fi -\RequirePackage{mathtools} % loads and extends amsmath - +\RequirePackage{mathtools}% loads and extends amsmath \RequirePackage[]{babel} -\RequirePackage[]{newtxtext} -\RequirePackage[varqu,varl]{inconsolata} % sans typewriter font -\RequirePackage[]{newtxmath} -% See package documentation -%% override \textsu if using default superiors -\ifthenelse{\boolean{DefaultSups}}{\let\textsu\textsuperscript}{\relax} +\ifpdftex + \RequirePackage[]{newtxtext} + \RequirePackage[varqu,varl]{inconsolata}% sans typewriter font + \RequirePackage[]{newtxmath} +\else + \ifac@fontspec + \RequirePackage[varqu,varl]{inconsolata}% typewriter font for math + \renewcommand*{\sfdefault}{qhv} % sans font for math + \renewcommand{\rmdefault}{ntxtlf} % roman font for math + \RequirePackage[]{newtxmath} % newtxmath still handles mathematics + + \RequirePackage[no-math]{fontspec} + \defaultfontfeatures{Ligatures= TeX,} +% + \setmainfont{TeXGyreTermesX}[% Presumes these are system fonts! Available at: http://www.gust.org.pl/projects/e-foundry/tex-gyre + WordSpace = {1,1.4,1},%% This stretch matches newtxtext a little better. + Extension = .otf, + UprightFont = *-Regular, + ItalicFont = *-Italic, + BoldFont = *-Bold, + BoldItalicFont = *-BoldItalic, + Ligatures= TeX, + Numbers = Lining, + ] + \setsansfont{texgyreheros}[% Presumes these are system fonts! Available at: http://www.gust.org.pl/projects/e-foundry/tex-gyre + WordSpace = {1,1.4,1}, + Extension = .otf, + UprightFont = *-regular, + ItalicFont = *-italic, + BoldFont = *-bold, + BoldItalicFont = *-bolditalic, + Ligatures = TeX, + Numbers = Lining, + Scale=0.9, + ] + \setmonofont{Inconsolatazi4}[% This otf font ships with the LaTeX Inconsolata package (it's in TeX Live) + \MonoNotMono,% match newtxtext if we enable wordspacing + Scale=1, + Extension = .otf, + UprightFont = *-Regular, + ItalicFont = *-Regular,% has no italic face + BoldFont = *-Bold, + BoldItalicFont = *-Bold,% has no italic face + Ligatures = TeX, + RawFeature = {+ss01,\ssztwo,+ss03}, + ] +% + % For many languages, using babel commands helps font loading. + % Noto fonts are available at https://github.com/googlefonts + \def\Noto@scale{0.92} + \def\NotoAra@scale{0.91}% The serif font only + \def\NotoBan@scale{0.92}% 1.} should probably stay consistent within the Noto family. + \def\NotoDev@scale{0.92}% 1.} should probably stay consistent within the Noto family. + \def\NotoTam@scale{0.92} + \def\Noto@color{black} +% + \babelprovide[import, language=Default]{arabic} + \babelfont [arabic]{rm}[Scale=\NotoAra@scale, + Renderer=HarfBuzz, + Extension = .ttf, + UprightFont = *-Regular, + ItalicFont = *-Regular,% don't use italic face, I am told + BoldFont = *-Bold,% + BoldItalicFont = *-Bold,% don't use italic face, I am told + ]{Amiri}% NotoNaskhArabic}% Some readers prefer Amiri font + \babelfont [arabic]{sf}[Scale=\Noto@scale, + Renderer=HarfBuzz, + Extension =.ttf, + UprightFont = *-Regular, + ItalicFont = *-Regular,% font has no italic face + BoldFont = *-SemiBold,% I'm told that legibility better than Bold + BoldItalicFont = *-SemiBold,% font has no italic face + ]{NotoSansArabic}%DejaVuSans}%NotoKufiArabic}% .otf,% + \babelfont [arabic]{tt}[% + Renderer=HarfBuzz, + Extension =.ttf, + UprightFont = *-Regular, + ItalicFont = *-Regular,% has no italic face + BoldFont = *-SemiBold,% I'm told that legibility is better than Bold + BoldItalicFont = *-SemiBold,% has no italic face + ]{NotoSansArabic}%same as above! + \providecommand\arabicabstractname{ملخص}% NB: utf-8 +% + \babelprovide[import,language=Default,script=Bangla]{bengali} + \babelfont [bengali]{rm}[% + Renderer=HarfBuzz, + Scale=\NotoBan@scale,% same as Devanagari + Color=\Noto@color, + Extension = .ttf, + UprightFont = *-Regular, + ItalicFont = *-Regular,% has no italic face + BoldFont = *-Bold, + BoldItalicFont = *-Bold,% has no italic face + ]{NotoSerifBengali} + \babelfont [bengali]{sf}[% + Renderer=HarfBuzz, + Scale=\NotoBan@scale, + Color=\Noto@color, + Extension = .ttf, + UprightFont = *-Regular, + ItalicFont = *-Regular,% has no italic face + BoldFont = *-Bold, + BoldItalicFont = *-Bold,% has no italic face + ]{NotoSansBengali} + \babelfont [bengali]{tt}[ + Renderer=HarfBuzz, + Scale=\NotoBan@scale, + Color=\Noto@color, + Extension = .ttf, + UprightFont = *-Regular, + ItalicFont = *-Regular,% has no italic face + BoldFont = *-Bold, + BoldItalicFont = *-Bold,% has no italic face + ]{NotoSansBengali} +% + % Cyrillic languages + \NewDocumentCommand\@LoadBabelCyr{>{\SplitList{;}}m}{\ProcessList{#1}{\@CyrillicBabel}} + \NewDocumentCommand\@CyrillicBabel{m}{% + \babelprovide[import,language=Default,script=Cyrillic]{#1} + \babelfont [#1]{rm}[Scale=\Noto@scale,Color=\Noto@color]{NotoSerif} + \babelfont [#1]{sf}[Scale=\Noto@scale,Color=\Noto@color]{NotoSans} + \babelfont [#1]{tt}[Scale=\Noto@scale,Color=\Noto@color]{NotoSansMono} + } + \@LoadBabelCyr{russian;belarusian;bulgarian;macedonian;serbian-cyrillic;ukrainian}% serbianc has no .ini under fontspec + \setlocalecaption{serbian-cyrillic}{abstract}{Сажетак}% NB: utf-8 +% + % Devanagari languages + \newfontscript{Devanagari}{deva}% HarfBuzz has some problems in Hindi, see babel manual Sect. 1.13 (main issue is ra) + \NewDocumentCommand\@LoadBabelDev{>{\SplitList{;}}m}{\ProcessList{#1}{\@DevBabel}} + \NewDocumentCommand\@DevBabel{m}{% + \babelprovide[import,language=Default]{#1} + \babelfont [#1]{rm}[% +% Renderer=HarfBuzz,% works for Marathi, throws errors in Hindi... + Scale=\NotoDev@scale, + Color=\Noto@color, + Extension = .ttf, + UprightFont = *-Regular, + ItalicFont = *-Regular,% has no italic face + BoldFont = *-Bold, + BoldItalicFont = *-Bold,% has no italic face + ]{NotoSerifDevanagari} + \babelfont [#1]{sf}[% +% Renderer=HarfBuzz,% works for Marathi, throws errors in Hindi... + Scale=\NotoDev@scale, + Color=\Noto@color, + Extension = .ttf, + UprightFont = *-Regular, + ItalicFont = *-Regular,% has no italic face + BoldFont = *-Bold, + BoldItalicFont = *-Bold,% has no italic face + ]{NotoSansDevanagari} + \babelfont [#1]{tt}[ +% Renderer=HarfBuzz,% works for Marathi, throws errors in Hindi... + Scale=\NotoDev@scale, + Color=\Noto@color, + Extension = .ttf, + UprightFont = *-Regular, + ItalicFont = *-Regular,% has no italic face + BoldFont = *-Bold, + BoldItalicFont = *-Bold,% has no italic face + ]{NotoSansDevanagari} + } + \@LoadBabelDev{hindi;marathi;kashmiri;nepali;sanskrit}% no .ldf files for these languages, but they do have .ini. Nepali: no abstractname +% + % Greek + \babelprovide[import,language=Default]{greek} + \babelfont [greek]{rm}[Scale=\Noto@scale,WordSpace={1.1},Color=\Noto@color]{NotoSerif}% increase word spacing slightly + \babelfont [greek]{sf}[Scale=\Noto@scale,WordSpace={1.1},Color=\Noto@color]{NotoSans} + \babelfont [greek]{tt}[Scale=\Noto@scale,Color=\Noto@color]{NotoSansMono} +% + % Japanese + \ifac@japanese + \RequirePackage[match]{luatexja-fontspec}% japanese typesets *much* better with this loaded + \setmainjfont{NotoSerifCJKjp}[Scale=\Noto@scale,Color=\Noto@color] + \setsansjfont{NotoSansCJKjp}[Scale=\Noto@scale,Color=\Noto@color] + \setmonojfont{NotoSansMonoCJKjp}[Scale=\Noto@scale,Color=\Noto@color] + \ltjsetparameter{jacharrange={-1, -2, +3, -4, -5, +6, +7, +8}}% this prevents luatexja from breaking Russian and Greek. + % see: https://tex.stackexchange.com/questions/222320/russian-in-document-with-japanese-as-main-language-lualatex-ltjsarticle + % Need at least one of the following to load the Japanese dictionary. + \babelfont [japanese]{rm}[% + Scale=\Noto@scale, + Color=\Noto@color, + Extension = .otf, + UprightFont = *-Regular, + ItalicFont = *-Regular,% has no italic face + BoldFont = *-Bold, + BoldItalicFont = *-Bold,% has no italic face + ]{NotoSerifCJKjp}% Scale estimated + \babelfont [japanese]{sf}[% + Scale=\Noto@scale, + Color=\Noto@color, + Extension = .ttc, + UprightFont = *-Regular, + ItalicFont = *-Regular,% has no italic face + BoldFont = *-Bold, + BoldItalicFont = *-Bold,% has no italic face + ]{NotoSansCJK} + \babelfont [japanese]{tt}[Scale=\Noto@scale,Color=\Noto@color]{NotoSansMonoCJKjp}% renders same as Sans! + \fi + % Note: \japaneseabstractname is not defined if japanese is not called as a package option. + + % Korean + \babelprovide[import,language=Default]{korean} + \babelfont [korean]{rm}[% + Scale=\Noto@scale, + Color=\Noto@color, + Extension = .otf, + UprightFont = *-Regular, + ItalicFont = *-Regular,% has no italic face + BoldFont = *-Bold, + BoldItalicFont = *-Bold,% has no italic face + ]{NotoSerifCJKkr} + \babelfont [korean]{sf}[% + Scale=\Noto@scale, + Color=\Noto@color, + Extension = .ttc, + UprightFont = *-Regular, + ItalicFont = *-Regular,% has no italic face + BoldFont = *-Bold, + BoldItalicFont = *-Bold,% has no italic face + ]{NotoSansCJK} + \babelfont [korean]{tt}[Scale=\Noto@scale,Color=\Noto@color]{NotoSansMonoCJKkr} + \renewcommand\koreanabstractname{초록}% NB: utf-8 + + % Simplified Chinese + \babelprovide[import,language=Default]{chinese-simplified} + \babelfont [chinese-simplified]{rm}[% + Scale=\Noto@scale, + Color=\Noto@color, + Extension = .otf, + UprightFont = *-Regular, + ItalicFont = *-Regular,% has no italic face + BoldFont = *-Bold, + BoldItalicFont = *-Bold,% has no italic face + ]{NotoSerifCJKsc} + \babelfont [chinese-simplified]{sf}[% + Scale=\Noto@scale, + Color=\Noto@color, + Extension = .ttc, + UprightFont = *-Regular, + ItalicFont = *-Regular,% has no italic face + BoldFont = *-Bold, + BoldItalicFont = *-Bold,% has no italic face + ]{NotoSansCJK} + \babelfont [chinese-simplified]{tt}[Scale=\Noto@scale,Color=\Noto@color]{NotoSansMonoCJKsc} +% + % Traditional Chinese (includes characters for Cantonese also) + \babelprovide[import,language=Default]{chinese-traditional} + \babelfont [chinese-tradiational]{rm}[% + Scale=\Noto@scale, + Color=\Noto@color, + Extension = .otf, + UprightFont = *-Regular, + ItalicFont = *-Regular,% has no italic face + BoldFont = *-Bold, + BoldItalicFont = *-Bold,% has no italic face + ]{NotoSerifCJKtc} + \babelfont [chinese-traditional]{sf}[% + Scale=\Noto@scale, + Color=\Noto@color, + Extension = .ttc, + UprightFont = *-Regular, + ItalicFont = *-Regular,% has no italic face + BoldFont = *-Bold, + BoldItalicFont = *-Bold,% has no italic face + ]{NotoSansCJK} + \babelfont [chinese-traditional]{tt}[Scale=\Noto@scale,Color=\Noto@color]{NotoSansMonoCJKtc} +% + \babelprovide[import,language=Default]{tamil} + \babelfont [tamil]{rm}[% + Renderer=HarfBuzz, + Scale=\NotoTam@scale, + Color=\Noto@color, + Extension = .ttf, + UprightFont = *-Regular, + ItalicFont = *-Regular,% has no italic face + BoldFont = *-Bold, + BoldItalicFont = *-Bold,% has no italic face + ]{NotoSerifTamil} + \babelfont [tamil]{sf}[% + Renderer=HarfBuzz, + Scale=\NotoTam@scale, + Color=\Noto@color, + Extension = .ttf, + UprightFont = *-Regular, + ItalicFont = *-Regular,% has no italic face + BoldFont = *-Bold, + BoldItalicFont = *-Bold,% has no italic face + ]{NotoSansTamil} + \babelfont [tamil]{tt}[ + Renderer=HarfBuzz, + Scale=\NotoTam@scale, + Color=\Noto@color, + Extension = .ttf, + UprightFont = *-Regular, + ItalicFont = *-Regular,% has no italic face + BoldFont = *-Bold, + BoldItalicFont = *-Bold,% has no italic face + ]{NotoSansTamil} +% + \babelprovide[import, captions/abstract = Muhtasari, language = Default]{swahili} +% + \else % use lualatex without font support for other languages (easier set-up and still enables luacode for numerics) + \RequirePackage[]{newtxtext} + \RequirePackage[varqu,varl]{inconsolata}% sans typewriter font + \RequirePackage[]{newtxmath} + \fi +\fi + +\RequirePackage[]{mathalfa}% load optional fonts for Calligraphy, Script, Fraktur. Key format: mathalfa=cal=euler (etc.) +\RequirePackage{bm}% load after all math to give further access to bold math -\RequirePackage[]{mathalfa} % load optional fonts for Calligraphy, Script, Fraktur -% See mathalfa package documentation for capabilities of this package. -% Option format: mathalfa=cal=euler (etc.) +%% option not to use latex default superscripts; if fontspec loaded, use the superiors package. +\ifthenelse{\boolean{DefaultSups}}{\relax}{% + \ifac@fontspec + \RequirePackage{superiors}% must come after text font is loaded + \else + \relax + \fi +} -\RequirePackage{bm} % load after all math to give access to bold math +%% override \textsu if using default superiors +\ifthenelse{\boolean{DefaultSups}}{\let\textsu\textsuperscript}{\relax} %% Ensure that the current font is used for equation tags, not \normalfont as set by amsmath \def\maketag@@@#1{\hbox{\m@th#1}} % The article class calls \sloppy in two-column mode (\tolerance 9999, \emergencystretch 3em) -% These adjustments affect line breaking; the values below are intended to produce +% The following adjustments affect line breaking; the values below are intended to produce % fewer lines with large spaces, without creating the problems of using \fussy in two-column mode. \tolerance 2500 \emergencystretch 3em +\RequirePackage{metalogo,hologo}% Access various LaTeX logos if needed -%%%% font size selection %%%%%%%% -%%%% ASME's specs differ slightly from latex standard article-10 class %%% +%% font size selection +%% ASME's specs differ slightly from latex standard article-10 class -\renewcommand\LARGE{\@setfontsize\LARGE{16}{19.2}} %{18}{21.6}} updated 7/7/19 to match new ASME spec. - % ...default is 17.28/22 ... used for paper# -\renewcommand\large{\@setfontsize\large{11}{13.6}} %... default is 12/14 ... used for headings +\renewcommand\LARGE{\@setfontsize\LARGE{16}{19.2}} %{18}{21.6}} updated 7/7/19 to match new ASME spec. + % ...default is 17.28/22 ... used for paper# +\renewcommand\large{\@setfontsize\large{11}{13.6}} % default is 12/14 ... used for headings %\renewcommand\Large{\@setfontsize\Large{14.4}{18}} % same as default %\renewcommand\normalsize{\@setfontsize\normalsize{10}{12}} % same as default @@ -290,7 +752,7 @@ %% This provides sans serif italic and sans serif bold italic math. -%% It's intended only for use in the figure captions and section headings (recommend \bm{..} elsewhere). +%% These fonts are for use in the figure captions and section headings. Use \mathbf{..}, \mathversion{bold}, or \bm{..} elsewhere. \DeclareMathVersion{sansbold} \SetSymbolFont{letters}{sansbold}{OML}{ntxsfmi}{b}{it} \SetSymbolFont{lettersA}{sansbold}{U}{ntxsfmia}{b}{it} @@ -298,32 +760,38 @@ \SetSymbolFont{operators}{sansbold}{\encodingdefault}{\sfdefault}{\bfdefault}{n} \SetMathAlphabet{\mathsf}{sansbold}{\encodingdefault}{\sfdefault}{b}{it} -%%%%%% footer %%%%%%% +% Nice solution from DPC to prevent aux file errors (due to active characters from babel) when switching from pdflatex to lualatex. +\ifx\directlua\undefined + \AtBeginDocument{\immediate\write\@auxout{\detokenize{% + \ifx\directlua\undefined\else\endinput\fi}}} +\fi + +%%%%%%%% Footers and Footnotes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \RequirePackage{fancyhdr} \pagestyle{fancy} +\AtBeginDocument{\edef\@EncodingMain{\encodingdefault}} +\NewDocumentCommand\@SetFont{}{\fontencoding\@EncodingMain\selectfont} + \fancyfoot{} \fancyhead{} -\fancyfoot[CE,CO]{\thepage} -\fancyfoot[RO,RE]{Copyright~\textcopyright~\the\year\ by ASME} +\fancyfoot[CE,CO]{\@SetFont\thepage}% force encoding so that passages in some languages won't switch footer font from the main font. +\fancyfoot[RO,RE]{\@SetFont Copyright~\textcopyright~\the\year\ by ASME} \renewcommand{\headrulewidth}{0pt} \renewcommand{\footrulewidth}{0pt} -\ifthenelse{\boolean{govt}}{% +\ifac@govt \newgeometry{left=0.5in, right=0.5in, top=0.5in, bottom = 1.in, footskip = 0.3in, columnsep = 0.38in} \fancyfoot[RO,RE]{} - \fancyfoot[CE,CO]{\thepage\\[1ex]\small This material is declared a work of the U.\ S.~Government and is not subject to copyright protection in the United States.\\Approved for public release; distribution is unlimited.} - }{\relax -} + \fancyfoot[CE,CO]{\@SetFont\thepage\\[1ex]\small This material is declared a work of the U.\ S.~Government and is not subject to copyright protection in the United States.\\Approved for public release; distribution is unlimited.} +\fi -\ifthenelse{\boolean{contractor}}{% +\ifac@contractor \newgeometry{left=0.5in, right=0.5in, top=0.5in, bottom = 1.in, footskip = 0.3in, columnsep = 0.38in} \fancyfoot[RO,RE]{} - \fancyfoot[CE,CO]{\thepage\\[1ex]\footnotesize The United States Government retains, and by accepting the article for publication, the publisher acknowledges that the United States Government retains, a non-exclusive, paid-up, irrevocable, worldwide license to publish or reproduce the published form of this work, or allow others to do so, for United States Government purposes.} - }{\relax -} - + \fancyfoot[CE,CO]{\@SetFont\thepage\\[1ex]\footnotesize The United States Government retains, and by accepting the article for publication, the publisher acknowledges that the United States Government retains, a non-exclusive, paid-up, irrevocable, worldwide license to publish or reproduce the published form of this work, or allow others to do so, for United States Government purposes.} +\fi %%%%%% footnotes %%%%%%% @@ -331,7 +799,7 @@ \makeFNbottom \makeFNbelow -\setlength{\skip\footins}{\baselineskip} % <=== per ASME 1 extra line +\setlength{\skip\footins}{\baselineskip}% <=== per ASME, 1 extra line \renewcommand{\footnoterule}{% \kern -3pt @@ -340,11 +808,10 @@ } %% reduce indentation of footnotes -\renewcommand\@makefntext[1]{% - \noindent\makebox[2ex][r]{\@makefnmark}#1} - +\RenewDocumentCommand\@makefntext{m}{% + \noindent\makebox[2ex][r]{\@makefnmark}#1}% <== To discourage hyphenation, do \hyphenpenalty=300\exhyphenpenalty=300 before #1 -%%%%%%%%% CAPTION RELATED %%%%%%%%%%%%%%%% +%%%%%%%%% Caption related %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \RequirePackage[labelfont={sf,bf},hypcap=false]{caption} \RequirePackage[hypcap=false,list=true]{subcaption} @@ -360,15 +827,9 @@ \let\scaption\caption \renewcommand*{\caption}[2][\shortcaption]{\def\shortcaption{#2}\scaption[#1]{\MakeTextUppercase{#2}}}% } - -%%%%%% introduce some caption or section names %%%%%%%%%%% - \providecommand{\nomname}{Nomenclature} - \providecommand{\keywordname}{Keywords} - \providecommand{\appendicesname}{APPENDICES} - \providecommand{\JAwords}{Joint first authors} - \providecommand{\CAwords}{Corresponding author} -%%%%%%%%%%%%%%%%%% Section headings %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%% Section headings %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %% wish to accommodate hyperref \RequirePackage{textcase} %% Allows uppercase titles and captions without errors from math and citations @@ -385,7 +846,6 @@ \titlespacing\subsection{0pt}{12pt plus 4pt minus 2pt}{0pt plus 2pt minus 1pt} \titlespacing\subsubsection{\parindent}{6pt plus 3pt minus 2pt}{0pt plus 2pt minus 1pt} % from 12 4 3, 7/7/19 - %% Special handling of the appendices %% Assumes that appendices are the last content in paper \RenewDocumentCommand{\appendix}{}{% @@ -395,20 +855,19 @@ \titleformat{\section}{\mathversion{sansbold}\bfseries\sffamily\raggedright}{\MakeTextUppercase{\appendixname}\ \thesection.}{0.5em}{\MakeTextUppercase} } -%%%%%%%%%%%%%%%%% Hyperref %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%% Hyperref, bookmarks, and PDF/A %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\ifthenelse{\boolean{setpdfa}}{% -% - %%% to assist with unicode glyph mapping, following M. Sharpe's recommendation in newtx documentation. +\ifac@setpdfa + %%% to assist with unicode glyph mapping, following M. Sharpe's recommendation in the newtx documentation. \pdfgentounicode=1 %% enable CMaps \input glyphtounicode.tex %% lists of mappings \InputIfFileExists{glyphtounicode-cmr.tex}{}{} %% additional mappings \InputIfFileExists{glyphtounicode-ntx.tex}{}{} %% additional mappings % -%%% a fairly generic RGB color profile, aimed at on-screen rendering (not print production) + %%% a fairly generic RGB color profile, aimed at on-screen rendering (not print production) \immediate\pdfobj stream attr{/N 3} file{sRGB.icc} \pdfcatalog{% - /OutputIntents [ + /OutputIntents [ << /Type /OutputIntent /S /GTS_PDFA1 @@ -416,11 +875,11 @@ /OutputConditionIdentifier (sRGB) /Info (sRGB) >> - ] - }% -}{\relax} + ] + }% +\fi -\RequirePackage{hyperxmp} %% to fix transfer of metadata to Acrobat pdf +\RequirePackage{hyperxmp}% improve transfer of metadata to pdf \RequirePackage[% unicode, % Unicode encoded PDF strings @@ -438,15 +897,14 @@ pdftitle={}, % <=== add in .tex file pdfkeywords={}, % <=== add in .tex file pdfnewwindow=true,% - pdfpagelayout=SinglePage, %TwoPageRight,% changed this 12/08/2020 + pdfpagelayout=SinglePage, %TwoPageRight,% changed this 08/12/20 pdfauthor={}, % <=== add in .tex file pdfdisplaydoctitle=true% ]{hyperref} -\urlstyle{same} % don't switch to typewriter font - +\urlstyle{same} % don't switch to typewriter font for urls \RequirePackage{doi} % supports the nasty characters in some doi's -\renewcommand{\doitext}{DOI } % change the default value, {doi:}, to this per ASME specification +\renewcommand{\doitext}{DOI } % change to this from default value, {doi:}, per ASME specification \RequirePackage{bookmark} % improves handling of pdf bookmarks %% Since \bm may be useful in headings, this fix will reduce frequency with which @@ -472,9 +930,8 @@ } %% Let's make sure footnotes in section headings don't break pdf bookmarks. -\RequirePackage{etoolbox} \robustify{\footnote} -% \patchcmd{\section}{\sectionmark}{\let\footnote\@gobble\sectionmark}{}{} <== not really needed in this context 28/2/20 +% \patchcmd{\section}{\sectionmark}{\let\footnote\@gobble\sectionmark}{}{}% <== not really needed in this context 28/2/20 \pdfstringdefDisableCommands{% \def\footnote#1{}% } @@ -505,79 +962,96 @@ }% } -%%%%%%%%%%%%% Line numbering and balancing columns on last page %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%% Line numbering and balancing columns on last page %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Allow line numbering in AMS math environments. %%% postdisplaypenalty adjusted to avoid extra line number at end, see discussion here: https://tex.stackexchange.com/a/461192/ -%%% multline has some problem that puts an extra line number above it. -%%% Requires xparse and etoolbox -\NewDocumentCommand{\losepostpenalty}{}{\patchcmd{\linenomathWithnumbers}{\advance\postdisplaypenalty\linenopenalty}{}{}{}} +%%% multline has some additional problem that puts an extra line number above it. + +\NewDocumentCommand{\@losepostpenalty}{}{\patchcmd{\linenomathWithnumbers}{\advance\postdisplaypenalty\linenopenalty}{}{}{}} -\NewDocumentCommand{\FixAMSMath}{m}{% - \AtBeginEnvironment{#1}{\losepostpenalty\linenomath}% +\NewDocumentCommand{\@FixAMSMath}{m}{% + \AtBeginEnvironment{#1}{\@losepostpenalty\linenomath}% \AtEndEnvironment{#1}{\endlinenomath}% - \AtBeginEnvironment{#1*}{\losepostpenalty\linenomath}% + \AtBeginEnvironment{#1*}{\@losepostpenalty\linenomath}% \AtEndEnvironment{#1*}{\endlinenomath}% } -\NewDocumentCommand{\FixAll}{>{\SplitList{;}}m}{\ProcessList{#1}{\FixAMSMath}} +\NewDocumentCommand{\@FixAll}{>{\SplitList{;}}m}{\ProcessList{#1}{\@FixAMSMath}} %%% Adjustments when lineno option is used -\ifthenelse{\boolean{lineno}}{% +\ifac@lineno% \RequirePackage[switch,mathlines]{lineno} \renewcommand{\linenumberfont}{\normalfont\footnotesize\color{red}} \AtBeginDocument{\linenumbers} \ClassWarningNoLine{asmeconf}{Package lineno loaded, so final column balancing is disabled} - \FixAll{align;alignat;gather;flalign;multline} - }{% - \ifthenelse{\boolean{Balance}}{\RequirePackage{flushend}}{\relax} % flushend is NOT compatible with lineno -} + \@FixAll{align;alignat;gather;flalign;multline} + \else + \ifac@balance\RequirePackage{flushend}\fi % flushend is NOT compatible with lineno +\fi %%% Enable dropping lineno option without trashing .aux file \providecommand{\@LN@col}[1]{\relax} \providecommand{\@LN}[2]{\relax} -%%%%%%%%%%%%% Define special environments %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%% Define special environments %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%% Introduce some special section and other names %%%%%%%%%%% -%% Abstract environment -%% \keywords command should be given someplace before the \end{abstract} command. +\providecommand{\nomname}{Nomenclature} +\providecommand{\keywordname}{Keywords} +\providecommand{\appendicesname}{APPENDICES} +\providecommand{\JAwords}{Joint first authors} +\providecommand{\CAwords}{Corresponding author} + +%% Abstract environment %%%%%%%%%%%%%%%%%% +%% \keywords command should be given someplace before the \end{abstract} command. \providecommand{\@keywords}{\relax} +% \ifblank is from etoolbox \NewDocumentCommand{\keywords}{m}{% - \IfNoValueTF{#1}{% - \relax}{% - \long\def\@keywords{\par\smallskip\noindent{\bfseries\sffamily \keywordname:} #1}% - } + \ifblank{#1}{\def\@keywords{\relax}}{ + \long\def\@keywords{\par\smallskip\noindent{\bfseries\sffamily \keywordname: #1}}% + } } \DeclareDocumentEnvironment{abstract}{}{% Overwrites existing abstract environment - \section*{\abstractname}\itshape% + \section*{\abstractname}\itshape + } + {\upshape\@keywords +} +\NewDocumentEnvironment{abstract*}{}{% Abstract with no keywords (same as using empty \keywords{} with first abstract) + \section*{\abstractname}\itshape } - {\upshape\@keywords%\medskip% + {\ignorespacesafterend } -%%%%%%%%%%%% Nomenclature environment %%%%%%%%%%%%%%%%%% -%% -%% Increase first optional argument to a dimension > 2em if wide entries cause undesired misalignment of columns. -%% Second argument can be used to rename, e.g., to List of Symbols. +%% Nomenclature environment %%%%%%%%%%%%%%%%%% %% +%% Increase first optional argument to a dimension > 2em if wide entries cause undesired misalignment of columns. +%% Second optional argument can be used to rename the environment, e.g., to List of Symbols. \newlength\nomenwidth \newlength\savitemsep %% If second argument of \entry is omitted, will produce an italicized heading (e.g. "Greek letters") -%% -\NewDocumentCommand{\entry}{m g}{% +\NewDocumentCommand\entry{m g}{% \IfNoValueTF{#2}{% \itemsep3\p@ plus 1\p@ minus 1\p@% - \goodbreak\item[\itshape#1\hfill]\setlength\itemsep\savitemsep\@itempenalty=1000%\nopagebreak% \smallskip + \goodbreak\item[\itshape#1\hfill]\setlength\itemsep\savitemsep\@itempenalty=1000% }{% \item[#1\hfill]#2% \@itempenalty=-\@lowpenalty% }% } +%% A separate command command for nomenclature subheadings (xparse "g" argument used in \entry is deprecated) +\NewDocumentCommand\EntryHeading{m}{% + \itemsep3\p@ plus 1\p@ minus 1\p@% + \goodbreak\item[\itshape#1\hfill]\setlength\itemsep\savitemsep\@itempenalty=1000% +} + \NewDocumentEnvironment{nomenclature}{O{2em} O{\nomname}}{% \setlength\columnsep{2em} \setlength{\nomenwidth}{#1} @@ -592,24 +1066,24 @@ \addtolength{\leftmargin}{\labelsep}% \setlength\savitemsep\itemsep% }% -}{\end{list}} +}{\end{list}\ignorespacesafterend} -%%%%%%%%%%%%%%%%% Headers and Title %%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%% Headers and Title %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand{\ConfName}[1]{\long\gdef\@ConfName{#1}} +\NewDocumentCommand\ConfName{m}{\long\gdef\@ConfName{#1}} \providecommand\@ConfName{\hbox{ }} -\newcommand{\ConfAcronym}[1]{\gdef\@ConfAcronym{#1}} +\NewDocumentCommand\ConfAcronym{m}{\gdef\@ConfAcronym{#1}} \providecommand\@ConfAcronym{\hbox{ }} -\newcommand{\ConfDate}[1]{\gdef\@ConfDate{#1,\space}} +\NewDocumentCommand\ConfDate{m}{\gdef\@ConfDate{#1,\space}} \providecommand\@ConfDate{\space} -\newcommand{\ConfCity}[1]{\gdef\@ConfCity{#1}} +\NewDocumentCommand\ConfCity{m}{\gdef\@ConfCity{#1}} \providecommand\@ConfCity{\hbox{ }} -\newcommand{\HeaderConfName}{% +\NewDocumentCommand\HeaderConfName{}{% \parbox{\linewidth}{% \raggedleft\bfseries\sffamily% \@ConfName\par% @@ -618,177 +1092,47 @@ }% } -\newcommand{\PaperNo}[1]{\gdef\@PaperNo{#1}} +\NewDocumentCommand\PaperNo{m}{\gdef\@PaperNo{#1}} \providecommand\@PaperNo{\protect\phantom{NO.}} -\newcommand{\paperno}{% +\NewDocumentCommand\paperno{}{% \vspace*{2\baselineskip} \parbox{\linewidth}{\raggedleft\bfseries\sffamily\LARGE% \MakeTextUppercase{\@PaperNo}% }% } -\newcommand{\PaperTitle}[1]{\gdef\@PaperTitle{#1}} +\NewDocumentCommand\PaperTitle{m}{\gdef\@PaperTitle{#1}} \providecommand\@PaperTitle{\hbox{ }} -\newcommand{\papertitle}{% +\NewDocumentCommand\papertitle{}{% \vspace*{3\baselineskip} \parbox{\linewidth}{\mathversion{sansbold}\centering{\bfseries\sffamily\large% -\MakeTextUppercase{\@PaperTitle}\par} %%% <=== extra \par to make leading stick. See adjustment in \MakeTitle +\MakeTextUppercase{\@PaperTitle}\par}%%% <=== extra \par to make leading stick. See adjustment in \MakeTitle }% } - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%% Author and affiliation block %%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%% Author and affiliation block %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \RequirePackage{xcoffins} -%% To maintain compatibility with newtxtext superiors option, if used, save the definition +%% To maintain compatibility with newtxtext superiors option, if used, save the definition (inline author style resets it) \let\savethefootnote\thefootnote \let\savemakefnmark\@makefnmark - -%%%% option to retain original grid layout of authors -\ifthenelse{\boolean{Oldauthors}}{% - -%%%%%%%%%%%%%%%%%%%% Gridded author layout %%%%%%%%%%%%%%%%%%%%%%%%% - -\NewCoffin{\authorblock} - -%% Allows for up to nine author groups... if you need more authors, the edits should be obvious -%% You can put multiple authors above a single affiliation to reduce number of author blocks needed. -\NewCoffin{\firstrowauthorblock} -\SetHorizontalCoffin\firstrowauthorblock{} -\NewCoffin{\secondrowauthorblock} -\SetHorizontalCoffin\secondrowauthorblock{} -\NewCoffin{\thirdrowauthorblock} -\SetHorizontalCoffin\thirdrowauthorblock{} - -\newcounter{authorno} -\setcounter{authorno}{0} - -\newlength{\coffinsep} %% horizontal space between coffins -\setlength{\coffinsep}{0.03\textwidth} - -\NewDocumentCommand\SetAuthorBlock{m m}{% - \addtocounter{authorno}{1}% - \SetVerticalCoffin{\authorblock}{0.3\textwidth}{% - \centering\sffamily% - \textbf{\ignorespaces#1\ignorespaces}\\ - #2% -} - -\ifnum\value{authorno}=1 - \JoinCoffins\firstrowauthorblock[r,t]\authorblock[l,t] - \else - \ifnum\value{authorno}=2 - \JoinCoffins\firstrowauthorblock[r,t]\authorblock[l,t](\coffinsep,0pt) - \else - \ifnum\value{authorno}=3 - \JoinCoffins\firstrowauthorblock[r,t]\authorblock[l,t](\coffinsep,0pt) - \fi - \fi -\fi -\ifnum\value{authorno}=4 - \JoinCoffins\secondrowauthorblock[r,t]\authorblock[l,t] - \else - \ifnum\value{authorno}=5 - \JoinCoffins\secondrowauthorblock[r,t]\authorblock[l,t](\coffinsep,0pt) - \else - \ifnum\value{authorno}=6 - \JoinCoffins\secondrowauthorblock[r,t]\authorblock[l,t](\coffinsep,0pt) - \fi - \fi -\fi -\ifnum\value{authorno}=7 - \JoinCoffins\thirdrowauthorblock[r,t]\authorblock[l,t] - \else - \ifnum\value{authorno}=8 - \JoinCoffins\thirdrowauthorblock[r,t]\authorblock[l,t](\coffinsep,0pt) - \else - \ifnum\value{authorno}=9 - \JoinCoffins\thirdrowauthorblock[r,t]\authorblock[l,t](\coffinsep,0pt) - \fi - \fi -\fi -} - -\NewDocumentCommand{\ConstructAuthorBlock}{}{% -\ifnum\value{authorno}>3 - \JoinCoffins\firstrowauthorblock[hc,b]\secondrowauthorblock[hc,t](0pt, -1.5\baselineskip) -\fi -\ifnum\value{authorno}>6 - \JoinCoffins\firstrowauthorblock[hc,b]\thirdrowauthorblock[hc,t](0pt, -1.5\baselineskip) -\fi -\centerline{\TypesetCoffin\firstrowauthorblock} %% in this instance, \centerline is better than \centering -} - -%% Flag for corresponding author (expecting just one, but if two enter both email addresses and flag both authors) -\newif\ifCA\CAfalse - -% allow for NO email address to be given by omitting second argument -\NewDocumentCommand{\CorrespondingAuthor}{m g}{% - \global\CAtrue% - \IfNoValueTF{#2}{% - \gdef\@CAsep{\relax}% - \gdef\@CAemail{\relax}% - }{% - \gdef\@CAsep{:\space}% - \gdef\@CAemail{#2}% - }% - \renewcommand*{\thefootnote}{\fnsymbol{footnote}}% - \ignorespaces#1\ignorespaces\footnotemark[1]% -} - %% Flag for joint first authors (two or more) -\newif\ifJA\JAfalse +\newif\ifac@JA\ac@JAfalse \NewDocumentCommand{\JointFirstAuthor}{}{% - \global\JAtrue% - \renewcommand*{\thefootnote}{\fnsymbol{footnote}}% - \ignorespaces\footnotemark[2]% -} - -%%% otherwise use new compact layout of authors -}{% i.e., this begins "else" - -%%%%%%%%%%%%%%%%%%%%%% New author layout (inline) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\NewCoffin{\AuthorBlock} -\NewCoffin{\AffiliationBlock} -\NewCoffin{\AffiliationsBlock} - -%% NB: \parbox width to \textwidth (full page) not \linewidth (single column) -\SetHorizontalCoffin\AffiliationsBlock{} -\NewDocumentCommand{\SetAuthors}{m}{% - \SetHorizontalCoffin\AuthorBlock{% - \parbox{\textwidth}{\centering\sffamily\bfseries\ignorespaces#1\ignorespaces}% - } + \global\ac@JAtrue% + $\bm{^\dagger}$% } - - -\def\@makefnmark{\hbox{\@textsuperscript{\sffamily\@thefnmark}}}% - -\NewDocumentCommand{\SetAffiliation}{m m}{% - \SetVerticalCoffin\AffiliationBlock{\textwidth}{% - \centering\sffamily\footnotemark[#1]#2\ignorespaces% - } - \JoinCoffins\AffiliationsBlock[hc,b]\AffiliationBlock[hc,t](0pt,-1pt) -} - - -%%% flag for corresponding author (usually just one, although you can have two by putting both email addresses -%%% into field and attaching to both authors -- footnote will only print only the email in the last occurrence) - %% Flag for corresponding author (expecting just one, but if two enter both email addresses and flag both authors) -\newif\ifCA\CAfalse +\newif\ifac@CA\ac@CAfalse -% allow for NO email address to be given by omitting the argument (g argument is deprecated, seems to have trouble with \IfNoValueTF) %% corrected spacing error 24 Jan 2020 -\NewDocumentCommand{\CorrespondingAuthor}{g}{% +\NewDocumentCommand\CorrespondingAuthor{m}{% Revised this command 29/12/20, to make the CA email mandatory but possibly empty \ignorespaces$\bm{^\ast}$% - \global\CAtrue% - % \IfNoValueTF{#1}{% + \global\ac@CAtrue% \ifblank{#1}{% \gdef\@CAsep{\relax}% \gdef\@CAemail{\relax}% @@ -798,122 +1142,285 @@ }% } -%%% Flag for joint first authors (two or more) -\newif\ifJA\JAfalse - -\NewDocumentCommand{\JointFirstAuthor}{}{% -\global\JAtrue% - $\bm{^\dagger}$% -} - -%%% Affiliation mark -\NewDocumentCommand{\affil}{m}{% - {\bfseries\footnotemark[#1]}% -} +%%%% option to use the traditional grid layout of authors or the inline style -%%% to deal with sequential notes as, e.g., "1,*", or "1,2,*" %%%%%%%%%% -\let\oldaffil\affil -\newcommand\nextToken\relax +\ifthenelse{\boolean{Oldauthors}}{% This command works better than \if... in this context. -\renewcommand\affil[1]{% - \oldaffil{#1}\futurelet\nextToken\isOthernote} + %%%%%%%%%%%%%%%%%%%% Gridded author layout %%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand\isOthernote{% - \ifx\CorrespondingAuthor\nextToken\textsuperscript{\sffamily\bfseries,}% - \else% - \ifx\JointFirstAuthor\nextToken\textsuperscript{\sffamily\bfseries,}% + \NewCoffin{\authorblock} + + %% Allows for up to fifteen author groups... if you need more authors, the edits should be obvious + %% You can put multiple authors above a single affiliation to reduce number of author blocks needed. + \NewCoffin{\firstrowauthorblock} + \SetHorizontalCoffin\firstrowauthorblock{} + \NewCoffin{\secondrowauthorblock} + \SetHorizontalCoffin\secondrowauthorblock{} + \NewCoffin{\thirdrowauthorblock} + \SetHorizontalCoffin\thirdrowauthorblock{} + \NewCoffin{\fourthrowauthorblock} + \SetHorizontalCoffin\fourthrowauthorblock{} + \NewCoffin{\fifthrowauthorblock} + \SetHorizontalCoffin\fifthrowauthorblock{} + + \newcounter{authorno} + \setcounter{authorno}{0} + + \newlength{\coffinsep}% horizontal space between coffins + \setlength{\coffinsep}{0.03\textwidth} + + \NewDocumentCommand\SetAuthorBlock{mm}{% + \addtocounter{authorno}{1}% + \SetVerticalCoffin{\authorblock}{0.3\textwidth}{% + \centering\sffamily% + \textbf{\ignorespaces#1\ignorespaces}\\ + #2% + } + \ifnum\value{authorno}=1 + \JoinCoffins\firstrowauthorblock[r,t]\authorblock[l,t] + \else + \ifnum\value{authorno}=2 + \JoinCoffins\firstrowauthorblock[r,t]\authorblock[l,t](\coffinsep,0pt) + \else + \ifnum\value{authorno}=3 + \JoinCoffins\firstrowauthorblock[r,t]\authorblock[l,t](\coffinsep,0pt) + \fi + \fi + \fi + \ifnum\value{authorno}=4 + \JoinCoffins\secondrowauthorblock[r,t]\authorblock[l,t] + \else + \ifnum\value{authorno}=5 + \JoinCoffins\secondrowauthorblock[r,t]\authorblock[l,t](\coffinsep,0pt) + \else + \ifnum\value{authorno}=6 + \JoinCoffins\secondrowauthorblock[r,t]\authorblock[l,t](\coffinsep,0pt) + \fi + \fi + \fi + \ifnum\value{authorno}=7 + \JoinCoffins\thirdrowauthorblock[r,t]\authorblock[l,t] \else - \ifx\affil\nextToken\textsuperscript{\sffamily\bfseries,}% + \ifnum\value{authorno}=8 + \JoinCoffins\thirdrowauthorblock[r,t]\authorblock[l,t](\coffinsep,0pt) + \else + \ifnum\value{authorno}=9 + \JoinCoffins\thirdrowauthorblock[r,t]\authorblock[l,t](\coffinsep,0pt) + \fi + \fi + \fi + \ifnum\value{authorno}=10 + \JoinCoffins\fourthrowauthorblock[r,t]\authorblock[l,t] + \else + \ifnum\value{authorno}=11 + \JoinCoffins\fourthrowauthorblock[r,t]\authorblock[l,t](\coffinsep,0pt) + \else + \ifnum\value{authorno}=12 + \JoinCoffins\fourthrowauthorblock[r,t]\authorblock[l,t](\coffinsep,0pt) + \fi + \fi + \fi + \ifnum\value{authorno}=13 + \JoinCoffins\fifthrowauthorblock[r,t]\authorblock[l,t] + \else + \ifnum\value{authorno}=14 + \JoinCoffins\fifthrowauthorblock[r,t]\authorblock[l,t](\coffinsep,0pt) + \else + \ifnum\value{authorno}=15 + \JoinCoffins\fifthrowauthorblock[r,t]\authorblock[l,t](\coffinsep,0pt) + \fi + \fi + \fi + \ifnum\value{authorno}>15 + \ClassWarningNoLine{asmeconf}{The class is programmed for up to 15 author blocks. If some of your authors are at the same institution, % + you may put more than one name above a single address. If you need more than 15 author blocks, try using the in-line author style % + instead of the [authorgrid] option} + \fi + } + + \NewDocumentCommand\ConstructAuthorBlock{}{% + \ifnum\value{authorno}>3 + \JoinCoffins\firstrowauthorblock[hc,b]\secondrowauthorblock[hc,t](0pt, -1.5\baselineskip) + \fi + \ifnum\value{authorno}>6 + \JoinCoffins\firstrowauthorblock[hc,b]\thirdrowauthorblock[hc,t](0pt, -1.5\baselineskip) + \fi + \ifnum\value{authorno}>9 + \JoinCoffins\firstrowauthorblock[hc,b]\fourthrowauthorblock[hc,t](0pt, -1.5\baselineskip) + \fi + \ifnum\value{authorno}>12 + \JoinCoffins\firstrowauthorblock[hc,b]\fifthrowauthorblock[hc,t](0pt, -1.5\baselineskip) + \fi + \centerline{\TypesetCoffin\firstrowauthorblock}%% in this instance, \centerline is better than \centering + } + + % Changed to follow syntax of the inline style, which is much easier to use! 29/12/2020 + % % allow for NO email address to be given by omitting second argument + % \NewDocumentCommand{\CorrespondingAuthor}{m g}{% + % \global\ac@CAtrue% + % \IfNoValueTF{#2}{% + % \gdef\@CAsep{\relax}% + % \gdef\@CAemail{\relax}% + % }{% + % \gdef\@CAsep{:\space}% + % \gdef\@CAemail{#2}% + % }% + % \ignorespaces#1\ignorespaces$\bm{^\ast}$%\footnotemark[1]% + % } + + %%% to deal with sequential notes as, e.g., "1,*", or "1,2,*" %%%%%%%%%% + % bug fixed 29/12/2020 + \newcommand\nextToken\relax + + \newcommand\isOthernote{% + \ifx\CorrespondingAuthor\nextToken\textsuperscript{\sffamily\bfseries,}% + \else% + \ifx\JointFirstAuthor\nextToken\textsuperscript{\sffamily\bfseries,}% \fi% \fi% - \fi% - \ignorespaces% -} - -\let\oldCorrespondingAuthor\CorrespondingAuthor -\renewcommand\CorrespondingAuthor[1]{% - \oldCorrespondingAuthor{#1}\futurelet\nextToken\isOthernote} + \ignorespaces% + } -\let\oldJointFirstAuthor\JointFirstAuthor -\renewcommand\JointFirstAuthor{% - \oldJointFirstAuthor\futurelet\nextToken\isOthernote} - -\let\oldfootnote\footnote -\renewcommand\footnote[1]{% - \oldfootnote{#1}\futurelet\nextToken\isOtherfnote} + \let\oldCorrespondingAuthor\CorrespondingAuthor + \renewcommand\CorrespondingAuthor[1]{% + \oldCorrespondingAuthor{#1}\futurelet\nextToken\isOthernote} + + \let\oldJointFirstAuthor\JointFirstAuthor + \renewcommand\JointFirstAuthor{% + \oldJointFirstAuthor\futurelet\nextToken\isOthernote} -\newcommand\isOtherfnote{% - \ifx\footnote\nextToken\textsu{\mdseries,}% - \fi% -} - -%%% - -\NewDocumentCommand{\SetAuthorBlock}{}{% - \let\savethefootnote\thefootnote - \JoinCoffins\AuthorBlock[hc,b]\AffiliationsBlock[hc,t](0pt,-\baselineskip) - \centerline{\TypesetCoffin\AuthorBlock} - \renewcommand*{\thefootnote}{\fnsymbol{footnote}} - \ifJA - \footnotetext[2]{\JAwords} - \fi - \ifCA - \footnotetext[1]{\CAwords\@CAsep\@CAemail} - \fi - \let\thefootnote\savethefootnote -} + \let\oldfootnote\footnote + \renewcommand\footnote[1]{% + \oldfootnote{#1}\futurelet\nextToken\isOtherfnote} + + \newcommand\isOtherfnote{% + \ifx\footnote\nextToken\textsu{\mdseries,}% + \fi% + } + +%%% otherwise use the new compact layout of authors +}{% i.e., this begins "else" + %%%%%%%%%%%%%%%%%%%%%% New author layout (inline) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \NewCoffin{\AuthorBlock} + \NewCoffin{\AffiliationBlock} + \NewCoffin{\AffiliationsBlock} + + %% NB: \parbox width to \textwidth (full page) not \linewidth (single column) + \SetHorizontalCoffin\AffiliationsBlock{} + \NewDocumentCommand\SetAuthors{m}{% + \SetHorizontalCoffin\AuthorBlock{% + \parbox{\textwidth}{\centering\sffamily\bfseries\ignorespaces#1\ignorespaces}% + } + } + + \def\@makefnmark{\hbox{\@textsuperscript{\sffamily\@thefnmark}}}% + + \NewDocumentCommand\SetAffiliation{mm}{% + \SetVerticalCoffin\AffiliationBlock{\textwidth}{% + \centering\sffamily\footnotemark[#1]#2\ignorespaces% + } + \JoinCoffins\AffiliationsBlock[hc,b]\AffiliationBlock[hc,t](0pt,-1pt) + } + + %%% Affiliation mark + \NewDocumentCommand{\affil}{m}{% + {\bfseries\footnotemark[#1]}% + } + + %%% to deal with sequential notes as, e.g., "1,*", or "1,2,*" %%%%%%%%%% + \let\oldaffil\affil + \newcommand\nextToken\relax + + \renewcommand\affil[1]{% + \oldaffil{#1}\futurelet\nextToken\isOthernote} + + \newcommand\isOthernote{% + \ifx\CorrespondingAuthor\nextToken\textsuperscript{\sffamily\bfseries,}% + \else% + \ifx\JointFirstAuthor\nextToken\textsuperscript{\sffamily\bfseries,}% + \else + \ifx\affil\nextToken\textsuperscript{\sffamily\bfseries,}% + \fi% + \fi% + \fi% + \ignorespaces% + } + + \let\oldCorrespondingAuthor\CorrespondingAuthor + \renewcommand\CorrespondingAuthor[1]{% + \oldCorrespondingAuthor{#1}\futurelet\nextToken\isOthernote} + + \let\oldJointFirstAuthor\JointFirstAuthor + \renewcommand\JointFirstAuthor{% + \oldJointFirstAuthor\futurelet\nextToken\isOthernote} + + \let\oldfootnote\footnote + \renewcommand\footnote[1]{% + \oldfootnote{#1}\futurelet\nextToken\isOtherfnote} + + \newcommand\isOtherfnote{% + \ifx\footnote\nextToken\textsu{\mdseries,}% + \fi% + } +%%% + \NewDocumentCommand\SetAuthorBlock{}{% + \let\savethefootnote\thefootnote + \JoinCoffins\AuthorBlock[hc,b]\AffiliationsBlock[hc,t](0pt,-\baselineskip) + \centerline{\TypesetCoffin\AuthorBlock} + } } %% end ifthenelse for Oldauthors -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% Make the title and author section -\NewDocumentCommand{\MakeTitlePage}{}{% -\twocolumn[ - \begin{@twocolumnfalse} - \HeaderConfName - \paperno - \papertitle - \vspace*{2\baselineskip} - \ifthenelse{\boolean{Oldauthors}}{% - \ConstructAuthorBlock}{% - \SetAuthorBlock} - \vspace*{3\baselineskip} - \end{@twocolumnfalse} -] -\let\@makefnmark\savemakefnmark -\renewcommand*{\thefootnote}{\fnsymbol{footnote}} -\ifJA - \footnotetext[2]{\JAwords} -\fi -\ifCA - \footnotetext[1]{\CAwords\@CAsep\@CAemail} -\fi -\let\thefootnote\savethefootnote +\NewDocumentCommand\MakeTitlePage{}{% + \twocolumn[ + \begin{@twocolumnfalse} + \HeaderConfName + \paperno + \papertitle + \vspace*{2\baselineskip} + \ifthenelse{\boolean{Oldauthors}}{% + \ConstructAuthorBlock}{% + \SetAuthorBlock} + \vspace*{3\baselineskip} + \end{@twocolumnfalse} + ] + \let\@makefnmark\savemakefnmark + \renewcommand*{\thefootnote}{\fnsymbol{footnote}} + \ifac@JA + \ifDefaultSups\relax\else\ifac@fontspec\def\f@@tn@te{blub}\fi\fi% https://tex.stackexchange.com/a/565263/46356 + \footnotetext[2]{\JAwords} + \fi + \ifac@CA + \footnotetext[1]{\CAwords\@CAsep\@CAemail} + \fi + \ifDefaultSups\relax\else + \ifac@fontspec\def\f@@tn@te{footnote}\fi + \fi + \let\thefootnote\savethefootnote } %%%%%%%%%% %% Provide compatibility with titling commands from standard LaTeX article class - \RenewDocumentCommand{\maketitle}{}{\MakeTitlePage} \RenewDocumentCommand{\title}{}{\PaperTitle} -\RenewDocumentCommand{\thanks}{m}{\relax} %% disabling this standard command, as it is inconsistent with the format +\RenewDocumentCommand{\thanks}{m}{\relax}% disabling this standard command (inconsistent with this format) %% Produces an unmarked footnote about the version date, to replace "date" -%% This is for editing and should not be used in the final draft -\NewDocumentCommand{\versionfootnote}{m}{\begin{NoHyper}\gdef\@thefnmark{}\@footnotetext{#1}\end{NoHyper}} +%% This tool is for editing and should not be used in the final draft +\NewDocumentCommand\versionfootnote{m}{\begin{NoHyper}\gdef\@thefnmark{}\@footnotetext{#1}\end{NoHyper}} -\RenewDocumentCommand{\date}{m}{\versionfootnote} %% in case someone wants to use \date this way. +\RenewDocumentCommand{\date}{m}{\versionfootnote{#1}}% if one wants to use \date this same way; fixed bug 14/01/2021 -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%% Special font definitions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Provide sans serif upright Greek letters, following a suggestion -%% to the class author by Michael Sharpe (March 2019). -%% Access sans serif Greek from newtxsf implementation of STIX fonts. -%% +%% Provide sans serif upright Greek letters, following a suggestion by Michael Sharpe (March 2019). +%% Following Sharpe's newtxsf implementation of the STIX fonts, under the LaTeX Project Public License. \DeclareSymbolFont{lettersAB}{U}{ntxsfmia}{m}{it} \SetSymbolFont{lettersAB}{bold}{U}{ntxsfmia}{b}{it} @@ -1002,7 +1509,156 @@ \DeclareMathSymbol{\varomegaup}{\mathalpha}{lettersAB}{36} \newcommand*{\sfvaromega}{\text{\ensuremath\varomegaup}} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%% Times-like fonts for specific languages %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\ifpdftex % Under lualatex, babel has problems with the following approach. Use [fontspec] option instead. + \ifac@vietnamese + \RequirePackage{substitutefont}% + \substitutefont{T5}{\rmdefault}{qtm}% Vietnamese is in T5 encoding, can use Tex Gyre Termes font (qtm); + %\substitutefont{T5}{\sfdefault}{qhv}% qhv = Heros (helvetica). We get the right font w/o loading this. + + % qcr = Cursor (monospaced) is poor match to inconsolata; qhv (the sf font) matches better, but isn't monospaced. + % From TeX Gyre Cursor .fd file by B. Jackowski and J. M. Nowacki, released under the GUST license + \begingroup + \nfss@catcodes + + \def\qcr@scale{s*[0.95]} + \DeclareFontFamily{T5}{\ttdefault}{}% not adjusting wordspacing + \DeclareFontShape{T5}{\ttdefault}{b}{sc}{<-> \qcr@scale t5-qcrb-sc}{} + \DeclareFontShape{T5}{\ttdefault}{b}{n}{<-> \qcr@scale t5-qcrb}{} + \DeclareFontShape{T5}{\ttdefault}{b}{scit}{<-> \qcr@scale t5-qcrbi-sc}{} + \DeclareFontShape{T5}{\ttdefault}{b}{it}{<-> \qcr@scale t5-qcrbi}{} + \DeclareFontShape{T5}{\ttdefault}{m}{sc}{<-> \qcr@scale t5-qcrr-sc}{} + \DeclareFontShape{T5}{\ttdefault}{m}{n}{<-> \qcr@scale t5-qcrr}{} + \DeclareFontShape{T5}{\ttdefault}{m}{scit}{<-> \qcr@scale t5-qcrri-sc}{} + \DeclareFontShape{T5}{\ttdefault}{m}{it}{<-> \qcr@scale t5-qcrri}{} + \DeclareFontShape{T5}{\ttdefault}{bx}{sc}{<->ssub * qcr/b/sc}{} + \DeclareFontShape{T5}{\ttdefault}{bx}{n}{<->ssub * qcr/b/n}{} + \DeclareFontShape{T5}{\ttdefault}{bx}{scit}{<->ssub * qcr/b/scit}{} + \DeclareFontShape{T5}{\ttdefault}{bx}{it}{<->ssub * qcr/b/it}{} + \DeclareFontShape{T5}{\ttdefault}{b}{sl}{<->sub * qcr/b/it}{} + \DeclareFontShape{T5}{\ttdefault}{m}{sl}{<->sub * qcr/m/it}{} + \DeclareFontShape{T5}{\ttdefault}{b}{scsl}{<->sub * qcr/b/scit}{} + \DeclareFontShape{T5}{\ttdefault}{m}{scsl}{<->sub * qcr/m/scit}{} + \endgroup + \fi + + \ifac@greek + %% Based on Artemisia fd files by A. Tsolomitis and ideas from substitutefont package by G. Milde, both LaTeX Public License. + \begingroup + \nfss@catcodes + + \def\artemisiasc@scaled{s*[0.95]} + \def\artemisia@scaled{s*[0.93]} + \DeclareFontFamily{LGR}{\rmdefault}{% + \fontdimen2\font=.25em + \fontdimen3\font=.2em + \fontdimen4\font=.1em + }% adjusted word spacing to match newtxtext... this is tighter. + \DeclareFontShape{LGR}{\rmdefault}{m}{n}{<-> \artemisia@scaled gartemisiarg6a}{} + \DeclareFontShape{LGR}{\rmdefault}{m}{it}{<-> \artemisia@scaled gartemisiai6a}{} + \DeclareFontShape{LGR}{\rmdefault}{b}{n}{<-> \artemisia@scaled gartemisiab6a}{} + \DeclareFontShape{LGR}{\rmdefault}{b}{it}{<-> \artemisia@scaled gartemisiabi6a}{} + \DeclareFontShape{LGR}{\rmdefault}{m}{sl}{<-> \artemisia@scaled gartemisiao6a}{} + \DeclareFontShape{LGR}{\rmdefault}{b}{sl}{<-> \artemisia@scaled gartemisiabo6a}{} + \DeclareFontShape{LGR}{\rmdefault}{m}{sc}{<-> \artemisiasc@scaled gartemisiasc6a}{} + \DeclareFontShape{LGR}{\rmdefault}{m}{sco}{<->\artemisiasc@scaled gartemisiasco6a}{} + + %% nextx names oblique sc as both scit and scsl. ("largesc" option of newtx is different font, not a scaling.) + \DeclareFontShape{LGR}{\rmdefault}{m}{scsl}{<->\artemisiasc@scaled gartemisiasco6a}{}% sco + \DeclareFontShape{LGR}{\rmdefault}{m}{scit}{<->\artemisiasc@scaled gartemisiasco6a}{}% sco + + \DeclareFontShape{LGR}{\rmdefault}{bx}{n}{<-> \artemisia@scaled gartemisiab6a}{} + \DeclareFontShape{LGR}{\rmdefault}{bx}{it}{<->\artemisia@scaled gartemisiabi6a}{} + \DeclareFontShape{LGR}{\rmdefault}{bx}{sl}{<->\artemisia@scaled gartemisiabo6a}{} + + % Sans Serif Greek font Kerkis + % Based on Kerkis fd file, by Antonis Tsolomitis, under the LaTeX Project Public License + \def\kerkissf@scaled{s*[0.95]} + \DeclareFontFamily{LGR}{\sfdefault}{}% not adjusting wordspacing + \DeclareFontShape{LGR}{\sfdefault}{m}{n}{<-> \kerkissf@scaled gksf7t}{} + \DeclareFontShape{LGR}{\sfdefault}{m}{it}{<->\kerkissf@scaled gksfi7t}{} + \DeclareFontShape{LGR}{\sfdefault}{m}{sl}{<->\kerkissf@scaled gksfi7t}{} + \DeclareFontShape{LGR}{\sfdefault}{m}{sc}{<->\kerkissf@scaled gksfsc7t}{} + \DeclareFontShape{LGR}{\sfdefault}{b}{n}{ <->\kerkissf@scaled gksfb7t}{} + \DeclareFontShape{LGR}{\sfdefault}{b}{it}{<->\kerkissf@scaled gksfbi7t}{} + \DeclareFontShape{LGR}{\sfdefault}{b}{sl}{<->\kerkissf@scaled gksfbi7t}{} + + \DeclareFontShape{LGR}{\sfdefault}{bx}{n}{ <-> \kerkissf@scaled gksfb7t}{} + \DeclareFontShape{LGR}{\sfdefault}{bx}{it}{ <-> \kerkissf@scaled gksfbi7t}{} + \DeclareFontShape{LGR}{\sfdefault}{bx}{sl}{ <-> \kerkissf@scaled gksfbi7t}{} + + %% Greek monospaced font, DejaVuSansMono + %% Based on DejaVu fd files by Pavel Farar, under the LaTeX Project Public License + \def\DejaVuSansMono@@scale{s*[0.85]}% + \DeclareFontFamily{LGR}{\ttdefault}{}% not adjusting wordspacing + \DeclareFontShape{LGR}{\ttdefault}{b}{it}{<-> \DejaVuSansMono@@scale DejaVuSansMono-BoldOblique-tlf-lgr}{} + \DeclareFontShape{LGR}{\ttdefault}{b}{n}{ <-> \DejaVuSansMono@@scale DejaVuSansMono-Bold-tlf-lgr}{} + \DeclareFontShape{LGR}{\ttdefault}{m}{it}{<-> \DejaVuSansMono@@scale DejaVuSansMono-Oblique-tlf-lgr}{} + \DeclareFontShape{LGR}{\ttdefault}{m}{n}{ <-> \DejaVuSansMono@@scale DejaVuSansMono-tlf-lgr}{} + + \DeclareFontShape{LGR}{\ttdefault}{m}{sl}{<-> \DejaVuSansMono@@scale DejaVuSansMono-TLF/m/it}{} + \DeclareFontShape{LGR}{\ttdefault}{b}{sl}{<-> \DejaVuSansMono@@scale DejaVuSansMono-TLF/b/it}{} + + \DeclareFontShape{LGR}{\ttdefault}{bx}{sl}{<->\DejaVuSansMono@@scale DejaVuSansMono-TLF/b/it}{} + \DeclareFontShape{LGR}{\ttdefault}{bx}{it}{<->\DejaVuSansMono@@scale DejaVuSansMono-TLF/b/it}{} + \DeclareFontShape{LGR}{\ttdefault}{bx}{n}{ <->\DejaVuSansMono@@scale DejaVuSansMono-TLF/b/n}{} + + \endgroup + \fi + + \ifac@cyrillic + %% Paratype fonts for cyrillic, maintained by Pavel Farar, under Latex Project Public License + \begingroup + \nfss@catcodes + + \def\PTSerif@@scale{s*[0.95]}% had had 0.94... + \DeclareFontFamily{T2A}{\rmdefault}{}% not adjusting wordspacing, since it matches newtxtext as is + \DeclareFontShape{T2A}{\rmdefault}{m}{n}{ <->\PTSerif@@scale PTSerif-Regular-tlf-t2a}{} + \DeclareFontShape{T2A}{\rmdefault}{m}{it}{<->\PTSerif@@scale PTSerif-Italic-tlf-t2a}{} + \DeclareFontShape{T2A}{\rmdefault}{b}{n}{ <->\PTSerif@@scale PTSerif-Bold-tlf-t2a}{} + \DeclareFontShape{T2A}{\rmdefault}{b}{it}{<->\PTSerif@@scale PTSerif-BoldItalic-tlf-t2a}{} + \DeclareFontShape{T2A}{\rmdefault}{m}{ui}{<->\PTSerif@@scale PTSerif-UprightItalic-tlf-t2a}{} + \DeclareFontShape{T2A}{\rmdefault}{m}{sl}{<->\PTSerif@@scale PTSerif-Slanted-tlf-t2a}{} + \DeclareFontShape{T2A}{\rmdefault}{b}{ui}{<->\PTSerif@@scale PTSerif-BoldUprightItalic-tlf-t2a}{} + \DeclareFontShape{T2A}{\rmdefault}{b}{sl}{<->\PTSerif@@scale PTSerif-BoldSlanted-tlf-t2a}{} + + \DeclareFontShape{T2A}{\rmdefault}{bx}{n}{<->ssub * PTSerif-TLF/b/n}{} + \DeclareFontShape{T2A}{\rmdefault}{bx}{it}{<->ssub * PTSerif-TLF/b/it}{} + \DeclareFontShape{T2A}{\rmdefault}{bx}{ui}{<->ssub * PTSerif-TLF/b/ui}{} + \DeclareFontShape{T2A}{\rmdefault}{bx}{sl}{<->ssub * PTSerif-TLF/b/sl}{} + + \def\PTSans@@scale{s*[0.94]}% + \DeclareFontFamily{T2A}{\sfdefault}{}% not adjusting wordspacing + \DeclareFontShape{T2A}{\sfdefault}{b}{it}{<->\PTSans@@scale PTSans-BoldItalic-tlf-t2a}{} + \DeclareFontShape{T2A}{\sfdefault}{b}{n}{<-> \PTSans@@scale PTSans-Bold-tlf-t2a}{} + \DeclareFontShape{T2A}{\sfdefault}{m}{it}{<->\PTSans@@scale PTSans-Italic-tlf-t2a}{} + \DeclareFontShape{T2A}{\sfdefault}{m}{n}{<-> \PTSans@@scale PTSans-Regular-tlf-t2a}{} + \DeclareFontShape{T2A}{\sfdefault}{c}{n}{<-> \PTSans@@scale PTSans-Narrow-tlf-t2a}{} + \DeclareFontShape{T2A}{\sfdefault}{bc}{n}{<->\PTSans@@scale PTSans-NarrowBold-tlf-t2a}{} + + \DeclareFontShape{T2A}{\sfdefault}{m}{sl}{<->ssub * PTSans-TLF/m/it}{} + \DeclareFontShape{T2A}{\sfdefault}{b}{sl}{<->ssub * PTSans-TLF/b/it}{} + \DeclareFontShape{T2A}{\sfdefault}{bx}{sl}{<->ssub * PTSans-TLF/b/it}{} + \DeclareFontShape{T2A}{\sfdefault}{bx}{it}{<->ssub * PTSans-TLF/b/it}{} + \DeclareFontShape{T2A}{\sfdefault}{bx}{n}{<->ssub * PTSans-TLF/b/n}{} + + %% the tt cyrillic is slightly larger than the latin characters. + \def\PTMono@@scale{s*[0.92]}% + \DeclareFontFamily{T2A}{\ttdefault}{}% not adjusting wordspacing + \DeclareFontShape{T2A}{\ttdefault}{m}{n}{<-> \PTMono@@scale PTMono-Regular-tlf-t2a}{} + \DeclareFontShape{T2A}{\ttdefault}{b}{n}{<-> \PTMono@@scale PTMono-Bold-tlf-t2a}{} + \DeclareFontShape{T2A}{\ttdefault}{m}{sl}{<->\PTMono@@scale PTMono-Slanted-tlf-t2a}{} + \DeclareFontShape{T2A}{\ttdefault}{b}{sl}{<->\PTMono@@scale PTMono-BoldSlanted-tlf-t2a}{} + + \DeclareFontShape{T2A}{\ttdefault}{bx}{n}{<->ssub * PTMono-TLF/b/n}{} + \DeclareFontShape{T2A}{\ttdefault}{bx}{sl}{<->ssub * PTMono-TLF/b/sl}{} + + \endgroup + \fi +\fi + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \endinput %% diff --git a/macros/latex/contrib/asmeconf/author-grid-style.pdf b/macros/latex/contrib/asmeconf/author-grid-style.pdf deleted file mode 100644 index a6f3ca6d12..0000000000 Binary files a/macros/latex/contrib/asmeconf/author-grid-style.pdf and /dev/null differ diff --git a/macros/latex/contrib/asmeconf/examples/CONTRACTOR-copyright-asmeconf-template.pdf b/macros/latex/contrib/asmeconf/examples/CONTRACTOR-copyright-asmeconf-template.pdf new file mode 100644 index 0000000000..27a247a589 Binary files /dev/null and b/macros/latex/contrib/asmeconf/examples/CONTRACTOR-copyright-asmeconf-template.pdf differ diff --git a/macros/latex/contrib/asmeconf/examples/GOVT-copyright-asmeconf-template.pdf b/macros/latex/contrib/asmeconf/examples/GOVT-copyright-asmeconf-template.pdf new file mode 100644 index 0000000000..e52d70accb Binary files /dev/null and b/macros/latex/contrib/asmeconf/examples/GOVT-copyright-asmeconf-template.pdf differ diff --git a/macros/latex/contrib/asmeconf/examples/asmeconf-authorgrid-example.pdf b/macros/latex/contrib/asmeconf/examples/asmeconf-authorgrid-example.pdf new file mode 100644 index 0000000000..3827579635 Binary files /dev/null and b/macros/latex/contrib/asmeconf/examples/asmeconf-authorgrid-example.pdf differ diff --git a/macros/latex/contrib/asmeconf/examples/asmeconf-authorgrid-example.tex b/macros/latex/contrib/asmeconf/examples/asmeconf-authorgrid-example.tex new file mode 100644 index 0000000000..4377134c69 --- /dev/null +++ b/macros/latex/contrib/asmeconf/examples/asmeconf-authorgrid-example.tex @@ -0,0 +1,650 @@ +% !TEX encoding = UTF-8 Unicode +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% This file is asmeconf-template.tex, a template to format ASME Conference papers according to +%% the requirements on ASME's conference web pages, and including hypertext support for the pdf. +%% +%% This file is version 1.22 dated 2021/1/14 +%% +%% As of version 1.11, this template follows ASME's newer conference guidelines first posted July 2019. +%% The new guidelines have changed the requested author block formatting to be inline. +%% (This template continues to support the traditional grid format as a package option.) +%% Nomenclature now follows the abstract. Abstract text is set in italics. +%% +%% Author: John H. Lienhard V +%% Department of Mechanical Engineering +%% Massachusetts Institute of Technology +%% Cambridge, MA 02139-4307 USA +%% +%% Class options include: +%% +%% * Math options from M. Sharpe's newtxmath package: upright integrals [upint]; +%% * [varvw] for a v and w that are better distinguished from greek nu; and also +%% * [subscriptcorrection, smallerops, varg, frenchmath, varbb, cmbraces, slantedGreek,...] +%% * See newtx documentation for descriptions (at CTAN: http://ctan.org, v1.6 or higher best). +%% +%% * Many options for calligraphic, script, and fraktur fonts from the mathalfa package; the +%% * example shown here is: [mathalfa=cal=euler] to use Euler font for \mathcal. +%% * Some other options for cal are: dutchcal, zapfc, cm (default), boondox,... +%% * frak (fraktur), bb (blackboard bold), scr (script) may also be chosen this way. +%% * For details, refer to mathalfa documentation (at CTAN: http://ctan.org). +%% +%% * Options to: omit the ASME copyright footer [nofoot]; +%% use government employee copyright notice [govt]; +%% use government contractor copyright notice [contractor] +%% +%% * An option to balance the heights of columns on the last page [balance]. +%% * This option is NOT compatible with the [lineno] option. +%% +%% * An option to include line numbers [lineno]. You must *run twice* for proper placement of the line numbers. +%% * The lineno package does not number titles, footnotes, captions, or tables. +%% * This option will disable balancing column height on final page if that option has been invoked. +%% * The lineno package won't always number the lines preceding displayed math in a paragraph because +%% * paragraph has not ended. See that package's documentation for macros to address this problem, or +%% * just leave a blank line above the displayed equation while you are editing and then remove the +%% * blank line and [lineno] option when you move to your final version. +%% +%% * An option to use the traditional grid arrangement of author names [authorgrid]. See Appendix B for usage, +%% * because the authors and affiliations must be entered differently in this case. (Same as former option [oldauthors]) +%% +%% * Options for PDF/A compliance. [pdf-a] will produce PDF/A-3u compliance with sRGB OutputIntent. +%% * [pdfapart= 1 or 2 or 3] and [pdfaconformance= b or u] can enable levels 1b, 2b, 2u, and 3b. +%% +%% * Option to use superiors font from newtxtext for footnotes [nodefaultsups] and +%% * for slightly larger small capitals, [largesc], also from newtxtext. +%% +%% * An option to allow hyphenation of the typewriter font [hyphenate], from inconsolata package. +%% * Hyphenation is normally suppressed for typewriter mode because it is often used for code. +%% * To replace the default variable word spacing by monospacing, use the option [mono]. +%% * To get a zero without a slash, use [var0] +%% +%% * Options (used by the babel package) to include passages in languages other than English (e.g., a translation +%% * of the abstract). Languages are called as options, e.g. [french], [spanish], [greek], [russian], etc. +%% * See Appendix C for details. +%% +%% The use of commands defined or modified by the asmeconf class is illustrated throughout this file. In particular, +%% ASME requires capitalized, sans-serif section headings, and as a result some care is needed when using macros +%% in section headings, as also illustrated below. +%% + %========================================================= +%% +%% LICENSE: +%% +%% Copyright (c) 2021 John H. Lienhard +%% +%% Offered under the MIT license: https://ctan.org/license/mit +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +%% Class options are described above. If you are not using the languages options, remove them. + +\documentclass[authorgrid,upint,subscriptcorrection,varvw,mathalfa=cal=euler,pdf-a,balance,spanish,french,greek,russian,colorlinks]{asmeconf} % <=== remove colorlinks before your *final* submission to ASME! But keep it for other purposes. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%% Fields to be completed %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%% pdf metadata %%%%%%%%%%%% +%%%%% The user should edit %%%%%%%%%%%% + +\hypersetup{% + pdftitle={ASME Conference Paper Template}, % <=== change to YOUR pdf file title + pdfkeywords={ASME, Paper, Template, \LaTeX, Research}, % <=== change to YOUR pdf keywords + pdfauthor={John H. Lienhard}, % <=== change to YOUR name[s]! +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{document} +% Change these fields to the right content for your conference. +% You can comment these out if for some reason you don't want a header. +% Use title case (first letters capitalized), not all capitals + +\ConfName{Proceedings of the \texttt{asmeconf}\linebreak International Examples Congress and Exposition} +\ConfAcronym{AIECE21} +\ConfDate{November 1-4, 2021} +\ConfCity{Virtual Conference, Online} +\PaperNo{AIECE2021-0003} + + +% Units of measure and other specialty lowercase terms in the title should be +% enclosed in \NoCaseChange{...} to maintain lower case type +% LaTeX will automatically set the rest of the title in all capital letters. + +\title{Place Title Here: Place Subtitle After Colon} % <=== change to YOUR title + +%%% This is the set-up for the traditional author block style (a grid of blocks) using option [authorgrid] + +% Change to your name[s] and addresses, in the desired order of authors. Up to nine author blocks. +% Note usage below for joint first authors and for corresponding author. +% First name, middle initial, last name +% Use title case (upper and lower case letters) +% (Most of the names below are not real people, just very common names.) + +\SetAuthorBlock{Luis Hern\'{a}ndez\JointFirstAuthor}{Institution or Company Name \\ City, State} +\SetAuthorBlock{Maria Silva\JointFirstAuthor}{Institution or Company Name \\ City, Province, Canada} + +\SetAuthorBlock{Henry Tudor, Catherine Parr\CorrespondingAuthor{}}{Hampton Court Palace \\ Richmond, England} +\SetAuthorBlock{Jinsoo Kim}{Institution or Company Name \\ City, Country} +\SetAuthorBlock{Yusuf Yilmaz}{Institution or Company Name \\ City, Country} + +\SetAuthorBlock{Amelia Smith}{Institution or Company Name \\ City, Country} +\SetAuthorBlock{Aadhya Acharya}{Institution or Company Name \\ City, Country} +\SetAuthorBlock{Omar Abu Bakr}{Institution or Company Name \\ City, Country} + +% Give an empty argument for \CorrespondingAuthor{} if you are putting email address into the address block. +% Can also put multiple emails into the argument and use command more than once for multiple +% corresponding authors. Only the *last* set of emails issued will be printed. + +\SetAuthorBlock{John H.\ Lienhard V\CorrespondingAuthor{lienhard@mit.edu, kate@thepalace.com}\JointFirstAuthor}{% +Massachusetts Institute of Technology \\ Cambridge, MA} + +% be sure to issue [authorgrid] option when using this (otherwise your authorblock will not display!) + + +\maketitle + +%%% Use this footnote for tracking various versions of your draft. Change text to suit your own needs. +%%% REMOVE from final version of your paper. +%%% \date{..} calls the same command. + +\versionfootnote{Documentation for \texttt{asmeconf.cls}. Version \versionno; \today.}% <=== Delete before final submission. + + +%%% Change these to your keywords. Keywords are automatically printed at the end of the abstract. +%%% This command MUST COME BEFORE the end of the abstract. +%%% If you don't want keywords, leave the argument of \keywords{} empty (or use the abstract* environment) + +\keywords{ASME, Paper, Template, \LaTeX, Research} + +%%%%%%%%%%%%%%%%%%%%% End of fields to be completed. Now write! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +%%%%%%%%% Abstract %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% Abstract should be no more than 200 words +\begin{abstract} +This paper is an example of and a template for typesetting ASME Conference Papers in {\upshape\LaTeX} using the {\upshape\texttt{asmeconf}} class. This class follows ASME guidelines for margins, fonts, headings, captions, and reference formats as of 2020. The class is intended to be used with the {\upshape\texttt{asmeconf.bst} \hologo{BibTeX}} style, which is part of this distribution. The class incorporates the {\upshape\texttt{hyperref}} package, so that pdfs will contain hyperlinks, bookmarks, and metadata, and references can include the DOI and URL fields. Links may be colored, for online use, or black, for publication. The class enables inline author names, following ASME's current style, but can also produce the traditional grid style. Options include line numbering, final column balancing, various math options, government copyright, and archivability (PDF/A). In addition, section headers may contain mathematics, references, citations, and footnotes. The class is compatible with {\upshape\hologo{pdfLaTeX}} or {\upshape\hologo{LuaLaTeX}}. +\end{abstract} + +%%%%%%%%% NOMENCLATURE (OPTIONAL) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% To change space between the symbols and definitions, use \begin{nomenclature}[Xcm] where X is a number +%% The unit cm can be replaced by any LaTeX unit of dimension: pt, in, ex, em, pc, etc. +%% Default is 2em. + +%% \EntryHeading{Greek letters} produces an italicized subheading, e.g., \EntryHeading{Greek letters} +%% (Leaving off the second argument of \entry, e.g. \entry{Greek letters}, has the same effect) + +\begin{nomenclature} +\EntryHeading{Roman letters} +\entry{$k$}{Thermal conductivity [W m$^{-1}$ K$^{-1}$]} +\entry{$\vec{q}$}{Heat flux vector [W m$^{-2}$]} + +\EntryHeading{Greek letters} +\entry{$\alpha$}{Thermal diffusivity [m$^2$ s$^{-1}$]} +\entry{$\nu$}{Kinematic viscosity [m$^2$ s$^{-1}$]} + +\EntryHeading{Dimensionless groups} +\entry{Pr}{Prandtl number, $\nu/\alpha$} +\entry{Sc}{Schmidt number, $\nu/\mathcal{D}_{1,2}$} + +\EntryHeading{Superscripts and subscripts} +\entry{b}{bulk value} +\entry{$\infty$}{free stream value} +\end{nomenclature} + + +%%%%%%%%% BODY OF PAPER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Introduction} +The \texttt{asmeconf} class typesets papers with margins, fonts, headings, captions, and reference formats that follow the specifications for conference papers of the American Society of Mechanical Engineers (ASME). In contrast to older ASME \LaTeX\ templates, \texttt{asmeconf} will set internal and external hyperlinks, and the pdf file will contain bookmarks and metadata. Many other useful features have been incorporated. This class is not a publication of ASME, but the author has published in ASME conferences since 1983. + +The \texttt{.tex} file may be written using standard \LaTeX\ commands, although some specific initial commands are needed to format the blocks containing the author[s], title, and abstract. This class loads a number of other packages, all of which are contained in up-to-date versions of \href{https://www.tug.org/texlive/}{\TeX\ Live}, \href{http://www.tug.org/mactex/}{Mac\TeX}, and similar platforms. If you find that you are missing one of these packages, you may obtain it at no cost from CTAN (\href{http://ctan.org}{ctan.org}). + +\subsection{Essential Initial Commands} +To begin, fill in the fields to be completed at top of the \texttt{asmeconf-template.tex} file. These fields include the headers for your conference and your paper number. Specified metadata will be placed into the pdf file itself. +The title should be placed into \verb|\title{..}|. + +Put author names into the \verb|\SetAuthors{name, name,...}| command in the desired order; follow the syntax illustrated \texttt{asmeconf-template.tex} file. Put each distinct address sequentially into a separate \verb|\SetAffiliation{n}{address}|, where $n = 1,2,\ldots$ Tag each author with an affiliation by putting \verb|\affil{n}| after that author's name inside the \verb|\SetAuthors{..| command. + +Keep author addresses short. List the author institution, and the City, State (US authors), City, Province, Canada (Canadian authors), or City, Country (other international authors). + +One author (or more) may be designated as the corresponding author by placing \verb|\CorrespondingAuthor{email}| after \verb|\affil{n}|. Two or more authors may be joint first authors by putting \verb|\JointFirstAuthor| after \verb|\affil{n}|. + +After setting up the headers, authors, and title, issue the \verb|\maketitle| command. + +The abstract text must be placed into \verb|\begin{abstract}| \ldots \verb|\end{abstract}|. The abstract will automatically be italicized. Keywords may be included using the \verb|\keywords{..}| command. The \texttt{keyword} command \textit{must} be issued before the abstract environment. + + +%%%%%%%%%%%%% begin figure %%%%%%%%%%%%%%%%% + +%% captions go below figures + +\begin{figure}[t] +\centering\includegraphics[width=0.7\linewidth]{sample-figure-1.pdf} +\caption{Figure caption with math, eqn.~\eqref{eqn:fourier}: $z = (r,\phi)$ \cite{Lienhard2019b}\label{fig:1}} +\end{figure} + +%%%%%%%%%%%%% end figure %%%%%%%%%%%%%%%%%%% + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Referring to Citations, Figures, and Equations} +Citations are automatically numbered \cite{ning2002}. They should be inserted at the appropriate point using a \verb|\cite{ref}| command~\cite{gibson2008,stevens1999}. The citations will be automatically sorted and compressed if they are given in a set \cite{stevens1999,ning2002,gibson2008,wions2005,smith2002,watson1982}. +A specific reference may be named with an abbreviation, as in Ref.~\cite{watson1982}. +See the \texttt{asmeconf-sample.bib} file and Sect.~\ref{sec:references} for examples of how to enter your references. + +For ASME conference papers, the labels Equation and Figure should be abbreviated when they do not start a sentence, as in Eq.~\eqref{eqn:dw} and Fig.~\ref{fig:1}. Figure~\ref{fig:1} is spelled out when it starts a sentence. Equation~\eqref{eqn:dw} is spelled out when it starts a sentence. + +Equations are typeset in the usual way and will be automatically numbered. The class file loads the \texttt{amsmath} and \texttt{mathtools} packages. Further, the \texttt{newtxmath} package used for the math fonts includes many additional features (see Sect.~\ref{sec:moremath}). +\begin{equation}\label{eqn:fourier} +\vec{q} = -k\nabla T +\end{equation} + +ASME prefers SI units. (U.S.\ style units may follow in parentheses.) Be sure to put all symbols into the nomenclature list, including their units. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Use title case for subsections and subsubsections + +\section{Section Headings and Captions} +ASME requires that section headings and captions be set in an uppercase, sans serif font. The class will do this automatically. You can place \verb|\cite{..}|, \verb|\ref{..}|, \verb|\label{..}|, and mathematics into headings and captions directly, as you would in the main text. Do not enclose them braces, e.g.\ \verb|{\cite{..}}|, which will cause errors. You can place \verb|\footnote{..}| into headings, but not into captions.\footnote{See \texttt{tex-stackexchange} for various approaches to footnotes in captions, if they seem necessary. For footnotes in tables, use the \texttt{tablefootnote} package.}\footnote{Sequential footnotes are automatically separated by a comma.} + +Text in section headings and captions will not be capitalized if enclosed in a \verb|\NoCaseChange{..}| command. + +Sections may either be numbered or left unnumbered. + +Simple mathematical expressions can be used in either captions or section headings. For a section heading that includes more complicated math (and macros), you may use the optional argument of \verb|\section[..]{..}| to create a pdf bookmark without losing characters or producing warnings or errors. See the \texttt{asmeconf-template.tex} source file for examples of this procedure. These bookmarks should usually be text expressions, although some math is supported. + +If you wish to override the default math format in captions, put \verb|\mathversion{normal}| in the caption. + +\subsection{Subsection and Sub-subsection Headings} +Subsections and sub-subsection headings should be entered in title case, with the first letter of primary words capitalized. Sub-subsections (i.e., paragraphs) are never numbered. + + +%%%%%%%%%%%%%%% begin simple table %%%%%%%%%%%%%%%%%%%%%%%%%% + +%% captions go above tables + +\begin{table}[t] +\caption[Table]{A simple table\label{tab:1}} +\centering{% +\begin{tabular}{l l r} +\toprule +Experiment & $u$ [m/s] & $T$ [\textdegree C] \\ +\midrule +Run 11 & 12.5 & 103.4 \\ +Run 12 & 24 & 68.3 \\ +\bottomrule +\end{tabular} +} +\end{table} + +%%%%%%%%%%%%%%%% end table %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%% begin more complicated table %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{table}[t] +\caption{Table with more complicated columns}\label{tab:2}% +\centering{% +\begin{tabular}{!{\hspace*{0.5cm}} >{\raggedright\hangindent=1em} p{3cm} d{3.3} @{\hspace*{1cm}} d{3.3} !{\hspace*{0.5cm}}} +\toprule +Experiment & \multicolumn{1}{c@{\hspace*{1cm}}}{$u$ [m/s]} & \multicolumn{1}{c!{\hspace*{0.5cm}}}{$T$ [\textdegree C]} \\ +\midrule +The first test we ran this morning & 124.3 & 68.3 \\ +The second test we ran this morning & 82.50 & 103.46 \\ +Our competitor's test & 72.321 & 141.384 \\ +\bottomrule +\end{tabular} +} +\end{table} + +%%%%%%%%%%%%%%%% end table %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%% begin two column table %%%%%%%%%%%%%%%%%% +\begin{table*} +\caption{A table spanning two columns\label{tab:3}}% +\centering{% +\begin{tabular*}{0.8\textwidth}{@{\hspace*{1.5em}}@{\extracolsep{\fill}}ccc!{\hspace*{3.em}}ccc@{\hspace*{1.5em}}} +\toprule +\multicolumn{1}{@{\hspace*{1.5em}}c}{$x$\rule{0pt}{11pt}} & +\multicolumn{1}{c}{$\textrm{erf}(x)$} & +\multicolumn{1}{c!{\hspace*{3.em}}}{$\textrm{erfc}(x)$} & +\multicolumn{1}{c}{$x$} & +\multicolumn{1}{c}{$\textrm{erf}(x)$} & +\multicolumn{1}{c@{\hspace*{1.5em}}}{$\textrm{erfc}(x)$} \\ \midrule +0.00 & 0.00000 & 1.00000 & 1.10 & 0.88021 & 0.11980\rule{0pt}{11pt} \\ +0.05 & 0.05637 & 0.94363 & 1.20 & 0.91031 & 0.08969 \\ +0.10 & 0.11246 & 0.88754 & 1.30 & 0.93401 & 0.06599 \\ +0.15 & 0.16800 & 0.83200 & 1.40 & 0.95229 & 0.04771 \\ +0.20 & 0.22270 & 0.77730 & 1.50 & 0.96611 & 0.03389 \\ +0.30 & 0.32863 & 0.67137 & 1.60 & 0.97635 & 0.02365 \\ +0.40 & 0.42839 & 0.57161 & 1.70 & 0.98379 & 0.01621 \\ +0.50 & 0.52050 & 0.47950 & 1.80 & 0.98909 & 0.01091 \\ +0.60 & 0.60386 & 0.39614 & 1.82\makebox[0pt][l]{14} & 0.99000 & 0.01000 \\ +0.70 & 0.67780 & 0.32220 & 1.90 & 0.99279 & 0.00721 \\ +0.80 & 0.74210 & 0.25790 & 2.00 & 0.99532 & 0.00468 \\ +0.90 & 0.79691 & 0.20309 & 2.50 & 0.99959 & 0.00041 \\ +1.00 & 0.84270 & 0.15730 & 3.00 & 0.99998 & 0.00002 \\[2pt] +\bottomrule\end{tabular*} +} +\end{table*} + +%%%%%%%%%%%%%%%%% end two column table %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Tables and Figures} + +Table \ref{tab:1} is an example of a simple table. Table captions should be placed above tables. +The class loads the \texttt{booktabs} package (used for horizontal rules in both Table \ref{tab:1} and \ref{tab:2}), and the \texttt{array} and \texttt{dcolumn} packages which provide extended capabilities for columns in the \texttt{tabular} environment (used in Table \ref{tab:2}). Table \ref{tab:3} is an example of a table that spans two columns. Two column tables (and figures) will always float to the top of a later page. + +Figure captions go below figures. Figure~\ref{fig:2} is an example of a figure that spans two columns and includes subfigures. The text in figures (and tables) should be no smaller than 6~point type. Images in figures are handled by the standard \texttt{graphicx} package. + +Landscape figures and tables may be produced at full-page size by putting \verb|\usepackage[figuresright]{rotating}| in your \texttt{.tex} file's preamble and using the \texttt{sidewaystable*} and \texttt{sidewaysfigure*} environments~\cite{fairbairns}. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Reference Formatting with \NoCaseChange{\texttt{asmeconf.bst}}\footnote{If you have text in a section heading or caption that you do not want to be capitalized, such as an SI unit, enclose it in a \texttt{\textbackslash NoCaseChange} command.}}\label{sec:references} + +The {\upshape\texttt{asmeconf.bst}} \hologo{BibTeX} style follows the reference styles shown on ASME's conference web site in 2020.\footnote{\texttt{asmeconf.bst} is intended as a replacement for the old \texttt{asmems4.bst}, which does not follow ASME's current reference formats or support DOI and URL.} +Examples for these and many other cases are given in the \texttt{asmeconf-sample.bib} file, which is part of this distribution. Citations and references are managed by the standard \texttt{natbib} package. Nevertheless, a few comments are necessary. + +%% sub-subsections should *not* be numbered + +\subsubsection*{DOI, URL, and eprint} Include DOI numbers when they are available. URL's may alternatively be given. ASME requests that URLs point to a document's abstract. + +Elementary support for \texttt{eprint} numbers is also included, generating a url at the end of the citation. The \texttt{archive} type may be specified using the macros \texttt{arxiv, googlebooks, hdl, jstore, oclc}, or \texttt{pubmed} (e.g., \texttt{archive=hdl}, \textit{without} braces). Both \texttt{eprint} and \texttt{archive} fields \textit{must} be given. Other root urls may be invoked using \verb|archive = {http://another.url.org/}|. + +\subsubsection*{Online Sources} A bibliography entry \verb|@online{..| is included for citation of online sources, such as web pages. A \texttt{url} or \texttt{eprint} with \texttt{archive} must be included. See the examples of use in the \texttt{asmeconf-sample.bib} file. + +\subsubsection*{Date Accessed} The \verb|urldate={..}| field may be used to provide the date on which a given url was accessed. By default, the text printed will be \texttt{Accessed `date',}. The word ``Accessed'' may be changed using the \verb|urltype={..}| field. + +\subsubsection*{Conference Location and Date} For the entry types \verb|@inproceeedings{..| and \verb|@proceeedings{..|, you may include \verb|venue={..}| and \verb|eventdate={..}| to specify the city and the date of a conference. + +\subsubsection*{Capitalization of Titles} ASME's bibliography style requires that document titles be in title case. The first letters of principal words are capitalized. Do this in the \texttt{.bib} file. + + + +%%%%%%%%%%%%%%%%% begin two column figure %%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{figure*} +\begin{subfigure}[t]{0.5\textwidth} % subfigure is basically the same as minipage +\vbox{ +\vspace*{1.7em} +\centering{ + \includegraphics{sample-figure-2a.pdf} +} +\vspace*{1.7em} +} +\subcaption{Interior region\label{fig:interior-region}} +\end{subfigure}% +%%%%%%%%%%%%% no spaces or line breaks between these two subfigures +\begin{subfigure}[t]{0.5\textwidth} +\centering{% +\includegraphics{sample-figure-2b.pdf} +\subcaption{Exterior region\label{fig:exterior-region}} +}\end{subfigure} +\caption{A figure with two subfigures \cite{Lienhard2019b}}\label{fig:2} +\end{figure*} + +%%%%%%%%%%%%%%%%%%% end two column figure %%%%%%%%%%%%%%%%%%%%%%%%%% + + +%%%%%%%%%%%%%%% MORE ON MATH %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Dealing with complicated math in a section or subsection heading: +%% the optional argument to \section will provide the pdf bookmark +%% without losing characters or producing warnings/errors. +%% +%% In this heading, letter u is forced to be upright with \mathrm{u} +%% +\section[More on math: u\cdot\omega=0]{More on math: $\vec{\mathrm{u}}\cdot\vec{\omega}=0$}\label{sec:moremath} + +In most cases, the need for a wide equation can be eliminated by using one of the multiline equation environments defined by +\texttt{amsmath}, such as \texttt{align}, \texttt{split}, or \texttt{multline}~\cite{amsmath}. The following equation is set with the +\texttt{multline} environment: +\begin{multline}\label{eqn:energy} +\frac{\partial}{\partial t}\left[\rho\bigl(e + \lvert\vec{u}\rvert^2\big/2\bigr)\right] + \nabla\cdot\left[\rho\bigl(h + \lvert\vec{u}\rvert^2\big/2 \bigr)\vec{u}\right] \\ + ={}-\nabla \cdot \vec{q} + \rho \vec{u}\cdot\vec{g}+ \frac{\partial}{\partial x_j}\bigl(d_{ji}u_i\bigr) + \dot{Q}_v +\end{multline} +An example using \texttt{align} appears in Appendix~\ref{appendix:a}. + +An alternative solution may be to set large equations into two-column-wide tables or figures. While a package exists for setting equations that span two columns (\texttt{widetext.sty}), that code is erratic in relation to floats and page breaks. + +Math italics are used for roman and greek letters by default. If you want an upright letter in math, you can use the relevant math alphabet, e.g., \verb|\mathrm, \mathbf, \mathsf|: +\begin{equation}\label{eqn:dw} +\vec{F} = m \vec{a} \quad\textrm{or}\quad \vec{\mathrm{F}} = m \vec{\mathrm{a}} \quad\textrm{or}\quad \mathbf{F} = m \mathbf{a} \quad\textrm{or}\quad \vec{\mathsf{F}} = m \vec{\mathsf{a}} +\end{equation} +To get additional symbols in bold math, you can use \verb|\mathversion{bold}| or the \verb|\bm{..}| macro from the \texttt{bm} package, which is loaded by the class. + +The class file also provides upright sans-serif greek letters with \verb|\sfalpha| and similar expressions (e.g., $\sfalpha, \sfbeta, \sfgamma, \sfdelta$ \ldots $\bm{\sfalpha, \sfbeta, \sfgamma, \sfdelta \ldots}$), in case they are needed (but note that the \verb|newtxmath| options \verb|frenchmath| and \verb|slantedGreek| also affect how greek letters are presented). + +\subsection{The \texttt{newtxmath} and \texttt{mathalpha} Packages~\cite{sharpe1,sharpe2}} The \texttt{newtxmath} package~\cite{sharpe1}, loaded by default, includes a large number of options for mathematics, most of which can be called as options to \verb|\documentclass|. For example, the \texttt{upint} option of \texttt{newtxmath} selects upright integral signs (rather than slanted integral signs): +\begin{quote} +\verb|\documentclass[upint]{asmeconf}|. +\end{quote} +The option \verb|subscriptcorrection| improves the spacing of math subscripts. These math options are discussed further in the \texttt{asmeconf-template.tex} file. + +In addition, many options for calligraphic, fraktur, and script fonts are available as options to the \texttt{mathalfa} package, which is also loaded. These may be invoked, for example, as +\begin{center} +\verb|\documentclass[mathalfa=cal=euler]{asmeconf}| +\end{center} +which selects the Euler font for \verb|\mathcal| (this is our default). To find all the font options, refer to the \texttt{mathalfa} package documentation \cite{sharpe2}. + +The \texttt{asmeconf} class is designed to be used with \texttt{newtxmath} and does not support the \texttt{unicode-math} package. + + +%%%%%%%%%%%%%%% ADDITIONAL PACKAGE OPTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Additional Options for \NoCaseChange{\texttt{asmeconf.cls}}} +The class accepts a number of options in addition to those already described. These options are discussed next. + +\subsection{Colored Hyperlinks} +ASME requires that all text be \textbf{in black} when the paper is submitted for publication. For other uses, authors may +obtain colored hyperlinks with the [\texttt{colorlinks}] option. + +\subsection{Final Column Balancing} The option \texttt{[balance]} invokes the the \texttt{flushend} package~\cite{tolusis}. +This package will attempt to give equal height to the two columns on the last page. The performance of this package is sometimes inconsistent (with odd page layout or, very rarely, errors), so use this option with caution. + +\subsection{Line Numbers} The option \texttt{[lineno]} invokes the the \texttt{lineno} package~\cite{bottcher}. This option will produce line numbers in the margins. You must run \LaTeX\ \textit{twice} for proper placement of the numbers. Tables, captions, and footnotes will not be numbered. Line numbers can be helpful for review and editing, but should not be used in your final manuscript. See the documentation of the \texttt{lineno} package for further commands to control line numbering. + +The \texttt{lineno} package is not compatible with the \texttt{flushend} package that makes final short columns the same height. Balancing is automatically disabled when this option is called. + +\subsection{Grid-Style Author Block} The option \texttt{[authorgrid]} invokes ASME's grid-style arrangement of author names. The authors and affiliations must be entered differently in this case. See Appendix \ref{appendix:b} for usage. + +\subsection{Changing the Copyright Footer} The option \texttt{[nofoot]} will omit the ASME copyright from the page footer. The option \texttt{[govt]} will produce a copyright notice for authors who are employees of the U.\ S.\ Government. The option \texttt{[contractor]} will produce a copyright +notice for authors who are employed by a U.\ S.\ Government contractor. + +The footers are generated with the \texttt{fancyhdr} package~\cite{oostrum}, so you can change them in any way you like using the commands of that package. Only the default arrangement of footers matches ASME's style, however. + +\subsection{Archivability:~PDF/A} Compliance with PDF/A standards can be enabled using the option \texttt{[pdf-a]} +when running with \hologo{pdfLaTeX}. The default setting is for PDF/A-3u with sRGB OutputIntent (\texttt{sRGB.icc}). +If levels 1b, 2b, 2u, or 3b are preferred, use the options \texttt{[pdfapart=1 or 2 or 3]} and +\texttt{[pdfaconformance=b or u]}. Note that accessible conformance~(\texttt{a}) is not currently possible with \LaTeX. + +\subsection{Superiors Font} The \texttt{newtxtext} package includes a superiors font (both numbers and letters) for use in footnote markers and superscripts. To enable this font, use the option \texttt{[nodefaultsups]}. + +\subsection{Typewriter Font Options} This font is the sans-serif \texttt{inconsolata}. By default, the word spacing is variable, but option \texttt{[mono]} ends this behavior. A slashed zero is default; option \texttt{[var0]} removes the slash. Option \texttt{[hyphenate]} enables hyphenation. (This option is not available if the \texttt{[fontspec]} option is used.) + +\subsection{Support for Other Languages} The package can be adapted to incorporate (or entirely use) languages other than English. See Appendix \ref{appendix:c} for details. + + +%%%%% Conclusions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Conclusion} +Provide a brief conclusion (3-4 lines). + + +%%%%% Acknowledgments %%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section*{Acknowledgments} +Place any acknowledgments here. + + + +%%% REFERENCES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% Put your references into your .bib file in the usual way. Run latex once, bibtex once, then latex twice. +%% The asmeconf.bst style allows: venue = {Location of Conference}, and eventdate = {Month, days} +%% for @inproceedings and @proceedings +%% + +\nocite{*} %% <=== Delete this line unless you want to typeset the entire contents of your .bib file! + +\bibliographystyle{asmeconf} %% .bst file following ASME conference format. Do not change. +\bibliography{asmeconf-sample} %% <=== change this to name of your bib file + + +%%% APPENDICES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\appendix + +%% Note that appendices will be "numbered" A, B, C, ... etc. Use \section, not \section* +%% Equations will be numbered sequentially following those in the paper. Do not reset the equation counter. + +%% Here we use the optional argument to control the pdf bookmark and prevent errors. +\section[The Vector Product A\times B]{The vector product $\vec{A}\times\vec{B}$}\label{appendix:a} + +This brief illustration of an appendix shows the numbering of the appendix and equations. Equations are numbered +consecutively, following those in the paper. Consider $\rho \neq \textrm{fn}(p)$: +\begin{align} +\frac{d\Gamma}{dt} &{}= \frac{d}{dt} \int_{\mathcal{C}} \mathbf{u} \cdot d\mathbf{r}\\ + &{}= \int_{\mathcal{C}} \frac{D\mathbf{u}}{Dt} \cdot d\mathbf{r} + \underbrace{\int_{\mathcal{C}} \mathbf{u}\cdot d\biggl( \frac{d\mathbf{r}}{dt}\Biggr)}_{=\, 0} \\[-2pt] + &{}= \iint_{\mathcal{S}} \nabla \times \frac{D\mathbf{u}}{Dt} \cdot d\mathbf{A}\\ + &{}= \iint_{\mathcal{S}} \nabla p \times \nabla \left( \frac{1}{\rho}\right) \cdot d\mathbf{A} +\end{align} + +\section{Option to Use an Author Grid}\label{appendix:b} + +ASME's most recent templates place author names inline, with affiliations for all authors in rows below. +This style is the default for this template. + +The traditional style of putting authors with affiliation into a grid of blocks may be invoked with +the option [\texttt{authorgrid}]. When using this form, the author names and addresses should be entered as below: + +\smallskip +\noindent\verb|\SetAuthorBlock{Name\JointFirstAuthor}{%| + \hbox{}\hfil\verb|Institution \\ City, State}| +\verb|\SetAuthorBlock{Name\JointFirstAuthor}{%| + \hbox{}\hfil\verb|Institution \\ City, Country}| +\verb|\SetAuthorBlock{Name, Name}{%|\hfil\hbox{} + \hbox{}\hfil\verb|Institution \\ City, Country}| +\verb|\SetAuthorBlock{John Lienhard\CorrespondingAuthor{%| + \hbox{\qquad}\hfil\verb|lienhard@mit.edu}}{Institution \\ City, State}| +\smallskip + +Code for the inline-author style is contained at the very end of this \texttt{.tex} file. + +Note that ASME interprets the author order in the grid style by reading names from left-to-right in the top row, then left-to-right in each +subsequent row. + +%% directly usable code follows the \end{document} command below. + +%\end{document} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Multilingual Support}\label{appendix:c} + +ASME publishes in English, but the \texttt{babel} package is loaded for +users who may wish to include other languages. For example, an author might wish to include an appendix that provides the +abstract in another language. + +When more than one language option is included in \verb|\documentclass[..]{asmeconf}|, English will be +assumed to be the main language of the document. (To choose a different main language, set \texttt{[main=..]}). +If no language options are given, the package defaults to English. As examples, a passage in French is +shown in \selectlanguage{french}\appendixname~\ref{app:fourier}\selectlanguage{english}, followed by +\ifpdftex abstracts in Spanish, Greek, and Russian.\else abstracts in other languages.\fi + +Font encoding is set to T1 with utf-8 input supported: +%% If you have trouble with the next line, your file may not be saved in utf-8 format. You can delete that line to resolve the issue. +\typeout{If you have trouble with the next line, your file may not be saved in utf-8 format. You can delete that line to resolve the issue.} +àáâäæãåā èéęëêēė îïíīįì ôöòóœøōõ ûüùúū çćč ł ñń ßśš ÿ žźż. + +Fonts similar to Times/Helvetica are automatically used when the Greek, Vietnamese, or selected cyrillic-alphabet languages are called as options under {\upshape\hologo{pdfLaTeX}}. Using {\upshape\hologo{LuaLaTeX}} with the \texttt{[fontspec]} option, many additional scripts are available; see the supplemental notes for such usage~\cite{lienhard2021}. Possibilities include Arabic, Bengali, Chinese, Devanagari (e.g., for Hindi), Hangul (for Korean), Kana (for Japanese), and Tamil. + +The bibliography style, \texttt{asmeconf.bst}, is designed in English and aimed at \hologo{BibTeX}. Multilingual bibliographies +can be supported using \texttt{BibLaTeX}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{selectlanguage}{french} +\section{Discours Préliminaire de Fourier}\label{app:fourier} +Les causes primordiales ne nous sont point con­nues; mais elles sont assujetties à des lois simples et constantes, que l'on peut découvrir par l'obser­vation, et dont l'étude est l'objet de la philosophie naturelle. + +La chale ur pénètre, comme la gravité, toutes les substances de l'univers, ses rayons occupent toutes les parties de l'espace. Le but de notre ouvrage est d'exposer les lois mathématiques que suit cet élé­ment. Cette théorie formera désormais une des branches les plus importantes de la physique gé­nérale~\cite{fourier1822}. +\end{selectlanguage} + +\begin{selectlanguage}{spanish} +\begin{abstract*} +Este es el resumen del artículo. Escribimos en español. Se describen el problema, los métodos y los resultados. También se incluyen referencias. +\end{abstract*} +\end{selectlanguage}% edited by Aarón Montoya-Moraga + +%% If you have trouble with the passages, your file may not be saved in utf-8 format. You can delete this stuff to resolve the issue. + +%% Examples of abstracts in other languages. The first three are intended for pdflatex, not lualatex. +\begin{selectlanguage}{greek}% +\begin{abstract*} +Αυτή είναι η περίληψη του άρθρου. Χρησιμοποιούμε την ελληνική γλώσσα. Περιγράφεται το πρόβλημα, οι μέθοδοι και τα αποτελέσματα. Περιλαμβάνονται επίσης αναφορές. +\end{abstract*} +\end{selectlanguage}% Edited by George Barbastathis + +\begin{selectlanguage}{russian} +\begin{abstract*} +Это резюме статьи. Пишем по русски. Описаны проблема, методы и результаты. Библиография также включена.% +\end{abstract*} +\end{selectlanguage}% edited by Steven Gerasimoff + +\iffontspecloaded +% + \begin{selectlanguage}{japanese} + \begin{abstract*} + %論文の要約です。日本語で記述します。問題、方法、および結果について説明します。また、参考文献も含めます。 + この論文の日本語での要約は以下のとおりです。問題、方法、および結果が説明されています。参考資料も添付してあります。 + \end{abstract*} + \end{selectlanguage}% Edited by Keiji Yano and Yoshiki Okamoto +% + \begin{selectlanguage}{korean} + \begin{abstract*} + 이것은 한국어로 쓰인 논문의 초록입니다. 문제, 방법 및 결과가 설명되어 있습니다. 참조도 포함됩니다. + \end{abstract*} + \end{selectlanguage}% Edited by Hyung Won Chung. +% + \begin{selectlanguage}{chinese-simplified} + \begin{abstract*} + 这是文章的摘要。我们用中文书写,描述了问题,方法和结果,还包括了参考文献。 + \end{abstract*} + \end{selectlanguage}% edited by Zi Hao Foo +% +\fi + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\end{document} + + +%%% This is the set-up for the inline author block style; don't use option [authorgrid] + +% Put author names into the order you want. Use the same order for affiliations. +% \affil{#} tags the author's affiliation to the address in \SetAffiliation{#}. +% No space between last name and \affil{#}, separate names with commas. +% +% \CorrespondingAuthor{email} follows that author's affiliation, no spaces. +% If multiple corresponding authors, put both email addresses in the same command and place after both authors. +% +% \JointFirstAuthor, if applicable, follows the affiliation of the relevant authors, no spaces. + +\SetAuthors{Luis Hern\'andez\affil{1}\JointFirstAuthor , Maria Silva\affil{2}\JointFirstAuthor, Henry Tudor\affil{3}, Catherine~Parr\affil{3}\CorrespondingAuthor{}, John H.\ Lienhard V\affil{4}\CorrespondingAuthor{lienhard@mit.edu, kate@thepalace.gov}} + +\SetAffiliation{1}{Institution or Company Name, City, State} +\SetAffiliation{2}{Institution or Company Name, City, Province, Canada} +\SetAffiliation{3}{Hampton Court Palace, Richmond, England} +\SetAffiliation{4}{Massachusetts Institute of Technology, Cambridge, MA } +% Note: Luis and Maria are not real people. Henry and Catherine have been dead for >450 years. + + +% To instead use the [authorgrid] option, follow the syntax in Appendix B. + diff --git a/macros/latex/contrib/asmeconf/examples/asmeconf-fontspec.pdf b/macros/latex/contrib/asmeconf/examples/asmeconf-fontspec.pdf new file mode 100644 index 0000000000..aa48eec92c Binary files /dev/null and b/macros/latex/contrib/asmeconf/examples/asmeconf-fontspec.pdf differ diff --git a/macros/latex/contrib/asmeconf/examples/asmeconf-fontspec.tex b/macros/latex/contrib/asmeconf/examples/asmeconf-fontspec.tex new file mode 100644 index 0000000000..e77fb2d346 --- /dev/null +++ b/macros/latex/contrib/asmeconf/examples/asmeconf-fontspec.tex @@ -0,0 +1,444 @@ +% !TEX TS-program = LuaLaTeX +% !TEX encoding = UTF-8 Unicode +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% This file is an example of using asmeconf with fontspec and lualatex to support non-Latin alphabets. +%% +%% Author: John H. Lienhard V +%% Department of Mechanical Engineering +%% Massachusetts Institute of Technology +%% Cambridge, MA 02139-4307 USA +%% + %========================================================= +%% +%% LICENSE: +%% +%% Copyright (c) 2021 John H. Lienhard +%% Offered under the MIT license: https://ctan.org/license/mit +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\documentclass[colorlinks,nofoot,fontspec,spanish,japanese,russian,greek,ukrainian,vietnamese,french,portuguese,turkish,polish,indonesian,italian,german,latin,serbianc,bidi=basic]{asmeconf} +% note that not all languages given as examples in this file can be called as options. + +\hypersetup{% + pdftitle={Language Support in ASMECONF: Non-Latin Alphabets, Lualatex, and fontspec}, + pdfkeywords={asmeconf, non-Latin alphabets, fontspec, LuaLaTeX, PDFLaTeX}, + pdfauthor={John H. Lienhard, V}, +} + +% To avoid typing these over and over, define: +\newcommand*\FS{{\upshape\texttt{fontspec}}} +\newcommand*\LLT{{\upshape\LuaLaTeX}} +\newcommand*\AC{{\upshape\texttt{asmeconf}}} +\newcommand*\PLT{{\upshape\texttt{\hologo{pdfLaTeX}}}} + +\makeatletter +\def\NotoBan@scale{0.98}% vary this if the Bengali is too small/large; the default value 0.92 matches scaling of the other Noto fonts used. +\def\NotoDev@scale{0.98}% vary this if the Devanagari is too small/large; the default value 0.92 matches scaling of the other Noto fonts used. +%\def\NotoTam@scale{0.92}% vary this if the Tamil is too small/large; the default value 0.92 matches scaling of the other Noto fonts used. +\def\NotoAra@scale{0.93}% The serif font only; the default value is 0.91 + +% Noto family is not as close to Tex Gyre Termes as I'd like, so for abstract examples in Latin script [only], use Noto Serif Italic for visual consistency +\newfontfamily{\NotoSerifItal}{NotoSerif-Italic.ttf}[ItalicFont=*,Scale=\Noto@scale,WordSpace={1,1.4,1}] +\newfontfamily{\NotoSerifItalns}{NotoSerif-Italic.ttf}[ItalicFont=*,Scale=\Noto@scale]% Turkish has trouble with WordSpace +\makeatother + +% babel [serbianc] module redefines some math commands that are also redefined by babel [russian]. Let's avoid error messages +% by erasing the [serbianc] definitions before \begin{document}, which is where [russian] will define them. +\usepackage{etoolbox} +\AtEndPreamble{% +\let\sh\relax \let\ch\relax \let\tg\relax \let\ctg\relax \let\arctg\relax \let\arcctg\relax \let\cth\relax \let\cosec\relax } + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% This environment will generate the .bib file the first time you run the code +% NB: if the .bib file already exists, it will not be overwritten +\begin{filecontents}{asmeconf-fontspec.bib} +@online{lienhard2021, + author = {John H. Lienhard, V}, + title = {{\texttt{asmeconf}}: A template for {ASME} conference papers}, + organization = {Comprehensive \TeX\ Archive Network}, + version = {1.22}, + year = {2021}, + url = {https://ctan.org/pkg/asmeconf}, + urldate = {pre-release}, +} +@online{bezos2020, + author = {Johannes L. Braams and Javier Bezos}, + title = {{\texttt{babel}}: Localization and internationalization}, + organization = {Comprehensive \TeX\ Archive Network}, + version = {3.52}, + year = {2020}, + url = {https://ctan.org/pkg/babel}, + urldate = {January 3, 2021}, +} +@online{robertson2020, + title = {The fontspec package: Font selection for {\LuaLaTeX} and {\XeLaTeX}}, + version = {2.7i}, + organization = {Comprehensive \TeX\ Archive Network}, + author = {Will Robertson}, + year = 2020, + url = {https://ctan.org/pkg/fontspec}, + urldate = {January 5, 2021}, +} +@online{lua-jp, + author = {{\LuaTeX-ja} project team}, + title = {The {\LuaLaTeX}-ja package}, + version = {20210103.0}, + organization = {Comprehensive \TeX\ Archive Network}, + year = 2021, + url = {https://ctan.org/pkg/luatexja}, + urldate = {January 5, 2021}, +} +@online{dpc, + author = {David Carlisle}, + title = {The {\texttt{dcolumn}} package}, + version = {1.06}, + organization = {Comprehensive \TeX\ Archive Network}, + year = 2014, + url = {https://ctan.org/pkg/dcolumn}, + urldate = {January 8, 2021}, +} +\end{filecontents} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{document} + +\ConfName{Proceedings of the \texttt{asmeconf} \linebreak International Examples Congress and Exposition} +\ConfAcronym{AIECE21} +\ConfDate{January 20, 2021} +\ConfCity{Cambridge, MA} +\PaperNo{AIECE2021-0002} + +\title{Language Support in ASMECONF: Non-Latin Alphabets, Lualatex, and fontspec} + +\SetAuthors{John H.\ Lienhard V\affil{1}\CorrespondingAuthor{lienhard@mit.edu}} +\SetAffiliation{1}{Department of Mechanical Engineering \\ Massachusetts Institute of Technology, Cambridge, MA} + +\maketitle + +\versionfootnote{Version~1.0, \today} + +\keywords{asmeconf, language support, non-Latin alphabets, fontspec, \LLT} + +%%%%%%%%% ABSTRACT %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{abstract} +This note describes the use of \AC\ to format multilingual documents in Latin or non-Latin alphabets. Font support encompasses the Arabic, Chinese, Greek, Hindi, Japanese, Korean, Marathi, Russian, and Tamil languages, among others. For asian alphabets, \LLT\ and \FS\ are employed. The system fonts that must be installed for \FS\ are listed, and examples of simple abstracts are shown in twenty-five languages. +\end{abstract} + +%%%%%%%%% BODY OF PAPER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Introduction: why have this?} +The \AC\ class~\cite{lienhard2021} provides a template for formatting conference papers submitted to the American Society of Mechanical Engineers. +The goal of adding language support to \AC\ is to enable authors to include translations of a paper's abstract or brief quotations in languages other than English. Although the entire \AC\ template may, in principle, be switched to another language without modifying the class file, I have not explored this option in much detail. These language capabilities are experimental, and their future development will be guided by the feedback that I receive from authors. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{The babel package} +The typesetting of languages is handled by the \texttt{babel} package~\cite{bezos2020}, which is called by the \AC\ class. For many languages, \texttt{babel} includes language definition files (\texttt{.ldf}) that provide information about section or caption titles, hyphenation rules, and so on. When an \texttt{.ldf} exists, \texttt{babel} will recognize the language as a global option that can be passed as an option to \AC, assuming that an appropriate font is available. A list of the many languages with \texttt{.ldf} files is given in the \texttt{babel} documentation. + +For languages in Latin scripts, it's usually safe to assume that the font is present, and many such languages have \texttt{.ldf} files. For other scripts, additional steps are needed. The \AC\ class handles this differently under \PLT\ and \LLT. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Non-Latin Scripts under PDFLATEX} +When using \PLT, \AC will load appropriate fonts for Greek, Vietnamese, and certain cyrillic-script languages (see Table~\ref{tab:1}). The user can give the corresponding class option and then call for a change of language as described in Section~\ref{sec:6}. No additional work is required. + +To access a broader range of fonts, \AC\ can be used under \LLT, with \FS. In that case, \AC\ will employ fonts that are installed in the user's operating system, rather than \LaTeX\ fonts. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\def\NOT{---} +\begin{table}[t] +\caption{Languages in non-Latin scripts for which \NoCaseChange{\AC} is known to provide font support. +Class options that must be called are shown.\label{tab:1}}% +\centering{% +\begin{tabular*}{\columnwidth}{@{\hspace*{1.5em}}@{\extracolsep{\fill}}llcc@{\hspace*{1.5em}}} +\toprule +\textbf{Language} & \textbf{Option} & \textbf{\hologo{pdfLaTeX}} & \textbf{\LLT}\\ \midrule +Arabic & bidi=basic & & \checkmark\\ +Belarusian & belarusian & \checkmark & \checkmark\\ +Bengali & \NOT & & \checkmark\\ +Bulgarian & bulgarian & \checkmark & \checkmark\\ +Chinese & \NOT & & \checkmark\\ +Greek & greek & \checkmark & \checkmark\\ +Hindi & \NOT & & \checkmark\\ +Japanese & japanese & & \checkmark\\ +Korean & \NOT & & \checkmark\\ +Macedonian & macedonian & \checkmark & \checkmark\\ +Marathi & \NOT & & \checkmark\\ +Russian & russian & \checkmark & \checkmark\\ +Serbian &serbianc$^\ast$& \checkmark & \checkmark\\ +Tamil & \NOT & & \checkmark\\ +Ukrainian & ukrainian & \checkmark & \checkmark\\ +Vietnamese & vietnamese & \checkmark & \checkmark\\ +\bottomrule +\multicolumn{4}{@{\hspace*{1.5em}}p{23em}@{\hspace*{1.5em}}}{\footnotesize$^\ast$\ Serbian option \texttt{[serbianc]}, for both engines, uses cyrillic. In \PLT, use \texttt{\textbackslash selectlanguage\{serbianc\}}. In \LLT, instead select ``\texttt{serbian-cyrillic}''.} +\end{tabular*} +} +\end{table} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{System fonts} +The \FS\ package~\cite{robertson2020} allows \LLT\ to access fonts that are installed on the user's system. Today, these fonts are normally in unicode, a 16-bit format that allows a font to contain a vast number of glyphs---up to $2^{16}$. Multiple languages can be contained within a single font. Specialized unicode fonts are dedicated to particular languages, especially those such as Japanese that have many thousands of characters. + +When processed in \PLT, \AC\ uses the \texttt{newtxtext} and \texttt{inconsolata} fonts, a collection of eight-bit fonts, for Latin script. To use \FS, we must replace those fonts with corresponding unicode fonts (the math fonts, from \texttt{newtxmath}, are unchanged). Specialized fonts are needed for some additional scripts. Thus, the user will need to install several unicode fonts onto their own system in order to use \AC\ with \FS. +Fortunately, all these fonts are all free and easily downloaded. + +The needed fonts are listed in Table~\ref{tab:2}. + +%%%%%%%%%%%%%%% two column table %%%%%%%%%%%%%%%%%% +\NewDocumentCommand\R{O{11pt}}{\rule{0pt}{#1}} +\begin{table*}[t!] +\caption{System fonts used by \AC\ with \FS. For all fonts, load regular and bold face. For Latin, Cyrillic, and Greek, also load italic and bold italic. For Noto Sans Arabic, install semibold instead of bold.\label{tab:2}}% +\centering{% +\begin{tabular*}{\textwidth}{@{\hspace*{0.5em}}@{\extracolsep{\fill}}>{\raggedright}p{6em}>{\raggedright}p{12em}>{\raggedright}p{10em}p{23em}@{\hspace*{0.5em}}} +\toprule +\textbf{Script}\rule{0pt}{11pt} & +\multicolumn{1}{c}{\textbf{Language}} & +\multicolumn{1}{c}{\textbf{Fonts}} & +\multicolumn{1}{c}{\textbf{Where to get the font}}\\ \midrule +Latin$^*$ & most European languages & Tex Gyre Termes, Tex~Gyre~Heros & \url{http://www.gust.org.pl/projects/e-foundry/tex-gyre}\rule{0pt}{11pt}\\ +Arabic\R & Arabic, Punjabi, Urdu, others & Amiri,\\ Noto~Sans~Arabic & \url{https://github.com/alif-type/amiri}\hfill\hbox{} \url{https://github.com/googlefonts/noto-fonts} \\ +Bengali\R & Assamese, Bengali, others & Noto Serif Bengali,\\ Noto~Sans Bengali& \url{https://github.com/googlefonts/noto-fonts} \\ +Cyrillic\R & Belarusian, Bulgarian, Macedonian, Russian, Serbian, Ukrainian, others & Noto Serif,\\ Noto~Sans, Noto~Sans~Mono & \url{https://github.com/googlefonts/noto-fonts} \\ +Devanagari\R& Hindi, Kashmiri, Marathi, Nepali, Sanskrit, others & Noto Serif Devanagari,\\ Noto~Sans Devanagari& \url{https://github.com/googlefonts/noto-fonts} \\ +Greek\R & Greek & Noto Serif, Noto~Sans, Noto~Sans~Mono & \url{https://github.com/googlefonts/noto-fonts} \\ +Hangul\R & Korean & Noto~Serif~CJK~KR, Noto~Sans~CJK~KR, Noto~Sans~Mono~CJK~KR & \url{https://github.com/googlefonts/noto-fonts} \\ +Japanese\R & Japanese & Noto~Serif~CJK~JP, Noto~Sans~CJK~JP, Noto~Sans~Mono~CJK~JP & \url{https://github.com/googlefonts/noto-fonts} \\ +Simplified\R\ Chinese & Mandarin & Noto~Serif~CJK~SC, Noto~Sans~CJK~SC, Noto~Sans~Mono~CJK~SC & \url{https://github.com/googlefonts/noto-fonts} \\ +Tamil\R & Tamil, others & Noto~Serif~Tamil, Noto~Sans~Tamil & \url{https://github.com/googlefonts/noto-fonts} \\ +Traditional\R\ Chinese & Traditional Mandarin, Cantonese & Noto~Serif~CJK~TC, Noto~Sans~CJK~TC, Noto~Sans~Mono~CJK~TC & \url{https://github.com/googlefonts/noto-fonts} \\ +\bottomrule +\multicolumn{4}{l}{\R $^*$\ The Latin fonts are \textit{required} with \AC+\FS, even if English is the only language called. Install others as needed.} +\end{tabular*} +} +\end{table*} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Using fontspec with asmeconf} +When running \LLT, the \texttt{[fontspec]} option should be called, to load the appropriate fonts. With \FS, \texttt{babel} will use \texttt{.ldf} files (if available) and separate initialization files (\texttt{.ini}). If a language option is called for which there is no \texttt{.ldf} file, an error will result. However, such languages may still have an \texttt{.ini} that provides necessary information. For example, Chinese and Korean do not have \texttt{.ldf} files, but they do have \texttt{.ini} files. These languages can be accessed as described in Section~\ref{sec:6}. + +Japanese typesetting is a little more complicated. When \texttt{[japanese]} is given as an option to the class, \AC\ calls the \texttt{luatexja-fontspec} package~\cite{lua-jp}, which is a specialized module for typesetting Japanese. + +When captions and the like are not needed (as for short passages), \texttt{babel} can load many languages ``on the fly'', with only a basic call in the \text{.tex} file (see Section \ref{sec:6}), if an appropriate font is available. + +What about support for scripts not shown in Table~\ref{tab:2}? Macros from \texttt{babel} for adding fonts can be placed into the preamble of your document. The \texttt{babel} package supports roughly 250 languages, and \AC\ has been tried with only about thirty. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{How to call a language\label{sec:6}} +A language is called by \verb|\begin{selectlanguage}{}|, where \texttt{} is the lower-case name of the language. +For example, suppose that a Spanish language abstract is desired. The user puts \texttt{[spanish]} as a global option (this language has an \texttt{.ldf} file), and then writes: +\begin{quotation} +\noindent\hbox{}\verb|\begin{selectlanguage}{spanish}|\\ +\verb|\begin{abstract*}|\\ +\verb|Este es el resumen del artículo|\ldots\\ +\verb|\end{abstract*}|\\ +\verb|\end{selectlanguage}| +\end{quotation} + +\textsc{\textbf{Nota Bene:}} \textbf{1)} Your \texttt{.tex} file \textit{must} be saved in \texttt{utf-8} encoding. Some operating systems default to a different encoding that will garble unicode characters. \textbf{2)} The features used to provide language support under \FS\ require an up-to-date \LaTeX\ distribution (2020 or~later). \textbf{3)} The features described here require \AC\ version~1.22 or later (2021). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Abstracts} +Examples of abstracts in various languages now follow. Reading the source \texttt{.tex} file for this document may clarify the syntax. + +\begin{selectlanguage}{chinese-simplified} +\begin{abstract*} +这是文章的摘要。我们用中文书写,描述了问题,方法和结果,还包括了参考文献。 +\end{abstract*} +\end{selectlanguage}% edited by Zi Hao Foo + +\begin{selectlanguage}{chinese-traditional}% this is Mandarin +\begin{abstract*} +這是文章的摘要。我們用中文書寫,描述了問題,方法和結果,還包括了參考文獻。 +\end{abstract*} +\end{selectlanguage}% edited by Zi Hao Foo + +\begin{selectlanguage}{chinese-traditional}% this is Cantonese +\begin{abstract*} +係文嘅摘要。 我哋用中文書寫,描述了問題,方法同結果,仲包括埋參考文獻。 +\end{abstract*} +\end{selectlanguage}% edited by Zi Hao Foo + +{\NotoSerifItal +\begin{selectlanguage}{spanish} +\begin{abstract*} +Este es el resumen del artículo. Escribimos en español. Se describen el problema, los métodos y los resultados. También se incluyen referencias. +\end{abstract*} +\end{selectlanguage}% edited by Aarón Montoya-Moraga + +\begin{selectlanguage}{english} +\begin{abstract*} +This is the summary of the article. We write in English. The problem, methods, and results are described. References are also included. +\end{abstract*} +\end{selectlanguage}% checked by JHL :-) +}% + +\begin{selectlanguage}{hindi} +\begin{abstract*} +यह हिंदी में लिखे गए एक लेख का सारांश है। समस्या, विधियों और परिणामों का वर्णन किया गया है। संदर्भ भी शामिल हैं। +\end{abstract*} +\end{selectlanguage}% Checked by Debanjan Banerjee + +\begin{selectlanguage}{bengali} +\begin{abstract*} +এটি নিবন্ধের সংক্ষিপ্তসার। আমরা বাংলা ভাষায় লিখি। সমস্যা, পদ্ধতি এবং ফলাফল বর্ণনা করা হয়। উল্লেখগুলিও অন্তর্ভুক্ত রয়েছে। +\end{abstract*} +\end{selectlanguage}% Checked by Yagnaseni Roy + +\begin{selectlanguage}{arabic}% NB: provide package option [bidi=basic] to get RL type. +\begin{abstract*}\upshape +هذا هو ملخص المقال. نكتب بالعربية. يتم وصف المشكلة والطرق والنتائج. يتم تضمين المراجع أيضاً. +\end{abstract*} +\end{selectlanguage}% Edited by Omar Labban + +{\NotoSerifItal +\begin{selectlanguage}{portuguese} +\begin{abstract*} +Este é o resumo do artigo. Escrevemos em português. O problema, métodos e resultados são descritos. Referências também estão incluídas. +\end{abstract*} +\end{selectlanguage}% Checked by Igo Krebs +}% + +\begin{selectlanguage}{russian} +\begin{abstract*} +Это резюме статьи. Пишем по русски. Описаны проблема, методы и результаты. Библиография также включена. +\end{abstract*} +\end{selectlanguage}% edited by Steven Gerasimoff + +\begin{selectlanguage}{japanese} +\begin{abstract*} +%論文の要約です。日本語で記述します。問題、方法、および結果について説明します。また、参考文献も含めます。 +この論文の日本語での要約は以下のとおりです。問題、方法、および結果が説明されています。参考資料も添付してあります。 +\end{abstract*} +\end{selectlanguage}% Edited by Keiji Yano and Yoshiki Okamoto + +\begin{selectlanguage}{marathi} +\begin{abstract*} +हा लेखाचा सारांश आहे. आपण मराठीत लिहित आहो. ह्यात समस्या , पद्धती आणि परिणामाचे वर्णन केले आहेत. संदर्भ देखील समविष्ट आहेत. +\end{abstract*} +\end{selectlanguage}% Edited by Vibhawari Deshmukh. (Note that proper fontspec renderer is needed for the combining characters.) + +{\NotoSerifItal +\begin{selectlanguage}{turkish} +\begin{abstract*}{\NotoSerifItalns +Bu, makalenin özetidir. Türkçe yazıyoruz. Sorun, yöntemler ve sonuçlar açıklanmaktadır. Referanslar da dahildir.}% +\end{abstract*}% +\end{selectlanguage}% Edited by Aslı Demir +}% + +\begin{selectlanguage}{korean} +\begin{abstract*} +이것은 한국어로 쓰인 논문의 초록입니다. 문제, 방법 및 결과가 설명되어 있습니다. 참조도 포함됩니다. +\end{abstract*} +\end{selectlanguage}% Edited by Hyung Won Chung. + +{\NotoSerifItal +\begin{selectlanguage}{french} +\begin{abstract*} +Ceci est le résumé de l'article. Il est écrit en français. Le problème, les méthodes et les résultats sont décrits. Des références sont également incluses. +\end{abstract*} +\end{selectlanguage}% Edited by Christine Gervais. + +\begin{selectlanguage}{german} +\begin{abstract*} +Hier ist die Zusammenfassung des Beitrags. Wir schreiben auf Deutsch. Die Fragestellung, die Methoden und die Ergebnisse werden beschrieben. Der Beitrag enthält auch ein Literaturverzeichnis. +\end{abstract*} +\end{selectlanguage}% Edited by Greg Thiel. +}% + +\begin{selectlanguage}{tamil} +\begin{abstract*} + இது கட்டுரையின் சுருக்கம். நாங்கள் தமிழில் எழுதுகிறோம். சிக்கல், முறைகள் மற்றும் முடிவுகள் விவரிக்கப்பட்டுள்ளன. குறிப்புகளும் சேர்க்கப்பட்டுள்ளன. +\end{abstract*} +\end{selectlanguage}% Edited by Jaichander Swaminathan. (Note that HarfBuzz is needed for combining characters to render correctly.) + +{\NotoSerifItal +\begin{selectlanguage}{vietnamese} +\begin{abstract*} +Đây là phần tóm tắt của bài báo khoa học. Chúng tôi viết bằng tiếng Việt. Vấn đề, các phương pháp và các kết quả được mô tả trong phần này. Tài liệu tham khảo cũng được bao gồm.% +\end{abstract*} +\end{selectlanguage}% Checked and edited by Nguyen Le and Thao Nguyen + +\begin{selectlanguage}{italian} +\begin{abstract*} +Questo è il riassunto dell'articolo. Scriviamo in italiano. Vengono descritti il ​​problema, i metodi e i risultati. Sono inclusi anche i riferimenti. +\end{abstract*} +\end{selectlanguage}% Checked by Jacopo Buongiorno. + +\begin{selectlanguage}{indonesian} +\begin{abstract*} +Ini adalah ringkasan dari artikel tersebut. Kami menulis dalam bahasa Indonesia. Masalah, metode, dan hasil dijelaskan. Referensi juga disertakan. +\end{abstract*} +\end{selectlanguage}% checked by Danyal Rehman and Turga Ganapathy + +\begin{selectlanguage}{polish} +\begin{abstract*} +To jest podsumowanie artykułu. Piszemy po polsku. Opisano problem, metody i wyniki. Literatura źródłowa zostanie udostępniona. +\end{abstract*} +\end{selectlanguage}% Edited by Leon Awerbuch + +\begin{selectlanguage}{swahili} +\begin{abstract*} +Huu ni Muhtasari wa makala. Tunaandika kwa Kiswahili. +Matatizo, Mbinu na matokeo yameelezewa. Marejeleo pia yamejumuishwa. +\end{abstract*} +\end{selectlanguage}% Edited by Judith Mmari +}% + +\begin{selectlanguage}{ukrainian} +\begin{abstract*} +Це короткий зміст статті. Пишемо українською мовою. Описана проблема, методи та результати. Стаття включає список використаної літератури. +\end{abstract*} +\end{selectlanguage}% Edited by Svetlana Boriskina + +\begin{selectlanguage}{greek}% +\begin{abstract*} +Αυτή είναι η περίληψη του άρθρου. Χρησιμοποιούμε την ελληνική γλώσσα. Περιγράφεται το πρόβλημα, οι μέθοδοι και τα αποτελέσματα. Περιλαμβάνονται επίσης αναφορές. +\end{abstract*} +\end{selectlanguage}% Edited by George Barbastathis + +% Use global option [serbianc] +% Note -- the Slavic language .ldf files redefine math operators. Russian and Ukrainian avoid conflicts, but Serbian does not. See local fix in preamble. +\begin{selectlanguage}{serbian-cyrillic} +\begin{abstract*} +Ово је резиме чланка. Пишемо на српском. Описани су проблем, методе и резултати. Укључене су и референце. +\end{abstract*} +\end{selectlanguage}% confirmed by Bora Mikić + +{\NotoSerifItal +\begin{selectlanguage}{latin} +\begin{abstract*} +Hoc argumentum in articulum. Latine scribere nobis. Quaestio est, modi, et describit eventus qui. Alia sunt opera citatis. +\end{abstract*} +\end{selectlanguage} +}% + +%%% ENTIRE DOCUMENT %%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Changing the language of the entire document} +The main language of the document is English by default. This means that section headings, captions, and other words chosen by macros will be in English. + +To chose a different main language, give the option \texttt{[main=..]}, e.g., \texttt{[main=french]}. The standard caption and section names will follow \texttt{babel}'s dictionary for the language chosen. Users may additionally change ``Keywords'', ``Nomenclature'', ``Corresponding author'', and ``Joint first authors'' by renewing the commands \verb|\keywordname|, \verb|\nomname|, \verb|\CAwords|, and \verb|\JAwords|. Changes to the page footer are described in the \AC\ documentation~\cite{lienhard2021}. The pdf bookmark for ``Appendices'' may be changed by renewing \verb|\appendicesname|. (See the \texttt{babel} documentation \cite[\S 1.15]{bezos2020} if the dictionary for the main language lacks the correct word for, say, \verb|abstractname|). + +Note that some languages make characters active, which can have unexpected effects. For example, Spanish makes ``.'' an active character, which clashes with the default \texttt{dcolumn} decimal separator, \texttt{d\{n.m\}}~\cite{dpc}. \texttt{\textbackslash spanishdeactivate\{.\}} stops this behavior. Alternatively, the decimal separator can be changed to a comma by putting \texttt{\textbackslash newcolumntype\{d\}[1]\{D\{,\}\{,\}\{\#1}\}\} in the preamble. + +I have not explored this usage in detail, and I would welcome comments from authors who attempt such conversions. + +%%% CONCLUSIONS %%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Conclusion} +\AC\ has multilingual capabilities under both \PLT\ and \LLT. In particular, with \FS, \AC\ can support a wide range of scripts and languages within a \LaTeX\ environment. These capabilities are largely experimental, and their future development will be guided by feedback that I receive from those using these features. + +%%% AKNOWLEDGMENTS %%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{AKNOWLEDGMENTS} +Thanks to everyone who helped me sort out the translated abstracts: Leon Awerbuch, Debanjan Banerjee, George Barbastathis, Svetlana Boriskina, Jacopo Buongiorno, Hyung Won Chung, Aslı Demir, Vibhawari Deshmukh, Zi Hao Foo, Turga Ganapathy, Steven Gerasimoff, Christine Gervais, Igo Krebs, Omar Labban, Nguyen Le, Bora Mikić, Judith Mmari, Aarón Montoya-Moraga, Thao Nguyen, Yoshiki Okamoto, Danyal Rehman, Yagnaseni Roy, Jaichander Swaminathan, Gregory Thiel, and Keiji Yano. All were generous with their time. + +%%% REFERENCES %%%%%%%%%%%%%%%%%%%%%%%%%% + +\bibliographystyle{asmeconf}%% .bst file following ASME conference format. Do not change. +\bibliography{asmeconf-fontspec}%% this bib file will be generated from the filecontents environment upon first run of this .tex file. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\end{document} + diff --git a/macros/latex/contrib/asmeconf/examples/asmeconf-lualatex-ode-example.pdf b/macros/latex/contrib/asmeconf/examples/asmeconf-lualatex-ode-example.pdf new file mode 100644 index 0000000000..ebef2df8cb Binary files /dev/null and b/macros/latex/contrib/asmeconf/examples/asmeconf-lualatex-ode-example.pdf differ diff --git a/macros/latex/contrib/asmeconf/examples/asmeconf-lualatex-ode-example.tex b/macros/latex/contrib/asmeconf/examples/asmeconf-lualatex-ode-example.tex new file mode 100644 index 0000000000..6db7d9c08a --- /dev/null +++ b/macros/latex/contrib/asmeconf/examples/asmeconf-lualatex-ode-example.tex @@ -0,0 +1,254 @@ +% !TEX TS-program = LuaLaTeX +% !TEX encoding = UTF-8 Unicode +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% This file is an example of using asmeconf with lualatex to solve and plot an ode in a landscape figure. +%% +%% Author: John H. Lienhard V +%% Department of Mechanical Engineering +%% Massachusetts Institute of Technology +%% Cambridge, MA 02139-4307 USA +%% + %========================================================= +%% +%% LICENSE: +%% +%% Copyright (c) 2021 John H. Lienhard +%% Offered under the MIT license: https://ctan.org/license/mit +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\documentclass[varvw,colorlinks,nofoot]{asmeconf} + +\hypersetup{% + pdftitle={Example of asmconf with LuaLaTeX to solve an ODE}, + pdfkeywords={asmeconf, LuaLaTeX, ODE, pgfplots, landscape figure}, + pdfauthor={John H. Lienhard}, +} + +\usepackage[figuresright]{rotating}% to use a landscape figure + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Now use lua code + +%% Runge-Kutta for simple first-order ODE +\begin{luacode*} +-- Differential equation y’(t) = f(t,y) +-- with f(t,y) = A * y * cos(t+sqrt(1+y)). +-- Initial condition: y(0) = 1 +function f(t,y,A) + return A * y * math.cos(t+math.sqrt(1+y)) +end +-- Code to write PGFplots data as coordinates +function print_RKfour(tMax,npoints,A,option) + local t0 = 0.0 + local y0 = 1.0 + local A = A + local h = (tMax-t0)/(npoints-1) + local t = t0 + local y = y0 + if option~=[[]] then + tex.sprint("\\addplot["..option.."] coordinates{") + else + tex.sprint("\\addplot coordinates{") + end + tex.sprint("("..t0..","..y0..")") + for i=1, npoints do + k1 = h * f(t,y,A) + k2 = h * f(t+h/2,y+k1/2,A) + k3 = h * f(t+h/2,y+k2/2,A) + k4 = h * f(t+h,y+k3,A) + y = y + (k1+2*k2+2*k3+k4)/6 + t = t + h + tex.sprint("("..t..","..y..")") + end + tex.sprint("}") +end +\end{luacode*} + +%% Define a latex macro to call the case to be plotted +\newcommand\addLUADEDplot[4][]{% + \directlua{print_RKfour(#2,#3,#4,[[#1]])}% +} +% SYNTAX: Solution of the initial value problem +% Code assumed t = 0 at start and y(0) = 1 +% #2 is the final time +% #3 is the number of points +% #4 is an amplitude parameter +% #1 are options passed to the pgfplots \addplot function. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% For plotting the results, call pgfplots package + +\usepackage{pgfplots}% load AFTER xcolor, which was already called by asmeconf.cls +\pgfplotsset{compat=newest}% to activate latest features + +\pgfplotsset{% + width=\textwidth,% + height=0.6\textwidth,% + /tikz/font={\sffamily},% + % every axis plot/.style={line width=2pt}, + every axis/.append style={very thick},% see manual page 189 + every minor tick/.append style={very thin,black},% modifies the style `every tick' + every minor grid/.append style={very thin, color=Snow4}, + every major tick/.append style={thin, black},% modifies the style `every minor tick' + every major grid/.append style={thin, color=Snow4}, + major tick length={1.2em}, + minor tick length={0.5em}, +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% This environment will generate the .bib file the first time you run the code +% if the .bib file already exists, it will not be overwritten +\begin{filecontents}{asmeconf-lualatex-ode-example.bib} +@online{fairbairns, + author = {Robin Fairbairns and Sebastian Rahtz and Leonor Barroca}, + title = {A Package for Rotated Objects in \LaTeX}, + version = {2.16d}, + organization = {Comprehensive \TeX\ Archive Network}, + year = {2016}, + url = {https://www.ctan.org/pkg/rotating}, + urldate = {October 2, 2019}, +} +@article{montijano2014, + title = {Numerical methods with {\LuaLaTeX}}, + author = {Juan I. Montijano and Mario P{\'{e}}rez and Luis R{\'{a}}ndez and Juan Luis Varona}, + year = 2014, + volume = 35, + month = {January}, + number = 1, + pages = {51--56}, + journal = {TUGboat}, + url = {https://tug.org/TUGboat/tb35-1/tb109montijano.pdf}, + note = {Open access.} +} +@manual{pgfplots, + title = {Manual for Package \textsc{PGFPLOTS}}, + url = {https://ctan.org/pkg/pgfplots}, + author = {Christian Feuers{\"{a}}nger}, + version = {1.17}, + year = {2020}, + organization = {Comprehensive \TeX\ Archive Network}, + month = feb, + urldate = {January 4, 2021}, +} +@manual{lua, + author = {Roberto {l}erusalimschy and Luiz Henrique {de Figueiredo} and Waldemar Celes}, + title = {{L}ua 5.3 Reference Manual}, + url = {https://www.lua.org/manual/5.3/}, + organization = {Pontifical Catholic University}, + address = {Rio de Janeiro, Brazil}, + year = {2017}, +} +\end{filecontents} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{document} + +\ConfName{Proceedings of the \texttt{asmeconf} \linebreak International Examples Congress and Exposition} +\ConfAcronym{AIECE21} +\ConfDate{January 20, 2021} +\ConfCity{Cambridge, MA} +\PaperNo{AIECE2021-0001} + +\title{Example of \NoCaseChange{{\upshape\hologo{LuaLaTeX}}} with asmeconf.cls for ODE Integration} + +\SetAuthors{John H.\ Lienhard V\affil{1}\CorrespondingAuthor{lienhard@mit.edu}} +\SetAffiliation{1}{Massachusetts Institute of Technology, Cambridge, MA} + +\maketitle + +\versionfootnote{Version~1.0, \today} + +\keywords{asmeconf, \hologo{LuaLaTeX}, ODE, pgfplots, landscape} + +%%%%%%%%% ABSTRACT %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{abstract} +This paper is an example of using \texttt{asmeconf} with {\upshape\hologo{LuaLaTeX}} to solve an ODE initial value problem using a fourth-order Runge-Kutta method and to plot the result using \texttt{PGFPLOTS}. The use of a landscape figure is also illustrated. References are given for further reading. +\end{abstract} + +%%%%%%%%% NOMENCLATURE (OPTIONAL) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{nomenclature} +\entry{$A$}{Constant parameter [--]} +\entry{$t$}{Time [s]} +\entry{$y(t)$}{Position [m]} +\end{nomenclature} + +%%%%%%%%% BODY OF PAPER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Introduction} +\hologo{LuaLaTeX} is built upon the Lua programming language~\cite{lua}. By directly using Lua code in a \LaTeX\ file, we can accomplish a wide range of tasks, as illustrated in the open-access paper by Montijano et al.~\cite{montijano2014}. In the present example, we follow Montijano et al.\ in solving a nonlinear first-order ordinary differential equation and plotting the result---all within a single \LaTeX\ file! + +\section{Solution to an initial value problem} +We consider an initial value problem like that of Montijano et al.: +\begin{equation}\label{eqn:1} +y'(t) = A\cdot y(t) \cos\Big(t + \sqrt{1 + y(t)}\,\Big) \text{ with }y(0)=1 +\end{equation} +Here, $A$ is a constant. We may adopt a fourth-order Runge-Kutta algorithm for the integration, which we shall perform to $t = 30$~s using a 400 point discretization. The details of the Runge-Kutta algorithm and a listing of the code are given in Montijano et al. (You can also read the code in the present \texttt{.tex} file.) + +The algorithm is implemented directly in the preamble of this file, and the results are plotted in Fig.~\ref{fig:1} for $A = \{0.25, 0.5, 0.75, 1.0\}$. Plotting is done using the \texttt{PGFPLOTS} package~\cite{pgfplots}. + +Landscape figures, such as Fig.~\ref{fig:1}, may be produced at full-page size by putting \verb|\usepackage[figuresright]{rotating}| in your \texttt{.tex} file's preamble and using the \texttt{sidewaysfigure*} environment~\cite{fairbairns}. + +\begin{sidewaysfigure*} +\begin{tikzpicture} +\begin{axis}[% + xmin=0., + xmax=30., + ymin=0.0, + ymax=1.1, + xtick={0,5,...,30}, + ytick={0,0.2,...,1.0}, + minor x tick num=4, + minor y tick num=3, + xlabel={Time, $\mathsf{t}$ [s]}, + ylabel={Position, $\mathsf{y}$ [m]}, + xticklabel={$\mathsf{\pgfmathprintnumber{\tick}}$}, + yticklabel={$\mathsf{\pgfmathprintnumber{\tick}}$}, + legend style={ + at={(0.7,0.85)}, + anchor=west, + fill=none, + cells={anchor=west}, + }, + ] +% tMax = 30, npoints = 400, A is the last argument +\addLUADEDplot[color=Purple4,densely dashed,,very thick]{30}{400}{0.25};% color names are from xcolor package + \addlegendentry[fill=white]{$\mathsf{A = 0.25}$}; +\addLUADEDplot[color=Chartreuse4,dashdotted,very thick]{30}{400}{0.5}; + \addlegendentry[fill=white]{$\mathsf{A = 0.5}$}; +\addLUADEDplot[color=Red3,densely dotted,very thick]{30}{400}{0.75}; + \addlegendentry[fill=white]{$\mathsf{A = 0.75}$}; +\addLUADEDplot[color=Blue3,smooth,very thick]{30}{400}{1}; + \addlegendentry[fill=white]{$\mathsf{A = 1}$}; +\end{axis} +\end{tikzpicture} +\caption{A trial of pgfplot with Luacode Runge-Kutta integration\label{fig:1}} +\end{sidewaysfigure*} + + +%%% CONCLUSIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Conclusion} +\hologo{LuaLaTeX} enables numerical computations within a \LaTeX\ environment. By combining this capability with +\texttt{PGFPlots}, the need for separate numerical and/or graphics packages can be reduced. + +%%% ACKNOWLEDGMENTS %%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section*{Acknowledgments} +The example shown in this paper is directly based on an example given by Montijano et al.~\cite{montijano2014}. Additional examples, such as the +Lorenz attractor, are contained in that paper. + + +%%% REFERENCES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\bibliographystyle{asmeconf}%% .bst file following ASME conference format. Do not change. +\bibliography{asmeconf-lualatex-ode-example}%% this bib file will be generated from the filecontents environment upon first run of this .tex file. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\end{document} + diff --git a/macros/latex/contrib/translations/README b/macros/latex/contrib/translations/README index e9a9f012f8..9af62b294d 100644 --- a/macros/latex/contrib/translations/README +++ b/macros/latex/contrib/translations/README @@ -1,5 +1,5 @@ -------------------------------------------------------------------------- -the TRANSLATIONS package v1.9 - 2020/11/08 +the TRANSLATIONS package v1.10 - 2021/01/16 internationalization of LaTeX2e packages -------------------------------------------------------------------------- @@ -7,7 +7,7 @@ Clemens Niederberger Web: https://github.com/cgnieder/translations E-Mail: contact@mychemistry.eu -------------------------------------------------------------------------- -Copyright 2012--2020 Clemens Niederberger +Copyright 2012--2021 Clemens Niederberger This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c diff --git a/macros/latex/contrib/translations/dicts/translations-basic-dictionary-brazil.trsl b/macros/latex/contrib/translations/dicts/translations-basic-dictionary-brazil.trsl index 9d0c440480..b2d495e261 100644 --- a/macros/latex/contrib/translations/dicts/translations-basic-dictionary-brazil.trsl +++ b/macros/latex/contrib/translations/dicts/translations-basic-dictionary-brazil.trsl @@ -8,23 +8,20 @@ % Web: https://github.com/cgnieder/translations % E-Mail: contact@mychemistry.eu % -------------------------------------------------------------------------- -% Copyright 2012--2020 Clemens Niederberger +% Copyright 2012--2021 Clemens Niederberger % % This work may be distributed and/or modified under the -% conditions of the LaTeX Project Public License, either version 1.3 +% conditions of the LaTeX Project Public License, either version 1.3c % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt -% and version 1.3 or later is part of all distributions of LaTeX -% version 2005/12/01 or later. +% and version 1.3c or later is part of all distributions of LaTeX +% version 2008/05/04 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Clemens Niederberger. % -------------------------------------------------------------------------- -% If you have any ideas, questions, suggestions or bugs to report, please -% feel free to contact me. -% -------------------------------------------------------------------------- \ProvideDictionaryFor{Brazil}{translations-basic-dictionary} \ProvideDictTranslation{Abstract}{Resumo} diff --git a/macros/latex/contrib/translations/dicts/translations-basic-dictionary-catalan.trsl b/macros/latex/contrib/translations/dicts/translations-basic-dictionary-catalan.trsl index dd9fe5409b..1be12223d7 100644 --- a/macros/latex/contrib/translations/dicts/translations-basic-dictionary-catalan.trsl +++ b/macros/latex/contrib/translations/dicts/translations-basic-dictionary-catalan.trsl @@ -1,32 +1,27 @@ % -------------------------------------------------------------------------- % the TRANSLATIONS package % -% internationalizations of LaTeX2e packages -% +% internationalization of LaTeX2e packages +% % -------------------------------------------------------------------------- % Clemens Niederberger % Web: https://github.com/cgnieder/translations % E-Mail: contact@mychemistry.eu % -------------------------------------------------------------------------- -% Copyright 2012--2020 Clemens Niederberger +% Copyright 2012--2021 Clemens Niederberger % % This work may be distributed and/or modified under the -% conditions of the LaTeX Project Public License, either version 1.3 +% conditions of the LaTeX Project Public License, either version 1.3c % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt -% and version 1.3 or later is part of all distributions of LaTeX -% version 2005/12/01 or later. +% and version 1.3c or later is part of all distributions of LaTeX +% version 2008/05/04 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Clemens Niederberger. % -------------------------------------------------------------------------- -% The translations package is part of the exsheets bundle -% -------------------------------------------------------------------------- -% If you have any ideas, questions, suggestions or bugs to report, please -% feel free to contact me. -% -------------------------------------------------------------------------- \ProvideDictionaryFor{Spanish}{translations-basic-dictionary} \ProvideDictTranslation{Abstract}{Resum} diff --git a/macros/latex/contrib/translations/dicts/translations-basic-dictionary-dutch.trsl b/macros/latex/contrib/translations/dicts/translations-basic-dictionary-dutch.trsl index 5d70d9dfb9..5a0f4f2fcc 100644 --- a/macros/latex/contrib/translations/dicts/translations-basic-dictionary-dutch.trsl +++ b/macros/latex/contrib/translations/dicts/translations-basic-dictionary-dutch.trsl @@ -8,23 +8,20 @@ % Web: https://github.com/cgnieder/translations % E-Mail: contact@mychemistry.eu % -------------------------------------------------------------------------- -% Copyright 2012--2020 Clemens Niederberger +% Copyright 2012--2021 Clemens Niederberger % % This work may be distributed and/or modified under the -% conditions of the LaTeX Project Public License, either version 1.3 +% conditions of the LaTeX Project Public License, either version 1.3c % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt -% and version 1.3 or later is part of all distributions of LaTeX -% version 2005/12/01 or later. +% and version 1.3c or later is part of all distributions of LaTeX +% version 2008/05/04 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Clemens Niederberger. % -------------------------------------------------------------------------- -% If you have any ideas, questions, suggestions or bugs to report, please -% feel free to contact me. -% -------------------------------------------------------------------------- \ProvideDictionaryFor{Dutch}{translations-basic-dictionary} \ProvideDictTranslation{Abstract}{Samenvatting} diff --git a/macros/latex/contrib/translations/dicts/translations-basic-dictionary-english.trsl b/macros/latex/contrib/translations/dicts/translations-basic-dictionary-english.trsl index 13c12392b8..ad659328b3 100644 --- a/macros/latex/contrib/translations/dicts/translations-basic-dictionary-english.trsl +++ b/macros/latex/contrib/translations/dicts/translations-basic-dictionary-english.trsl @@ -8,23 +8,20 @@ % Web: https://github.com/cgnieder/translations % E-Mail: contact@mychemistry.eu % -------------------------------------------------------------------------- -% Copyright 2012--2020 Clemens Niederberger +% Copyright 2012--2021 Clemens Niederberger % % This work may be distributed and/or modified under the -% conditions of the LaTeX Project Public License, either version 1.3 +% conditions of the LaTeX Project Public License, either version 1.3c % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt -% and version 1.3 or later is part of all distributions of LaTeX -% version 2005/12/01 or later. +% and version 1.3c or later is part of all distributions of LaTeX +% version 2008/05/04 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Clemens Niederberger. % -------------------------------------------------------------------------- -% If you have any ideas, questions, suggestions or bugs to report, please -% feel free to contact me. -% -------------------------------------------------------------------------- \ProvideDictionaryFor{English}{translations-basic-dictionary} \ProvideDictTranslation{Abstract}{Abstract} diff --git a/macros/latex/contrib/translations/dicts/translations-basic-dictionary-french.trsl b/macros/latex/contrib/translations/dicts/translations-basic-dictionary-french.trsl index ed0a99cd66..4f3818cc24 100644 --- a/macros/latex/contrib/translations/dicts/translations-basic-dictionary-french.trsl +++ b/macros/latex/contrib/translations/dicts/translations-basic-dictionary-french.trsl @@ -8,23 +8,20 @@ % Web: https://github.com/cgnieder/translations % E-Mail: contact@mychemistry.eu % -------------------------------------------------------------------------- -% Copyright 2012--2020 Clemens Niederberger +% Copyright 2012--2021 Clemens Niederberger % % This work may be distributed and/or modified under the -% conditions of the LaTeX Project Public License, either version 1.3 +% conditions of the LaTeX Project Public License, either version 1.3c % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt -% and version 1.3 or later is part of all distributions of LaTeX -% version 2005/12/01 or later. +% and version 1.3c or later is part of all distributions of LaTeX +% version 2008/05/04 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Clemens Niederberger. % -------------------------------------------------------------------------- -% If you have any ideas, questions, suggestions or bugs to report, please -% feel free to contact me. -% -------------------------------------------------------------------------- \ProvideDictionaryFor{French}{translations-basic-dictionary} \ProvideDictTranslation{Abstract}{R\'{e}sum\'{e}} diff --git a/macros/latex/contrib/translations/dicts/translations-basic-dictionary-german.trsl b/macros/latex/contrib/translations/dicts/translations-basic-dictionary-german.trsl index 1bda332224..4c192b3dac 100644 --- a/macros/latex/contrib/translations/dicts/translations-basic-dictionary-german.trsl +++ b/macros/latex/contrib/translations/dicts/translations-basic-dictionary-german.trsl @@ -8,23 +8,20 @@ % Web: https://github.com/cgnieder/translations % E-Mail: contact@mychemistry.eu % -------------------------------------------------------------------------- -% Copyright 2012--2020 Clemens Niederberger +% Copyright 2012--2021 Clemens Niederberger % % This work may be distributed and/or modified under the -% conditions of the LaTeX Project Public License, either version 1.3 +% conditions of the LaTeX Project Public License, either version 1.3c % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt -% and version 1.3 or later is part of all distributions of LaTeX -% version 2005/12/01 or later. +% and version 1.3c or later is part of all distributions of LaTeX +% version 2008/05/04 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Clemens Niederberger. % -------------------------------------------------------------------------- -% If you have any ideas, questions, suggestions or bugs to report, please -% feel free to contact me. -% -------------------------------------------------------------------------- \ProvideDictionaryFor{German}{translations-basic-dictionary} \ProvideDictTranslation{Abstract}{Zusammenfassung} diff --git a/macros/latex/contrib/translations/dicts/translations-basic-dictionary-spanish.trsl b/macros/latex/contrib/translations/dicts/translations-basic-dictionary-spanish.trsl index 38d4dcf827..9d281f509d 100644 --- a/macros/latex/contrib/translations/dicts/translations-basic-dictionary-spanish.trsl +++ b/macros/latex/contrib/translations/dicts/translations-basic-dictionary-spanish.trsl @@ -8,23 +8,20 @@ % Web: https://github.com/cgnieder/translations % E-Mail: contact@mychemistry.eu % -------------------------------------------------------------------------- -% Copyright 2012--2020 Clemens Niederberger +% Copyright 2012--2021 Clemens Niederberger % % This work may be distributed and/or modified under the -% conditions of the LaTeX Project Public License, either version 1.3 +% conditions of the LaTeX Project Public License, either version 1.3c % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt -% and version 1.3 or later is part of all distributions of LaTeX -% version 2005/12/01 or later. +% and version 1.3c or later is part of all distributions of LaTeX +% version 2008/05/04 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Clemens Niederberger. % -------------------------------------------------------------------------- -% If you have any ideas, questions, suggestions or bugs to report, please -% feel free to contact me. -% -------------------------------------------------------------------------- \ProvideDictionaryFor{Spanish}{translations-basic-dictionary} \ProvideDictTranslation{Abstract}{Resumen} diff --git a/macros/latex/contrib/translations/translations.sty b/macros/latex/contrib/translations/translations.sty index 49418ecc85..85ca86120d 100644 --- a/macros/latex/contrib/translations/translations.sty +++ b/macros/latex/contrib/translations/translations.sty @@ -8,15 +8,15 @@ % Web: https://github.com/cgnieder/translations % E-Mail: contact@mychemistry.eu % -------------------------------------------------------------------------- -% Copyright 2012--2020 Clemens Niederberger +% Copyright 2012--2021 Clemens Niederberger % % This work may be distributed and/or modified under the -% conditions of the LaTeX Project Public License, either version 1.3 +% conditions of the LaTeX Project Public License, either version 1.3c % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt -% and version 1.3 or later is part of all distributions of LaTeX -% version 2005/12/01 or later. +% and version 1.3c or later is part of all distributions of LaTeX +% version 2008/05/04 or later. % % This work has the LPPL maintenance status `maintained'. % @@ -25,15 +25,15 @@ % If you have any ideas, questions, suggestions or bugs to report, please % feel free to contact me. % -------------------------------------------------------------------------- -\newcommand*\@trnslt@date{2020/11/08} -\newcommand*\@trnslt@version{v1.9} +\newcommand*\@trnslt@date{2021/01/16} +\newcommand*\@trnslt@version{v1.10} \newcommand*\@trnslt@packageinfo{internationalization of LaTeX2e packages} \ProvidesPackage{translations}[% \@trnslt@date\space \@trnslt@version\space \@trnslt@packageinfo\space (CN)] -\RequirePackage{scrlfile,etoolbox,pdftexcmds} +\RequirePackage{etoolbox,pdftexcmds} % -------------------------------------------------------------------------- % message handling @@ -70,7 +70,7 @@ % -------------------------------------------------------------------------- % check if babel or polyglossia is used -\AtEndPreamble{ +\AddToHook{begindocument/before}{ \@ifpackageloaded{babel}{}{ \@ifpackageloaded{polyglossia}{} {\@trnslt@info{No language package found. I am going to use `english' @@ -579,7 +579,7 @@ % load dictionaries and check for existing ones: % \LoadDictionary and \LoadDictionaryFor \newrobustcmd*\LoadDictionary[1]{% - \AtEndPreamble{% + \AddToHook{begindocument/before}{% \@trnslt@load@dictionary@for{#1}{\@trnslt@current@language}% }% } @@ -632,7 +632,7 @@ % #1: name % #2: lang \newrobustcmd*\@trnslt@check@dictionary[2]{% - \AfterFile{#1-\@trnslt@language{#2}.trsl} + \AddToHook{file/#1-\@trnslt@language{#2}.trsl/after} {% \edef\@trnslt@tmpa{\@trnslt@language{#2}}% \ifcsdef{@trnslt@dictionary@#1@\@trnslt@tmpa} @@ -1233,4 +1233,4 @@ 2020/11/08 v1.9 - add \ifcurrentlang{} ... \else ... \fi - add \ifcurrentbaselang{} ... \else ... \fi - add Brazilian basic dictionary - +2021/01/16 v1.10 - remove scrlfile dependency diff --git a/macros/latex/contrib/translations/translations_en.pdf b/macros/latex/contrib/translations/translations_en.pdf index fea9e5ce3f..e0eaca60ed 100644 Binary files a/macros/latex/contrib/translations/translations_en.pdf and b/macros/latex/contrib/translations/translations_en.pdf differ diff --git a/macros/latex/contrib/translations/translations_en.tex b/macros/latex/contrib/translations/translations_en.tex index 7118e67b3e..3d579860f3 100644 --- a/macros/latex/contrib/translations/translations_en.tex +++ b/macros/latex/contrib/translations/translations_en.tex @@ -12,23 +12,18 @@ % Web: https://github.com/cgnieder/translations % E-Mail: contact@mychemistry.eu % -------------------------------------------------------------------------- -% Copyright 2012--2020 Clemens Niederberger +% Copyright 2012--2021 Clemens Niederberger % % This work may be distributed and/or modified under the -% conditions of the LaTeX Project Public License, either version 1.3 +% conditions of the LaTeX Project Public License, either version 1.3c % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt -% and version 1.3 or later is part of all distributions of LaTeX -% version 2005/12/01 or later. -% -% This work has the LPPL maintenance status `maintained'. +% and version 1.3c or later is part of all distributions of LaTeX +% version 2008/05/04 or later. % % The Current Maintainer of this work is Clemens Niederberger. % -------------------------------------------------------------------------- -% If you have any ideas, questions, suggestions or bugs to report, please -% feel free to contact me. -% -------------------------------------------------------------------------- \documentclass[load-preamble]{cnltx-doc} \usepackage[french,brazil,spanish,ngerman,english]{babel} % ---------------------------------------------------------------------------- @@ -143,13 +138,9 @@ package available I began using it in various of my other packages so it got extended to the needs I faced there. -\section{License and Requirements}\label{sec:license} +\section{License}\label{sec:license} \license -\translations\ requires the packages \pkg{etoolbox}~\cite{pkg:etoolbox} and -\pkg{scrlfile} (part of the \KOMAScript\ bundle~\cite{bnd:koma-script}). - - \section{Usage} \subsection{Background} The \translations\ package enables the author of a package or a class (or a diff --git a/macros/luatex/generic/luaotfload/NEWS b/macros/luatex/generic/luaotfload/NEWS index b0a7f124c1..5b17fe46c1 100644 --- a/macros/luatex/generic/luaotfload/NEWS +++ b/macros/luatex/generic/luaotfload/NEWS @@ -1,5 +1,10 @@ Change History -------------- +2021-01-08 luaotfload v3.17 + + * The fontloader has been synced with the context code from 2021-01-07. + This improves support for advanced CFF based OpenType variable fonts. + 2020-12-31 luaotfload v3.16 * The fontloader has been synced with the context code from 2020-12-30 diff --git a/macros/luatex/generic/luaotfload/README.md b/macros/luatex/generic/luaotfload/README.md index f19c4c5563..6704e66b90 100644 --- a/macros/luatex/generic/luaotfload/README.md +++ b/macros/luatex/generic/luaotfload/README.md @@ -1,8 +1,8 @@ # The Luaotfload Package -VERSION: 3.16 +VERSION: 3.17 -DATE: 2020-12-31 +DATE: 2021-01-08 ## Description diff --git a/macros/luatex/generic/luaotfload/filegraph.pdf b/macros/luatex/generic/luaotfload/filegraph.pdf index ac40ce55f9..c019d96ba8 100644 Binary files a/macros/luatex/generic/luaotfload/filegraph.pdf and b/macros/luatex/generic/luaotfload/filegraph.pdf differ diff --git a/macros/luatex/generic/luaotfload/fontloader-2020-12-30.lua b/macros/luatex/generic/luaotfload/fontloader-2020-12-30.lua deleted file mode 100644 index 835eca6695..0000000000 --- a/macros/luatex/generic/luaotfload/fontloader-2020-12-30.lua +++ /dev/null @@ -1,35110 +0,0 @@ ---[[info----------------------------------------------------------------------- - Luaotfload fontloader package - build 2020-12-30 17:29:34 -------------------------------------------------------------------------------- - - © 2020 PRAGMA ADE / ConTeXt Development Team - - The code in this file is provided under the GPL v2.0 license. See the - file COPYING in the Luaotfload repository for details. - - Report bugs to https://github.com/latex3/luaotfload - - This file has been assembled from components taken from Context. See - the Luaotfload documentation for details: - - $ texdoc luaotfload - $ man 1 luaotfload-tool - $ man 5 luaotfload.conf - - Included files: - - · fontloader-data-con.lua - · fontloader-basics-nod.lua - · fontloader-basics-chr.lua - · fontloader-font-ini.lua - · fontloader-fonts-mis.lua - · fontloader-font-con.lua - · fontloader-fonts-enc.lua - · fontloader-font-cid.lua - · fontloader-font-map.lua - · fontloader-font-vfc.lua - · fontloader-font-otr.lua - · fontloader-font-oti.lua - · fontloader-font-ott.lua - · fontloader-font-cff.lua - · fontloader-font-ttf.lua - · fontloader-font-dsp.lua - · fontloader-font-oup.lua - · fontloader-font-otl.lua - · fontloader-font-oto.lua - · fontloader-font-otj.lua - · fontloader-font-ota.lua - · fontloader-font-ots.lua - · fontloader-font-osd.lua - · fontloader-font-ocl.lua - · fontloader-font-otc.lua - · fontloader-font-onr.lua - · fontloader-font-one.lua - · fontloader-font-afk.lua - · fontloader-fonts-tfm.lua - · fontloader-font-lua.lua - · fontloader-font-def.lua - · fontloader-font-shp.lua - · fontloader-fonts-def.lua - · fontloader-fonts-ext.lua - · fontloader-font-imp-tex.lua - · fontloader-font-imp-ligatures.lua - · fontloader-font-imp-italics.lua - · fontloader-font-imp-effects.lua - · fontloader-fonts-lig.lua - · fontloader-fonts-gbn.lua - ---info]]----------------------------------------------------------------------- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “data-con” 23a0f5386d46a1c157ae82a373e35fa0] --- - -if not modules then modules={} end modules ['data-con']={ - version=1.100, - comment="companion to luat-lib.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local setmetatable=setmetatable -local format,lower,gsub=string.format,string.lower,string.gsub -local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end) -local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end) -local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end) -containers=containers or {} -local containers=containers -containers.usecache=true -local getwritablepath=caches.getwritablepath -local getreadablepaths=caches.getreadablepaths -local cacheiswritable=caches.is_writable -local loaddatafromcache=caches.loaddata -local savedataincache=caches.savedata -local report_containers=logs.reporter("resolvers","containers") -local allocated={} -local mt={ - __index=function(t,k) - if k=="writable" then - local writable=getwritablepath(t.category,t.subcategory) or { "." } - t.writable=writable - return writable - elseif k=="readables" then - local readables=getreadablepaths(t.category,t.subcategory) or { "." } - t.readables=readables - return readables - end - end, - __storage__=true -} -function containers.define(category,subcategory,version,enabled) - if category and subcategory then - local c=allocated[category] - if not c then - c={} - allocated[category]=c - end - local s=c[subcategory] - if not s then - s={ - category=category, - subcategory=subcategory, - storage={}, - enabled=enabled, - version=version or math.pi, - trace=false, - } - setmetatable(s,mt) - c[subcategory]=s - end - return s - end -end -function containers.is_usable(container,name) - return container.enabled and caches and cacheiswritable(container.writable,name) -end -function containers.is_valid(container,name) - if name and name~="" then - local storage=container.storage[name] - return storage and storage.cache_version==container.version - else - return false - end -end -function containers.read(container,name) - local storage=container.storage - local stored=storage[name] - if not stored and container.enabled and caches and containers.usecache then - stored=loaddatafromcache(container.readables,name,container.writable) - if stored and stored.cache_version==container.version then - if trace_cache or trace_containers then - report_containers("action %a, category %a, name %a","load",container.subcategory,name) - end - else - stored=nil - end - storage[name]=stored - elseif stored then - if trace_cache or trace_containers then - report_containers("action %a, category %a, name %a","reuse",container.subcategory,name) - end - end - return stored -end -function containers.write(container,name,data,fast) - if data then - data.cache_version=container.version - if container.enabled and caches then - local unique=data.unique - local shared=data.shared - data.unique=nil - data.shared=nil - savedataincache(container.writable,name,data,fast) - if trace_cache or trace_containers then - report_containers("action %a, category %a, name %a","save",container.subcategory,name) - end - data.unique=unique - data.shared=shared - end - if trace_cache or trace_containers then - report_containers("action %a, category %a, name %a","store",container.subcategory,name) - end - container.storage[name]=data - end - return data -end -function containers.content(container,name) - return container.storage[name] -end -function containers.cleanname(name) - return (gsub(lower(name),"[^%w\128-\255]+","-")) -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “data-con”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “basics-nod” 4b5c3c63e19df1b3f37fae7f87c25bda] --- - -if not modules then modules={} end modules ['luatex-fonts-nod']={ - version=1.001, - comment="companion to luatex-fonts.lua", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -if context then - os.exit() -end -if tex.attribute[0]~=0 then - texio.write_nl("log","!") - texio.write_nl("log","! Attribute 0 is reserved for ConTeXt's font feature management and has to be") - texio.write_nl("log","! set to zero. Also, some attributes in the range 1-255 are used for special") - texio.write_nl("log","! purposes so setting them at the TeX end might break the font handler.") - texio.write_nl("log","!") - tex.attribute[0]=0 -end -attributes=attributes or {} -attributes.unsetvalue=-0x7FFFFFFF -local numbers,last={},127 -attributes.private=attributes.private or function(name) - local number=numbers[name] - if not number then - if last<255 then - last=last+1 - end - number=last - numbers[name]=number - end - return number -end -nodes={} -nodes.handlers={} -local nodecodes={} -local glyphcodes=node.subtypes("glyph") -local disccodes=node.subtypes("disc") -for k,v in next,node.types() do - v=string.gsub(v,"_","") - nodecodes[k]=v - nodecodes[v]=k -end -for k,v in next,glyphcodes do - glyphcodes[v]=k -end -for k,v in next,disccodes do - disccodes[v]=k -end -nodes.nodecodes=nodecodes -nodes.glyphcodes=glyphcodes -nodes.disccodes=disccodes -nodes.dirvalues={ lefttoright=0,righttoleft=1 } -nodes.handlers.protectglyphs=node.protect_glyphs -nodes.handlers.unprotectglyphs=node.unprotect_glyphs -local direct=node.direct -local nuts={} -nodes.nuts=nuts -local tonode=direct.tonode -local tonut=direct.todirect -nodes.tonode=tonode -nodes.tonut=tonut -nuts.tonode=tonode -nuts.tonut=tonut -nuts.getattr=direct.get_attribute -nuts.getboth=direct.getboth -nuts.getchar=direct.getchar -nuts.getdirection=direct.getdirection -nuts.getdisc=direct.getdisc -nuts.getreplace=direct.getreplace -nuts.getfield=direct.getfield -nuts.getfont=direct.getfont -nuts.getid=direct.getid -nuts.getkern=direct.getkern -nuts.getlist=direct.getlist -nuts.getnext=direct.getnext -nuts.getoffsets=direct.getoffsets -nuts.getoptions=direct.getoptions or function() return 0 end -nuts.getprev=direct.getprev -nuts.getsubtype=direct.getsubtype -nuts.getwidth=direct.getwidth -nuts.setattr=direct.setfield -nuts.setboth=direct.setboth -nuts.setchar=direct.setchar -nuts.setcomponents=direct.setcomponents -nuts.setdirection=direct.setdirection -nuts.setdisc=direct.setdisc -nuts.setreplace=direct.setreplace -nuts.setfield=setfield -nuts.setkern=direct.setkern -nuts.setlink=direct.setlink -nuts.setlist=direct.setlist -nuts.setnext=direct.setnext -nuts.setoffsets=direct.setoffsets -nuts.setprev=direct.setprev -nuts.setsplit=direct.setsplit -nuts.setsubtype=direct.setsubtype -nuts.setwidth=direct.setwidth -nuts.getglyphdata=nuts.getattr -nuts.setglyphdata=nuts.setattr -nuts.ischar=direct.is_char -nuts.isglyph=direct.is_glyph -nuts.copy=direct.copy -nuts.copy_list=direct.copy_list -nuts.copy_node=direct.copy -nuts.end_of_math=direct.end_of_math -nuts.flush=direct.flush -nuts.flush_list=direct.flush_list -nuts.flush_node=direct.flush_node -nuts.free=direct.free -nuts.insert_after=direct.insert_after -nuts.insert_before=direct.insert_before -nuts.is_node=direct.is_node -nuts.kerning=direct.kerning -nuts.ligaturing=direct.ligaturing -nuts.new=direct.new -nuts.remove=direct.remove -nuts.tail=direct.tail -nuts.traverse=direct.traverse -nuts.traverse_char=direct.traverse_char -nuts.traverse_glyph=direct.traverse_glyph -nuts.traverse_id=direct.traverse_id -local propertydata=direct.get_properties_table() -nodes.properties={ data=propertydata } -if direct.set_properties_mode then - direct.set_properties_mode(true,true) - function direct.set_properties_mode() end -end -nuts.getprop=function(n,k) - local p=propertydata[n] - if p then - return p[k] - end -end -nuts.setprop=function(n,k,v) - if v then - local p=propertydata[n] - if p then - p[k]=v - else - propertydata[n]={ [k]=v } - end - end -end -nodes.setprop=nodes.setproperty -nodes.getprop=nodes.getproperty -local setprev=nuts.setprev -local setnext=nuts.setnext -local getnext=nuts.getnext -local setlink=nuts.setlink -local getfield=nuts.getfield -local setfield=nuts.setfield -local getsubtype=nuts.getsubtype -local isglyph=nuts.isglyph -local find_tail=nuts.tail -local flush_list=nuts.flush_list -local flush_node=nuts.flush_node -local traverse_id=nuts.traverse_id -local copy_node=nuts.copy_node -local glyph_code=nodes.nodecodes.glyph -local ligature_code=nodes.glyphcodes.ligature -do - local p=nodecodes.localpar or nodecodes.local_par - if p then - nodecodes.par=p - nodecodes[p]="par" - nodecodes.localpar=p - nodecodes.local_par=p - end -end -do - local get_components=node.direct.getcomponents - local set_components=node.direct.setcomponents - local function copy_no_components(g,copyinjection) - local components=get_components(g) - if components then - set_components(g) - local n=copy_node(g) - if copyinjection then - copyinjection(n,g) - end - set_components(g,components) - return n - else - local n=copy_node(g) - if copyinjection then - copyinjection(n,g) - end - return n - end - end - local function copy_only_glyphs(current) - local head=nil - local previous=nil - for n in traverse_id(glyph_code,current) do - n=copy_node(n) - if head then - setlink(previous,n) - else - head=n - end - previous=n - end - return head - end - local function count_components(start,marks) - local char=isglyph(start) - if char then - if getsubtype(start)==ligature_code then - local n=0 - local components=get_components(start) - while components do - n=n+count_components(components,marks) - components=getnext(components) - end - return n - elseif not marks[char] then - return 1 - end - end - return 0 - end - local function flush_components() - end - nuts.set_components=set_components - nuts.get_components=get_components - nuts.copy_only_glyphs=copy_only_glyphs - nuts.copy_no_components=copy_no_components - nuts.count_components=count_components - nuts.flush_components=flush_components -end -nuts.uses_font=direct.uses_font -do - local dummy=tonut(node.new("glyph")) - nuts.traversers={ - glyph=nuts.traverse_id(nodecodes.glyph,dummy), - glue=nuts.traverse_id(nodecodes.glue,dummy), - disc=nuts.traverse_id(nodecodes.disc,dummy), - boundary=nuts.traverse_id(nodecodes.boundary,dummy), - char=nuts.traverse_char(dummy), - node=nuts.traverse(dummy), - } -end -if not nuts.setreplace then - local getdisc=nuts.getdisc - local setfield=nuts.setfield - function nuts.getreplace(n) - local _,_,h,_,_,t=getdisc(n,true) - return h,t - end - function nuts.setreplace(n,h) - setfield(n,"replace",h) - end -end -do - local getsubtype=nuts.getsubtype - function nuts.start_of_par(n) - local s=getsubtype(n) - return s==0 or s==2 - end -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “basics-nod”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “basics-chr” 64fafe4eaf55d64aead6513c1e74a024] --- - - -characters=characters or {} -characters.blockrange={} -characters.classifiers={ - [768]=5, - [769]=5, - [770]=5, - [771]=5, - [772]=5, - [773]=5, - [774]=5, - [775]=5, - [776]=5, - [777]=5, - [778]=5, - [779]=5, - [780]=5, - [781]=5, - [782]=5, - [783]=5, - [784]=5, - [785]=5, - [786]=5, - [787]=5, - [788]=5, - [789]=5, - [790]=5, - [791]=5, - [792]=5, - [793]=5, - [794]=5, - [795]=5, - [796]=5, - [797]=5, - [798]=5, - [799]=5, - [800]=5, - [801]=5, - [802]=5, - [803]=5, - [804]=5, - [805]=5, - [806]=5, - [807]=5, - [808]=5, - [809]=5, - [810]=5, - [811]=5, - [812]=5, - [813]=5, - [814]=5, - [815]=5, - [816]=5, - [817]=5, - [818]=5, - [819]=5, - [820]=5, - [821]=5, - [822]=5, - [823]=5, - [824]=5, - [825]=5, - [826]=5, - [827]=5, - [828]=5, - [829]=5, - [830]=5, - [831]=5, - [832]=5, - [833]=5, - [834]=5, - [835]=5, - [836]=5, - [837]=5, - [838]=5, - [839]=5, - [840]=5, - [841]=5, - [842]=5, - [843]=5, - [844]=5, - [845]=5, - [846]=5, - [847]=5, - [848]=5, - [849]=5, - [850]=5, - [851]=5, - [852]=5, - [853]=5, - [854]=5, - [855]=5, - [856]=5, - [857]=5, - [858]=5, - [859]=5, - [860]=5, - [861]=5, - [862]=5, - [863]=5, - [864]=5, - [865]=5, - [866]=5, - [867]=5, - [868]=5, - [869]=5, - [870]=5, - [871]=5, - [872]=5, - [873]=5, - [874]=5, - [875]=5, - [876]=5, - [877]=5, - [878]=5, - [879]=5, - [1155]=5, - [1156]=5, - [1157]=5, - [1158]=5, - [1159]=5, - [1425]=5, - [1426]=5, - [1427]=5, - [1428]=5, - [1429]=5, - [1430]=5, - [1431]=5, - [1432]=5, - [1433]=5, - [1434]=5, - [1435]=5, - [1436]=5, - [1437]=5, - [1438]=5, - [1439]=5, - [1440]=5, - [1441]=5, - [1442]=5, - [1443]=5, - [1444]=5, - [1445]=5, - [1446]=5, - [1447]=5, - [1448]=5, - [1449]=5, - [1450]=5, - [1451]=5, - [1452]=5, - [1453]=5, - [1454]=5, - [1455]=5, - [1456]=5, - [1457]=5, - [1458]=5, - [1459]=5, - [1460]=5, - [1461]=5, - [1462]=5, - [1463]=5, - [1464]=5, - [1465]=5, - [1466]=5, - [1467]=5, - [1468]=5, - [1469]=5, - [1471]=5, - [1473]=5, - [1474]=5, - [1476]=5, - [1477]=5, - [1479]=5, - [1536]=4, - [1537]=4, - [1538]=4, - [1539]=4, - [1540]=4, - [1541]=4, - [1542]=6, - [1543]=6, - [1544]=4, - [1545]=6, - [1546]=6, - [1547]=4, - [1548]=6, - [1549]=6, - [1550]=6, - [1551]=6, - [1552]=5, - [1553]=5, - [1554]=5, - [1555]=5, - [1556]=5, - [1557]=5, - [1558]=5, - [1559]=5, - [1560]=5, - [1561]=5, - [1562]=5, - [1563]=6, - [1564]=6, - [1566]=6, - [1567]=6, - [1568]=2, - [1569]=4, - [1570]=3, - [1571]=3, - [1572]=3, - [1573]=3, - [1574]=2, - [1575]=3, - [1576]=2, - [1577]=3, - [1578]=2, - [1579]=2, - [1580]=2, - [1581]=2, - [1582]=2, - [1583]=3, - [1584]=3, - [1585]=3, - [1586]=3, - [1587]=2, - [1588]=2, - [1589]=2, - [1590]=2, - [1591]=2, - [1592]=2, - [1593]=2, - [1594]=2, - [1595]=2, - [1596]=2, - [1597]=2, - [1598]=2, - [1599]=2, - [1600]=2, - [1601]=2, - [1602]=2, - [1603]=2, - [1604]=2, - [1605]=2, - [1606]=2, - [1607]=2, - [1608]=3, - [1609]=2, - [1610]=2, - [1611]=5, - [1612]=5, - [1613]=5, - [1614]=5, - [1615]=5, - [1616]=5, - [1617]=5, - [1618]=5, - [1619]=5, - [1620]=5, - [1621]=5, - [1622]=5, - [1623]=5, - [1624]=5, - [1625]=5, - [1626]=5, - [1627]=5, - [1628]=5, - [1629]=5, - [1630]=5, - [1631]=5, - [1632]=6, - [1633]=6, - [1634]=6, - [1635]=6, - [1636]=6, - [1637]=6, - [1638]=6, - [1639]=6, - [1640]=6, - [1641]=6, - [1642]=6, - [1643]=6, - [1644]=6, - [1645]=6, - [1646]=2, - [1647]=2, - [1648]=5, - [1649]=3, - [1650]=3, - [1651]=3, - [1652]=4, - [1653]=3, - [1654]=3, - [1655]=3, - [1656]=2, - [1657]=2, - [1658]=2, - [1659]=2, - [1660]=2, - [1661]=2, - [1662]=2, - [1663]=2, - [1664]=2, - [1665]=2, - [1666]=2, - [1667]=2, - [1668]=2, - [1669]=2, - [1670]=2, - [1671]=2, - [1672]=3, - [1673]=3, - [1674]=3, - [1675]=3, - [1676]=3, - [1677]=3, - [1678]=3, - [1679]=3, - [1680]=3, - [1681]=3, - [1682]=3, - [1683]=3, - [1684]=3, - [1685]=3, - [1686]=3, - [1687]=3, - [1688]=3, - [1689]=3, - [1690]=2, - [1691]=2, - [1692]=2, - [1693]=2, - [1694]=2, - [1695]=2, - [1696]=2, - [1697]=2, - [1698]=2, - [1699]=2, - [1700]=2, - [1701]=2, - [1702]=2, - [1703]=2, - [1704]=2, - [1705]=2, - [1706]=2, - [1707]=2, - [1708]=2, - [1709]=2, - [1710]=2, - [1711]=2, - [1712]=2, - [1713]=2, - [1714]=2, - [1715]=2, - [1716]=2, - [1717]=2, - [1718]=2, - [1719]=2, - [1720]=2, - [1721]=2, - [1722]=2, - [1723]=2, - [1724]=2, - [1725]=2, - [1726]=2, - [1727]=2, - [1728]=3, - [1729]=2, - [1730]=2, - [1731]=3, - [1732]=3, - [1733]=3, - [1734]=3, - [1735]=3, - [1736]=3, - [1737]=3, - [1738]=3, - [1739]=3, - [1740]=2, - [1741]=3, - [1742]=2, - [1743]=3, - [1744]=2, - [1745]=2, - [1746]=3, - [1747]=3, - [1748]=6, - [1749]=3, - [1750]=5, - [1751]=5, - [1752]=5, - [1753]=5, - [1754]=5, - [1755]=5, - [1756]=5, - [1757]=4, - [1758]=6, - [1759]=5, - [1760]=5, - [1761]=5, - [1762]=5, - [1763]=5, - [1764]=5, - [1765]=6, - [1766]=6, - [1767]=5, - [1768]=5, - [1769]=6, - [1770]=5, - [1771]=5, - [1772]=5, - [1773]=5, - [1774]=3, - [1775]=3, - [1776]=6, - [1777]=6, - [1778]=6, - [1779]=6, - [1780]=6, - [1781]=6, - [1782]=6, - [1783]=6, - [1784]=6, - [1785]=6, - [1786]=2, - [1787]=2, - [1788]=2, - [1789]=6, - [1790]=6, - [1791]=2, - [1792]=6, - [1793]=6, - [1794]=6, - [1795]=6, - [1796]=6, - [1797]=6, - [1798]=6, - [1799]=6, - [1800]=6, - [1801]=6, - [1802]=6, - [1803]=6, - [1804]=6, - [1805]=6, - [1808]=3, - [1809]=5, - [1810]=2, - [1811]=2, - [1812]=2, - [1813]=3, - [1814]=3, - [1815]=3, - [1816]=3, - [1817]=3, - [1818]=2, - [1819]=2, - [1820]=2, - [1821]=2, - [1822]=3, - [1823]=2, - [1824]=2, - [1825]=2, - [1826]=2, - [1827]=2, - [1828]=2, - [1829]=2, - [1830]=2, - [1831]=2, - [1832]=3, - [1833]=2, - [1834]=3, - [1835]=2, - [1836]=3, - [1837]=2, - [1838]=2, - [1839]=3, - [1840]=5, - [1841]=5, - [1842]=5, - [1843]=5, - [1844]=5, - [1845]=5, - [1846]=5, - [1847]=5, - [1848]=5, - [1849]=5, - [1850]=5, - [1851]=5, - [1852]=5, - [1853]=5, - [1854]=5, - [1855]=5, - [1856]=5, - [1857]=5, - [1858]=5, - [1859]=5, - [1860]=5, - [1861]=5, - [1862]=5, - [1863]=5, - [1864]=5, - [1865]=5, - [1866]=5, - [1869]=3, - [1870]=2, - [1871]=2, - [1872]=2, - [1873]=2, - [1874]=2, - [1875]=2, - [1876]=2, - [1877]=2, - [1878]=2, - [1879]=2, - [1880]=2, - [1881]=3, - [1882]=3, - [1883]=3, - [1884]=2, - [1885]=2, - [1886]=2, - [1887]=2, - [1888]=2, - [1889]=2, - [1890]=2, - [1891]=2, - [1892]=2, - [1893]=2, - [1894]=2, - [1895]=2, - [1896]=2, - [1897]=2, - [1898]=2, - [1899]=3, - [1900]=3, - [1901]=2, - [1902]=2, - [1903]=2, - [1904]=2, - [1905]=3, - [1906]=2, - [1907]=3, - [1908]=3, - [1909]=2, - [1910]=2, - [1911]=2, - [1912]=3, - [1913]=3, - [1914]=2, - [1915]=2, - [1916]=2, - [1917]=2, - [1918]=2, - [1919]=2, - [1958]=5, - [1959]=5, - [1960]=5, - [1961]=5, - [1962]=5, - [1963]=5, - [1964]=5, - [1965]=5, - [1966]=5, - [1967]=5, - [1968]=5, - [1984]=6, - [1985]=6, - [1986]=6, - [1987]=6, - [1988]=6, - [1989]=6, - [1990]=6, - [1991]=6, - [1992]=6, - [1993]=6, - [1994]=2, - [1995]=2, - [1996]=2, - [1997]=2, - [1998]=2, - [1999]=2, - [2000]=2, - [2001]=2, - [2002]=2, - [2003]=2, - [2004]=2, - [2005]=2, - [2006]=2, - [2007]=2, - [2008]=2, - [2009]=2, - [2010]=2, - [2011]=2, - [2012]=2, - [2013]=2, - [2014]=2, - [2015]=2, - [2016]=2, - [2017]=2, - [2018]=2, - [2019]=2, - [2020]=2, - [2021]=2, - [2022]=2, - [2023]=2, - [2024]=2, - [2025]=2, - [2026]=2, - [2027]=5, - [2028]=5, - [2029]=5, - [2030]=5, - [2031]=5, - [2032]=5, - [2033]=5, - [2034]=5, - [2035]=5, - [2036]=6, - [2037]=6, - [2038]=6, - [2039]=6, - [2040]=6, - [2041]=6, - [2042]=2, - [2045]=5, - [2046]=6, - [2047]=6, - [2070]=5, - [2071]=5, - [2072]=5, - [2073]=5, - [2075]=5, - [2076]=5, - [2077]=5, - [2078]=5, - [2079]=5, - [2080]=5, - [2081]=5, - [2082]=5, - [2083]=5, - [2085]=5, - [2086]=5, - [2087]=5, - [2089]=5, - [2090]=5, - [2091]=5, - [2092]=5, - [2093]=5, - [2112]=3, - [2113]=2, - [2114]=2, - [2115]=2, - [2116]=2, - [2117]=2, - [2118]=3, - [2119]=3, - [2120]=2, - [2121]=3, - [2122]=2, - [2123]=2, - [2124]=2, - [2125]=2, - [2126]=2, - [2127]=2, - [2128]=2, - [2129]=2, - [2130]=2, - [2131]=2, - [2132]=3, - [2133]=2, - [2134]=4, - [2135]=4, - [2136]=4, - [2137]=5, - [2138]=5, - [2139]=5, - [2144]=2, - [2145]=4, - [2146]=2, - [2147]=2, - [2148]=2, - [2149]=2, - [2150]=4, - [2151]=3, - [2152]=2, - [2153]=3, - [2154]=3, - [2208]=2, - [2209]=2, - [2210]=2, - [2211]=2, - [2212]=2, - [2213]=2, - [2214]=2, - [2215]=2, - [2216]=2, - [2217]=2, - [2218]=3, - [2219]=3, - [2220]=3, - [2221]=4, - [2222]=3, - [2223]=2, - [2224]=2, - [2225]=3, - [2226]=3, - [2227]=2, - [2228]=2, - [2230]=2, - [2231]=2, - [2232]=2, - [2233]=3, - [2234]=2, - [2235]=2, - [2236]=2, - [2237]=2, - [2259]=5, - [2260]=5, - [2261]=5, - [2262]=5, - [2263]=5, - [2264]=5, - [2265]=5, - [2266]=5, - [2267]=5, - [2268]=5, - [2269]=5, - [2270]=5, - [2271]=5, - [2272]=5, - [2273]=5, - [2274]=4, - [2275]=5, - [2276]=5, - [2277]=5, - [2278]=5, - [2279]=5, - [2280]=5, - [2281]=5, - [2282]=5, - [2283]=5, - [2284]=5, - [2285]=5, - [2286]=5, - [2287]=5, - [2288]=5, - [2289]=5, - [2290]=5, - [2291]=5, - [2292]=5, - [2293]=5, - [2294]=5, - [2295]=5, - [2296]=5, - [2297]=5, - [2298]=5, - [2299]=5, - [2300]=5, - [2301]=5, - [2302]=5, - [2303]=5, - [2304]=5, - [2305]=5, - [2306]=5, - [2362]=5, - [2364]=5, - [2369]=5, - [2370]=5, - [2371]=5, - [2372]=5, - [2373]=5, - [2374]=5, - [2375]=5, - [2376]=5, - [2381]=5, - [2385]=5, - [2386]=5, - [2387]=5, - [2388]=5, - [2389]=5, - [2390]=5, - [2391]=5, - [2402]=5, - [2403]=5, - [2433]=5, - [2492]=5, - [2497]=5, - [2498]=5, - [2499]=5, - [2500]=5, - [2509]=5, - [2530]=5, - [2531]=5, - [2558]=5, - [2561]=5, - [2562]=5, - [2620]=5, - [2625]=5, - [2626]=5, - [2631]=5, - [2632]=5, - [2635]=5, - [2636]=5, - [2637]=5, - [2641]=5, - [2672]=5, - [2673]=5, - [2677]=5, - [2689]=5, - [2690]=5, - [2748]=5, - [2753]=5, - [2754]=5, - [2755]=5, - [2756]=5, - [2757]=5, - [2759]=5, - [2760]=5, - [2765]=5, - [2786]=5, - [2787]=5, - [2810]=5, - [2811]=5, - [2812]=5, - [2813]=5, - [2814]=5, - [2815]=5, - [2817]=5, - [2876]=5, - [2879]=5, - [2881]=5, - [2882]=5, - [2883]=5, - [2884]=5, - [2893]=5, - [2902]=5, - [2914]=5, - [2915]=5, - [2946]=5, - [3008]=5, - [3021]=5, - [3072]=5, - [3076]=5, - [3134]=5, - [3135]=5, - [3136]=5, - [3142]=5, - [3143]=5, - [3144]=5, - [3146]=5, - [3147]=5, - [3148]=5, - [3149]=5, - [3157]=5, - [3158]=5, - [3170]=5, - [3171]=5, - [3201]=5, - [3260]=5, - [3263]=5, - [3270]=5, - [3276]=5, - [3277]=5, - [3298]=5, - [3299]=5, - [3328]=5, - [3329]=5, - [3387]=5, - [3388]=5, - [3393]=5, - [3394]=5, - [3395]=5, - [3396]=5, - [3405]=5, - [3426]=5, - [3427]=5, - [3530]=5, - [3538]=5, - [3539]=5, - [3540]=5, - [3542]=5, - [3633]=5, - [3636]=5, - [3637]=5, - [3638]=5, - [3639]=5, - [3640]=5, - [3641]=5, - [3642]=5, - [3655]=5, - [3656]=5, - [3657]=5, - [3658]=5, - [3659]=5, - [3660]=5, - [3661]=5, - [3662]=5, - [3761]=5, - [3764]=5, - [3765]=5, - [3766]=5, - [3767]=5, - [3768]=5, - [3769]=5, - [3770]=5, - [3771]=5, - [3772]=5, - [3784]=5, - [3785]=5, - [3786]=5, - [3787]=5, - [3788]=5, - [3789]=5, - [3864]=5, - [3865]=5, - [3893]=5, - [3895]=5, - [3897]=5, - [3953]=5, - [3954]=5, - [3955]=5, - [3956]=5, - [3957]=5, - [3958]=5, - [3959]=5, - [3960]=5, - [3961]=5, - [3962]=5, - [3963]=5, - [3964]=5, - [3965]=5, - [3966]=5, - [3968]=5, - [3969]=5, - [3970]=5, - [3971]=5, - [3972]=5, - [3974]=5, - [3975]=5, - [3981]=5, - [3982]=5, - [3983]=5, - [3984]=5, - [3985]=5, - [3986]=5, - [3987]=5, - [3988]=5, - [3989]=5, - [3990]=5, - [3991]=5, - [3993]=5, - [3994]=5, - [3995]=5, - [3996]=5, - [3997]=5, - [3998]=5, - [3999]=5, - [4000]=5, - [4001]=5, - [4002]=5, - [4003]=5, - [4004]=5, - [4005]=5, - [4006]=5, - [4007]=5, - [4008]=5, - [4009]=5, - [4010]=5, - [4011]=5, - [4012]=5, - [4013]=5, - [4014]=5, - [4015]=5, - [4016]=5, - [4017]=5, - [4018]=5, - [4019]=5, - [4020]=5, - [4021]=5, - [4022]=5, - [4023]=5, - [4024]=5, - [4025]=5, - [4026]=5, - [4027]=5, - [4028]=5, - [4038]=5, - [4141]=5, - [4142]=5, - [4143]=5, - [4144]=5, - [4146]=5, - [4147]=5, - [4148]=5, - [4149]=5, - [4150]=5, - [4151]=5, - [4153]=5, - [4154]=5, - [4157]=5, - [4158]=5, - [4184]=5, - [4185]=5, - [4190]=5, - [4191]=5, - [4192]=5, - [4209]=5, - [4210]=5, - [4211]=5, - [4212]=5, - [4226]=5, - [4229]=5, - [4230]=5, - [4237]=5, - [4253]=5, - [4957]=5, - [4958]=5, - [4959]=5, - [5906]=5, - [5907]=5, - [5908]=5, - [5938]=5, - [5939]=5, - [5940]=5, - [5970]=5, - [5971]=5, - [6002]=5, - [6003]=5, - [6071]=5, - [6072]=5, - [6073]=5, - [6074]=5, - [6075]=5, - [6076]=5, - [6077]=5, - [6086]=5, - [6089]=5, - [6090]=5, - [6091]=5, - [6092]=5, - [6093]=5, - [6094]=5, - [6095]=5, - [6096]=5, - [6097]=5, - [6098]=5, - [6099]=5, - [6109]=5, - [6150]=4, - [6151]=2, - [6154]=2, - [6155]=5, - [6156]=5, - [6157]=5, - [6158]=4, - [6176]=2, - [6177]=2, - [6178]=2, - [6179]=2, - [6180]=2, - [6181]=2, - [6182]=2, - [6183]=2, - [6184]=2, - [6185]=2, - [6186]=2, - [6187]=2, - [6188]=2, - [6189]=2, - [6190]=2, - [6191]=2, - [6192]=2, - [6193]=2, - [6194]=2, - [6195]=2, - [6196]=2, - [6197]=2, - [6198]=2, - [6199]=2, - [6200]=2, - [6201]=2, - [6202]=2, - [6203]=2, - [6204]=2, - [6205]=2, - [6206]=2, - [6207]=2, - [6208]=2, - [6209]=2, - [6210]=2, - [6211]=2, - [6212]=2, - [6213]=2, - [6214]=2, - [6215]=2, - [6216]=2, - [6217]=2, - [6218]=2, - [6219]=2, - [6220]=2, - [6221]=2, - [6222]=2, - [6223]=2, - [6224]=2, - [6225]=2, - [6226]=2, - [6227]=2, - [6228]=2, - [6229]=2, - [6230]=2, - [6231]=2, - [6232]=2, - [6233]=2, - [6234]=2, - [6235]=2, - [6236]=2, - [6237]=2, - [6238]=2, - [6239]=2, - [6240]=2, - [6241]=2, - [6242]=2, - [6243]=2, - [6244]=2, - [6245]=2, - [6246]=2, - [6247]=2, - [6248]=2, - [6249]=2, - [6250]=2, - [6251]=2, - [6252]=2, - [6253]=2, - [6254]=2, - [6255]=2, - [6256]=2, - [6257]=2, - [6258]=2, - [6259]=2, - [6260]=2, - [6261]=2, - [6262]=2, - [6263]=2, - [6264]=2, - [6272]=4, - [6273]=4, - [6274]=4, - [6275]=4, - [6276]=4, - [6279]=2, - [6280]=2, - [6281]=2, - [6282]=2, - [6283]=2, - [6284]=2, - [6285]=2, - [6286]=2, - [6287]=2, - [6288]=2, - [6289]=2, - [6290]=2, - [6291]=2, - [6292]=2, - [6293]=2, - [6294]=2, - [6295]=2, - [6296]=2, - [6297]=2, - [6298]=2, - [6299]=2, - [6300]=2, - [6301]=2, - [6302]=2, - [6303]=2, - [6304]=2, - [6305]=2, - [6306]=2, - [6307]=2, - [6308]=2, - [6309]=2, - [6310]=2, - [6311]=2, - [6312]=2, - [6313]=5, - [6314]=2, - [6432]=5, - [6433]=5, - [6434]=5, - [6439]=5, - [6440]=5, - [6450]=5, - [6457]=5, - [6458]=5, - [6459]=5, - [6679]=5, - [6680]=5, - [6742]=5, - [6744]=5, - [6745]=5, - [6746]=5, - [6747]=5, - [6748]=5, - [6749]=5, - [6750]=5, - [6752]=5, - [6754]=5, - [6757]=5, - [6758]=5, - [6759]=5, - [6760]=5, - [6761]=5, - [6762]=5, - [6763]=5, - [6764]=5, - [6771]=5, - [6772]=5, - [6773]=5, - [6774]=5, - [6775]=5, - [6776]=5, - [6777]=5, - [6778]=5, - [6779]=5, - [6780]=5, - [6783]=5, - [6832]=5, - [6833]=5, - [6834]=5, - [6835]=5, - [6836]=5, - [6837]=5, - [6838]=5, - [6839]=5, - [6840]=5, - [6841]=5, - [6842]=5, - [6843]=5, - [6844]=5, - [6845]=5, - [6912]=5, - [6913]=5, - [6914]=5, - [6915]=5, - [6964]=5, - [6966]=5, - [6967]=5, - [6968]=5, - [6969]=5, - [6970]=5, - [6972]=5, - [6978]=5, - [7019]=5, - [7020]=5, - [7021]=5, - [7022]=5, - [7023]=5, - [7024]=5, - [7025]=5, - [7026]=5, - [7027]=5, - [7040]=5, - [7041]=5, - [7074]=5, - [7075]=5, - [7076]=5, - [7077]=5, - [7080]=5, - [7081]=5, - [7083]=5, - [7142]=5, - [7144]=5, - [7145]=5, - [7149]=5, - [7151]=5, - [7152]=5, - [7153]=5, - [7212]=5, - [7213]=5, - [7214]=5, - [7215]=5, - [7216]=5, - [7217]=5, - [7218]=5, - [7219]=5, - [7222]=5, - [7223]=5, - [7376]=5, - [7377]=5, - [7378]=5, - [7380]=5, - [7381]=5, - [7382]=5, - [7383]=5, - [7384]=5, - [7385]=5, - [7386]=5, - [7387]=5, - [7388]=5, - [7389]=5, - [7390]=5, - [7391]=5, - [7392]=5, - [7394]=5, - [7395]=5, - [7396]=5, - [7397]=5, - [7398]=5, - [7399]=5, - [7400]=5, - [7405]=5, - [7412]=5, - [7416]=5, - [7417]=5, - [7616]=5, - [7617]=5, - [7618]=5, - [7619]=5, - [7620]=5, - [7621]=5, - [7622]=5, - [7623]=5, - [7624]=5, - [7625]=5, - [7626]=5, - [7627]=5, - [7628]=5, - [7629]=5, - [7630]=5, - [7631]=5, - [7632]=5, - [7633]=5, - [7634]=5, - [7635]=5, - [7636]=5, - [7637]=5, - [7638]=5, - [7639]=5, - [7640]=5, - [7641]=5, - [7642]=5, - [7643]=5, - [7644]=5, - [7645]=5, - [7646]=5, - [7647]=5, - [7648]=5, - [7649]=5, - [7650]=5, - [7651]=5, - [7652]=5, - [7653]=5, - [7654]=5, - [7655]=5, - [7656]=5, - [7657]=5, - [7658]=5, - [7659]=5, - [7660]=5, - [7661]=5, - [7662]=5, - [7663]=5, - [7664]=5, - [7665]=5, - [7666]=5, - [7667]=5, - [7668]=5, - [7669]=5, - [7670]=5, - [7671]=5, - [7672]=5, - [7673]=5, - [7675]=5, - [7676]=5, - [7677]=5, - [7678]=5, - [7679]=5, - [8204]=4, - [8205]=2, - [8239]=4, - [8294]=4, - [8295]=4, - [8296]=4, - [8297]=4, - [8400]=5, - [8401]=5, - [8402]=5, - [8403]=5, - [8404]=5, - [8405]=5, - [8406]=5, - [8407]=5, - [8408]=5, - [8409]=5, - [8410]=5, - [8411]=5, - [8412]=5, - [8417]=5, - [8421]=5, - [8422]=5, - [8423]=5, - [8424]=5, - [8425]=5, - [8426]=5, - [8427]=5, - [8428]=5, - [8429]=5, - [8430]=5, - [8431]=5, - [8432]=5, - [11503]=5, - [11504]=5, - [11505]=5, - [11647]=5, - [11744]=5, - [11745]=5, - [11746]=5, - [11747]=5, - [11748]=5, - [11749]=5, - [11750]=5, - [11751]=5, - [11752]=5, - [11753]=5, - [11754]=5, - [11755]=5, - [11756]=5, - [11757]=5, - [11758]=5, - [11759]=5, - [11760]=5, - [11761]=5, - [11762]=5, - [11763]=5, - [11764]=5, - [11765]=5, - [11766]=5, - [11767]=5, - [11768]=5, - [11769]=5, - [11770]=5, - [11771]=5, - [11772]=5, - [11773]=5, - [11774]=5, - [11775]=5, - [12330]=5, - [12331]=5, - [12332]=5, - [12333]=5, - [12334]=5, - [12335]=5, - [12441]=5, - [12442]=5, - [42607]=5, - [42612]=5, - [42613]=5, - [42614]=5, - [42615]=5, - [42616]=5, - [42617]=5, - [42618]=5, - [42619]=5, - [42620]=5, - [42621]=5, - [42654]=5, - [42655]=5, - [42736]=5, - [42737]=5, - [43014]=5, - [43019]=5, - [43045]=5, - [43046]=5, - [43072]=2, - [43073]=2, - [43074]=2, - [43075]=2, - [43076]=2, - [43077]=2, - [43078]=2, - [43079]=2, - [43080]=2, - [43081]=2, - [43082]=2, - [43083]=2, - [43084]=2, - [43085]=2, - [43086]=2, - [43087]=2, - [43088]=2, - [43089]=2, - [43090]=2, - [43091]=2, - [43092]=2, - [43093]=2, - [43094]=2, - [43095]=2, - [43096]=2, - [43097]=2, - [43098]=2, - [43099]=2, - [43100]=2, - [43101]=2, - [43102]=2, - [43103]=2, - [43104]=2, - [43105]=2, - [43106]=2, - [43107]=2, - [43108]=2, - [43109]=2, - [43110]=2, - [43111]=2, - [43112]=2, - [43113]=2, - [43114]=2, - [43115]=2, - [43116]=2, - [43117]=2, - [43118]=2, - [43119]=2, - [43120]=2, - [43121]=2, - [43122]=1, - [43123]=4, - [43204]=5, - [43205]=5, - [43232]=5, - [43233]=5, - [43234]=5, - [43235]=5, - [43236]=5, - [43237]=5, - [43238]=5, - [43239]=5, - [43240]=5, - [43241]=5, - [43242]=5, - [43243]=5, - [43244]=5, - [43245]=5, - [43246]=5, - [43247]=5, - [43248]=5, - [43249]=5, - [43263]=5, - [43302]=5, - [43303]=5, - [43304]=5, - [43305]=5, - [43306]=5, - [43307]=5, - [43308]=5, - [43309]=5, - [43335]=5, - [43336]=5, - [43337]=5, - [43338]=5, - [43339]=5, - [43340]=5, - [43341]=5, - [43342]=5, - [43343]=5, - [43344]=5, - [43345]=5, - [43392]=5, - [43393]=5, - [43394]=5, - [43443]=5, - [43446]=5, - [43447]=5, - [43448]=5, - [43449]=5, - [43452]=5, - [43493]=5, - [43561]=5, - [43562]=5, - [43563]=5, - [43564]=5, - [43565]=5, - [43566]=5, - [43569]=5, - [43570]=5, - [43573]=5, - [43574]=5, - [43587]=5, - [43596]=5, - [43644]=5, - [43696]=5, - [43698]=5, - [43699]=5, - [43700]=5, - [43703]=5, - [43704]=5, - [43710]=5, - [43711]=5, - [43713]=5, - [43756]=5, - [43757]=5, - [43766]=5, - [44005]=5, - [44008]=5, - [44013]=5, - [64286]=5, - [65056]=5, - [65057]=5, - [65058]=5, - [65059]=5, - [65060]=5, - [65061]=5, - [65062]=5, - [65063]=5, - [65064]=5, - [65065]=5, - [65066]=5, - [65067]=5, - [65068]=5, - [65069]=5, - [65070]=5, - [65071]=5, - [66045]=5, - [66272]=5, - [66422]=5, - [66423]=5, - [66424]=5, - [66425]=5, - [66426]=5, - [68097]=5, - [68098]=5, - [68099]=5, - [68101]=5, - [68102]=5, - [68108]=5, - [68109]=5, - [68110]=5, - [68111]=5, - [68152]=5, - [68153]=5, - [68154]=5, - [68159]=5, - [68288]=2, - [68289]=2, - [68290]=2, - [68291]=2, - [68292]=2, - [68293]=3, - [68294]=4, - [68295]=3, - [68296]=4, - [68297]=3, - [68298]=3, - [68299]=4, - [68300]=4, - [68301]=1, - [68302]=3, - [68303]=3, - [68304]=3, - [68305]=3, - [68306]=3, - [68307]=2, - [68308]=2, - [68309]=2, - [68310]=2, - [68311]=1, - [68312]=2, - [68313]=2, - [68314]=2, - [68315]=2, - [68316]=2, - [68317]=3, - [68318]=2, - [68319]=2, - [68320]=2, - [68321]=3, - [68322]=4, - [68323]=4, - [68324]=3, - [68325]=5, - [68326]=5, - [68331]=2, - [68332]=2, - [68333]=2, - [68334]=2, - [68335]=3, - [68480]=2, - [68481]=3, - [68482]=2, - [68483]=3, - [68484]=3, - [68485]=3, - [68486]=2, - [68487]=2, - [68488]=2, - [68489]=3, - [68490]=2, - [68491]=2, - [68492]=3, - [68493]=2, - [68494]=3, - [68495]=3, - [68496]=2, - [68497]=3, - [68521]=3, - [68522]=3, - [68523]=3, - [68524]=3, - [68525]=2, - [68526]=2, - [68527]=4, - [68864]=1, - [68865]=2, - [68866]=2, - [68867]=2, - [68868]=2, - [68869]=2, - [68870]=2, - [68871]=2, - [68872]=2, - [68873]=2, - [68874]=2, - [68875]=2, - [68876]=2, - [68877]=2, - [68878]=2, - [68879]=2, - [68880]=2, - [68881]=2, - [68882]=2, - [68883]=2, - [68884]=2, - [68885]=2, - [68886]=2, - [68887]=2, - [68888]=2, - [68889]=2, - [68890]=2, - [68891]=2, - [68892]=2, - [68893]=2, - [68894]=2, - [68895]=2, - [68896]=2, - [68897]=2, - [68898]=3, - [68899]=2, - [68900]=5, - [68901]=5, - [68902]=5, - [68903]=5, - [69424]=2, - [69425]=2, - [69426]=2, - [69427]=3, - [69428]=2, - [69429]=2, - [69430]=2, - [69431]=2, - [69432]=2, - [69433]=2, - [69434]=2, - [69435]=2, - [69436]=2, - [69437]=2, - [69438]=2, - [69439]=2, - [69440]=2, - [69441]=2, - [69442]=2, - [69443]=2, - [69444]=2, - [69445]=4, - [69446]=5, - [69447]=5, - [69448]=5, - [69449]=5, - [69450]=5, - [69451]=5, - [69452]=5, - [69453]=5, - [69454]=5, - [69455]=5, - [69456]=5, - [69457]=2, - [69458]=2, - [69459]=2, - [69460]=3, - [69633]=5, - [69688]=5, - [69689]=5, - [69690]=5, - [69691]=5, - [69692]=5, - [69693]=5, - [69694]=5, - [69695]=5, - [69696]=5, - [69697]=5, - [69698]=5, - [69699]=5, - [69700]=5, - [69701]=5, - [69702]=5, - [69759]=5, - [69760]=5, - [69761]=5, - [69811]=5, - [69812]=5, - [69813]=5, - [69814]=5, - [69817]=5, - [69818]=5, - [69821]=4, - [69837]=4, - [69888]=5, - [69889]=5, - [69890]=5, - [69927]=5, - [69928]=5, - [69929]=5, - [69930]=5, - [69931]=5, - [69933]=5, - [69934]=5, - [69935]=5, - [69936]=5, - [69937]=5, - [69938]=5, - [69939]=5, - [69940]=5, - [70003]=5, - [70016]=5, - [70017]=5, - [70070]=5, - [70071]=5, - [70072]=5, - [70073]=5, - [70074]=5, - [70075]=5, - [70076]=5, - [70077]=5, - [70078]=5, - [70090]=5, - [70091]=5, - [70092]=5, - [70191]=5, - [70192]=5, - [70193]=5, - [70196]=5, - [70198]=5, - [70199]=5, - [70206]=5, - [70367]=5, - [70371]=5, - [70372]=5, - [70373]=5, - [70374]=5, - [70375]=5, - [70376]=5, - [70377]=5, - [70378]=5, - [70400]=5, - [70401]=5, - [70459]=5, - [70460]=5, - [70464]=5, - [70502]=5, - [70503]=5, - [70504]=5, - [70505]=5, - [70506]=5, - [70507]=5, - [70508]=5, - [70512]=5, - [70513]=5, - [70514]=5, - [70515]=5, - [70516]=5, - [70712]=5, - [70713]=5, - [70714]=5, - [70715]=5, - [70716]=5, - [70717]=5, - [70718]=5, - [70719]=5, - [70722]=5, - [70723]=5, - [70724]=5, - [70726]=5, - [70750]=5, - [70835]=5, - [70836]=5, - [70837]=5, - [70838]=5, - [70839]=5, - [70840]=5, - [70842]=5, - [70847]=5, - [70848]=5, - [70850]=5, - [70851]=5, - [71090]=5, - [71091]=5, - [71092]=5, - [71093]=5, - [71100]=5, - [71101]=5, - [71103]=5, - [71104]=5, - [71132]=5, - [71133]=5, - [71219]=5, - [71220]=5, - [71221]=5, - [71222]=5, - [71223]=5, - [71224]=5, - [71225]=5, - [71226]=5, - [71229]=5, - [71231]=5, - [71232]=5, - [71339]=5, - [71341]=5, - [71344]=5, - [71345]=5, - [71346]=5, - [71347]=5, - [71348]=5, - [71349]=5, - [71351]=5, - [71453]=5, - [71454]=5, - [71455]=5, - [71458]=5, - [71459]=5, - [71460]=5, - [71461]=5, - [71463]=5, - [71464]=5, - [71465]=5, - [71466]=5, - [71467]=5, - [71727]=5, - [71728]=5, - [71729]=5, - [71730]=5, - [71731]=5, - [71732]=5, - [71733]=5, - [71734]=5, - [71735]=5, - [71737]=5, - [71738]=5, - [72148]=5, - [72149]=5, - [72150]=5, - [72151]=5, - [72154]=5, - [72155]=5, - [72160]=5, - [72193]=5, - [72194]=5, - [72195]=5, - [72196]=5, - [72197]=5, - [72198]=5, - [72201]=5, - [72202]=5, - [72243]=5, - [72244]=5, - [72245]=5, - [72246]=5, - [72247]=5, - [72248]=5, - [72251]=5, - [72252]=5, - [72253]=5, - [72254]=5, - [72263]=5, - [72273]=5, - [72274]=5, - [72275]=5, - [72276]=5, - [72277]=5, - [72278]=5, - [72281]=5, - [72282]=5, - [72283]=5, - [72330]=5, - [72331]=5, - [72332]=5, - [72333]=5, - [72334]=5, - [72335]=5, - [72336]=5, - [72337]=5, - [72338]=5, - [72339]=5, - [72340]=5, - [72341]=5, - [72342]=5, - [72344]=5, - [72345]=5, - [72752]=5, - [72753]=5, - [72754]=5, - [72755]=5, - [72756]=5, - [72757]=5, - [72758]=5, - [72760]=5, - [72761]=5, - [72762]=5, - [72763]=5, - [72764]=5, - [72765]=5, - [72767]=5, - [72850]=5, - [72851]=5, - [72852]=5, - [72853]=5, - [72854]=5, - [72855]=5, - [72856]=5, - [72857]=5, - [72858]=5, - [72859]=5, - [72860]=5, - [72861]=5, - [72862]=5, - [72863]=5, - [72864]=5, - [72865]=5, - [72866]=5, - [72867]=5, - [72868]=5, - [72869]=5, - [72870]=5, - [72871]=5, - [72874]=5, - [72875]=5, - [72876]=5, - [72877]=5, - [72878]=5, - [72879]=5, - [72880]=5, - [72882]=5, - [72883]=5, - [72885]=5, - [72886]=5, - [73009]=5, - [73010]=5, - [73011]=5, - [73012]=5, - [73013]=5, - [73014]=5, - [73018]=5, - [73020]=5, - [73021]=5, - [73023]=5, - [73024]=5, - [73025]=5, - [73026]=5, - [73027]=5, - [73028]=5, - [73029]=5, - [73031]=5, - [73104]=5, - [73105]=5, - [73109]=5, - [73111]=5, - [73459]=5, - [73460]=5, - [92912]=5, - [92913]=5, - [92914]=5, - [92915]=5, - [92916]=5, - [92976]=5, - [92977]=5, - [92978]=5, - [92979]=5, - [92980]=5, - [92981]=5, - [92982]=5, - [94031]=5, - [94095]=5, - [94096]=5, - [94097]=5, - [94098]=5, - [113821]=5, - [113822]=5, - [119143]=5, - [119144]=5, - [119145]=5, - [119163]=5, - [119164]=5, - [119165]=5, - [119166]=5, - [119167]=5, - [119168]=5, - [119169]=5, - [119170]=5, - [119173]=5, - [119174]=5, - [119175]=5, - [119176]=5, - [119177]=5, - [119178]=5, - [119179]=5, - [119210]=5, - [119211]=5, - [119212]=5, - [119213]=5, - [119362]=5, - [119363]=5, - [119364]=5, - [121344]=5, - [121345]=5, - [121346]=5, - [121347]=5, - [121348]=5, - [121349]=5, - [121350]=5, - [121351]=5, - [121352]=5, - [121353]=5, - [121354]=5, - [121355]=5, - [121356]=5, - [121357]=5, - [121358]=5, - [121359]=5, - [121360]=5, - [121361]=5, - [121362]=5, - [121363]=5, - [121364]=5, - [121365]=5, - [121366]=5, - [121367]=5, - [121368]=5, - [121369]=5, - [121370]=5, - [121371]=5, - [121372]=5, - [121373]=5, - [121374]=5, - [121375]=5, - [121376]=5, - [121377]=5, - [121378]=5, - [121379]=5, - [121380]=5, - [121381]=5, - [121382]=5, - [121383]=5, - [121384]=5, - [121385]=5, - [121386]=5, - [121387]=5, - [121388]=5, - [121389]=5, - [121390]=5, - [121391]=5, - [121392]=5, - [121393]=5, - [121394]=5, - [121395]=5, - [121396]=5, - [121397]=5, - [121398]=5, - [121403]=5, - [121404]=5, - [121405]=5, - [121406]=5, - [121407]=5, - [121408]=5, - [121409]=5, - [121410]=5, - [121411]=5, - [121412]=5, - [121413]=5, - [121414]=5, - [121415]=5, - [121416]=5, - [121417]=5, - [121418]=5, - [121419]=5, - [121420]=5, - [121421]=5, - [121422]=5, - [121423]=5, - [121424]=5, - [121425]=5, - [121426]=5, - [121427]=5, - [121428]=5, - [121429]=5, - [121430]=5, - [121431]=5, - [121432]=5, - [121433]=5, - [121434]=5, - [121435]=5, - [121436]=5, - [121437]=5, - [121438]=5, - [121439]=5, - [121440]=5, - [121441]=5, - [121442]=5, - [121443]=5, - [121444]=5, - [121445]=5, - [121446]=5, - [121447]=5, - [121448]=5, - [121449]=5, - [121450]=5, - [121451]=5, - [121452]=5, - [121461]=5, - [121476]=5, - [121499]=5, - [121500]=5, - [121501]=5, - [121502]=5, - [121503]=5, - [121505]=5, - [121506]=5, - [121507]=5, - [121508]=5, - [121509]=5, - [121510]=5, - [121511]=5, - [121512]=5, - [121513]=5, - [121514]=5, - [121515]=5, - [121516]=5, - [121517]=5, - [121518]=5, - [121519]=5, - [122880]=5, - [122881]=5, - [122882]=5, - [122883]=5, - [122884]=5, - [122885]=5, - [122886]=5, - [122888]=5, - [122889]=5, - [122890]=5, - [122891]=5, - [122892]=5, - [122893]=5, - [122894]=5, - [122895]=5, - [122896]=5, - [122897]=5, - [122898]=5, - [122899]=5, - [122900]=5, - [122901]=5, - [122902]=5, - [122903]=5, - [122904]=5, - [122907]=5, - [122908]=5, - [122909]=5, - [122910]=5, - [122911]=5, - [122912]=5, - [122913]=5, - [122915]=5, - [122916]=5, - [122918]=5, - [122919]=5, - [122920]=5, - [122921]=5, - [122922]=5, - [123184]=5, - [123185]=5, - [123186]=5, - [123187]=5, - [123188]=5, - [123189]=5, - [123190]=5, - [123628]=5, - [123629]=5, - [123630]=5, - [123631]=5, - [125136]=5, - [125137]=5, - [125138]=5, - [125139]=5, - [125140]=5, - [125141]=5, - [125142]=5, - [125184]=2, - [125185]=2, - [125186]=2, - [125187]=2, - [125188]=2, - [125189]=2, - [125190]=2, - [125191]=2, - [125192]=2, - [125193]=2, - [125194]=2, - [125195]=2, - [125196]=2, - [125197]=2, - [125198]=2, - [125199]=2, - [125200]=2, - [125201]=2, - [125202]=2, - [125203]=2, - [125204]=2, - [125205]=2, - [125206]=2, - [125207]=2, - [125208]=2, - [125209]=2, - [125210]=2, - [125211]=2, - [125212]=2, - [125213]=2, - [125214]=2, - [125215]=2, - [125216]=2, - [125217]=2, - [125218]=2, - [125219]=2, - [125220]=2, - [125221]=2, - [125222]=2, - [125223]=2, - [125224]=2, - [125225]=2, - [125226]=2, - [125227]=2, - [125228]=2, - [125229]=2, - [125230]=2, - [125231]=2, - [125232]=2, - [125233]=2, - [125234]=2, - [125235]=2, - [125236]=2, - [125237]=2, - [125238]=2, - [125239]=2, - [125240]=2, - [125241]=2, - [125242]=2, - [125243]=2, - [125244]=2, - [125245]=2, - [125246]=2, - [125247]=2, - [125248]=2, - [125249]=2, - [125250]=2, - [125251]=2, - [125252]=5, - [125253]=5, - [125254]=5, - [125255]=5, - [125256]=5, - [125257]=5, - [125258]=5, - [1042752]=5, -} -characters.indicgroups={ - ["above_mark"]={ - [2304]=true, - [2305]=true, - [2306]=true, - [2362]=true, - [2373]=true, - [2374]=true, - [2375]=true, - [2376]=true, - [2385]=true, - [2387]=true, - [2388]=true, - [2389]=true, - [2631]=true, - [2632]=true, - [2635]=true, - [2636]=true, - [2690]=true, - [2757]=true, - [2759]=true, - [2760]=true, - [2879]=true, - [3008]=true, - [3021]=true, - [3134]=true, - [3135]=true, - [3136]=true, - [3142]=true, - [3143]=true, - [3146]=true, - [3147]=true, - [3148]=true, - [3149]=true, - [3263]=true, - [3270]=true, - [3406]=true, - [4141]=true, - [4142]=true, - [4146]=true, - [4147]=true, - [4148]=true, - [4149]=true, - [4150]=true, - [4154]=true, - [4209]=true, - [4210]=true, - [4211]=true, - [4212]=true, - [4229]=true, - [4230]=true, - [4253]=true, - [43232]=true, - [43233]=true, - [43234]=true, - [43235]=true, - [43236]=true, - [43237]=true, - [43238]=true, - [43239]=true, - [43240]=true, - [43241]=true, - [43242]=true, - [43243]=true, - [43244]=true, - [43245]=true, - [43246]=true, - [43247]=true, - [43248]=true, - [43249]=true, - [43493]=true, - [43644]=true, - }, - ["after_half"]={}, - ["after_main"]={ - [2864]=true, - [2879]=true, - [2902]=true, - [3376]=true, - }, - ["after_postscript"]={ - [2433]=true, - [2494]=true, - [2496]=true, - [2519]=true, - [2561]=true, - [2562]=true, - [2622]=true, - [2624]=true, - [2625]=true, - [2626]=true, - [2672]=true, - [2673]=true, - [2735]=true, - [2750]=true, - [2752]=true, - [2753]=true, - [2754]=true, - [2755]=true, - [2756]=true, - [2761]=true, - [2763]=true, - [2764]=true, - [2786]=true, - [2787]=true, - [2878]=true, - [2880]=true, - [2903]=true, - [2992]=true, - [3006]=true, - [3007]=true, - [3009]=true, - [3010]=true, - [3031]=true, - [3120]=true, - [3248]=true, - [3390]=true, - [3391]=true, - [3392]=true, - [3393]=true, - [3394]=true, - [3395]=true, - [3415]=true, - }, - ["after_subscript"]={ - [2366]=true, - [2368]=true, - [2369]=true, - [2370]=true, - [2371]=true, - [2372]=true, - [2373]=true, - [2374]=true, - [2375]=true, - [2376]=true, - [2377]=true, - [2378]=true, - [2379]=true, - [2380]=true, - [2402]=true, - [2403]=true, - [2480]=true, - [2497]=true, - [2498]=true, - [2499]=true, - [2500]=true, - [2530]=true, - [2531]=true, - [2544]=true, - [2631]=true, - [2632]=true, - [2635]=true, - [2636]=true, - [2757]=true, - [2759]=true, - [2760]=true, - [2881]=true, - [2882]=true, - [2883]=true, - [3008]=true, - [3139]=true, - [3140]=true, - [3267]=true, - [3268]=true, - [3285]=true, - [3286]=true, - }, - ["anudatta"]={ - [2386]=true, - }, - ["before_half"]={ - [2367]=true, - [2382]=true, - [2495]=true, - [2503]=true, - [2504]=true, - [2623]=true, - [2751]=true, - [2887]=true, - }, - ["before_main"]={ - [3014]=true, - [3015]=true, - [3016]=true, - [3398]=true, - [3399]=true, - [3400]=true, - }, - ["before_postscript"]={ - [2352]=true, - [2736]=true, - }, - ["before_subscript"]={ - [2608]=true, - [2817]=true, - [3134]=true, - [3135]=true, - [3136]=true, - [3137]=true, - [3138]=true, - [3142]=true, - [3143]=true, - [3146]=true, - [3147]=true, - [3148]=true, - [3157]=true, - [3158]=true, - [3262]=true, - [3263]=true, - [3265]=true, - [3266]=true, - [3270]=true, - [3276]=true, - [3298]=true, - [3299]=true, - }, - ["below_mark"]={ - [2364]=true, - [2369]=true, - [2370]=true, - [2371]=true, - [2372]=true, - [2381]=true, - [2386]=true, - [2390]=true, - [2391]=true, - [2402]=true, - [2403]=true, - [2492]=true, - [2497]=true, - [2498]=true, - [2499]=true, - [2500]=true, - [2509]=true, - [2620]=true, - [2625]=true, - [2626]=true, - [2637]=true, - [2748]=true, - [2753]=true, - [2754]=true, - [2755]=true, - [2756]=true, - [2765]=true, - [2876]=true, - [2881]=true, - [2882]=true, - [2883]=true, - [2884]=true, - [2893]=true, - [2914]=true, - [2915]=true, - [3009]=true, - [3010]=true, - [3170]=true, - [3171]=true, - [3260]=true, - [3286]=true, - [3298]=true, - [3299]=true, - [3426]=true, - [3427]=true, - [4143]=true, - [4144]=true, - [4151]=true, - [4153]=true, - [4157]=true, - [4158]=true, - [4184]=true, - [4185]=true, - [4190]=true, - [4191]=true, - [4192]=true, - [4226]=true, - [4237]=true, - }, - ["consonant"]={ - [2325]=true, - [2326]=true, - [2327]=true, - [2328]=true, - [2329]=true, - [2330]=true, - [2331]=true, - [2332]=true, - [2333]=true, - [2334]=true, - [2335]=true, - [2336]=true, - [2337]=true, - [2338]=true, - [2339]=true, - [2340]=true, - [2341]=true, - [2342]=true, - [2343]=true, - [2344]=true, - [2345]=true, - [2346]=true, - [2347]=true, - [2348]=true, - [2349]=true, - [2350]=true, - [2351]=true, - [2352]=true, - [2353]=true, - [2354]=true, - [2355]=true, - [2356]=true, - [2357]=true, - [2358]=true, - [2359]=true, - [2360]=true, - [2361]=true, - [2392]=true, - [2393]=true, - [2394]=true, - [2395]=true, - [2396]=true, - [2397]=true, - [2398]=true, - [2399]=true, - [2424]=true, - [2425]=true, - [2426]=true, - [2453]=true, - [2454]=true, - [2455]=true, - [2456]=true, - [2457]=true, - [2458]=true, - [2459]=true, - [2460]=true, - [2461]=true, - [2462]=true, - [2463]=true, - [2464]=true, - [2465]=true, - [2466]=true, - [2467]=true, - [2468]=true, - [2469]=true, - [2470]=true, - [2471]=true, - [2472]=true, - [2474]=true, - [2475]=true, - [2476]=true, - [2477]=true, - [2478]=true, - [2479]=true, - [2480]=true, - [2482]=true, - [2486]=true, - [2487]=true, - [2488]=true, - [2489]=true, - [2510]=true, - [2524]=true, - [2525]=true, - [2527]=true, - [2581]=true, - [2582]=true, - [2583]=true, - [2584]=true, - [2585]=true, - [2586]=true, - [2587]=true, - [2588]=true, - [2589]=true, - [2590]=true, - [2591]=true, - [2592]=true, - [2593]=true, - [2594]=true, - [2595]=true, - [2596]=true, - [2597]=true, - [2598]=true, - [2599]=true, - [2600]=true, - [2602]=true, - [2603]=true, - [2604]=true, - [2605]=true, - [2606]=true, - [2607]=true, - [2608]=true, - [2610]=true, - [2611]=true, - [2613]=true, - [2614]=true, - [2616]=true, - [2617]=true, - [2649]=true, - [2650]=true, - [2651]=true, - [2652]=true, - [2654]=true, - [2709]=true, - [2710]=true, - [2711]=true, - [2712]=true, - [2713]=true, - [2714]=true, - [2715]=true, - [2716]=true, - [2717]=true, - [2718]=true, - [2719]=true, - [2720]=true, - [2721]=true, - [2722]=true, - [2723]=true, - [2724]=true, - [2725]=true, - [2726]=true, - [2727]=true, - [2728]=true, - [2730]=true, - [2731]=true, - [2732]=true, - [2733]=true, - [2734]=true, - [2735]=true, - [2736]=true, - [2738]=true, - [2739]=true, - [2741]=true, - [2742]=true, - [2743]=true, - [2744]=true, - [2745]=true, - [2837]=true, - [2838]=true, - [2839]=true, - [2840]=true, - [2841]=true, - [2842]=true, - [2843]=true, - [2844]=true, - [2845]=true, - [2846]=true, - [2847]=true, - [2848]=true, - [2849]=true, - [2850]=true, - [2851]=true, - [2852]=true, - [2853]=true, - [2854]=true, - [2855]=true, - [2856]=true, - [2858]=true, - [2859]=true, - [2860]=true, - [2861]=true, - [2862]=true, - [2863]=true, - [2864]=true, - [2866]=true, - [2867]=true, - [2869]=true, - [2870]=true, - [2871]=true, - [2872]=true, - [2873]=true, - [2908]=true, - [2909]=true, - [2929]=true, - [2965]=true, - [2969]=true, - [2970]=true, - [2972]=true, - [2974]=true, - [2975]=true, - [2979]=true, - [2980]=true, - [2984]=true, - [2985]=true, - [2986]=true, - [2990]=true, - [2991]=true, - [2992]=true, - [2993]=true, - [2994]=true, - [2995]=true, - [2996]=true, - [2997]=true, - [2998]=true, - [2999]=true, - [3000]=true, - [3001]=true, - [3093]=true, - [3094]=true, - [3095]=true, - [3096]=true, - [3097]=true, - [3098]=true, - [3099]=true, - [3100]=true, - [3101]=true, - [3102]=true, - [3103]=true, - [3104]=true, - [3105]=true, - [3106]=true, - [3107]=true, - [3108]=true, - [3109]=true, - [3110]=true, - [3111]=true, - [3112]=true, - [3114]=true, - [3115]=true, - [3116]=true, - [3117]=true, - [3118]=true, - [3119]=true, - [3120]=true, - [3121]=true, - [3122]=true, - [3123]=true, - [3124]=true, - [3125]=true, - [3126]=true, - [3127]=true, - [3128]=true, - [3129]=true, - [3133]=true, - [3221]=true, - [3222]=true, - [3223]=true, - [3224]=true, - [3225]=true, - [3226]=true, - [3227]=true, - [3228]=true, - [3229]=true, - [3230]=true, - [3231]=true, - [3232]=true, - [3233]=true, - [3234]=true, - [3235]=true, - [3236]=true, - [3237]=true, - [3238]=true, - [3239]=true, - [3240]=true, - [3242]=true, - [3243]=true, - [3244]=true, - [3245]=true, - [3246]=true, - [3247]=true, - [3248]=true, - [3249]=true, - [3250]=true, - [3251]=true, - [3253]=true, - [3254]=true, - [3255]=true, - [3256]=true, - [3257]=true, - [3294]=true, - [3349]=true, - [3350]=true, - [3351]=true, - [3352]=true, - [3353]=true, - [3354]=true, - [3355]=true, - [3356]=true, - [3357]=true, - [3358]=true, - [3359]=true, - [3360]=true, - [3361]=true, - [3362]=true, - [3363]=true, - [3364]=true, - [3365]=true, - [3366]=true, - [3367]=true, - [3368]=true, - [3369]=true, - [3370]=true, - [3371]=true, - [3372]=true, - [3373]=true, - [3374]=true, - [3375]=true, - [3376]=true, - [3377]=true, - [3378]=true, - [3379]=true, - [3380]=true, - [3381]=true, - [3382]=true, - [3383]=true, - [3384]=true, - [3385]=true, - [3386]=true, - [4096]=true, - [4097]=true, - [4098]=true, - [4099]=true, - [4100]=true, - [4101]=true, - [4102]=true, - [4103]=true, - [4104]=true, - [4105]=true, - [4106]=true, - [4107]=true, - [4108]=true, - [4109]=true, - [4110]=true, - [4111]=true, - [4112]=true, - [4113]=true, - [4114]=true, - [4115]=true, - [4116]=true, - [4117]=true, - [4118]=true, - [4119]=true, - [4120]=true, - [4121]=true, - [4122]=true, - [4123]=true, - [4124]=true, - [4125]=true, - [4126]=true, - [4127]=true, - [4128]=true, - [4155]=true, - [4156]=true, - [4157]=true, - [4158]=true, - [4159]=true, - [4176]=true, - [4177]=true, - [4186]=true, - [4187]=true, - [4188]=true, - [4189]=true, - [4190]=true, - [4191]=true, - [4192]=true, - [4193]=true, - [4197]=true, - [4198]=true, - [4206]=true, - [4207]=true, - [4208]=true, - [4213]=true, - [4214]=true, - [4215]=true, - [4216]=true, - [4217]=true, - [4218]=true, - [4219]=true, - [4220]=true, - [4221]=true, - [4222]=true, - [4223]=true, - [4224]=true, - [4225]=true, - [4226]=true, - [4238]=true, - [43488]=true, - [43489]=true, - [43490]=true, - [43491]=true, - [43492]=true, - [43495]=true, - [43496]=true, - [43497]=true, - [43498]=true, - [43499]=true, - [43500]=true, - [43501]=true, - [43502]=true, - [43503]=true, - [43514]=true, - [43515]=true, - [43516]=true, - [43517]=true, - [43518]=true, - [43616]=true, - [43617]=true, - [43618]=true, - [43619]=true, - [43620]=true, - [43621]=true, - [43622]=true, - [43623]=true, - [43624]=true, - [43625]=true, - [43626]=true, - [43628]=true, - [43629]=true, - [43630]=true, - [43631]=true, - [43633]=true, - [43634]=true, - [43635]=true, - [43636]=true, - [43637]=true, - [43638]=true, - [43642]=true, - [43646]=true, - [43647]=true, - }, - ["dependent_vowel"]={ - [2362]=true, - [2363]=true, - [2366]=true, - [2367]=true, - [2368]=true, - [2369]=true, - [2370]=true, - [2371]=true, - [2372]=true, - [2373]=true, - [2374]=true, - [2375]=true, - [2376]=true, - [2377]=true, - [2378]=true, - [2379]=true, - [2380]=true, - [2382]=true, - [2383]=true, - [2389]=true, - [2390]=true, - [2391]=true, - [2402]=true, - [2403]=true, - [2494]=true, - [2495]=true, - [2497]=true, - [2498]=true, - [2499]=true, - [2500]=true, - [2503]=true, - [2504]=true, - [2507]=true, - [2508]=true, - [2622]=true, - [2623]=true, - [2624]=true, - [2625]=true, - [2626]=true, - [2631]=true, - [2632]=true, - [2635]=true, - [2636]=true, - [2750]=true, - [2751]=true, - [2752]=true, - [2753]=true, - [2754]=true, - [2755]=true, - [2756]=true, - [2757]=true, - [2759]=true, - [2760]=true, - [2761]=true, - [2763]=true, - [2764]=true, - [2878]=true, - [2879]=true, - [2880]=true, - [2881]=true, - [2882]=true, - [2883]=true, - [2884]=true, - [2887]=true, - [2888]=true, - [2891]=true, - [2892]=true, - [2914]=true, - [2915]=true, - [3006]=true, - [3007]=true, - [3008]=true, - [3009]=true, - [3010]=true, - [3014]=true, - [3015]=true, - [3016]=true, - [3018]=true, - [3019]=true, - [3020]=true, - [3134]=true, - [3135]=true, - [3136]=true, - [3137]=true, - [3138]=true, - [3139]=true, - [3140]=true, - [3142]=true, - [3143]=true, - [3144]=true, - [3146]=true, - [3147]=true, - [3148]=true, - [3170]=true, - [3171]=true, - [3262]=true, - [3263]=true, - [3264]=true, - [3265]=true, - [3266]=true, - [3267]=true, - [3268]=true, - [3270]=true, - [3271]=true, - [3272]=true, - [3274]=true, - [3275]=true, - [3276]=true, - [3285]=true, - [3286]=true, - [3298]=true, - [3299]=true, - [3390]=true, - [3391]=true, - [3392]=true, - [3393]=true, - [3394]=true, - [3395]=true, - [3396]=true, - [3398]=true, - [3399]=true, - [3400]=true, - [3402]=true, - [3403]=true, - [3404]=true, - [3415]=true, - [3426]=true, - [3427]=true, - [4139]=true, - [4140]=true, - [4141]=true, - [4142]=true, - [4143]=true, - [4144]=true, - [4145]=true, - [4146]=true, - [4147]=true, - [4148]=true, - [4149]=true, - [4182]=true, - [4183]=true, - [4184]=true, - [4185]=true, - [4194]=true, - [4199]=true, - [4200]=true, - [4209]=true, - [4210]=true, - [4211]=true, - [4212]=true, - [4227]=true, - [4228]=true, - [4229]=true, - [4230]=true, - [4252]=true, - [4253]=true, - [43493]=true, - }, - ["halant"]={ - [2381]=true, - [2509]=true, - [2637]=true, - [2765]=true, - [2893]=true, - [3021]=true, - [3149]=true, - [3277]=true, - [3405]=true, - }, - ["independent_vowel"]={ - [2308]=true, - [2309]=true, - [2310]=true, - [2311]=true, - [2312]=true, - [2313]=true, - [2314]=true, - [2315]=true, - [2316]=true, - [2317]=true, - [2318]=true, - [2319]=true, - [2320]=true, - [2321]=true, - [2322]=true, - [2323]=true, - [2324]=true, - [2400]=true, - [2401]=true, - [2418]=true, - [2419]=true, - [2420]=true, - [2421]=true, - [2422]=true, - [2423]=true, - [2437]=true, - [2438]=true, - [2439]=true, - [2440]=true, - [2441]=true, - [2442]=true, - [2443]=true, - [2444]=true, - [2447]=true, - [2448]=true, - [2451]=true, - [2452]=true, - [2528]=true, - [2529]=true, - [2530]=true, - [2531]=true, - [2565]=true, - [2566]=true, - [2567]=true, - [2568]=true, - [2569]=true, - [2570]=true, - [2575]=true, - [2576]=true, - [2579]=true, - [2580]=true, - [2693]=true, - [2694]=true, - [2695]=true, - [2696]=true, - [2697]=true, - [2698]=true, - [2699]=true, - [2700]=true, - [2701]=true, - [2703]=true, - [2704]=true, - [2705]=true, - [2707]=true, - [2708]=true, - [2784]=true, - [2785]=true, - [2786]=true, - [2787]=true, - [2821]=true, - [2822]=true, - [2823]=true, - [2824]=true, - [2825]=true, - [2826]=true, - [2827]=true, - [2828]=true, - [2831]=true, - [2832]=true, - [2835]=true, - [2836]=true, - [2912]=true, - [2913]=true, - [2949]=true, - [2950]=true, - [2951]=true, - [2952]=true, - [2953]=true, - [2954]=true, - [2958]=true, - [2959]=true, - [2960]=true, - [2962]=true, - [2963]=true, - [2964]=true, - [3077]=true, - [3078]=true, - [3079]=true, - [3080]=true, - [3081]=true, - [3082]=true, - [3083]=true, - [3084]=true, - [3086]=true, - [3087]=true, - [3088]=true, - [3090]=true, - [3091]=true, - [3092]=true, - [3168]=true, - [3169]=true, - [3205]=true, - [3206]=true, - [3207]=true, - [3208]=true, - [3209]=true, - [3210]=true, - [3211]=true, - [3212]=true, - [3214]=true, - [3215]=true, - [3216]=true, - [3218]=true, - [3219]=true, - [3220]=true, - [3296]=true, - [3297]=true, - [3333]=true, - [3334]=true, - [3335]=true, - [3336]=true, - [3337]=true, - [3338]=true, - [3339]=true, - [3340]=true, - [3342]=true, - [3343]=true, - [3344]=true, - [3346]=true, - [3347]=true, - [3348]=true, - [3423]=true, - [3424]=true, - [3425]=true, - [4129]=true, - [4130]=true, - [4131]=true, - [4132]=true, - [4133]=true, - [4134]=true, - [4135]=true, - [4136]=true, - [4137]=true, - [4138]=true, - [4178]=true, - [4179]=true, - [4180]=true, - [4181]=true, - }, - ["nukta"]={ - [2364]=true, - [2492]=true, - [2620]=true, - [2748]=true, - [2876]=true, - [3260]=true, - }, - ["post_mark"]={ - [2307]=true, - [2363]=true, - [2366]=true, - [2368]=true, - [2377]=true, - [2378]=true, - [2379]=true, - [2380]=true, - [2383]=true, - [2494]=true, - [2496]=true, - [2622]=true, - [2624]=true, - [2750]=true, - [2752]=true, - [2761]=true, - [2763]=true, - [2764]=true, - [2878]=true, - [2880]=true, - [3006]=true, - [3007]=true, - [3137]=true, - [3138]=true, - [3139]=true, - [3140]=true, - [3262]=true, - [3265]=true, - [3266]=true, - [3267]=true, - [3268]=true, - [3276]=true, - [3285]=true, - [3390]=true, - [3391]=true, - [3392]=true, - [3393]=true, - [3394]=true, - [3395]=true, - [3396]=true, - [3415]=true, - [4139]=true, - [4140]=true, - [4152]=true, - [4155]=true, - [4182]=true, - [4183]=true, - [4194]=true, - [4195]=true, - [4196]=true, - [4199]=true, - [4200]=true, - [4201]=true, - [4202]=true, - [4203]=true, - [4204]=true, - [4205]=true, - [4227]=true, - [4231]=true, - [4232]=true, - [4233]=true, - [4234]=true, - [4235]=true, - [4236]=true, - [4239]=true, - [4250]=true, - [4251]=true, - [4252]=true, - [43643]=true, - [43645]=true, - }, - ["pre_mark"]={ - [2367]=true, - [2382]=true, - [2495]=true, - [2503]=true, - [2504]=true, - [2623]=true, - [2751]=true, - [2887]=true, - [3014]=true, - [3015]=true, - [3016]=true, - [3398]=true, - [3399]=true, - [3400]=true, - [4145]=true, - [4228]=true, - }, - ["ra"]={ - [2352]=true, - [2480]=true, - [2544]=true, - [2608]=true, - [2736]=true, - [2864]=true, - [2992]=true, - [3120]=true, - [3248]=true, - [3376]=true, - }, - ["stress_tone_mark"]={ - [2385]=true, - [2386]=true, - [2387]=true, - [2388]=true, - [4151]=true, - [4195]=true, - [4196]=true, - [4201]=true, - [4202]=true, - [4203]=true, - [4204]=true, - [4205]=true, - [4231]=true, - [4232]=true, - [4233]=true, - [4234]=true, - [4235]=true, - [4236]=true, - [4237]=true, - [4239]=true, - [4250]=true, - [4251]=true, - [43643]=true, - [43644]=true, - [43645]=true, - }, - ["twopart_mark"]={ - [2507]={ 2503,2494 }, - [2508]={ 2503,2519 }, - [2888]={ 2887,2902 }, - [2891]={ 2887,2878 }, - [2892]={ 2887,2903 }, - [3018]={ 3014,3006 }, - [3019]={ 3015,3006 }, - [3020]={ 3014,3031 }, - [3144]={ 3142,3158 }, - [3264]={ 3263,3285 }, - [3271]={ 3270,3285 }, - [3272]={ 3270,3286 }, - [3274]={ 3270,3266 }, - [3275]={ 3274,3285 }, - [3402]={ 3398,3390 }, - [3403]={ 3399,3390 }, - [3404]={ 3398,3415 }, - }, - ["vowel_modifier"]={ - [2304]=true, - [2305]=true, - [2306]=true, - [2307]=true, - [2433]=true, - [3330]=true, - [3331]=true, - [4150]=true, - [4152]=true, - [4153]=true, - [4154]=true, - [43232]=true, - [43233]=true, - [43234]=true, - [43235]=true, - [43236]=true, - [43237]=true, - [43238]=true, - [43239]=true, - [43240]=true, - [43241]=true, - [43242]=true, - [43243]=true, - [43244]=true, - [43245]=true, - [43246]=true, - [43247]=true, - [43249]=true, - }, -} - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “basics-chr”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ini” 5343de60613adb24cdd7a8d2ee1d153c] --- - -if not modules then modules={} end modules ['font-ini']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local allocate=utilities.storage.allocate -local sortedhash=table.sortedhash -fonts=fonts or {} -local fonts=fonts -local identifiers=allocate() -fonts.hashes=fonts.hashes or { identifiers=identifiers } -fonts.tables=fonts.tables or {} -fonts.helpers=fonts.helpers or {} -fonts.tracers=fonts.tracers or {} -fonts.specifiers=fonts.specifiers or {} -fonts.analyzers={} -fonts.readers={} -fonts.definers={ methods={} } -fonts.loggers={ register=function() end } -if context then - font.originaleach=font.each - function font.each() - return sortedhash(identifiers) - end - fontloader=nil -end -fonts.privateoffsets={ - textbase=0xF0000, - textextrabase=0xFD000, - mathextrabase=0xFE000, - mathbase=0xFF000, - keepnames=false, -} -if node and not tex.getfontoffamily then - tex.getfontoffamily=node.family_font -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ini”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-mis” 17e967c9ec4d001deefd43ddf25e98f7] --- - -if not modules then modules={} end modules ['luatex-font-mis']={ - version=1.001, - comment="companion to luatex-*.tex", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -if context then - os.exit() -end -local currentfont=font.current -local hashes=fonts.hashes -local identifiers=hashes.identifiers or {} -local marks=hashes.marks or {} -hashes.identifiers=identifiers -hashes.marks=marks -table.setmetatableindex(marks,function(t,k) - if k==true then - return marks[currentfont()] - else - local resources=identifiers[k].resources or {} - local marks=resources.marks or {} - t[k]=marks - return marks - end -end) -function font.each() - return table.sortedhash(fonts.hashes.identifiers) -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-mis”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-con” a3eb543fa5946fa1faf0e1e50d5b3b91] --- - -if not modules then modules={} end modules ['font-con']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next,tostring,tonumber,rawget=next,tostring,tonumber,rawget -local format,match,lower,gsub,find=string.format,string.match,string.lower,string.gsub,string.find -local sort,insert,concat=table.sort,table.insert,table.concat -local sortedkeys,sortedhash,serialize,fastcopy=table.sortedkeys,table.sortedhash,table.serialize,table.fastcopy -local derivetable=table.derive -local ioflush=io.flush -local round=math.round -local setmetatable,getmetatable,rawget,rawset=setmetatable,getmetatable,rawget,rawset -local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) -local trace_scaling=false trackers.register("fonts.scaling",function(v) trace_scaling=v end) -local report_defining=logs.reporter("fonts","defining") -local fonts=fonts -local constructors=fonts.constructors or {} -fonts.constructors=constructors -local handlers=fonts.handlers or {} -fonts.handlers=handlers -local allocate=utilities.storage.allocate -local setmetatableindex=table.setmetatableindex -constructors.dontembed=allocate() -constructors.namemode="fullpath" -constructors.version=1.01 -constructors.cache=containers.define("fonts","constructors",constructors.version,false) -constructors.privateoffset=fonts.privateoffsets.textbase or 0xF0000 -constructors.cacheintex=true -constructors.addtounicode=true -constructors.fixprotrusion=true -local designsizes=allocate() -constructors.designsizes=designsizes -local loadedfonts=allocate() -constructors.loadedfonts=loadedfonts -local factors={ - pt=65536.0, - bp=65781.8, -} -function constructors.setfactor(f) - constructors.factor=factors[f or 'pt'] or factors.pt -end -constructors.setfactor() -function constructors.scaled(scaledpoints,designsize) - if scaledpoints<0 then - local factor=constructors.factor - if designsize then - if designsize>factor then - return (- scaledpoints/1000)*designsize - else - return (- scaledpoints/1000)*designsize*factor - end - else - return (- scaledpoints/1000)*10*factor - end - else - return scaledpoints - end -end -function constructors.getprivate(tfmdata) - local properties=tfmdata.properties - local private=properties.private - properties.private=private+1 - return private -end -function constructors.setmathparameter(tfmdata,name,value) - local m=tfmdata.mathparameters - local c=tfmdata.MathConstants - if m then - m[name]=value - end - if c and c~=m then - c[name]=value - end -end -function constructors.getmathparameter(tfmdata,name) - local p=tfmdata.mathparameters or tfmdata.MathConstants - if p then - return p[name] - end -end -function constructors.cleanuptable(tfmdata) -end -function constructors.calculatescale(tfmdata,scaledpoints) - local parameters=tfmdata.parameters - if scaledpoints<0 then - scaledpoints=(- scaledpoints/1000)*(tfmdata.designsize or parameters.designsize) - end - return scaledpoints,scaledpoints/(parameters.units or 1000) -end -local unscaled={ - ScriptPercentScaleDown=true, - ScriptScriptPercentScaleDown=true, - RadicalDegreeBottomRaisePercent=true, - NoLimitSupFactor=true, - NoLimitSubFactor=true, -} -function constructors.assignmathparameters(target,original) - local mathparameters=original.mathparameters - if mathparameters and next(mathparameters) then - local targetparameters=target.parameters - local targetproperties=target.properties - local targetmathparameters={} - local factor=targetproperties.math_is_scaled and 1 or targetparameters.factor - for name,value in next,mathparameters do - if unscaled[name] then - targetmathparameters[name]=value - else - targetmathparameters[name]=value*factor - end - end - if not targetmathparameters.FractionDelimiterSize then - targetmathparameters.FractionDelimiterSize=1.01*targetparameters.size - end - if not mathparameters.FractionDelimiterDisplayStyleSize then - targetmathparameters.FractionDelimiterDisplayStyleSize=2.40*targetparameters.size - end - if not targetmathparameters.SpaceBeforeScript then - targetmathparameters.SpaceBeforeScript=targetmathparameters.SpaceAfterScript - end - target.mathparameters=targetmathparameters - end -end -function constructors.beforecopyingcharacters(target,original) -end -function constructors.aftercopyingcharacters(target,original) -end -local nofinstances=0 -local instances=setmetatableindex(function(t,k) - nofinstances=nofinstances+1 - t[k]=nofinstances - return nofinstances -end) -function constructors.trytosharefont(target,tfmdata) - local properties=target.properties - local instance=properties.instance - if instance then - local fullname=target.fullname - local fontname=target.fontname - local psname=target.psname - local format=tfmdata.properties.format - if format=="opentype" then - target.streamprovider=1 - elseif format=="truetype" then - target.streamprovider=2 - else - target.streamprovider=0 - end - if target.streamprovider>0 then - if fullname then - fullname=fullname..":"..instances[instance] - target.fullname=fullname - end - if fontname then - fontname=fontname..":"..instances[instance] - target.fontname=fontname - end - if psname then - psname=psname..":"..instances[instance] - target.psname=psname - end - end - end -end -local synonyms={ - exheight="x_height", - xheight="x_height", - ex="x_height", - emwidth="quad", - em="quad", - spacestretch="space_stretch", - stretch="space_stretch", - spaceshrink="space_shrink", - shrink="space_shrink", - extraspace="extra_space", - xspace="extra_space", - slantperpoint="slant", -} -function constructors.enhanceparameters(parameters) - local mt=getmetatable(parameters) - local getter=function(t,k) - if not k then - return nil - end - local s=synonyms[k] - if s then - return rawget(t,s) or (mt and mt[s]) or nil - end - if k=="spacing" then - return { - width=t.space, - stretch=t.space_stretch, - shrink=t.space_shrink, - extra=t.extra_space, - } - end - return mt and mt[k] or nil - end - local setter=function(t,k,v) - if not k then - return 0 - end - local s=synonyms[k] - if s then - rawset(t,s,v) - elseif k=="spacing" then - if type(v)=="table" then - rawset(t,"space",v.width or 0) - rawset(t,"space_stretch",v.stretch or 0) - rawset(t,"space_shrink",v.shrink or 0) - rawset(t,"extra_space",v.extra or 0) - end - else - rawset(t,k,v) - end - end - setmetatable(parameters,{ - __index=getter, - __newindex=setter, - }) -end -local function mathkerns(v,vdelta) - local k={} - for i=1,#v do - local entry=v[i] - local height=entry.height - local kern=entry.kern - k[i]={ - height=height and vdelta*height or 0, - kern=kern and vdelta*kern or 0, - } - end - return k -end -local psfake=0 -local function fixedpsname(psname,fallback) - local usedname=psname - if psname and psname~="" then - if find(psname," ",1,true) then - usedname=gsub(psname,"[%s]+","-") - else - end - elseif not fallback or fallback=="" then - psfake=psfake+1 - psname="fakename-"..psfake - else - psname=fallback - usedname=gsub(psname,"[^a-zA-Z0-9]+","-") - end - return usedname,psname~=usedname -end -function constructors.scale(tfmdata,specification) - local target={} - if tonumber(specification) then - specification={ size=specification } - end - target.specification=specification - local scaledpoints=specification.size - local relativeid=specification.relativeid - local properties=tfmdata.properties or {} - local goodies=tfmdata.goodies or {} - local resources=tfmdata.resources or {} - local descriptions=tfmdata.descriptions or {} - local characters=tfmdata.characters or {} - local changed=tfmdata.changed or {} - local shared=tfmdata.shared or {} - local parameters=tfmdata.parameters or {} - local mathparameters=tfmdata.mathparameters or {} - local targetcharacters={} - local targetdescriptions=derivetable(descriptions) - local targetparameters=derivetable(parameters) - local targetproperties=derivetable(properties) - local targetgoodies=goodies - target.characters=targetcharacters - target.descriptions=targetdescriptions - target.parameters=targetparameters - target.properties=targetproperties - target.goodies=targetgoodies - target.shared=shared - target.resources=resources - target.unscaled=tfmdata - local mathsize=tonumber(specification.mathsize) or 0 - local textsize=tonumber(specification.textsize) or scaledpoints - local forcedsize=tonumber(parameters.mathsize ) or 0 - local extrafactor=tonumber(specification.factor ) or 1 - if (mathsize==2 or forcedsize==2) and parameters.scriptpercentage then - scaledpoints=parameters.scriptpercentage*textsize/100 - elseif (mathsize==3 or forcedsize==3) and parameters.scriptscriptpercentage then - scaledpoints=parameters.scriptscriptpercentage*textsize/100 - elseif forcedsize>1000 then - scaledpoints=forcedsize - else - end - targetparameters.mathsize=mathsize - targetparameters.textsize=textsize - targetparameters.forcedsize=forcedsize - targetparameters.extrafactor=extrafactor - local addtounicode=constructors.addtounicode - local tounicode=fonts.mappings.tounicode - local unknowncode=tounicode(0xFFFD) - local defaultwidth=resources.defaultwidth or 0 - local defaultheight=resources.defaultheight or 0 - local defaultdepth=resources.defaultdepth or 0 - local units=parameters.units or 1000 - targetproperties.language=properties.language or "dflt" - targetproperties.script=properties.script or "dflt" - targetproperties.mode=properties.mode or "base" - targetproperties.method=properties.method - local askedscaledpoints=scaledpoints - local scaledpoints,delta=constructors.calculatescale(tfmdata,scaledpoints,nil,specification) - local hdelta=delta - local vdelta=delta - target.designsize=parameters.designsize - target.units=units - target.units_per_em=units - local direction=properties.direction or tfmdata.direction or 0 - target.direction=direction - properties.direction=direction - target.size=scaledpoints - target.encodingbytes=properties.encodingbytes or 1 - target.subfont=properties.subfont - target.embedding=properties.embedding or "subset" - target.tounicode=1 - target.cidinfo=properties.cidinfo - target.format=properties.format - target.cache=constructors.cacheintex and "yes" or "renew" - local original=properties.original or tfmdata.original - local fontname=properties.fontname or tfmdata.fontname - local fullname=properties.fullname or tfmdata.fullname - local filename=properties.filename or tfmdata.filename - local psname=properties.psname or tfmdata.psname - local name=properties.name or tfmdata.name - local psname,psfixed=fixedpsname(psname,fontname or fullname or file.nameonly(filename)) - target.original=original - target.fontname=fontname - target.fullname=fullname - target.filename=filename - target.psname=psname - target.name=name - properties.fontname=fontname - properties.fullname=fullname - properties.filename=filename - properties.psname=psname - properties.name=name - local expansion=parameters.expansion - if expansion then - target.stretch=expansion.stretch - target.shrink=expansion.shrink - target.step=expansion.step - end - local slantfactor=parameters.slantfactor or 0 - if slantfactor~=0 then - target.slant=slantfactor*1000 - else - target.slant=0 - end - local extendfactor=parameters.extendfactor or 0 - if extendfactor~=0 and extendfactor~=1 then - hdelta=hdelta*extendfactor - target.extend=extendfactor*1000 - else - target.extend=1000 - end - local squeezefactor=parameters.squeezefactor or 0 - if squeezefactor~=0 and squeezefactor~=1 then - vdelta=vdelta*squeezefactor - target.squeeze=squeezefactor*1000 - else - target.squeeze=1000 - end - local mode=parameters.mode or 0 - if mode~=0 then - target.mode=mode - end - local width=parameters.width or 0 - if width~=0 then - target.width=width*delta*1000/655360 - end - targetparameters.factor=delta - targetparameters.hfactor=hdelta - targetparameters.vfactor=vdelta - targetparameters.size=scaledpoints - targetparameters.units=units - targetparameters.scaledpoints=askedscaledpoints - targetparameters.mode=mode - targetparameters.width=width - local isvirtual=properties.virtualized or tfmdata.type=="virtual" - local hasquality=parameters.expansion or parameters.protrusion - local hasitalics=properties.hasitalics - local autoitalicamount=properties.autoitalicamount - local stackmath=not properties.nostackmath - local haskerns=properties.haskerns or properties.mode=="base" - local hasligatures=properties.hasligatures or properties.mode=="base" - local realdimensions=properties.realdimensions - local writingmode=properties.writingmode or "horizontal" - local identity=properties.identity or "horizontal" - local vfonts=target.fonts - if vfonts and #vfonts>0 then - target.fonts=fastcopy(vfonts) - elseif isvirtual then - target.fonts={ { id=0 } } - end - if changed and not next(changed) then - changed=false - end - target.type=isvirtual and "virtual" or "real" - target.writingmode=writingmode=="vertical" and "vertical" or "horizontal" - target.identity=identity=="vertical" and "vertical" or "horizontal" - target.postprocessors=tfmdata.postprocessors - local targetslant=(parameters.slant or parameters[1] or 0)*factors.pt - local targetspace=(parameters.space or parameters[2] or 0)*hdelta - local targetspace_stretch=(parameters.space_stretch or parameters[3] or 0)*hdelta - local targetspace_shrink=(parameters.space_shrink or parameters[4] or 0)*hdelta - local targetx_height=(parameters.x_height or parameters[5] or 0)*vdelta - local targetquad=(parameters.quad or parameters[6] or 0)*hdelta - local targetextra_space=(parameters.extra_space or parameters[7] or 0)*hdelta - targetparameters.slant=targetslant - targetparameters.space=targetspace - targetparameters.space_stretch=targetspace_stretch - targetparameters.space_shrink=targetspace_shrink - targetparameters.x_height=targetx_height - targetparameters.quad=targetquad - targetparameters.extra_space=targetextra_space - local hshift=parameters.hshift - if hshift then - targetparameters.hshift=delta*hshift - end - local vshift=parameters.vshift - if vshift then - targetparameters.vshift=delta*vshift - end - local ascender=parameters.ascender - if ascender then - targetparameters.ascender=delta*ascender - end - local descender=parameters.descender - if descender then - targetparameters.descender=delta*descender - end - constructors.enhanceparameters(targetparameters) - local protrusionfactor=constructors.fixprotrusion and ((targetquad~=0 and 1000/targetquad) or 1) or 1 - local scaledwidth=defaultwidth*hdelta - local scaledheight=defaultheight*vdelta - local scaleddepth=defaultdepth*vdelta - local hasmath=(properties.hasmath or next(mathparameters)) and true - if hasmath then - constructors.assignmathparameters(target,tfmdata) - properties.hasmath=true - target.nomath=false - target.MathConstants=target.mathparameters - else - properties.hasmath=false - target.nomath=true - target.mathparameters=nil - end - if hasmath then - local mathitalics=properties.mathitalics - if mathitalics==false then - if trace_defining then - report_defining("%s italics %s for font %a, fullname %a, filename %a","math",hasitalics and "ignored" or "disabled",name,fullname,filename) - end - hasitalics=false - autoitalicamount=false - end - else - local textitalics=properties.textitalics - if textitalics==false then - if trace_defining then - report_defining("%s italics %s for font %a, fullname %a, filename %a","text",hasitalics and "ignored" or "disabled",name,fullname,filename) - end - hasitalics=false - autoitalicamount=false - end - end - if trace_defining then - report_defining("defining tfm, name %a, fullname %a, filename %a, %spsname %a, hscale %a, vscale %a, math %a, italics %a", - name,fullname,filename,psfixed and "(fixed) " or "",psname,hdelta,vdelta, - hasmath and "enabled" or "disabled",hasitalics and "enabled" or "disabled") - end - constructors.beforecopyingcharacters(target,tfmdata) - local sharedkerns={} - for unicode,character in next,characters do - local chr,description,index - if changed then - local c=changed[unicode] - if c and c~=unicode then - if c then - description=descriptions[c] or descriptions[unicode] or character - character=characters[c] or character - index=description.index or c - else - description=descriptions[unicode] or character - index=description.index or unicode - end - else - description=descriptions[unicode] or character - index=description.index or unicode - end - else - description=descriptions[unicode] or character - index=description.index or unicode - end - local width=description.width - local height=description.height - local depth=description.depth - local isunicode=description.unicode - if realdimensions then - if not height or height==0 then - local bb=description.boundingbox - local ht=bb[4] - if ht~=0 then - height=ht - end - if not depth or depth==0 then - local dp=-bb[2] - if dp~=0 then - depth=dp - end - end - elseif not depth or depth==0 then - local dp=-description.boundingbox[2] - if dp~=0 then - depth=dp - end - end - end - if width then width=hdelta*width else width=scaledwidth end - if height then height=vdelta*height else height=scaledheight end - if depth and depth~=0 then - depth=delta*depth - if isunicode then - chr={ - index=index, - height=height, - depth=depth, - width=width, - unicode=isunicode, - } - else - chr={ - index=index, - height=height, - depth=depth, - width=width, - } - end - else - if isunicode then - chr={ - index=index, - height=height, - width=width, - unicode=isunicode, - } - else - chr={ - index=index, - height=height, - width=width, - } - end - end - if addtounicode then - chr.tounicode=isunicode and tounicode(isunicode) or unknowncode - end - if hasquality then - local ve=character.expansion_factor - if ve then - chr.expansion_factor=ve*1000 - end - local vl=character.left_protruding - if vl then - chr.left_protruding=protrusionfactor*width*vl - end - local vr=character.right_protruding - if vr then - chr.right_protruding=protrusionfactor*width*vr - end - end - if hasmath then - local vn=character.next - if vn then - chr.next=vn - else - local vv=character.vert_variants - if vv then - local t={} - for i=1,#vv do - local vvi=vv[i] - local s=vvi["start"] or 0 - local e=vvi["end"] or 0 - local a=vvi["advance"] or 0 - t[i]={ - ["start"]=s==0 and 0 or s*vdelta, - ["end"]=e==0 and 0 or e*vdelta, - ["advance"]=a==0 and 0 or a*vdelta, - ["extender"]=vvi["extender"], - ["glyph"]=vvi["glyph"], - } - end - chr.vert_variants=t - else - local hv=character.horiz_variants - if hv then - local t={} - for i=1,#hv do - local hvi=hv[i] - local s=hvi["start"] or 0 - local e=hvi["end"] or 0 - local a=hvi["advance"] or 0 - t[i]={ - ["start"]=s==0 and 0 or s*hdelta, - ["end"]=e==0 and 0 or e*hdelta, - ["advance"]=a==0 and 0 or a*hdelta, - ["extender"]=hvi["extender"], - ["glyph"]=hvi["glyph"], - } - end - chr.horiz_variants=t - end - end - end - local vi=character.vert_italic - if vi and vi~=0 then - chr.vert_italic=vi*hdelta - end - local va=character.accent - if va then - chr.top_accent=vdelta*va - end - if stackmath then - local mk=character.mathkerns - if mk then - local tr=mk.topright - local tl=mk.topleft - local br=mk.bottomright - local bl=mk.bottomleft - chr.mathkern={ - top_right=tr and mathkerns(tr,vdelta) or nil, - top_left=tl and mathkerns(tl,vdelta) or nil, - bottom_right=br and mathkerns(br,vdelta) or nil, - bottom_left=bl and mathkerns(bl,vdelta) or nil, - } - end - end - if hasitalics then - local vi=character.italic - if vi and vi~=0 then - chr.italic=vi*hdelta - end - end - elseif autoitalicamount then - local vi=description.italic - if not vi then - local bb=description.boundingbox - if bb then - local vi=bb[3]-description.width+autoitalicamount - if vi>0 then - chr.italic=vi*hdelta - end - else - end - elseif vi~=0 then - chr.italic=vi*hdelta - end - elseif hasitalics then - local vi=character.italic - if vi and vi~=0 then - chr.italic=vi*hdelta - end - end - if haskerns then - local vk=character.kerns - if vk then - local s=sharedkerns[vk] - if not s then - s={} - for k,v in next,vk do s[k]=v*hdelta end - sharedkerns[vk]=s - end - chr.kerns=s - end - end - if hasligatures then - local vl=character.ligatures - if vl then - if true then - chr.ligatures=vl - else - local tt={} - for i,l in next,vl do - tt[i]=l - end - chr.ligatures=tt - end - end - end - if isvirtual then - local vc=character.commands - if vc then - local ok=false - for i=1,#vc do - local key=vc[i][1] - if key=="right" or key=="down" or key=="rule" then - ok=true - break - end - end - if ok then - local tt={} - for i=1,#vc do - local ivc=vc[i] - local key=ivc[1] - if key=="right" then - tt[i]={ key,ivc[2]*hdelta } - elseif key=="down" then - tt[i]={ key,ivc[2]*vdelta } - elseif key=="rule" then - tt[i]={ key,ivc[2]*vdelta,ivc[3]*hdelta } - else - tt[i]=ivc - end - end - chr.commands=tt - else - chr.commands=vc - end - end - end - targetcharacters[unicode]=chr - end - properties.setitalics=hasitalics - constructors.aftercopyingcharacters(target,tfmdata) - constructors.trytosharefont(target,tfmdata) - local vfonts=target.fonts - if isvirtual or target.type=="virtual" or properties.virtualized then - properties.virtualized=true - target.type="virtual" - if not vfonts or #vfonts==0 then - target.fonts={ { id=0 } } - end - elseif vfonts then - properties.virtualized=true - target.type="virtual" - if #vfonts==0 then - target.fonts={ { id=0 } } - end - end - return target -end -function constructors.finalize(tfmdata) - if tfmdata.properties and tfmdata.properties.finalized then - return - end - if not tfmdata.characters then - return nil - end - if not tfmdata.goodies then - tfmdata.goodies={} - end - local parameters=tfmdata.parameters - if not parameters then - return nil - end - if not parameters.expansion then - parameters.expansion={ - stretch=tfmdata.stretch or 0, - shrink=tfmdata.shrink or 0, - step=tfmdata.step or 0, - } - end - if not parameters.size then - parameters.size=tfmdata.size - end - if not parameters.mode then - parameters.mode=0 - end - if not parameters.width then - parameters.width=0 - end - if not parameters.slantfactor then - parameters.slantfactor=(tfmdata.slant or 0)/1000 - end - if not parameters.extendfactor then - parameters.extendfactor=(tfmdata.extend or 1000)/1000 - end - if not parameters.squeezefactor then - parameters.squeezefactor=(tfmdata.squeeze or 1000)/1000 - end - local designsize=parameters.designsize - if designsize then - parameters.minsize=tfmdata.minsize or designsize - parameters.maxsize=tfmdata.maxsize or designsize - else - designsize=factors.pt*10 - parameters.designsize=designsize - parameters.minsize=designsize - parameters.maxsize=designsize - end - parameters.minsize=tfmdata.minsize or parameters.designsize - parameters.maxsize=tfmdata.maxsize or parameters.designsize - if not parameters.units then - parameters.units=tfmdata.units or tfmdata.units_per_em or 1000 - end - if not tfmdata.descriptions then - local descriptions={} - setmetatableindex(descriptions,function(t,k) local v={} t[k]=v return v end) - tfmdata.descriptions=descriptions - end - local properties=tfmdata.properties - if not properties then - properties={} - tfmdata.properties=properties - end - if not properties.virtualized then - properties.virtualized=tfmdata.type=="virtual" - end - properties.fontname=properties.fontname or tfmdata.fontname - properties.filename=properties.filename or tfmdata.filename - properties.fullname=properties.fullname or tfmdata.fullname - properties.name=properties.name or tfmdata.name - properties.psname=properties.psname or tfmdata.psname - properties.encodingbytes=tfmdata.encodingbytes or 1 - properties.subfont=tfmdata.subfont or nil - properties.embedding=tfmdata.embedding or "subset" - properties.tounicode=tfmdata.tounicode or 1 - properties.cidinfo=tfmdata.cidinfo or nil - properties.format=tfmdata.format or "type1" - properties.direction=tfmdata.direction or 0 - properties.writingmode=tfmdata.writingmode or "horizontal" - properties.identity=tfmdata.identity or "horizontal" - properties.usedbitmap=tfmdata.usedbitmap - if not tfmdata.resources then - tfmdata.resources={} - end - if not tfmdata.shared then - tfmdata.shared={} - end - if not properties.hasmath then - properties.hasmath=not tfmdata.nomath - end - tfmdata.MathConstants=nil - tfmdata.postprocessors=nil - tfmdata.fontname=nil - tfmdata.filename=nil - tfmdata.fullname=nil - tfmdata.name=nil - tfmdata.psname=nil - tfmdata.encodingbytes=nil - tfmdata.subfont=nil - tfmdata.embedding=nil - tfmdata.tounicode=nil - tfmdata.cidinfo=nil - tfmdata.format=nil - tfmdata.direction=nil - tfmdata.type=nil - tfmdata.nomath=nil - tfmdata.designsize=nil - tfmdata.size=nil - tfmdata.stretch=nil - tfmdata.shrink=nil - tfmdata.step=nil - tfmdata.slant=nil - tfmdata.extend=nil - tfmdata.squeeze=nil - tfmdata.mode=nil - tfmdata.width=nil - tfmdata.units=nil - tfmdata.units_per_em=nil - tfmdata.cache=nil - properties.finalized=true - return tfmdata -end -local hashmethods={} -constructors.hashmethods=hashmethods -function constructors.hashfeatures(specification) - local features=specification.features - if features then - local t,n={},0 - for category,list in sortedhash(features) do - if next(list) then - local hasher=hashmethods[category] - if hasher then - local hash=hasher(list) - if hash then - n=n+1 - t[n]=category..":"..hash - end - end - end - end - if n>0 then - return concat(t," & ") - end - end - return "unknown" -end -hashmethods.normal=function(list) - local s={} - local n=0 - for k,v in next,list do - if not k then - elseif k=="number" or k=="features" then - else - n=n+1 - if type(v)=="table" then - local t={} - local m=0 - for k,v in next,v do - m=m+1 - t[m]=k..'='..tostring(v) - end - sort(t) - s[n]=k..'={'..concat(t,",").."}" - else - s[n]=k..'='..tostring(v) - end - end - end - if n>0 then - sort(s) - return concat(s,"+") - end -end -function constructors.hashinstance(specification,force) - local hash=specification.hash - local size=specification.size - local fallbacks=specification.fallbacks - if force or not hash then - hash=constructors.hashfeatures(specification) - specification.hash=hash - end - if size<1000 and designsizes[hash] then - size=round(constructors.scaled(size,designsizes[hash])) - else - size=round(size) - end - specification.size=size - if fallbacks then - return hash..' @ '..size..' @ '..fallbacks - else - return hash..' @ '..size - end -end -function constructors.setname(tfmdata,specification) - if constructors.namemode=="specification" then - local specname=specification.specification - if specname then - tfmdata.properties.name=specname - if trace_defining then - report_otf("overloaded fontname %a",specname) - end - end - end -end -function constructors.checkedfilename(data) - local foundfilename=data.foundfilename - if not foundfilename then - local askedfilename=data.filename or "" - if askedfilename~="" then - askedfilename=resolvers.resolve(askedfilename) - foundfilename=resolvers.findbinfile(askedfilename,"") or "" - if foundfilename=="" then - report_defining("source file %a is not found",askedfilename) - foundfilename=resolvers.findbinfile(file.basename(askedfilename),"") or "" - if foundfilename~="" then - report_defining("using source file %a due to cache mismatch",foundfilename) - end - end - end - data.foundfilename=foundfilename - end - return foundfilename -end -local formats=allocate() -fonts.formats=formats -setmetatableindex(formats,function(t,k) - local l=lower(k) - if rawget(t,k) then - t[k]=l - return l - end - return rawget(t,file.suffix(l)) -end) -do - local function setindeed(mode,source,target,group,name,position) - local action=source[mode] - if not action then - return - end - local t=target[mode] - if not t then - report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode) - os.exit() - elseif position then - insert(t,position,{ name=name,action=action }) - else - for i=1,#t do - local ti=t[i] - if ti.name==name then - ti.action=action - return - end - end - insert(t,{ name=name,action=action }) - end - end - local function set(group,name,target,source) - target=target[group] - if not target then - report_defining("fatal target error in setting feature %a, group %a",name,group) - os.exit() - end - local source=source[group] - if not source then - report_defining("fatal source error in setting feature %a, group %a",name,group) - os.exit() - end - local position=source.position - setindeed("node",source,target,group,name,position) - setindeed("base",source,target,group,name,position) - setindeed("plug",source,target,group,name,position) - end - local function register(where,specification) - local name=specification.name - if name and name~="" then - local default=specification.default - local description=specification.description - local initializers=specification.initializers - local processors=specification.processors - local manipulators=specification.manipulators - local modechecker=specification.modechecker - if default then - where.defaults[name]=default - end - if description and description~="" then - where.descriptions[name]=description - end - if initializers then - set('initializers',name,where,specification) - end - if processors then - set('processors',name,where,specification) - end - if manipulators then - set('manipulators',name,where,specification) - end - if modechecker then - where.modechecker=modechecker - end - end - end - constructors.registerfeature=register - function constructors.getfeatureaction(what,where,mode,name) - what=handlers[what].features - if what then - where=what[where] - if where then - mode=where[mode] - if mode then - for i=1,#mode do - local m=mode[i] - if m.name==name then - return m.action - end - end - end - end - end - end - local newfeatures={} - constructors.newfeatures=newfeatures - constructors.features=newfeatures - local function setnewfeatures(what) - local handler=handlers[what] - local features=handler.features - if not features then - local tables=handler.tables - local statistics=handler.statistics - features=allocate { - defaults={}, - descriptions=tables and tables.features or {}, - used=statistics and statistics.usedfeatures or {}, - initializers={ base={},node={},plug={} }, - processors={ base={},node={},plug={} }, - manipulators={ base={},node={},plug={} }, - } - features.register=function(specification) return register(features,specification) end - handler.features=features - end - return features - end - setmetatable(newfeatures,{ - __call=function(t,k) local v=t[k] return v end, - __index=function(t,k) local v=setnewfeatures(k) t[k]=v return v end, - }) -end -do - local newhandler={} - constructors.handlers=newhandler - constructors.newhandler=newhandler - local function setnewhandler(what) - local handler=handlers[what] - if not handler then - handler={} - handlers[what]=handler - end - return handler - end - setmetatable(newhandler,{ - __call=function(t,k) local v=t[k] return v end, - __index=function(t,k) local v=setnewhandler(k) t[k]=v return v end, - }) -end -do - local newenhancer={} - constructors.enhancers=newenhancer - constructors.newenhancer=newenhancer - local function setnewenhancer(format) - local handler=handlers[format] - local enhancers=handler.enhancers - if not enhancers then - local actions=allocate() - local before=allocate() - local after=allocate() - local order=allocate() - local known={} - local nofsteps=0 - local patches={ before=before,after=after } - local trace=false - local report=logs.reporter("fonts",format.." enhancing") - trackers.register(format..".loading",function(v) trace=v end) - local function enhance(name,data,filename,raw) - local enhancer=actions[name] - if enhancer then - if trace then - report("apply enhancement %a to file %a",name,filename) - ioflush() - end - enhancer(data,filename,raw) - else - end - end - local function apply(data,filename,raw) - local basename=file.basename(lower(filename)) - if trace then - report("%s enhancing file %a","start",filename) - end - ioflush() - for e=1,nofsteps do - local enhancer=order[e] - local b=before[enhancer] - if b then - for pattern,action in next,b do - if find(basename,pattern) then - action(data,filename,raw) - end - end - end - enhance(enhancer,data,filename,raw) - local a=after[enhancer] - if a then - for pattern,action in next,a do - if find(basename,pattern) then - action(data,filename,raw) - end - end - end - ioflush() - end - if trace then - report("%s enhancing file %a","stop",filename) - end - ioflush() - end - local function register(what,action) - if action then - if actions[what] then - else - nofsteps=nofsteps+1 - order[nofsteps]=what - known[what]=nofsteps - end - actions[what]=action - else - report("bad enhancer %a",what) - end - end - local function patch(what,where,pattern,action) - local pw=patches[what] - if pw then - local ww=pw[where] - if ww then - ww[pattern]=action - else - pw[where]={ [pattern]=action } - if not known[where] then - nofsteps=nofsteps+1 - order[nofsteps]=where - known[where]=nofsteps - end - end - end - end - enhancers={ - register=register, - apply=apply, - patch=patch, - report=report, - patches={ - register=patch, - report=report, - }, - } - handler.enhancers=enhancers - end - return enhancers - end - setmetatable(newenhancer,{ - __call=function(t,k) local v=t[k] return v end, - __index=function(t,k) local v=setnewenhancer(k) t[k]=v return v end, - }) -end -function constructors.checkedfeatures(what,features) - local defaults=handlers[what].features.defaults - if features and next(features) then - features=fastcopy(features) - for key,value in next,defaults do - if features[key]==nil then - features[key]=value - end - end - return features - else - return fastcopy(defaults) - end -end -function constructors.initializefeatures(what,tfmdata,features,trace,report) - if features and next(features) then - local properties=tfmdata.properties or {} - local whathandler=handlers[what] - local whatfeatures=whathandler.features - local whatmodechecker=whatfeatures.modechecker - local mode=properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features,features.mode)) or features.mode or "base" - properties.mode=mode - features.mode=mode - local done={} - while true do - local redo=false - local initializers=whatfeatures.initializers[mode] - if initializers then - for i=1,#initializers do - local step=initializers[i] - local feature=step.name - local value=features[feature] - if not value then - elseif done[feature] then - else - local action=step.action - if trace then - report("initializing feature %a to %a for mode %a for font %a",feature, - value,mode,tfmdata.properties.fullname) - end - action(tfmdata,value,features) - if mode~=properties.mode or mode~=features.mode then - if whatmodechecker then - properties.mode=whatmodechecker(tfmdata,features,properties.mode) - features.mode=properties.mode - end - if mode~=properties.mode then - mode=properties.mode - redo=true - end - end - done[feature]=true - end - if redo then - break - end - end - if not redo then - break - end - else - break - end - end - properties.mode=mode - return true - else - return false - end -end -function constructors.collectprocessors(what,tfmdata,features,trace,report) - local processes={} - local nofprocesses=0 - if features and next(features) then - local properties=tfmdata.properties - local whathandler=handlers[what] - local whatfeatures=whathandler.features - local whatprocessors=whatfeatures.processors - local mode=properties.mode - local processors=whatprocessors[mode] - if processors then - for i=1,#processors do - local step=processors[i] - local feature=step.name - if features[feature] then - local action=step.action - if trace then - report("installing feature processor %a for mode %a for font %a",feature,mode,tfmdata.properties.fullname) - end - if action then - nofprocesses=nofprocesses+1 - processes[nofprocesses]=action - end - end - end - elseif trace then - report("no feature processors for mode %a for font %a",mode,properties.fullname) - end - end - return processes -end -function constructors.applymanipulators(what,tfmdata,features,trace,report) - if features and next(features) then - local properties=tfmdata.properties - local whathandler=handlers[what] - local whatfeatures=whathandler.features - local whatmanipulators=whatfeatures.manipulators - local mode=properties.mode - local manipulators=whatmanipulators[mode] - if manipulators then - for i=1,#manipulators do - local step=manipulators[i] - local feature=step.name - local value=features[feature] - if value then - local action=step.action - if trace then - report("applying feature manipulator %a for mode %a for font %a",feature,mode,properties.fullname) - end - if action then - action(tfmdata,feature,value) - end - end - end - end - end -end -function constructors.addcoreunicodes(unicodes) - if not unicodes then - unicodes={} - end - unicodes.space=0x0020 - unicodes.hyphen=0x002D - unicodes.zwj=0x200D - unicodes.zwnj=0x200C - return unicodes -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-con”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-enc” 5ff4ca50493d7c4ecea0e15c203099f0] --- - -if not modules then modules={} end modules ['luatex-font-enc']={ - version=1.001, - comment="companion to luatex-*.tex", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -if context then - os.exit() -end -local fonts=fonts -local encodings={} -fonts.encodings=encodings -encodings.agl={} -encodings.known={} -setmetatable(encodings.agl,{ __index=function(t,k) - if k=="unicodes" then - logs.report("fonts","loading (extended) adobe glyph list") - local unicodes=dofile(resolvers.findfile("font-age.lua")) - encodings.agl={ unicodes=unicodes } - return unicodes - else - return nil - end -end }) -encodings.cache=containers.define("fonts","enc",encodings.version,true) -function encodings.load(filename) - local name=file.removesuffix(filename) - local data=containers.read(encodings.cache,name) - if data then - return data - end - local vector,tag,hash,unicodes={},"",{},{} - local foundname=resolvers.findfile(filename,'enc') - if foundname and foundname~="" then - local ok,encoding,size=resolvers.loadbinfile(foundname) - if ok and encoding then - encoding=string.gsub(encoding,"%%(.-)\n","") - local unicoding=encodings.agl.unicodes - local tag,vec=string.match(encoding,"/(%w+)%s*%[(.*)%]%s*def") - local i=0 - for ch in string.gmatch(vec,"/([%a%d%.]+)") do - if ch~=".notdef" then - vector[i]=ch - if not hash[ch] then - hash[ch]=i - else - end - local u=unicoding[ch] - if u then - unicodes[u]=i - end - end - i=i+1 - end - end - end - local data={ - name=name, - tag=tag, - vector=vector, - hash=hash, - unicodes=unicodes - } - return containers.write(encodings.cache,name,data) -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-enc”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-cid” 22b0367742fb253deef84ef7ccf5e8de] --- - -if not modules then modules={} end modules ['font-cid']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local format,match,lower=string.format,string.match,string.lower -local tonumber=tonumber -local P,S,R,C,V,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.match -local fonts,logs,trackers=fonts,logs,trackers -local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) -local report_otf=logs.reporter("fonts","otf loading") -local cid={} -fonts.cid=cid -local cidmap={} -local cidmax=10 -local number=C(R("09","af","AF")^1) -local space=S(" \n\r\t") -local spaces=space^0 -local period=P(".") -local periods=period*period -local name=P("/")*C((1-space)^1) -local unicodes,names={},{} -local function do_one(a,b) - unicodes[tonumber(a)]=tonumber(b,16) -end -local function do_range(a,b,c) - c=tonumber(c,16) - for i=tonumber(a),tonumber(b) do - unicodes[i]=c - c=c+1 - end -end -local function do_name(a,b) - names[tonumber(a)]=b -end -local grammar=P { "start", - start=number*spaces*number*V("series"), - series=(spaces*(V("one")+V("range")+V("named")))^1, - one=(number*spaces*number)/do_one, - range=(number*periods*number*spaces*number)/do_range, - named=(number*spaces*name)/do_name -} -local function loadcidfile(filename) - local data=io.loaddata(filename) - if data then - unicodes,names={},{} - lpegmatch(grammar,data) - local supplement,registry,ordering=match(filename,"^(.-)%-(.-)%-()%.(.-)$") - return { - supplement=supplement, - registry=registry, - ordering=ordering, - filename=filename, - unicodes=unicodes, - names=names, - } - end -end -cid.loadfile=loadcidfile -local template="%s-%s-%s.cidmap" -local function locate(registry,ordering,supplement) - local filename=format(template,registry,ordering,supplement) - local hashname=lower(filename) - local found=cidmap[hashname] - if not found then - if trace_loading then - report_otf("checking cidmap, registry %a, ordering %a, supplement %a, filename %a",registry,ordering,supplement,filename) - end - local fullname=resolvers.findfile(filename,'cid') or "" - if fullname~="" then - found=loadcidfile(fullname) - if found then - if trace_loading then - report_otf("using cidmap file %a",filename) - end - cidmap[hashname]=found - found.usedname=file.basename(filename) - end - end - end - return found -end -function cid.getmap(specification) - if not specification then - report_otf("invalid cidinfo specification, table expected") - return - end - local registry=specification.registry - local ordering=specification.ordering - local supplement=specification.supplement - local filename=format(registry,ordering,supplement) - local lowername=lower(filename) - local found=cidmap[lowername] - if found then - return found - end - if ordering=="Identity" then - local found={ - supplement=supplement, - registry=registry, - ordering=ordering, - filename=filename, - unicodes={}, - names={}, - } - cidmap[lowername]=found - return found - end - if trace_loading then - report_otf("cidmap needed, registry %a, ordering %a, supplement %a",registry,ordering,supplement) - end - found=locate(registry,ordering,supplement) - if not found then - local supnum=tonumber(supplement) - local cidnum=nil - if supnum0 then - for s=supnum-1,0,-1 do - local c=locate(registry,ordering,s) - if c then - found,cidnum=c,s - break - end - end - end - registry=lower(registry) - ordering=lower(ordering) - if found and cidnum>0 then - for s=0,cidnum-1 do - local filename=format(template,registry,ordering,s) - if not cidmap[filename] then - cidmap[filename]=found - end - end - end - end - return found -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-cid”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-map” c4a39db5ad822b348aa61bca5f4a599a] --- - -if not modules then modules={} end modules ['font-map']={ - version=1.001, - optimize=true, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local tonumber,next,type=tonumber,next,type -local match,format,find,concat,gsub,lower=string.match,string.format,string.find,table.concat,string.gsub,string.lower -local P,R,S,C,Ct,Cc,lpegmatch=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.match -local formatters=string.formatters -local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys -local idiv=number.idiv -local trace_loading=false trackers.register("fonts.loading",function(v) trace_loading=v end) -local trace_mapping=false trackers.register("fonts.mapping",function(v) trace_mapping=v end) -local report_fonts=logs.reporter("fonts","loading") -local force_ligatures=false directives.register("fonts.mapping.forceligatures",function(v) force_ligatures=v end) -local fonts=fonts or {} -local mappings=fonts.mappings or {} -fonts.mappings=mappings -local allocate=utilities.storage.allocate -local hex=R("AF","af","09") -local hexfour=(hex*hex*hex^-2)/function(s) return tonumber(s,16) end -local hexsix=(hex*hex*hex^-4)/function(s) return tonumber(s,16) end -local dec=(R("09")^1)/tonumber -local period=P(".") -local unicode=(P("uni")+P("UNI"))*(hexfour*(period+P(-1))*Cc(false)+Ct(hexfour^1)*Cc(true)) -local ucode=(P("u")+P("U") )*(hexsix*(period+P(-1))*Cc(false)+Ct(hexsix^1)*Cc(true)) -local index=P("index")*dec*Cc(false) -local parser=unicode+ucode+index -local parsers={} -local function makenameparser(str) - if not str or str=="" then - return parser - else - local p=parsers[str] - if not p then - p=P(str)*period*dec*Cc(false) - parsers[str]=p - end - return p - end -end -local f_single=formatters["%04X"] -local f_double=formatters["%04X%04X"] -local s_unknown="FFFD" -local function tounicode16(unicode) - if unicode<0xD7FF or (unicode>0xDFFF and unicode<=0xFFFF) then - return f_single(unicode) - elseif unicode>=0x00E000 and unicode<=0x00F8FF then - return s_unknown - elseif unicode>=0x0F0000 and unicode<=0x0FFFFF then - return s_unknown - elseif unicode>=0x100000 and unicode<=0x10FFFF then - return s_unknown - elseif unicode>=0x00D800 and unicode<=0x00DFFF then - return s_unknown - else - unicode=unicode-0x10000 - return f_double(idiv(k,0x400)+0xD800,unicode%0x400+0xDC00) - end -end -local function tounicode16sequence(unicodes) - local t={} - for l=1,#unicodes do - local u=unicodes[l] - if u<0xD7FF or (u>0xDFFF and u<=0xFFFF) then - t[l]=f_single(u) - elseif unicode>=0x00E000 and unicode<=0x00F8FF then - t[l]=s_unknown - elseif unicode>=0x0F0000 and unicode<=0x0FFFFF then - t[l]=s_unknown - elseif unicode>=0x100000 and unicode<=0x10FFFF then - t[l]=s_unknown - elseif unicode>=0x00D7FF and unicode<=0x00DFFF then - t[l]=s_unknown - else - u=u-0x10000 - t[l]=f_double(idiv(k,0x400)+0xD800,u%0x400+0xDC00) - end - end - return concat(t) -end -local hash={} -local conc={} -table.setmetatableindex(hash,function(t,k) - local v - if k<0xD7FF or (k>0xDFFF and k<=0xFFFF) then - v=f_single(k) - else - local k=k-0x10000 - v=f_double(idiv(k,0x400)+0xD800,k%0x400+0xDC00) - end - t[k]=v - return v -end) -local function tounicode(k) - if type(k)=="table" then - local n=#k - for l=1,n do - conc[l]=hash[k[l]] - end - return concat(conc,"",1,n) - elseif k>=0x00E000 and k<=0x00F8FF then - return s_unknown - elseif k>=0x0F0000 and k<=0x0FFFFF then - return s_unknown - elseif k>=0x100000 and k<=0x10FFFF then - return s_unknown - elseif k>=0x00D7FF and k<=0x00DFFF then - return s_unknown - else - return hash[k] - end -end -local function fromunicode16(str) - if #str==4 then - return tonumber(str,16) - else - local l,r=match(str,"(....)(....)") - return 0x10000+(tonumber(l,16)-0xD800)*0x400+tonumber(r,16)-0xDC00 - end -end -mappings.makenameparser=makenameparser -mappings.tounicode=tounicode -mappings.tounicode16=tounicode16 -mappings.tounicode16sequence=tounicode16sequence -mappings.fromunicode16=fromunicode16 -local ligseparator=P("_") -local varseparator=P(".") -local namesplitter=Ct(C((1-ligseparator-varseparator)^1)*(ligseparator*C((1-ligseparator-varseparator)^1))^0) -do - local overloads={ - IJ={ name="I_J",unicode={ 0x49,0x4A },mess=0x0132 }, - ij={ name="i_j",unicode={ 0x69,0x6A },mess=0x0133 }, - ff={ name="f_f",unicode={ 0x66,0x66 },mess=0xFB00 }, - fi={ name="f_i",unicode={ 0x66,0x69 },mess=0xFB01 }, - fl={ name="f_l",unicode={ 0x66,0x6C },mess=0xFB02 }, - ffi={ name="f_f_i",unicode={ 0x66,0x66,0x69 },mess=0xFB03 }, - ffl={ name="f_f_l",unicode={ 0x66,0x66,0x6C },mess=0xFB04 }, - fj={ name="f_j",unicode={ 0x66,0x6A } }, - fk={ name="f_k",unicode={ 0x66,0x6B } }, - } - local o=allocate {} - for k,v in next,overloads do - local name=v.name - local mess=v.mess - if name then - o[name]=v - end - if mess then - o[mess]=v - end - o[k]=v - end - mappings.overloads=o -end -function mappings.addtounicode(data,filename,checklookups,forceligatures) - local resources=data.resources - local unicodes=resources.unicodes - if not unicodes then - if trace_mapping then - report_fonts("no unicode list, quitting tounicode for %a",filename) - end - return - end - local properties=data.properties - local descriptions=data.descriptions - local overloads=mappings.overloads - unicodes['space']=unicodes['space'] or 32 - unicodes['hyphen']=unicodes['hyphen'] or 45 - unicodes['zwj']=unicodes['zwj'] or 0x200D - unicodes['zwnj']=unicodes['zwnj'] or 0x200C - local private=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 - local unicodevector=fonts.encodings.agl.unicodes or {} - local contextvector=fonts.encodings.agl.ctxcodes or {} - local missing={} - local nofmissing=0 - local oparser=nil - local cidnames=nil - local cidcodes=nil - local cidinfo=properties.cidinfo - local usedmap=cidinfo and fonts.cid.getmap(cidinfo) - local uparser=makenameparser() - if usedmap then - oparser=usedmap and makenameparser(cidinfo.ordering) - cidnames=usedmap.names - cidcodes=usedmap.unicodes - end - local ns=0 - local nl=0 - local dlist=sortedkeys(descriptions) - for i=1,#dlist do - local du=dlist[i] - local glyph=descriptions[du] - local name=glyph.name - if name then - local overload=overloads[name] or overloads[du] - if overload then - glyph.unicode=overload.unicode - else - local gu=glyph.unicode - if not gu or gu==-1 or du>=private or (du>=0xE000 and du<=0xF8FF) or du==0xFFFE or du==0xFFFF then - local unicode=unicodevector[name] or contextvector[name] - if unicode then - glyph.unicode=unicode - ns=ns+1 - end - if (not unicode) and usedmap then - local foundindex=lpegmatch(oparser,name) - if foundindex then - unicode=cidcodes[foundindex] - if unicode then - glyph.unicode=unicode - ns=ns+1 - else - local reference=cidnames[foundindex] - if reference then - local foundindex=lpegmatch(oparser,reference) - if foundindex then - unicode=cidcodes[foundindex] - if unicode then - glyph.unicode=unicode - ns=ns+1 - end - end - if not unicode or unicode=="" then - local foundcodes,multiple=lpegmatch(uparser,reference) - if foundcodes then - glyph.unicode=foundcodes - if multiple then - nl=nl+1 - unicode=true - else - ns=ns+1 - unicode=foundcodes - end - end - end - end - end - end - end - if not unicode or unicode=="" then - local split=lpegmatch(namesplitter,name) - local nsplit=split and #split or 0 - if nsplit==0 then - elseif nsplit==1 then - local base=split[1] - local u=unicodes[base] or unicodevector[base] or contextvector[name] - if not u then - elseif type(u)=="table" then - if u[1]=private then - break - end - n=n+1 - t[n]=u[1] - else - if u>=private then - break - end - n=n+1 - t[n]=u - end - end - if n>0 then - if n==1 then - unicode=t[1] - else - unicode=t - end - glyph.unicode=unicode - end - end - nl=nl+1 - end - if not unicode or unicode=="" then - local foundcodes,multiple=lpegmatch(uparser,name) - if foundcodes then - glyph.unicode=foundcodes - if multiple then - nl=nl+1 - unicode=true - else - ns=ns+1 - unicode=foundcodes - end - end - end - local r=overloads[unicode] - if r then - unicode=r.unicode - glyph.unicode=unicode - end - if not unicode then - missing[du]=true - nofmissing=nofmissing+1 - end - else - end - end - else - local overload=overloads[du] - if overload then - glyph.unicode=overload.unicode - elseif not glyph.unicode then - missing[du]=true - nofmissing=nofmissing+1 - end - end - end - if type(checklookups)=="function" then - checklookups(data,missing,nofmissing) - end - local unicoded=0 - local collected=fonts.handlers.otf.readers.getcomponents(data) - local function resolve(glyph,u) - local n=#u - for i=1,n do - if u[i]>private then - n=0 - break - end - end - if n>0 then - if n>1 then - glyph.unicode=u - else - glyph.unicode=u[1] - end - unicoded=unicoded+1 - end - end - if not collected then - elseif forceligatures or force_ligatures then - for i=1,#dlist do - local du=dlist[i] - if du>=private or (du>=0xE000 and du<=0xF8FF) then - local u=collected[du] - if u then - resolve(descriptions[du],u) - end - end - end - else - for i=1,#dlist do - local du=dlist[i] - if du>=private or (du>=0xE000 and du<=0xF8FF) then - local glyph=descriptions[du] - if glyph.class=="ligature" and not glyph.unicode then - local u=collected[du] - if u then - resolve(glyph,u) - end - end - end - end - end - if trace_mapping and unicoded>0 then - report_fonts("%n ligature tounicode mappings deduced from gsub ligature features",unicoded) - end - if trace_mapping then - for i=1,#dlist do - local du=dlist[i] - local glyph=descriptions[du] - local name=glyph.name or "-" - local index=glyph.index or 0 - local unicode=glyph.unicode - if unicode then - if type(unicode)=="table" then - local unicodes={} - for i=1,#unicode do - unicodes[i]=formatters("%U",unicode[i]) - end - report_fonts("internal slot %U, name %a, unicode %U, tounicode % t",index,name,du,unicodes) - else - report_fonts("internal slot %U, name %a, unicode %U, tounicode %U",index,name,du,unicode) - end - else - report_fonts("internal slot %U, name %a, unicode %U",index,name,du) - end - end - end - if trace_loading and (ns>0 or nl>0) then - report_fonts("%s tounicode entries added, ligatures %s",nl+ns,ns) - end -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-map”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-vfc” a81c29eda98cd62cbebdb6c93544b50d] --- - -if not modules then modules={} end modules ['font-vfc']={ - version=1.001, - comment="companion to font-ini.mkiv and hand-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local select,type=select,type -local insert=table.insert -local fonts=fonts -local helpers=fonts.helpers -local setmetatableindex=table.setmetatableindex -local push={ "push" } -local pop={ "pop" } -local dummy={ "comment" } -function helpers.prependcommands(commands,...) - insert(commands,1,push) - for i=select("#",...),1,-1 do - local s=(select(i,...)) - if s then - insert(commands,1,s) - end - end - insert(commands,pop) - return commands -end -function helpers.appendcommands(commands,...) - insert(commands,1,push) - insert(commands,pop) - for i=1,select("#",...) do - local s=(select(i,...)) - if s then - insert(commands,s) - end - end - return commands -end -function helpers.prependcommandtable(commands,t) - insert(commands,1,push) - for i=#t,1,-1 do - local s=t[i] - if s then - insert(commands,1,s) - end - end - insert(commands,pop) - return commands -end -function helpers.appendcommandtable(commands,t) - insert(commands,1,push) - insert(commands,pop) - for i=1,#t do - local s=t[i] - if s then - insert(commands,s) - end - end - return commands -end -local char=setmetatableindex(function(t,k) - local v={ "slot",0,k } - t[k]=v - return v -end) -local right=setmetatableindex(function(t,k) - local v={ "right",k } - t[k]=v - return v -end) -local left=setmetatableindex(function(t,k) - local v={ "right",-k } - t[k]=v - return v -end) -local down=setmetatableindex(function(t,k) - local v={ "down",k } - t[k]=v - return v -end) -local up=setmetatableindex(function(t,k) - local v={ "down",-k } - t[k]=v - return v -end) -helpers.commands=utilities.storage.allocate { - char=char, - right=right, - left=left, - down=down, - up=up, - push=push, - pop=pop, - dummy=dummy, -} - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-vfc”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otr” 64dcbbc7107538723990e1119a80a9f8] --- - -if not modules then modules={} end modules ['font-otr']={ - version=1.001, - optimize=true, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next,type,tonumber,rawget=next,type,tonumber,rawget -local byte,lower,char,gsub=string.byte,string.lower,string.char,string.gsub -local fullstrip=string.fullstrip -local floor,round=math.floor,math.round -local P,R,S,C,Cs,Cc,Ct,Carg,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg,lpeg.Cmt -local lpegmatch=lpeg.match -local rshift=bit32.rshift -local setmetatableindex=table.setmetatableindex -local sortedkeys=table.sortedkeys -local sortedhash=table.sortedhash -local stripstring=string.nospaces -local utf16_to_utf8_be=utf.utf16_to_utf8_be -local report=logs.reporter("otf reader") -local report_cmap=logs.reporter("otf reader","cmap") -local trace_cmap=false trackers.register("otf.cmap",function(v) trace_cmap=v end) -local trace_cmap_details=false trackers.register("otf.cmap.details",function(v) trace_cmap_details=v end) -fonts=fonts or {} -local handlers=fonts.handlers or {} -fonts.handlers=handlers -local otf=handlers.otf or {} -handlers.otf=otf -local readers=otf.readers or {} -otf.readers=readers -local streamreader=utilities.files -local streamwriter=utilities.files -readers.streamreader=streamreader -readers.streamwriter=streamwriter -local openfile=streamreader.open -local closefile=streamreader.close -local setposition=streamreader.setposition -local skipshort=streamreader.skipshort -local readbytes=streamreader.readbytes -local readstring=streamreader.readstring -local readbyte=streamreader.readcardinal1 -local readushort=streamreader.readcardinal2 -local readuint=streamreader.readcardinal3 -local readulong=streamreader.readcardinal4 -local readshort=streamreader.readinteger2 -local readlong=streamreader.readinteger4 -local readfixed=streamreader.readfixed4 -local read2dot14=streamreader.read2dot14 -local readfword=readshort -local readufword=readushort -local readoffset=readushort -local readcardinaltable=streamreader.readcardinaltable -local readintegertable=streamreader.readintegertable -function streamreader.readtag(f) - return lower(stripstring(readstring(f,4))) -end -local short=2 -local ushort=2 -local ulong=4 -directives.register("fonts.streamreader",function() - streamreader=utilities.streams - openfile=streamreader.open - closefile=streamreader.close - setposition=streamreader.setposition - skipshort=streamreader.skipshort - readbytes=streamreader.readbytes - readstring=streamreader.readstring - readbyte=streamreader.readcardinal1 - readushort=streamreader.readcardinal2 - readuint=streamreader.readcardinal3 - readulong=streamreader.readcardinal4 - readshort=streamreader.readinteger2 - readlong=streamreader.readinteger4 - readfixed=streamreader.readfixed4 - read2dot14=streamreader.read2dot14 - readfword=readshort - readufword=readushort - readoffset=readushort - readcardinaltable=streamreader.readcardinaltable - readintegertable=streamreader.readintegertable - function streamreader.readtag(f) - return lower(stripstring(readstring(f,4))) - end -end) -local function readlongdatetime(f) - local a,b,c,d,e,f,g,h=readbytes(f,8) - return 0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h -end -local tableversion=0.004 -readers.tableversion=tableversion -local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -local reservednames={ [0]="copyright", - "family", - "subfamily", - "uniqueid", - "fullname", - "version", - "postscriptname", - "trademark", - "manufacturer", - "designer", - "description", - "vendorurl", - "designerurl", - "license", - "licenseurl", - "reserved", - "typographicfamily", - "typographicsubfamily", - "compatiblefullname", - "sampletext", - "cidfindfontname", - "wwsfamily", - "wwssubfamily", - "lightbackgroundpalette", - "darkbackgroundpalette", - "variationspostscriptnameprefix", -} -local platforms={ [0]="unicode", - "macintosh", - "iso", - "windows", - "custom", -} -local encodings={ - unicode={ [0]="unicode 1.0 semantics", - "unicode 1.1 semantics", - "iso/iec 10646", - "unicode 2.0 bmp", - "unicode 2.0 full", - "unicode variation sequences", - "unicode full repertoire", - }, - macintosh={ [0]="roman","japanese","chinese (traditional)","korean","arabic","hebrew","greek","russian", - "rsymbol","devanagari","gurmukhi","gujarati","oriya","bengali","tamil","telugu","kannada", - "malayalam","sinhalese","burmese","khmer","thai","laotian","georgian","armenian", - "chinese (simplified)","tibetan","mongolian","geez","slavic","vietnamese","sindhi", - "uninterpreted", - }, - iso={ [0]="7-bit ascii", - "iso 10646", - "iso 8859-1", - }, - windows={ [0]="symbol", - "unicode bmp", - "shiftjis", - "prc", - "big5", - "wansung", - "johab", - "reserved 7", - "reserved 8", - "reserved 9", - "unicode ucs-4", - }, - custom={ - } -} -local decoders={ - unicode={}, - macintosh={}, - iso={}, - windows={ - ["unicode semantics"]=utf16_to_utf8_be, - ["unicode bmp"]=utf16_to_utf8_be, - ["unicode full"]=utf16_to_utf8_be, - ["unicode 1.0 semantics"]=utf16_to_utf8_be, - ["unicode 1.1 semantics"]=utf16_to_utf8_be, - ["unicode 2.0 bmp"]=utf16_to_utf8_be, - ["unicode 2.0 full"]=utf16_to_utf8_be, - ["unicode variation sequences"]=utf16_to_utf8_be, - ["unicode full repertoire"]=utf16_to_utf8_be, - }, - custom={}, -} -local languages={ - unicode={ - [ 0]="english", - }, - macintosh={ - [ 0]="english", - }, - iso={}, - windows={ - [0x0409]="english - united states", - }, - custom={}, -} -local standardromanencoding={ [0]= - "notdef",".null","nonmarkingreturn","space","exclam","quotedbl", - "numbersign","dollar","percent","ampersand","quotesingle","parenleft", - "parenright","asterisk","plus","comma","hyphen","period","slash", - "zero","one","two","three","four","five","six","seven","eight", - "nine","colon","semicolon","less","equal","greater","question","at", - "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O", - "P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft", - "backslash","bracketright","asciicircum","underscore","grave","a","b", - "c","d","e","f","g","h","i","j","k","l","m","n","o","p","q", - "r","s","t","u","v","w","x","y","z","braceleft","bar", - "braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute", - "Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex", - "adieresis","atilde","aring","ccedilla","eacute","egrave", - "ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis", - "ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute", - "ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling", - "section","bullet","paragraph","germandbls","registered","copyright", - "trademark","acute","dieresis","notequal","AE","Oslash","infinity", - "plusminus","lessequal","greaterequal","yen","mu","partialdiff", - "summation","product","pi","integral","ordfeminine","ordmasculine", - "Omega","ae","oslash","questiondown","exclamdown","logicalnot", - "radical","florin","approxequal","Delta","guillemotleft", - "guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde", - "Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright", - "quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis", - "fraction","currency","guilsinglleft","guilsinglright","fi","fl", - "daggerdbl","periodcentered","quotesinglbase","quotedblbase", - "perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave", - "Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex", - "apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi", - "circumflex","tilde","macron","breve","dotaccent","ring","cedilla", - "hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron", - "Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn", - "thorn","minus","multiply","onesuperior","twosuperior","threesuperior", - "onehalf","onequarter","threequarters","franc","Gbreve","gbreve", - "Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron", - "dcroat", -} -local weights={ - [100]="thin", - [200]="extralight", - [300]="light", - [400]="normal", - [500]="medium", - [600]="semibold", - [700]="bold", - [800]="extrabold", - [900]="black", -} -local widths={ - [1]="ultracondensed", - [2]="extracondensed", - [3]="condensed", - [4]="semicondensed", - [5]="normal", - [6]="semiexpanded", - [7]="expanded", - [8]="extraexpanded", - [9]="ultraexpanded", -} -setmetatableindex(weights,function(t,k) - local r=floor((k+50)/100)*100 - local v=(r>900 and "black") or rawget(t,r) or "normal" - return v -end) -setmetatableindex(widths,function(t,k) - return "normal" -end) -local panoseweights={ - [ 0]="normal", - [ 1]="normal", - [ 2]="verylight", - [ 3]="light", - [ 4]="thin", - [ 5]="book", - [ 6]="medium", - [ 7]="demi", - [ 8]="bold", - [ 9]="heavy", - [10]="black", -} -local panosewidths={ - [ 0]="normal", - [ 1]="normal", - [ 2]="normal", - [ 3]="normal", - [ 4]="normal", - [ 5]="expanded", - [ 6]="condensed", - [ 7]="veryexpanded", - [ 8]="verycondensed", - [ 9]="monospaced", -} -local helpers={} -readers.helpers=helpers -local function gotodatatable(f,fontdata,tag,criterium) - if criterium and f then - local tables=fontdata.tables - if tables then - local datatable=tables[tag] - if datatable then - local tableoffset=datatable.offset - setposition(f,tableoffset) - return tableoffset - end - else - report("no tables") - end - end -end -local function reportskippedtable(f,fontdata,tag,criterium) - if criterium and f then - local tables=fontdata.tables - if tables then - local datatable=tables[tag] - if datatable then - report("loading of table %a skipped",tag) - end - else - report("no tables") - end - end -end -local function setvariabledata(fontdata,tag,data) - local variabledata=fontdata.variabledata - if variabledata then - variabledata[tag]=data - else - fontdata.variabledata={ [tag]=data } - end -end -helpers.gotodatatable=gotodatatable -helpers.setvariabledata=setvariabledata -helpers.reportskippedtable=reportskippedtable -local platformnames={ - postscriptname=true, - fullname=true, - family=true, - subfamily=true, - typographicfamily=true, - typographicsubfamily=true, - compatiblefullname=true, -} -local platformextras={ - uniqueid=true, - version=true, - copyright=true, - license=true, - licenseurl=true, - manufacturer=true, - vendorurl=true, -} -function readers.name(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"name",true) - if tableoffset then - local format=readushort(f) - local nofnames=readushort(f) - local offset=readushort(f) - local start=tableoffset+offset - local namelists={ - unicode={}, - windows={}, - macintosh={}, - } - for i=1,nofnames do - local platform=platforms[readushort(f)] - if platform then - local namelist=namelists[platform] - if namelist then - local encoding=readushort(f) - local language=readushort(f) - local encodings=encodings[platform] - local languages=languages[platform] - if encodings and languages then - local encoding=encodings[encoding] - local language=languages[language] - if encoding and language then - local index=readushort(f) - local name=reservednames[index] - namelist[#namelist+1]={ - platform=platform, - encoding=encoding, - language=language, - name=name, - index=index, - length=readushort(f), - offset=start+readushort(f), - } - else - skipshort(f,3) - end - else - skipshort(f,3) - end - else - skipshort(f,5) - end - else - skipshort(f,5) - end - end - local names={} - local done={} - local extras={} - local function decoded(platform,encoding,content) - local decoder=decoders[platform] - if decoder then - decoder=decoder[encoding] - end - if decoder then - return decoder(content) - else - return content - end - end - local function filter(platform,e,l) - local namelist=namelists[platform] - for i=1,#namelist do - local name=namelist[i] - local nametag=name.name - local index=name.index - if not done[nametag or i] then - local encoding=name.encoding - local language=name.language - if (not e or encoding==e) and (not l or language==l) then - setposition(f,name.offset) - local content=decoded(platform,encoding,readstring(f,name.length)) - if nametag then - names[nametag]={ - content=content, - platform=platform, - encoding=encoding, - language=language, - } - end - extras[index]=content - done[nametag or i]=true - end - end - end - end - filter("windows","unicode bmp","english - united states") - filter("macintosh","roman","english") - filter("windows") - filter("macintosh") - filter("unicode") - fontdata.names=names - fontdata.extras=extras - if specification.platformnames then - local collected={} - local platformextras=specification.platformextras and platformextras - for platform,namelist in next,namelists do - local filtered=false - for i=1,#namelist do - local entry=namelist[i] - local name=entry.name - if platformnames[name] or (platformextras and platformextras[name]) then - setposition(f,entry.offset) - local content=decoded(platform,entry.encoding,readstring(f,entry.length)) - if filtered then - filtered[name]=content - else - filtered={ [name]=content } - end - end - end - if filtered then - collected[platform]=filtered - end - end - fontdata.platformnames=collected - end - else - fontdata.names={} - end -end -local validutf=lpeg.patterns.validutf8 -local function getname(fontdata,key) - local names=fontdata.names - if names then - local value=names[key] - if value then - local content=value.content - return lpegmatch(validutf,content) and content or nil - end - end -end -readers["os/2"]=function(f,fontdata) - local tableoffset=gotodatatable(f,fontdata,"os/2",true) - if tableoffset then - local version=readushort(f) - local windowsmetrics={ - version=version, - averagewidth=readshort(f), - weightclass=readushort(f), - widthclass=readushort(f), - fstype=readushort(f), - subscriptxsize=readshort(f), - subscriptysize=readshort(f), - subscriptxoffset=readshort(f), - subscriptyoffset=readshort(f), - superscriptxsize=readshort(f), - superscriptysize=readshort(f), - superscriptxoffset=readshort(f), - superscriptyoffset=readshort(f), - strikeoutsize=readshort(f), - strikeoutpos=readshort(f), - familyclass=readshort(f), - panose={ readbytes(f,10) }, - unicoderanges={ readulong(f),readulong(f),readulong(f),readulong(f) }, - vendor=readstring(f,4), - fsselection=readushort(f), - firstcharindex=readushort(f), - lastcharindex=readushort(f), - typoascender=readshort(f), - typodescender=readshort(f), - typolinegap=readshort(f), - winascent=readushort(f), - windescent=readushort(f), - } - if version>=1 then - windowsmetrics.codepageranges={ readulong(f),readulong(f) } - end - if version>=2 then - windowsmetrics.xheight=readshort(f) - windowsmetrics.capheight=readshort(f) - windowsmetrics.defaultchar=readushort(f) - windowsmetrics.breakchar=readushort(f) - end - windowsmetrics.weight=windowsmetrics.weightclass and weights[windowsmetrics.weightclass] - windowsmetrics.width=windowsmetrics.widthclass and widths [windowsmetrics.widthclass] - windowsmetrics.panoseweight=panoseweights[windowsmetrics.panose[3]] - windowsmetrics.panosewidth=panosewidths [windowsmetrics.panose[4]] - fontdata.windowsmetrics=windowsmetrics - else - fontdata.windowsmetrics={} - end -end -readers.head=function(f,fontdata) - local tableoffset=gotodatatable(f,fontdata,"head",true) - if tableoffset then - local version=readulong(f) - local fontversion=readulong(f) - local fontheader={ - version=version, - fontversion=number.to16dot16(fontversion), - fontversionnumber=fontversion, - checksum=readushort(f)*0x10000+readushort(f), - magic=readulong(f), - flags=readushort(f), - units=readushort(f), - created=readlongdatetime(f), - modified=readlongdatetime(f), - xmin=readshort(f), - ymin=readshort(f), - xmax=readshort(f), - ymax=readshort(f), - macstyle=readushort(f), - smallpixels=readushort(f), - directionhint=readshort(f), - indextolocformat=readshort(f), - glyphformat=readshort(f), - } - fontdata.fontheader=fontheader - else - fontdata.fontheader={} - end - fontdata.nofglyphs=0 -end -readers.hhea=function(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"hhea",specification.details) - if tableoffset then - fontdata.horizontalheader={ - version=readulong(f), - ascender=readfword(f), - descender=readfword(f), - linegap=readfword(f), - maxadvancewidth=readufword(f), - minleftsidebearing=readfword(f), - minrightsidebearing=readfword(f), - maxextent=readfword(f), - caretsloperise=readshort(f), - caretsloperun=readshort(f), - caretoffset=readshort(f), - reserved_1=readshort(f), - reserved_2=readshort(f), - reserved_3=readshort(f), - reserved_4=readshort(f), - metricdataformat=readshort(f), - nofmetrics=readushort(f), - } - else - fontdata.horizontalheader={ - nofmetrics=0, - } - end -end -readers.vhea=function(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"vhea",specification.details) - if tableoffset then - fontdata.verticalheader={ - version=readulong(f), - ascender=readfword(f), - descender=readfword(f), - linegap=readfword(f), - maxadvanceheight=readufword(f), - mintopsidebearing=readfword(f), - minbottomsidebearing=readfword(f), - maxextent=readfword(f), - caretsloperise=readshort(f), - caretsloperun=readshort(f), - caretoffset=readshort(f), - reserved_1=readshort(f), - reserved_2=readshort(f), - reserved_3=readshort(f), - reserved_4=readshort(f), - metricdataformat=readshort(f), - nofmetrics=readushort(f), - } - else - fontdata.verticalheader={ - nofmetrics=0, - } - end -end -readers.maxp=function(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"maxp",specification.details) - if tableoffset then - local version=readulong(f) - local nofglyphs=readushort(f) - fontdata.nofglyphs=nofglyphs - if version==0x00005000 then - fontdata.maximumprofile={ - version=version, - nofglyphs=nofglyphs, - } - elseif version==0x00010000 then - fontdata.maximumprofile={ - version=version, - nofglyphs=nofglyphs, - points=readushort(f), - contours=readushort(f), - compositepoints=readushort(f), - compositecontours=readushort(f), - zones=readushort(f), - twilightpoints=readushort(f), - storage=readushort(f), - functiondefs=readushort(f), - instructiondefs=readushort(f), - stackelements=readushort(f), - sizeofinstructions=readushort(f), - componentelements=readushort(f), - componentdepth=readushort(f), - } - else - fontdata.maximumprofile={ - version=version, - nofglyphs=0, - } - end - end -end -readers.hmtx=function(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"hmtx",specification.glyphs) - if tableoffset then - local horizontalheader=fontdata.horizontalheader - local nofmetrics=horizontalheader.nofmetrics - local glyphs=fontdata.glyphs - local nofglyphs=fontdata.nofglyphs - local width=0 - local leftsidebearing=0 - for i=0,nofmetrics-1 do - local glyph=glyphs[i] - width=readshort(f) - leftsidebearing=readshort(f) - if width~=0 then - glyph.width=width - end - end - for i=nofmetrics,nofglyphs-1 do - local glyph=glyphs[i] - if width~=0 then - glyph.width=width - end - end - end -end -readers.vmtx=function(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"vmtx",specification.glyphs) - if tableoffset then - local verticalheader=fontdata.verticalheader - local nofmetrics=verticalheader.nofmetrics - local glyphs=fontdata.glyphs - local nofglyphs=fontdata.nofglyphs - local vheight=0 - local vdefault=verticalheader.ascender-verticalheader.descender - local topsidebearing=0 - for i=0,nofmetrics-1 do - local glyph=glyphs[i] - vheight=readushort(f) - topsidebearing=readshort(f) - if vheight~=0 and vheight~=vdefault then - glyph.vheight=vheight - end - if topsidebearing~=0 then - glyph.tsb=topsidebearing - end - end - for i=nofmetrics,nofglyphs-1 do - local glyph=glyphs[i] - if vheight~=0 and vheight~=vdefault then - glyph.vheight=vheight - end - end - end -end -readers.vorg=function(f,fontdata,specification) - reportskippedtable(f,fontdata,"vorg",specification.glyphs) -end -readers.post=function(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"post",true) - if tableoffset then - local version=readulong(f) - fontdata.postscript={ - version=version, - italicangle=round(1000*readfixed(f))/1000, - underlineposition=readfword(f), - underlinethickness=readfword(f), - monospaced=readulong(f), - minmemtype42=readulong(f), - maxmemtype42=readulong(f), - minmemtype1=readulong(f), - maxmemtype1=readulong(f), - } - if not specification.glyphs then - elseif version==0x00010000 then - for index=0,#standardromanencoding do - glyphs[index].name=standardromanencoding[index] - end - elseif version==0x00020000 then - local glyphs=fontdata.glyphs - local nofglyphs=readushort(f) - local indices={} - local names={} - local maxnames=0 - for i=0,nofglyphs-1 do - local nameindex=readushort(f) - if nameindex>=258 then - maxnames=maxnames+1 - nameindex=nameindex-257 - indices[nameindex]=i - else - glyphs[i].name=standardromanencoding[nameindex] - end - end - for i=1,maxnames do - local mapping=indices[i] - if not mapping then - report("quit post name fetching at %a of %a: %s",i,maxnames,"no index") - break - else - local length=readbyte(f) - if length>0 then - glyphs[mapping].name=readstring(f,length) - else - report("quit post name fetching at %a of %a: %s",i,maxnames,"overflow") - break - end - end - end - end - else - fontdata.postscript={} - end -end -readers.cff=function(f,fontdata,specification) - reportskippedtable(f,fontdata,"cff",specification.glyphs) -end -local formatreaders={} -local duplicatestoo=true -local sequence={ - { 3,1,4 }, - { 3,10,12 }, - { 0,3,4 }, - { 0,3,12 }, - { 0,1,4 }, - { 0,1,12 }, - { 0,0,6 }, - { 3,0,6 }, - { 3,0,4 }, - { 0,5,14 }, - { 0,4,12 }, - { 3,10,13 }, -} -local supported={} -for i=1,#sequence do - local si=sequence[i] - local sp,se,sf=si[1],si[2],si[3] - local p=supported[sp] - if not p then - p={} - supported[sp]=p - end - local e=p[se] - if not e then - e={} - p[se]=e - end - e[sf]=true -end -formatreaders[4]=function(f,fontdata,offset) - setposition(f,offset+2) - local length=readushort(f) - local language=readushort(f) - local nofsegments=readushort(f)/2 - skipshort(f,3) - local mapping=fontdata.mapping - local glyphs=fontdata.glyphs - local duplicates=fontdata.duplicates - local nofdone=0 - local endchars=readcardinaltable(f,nofsegments,ushort) - local reserved=readushort(f) - local startchars=readcardinaltable(f,nofsegments,ushort) - local deltas=readcardinaltable(f,nofsegments,ushort) - local offsets=readcardinaltable(f,nofsegments,ushort) - local size=(length-2*2-5*2-4*2*nofsegments)/2 - local indices=readcardinaltable(f,size-1,ushort) - for segment=1,nofsegments do - local startchar=startchars[segment] - local endchar=endchars[segment] - local offset=offsets[segment] - local delta=deltas[segment] - if startchar==0xFFFF and endchar==0xFFFF then - elseif startchar==0xFFFF and offset==0 then - elseif offset==0xFFFF then - elseif offset==0 then - if trace_cmap_details then - report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,(startchar+delta)%65536) - end - for unicode=startchar,endchar do - local index=(unicode+delta)%65536 - if index and index>0 then - local glyph=glyphs[index] - if glyph then - local gu=glyph.unicode - if not gu then - glyph.unicode=unicode - nofdone=nofdone+1 - elseif gu~=unicode then - if duplicatestoo then - local d=duplicates[gu] - if d then - d[unicode]=true - else - duplicates[gu]={ [unicode]=true } - end - else - report("duplicate case 1: %C %04i %s",unicode,index,glyphs[index].name) - end - end - if not mapping[index] then - mapping[index]=unicode - end - end - end - end - else - local shift=(segment-nofsegments+offset/2)-startchar - if trace_cmap_details then - report_cmap("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,(startchar+delta)%65536) - end - for unicode=startchar,endchar do - local slot=shift+unicode - local index=indices[slot] - if index and index>0 then - index=(index+delta)%65536 - local glyph=glyphs[index] - if glyph then - local gu=glyph.unicode - if not gu then - glyph.unicode=unicode - nofdone=nofdone+1 - elseif gu~=unicode then - if duplicatestoo then - local d=duplicates[gu] - if d then - d[unicode]=true - else - duplicates[gu]={ [unicode]=true } - end - else - report("duplicate case 2: %C %04i %s",unicode,index,glyphs[index].name) - end - end - if not mapping[index] then - mapping[index]=unicode - end - end - end - end - end - end - return nofdone -end -formatreaders[6]=function(f,fontdata,offset) - setposition(f,offset) - local format=readushort(f) - local length=readushort(f) - local language=readushort(f) - local mapping=fontdata.mapping - local glyphs=fontdata.glyphs - local duplicates=fontdata.duplicates - local start=readushort(f) - local count=readushort(f) - local stop=start+count-1 - local nofdone=0 - if trace_cmap_details then - report_cmap("format 6 from %C to %C",2,start,stop) - end - for unicode=start,stop do - local index=readushort(f) - if index>0 then - local glyph=glyphs[index] - if glyph then - local gu=glyph.unicode - if not gu then - glyph.unicode=unicode - nofdone=nofdone+1 - elseif gu~=unicode then - end - if not mapping[index] then - mapping[index]=unicode - end - end - end - end - return nofdone -end -formatreaders[12]=function(f,fontdata,offset) - setposition(f,offset+2+2+4+4) - local mapping=fontdata.mapping - local glyphs=fontdata.glyphs - local duplicates=fontdata.duplicates - local nofgroups=readulong(f) - local nofdone=0 - for i=1,nofgroups do - local first=readulong(f) - local last=readulong(f) - local index=readulong(f) - if trace_cmap_details then - report_cmap("format 12 from %C to %C starts at index %i",first,last,index) - end - for unicode=first,last do - local glyph=glyphs[index] - if glyph then - local gu=glyph.unicode - if not gu then - glyph.unicode=unicode - nofdone=nofdone+1 - elseif gu~=unicode then - local d=duplicates[gu] - if d then - d[unicode]=true - else - duplicates[gu]={ [unicode]=true } - end - end - if not mapping[index] then - mapping[index]=unicode - end - end - index=index+1 - end - end - return nofdone -end -formatreaders[13]=function(f,fontdata,offset) - setposition(f,offset+2+2+4+4) - local mapping=fontdata.mapping - local glyphs=fontdata.glyphs - local duplicates=fontdata.duplicates - local nofgroups=readulong(f) - local nofdone=0 - for i=1,nofgroups do - local first=readulong(f) - local last=readulong(f) - local index=readulong(f) - if first=privateoffset then - local limit=privateoffset-1 - report("format 13 from %C to %C pruned to %C",first,last,limit) - last=limit - end - for unicode=first,last do - list[unicode]=true - end - nofdone=nofdone+last-first+1 - else - report("format 13 from %C to %C ignored",first,last) - end - end - return nofdone -end -formatreaders[14]=function(f,fontdata,offset) - if offset and offset~=0 then - setposition(f,offset) - local format=readushort(f) - local length=readulong(f) - local nofrecords=readulong(f) - local records={} - local variants={} - local nofdone=0 - fontdata.variants=variants - for i=1,nofrecords do - records[i]={ - selector=readuint(f), - default=readulong(f), - other=readulong(f), - } - end - for i=1,nofrecords do - local record=records[i] - local selector=record.selector - local default=record.default - local other=record.other - local other=record.other - if other~=0 then - setposition(f,offset+other) - local mapping={} - local count=readulong(f) - for i=1,count do - mapping[readuint(f)]=readushort(f) - end - nofdone=nofdone+count - variants[selector]=mapping - end - end - return nofdone - else - return 0 - end -end -local function checkcmap(f,fontdata,records,platform,encoding,format) - local pdata=records[platform] - if not pdata then - if trace_cmap_details then - report_cmap("skipped, %s, p=%i e=%i f=%i","no platform",platform,encoding,format) - end - return 0 - end - local edata=pdata[encoding] - if not edata then - if trace_cmap_details then - report_cmap("skipped, %s, p=%i e=%i f=%i","no encoding",platform,encoding,format) - end - return 0 - end - local fdata=edata[format] - if not fdata then - if trace_cmap_details then - report_cmap("skipped, %s, p=%i e=%i f=%i","no format",platform,encoding,format) - end - return 0 - elseif type(fdata)~="number" then - if trace_cmap_details then - report_cmap("skipped, %s, p=%i e=%i f=%i","already done",platform,encoding,format) - end - return 0 - end - edata[format]=true - local reader=formatreaders[format] - if not reader then - if trace_cmap_details then - report_cmap("skipped, %s, p=%i e=%i f=%i","unsupported format",platform,encoding,format) - end - return 0 - end - local n=reader(f,fontdata,fdata) or 0 - if trace_cmap_details or trace_cmap then - local p=platforms[platform] - local e=encodings[p] - report_cmap("checked, platform %i (%s), encoding %i (%s), format %i, new unicodes %i", - platform,p,encoding,e and e[encoding] or "?",format,n) - end - return n -end -function readers.cmap(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"cmap",specification.glyphs) - if tableoffset then - local version=readushort(f) - local noftables=readushort(f) - local records={} - local unicodecid=false - local variantcid=false - local variants={} - local duplicates=fontdata.duplicates or {} - fontdata.duplicates=duplicates - for i=1,noftables do - local platform=readushort(f) - local encoding=readushort(f) - local offset=readulong(f) - local record=records[platform] - if not record then - records[platform]={ - [encoding]={ - offsets={ offset }, - formats={}, - } - } - else - local subtables=record[encoding] - if not subtables then - record[encoding]={ - offsets={ offset }, - formats={}, - } - else - local offsets=subtables.offsets - offsets[#offsets+1]=offset - end - end - end - if trace_cmap then - report("found cmaps:") - end - for platform,record in sortedhash(records) do - local p=platforms[platform] - local e=encodings[p] - local sp=supported[platform] - local ps=p or "?" - if trace_cmap then - if sp then - report(" platform %i: %s",platform,ps) - else - report(" platform %i: %s (unsupported)",platform,ps) - end - end - for encoding,subtables in sortedhash(record) do - local se=sp and sp[encoding] - local es=e and e[encoding] or "?" - if trace_cmap then - if se then - report(" encoding %i: %s",encoding,es) - else - report(" encoding %i: %s (unsupported)",encoding,es) - end - end - local offsets=subtables.offsets - local formats=subtables.formats - for i=1,#offsets do - local offset=tableoffset+offsets[i] - setposition(f,offset) - formats[readushort(f)]=offset - end - record[encoding]=formats - if trace_cmap then - local list=sortedkeys(formats) - for i=1,#list do - if not (se and se[list[i]]) then - list[i]=list[i].." (unsupported)" - end - end - report(" formats: % t",list) - end - end - end - local ok=false - for i=1,#sequence do - local si=sequence[i] - local sp,se,sf=si[1],si[2],si[3] - if checkcmap(f,fontdata,records,sp,se,sf)>0 then - ok=true - end - end - if not ok then - report("no useable unicode cmap found") - end - fontdata.cidmaps={ - version=version, - noftables=noftables, - records=records, - } - else - fontdata.cidmaps={} - end -end -function readers.loca(f,fontdata,specification) - reportskippedtable(f,fontdata,"loca",specification.glyphs) -end -function readers.glyf(f,fontdata,specification) - reportskippedtable(f,fontdata,"glyf",specification.glyphs) -end -function readers.colr(f,fontdata,specification) - reportskippedtable(f,fontdata,"colr",specification.glyphs) -end -function readers.cpal(f,fontdata,specification) - reportskippedtable(f,fontdata,"cpal",specification.glyphs) -end -function readers.svg(f,fontdata,specification) - reportskippedtable(f,fontdata,"svg",specification.glyphs) -end -function readers.sbix(f,fontdata,specification) - reportskippedtable(f,fontdata,"sbix",specification.glyphs) -end -function readers.cbdt(f,fontdata,specification) - reportskippedtable(f,fontdata,"cbdt",specification.glyphs) -end -function readers.cblc(f,fontdata,specification) - reportskippedtable(f,fontdata,"cblc",specification.glyphs) -end -function readers.ebdt(f,fontdata,specification) - reportskippedtable(f,fontdata,"ebdt",specification.glyphs) -end -function readers.ebsc(f,fontdata,specification) - reportskippedtable(f,fontdata,"ebsc",specification.glyphs) -end -function readers.eblc(f,fontdata,specification) - reportskippedtable(f,fontdata,"eblc",specification.glyphs) -end -function readers.kern(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"kern",specification.kerns) - if tableoffset then - local version=readushort(f) - local noftables=readushort(f) - for i=1,noftables do - local version=readushort(f) - local length=readushort(f) - local coverage=readushort(f) - local format=rshift(coverage,8) - if format==0 then - local nofpairs=readushort(f) - local searchrange=readushort(f) - local entryselector=readushort(f) - local rangeshift=readushort(f) - local kerns={} - local glyphs=fontdata.glyphs - for i=1,nofpairs do - local left=readushort(f) - local right=readushort(f) - local kern=readfword(f) - local glyph=glyphs[left] - local kerns=glyph.kerns - if kerns then - kerns[right]=kern - else - glyph.kerns={ [right]=kern } - end - end - elseif format==2 then - report("todo: kern classes") - else - report("todo: kerns") - end - end - end -end -function readers.gdef(f,fontdata,specification) - reportskippedtable(f,fontdata,"gdef",specification.details) -end -function readers.gsub(f,fontdata,specification) - reportskippedtable(f,fontdata,"gsub",specification.details) -end -function readers.gpos(f,fontdata,specification) - reportskippedtable(f,fontdata,"gpos",specification.details) -end -function readers.math(f,fontdata,specification) - reportskippedtable(f,fontdata,"math",specification.details) -end -local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo,instancenames) - local fontdata=sub and maindata.subfonts and maindata.subfonts[sub] or maindata - local names=fontdata.names - local info=nil - if names then - local metrics=fontdata.windowsmetrics or {} - local postscript=fontdata.postscript or {} - local fontheader=fontdata.fontheader or {} - local cffinfo=fontdata.cffinfo or {} - local verticalheader=fontdata.verticalheader or {} - local filename=fontdata.filename - local weight=getname(fontdata,"weight") or (cffinfo and cffinfo.weight) or (metrics and metrics.weight) - local width=getname(fontdata,"width") or (cffinfo and cffinfo.width ) or (metrics and metrics.width ) - local fontname=getname(fontdata,"postscriptname") - local fullname=getname(fontdata,"fullname") - local family=getname(fontdata,"family") - local subfamily=getname(fontdata,"subfamily") - local familyname=getname(fontdata,"typographicfamily") - local subfamilyname=getname(fontdata,"typographicsubfamily") - local compatiblename=getname(fontdata,"compatiblefullname") - if rawfamilynames then - else - if not familyname then familyname=family end - if not subfamilyname then subfamilyname=subfamily end - end - if platformnames then - platformnames=fontdata.platformnames - end - if instancenames then - local variabledata=fontdata.variabledata - if variabledata then - local instances=variabledata and variabledata.instances - if instances then - instancenames={} - for i=1,#instances do - instancenames[i]=lower(stripstring(instances[i].subfamily)) - end - else - instancenames=nil - end - else - instancenames=nil - end - end - info={ - subfontindex=fontdata.subfontindex or sub or 0, - version=getname(fontdata,"version"), - fontname=fontname, - fullname=fullname, - family=family, - subfamily=subfamily, - familyname=familyname, - subfamilyname=subfamilyname, - compatiblename=compatiblename, - weight=weight and lower(weight), - width=width and lower(width), - pfmweight=metrics.weightclass or 400, - pfmwidth=metrics.widthclass or 5, - panosewidth=metrics.panosewidth, - panoseweight=metrics.panoseweight, - italicangle=postscript.italicangle or 0, - units=fontheader.units or 0, - designsize=fontdata.designsize, - minsize=fontdata.minsize, - maxsize=fontdata.maxsize, - boundingbox=fontheader and { fontheader.xmin or 0,fontheader.ymin or 0,fontheader.xmax or 0,fontheader.ymax or 0 } or nil, - monospaced=(tonumber(postscript.monospaced or 0)>0) or metrics.panosewidth=="monospaced", - averagewidth=metrics.averagewidth, - xheight=metrics.xheight, - capheight=metrics.capheight or fontdata.maxy, - ascender=metrics.typoascender, - descender=metrics.typodescender, - platformnames=platformnames or nil, - instancenames=instancenames or nil, - tableoffsets=fontdata.tableoffsets, - defaultvheight=(verticalheader.ascender or 0)-(verticalheader.descender or 0) - } - if metricstoo then - local keys={ - "version", - "ascender","descender","linegap", - "maxadvancewidth","maxadvanceheight","maxextent", - "minbottomsidebearing","mintopsidebearing", - } - local h=fontdata.horizontalheader or {} - local v=fontdata.verticalheader or {} - if h then - local th={} - local tv={} - for i=1,#keys do - local key=keys[i] - th[key]=h[key] or 0 - tv[key]=v[key] or 0 - end - info.horizontalmetrics=th - info.verticalmetrics=tv - end - end - elseif n then - info={ - filename=fontdata.filename, - comment="there is no info for subfont "..n, - } - else - info={ - filename=fontdata.filename, - comment="there is no info", - } - end - return info -end -local function loadtables(f,specification,offset) - if offset then - setposition(f,offset) - end - local tables={} - local basename=file.basename(specification.filename) - local filesize=specification.filesize - local filetime=specification.filetime - local fontdata={ - filename=basename, - filesize=filesize, - filetime=filetime, - version=readstring(f,4), - noftables=readushort(f), - searchrange=readushort(f), - entryselector=readushort(f), - rangeshift=readushort(f), - tables=tables, - foundtables=false, - } - for i=1,fontdata.noftables do - local tag=lower(stripstring(readstring(f,4))) - local checksum=readushort(f)*0x10000+readushort(f) - local offset=readulong(f) - local length=readulong(f) - if offset+length>filesize then - report("bad %a table in file %a",tag,basename) - end - tables[tag]={ - checksum=checksum, - offset=offset, - length=length, - } - end - fontdata.foundtables=sortedkeys(tables) - if tables.cff or tables.cff2 then - fontdata.format="opentype" - else - fontdata.format="truetype" - end - return fontdata,tables -end -local function prepareglyps(fontdata) - local glyphs=setmetatableindex(function(t,k) - local v={ - index=k, - } - t[k]=v - return v - end) - fontdata.glyphs=glyphs - fontdata.mapping={} -end -local function readtable(tag,f,fontdata,specification,...) - local reader=readers[tag] - if reader then - reader(f,fontdata,specification,...) - end -end -local function readdata(f,offset,specification) - local fontdata,tables=loadtables(f,specification,offset) - if specification.glyphs then - prepareglyps(fontdata) - end - fontdata.temporary={} - readtable("name",f,fontdata,specification) - local askedname=specification.askedname - if askedname then - local fullname=getname(fontdata,"fullname") or "" - local cleanname=gsub(askedname,"[^a-zA-Z0-9]","") - local foundname=gsub(fullname,"[^a-zA-Z0-9]","") - if lower(cleanname)~=lower(foundname) then - return - end - end - readtable("stat",f,fontdata,specification) - readtable("avar",f,fontdata,specification) - readtable("fvar",f,fontdata,specification) - local variabledata=fontdata.variabledata - if variabledata then - local instances=variabledata.instances - local axis=variabledata.axis - if axis and (not instances or #instances==0) then - instances={} - variabledata.instances=instances - local function add(n,subfamily,value) - local values={} - for i=1,#axis do - local a=axis[i] - values[i]={ - axis=a.tag, - value=i==n and value or a.default, - } - end - instances[#instances+1]={ - subfamily=subfamily, - values=values, - } - end - for i=1,#axis do - local a=axis[i] - local tag=a.tag - add(i,"default"..tag,a.default) - add(i,"minimum"..tag,a.minimum) - add(i,"maximum"..tag,a.maximum) - end - end - end - if not specification.factors then - local instance=specification.instance - if type(instance)=="string" then - local factors=helpers.getfactors(fontdata,instance) - if factors then - specification.factors=factors - fontdata.factors=factors - fontdata.instance=instance - report("user instance: %s, factors: % t",instance,factors) - else - report("user instance: %s, bad factors",instance) - end - end - end - if not fontdata.factors then - if fontdata.variabledata then - local factors=helpers.getfactors(fontdata,true) - if factors then - specification.factors=factors - fontdata.factors=factors - end - else - end - end - readtable("os/2",f,fontdata,specification) - readtable("head",f,fontdata,specification) - readtable("maxp",f,fontdata,specification) - readtable("hhea",f,fontdata,specification) - readtable("vhea",f,fontdata,specification) - readtable("hmtx",f,fontdata,specification) - readtable("vmtx",f,fontdata,specification) - readtable("vorg",f,fontdata,specification) - readtable("post",f,fontdata,specification) - readtable("mvar",f,fontdata,specification) - readtable("hvar",f,fontdata,specification) - readtable("vvar",f,fontdata,specification) - readtable("gdef",f,fontdata,specification) - readtable("cff",f,fontdata,specification) - readtable("cff2",f,fontdata,specification) - readtable("cmap",f,fontdata,specification) - readtable("loca",f,fontdata,specification) - readtable("glyf",f,fontdata,specification) - readtable("colr",f,fontdata,specification) - readtable("cpal",f,fontdata,specification) - readtable("svg",f,fontdata,specification) - readtable("sbix",f,fontdata,specification) - readtable("cbdt",f,fontdata,specification) - readtable("cblc",f,fontdata,specification) - readtable("ebdt",f,fontdata,specification) - readtable("eblc",f,fontdata,specification) - readtable("kern",f,fontdata,specification) - readtable("gsub",f,fontdata,specification) - readtable("gpos",f,fontdata,specification) - readtable("math",f,fontdata,specification) - fontdata.locations=nil - fontdata.cidmaps=nil - fontdata.dictionaries=nil - if specification.tableoffsets then - fontdata.tableoffsets=tables - setmetatableindex(tables,{ - version=fontdata.version, - noftables=fontdata.noftables, - searchrange=fontdata.searchrange, - entryselector=fontdata.entryselector, - rangeshift=fontdata.rangeshift, - }) - end - return fontdata -end -local function loadfontdata(specification) - local filename=specification.filename - local fileattr=lfs.attributes(filename) - local filesize=fileattr and fileattr.size or 0 - local filetime=fileattr and fileattr.modification or 0 - local f=openfile(filename,true) - if not f then - report("unable to open %a",filename) - elseif filesize==0 then - report("empty file %a",filename) - closefile(f) - else - specification.filesize=filesize - specification.filetime=filetime - local version=readstring(f,4) - local fontdata=nil - if version=="OTTO" or version=="true" or version=="\0\1\0\0" then - fontdata=readdata(f,0,specification) - elseif version=="ttcf" then - local subfont=tonumber(specification.subfont) - local ttcversion=readulong(f) - local nofsubfonts=readulong(f) - local offsets=readcardinaltable(f,nofsubfonts,ulong) - if subfont then - if subfont>=1 and subfont<=nofsubfonts then - fontdata=readdata(f,offsets[subfont],specification) - else - report("no subfont %a in file %a",subfont,filename) - end - else - subfont=specification.subfont - if type(subfont)=="string" and subfont~="" then - specification.askedname=subfont - for i=1,nofsubfonts do - fontdata=readdata(f,offsets[i],specification) - if fontdata then - fontdata.subfontindex=i - report("subfont named %a has index %a",subfont,i) - break - end - end - if not fontdata then - report("no subfont named %a",subfont) - end - else - local subfonts={} - fontdata={ - filename=filename, - filesize=filesize, - filetime=filetime, - version=version, - subfonts=subfonts, - ttcversion=ttcversion, - nofsubfonts=nofsubfonts, - } - for i=1,nofsubfonts do - subfonts[i]=readdata(f,offsets[i],specification) - end - end - end - else - report("unknown version %a in file %a",version,filename) - end - closefile(f) - return fontdata or {} - end -end -local function loadfont(specification,n,instance) - if type(specification)=="string" then - specification={ - filename=specification, - info=true, - details=true, - glyphs=true, - shapes=true, - kerns=true, - variable=true, - globalkerns=true, - lookups=true, - subfont=n or true, - tounicode=false, - instance=instance - } - end - if specification.shapes or specification.lookups or specification.kerns then - specification.glyphs=true - end - if specification.glyphs then - specification.details=true - end - if specification.details then - specification.info=true - end - if specification.platformnames then - specification.platformnames=true - end - if specification.instance or instance then - specification.variable=true - specification.instance=specification.instance or instance - end - local function message(str) - report("fatal error in file %a: %s\n%s",specification.filename,str,debug and debug.traceback()) - end - local ok,result=xpcall(loadfontdata,message,specification) - if ok then - return result - end -end -function readers.loadshapes(filename,n,instance,streams) - local fontdata=loadfont { - filename=filename, - shapes=true, - streams=streams, - variable=true, - subfont=n, - instance=instance, - } - if fontdata then - for k,v in next,fontdata.glyphs do - v.class=nil - v.index=nil - v.math=nil - end - local names=fontdata.names - if names then - for k,v in next,names do - names[k]=fullstrip(v.content) - end - end - end - return fontdata and { - filename=filename, - format=fontdata.format, - glyphs=fontdata.glyphs, - units=fontdata.fontheader.units, - cffinfo=fontdata.cffinfo, - fontheader=fontdata.fontheader, - horizontalheader=fontdata.horizontalheader, - verticalheader=fontdata.verticalheader, - maximumprofile=fontdata.maximumprofile, - names=fontdata.names, - postscript=fontdata.postscript, - } or { - filename=filename, - format="unknown", - glyphs={}, - units=0, - } -end -function readers.loadfont(filename,n,instance) - local fontdata=loadfont { - filename=filename, - glyphs=true, - shapes=false, - lookups=true, - variable=true, - subfont=n, - instance=instance, - } - if fontdata then - return { - tableversion=tableversion, - creator="context mkiv", - size=fontdata.filesize, - time=fontdata.filetime, - glyphs=fontdata.glyphs, - descriptions=fontdata.descriptions, - format=fontdata.format, - goodies={}, - metadata=getinfo(fontdata,n,false,false,true,true), - properties={ - hasitalics=fontdata.hasitalics or false, - maxcolorclass=fontdata.maxcolorclass, - hascolor=fontdata.hascolor or false, - instance=fontdata.instance, - factors=fontdata.factors, - nofsubfonts=fontdata.subfonts and #fontdata.subfonts or nil, - }, - resources={ - filename=filename, - private=privateoffset, - duplicates=fontdata.duplicates or {}, - features=fontdata.features or {}, - sublookups=fontdata.sublookups or {}, - marks=fontdata.marks or {}, - markclasses=fontdata.markclasses or {}, - marksets=fontdata.marksets or {}, - sequences=fontdata.sequences or {}, - variants=fontdata.variants, - version=getname(fontdata,"version"), - cidinfo=fontdata.cidinfo, - mathconstants=fontdata.mathconstants, - colorpalettes=fontdata.colorpalettes, - svgshapes=fontdata.svgshapes, - pngshapes=fontdata.pngshapes, - variabledata=fontdata.variabledata, - foundtables=fontdata.foundtables, - }, - } - end -end -function readers.getinfo(filename,specification) - local subfont=nil - local platformnames=false - local rawfamilynames=false - local instancenames=true - local tableoffsets=false - if type(specification)=="table" then - subfont=tonumber(specification.subfont) - platformnames=specification.platformnames - rawfamilynames=specification.rawfamilynames - tableoffsets=specification.tableoffsets - else - subfont=tonumber(specification) - end - local fontdata=loadfont { - filename=filename, - details=true, - platformnames=platformnames, - instancenames=true, - tableoffsets=tableoffsets, - } - if fontdata then - local subfonts=fontdata.subfonts - if not subfonts then - return getinfo(fontdata,nil,platformnames,rawfamilynames,false,instancenames) - elseif not subfont then - local info={} - for i=1,#subfonts do - info[i]=getinfo(fontdata,i,platformnames,rawfamilynames,false,instancenames) - end - return info - elseif subfont>=1 and subfont<=#subfonts then - return getinfo(fontdata,subfont,platformnames,rawfamilynames,false,instancenames) - else - return { - filename=filename, - comment="there is no subfont "..subfont.." in this file" - } - end - else - return { - filename=filename, - comment="the file cannot be opened for reading", - } - end -end -function readers.rehash(fontdata,hashmethod) - report("the %a helper is not yet implemented","rehash") -end -function readers.checkhash(fontdata) - report("the %a helper is not yet implemented","checkhash") -end -function readers.pack(fontdata,hashmethod) - report("the %a helper is not yet implemented","pack") -end -function readers.unpack(fontdata) - report("the %a helper is not yet implemented","unpack") -end -function readers.expand(fontdata) - report("the %a helper is not yet implemented","unpack") -end -function readers.compact(fontdata) - report("the %a helper is not yet implemented","compact") -end -local extenders={} -function readers.registerextender(extender) - extenders[#extenders+1]=extender -end -function readers.extend(fontdata) - for i=1,#extenders do - local extender=extenders[i] - local name=extender.name or "unknown" - local action=extender.action - if action then - action(fontdata) - end - end -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otr”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oti” 309a75f9c14b77d87e94eba827dc4e71] --- - -if not modules then modules={} end modules ['font-oti']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local lower=string.lower -local fonts=fonts -local constructors=fonts.constructors -local otf=constructors.handlers.otf -local otffeatures=constructors.features.otf -local registerotffeature=otffeatures.register -local otftables=otf.tables or {} -otf.tables=otftables -local allocate=utilities.storage.allocate -registerotffeature { - name="features", - description="initialization of feature handler", - default=true, -} -local function setmode(tfmdata,value) - if value then - tfmdata.properties.mode=lower(value) - end -end -otf.modeinitializer=setmode -local function setlanguage(tfmdata,value) - if value then - local cleanvalue=lower(value) - local languages=otftables and otftables.languages - local properties=tfmdata.properties - if not languages then - properties.language=cleanvalue - elseif languages[value] then - properties.language=cleanvalue - else - properties.language="dflt" - end - end -end -local function setscript(tfmdata,value) - if value then - local cleanvalue=lower(value) - local scripts=otftables and otftables.scripts - local properties=tfmdata.properties - if not scripts then - properties.script=cleanvalue - elseif scripts[value] then - properties.script=cleanvalue - else - properties.script="dflt" - end - end -end -registerotffeature { - name="mode", - description="mode", - initializers={ - base=setmode, - node=setmode, - plug=setmode, - } -} -registerotffeature { - name="language", - description="language", - initializers={ - base=setlanguage, - node=setlanguage, - plug=setlanguage, - } -} -registerotffeature { - name="script", - description="script", - initializers={ - base=setscript, - node=setscript, - plug=setscript, - } -} -otftables.featuretypes=allocate { - gpos_single="position", - gpos_pair="position", - gpos_cursive="position", - gpos_mark2base="position", - gpos_mark2ligature="position", - gpos_mark2mark="position", - gpos_context="position", - gpos_contextchain="position", - gsub_single="substitution", - gsub_multiple="substitution", - gsub_alternate="substitution", - gsub_ligature="substitution", - gsub_context="substitution", - gsub_contextchain="substitution", - gsub_reversecontextchain="substitution", - gsub_reversesub="substitution", -} -function otffeatures.checkeddefaultscript(featuretype,autoscript,scripts) - if featuretype=="position" then - local default=scripts.dflt - if default then - if autoscript=="position" or autoscript==true then - return default - else - report_otf("script feature %s not applied, enable default positioning") - end - else - end - elseif featuretype=="substitution" then - local default=scripts.dflt - if default then - if autoscript=="substitution" or autoscript==true then - return default - end - end - end -end -function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages) - if featuretype=="position" then - local default=languages.dflt - if default then - if autolanguage=="position" or autolanguage==true then - return default - else - report_otf("language feature %s not applied, enable default positioning") - end - else - end - elseif featuretype=="substitution" then - local default=languages.dflt - if default then - if autolanguage=="substitution" or autolanguage==true then - return default - end - end - end -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oti”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ott” 673ed11e1d159997f535bfec5fa73808] --- - -if not modules then modules={} end modules ["font-ott"]={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files", -} -local type,next,tonumber,tostring,rawget,rawset=type,next,tonumber,tostring,rawget,rawset -local gsub,lower,format,match,gmatch,find=string.gsub,string.lower,string.format,string.match,string.gmatch,string.find -local sequenced=table.sequenced -local is_boolean=string.is_boolean -local setmetatableindex=table.setmetatableindex -local setmetatablenewindex=table.setmetatablenewindex -local allocate=utilities.storage.allocate -local fonts=fonts -local otf=fonts.handlers.otf -local otffeatures=otf.features -local tables=otf.tables or {} -otf.tables=tables -local statistics=otf.statistics or {} -otf.statistics=statistics -local scripts=allocate { - ["adlm"]="adlam", - ["aghb"]="caucasian albanian", - ["ahom"]="ahom", - ["arab"]="arabic", - ["armi"]="imperial aramaic", - ["armn"]="armenian", - ["avst"]="avestan", - ["bali"]="balinese", - ["bamu"]="bamum", - ["bass"]="bassa vah", - ["batk"]="batak", - ["beng"]="bengali", - ["bhks"]="bhaiksuki", - ["bng2"]="bengali variant 2", - ["bopo"]="bopomofo", - ["brah"]="brahmi", - ["brai"]="braille", - ["bugi"]="buginese", - ["buhd"]="buhid", - ["byzm"]="byzantine music", - ["cakm"]="chakma", - ["cans"]="canadian syllabics", - ["cari"]="carian", - ["cham"]="cham", - ["cher"]="cherokee", - ["copt"]="coptic", - ["cprt"]="cypriot syllabary", - ["cyrl"]="cyrillic", - ["dev2"]="devanagari variant 2", - ["deva"]="devanagari", - ["dogr"]="dogra", - ["dsrt"]="deseret", - ["dupl"]="duployan", - ["egyp"]="egyptian heiroglyphs", - ["elba"]="elbasan", - ["ethi"]="ethiopic", - ["geor"]="georgian", - ["gjr2"]="gujarati variant 2", - ["glag"]="glagolitic", - ["gong"]="gunjala gondi", - ["gonm"]="masaram gondi", - ["goth"]="gothic", - ["gran"]="grantha", - ["grek"]="greek", - ["gujr"]="gujarati", - ["gur2"]="gurmukhi variant 2", - ["guru"]="gurmukhi", - ["hang"]="hangul", - ["hani"]="cjk ideographic", - ["hano"]="hanunoo", - ["hatr"]="hatran", - ["hebr"]="hebrew", - ["hluw"]="anatolian hieroglyphs", - ["hmng"]="pahawh hmong", - ["hung"]="old hungarian", - ["ital"]="old italic", - ["jamo"]="hangul jamo", - ["java"]="javanese", - ["kali"]="kayah li", - ["kana"]="hiragana and katakana", - ["khar"]="kharosthi", - ["khmr"]="khmer", - ["khoj"]="khojki", - ["knd2"]="kannada variant 2", - ["knda"]="kannada", - ["kthi"]="kaithi", - ["lana"]="tai tham", - ["lao" ]="lao", - ["latn"]="latin", - ["lepc"]="lepcha", - ["limb"]="limbu", - ["lina"]="linear a", - ["linb"]="linear b", - ["lisu"]="lisu", - ["lyci"]="lycian", - ["lydi"]="lydian", - ["mahj"]="mahajani", - ["maka"]="makasar", - ["mand"]="mandaic and mandaean", - ["mani"]="manichaean", - ["marc"]="marchen", - ["math"]="mathematical alphanumeric symbols", - ["medf"]="medefaidrin", - ["mend"]="mende kikakui", - ["merc"]="meroitic cursive", - ["mero"]="meroitic hieroglyphs", - ["mlm2"]="malayalam variant 2", - ["mlym"]="malayalam", - ["modi"]="modi", - ["mong"]="mongolian", - ["mroo"]="mro", - ["mtei"]="meitei Mayek", - ["mult"]="multani", - ["musc"]="musical symbols", - ["mym2"]="myanmar variant 2", - ["mymr"]="myanmar", - ["narb"]="old north arabian", - ["nbat"]="nabataean", - ["newa"]="newa", - ["nko" ]='n"ko', - ["nshu"]="nüshu", - ["ogam"]="ogham", - ["olck"]="ol chiki", - ["orkh"]="old turkic and orkhon runic", - ["ory2"]="odia variant 2", - ["orya"]="oriya", - ["osge"]="osage", - ["osma"]="osmanya", - ["palm"]="palmyrene", - ["pauc"]="pau cin hau", - ["perm"]="old permic", - ["phag"]="phags-pa", - ["phli"]="inscriptional pahlavi", - ["phlp"]="psalter pahlavi", - ["phnx"]="phoenician", - ["plrd"]="miao", - ["prti"]="inscriptional parthian", - ["rjng"]="rejang", - ["rohg"]="hanifi rohingya", - ["runr"]="runic", - ["samr"]="samaritan", - ["sarb"]="old south arabian", - ["saur"]="saurashtra", - ["sgnw"]="sign writing", - ["shaw"]="shavian", - ["shrd"]="sharada", - ["sidd"]="siddham", - ["sind"]="khudawadi", - ["sinh"]="sinhala", - ["sogd"]="sogdian", - ["sogo"]="old sogdian", - ["sora"]="sora sompeng", - ["soyo"]="soyombo", - ["sund"]="sundanese", - ["sylo"]="syloti nagri", - ["syrc"]="syriac", - ["tagb"]="tagbanwa", - ["takr"]="takri", - ["tale"]="tai le", - ["talu"]="tai lu", - ["taml"]="tamil", - ["tang"]="tangut", - ["tavt"]="tai viet", - ["tel2"]="telugu variant 2", - ["telu"]="telugu", - ["tfng"]="tifinagh", - ["tglg"]="tagalog", - ["thaa"]="thaana", - ["thai"]="thai", - ["tibt"]="tibetan", - ["tirh"]="tirhuta", - ["tml2"]="tamil variant 2", - ["ugar"]="ugaritic cuneiform", - ["vai" ]="vai", - ["wara"]="warang citi", - ["xpeo"]="old persian cuneiform", - ["xsux"]="sumero-akkadian cuneiform", - ["yi" ]="yi", - ["zanb"]="zanabazar square", -} -local languages=allocate { - ["aba" ]="abaza", - ["abk" ]="abkhazian", - ["ach" ]="acholi", - ["acr" ]="achi", - ["ady" ]="adyghe", - ["afk" ]="afrikaans", - ["afr" ]="afar", - ["agw" ]="agaw", - ["aio" ]="aiton", - ["aka" ]="akan", - ["als" ]="alsatian", - ["alt" ]="altai", - ["amh" ]="amharic", - ["ang" ]="anglo-saxon", - ["apph"]="phonetic transcription—americanist conventions", - ["ara" ]="arabic", - ["arg" ]="aragonese", - ["ari" ]="aari", - ["ark" ]="rakhine", - ["asm" ]="assamese", - ["ast" ]="asturian", - ["ath" ]="athapaskan", - ["avr" ]="avar", - ["awa" ]="awadhi", - ["aym" ]="aymara", - ["azb" ]="torki", - ["aze" ]="azerbaijani", - ["bad" ]="badaga", - ["bad0"]="banda", - ["bag" ]="baghelkhandi", - ["bal" ]="balkar", - ["ban" ]="balinese", - ["bar" ]="bavarian", - ["bau" ]="baulé", - ["bbc" ]="batak toba", - ["bbr" ]="berber", - ["bch" ]="bench", - ["bcr" ]="bible cree", - ["bdy" ]="bandjalang", - ["bel" ]="belarussian", - ["bem" ]="bemba", - ["ben" ]="bengali", - ["bgc" ]="haryanvi", - ["bgq" ]="bagri", - ["bgr" ]="bulgarian", - ["bhi" ]="bhili", - ["bho" ]="bhojpuri", - ["bik" ]="bikol", - ["bil" ]="bilen", - ["bis" ]="bislama", - ["bjj" ]="kanauji", - ["bkf" ]="blackfoot", - ["bli" ]="baluchi", - ["blk" ]="pa'o karen", - ["bln" ]="balante", - ["blt" ]="balti", - ["bmb" ]="bambara (bamanankan)", - ["bml" ]="bamileke", - ["bos" ]="bosnian", - ["bpy" ]="bishnupriya manipuri", - ["bre" ]="breton", - ["brh" ]="brahui", - ["bri" ]="braj bhasha", - ["brm" ]="burmese", - ["brx" ]="bodo", - ["bsh" ]="bashkir", - ["bsk" ]="burushaski", - ["bti" ]="beti", - ["bts" ]="batak simalungun", - ["bug" ]="bugis", - ["byv" ]="medumba", - ["cak" ]="kaqchikel", - ["cat" ]="catalan", - ["cbk" ]="zamboanga chavacano", - ["cchn"]="chinantec", - ["ceb" ]="cebuano", - ["cgg" ]="chiga", - ["cha" ]="chamorro", - ["che" ]="chechen", - ["chg" ]="chaha gurage", - ["chh" ]="chattisgarhi", - ["chi" ]="chichewa (chewa, nyanja)", - ["chk" ]="chukchi", - ["chk0"]="chuukese", - ["cho" ]="choctaw", - ["chp" ]="chipewyan", - ["chr" ]="cherokee", - ["chu" ]="chuvash", - ["chy" ]="cheyenne", - ["cja" ]="western cham", - ["cjm" ]="eastern cham", - ["cmr" ]="comorian", - ["cop" ]="coptic", - ["cor" ]="cornish", - ["cos" ]="corsican", - ["cpp" ]="creoles", - ["cre" ]="cree", - ["crr" ]="carrier", - ["crt" ]="crimean tatar", - ["csb" ]="kashubian", - ["csl" ]="church slavonic", - ["csy" ]="czech", - ["ctg" ]="chittagonian", - ["cuk" ]="san blas kuna", - ["dan" ]="danish", - ["dar" ]="dargwa", - ["dax" ]="dayi", - ["dcr" ]="woods cree", - ["deu" ]="german", - ["dgo" ]="dogri", - ["dgr" ]="dogri", - ["dhg" ]="dhangu", - ["dhv" ]="divehi (dhivehi, maldivian)", - ["diq" ]="dimli", - ["div" ]="divehi (dhivehi, maldivian)", - ["djr" ]="zarma", - ["djr0"]="djambarrpuyngu", - ["dng" ]="dangme", - ["dnj" ]="dan", - ["dnk" ]="dinka", - ["dri" ]="dari", - ["duj" ]="dhuwal", - ["dun" ]="dungan", - ["dzn" ]="dzongkha", - ["ebi" ]="ebira", - ["ecr" ]="eastern cree", - ["edo" ]="edo", - ["efi" ]="efik", - ["ell" ]="greek", - ["emk" ]="eastern maninkakan", - ["eng" ]="english", - ["erz" ]="erzya", - ["esp" ]="spanish", - ["esu" ]="central yupik", - ["eti" ]="estonian", - ["euq" ]="basque", - ["evk" ]="evenki", - ["evn" ]="even", - ["ewe" ]="ewe", - ["fan" ]="french antillean", - ["fan0"]=" fang", - ["far" ]="persian", - ["fat" ]="fanti", - ["fin" ]="finnish", - ["fji" ]="fijian", - ["fle" ]="dutch (flemish)", - ["fmp" ]="fe’fe’", - ["fne" ]="forest nenets", - ["fon" ]="fon", - ["fos" ]="faroese", - ["fra" ]="french", - ["frc" ]="cajun french", - ["fri" ]="frisian", - ["frl" ]="friulian", - ["frp" ]="arpitan", - ["fta" ]="futa", - ["ful" ]="fulah", - ["fuv" ]="nigerian fulfulde", - ["gad" ]="ga", - ["gae" ]="scottish gaelic (gaelic)", - ["gag" ]="gagauz", - ["gal" ]="galician", - ["gar" ]="garshuni", - ["gaw" ]="garhwali", - ["gez" ]="ge'ez", - ["gih" ]="githabul", - ["gil" ]="gilyak", - ["gil0"]="kiribati (gilbertese)", - ["gkp" ]="kpelle (guinea)", - ["glk" ]="gilaki", - ["gmz" ]="gumuz", - ["gnn" ]="gumatj", - ["gog" ]="gogo", - ["gon" ]="gondi", - ["grn" ]="greenlandic", - ["gro" ]="garo", - ["gua" ]="guarani", - ["guc" ]="wayuu", - ["guf" ]="gupapuyngu", - ["guj" ]="gujarati", - ["guz" ]="gusii", - ["hai" ]="haitian (haitian creole)", - ["hal" ]="halam", - ["har" ]="harauti", - ["hau" ]="hausa", - ["haw" ]="hawaiian", - ["hay" ]="haya", - ["haz" ]="hazaragi", - ["hbn" ]="hammer-banna", - ["her" ]="herero", - ["hil" ]="hiligaynon", - ["hin" ]="hindi", - ["hma" ]="high mari", - ["hmn" ]="hmong", - ["hmo" ]="hiri motu", - ["hnd" ]="hindko", - ["ho" ]="ho", - ["hri" ]="harari", - ["hrv" ]="croatian", - ["hun" ]="hungarian", - ["hye" ]="armenian", - ["hye0"]="armenian east", - ["iba" ]="iban", - ["ibb" ]="ibibio", - ["ibo" ]="igbo", - ["ido" ]="ido", - ["ijo" ]="ijo languages", - ["ile" ]="interlingue", - ["ilo" ]="ilokano", - ["ina" ]="interlingua", - ["ind" ]="indonesian", - ["ing" ]="ingush", - ["inu" ]="inuktitut", - ["ipk" ]="inupiat", - ["ipph"]="phonetic transcription—ipa conventions", - ["iri" ]="irish", - ["irt" ]="irish traditional", - ["isl" ]="icelandic", - ["ism" ]="inari sami", - ["ita" ]="italian", - ["iwr" ]="hebrew", - ["jam" ]="jamaican creole", - ["jan" ]="japanese", - ["jav" ]="javanese", - ["jbo" ]="lojban", - ["jct" ]="krymchak", - ["jii" ]="yiddish", - ["jud" ]="ladino", - ["jul" ]="jula", - ["kab" ]="kabardian", - ["kab0"]="kabyle", - ["kac" ]="kachchi", - ["kal" ]="kalenjin", - ["kan" ]="kannada", - ["kar" ]="karachay", - ["kat" ]="georgian", - ["kaz" ]="kazakh", - ["kde" ]="makonde", - ["kea" ]="kabuverdianu (crioulo)", - ["keb" ]="kebena", - ["kek" ]="kekchi", - ["kge" ]="khutsuri georgian", - ["kha" ]="khakass", - ["khk" ]="khanty-kazim", - ["khm" ]="khmer", - ["khs" ]="khanty-shurishkar", - ["kht" ]="khamti shan", - ["khv" ]="khanty-vakhi", - ["khw" ]="khowar", - ["kik" ]="kikuyu (gikuyu)", - ["kir" ]="kirghiz (kyrgyz)", - ["kis" ]="kisii", - ["kiu" ]="kirmanjki", - ["kjd" ]="southern kiwai", - ["kjp" ]="eastern pwo karen", - ["kjz" ]="bumthangkha", - ["kkn" ]="kokni", - ["klm" ]="kalmyk", - ["kmb" ]="kamba", - ["kmn" ]="kumaoni", - ["kmo" ]="komo", - ["kms" ]="komso", - ["kmz" ]="khorasani turkic", - ["knr" ]="kanuri", - ["kod" ]="kodagu", - ["koh" ]="korean old hangul", - ["kok" ]="konkani", - ["kom" ]="komi", - ["kon" ]="kikongo", - ["kon0"]="kongo", - ["kop" ]="komi-permyak", - ["kor" ]="korean", - ["kos" ]="kosraean", - ["koz" ]="komi-zyrian", - ["kpl" ]="kpelle", - ["kri" ]="krio", - ["krk" ]="karakalpak", - ["krl" ]="karelian", - ["krm" ]="karaim", - ["krn" ]="karen", - ["krt" ]="koorete", - ["ksh" ]="kashmiri", - ["ksh0"]="ripuarian", - ["ksi" ]="khasi", - ["ksm" ]="kildin sami", - ["ksw" ]="s’gaw karen", - ["kua" ]="kuanyama", - ["kui" ]="kui", - ["kul" ]="kulvi", - ["kum" ]="kumyk", - ["kur" ]="kurdish", - ["kuu" ]="kurukh", - ["kuy" ]="kuy", - ["kyk" ]="koryak", - ["kyu" ]="western kayah", - ["lad" ]="ladin", - ["lah" ]="lahuli", - ["lak" ]="lak", - ["lam" ]="lambani", - ["lao" ]="lao", - ["lat" ]="latin", - ["laz" ]="laz", - ["lcr" ]="l-cree", - ["ldk" ]="ladakhi", - ["lez" ]="lezgi", - ["lij" ]="ligurian", - ["lim" ]="limburgish", - ["lin" ]="lingala", - ["lis" ]="lisu", - ["ljp" ]="lampung", - ["lki" ]="laki", - ["lma" ]="low mari", - ["lmb" ]="limbu", - ["lmo" ]="lombard", - ["lmw" ]="lomwe", - ["lom" ]="loma", - ["lrc" ]="luri", - ["lsb" ]="lower sorbian", - ["lsm" ]="lule sami", - ["lth" ]="lithuanian", - ["ltz" ]="luxembourgish", - ["lua" ]="luba-lulua", - ["lub" ]="luba-katanga", - ["lug" ]="ganda", - ["luh" ]="luyia", - ["luo" ]="luo", - ["lvi" ]="latvian", - ["mad" ]="madura", - ["mag" ]="magahi", - ["mah" ]="marshallese", - ["maj" ]="majang", - ["mak" ]="makhuwa", - ["mal" ]="malayalam reformed", - ["mam" ]="mam", - ["man" ]="mansi", - ["map" ]="mapudungun", - ["mar" ]="marathi", - ["maw" ]="marwari", - ["mbn" ]="mbundu", - ["mbo" ]="mbo", - ["mch" ]="manchu", - ["mcr" ]="moose cree", - ["mde" ]="mende", - ["mdr" ]="mandar", - ["men" ]="me'en", - ["mer" ]="meru", - ["mfa" ]="pattani malay", - ["mfe" ]="morisyen", - ["min" ]="minangkabau", - ["miz" ]="mizo", - ["mkd" ]="macedonian", - ["mkr" ]="makasar", - ["mkw" ]="kituba", - ["mle" ]="male", - ["mlg" ]="malagasy", - ["mln" ]="malinke", - ["mlr" ]="malayalam reformed", - ["mly" ]="malay", - ["mnd" ]="mandinka", - ["mng" ]="mongolian", - ["mni" ]="manipuri", - ["mnk" ]="maninka", - ["mnx" ]="manx", - ["moh" ]="mohawk", - ["mok" ]="moksha", - ["mol" ]="moldavian", - ["mon" ]="mon", - ["mor" ]="moroccan", - ["mos" ]="mossi", - ["mri" ]="maori", - ["mth" ]="maithili", - ["mts" ]="maltese", - ["mun" ]="mundari", - ["mus" ]="muscogee", - ["mwl" ]="mirandese", - ["mww" ]="hmong daw", - ["myn" ]="mayan", - ["mzn" ]="mazanderani", - ["nag" ]="naga-assamese", - ["nah" ]="nahuatl", - ["nan" ]="nanai", - ["nap" ]="neapolitan", - ["nas" ]="naskapi", - ["nau" ]="nauruan", - ["nav" ]="navajo", - ["ncr" ]="n-cree", - ["ndb" ]="ndebele", - ["ndc" ]="ndau", - ["ndg" ]="ndonga", - ["nds" ]="low saxon", - ["nep" ]="nepali", - ["new" ]="newari", - ["nga" ]="ngbaka", - ["ngr" ]="nagari", - ["nhc" ]="norway house cree", - ["nis" ]="nisi", - ["niu" ]="niuean", - ["nkl" ]="nyankole", - ["nko" ]="n'ko", - ["nld" ]="dutch", - ["noe" ]="nimadi", - ["nog" ]="nogai", - ["nor" ]="norwegian", - ["nov" ]="novial", - ["nsm" ]="northern sami", - ["nso" ]="sotho, northern", - ["nta" ]="northern tai", - ["nto" ]="esperanto", - ["nym" ]="nyamwezi", - ["nyn" ]="norwegian nynorsk", - ["nza" ]="mbembe tigon", - ["oci" ]="occitan", - ["ocr" ]="oji-cree", - ["ojb" ]="ojibway", - ["ori" ]="odia", - ["oro" ]="oromo", - ["oss" ]="ossetian", - ["paa" ]="palestinian aramaic", - ["pag" ]="pangasinan", - ["pal" ]="pali", - ["pam" ]="pampangan", - ["pan" ]="punjabi", - ["pap" ]="palpa", - ["pap0"]="papiamentu", - ["pas" ]="pashto", - ["pau" ]="palauan", - ["pcc" ]="bouyei", - ["pcd" ]="picard", - ["pdc" ]="pennsylvania german", - ["pgr" ]="polytonic greek", - ["phk" ]="phake", - ["pih" ]="norfolk", - ["pil" ]="filipino", - ["plg" ]="palaung", - ["plk" ]="polish", - ["pms" ]="piemontese", - ["pnb" ]="western panjabi", - ["poh" ]="pocomchi", - ["pon" ]="pohnpeian", - ["pro" ]="provencal", - ["ptg" ]="portuguese", - ["pwo" ]="western pwo karen", - ["qin" ]="chin", - ["quc" ]="k’iche’", - ["quh" ]="quechua (bolivia)", - ["quz" ]="quechua", - ["qvi" ]="quechua (ecuador)", - ["qwh" ]="quechua (peru)", - ["raj" ]="rajasthani", - ["rar" ]="rarotongan", - ["rbu" ]="russian buriat", - ["rcr" ]="r-cree", - ["rej" ]="rejang", - ["ria" ]="riang", - ["rif" ]="tarifit", - ["rit" ]="ritarungo", - ["rkw" ]="arakwal", - ["rms" ]="romansh", - ["rmy" ]="vlax romani", - ["rom" ]="romanian", - ["roy" ]="romany", - ["rsy" ]="rusyn", - ["rtm" ]="rotuman", - ["rua" ]="kinyarwanda", - ["run" ]="rundi", - ["rup" ]="aromanian", - ["rus" ]="russian", - ["sad" ]="sadri", - ["san" ]="sanskrit", - ["sas" ]="sasak", - ["sat" ]="santali", - ["say" ]="sayisi", - ["scn" ]="sicilian", - ["sco" ]="scots", - ["scs" ]="north slavey", - ["sek" ]="sekota", - ["sel" ]="selkup", - ["sga" ]="old irish", - ["sgo" ]="sango", - ["sgs" ]="samogitian", - ["shi" ]="tachelhit", - ["shn" ]="shan", - ["sib" ]="sibe", - ["sid" ]="sidamo", - ["sig" ]="silte gurage", - ["sks" ]="skolt sami", - ["sky" ]="slovak", - ["sla" ]="slavey", - ["slv" ]="slovenian", - ["sml" ]="somali", - ["smo" ]="samoan", - ["sna" ]="sena", - ["sna0"]="shona", - ["snd" ]="sindhi", - ["snh" ]="sinhala (sinhalese)", - ["snk" ]="soninke", - ["sog" ]="sodo gurage", - ["sop" ]="songe", - ["sot" ]="sotho, southern", - ["sqi" ]="albanian", - ["srb" ]="serbian", - ["srd" ]="sardinian", - ["srk" ]="saraiki", - ["srr" ]="serer", - ["ssl" ]="south slavey", - ["ssm" ]="southern sami", - ["stq" ]="saterland frisian", - ["suk" ]="sukuma", - ["sun" ]="sundanese", - ["sur" ]="suri", - ["sva" ]="svan", - ["sve" ]="swedish", - ["swa" ]="swadaya aramaic", - ["swk" ]="swahili", - ["swz" ]="swati", - ["sxt" ]="sutu", - ["sxu" ]="upper saxon", - ["syl" ]="sylheti", - ["syr" ]="syriac", - ["syre"]="estrangela syriac", - ["syrj"]="western syriac", - ["syrn"]="eastern syriac", - ["szl" ]="silesian", - ["tab" ]="tabasaran", - ["taj" ]="tajiki", - ["tam" ]="tamil", - ["tat" ]="tatar", - ["tcr" ]="th-cree", - ["tdd" ]="dehong dai", - ["tel" ]="telugu", - ["tet" ]="tetum", - ["tgl" ]="tagalog", - ["tgn" ]="tongan", - ["tgr" ]="tigre", - ["tgy" ]="tigrinya", - ["tha" ]="thai", - ["tht" ]="tahitian", - ["tib" ]="tibetan", - ["tiv" ]="tiv", - ["tkm" ]="turkmen", - ["tmh" ]="tamashek", - ["tmn" ]="temne", - ["tna" ]="tswana", - ["tne" ]="tundra nenets", - ["tng" ]="tonga", - ["tod" ]="todo", - ["tod0"]="toma", - ["tpi" ]="tok pisin", - ["trk" ]="turkish", - ["tsg" ]="tsonga", - ["tsj" ]="tshangla", - ["tua" ]="turoyo aramaic", - ["tul" ]="tulu", - ["tum" ]="tulu", - ["tuv" ]="tuvin", - ["tvl" ]="tuvalu", - ["twi" ]="twi", - ["tyz" ]="tày", - ["tzm" ]="tamazight", - ["tzo" ]="tzotzil", - ["udm" ]="udmurt", - ["ukr" ]="ukrainian", - ["umb" ]="umbundu", - ["urd" ]="urdu", - ["usb" ]="upper sorbian", - ["uyg" ]="uyghur", - ["uzb" ]="uzbek", - ["vec" ]="venetian", - ["ven" ]="venda", - ["vit" ]="vietnamese", - ["vol" ]="volapük", - ["vro" ]="võro", - ["wa" ]="wa", - ["wag" ]="wagdi", - ["war" ]="waray-waray", - ["wcr" ]="west-cree", - ["wel" ]="welsh", - ["wlf" ]="wolof", - ["wln" ]="walloon", - ["wtm" ]="mewati", - ["xbd" ]="lü", - ["xhs" ]="xhosa", - ["xjb" ]="minjangbal", - ["xkf" ]="khengkha", - ["xog" ]="soga", - ["xpe" ]="kpelle (liberia)", - ["yak" ]="sakha", - ["yao" ]="yao", - ["yap" ]="yapese", - ["yba" ]="yoruba", - ["ycr" ]="y-cree", - ["yic" ]="yi classic", - ["yim" ]="yi modern", - ["zea" ]="zealandic", - ["zgh" ]="standard morrocan tamazigh", - ["zha" ]="zhuang", - ["zhh" ]="chinese, hong kong sar", - ["zhp" ]="chinese phonetic", - ["zhs" ]="chinese simplified", - ["zht" ]="chinese traditional", - ["znd" ]="zande", - ["zul" ]="zulu", - ["zza" ]="zazaki", -} -local features=allocate { - ["aalt"]="access all alternates", - ["abvf"]="above-base forms", - ["abvm"]="above-base mark positioning", - ["abvs"]="above-base substitutions", - ["afrc"]="alternative fractions", - ["akhn"]="akhands", - ["blwf"]="below-base forms", - ["blwm"]="below-base mark positioning", - ["blws"]="below-base substitutions", - ["c2pc"]="petite capitals from capitals", - ["c2sc"]="small capitals from capitals", - ["calt"]="contextual alternates", - ["case"]="case-sensitive forms", - ["ccmp"]="glyph composition/decomposition", - ["cfar"]="conjunct form after ro", - ["cjct"]="conjunct forms", - ["clig"]="contextual ligatures", - ["cpct"]="centered cjk punctuation", - ["cpsp"]="capital spacing", - ["cswh"]="contextual swash", - ["curs"]="cursive positioning", - ["dflt"]="default processing", - ["dist"]="distances", - ["dlig"]="discretionary ligatures", - ["dnom"]="denominators", - ["dtls"]="dotless forms", - ["expt"]="expert forms", - ["falt"]="final glyph alternates", - ["fin2"]="terminal forms #2", - ["fin3"]="terminal forms #3", - ["fina"]="terminal forms", - ["flac"]="flattened accents over capitals", - ["frac"]="fractions", - ["fwid"]="full width", - ["half"]="half forms", - ["haln"]="halant forms", - ["halt"]="alternate half width", - ["hist"]="historical forms", - ["hkna"]="horizontal kana alternates", - ["hlig"]="historical ligatures", - ["hngl"]="hangul", - ["hojo"]="hojo kanji forms", - ["hwid"]="half width", - ["init"]="initial forms", - ["isol"]="isolated forms", - ["ital"]="italics", - ["jalt"]="justification alternatives", - ["jp04"]="jis2004 forms", - ["jp78"]="jis78 forms", - ["jp83"]="jis83 forms", - ["jp90"]="jis90 forms", - ["kern"]="kerning", - ["lfbd"]="left bounds", - ["liga"]="standard ligatures", - ["ljmo"]="leading jamo forms", - ["lnum"]="lining figures", - ["locl"]="localized forms", - ["ltra"]="left-to-right alternates", - ["ltrm"]="left-to-right mirrored forms", - ["mark"]="mark positioning", - ["med2"]="medial forms #2", - ["medi"]="medial forms", - ["mgrk"]="mathematical greek", - ["mkmk"]="mark to mark positioning", - ["mset"]="mark positioning via substitution", - ["nalt"]="alternate annotation forms", - ["nlck"]="nlc kanji forms", - ["nukt"]="nukta forms", - ["numr"]="numerators", - ["onum"]="old style figures", - ["opbd"]="optical bounds", - ["ordn"]="ordinals", - ["ornm"]="ornaments", - ["palt"]="proportional alternate width", - ["pcap"]="petite capitals", - ["pkna"]="proportional kana", - ["pnum"]="proportional figures", - ["pref"]="pre-base forms", - ["pres"]="pre-base substitutions", - ["pstf"]="post-base forms", - ["psts"]="post-base substitutions", - ["pwid"]="proportional widths", - ["qwid"]="quarter widths", - ["rand"]="randomize", - ["rclt"]="required contextual alternates", - ["rkrf"]="rakar forms", - ["rlig"]="required ligatures", - ["rphf"]="reph form", - ["rtbd"]="right bounds", - ["rtla"]="right-to-left alternates", - ["rtlm"]="right to left mirrored forms", - ["rvrn"]="required variation alternates", - ["ruby"]="ruby notation forms", - ["salt"]="stylistic alternates", - ["sinf"]="scientific inferiors", - ["size"]="optical size", - ["smcp"]="small capitals", - ["smpl"]="simplified forms", - ["ssty"]="script style", - ["stch"]="stretching glyph decomposition", - ["subs"]="subscript", - ["sups"]="superscript", - ["swsh"]="swash", - ["titl"]="titling", - ["tjmo"]="trailing jamo forms", - ["tnam"]="traditional name forms", - ["tnum"]="tabular figures", - ["trad"]="traditional forms", - ["twid"]="third widths", - ["unic"]="unicase", - ["valt"]="alternate vertical metrics", - ["vatu"]="vattu variants", - ["vert"]="vertical writing", - ["vhal"]="alternate vertical half metrics", - ["vjmo"]="vowel jamo forms", - ["vkna"]="vertical kana alternates", - ["vkrn"]="vertical kerning", - ["vpal"]="proportional alternate vertical metrics", - ["vrtr"]="vertical alternates for rotation", - ["vrt2"]="vertical rotation", - ["zero"]="slashed zero", - ["trep"]="traditional tex replacements", - ["tlig"]="traditional tex ligatures", - ["ss.."]="stylistic set ..", - ["cv.."]="character variant ..", - ["js.."]="justification ..", - ["dv.."]="devanagari ..", - ["ml.."]="malayalam ..", -} -local baselines=allocate { - ["hang"]="hanging baseline", - ["icfb"]="ideographic character face bottom edge baseline", - ["icft"]="ideographic character face tope edige baseline", - ["ideo"]="ideographic em-box bottom edge baseline", - ["idtp"]="ideographic em-box top edge baseline", - ["math"]="mathematical centered baseline", - ["romn"]="roman baseline" -} -tables.scripts=scripts -tables.languages=languages -tables.features=features -tables.baselines=baselines -local acceptscripts=true directives.register("otf.acceptscripts",function(v) acceptscripts=v end) -local acceptlanguages=true directives.register("otf.acceptlanguages",function(v) acceptlanguages=v end) -local report_checks=logs.reporter("fonts","checks") -if otffeatures.features then - for k,v in next,otffeatures.features do - features[k]=v - end - otffeatures.features=features -end -local function swapped(h) - local r={} - for k,v in next,h do - r[gsub(v,"[^a-z0-9]","")]=k - end - return r -end -local verbosescripts=allocate(swapped(scripts )) -local verboselanguages=allocate(swapped(languages)) -local verbosefeatures=allocate(swapped(features )) -local verbosebaselines=allocate(swapped(baselines)) -local function resolve(t,k) - if k then - k=gsub(lower(k),"[^a-z0-9]","") - local v=rawget(t,k) - if v then - return v - end - end -end -setmetatableindex(verbosescripts,resolve) -setmetatableindex(verboselanguages,resolve) -setmetatableindex(verbosefeatures,resolve) -setmetatableindex(verbosebaselines,resolve) -setmetatableindex(scripts,function(t,k) - if k then - k=lower(k) - if k=="dflt" then - return k - end - local v=rawget(t,k) - if v then - return v - end - k=gsub(k," ","") - v=rawget(t,v) - if v then - return v - elseif acceptscripts then - report_checks("registering extra script %a",k) - rawset(t,k,k) - return k - end - end - return "dflt" -end) -setmetatableindex(languages,function(t,k) - if k then - k=lower(k) - if k=="dflt" then - return k - end - local v=rawget(t,k) - if v then - return v - end - k=gsub(k," ","") - v=rawget(t,v) - if v then - return v - elseif acceptlanguages then - report_checks("registering extra language %a",k) - rawset(t,k,k) - return k - end - end - return "dflt" -end) -if setmetatablenewindex then - setmetatablenewindex(languages,"ignore") - setmetatablenewindex(scripts,"ignore") - setmetatablenewindex(baselines,"ignore") -end -local function resolve(t,k) - if k then - k=lower(k) - local v=rawget(t,k) - if v then - return v - end - k=gsub(k," ","") - local v=rawget(t,k) - if v then - return v - end - local tag,dd=match(k,"(..)(%d+)") - if tag and dd then - local v=rawget(t,tag) - if v then - return v - else - local v=rawget(t,tag.."..") - if v then - return (gsub(v,"%.%.",tonumber(dd))) - end - end - end - end - return k -end -setmetatableindex(features,resolve) -local function assign(t,k,v) - if k and v then - v=lower(v) - rawset(t,k,v) - end -end -if setmetatablenewindex then - setmetatablenewindex(features,assign) -end -local checkers={ - rand=function(v) - return v==true and "random" or v - end -} -if not storage then - return -end -local usedfeatures=statistics.usedfeatures or {} -statistics.usedfeatures=usedfeatures -table.setmetatableindex(usedfeatures,function(t,k) if k then local v={} t[k]=v return v end end) -storage.register("fonts/otf/usedfeatures",usedfeatures,"fonts.handlers.otf.statistics.usedfeatures" ) -local normalizedaxis=otf.readers.helpers.normalizedaxis or function(s) return s end -function otffeatures.normalize(features,wrap) - if features then - local h={} - for key,value in next,features do - local k=lower(key) - if k=="language" then - local v=gsub(lower(value),"[^a-z0-9]","") - h.language=rawget(verboselanguages,v) or (languages[v] and v) or "dflt" - elseif k=="script" then - local v=gsub(lower(value),"[^a-z0-9]","") - h.script=rawget(verbosescripts,v) or (scripts[v] and v) or "dflt" - elseif k=="axis" then - h[k]=normalizedaxis(value) - else - local uk=usedfeatures[key] - local uv=uk[value] - if uv then - else - uv=tonumber(value) - if uv then - elseif type(value)=="string" then - local b=is_boolean(value) - if type(b)=="nil" then - if wrap and find(value,",") then - uv="{"..lower(value).."}" - else - uv=lower(value) - end - else - uv=b - end - elseif type(value)=="table" then - uv=sequenced(t,",") - else - uv=value - end - if not rawget(features,k) then - k=rawget(verbosefeatures,k) or k - end - local c=checkers[k] - if c then - uv=c(uv) or vc - end - uk[value]=uv - end - h[k]=uv - end - end - return h - end -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ott”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-cff” 802a10ad12ac32329f540881f940e3f2] --- - -if not modules then modules={} end modules ['font-cff']={ - version=1.001, - optimize=true, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next,type,tonumber,rawget=next,type,tonumber,rawget -local byte,char,gmatch,sub=string.byte,string.char,string.gmatch,string.sub -local concat,remove,unpack=table.concat,table.remove,table.unpack -local floor,abs,round,ceil,min,max=math.floor,math.abs,math.round,math.ceil,math.min,math.max -local P,C,R,S,C,Cs,Ct=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Ct -local lpegmatch=lpeg.match -local formatters=string.formatters -local bytetable=string.bytetable -local idiv=number.idiv -local rshift,band,extract=bit32.rshift,bit32.band,bit32.extract -local readers=fonts.handlers.otf.readers -local streamreader=readers.streamreader -local readstring=streamreader.readstring -local readbyte=streamreader.readcardinal1 -local readushort=streamreader.readcardinal2 -local readuint=streamreader.readcardinal3 -local readulong=streamreader.readcardinal4 -local setposition=streamreader.setposition -local getposition=streamreader.getposition -local readbytetable=streamreader.readbytetable -directives.register("fonts.streamreader",function() - streamreader=utilities.streams - readstring=streamreader.readstring - readbyte=streamreader.readcardinal1 - readushort=streamreader.readcardinal2 - readuint=streamreader.readcardinal3 - readulong=streamreader.readcardinal4 - setposition=streamreader.setposition - getposition=streamreader.getposition - readbytetable=streamreader.readbytetable -end) -local setmetatableindex=table.setmetatableindex -local trace_charstrings=false trackers.register("fonts.cff.charstrings",function(v) trace_charstrings=v end) -local report=logs.reporter("otf reader","cff") -local parsedictionaries -local parsecharstring -local parsecharstrings -local resetcharstrings -local parseprivates -local startparsing -local stopparsing -local defaultstrings={ [0]= - ".notdef","space","exclam","quotedbl","numbersign","dollar","percent", - "ampersand","quoteright","parenleft","parenright","asterisk","plus", - "comma","hyphen","period","slash","zero","one","two","three","four", - "five","six","seven","eight","nine","colon","semicolon","less", - "equal","greater","question","at","A","B","C","D","E","F","G","H", - "I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W", - "X","Y","Z","bracketleft","backslash","bracketright","asciicircum", - "underscore","quoteleft","a","b","c","d","e","f","g","h","i","j", - "k","l","m","n","o","p","q","r","s","t","u","v","w","x","y", - "z","braceleft","bar","braceright","asciitilde","exclamdown","cent", - "sterling","fraction","yen","florin","section","currency", - "quotesingle","quotedblleft","guillemotleft","guilsinglleft", - "guilsinglright","fi","fl","endash","dagger","daggerdbl", - "periodcentered","paragraph","bullet","quotesinglbase","quotedblbase", - "quotedblright","guillemotright","ellipsis","perthousand","questiondown", - "grave","acute","circumflex","tilde","macron","breve","dotaccent", - "dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash", - "AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae", - "dotlessi","lslash","oslash","oe","germandbls","onesuperior", - "logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn", - "onequarter","divide","brokenbar","degree","thorn","threequarters", - "twosuperior","registered","minus","eth","multiply","threesuperior", - "copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring", - "Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave", - "Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute", - "Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute", - "Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron", - "aacute","acircumflex","adieresis","agrave","aring","atilde", - "ccedilla","eacute","ecircumflex","edieresis","egrave","iacute", - "icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex", - "odieresis","ograve","otilde","scaron","uacute","ucircumflex", - "udieresis","ugrave","yacute","ydieresis","zcaron","exclamsmall", - "Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall", - "Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader", - "onedotenleader","zerooldstyle","oneoldstyle","twooldstyle", - "threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle", - "sevenoldstyle","eightoldstyle","nineoldstyle","commasuperior", - "threequartersemdash","periodsuperior","questionsmall","asuperior", - "bsuperior","centsuperior","dsuperior","esuperior","isuperior", - "lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior", - "tsuperior","ff","ffi","ffl","parenleftinferior","parenrightinferior", - "Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall", - "Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall", - "Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall", - "Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall", - "Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah", - "Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall", - "Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall", - "Dotaccentsmall","Macronsmall","figuredash","hypheninferior", - "Ogoneksmall","Ringsmall","Cedillasmall","questiondownsmall","oneeighth", - "threeeighths","fiveeighths","seveneighths","onethird","twothirds", - "zerosuperior","foursuperior","fivesuperior","sixsuperior", - "sevensuperior","eightsuperior","ninesuperior","zeroinferior", - "oneinferior","twoinferior","threeinferior","fourinferior", - "fiveinferior","sixinferior","seveninferior","eightinferior", - "nineinferior","centinferior","dollarinferior","periodinferior", - "commainferior","Agravesmall","Aacutesmall","Acircumflexsmall", - "Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall", - "Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall", - "Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall", - "Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall", - "Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall", - "Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall", - "Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003", - "Black","Bold","Book","Light","Medium","Regular","Roman","Semibold", -} -local standardnames={ [0]= - false,false,false,false,false,false,false,false,false,false,false, - false,false,false,false,false,false,false,false,false,false,false, - false,false,false,false,false,false,false,false,false,false, - "space","exclam","quotedbl","numbersign","dollar","percent", - "ampersand","quoteright","parenleft","parenright","asterisk","plus", - "comma","hyphen","period","slash","zero","one","two","three","four", - "five","six","seven","eight","nine","colon","semicolon","less", - "equal","greater","question","at","A","B","C","D","E","F","G","H", - "I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W", - "X","Y","Z","bracketleft","backslash","bracketright","asciicircum", - "underscore","quoteleft","a","b","c","d","e","f","g","h","i","j", - "k","l","m","n","o","p","q","r","s","t","u","v","w","x","y", - "z","braceleft","bar","braceright","asciitilde",false,false,false, - false,false,false,false,false,false,false,false,false,false,false, - false,false,false,false,false,false,false,false,false,false,false, - false,false,false,false,false,false,false,false,false,"exclamdown", - "cent","sterling","fraction","yen","florin","section","currency", - "quotesingle","quotedblleft","guillemotleft","guilsinglleft", - "guilsinglright","fi","fl",false,"endash","dagger","daggerdbl", - "periodcentered",false,"paragraph","bullet","quotesinglbase", - "quotedblbase","quotedblright","guillemotright","ellipsis","perthousand", - false,"questiondown",false,"grave","acute","circumflex","tilde", - "macron","breve","dotaccent","dieresis",false,"ring","cedilla",false, - "hungarumlaut","ogonek","caron","emdash",false,false,false,false, - false,false,false,false,false,false,false,false,false,false,false, - false,"AE",false,"ordfeminine",false,false,false,false,"Lslash", - "Oslash","OE","ordmasculine",false,false,false,false,false,"ae", - false,false,false,"dotlessi",false,false,"lslash","oslash","oe", - "germandbls",false,false,false,false -} -local cffreaders={ - readbyte, - readushort, - readuint, - readulong, -} -directives.register("fonts.streamreader",function() - cffreaders={ - readbyte, - readushort, - readuint, - readulong, - } -end) -local function readheader(f) - local offset=getposition(f) - local major=readbyte(f) - local header={ - offset=offset, - major=major, - minor=readbyte(f), - size=readbyte(f), - } - if major==1 then - header.dsize=readbyte(f) - elseif major==2 then - header.dsize=readushort(f) - else - end - setposition(f,offset+header.size) - return header -end -local function readlengths(f,longcount) - local count=longcount and readulong(f) or readushort(f) - if count==0 then - return {} - end - local osize=readbyte(f) - local read=cffreaders[osize] - if not read then - report("bad offset size: %i",osize) - return {} - end - local lengths={} - local previous=read(f) - for i=1,count do - local offset=read(f) - local length=offset-previous - if length<0 then - report("bad offset: %i",length) - length=0 - end - lengths[i]=length - previous=offset - end - return lengths -end -local function readfontnames(f) - local names=readlengths(f) - for i=1,#names do - names[i]=readstring(f,names[i]) - end - return names -end -local function readtopdictionaries(f) - local dictionaries=readlengths(f) - for i=1,#dictionaries do - dictionaries[i]=readstring(f,dictionaries[i]) - end - return dictionaries -end -local function readstrings(f) - local lengths=readlengths(f) - local strings=setmetatableindex({},defaultstrings) - local index=#defaultstrings - for i=1,#lengths do - index=index+1 - strings[index]=readstring(f,lengths[i]) - end - return strings -end -do - local stack={} - local top=0 - local result={} - local strings={} - local p_single=P("\00")/function() - result.version=strings[stack[top]] or "unset" - top=0 - end+P("\01")/function() - result.notice=strings[stack[top]] or "unset" - top=0 - end+P("\02")/function() - result.fullname=strings[stack[top]] or "unset" - top=0 - end+P("\03")/function() - result.familyname=strings[stack[top]] or "unset" - top=0 - end+P("\04")/function() - result.weight=strings[stack[top]] or "unset" - top=0 - end+P("\05")/function() - result.fontbbox={ unpack(stack,1,4) } - top=0 - end+P("\06")/function() - result.bluevalues={ unpack(stack,1,top) } - top=0 - end+P("\07")/function() - result.otherblues={ unpack(stack,1,top) } - top=0 - end+P("\08")/function() - result.familyblues={ unpack(stack,1,top) } - top=0 - end+P("\09")/function() - result.familyotherblues={ unpack(stack,1,top) } - top=0 - end+P("\10")/function() - result.strhw=stack[top] - top=0 - end+P("\11")/function() - result.strvw=stack[top] - top=0 - end+P("\13")/function() - result.uniqueid=stack[top] - top=0 - end+P("\14")/function() - result.xuid=concat(stack,"",1,top) - top=0 - end+P("\15")/function() - result.charset=stack[top] - top=0 - end+P("\16")/function() - result.encoding=stack[top] - top=0 - end+P("\17")/function() - result.charstrings=stack[top] - top=0 - end+P("\18")/function() - result.private={ - size=stack[top-1], - offset=stack[top], - } - top=0 - end+P("\19")/function() - result.subroutines=stack[top] - top=0 - end+P("\20")/function() - result.defaultwidthx=stack[top] - top=0 - end+P("\21")/function() - result.nominalwidthx=stack[top] - top=0 - end -+P("\24")/function() - result.vstore=stack[top] - top=0 - end+P("\25")/function() - result.maxstack=stack[top] - top=0 - end - local p_double=P("\12")*( - P("\00")/function() - result.copyright=stack[top] - top=0 - end+P("\01")/function() - result.monospaced=stack[top]==1 and true or false - top=0 - end+P("\02")/function() - result.italicangle=stack[top] - top=0 - end+P("\03")/function() - result.underlineposition=stack[top] - top=0 - end+P("\04")/function() - result.underlinethickness=stack[top] - top=0 - end+P("\05")/function() - result.painttype=stack[top] - top=0 - end+P("\06")/function() - result.charstringtype=stack[top] - top=0 - end+P("\07")/function() - result.fontmatrix={ unpack(stack,1,6) } - top=0 - end+P("\08")/function() - result.strokewidth=stack[top] - top=0 - end+P("\09")/function() - result.bluescale=stack[top] - top=0 - end+P("\10")/function() - result.bluesnap=stack[top] - top=0 - end+P("\11")/function() - result.bluefuzz=stack[top] - top=0 - end+P("\12")/function() - result.stemsnaph={ unpack(stack,1,top) } - top=0 - end+P("\13")/function() - result.stemsnapv={ unpack(stack,1,top) } - top=0 - end+P("\20")/function() - result.syntheticbase=stack[top] - top=0 - end+P("\21")/function() - result.postscript=strings[stack[top]] or "unset" - top=0 - end+P("\22")/function() - result.basefontname=strings[stack[top]] or "unset" - top=0 - end+P("\21")/function() - result.basefontblend=stack[top] - top=0 - end+P("\30")/function() - result.cid.registry=strings[stack[top-2]] or "unset" - result.cid.ordering=strings[stack[top-1]] or "unset" - result.cid.supplement=stack[top] - top=0 - end+P("\31")/function() - result.cid.fontversion=stack[top] - top=0 - end+P("\32")/function() - result.cid.fontrevision=stack[top] - top=0 - end+P("\33")/function() - result.cid.fonttype=stack[top] - top=0 - end+P("\34")/function() - result.cid.count=stack[top] - top=0 - end+P("\35")/function() - result.cid.uidbase=stack[top] - top=0 - end+P("\36")/function() - result.cid.fdarray=stack[top] - top=0 - end+P("\37")/function() - result.cid.fdselect=stack[top] - top=0 - end+P("\38")/function() - result.cid.fontname=strings[stack[top]] or "unset" - top=0 - end - ) - local remap={ - ["\x00"]="00",["\x01"]="01",["\x02"]="02",["\x03"]="03",["\x04"]="04",["\x05"]="05",["\x06"]="06",["\x07"]="07",["\x08"]="08",["\x09"]="09",["\x0A"]="0.",["\x0B"]="0E",["\x0C"]="0E-",["\x0D"]="0",["\x0E"]="0-",["\x0F"]="0", - ["\x10"]="10",["\x11"]="11",["\x12"]="12",["\x13"]="13",["\x14"]="14",["\x15"]="15",["\x16"]="16",["\x17"]="17",["\x18"]="18",["\x19"]="19",["\x1A"]="1.",["\x1B"]="1E",["\x1C"]="1E-",["\x1D"]="1",["\x1E"]="1-",["\x1F"]="1", - ["\x20"]="20",["\x21"]="21",["\x22"]="22",["\x23"]="23",["\x24"]="24",["\x25"]="25",["\x26"]="26",["\x27"]="27",["\x28"]="28",["\x29"]="29",["\x2A"]="2.",["\x2B"]="2E",["\x2C"]="2E-",["\x2D"]="2",["\x2E"]="2-",["\x2F"]="2", - ["\x30"]="30",["\x31"]="31",["\x32"]="32",["\x33"]="33",["\x34"]="34",["\x35"]="35",["\x36"]="36",["\x37"]="37",["\x38"]="38",["\x39"]="39",["\x3A"]="3.",["\x3B"]="3E",["\x3C"]="3E-",["\x3D"]="3",["\x3E"]="3-",["\x3F"]="3", - ["\x40"]="40",["\x41"]="41",["\x42"]="42",["\x43"]="43",["\x44"]="44",["\x45"]="45",["\x46"]="46",["\x47"]="47",["\x48"]="48",["\x49"]="49",["\x4A"]="4.",["\x4B"]="4E",["\x4C"]="4E-",["\x4D"]="4",["\x4E"]="4-",["\x4F"]="4", - ["\x50"]="50",["\x51"]="51",["\x52"]="52",["\x53"]="53",["\x54"]="54",["\x55"]="55",["\x56"]="56",["\x57"]="57",["\x58"]="58",["\x59"]="59",["\x5A"]="5.",["\x5B"]="5E",["\x5C"]="5E-",["\x5D"]="5",["\x5E"]="5-",["\x5F"]="5", - ["\x60"]="60",["\x61"]="61",["\x62"]="62",["\x63"]="63",["\x64"]="64",["\x65"]="65",["\x66"]="66",["\x67"]="67",["\x68"]="68",["\x69"]="69",["\x6A"]="6.",["\x6B"]="6E",["\x6C"]="6E-",["\x6D"]="6",["\x6E"]="6-",["\x6F"]="6", - ["\x70"]="70",["\x71"]="71",["\x72"]="72",["\x73"]="73",["\x74"]="74",["\x75"]="75",["\x76"]="76",["\x77"]="77",["\x78"]="78",["\x79"]="79",["\x7A"]="7.",["\x7B"]="7E",["\x7C"]="7E-",["\x7D"]="7",["\x7E"]="7-",["\x7F"]="7", - ["\x80"]="80",["\x81"]="81",["\x82"]="82",["\x83"]="83",["\x84"]="84",["\x85"]="85",["\x86"]="86",["\x87"]="87",["\x88"]="88",["\x89"]="89",["\x8A"]="8.",["\x8B"]="8E",["\x8C"]="8E-",["\x8D"]="8",["\x8E"]="8-",["\x8F"]="8", - ["\x90"]="90",["\x91"]="91",["\x92"]="92",["\x93"]="93",["\x94"]="94",["\x95"]="95",["\x96"]="96",["\x97"]="97",["\x98"]="98",["\x99"]="99",["\x9A"]="9.",["\x9B"]="9E",["\x9C"]="9E-",["\x9D"]="9",["\x9E"]="9-",["\x9F"]="9", - ["\xA0"]=".0",["\xA1"]=".1",["\xA2"]=".2",["\xA3"]=".3",["\xA4"]=".4",["\xA5"]=".5",["\xA6"]=".6",["\xA7"]=".7",["\xA8"]=".8",["\xA9"]=".9",["\xAA"]="..",["\xAB"]=".E",["\xAC"]=".E-",["\xAD"]=".",["\xAE"]=".-",["\xAF"]=".", - ["\xB0"]="E0",["\xB1"]="E1",["\xB2"]="E2",["\xB3"]="E3",["\xB4"]="E4",["\xB5"]="E5",["\xB6"]="E6",["\xB7"]="E7",["\xB8"]="E8",["\xB9"]="E9",["\xBA"]="E.",["\xBB"]="EE",["\xBC"]="EE-",["\xBD"]="E",["\xBE"]="E-",["\xBF"]="E", - ["\xC0"]="E-0",["\xC1"]="E-1",["\xC2"]="E-2",["\xC3"]="E-3",["\xC4"]="E-4",["\xC5"]="E-5",["\xC6"]="E-6",["\xC7"]="E-7",["\xC8"]="E-8",["\xC9"]="E-9",["\xCA"]="E-.",["\xCB"]="E-E",["\xCC"]="E-E-",["\xCD"]="E-",["\xCE"]="E--",["\xCF"]="E-", - ["\xD0"]="-0",["\xD1"]="-1",["\xD2"]="-2",["\xD3"]="-3",["\xD4"]="-4",["\xD5"]="-5",["\xD6"]="-6",["\xD7"]="-7",["\xD8"]="-8",["\xD9"]="-9",["\xDA"]="-.",["\xDB"]="-E",["\xDC"]="-E-",["\xDD"]="-",["\xDE"]="--",["\xDF"]="-", - } - local p_last=S("\x0F\x1F\x2F\x3F\x4F\x5F\x6F\x7F\x8F\x9F\xAF\xBF")+R("\xF0\xFF") - local p_nibbles=P("\30")*Cs(((1-p_last)/remap)^0*(P(1)/remap))/function(n) - top=top+1 - stack[top]=tonumber(n) or 0 - end - local p_byte=C(R("\32\246"))/function(b0) - top=top+1 - stack[top]=byte(b0)-139 - end - local p_positive=C(R("\247\250"))*C(1)/function(b0,b1) - top=top+1 - stack[top]=(byte(b0)-247)*256+byte(b1)+108 - end - local p_negative=C(R("\251\254"))*C(1)/function(b0,b1) - top=top+1 - stack[top]=-(byte(b0)-251)*256-byte(b1)-108 - end - local p_short=P("\28")*C(1)*C(1)/function(b1,b2) - top=top+1 - local n=0x100*byte(b1)+byte(b2) - if n>=0x8000 then - stack[top]=n-0xFFFF-1 - else - stack[top]=n - end - end - local p_long=P("\29")*C(1)*C(1)*C(1)*C(1)/function(b1,b2,b3,b4) - top=top+1 - local n=0x1000000*byte(b1)+0x10000*byte(b2)+0x100*byte(b3)+byte(b4) - if n>=0x8000000 then - stack[top]=n-0xFFFFFFFF-1 - else - stack[top]=n - end - end - local p_unsupported=P(1)/function(detail) - top=0 - end - local p_dictionary=( - p_byte+p_positive+p_negative+p_short+p_long+p_nibbles+p_single+p_double+p_unsupported - )^1 - parsedictionaries=function(data,dictionaries,version) - stack={} - strings=data.strings - if trace_charstrings then - report("charstring format %a",version) - end - for i=1,#dictionaries do - top=0 - result=version=="cff" and { - monospaced=false, - italicangle=0, - underlineposition=-100, - underlinethickness=50, - painttype=0, - charstringtype=2, - fontmatrix={ 0.001,0,0,0.001,0,0 }, - fontbbox={ 0,0,0,0 }, - strokewidth=0, - charset=0, - encoding=0, - cid={ - fontversion=0, - fontrevision=0, - fonttype=0, - count=8720, - } - } or { - charstringtype=2, - charset=0, - vstore=0, - cid={ - }, - } - lpegmatch(p_dictionary,dictionaries[i]) - dictionaries[i]=result - end - result={} - top=0 - stack={} - end - parseprivates=function(data,dictionaries) - stack={} - strings=data.strings - for i=1,#dictionaries do - local private=dictionaries[i].private - if private and private.data then - top=0 - result={ - forcebold=false, - languagegroup=0, - expansionfactor=0.06, - initialrandomseed=0, - subroutines=0, - defaultwidthx=0, - nominalwidthx=0, - cid={ - }, - } - lpegmatch(p_dictionary,private.data) - private.data=result - end - end - result={} - top=0 - stack={} - end - local x=0 - local y=0 - local width=false - local lsb=0 - local r=0 - local stems=0 - local globalbias=0 - local localbias=0 - local nominalwidth=0 - local defaultwidth=0 - local charset=false - local globals=false - local locals=false - local depth=1 - local xmin=0 - local xmax=0 - local ymin=0 - local ymax=0 - local checked=false - local keepcurve=false - local version=2 - local regions=false - local nofregions=0 - local region=false - local factors=false - local axis=false - local vsindex=0 - local justpass=false - local seacs={} - local procidx=nil - local function showstate(where) - report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top) - end - local function showvalue(where,value,showstack) - if showstack then - report("%w%-10s : %s : [%s] n=%i",depth*2,where,tostring(value),concat(stack," ",1,top),top) - else - report("%w%-10s : %s",depth*2,where,tostring(value)) - end - end - local function xymoveto() - if keepcurve then - r=r+1 - result[r]={ x,y,"m" } - end - if checked then - if x>xmax then xmax=x elseif xymax then ymax=y elseif yxmax then - xmax=x - elseif xymax then - ymax=y - elseif yxmax then xmax=x elseif xymax then ymax=y elseif yxmax then - xmax=x - elseif xymax then - ymax=y - elseif yxmax then xmax=x1 elseif x1ymax then ymax=y1 elseif y1xmax then xmax=x2 elseif x2ymax then ymax=y2 elseif y2xmax then xmax=x3 elseif x3ymax then ymax=y3 elseif y32 then - width=stack[1] - if trace_charstrings then - showvalue("backtrack width",width) - end - else - width=true - end - end - if trace_charstrings then - showstate("rmoveto") - end - x=x+stack[top-1] - y=y+stack[top] - top=0 - xymoveto() - end - local function hmoveto() - if not width then - if top>1 then - width=stack[1] - if trace_charstrings then - showvalue("backtrack width",width) - end - else - width=true - end - end - if trace_charstrings then - showstate("hmoveto") - end - x=x+stack[top] - top=0 - xmoveto() - end - local function vmoveto() - if not width then - if top>1 then - width=stack[1] - if trace_charstrings then - showvalue("backtrack width",width) - end - else - width=true - end - end - if trace_charstrings then - showstate("vmoveto") - end - y=y+stack[top] - top=0 - ymoveto() - end - local function rlineto() - if trace_charstrings then - showstate("rlineto") - end - for i=1,top,2 do - x=x+stack[i] - y=y+stack[i+1] - xylineto() - end - top=0 - end - local function hlineto() - if trace_charstrings then - showstate("hlineto") - end - if top==1 then - x=x+stack[1] - xlineto() - else - local swap=true - for i=1,top do - if swap then - x=x+stack[i] - xlineto() - swap=false - else - y=y+stack[i] - ylineto() - swap=true - end - end - end - top=0 - end - local function vlineto() - if trace_charstrings then - showstate("vlineto") - end - if top==1 then - y=y+stack[1] - ylineto() - else - local swap=false - for i=1,top do - if swap then - x=x+stack[i] - xlineto() - swap=false - else - y=y+stack[i] - ylineto() - swap=true - end - end - end - top=0 - end - local function rrcurveto() - if trace_charstrings then - showstate("rrcurveto") - end - for i=1,top,6 do - local ax=x+stack[i] - local ay=y+stack[i+1] - local bx=ax+stack[i+2] - local by=ay+stack[i+3] - x=bx+stack[i+4] - y=by+stack[i+5] - xycurveto(ax,ay,bx,by,x,y) - end - top=0 - end - local function hhcurveto() - if trace_charstrings then - showstate("hhcurveto") - end - local s=1 - if top%2~=0 then - y=y+stack[1] - s=2 - end - for i=s,top,4 do - local ax=x+stack[i] - local ay=y - local bx=ax+stack[i+1] - local by=ay+stack[i+2] - x=bx+stack[i+3] - y=by - xycurveto(ax,ay,bx,by,x,y) - end - top=0 - end - local function vvcurveto() - if trace_charstrings then - showstate("vvcurveto") - end - local s=1 - local d=0 - if top%2~=0 then - d=stack[1] - s=2 - end - for i=s,top,4 do - local ax=x+d - local ay=y+stack[i] - local bx=ax+stack[i+1] - local by=ay+stack[i+2] - x=bx - y=by+stack[i+3] - xycurveto(ax,ay,bx,by,x,y) - d=0 - end - top=0 - end - local function xxcurveto(swap) - local last=top%4~=0 and stack[top] - if last then - top=top-1 - end - for i=1,top,4 do - local ax,ay,bx,by - if swap then - ax=x+stack[i] - ay=y - bx=ax+stack[i+1] - by=ay+stack[i+2] - y=by+stack[i+3] - if last and i+3==top then - x=bx+last - else - x=bx - end - swap=false - else - ax=x - ay=y+stack[i] - bx=ax+stack[i+1] - by=ay+stack[i+2] - x=bx+stack[i+3] - if last and i+3==top then - y=by+last - else - y=by - end - swap=true - end - xycurveto(ax,ay,bx,by,x,y) - end - top=0 - end - local function hvcurveto() - if trace_charstrings then - showstate("hvcurveto") - end - xxcurveto(true) - end - local function vhcurveto() - if trace_charstrings then - showstate("vhcurveto") - end - xxcurveto(false) - end - local function rcurveline() - if trace_charstrings then - showstate("rcurveline") - end - for i=1,top-2,6 do - local ax=x+stack[i] - local ay=y+stack[i+1] - local bx=ax+stack[i+2] - local by=ay+stack[i+3] - x=bx+stack[i+4] - y=by+stack[i+5] - xycurveto(ax,ay,bx,by,x,y) - end - x=x+stack[top-1] - y=y+stack[top] - xylineto() - top=0 - end - local function rlinecurve() - if trace_charstrings then - showstate("rlinecurve") - end - if top>6 then - for i=1,top-6,2 do - x=x+stack[i] - y=y+stack[i+1] - xylineto() - end - end - local ax=x+stack[top-5] - local ay=y+stack[top-4] - local bx=ax+stack[top-3] - local by=ay+stack[top-2] - x=bx+stack[top-1] - y=by+stack[top] - xycurveto(ax,ay,bx,by,x,y) - top=0 - end - local function flex() - if trace_charstrings then - showstate("flex") - end - local ax=x+stack[1] - local ay=y+stack[2] - local bx=ax+stack[3] - local by=ay+stack[4] - local cx=bx+stack[5] - local cy=by+stack[6] - xycurveto(ax,ay,bx,by,cx,cy) - local dx=cx+stack[7] - local dy=cy+stack[8] - local ex=dx+stack[9] - local ey=dy+stack[10] - x=ex+stack[11] - y=ey+stack[12] - xycurveto(dx,dy,ex,ey,x,y) - top=0 - end - local function hflex() - if trace_charstrings then - showstate("hflex") - end - local ax=x+stack[1] - local ay=y - local bx=ax+stack[2] - local by=ay+stack[3] - local cx=bx+stack[4] - local cy=by - xycurveto(ax,ay,bx,by,cx,cy) - local dx=cx+stack[5] - local dy=by - local ex=dx+stack[6] - local ey=y - x=ex+stack[7] - xycurveto(dx,dy,ex,ey,x,y) - top=0 - end - local function hflex1() - if trace_charstrings then - showstate("hflex1") - end - local ax=x+stack[1] - local ay=y+stack[2] - local bx=ax+stack[3] - local by=ay+stack[4] - local cx=bx+stack[5] - local cy=by - xycurveto(ax,ay,bx,by,cx,cy) - local dx=cx+stack[6] - local dy=by - local ex=dx+stack[7] - local ey=dy+stack[8] - x=ex+stack[9] - xycurveto(dx,dy,ex,ey,x,y) - top=0 - end - local function flex1() - if trace_charstrings then - showstate("flex1") - end - local ax=x+stack[1] - local ay=y+stack[2] - local bx=ax+stack[3] - local by=ay+stack[4] - local cx=bx+stack[5] - local cy=by+stack[6] - xycurveto(ax,ay,bx,by,cx,cy) - local dx=cx+stack[7] - local dy=cy+stack[8] - local ex=dx+stack[9] - local ey=dy+stack[10] - if abs(ex-x)>abs(ey-y) then - x=ex+stack[11] - else - y=ey+stack[11] - end - xycurveto(dx,dy,ex,ey,x,y) - top=0 - end - local function getstem() - if top==0 then - elseif top%2~=0 then - if width then - remove(stack,1) - else - width=remove(stack,1) - if trace_charstrings then - showvalue("width",width) - end - end - top=top-1 - end - if trace_charstrings then - showstate("stem") - end - stems=stems+idiv(top,2) - top=0 - end - local function getmask() - if top==0 then - elseif top%2~=0 then - if width then - remove(stack,1) - else - width=remove(stack,1) - if trace_charstrings then - showvalue("width",width) - end - end - top=top-1 - end - if trace_charstrings then - showstate(operator==19 and "hintmark" or "cntrmask") - end - stems=stems+idiv(top,2) - top=0 - if stems==0 then - elseif stems<=8 then - return 1 - else - return idiv(stems+7,8) - end - end - local function unsupported(t) - if trace_charstrings then - showstate("unsupported "..t) - end - top=0 - end - local function unsupportedsub(t) - if trace_charstrings then - showstate("unsupported sub "..t) - end - top=0 - end - local function getstem3() - if trace_charstrings then - showstate("stem3") - end - top=0 - end - local function divide() - if version=="cff" then - local d=stack[top] - top=top-1 - stack[top]=stack[top]/d - end - end - local function closepath() - if version=="cff" then - if trace_charstrings then - showstate("closepath") - end - end - top=0 - end - local function hsbw() - if version=="cff" then - if trace_charstrings then - showstate("hsbw") - end - lsb=stack[top-1] or 0 - width=stack[top] - end - top=0 - end - local function sbw() - if version=="cff" then - if trace_charstrings then - showstate("sbw") - end - lsb=stack[top-3] - width=stack[top-1] - end - top=0 - end - local function seac() - if version=="cff" then - if trace_charstrings then - showstate("seac") - end - end - top=0 - end - local popped=3 - local hints=3 - local function callothersubr() - if version=="cff" then - if trace_charstrings then - showstate("callothersubr") - end - if stack[top]==hints then - popped=stack[top-2] - else - popped=3 - end - local t=stack[top-1] - if t then - top=top-(t+2) - if top<0 then - top=0 - end - else - top=0 - end - else - top=0 - end - end - local function pop() - if version=="cff" then - if trace_charstrings then - showstate("pop") - end - top=top+1 - stack[top]=popped - else - top=0 - end - end - local function setcurrentpoint() - if version=="cff" then - if trace_charstrings then - showstate("setcurrentpoint (unsupported)") - end - x=x+stack[top-1] - y=y+stack[top] - end - top=0 - end - local reginit=false - local function updateregions(n) - if regions then - local current=regions[n] or regions[1] - nofregions=#current - if axis and n~=reginit then - factors={} - for i=1,nofregions do - local region=current[i] - local s=1 - for j=1,#axis do - local f=axis[j] - local r=region[j] - local start=r.start - local peak=r.peak - local stop=r.stop - if start>peak or peak>stop then - elseif start<0 and stop>0 and peak~=0 then - elseif peak==0 then - elseif fstop then - s=0 - break - elseif fpeak then - s=s*(stop-f)/(stop-peak) - else - end - end - factors[i]=s - end - end - end - reginit=n - end - local function setvsindex() - local vsindex=stack[top] - if trace_charstrings then - showstate(formatters["vsindex %i"](vsindex)) - end - updateregions(vsindex) - top=top-1 - end - local function blend() - local n=stack[top] - top=top-1 - if axis then - if trace_charstrings then - local t=top-nofregions*n - local m=t-n - for i=1,n do - local k=m+i - local d=m+n+(i-1)*nofregions - local old=stack[k] - local new=old - for r=1,nofregions do - new=new+stack[d+r]*factors[r] - end - stack[k]=new - showstate(formatters["blend %i of %i: %s -> %s"](i,n,old,new)) - end - top=t - elseif n==1 then - top=top-nofregions - local v=stack[top] - for r=1,nofregions do - v=v+stack[top+r]*factors[r] - end - stack[top]=v - else - top=top-nofregions*n - local d=top - local k=top-n - for i=1,n do - k=k+1 - local v=stack[k] - for r=1,nofregions do - v=v+stack[d+r]*factors[r] - end - stack[k]=v - d=d+nofregions - end - end - else - top=top-nofregions*n - end - end - local actions={ [0]=unsupported, - getstem, - unsupported, - getstem, - vmoveto, - rlineto, - hlineto, - vlineto, - rrcurveto, - unsupported, - unsupported, - unsupported, - unsupported, - hsbw, - unsupported, - setvsindex, - blend, - unsupported, - getstem, - getmask, - getmask, - rmoveto, - hmoveto, - getstem, - rcurveline, - rlinecurve, - vvcurveto, - hhcurveto, - unsupported, - unsupported, - vhcurveto, - hvcurveto, - } - local reverse={ [0]="unsupported", - "getstem", - "unsupported", - "getstem", - "vmoveto", - "rlineto", - "hlineto", - "vlineto", - "rrcurveto", - "unsupported", - "unsupported", - "unsupported", - "unsupported", - "hsbw", - "unsupported", - "setvsindex", - "blend", - "unsupported", - "getstem", - "getmask", - "getmask", - "rmoveto", - "hmoveto", - "getstem", - "rcurveline", - "rlinecurve", - "vvcurveto", - "hhcurveto", - "unsupported", - "unsupported", - "vhcurveto", - "hvcurveto", - } - local subactions={ - [000]=dotsection, - [001]=getstem3, - [002]=getstem3, - [006]=seac, - [007]=sbw, - [012]=divide, - [016]=callothersubr, - [017]=pop, - [033]=setcurrentpoint, - [034]=hflex, - [035]=flex, - [036]=hflex1, - [037]=flex1, - } - local chars=setmetatableindex(function (t,k) - local v=char(k) - t[k]=v - return v - end) - local c_endchar=chars[14] - local encode={} - setmetatableindex(encode,function(t,i) - for i=-2048,-1130 do - t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF)) - end - for i=-1131,-108 do - local v=0xFB00-i-108 - t[i]=char(band(rshift(v,8),0xFF),band(v,0xFF)) - end - for i=-107,107 do - t[i]=chars[i+139] - end - for i=108,1131 do - local v=0xF700+i-108 - t[i]=char(extract(v,8,8),extract(v,0,8)) - end - for i=1132,2048 do - t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF)) - end - setmetatableindex(encode,function(t,k) - local r=round(k) - local v=rawget(t,r) - if v then - return v - end - local v1=floor(k) - local v2=floor((k-v1)*0x10000) - return char(255,extract(v1,8,8),extract(v1,0,8),extract(v2,8,8),extract(v2,0,8)) - end) - return t[i] - end) - readers.cffencoder=encode - local function p_setvsindex() - local vsindex=stack[top] - updateregions(vsindex) - top=top-1 - end - local function p_blend() - local n=stack[top] - top=top-1 - if not axis then - elseif n==1 then - top=top-nofregions - local v=stack[top] - for r=1,nofregions do - v=v+stack[top+r]*factors[r] - end - stack[top]=round(v) - else - top=top-nofregions*n - local d=top - local k=top-n - for i=1,n do - k=k+1 - local v=stack[k] - for r=1,nofregions do - v=v+stack[d+r]*factors[r] - end - stack[k]=round(v) - d=d+nofregions - end - end - end - local function p_getstem() - local n=0 - if top%2~=0 then - n=1 - end - if top>n then - stems=stems+idiv(top-n,2) - end - end - local function p_getmask() - local n=0 - if top%2~=0 then - n=1 - end - if top>n then - stems=stems+idiv(top-n,2) - end - if stems==0 then - return 0 - elseif stems<=8 then - return 1 - else - return idiv(stems+7,8) - end - end - local process - local function call(scope,list,bias) - depth=depth+1 - if top==0 then - showstate(formatters["unknown %s call %s, case %s"](scope,"?",1)) - top=0 - else - local index=stack[top]+bias - top=top-1 - if trace_charstrings then - showvalue(scope,index,true) - end - local tab=list[index] - if tab then - process(tab) - else - showstate(formatters["unknown %s call %s, case %s"](scope,index,2)) - top=0 - end - end - depth=depth-1 - end - process=function(tab) - local i=1 - local n=#tab - while i<=n do - local t=tab[i] - if t>=32 then - top=top+1 - if t<=246 then - stack[top]=t-139 - i=i+1 - elseif t<=250 then - stack[top]=t*256-63124+tab[i+1] - i=i+2 - elseif t<=254 then - stack[top]=-t*256+64148-tab[i+1] - i=i+2 - else - local n=0x100*tab[i+1]+tab[i+2] - if n>=0x8000 then - stack[top]=n-0x10000+(0x100*tab[i+3]+tab[i+4])/0xFFFF - else - stack[top]=n+(0x100*tab[i+3]+tab[i+4])/0xFFFF - end - i=i+5 - end - elseif t==28 then - top=top+1 - local n=0x100*tab[i+1]+tab[i+2] - if n>=0x8000 then - stack[top]=n-0x10000 - else - stack[top]=n - end - i=i+3 - elseif t==11 then - if trace_charstrings then - showstate("return") - end - return - elseif t==10 then - call("local",locals,localbias) - i=i+1 - elseif t==14 then - if width then - elseif top>0 then - width=stack[1] - if trace_charstrings then - showvalue("width",width) - end - else - width=true - end - if trace_charstrings then - showstate("endchar") - end - return - elseif t==29 then - call("global",globals,globalbias) - i=i+1 - elseif t==12 then - i=i+1 - local t=tab[i] - if justpass then - if t>=34 and t<=37 then - for i=1,top do - r=r+1;result[r]=encode[stack[i]] - end - r=r+1;result[r]=chars[12] - r=r+1;result[r]=chars[t] - top=0 - elseif t==6 then - seacs[procidx]={ - asb=stack[1], - adx=stack[2], - ady=stack[3], - base=stack[4], - accent=stack[5], - width=width, - lsb=lsb, - } - top=0 - else - local a=subactions[t] - if a then - a(t) - else - top=0 - end - end - else - local a=subactions[t] - if a then - a(t) - else - if trace_charstrings then - showvalue("",t) - end - top=0 - end - end - i=i+1 - elseif justpass then - if t==15 then - p_setvsindex() - i=i+1 - elseif t==16 then - local s=p_blend() or 0 - i=i+s+1 - elseif t==1 or t==3 or t==18 or operation==23 then - p_getstem() - if true then - if top>0 then - for i=1,top do - r=r+1;result[r]=encode[stack[i]] - end - top=0 - end - r=r+1;result[r]=chars[t] - else - top=0 - end - i=i+1 - elseif t==19 or t==20 then - local s=p_getmask() or 0 - if true then - if top>0 then - for i=1,top do - r=r+1;result[r]=encode[stack[i]] - end - top=0 - end - r=r+1;result[r]=chars[t] - for j=1,s do - i=i+1 - r=r+1;result[r]=chars[tab[i]] - end - else - i=i+s - top=0 - end - i=i+1 - elseif t==9 then - top=0 - i=i+1 - elseif t==13 then - hsbw() - if version=="cff" then - r=r+1;result[r]=encode[lsb] - r=r+1;result[r]=chars[22] - else - end - i=i+1 - else - if trace_charstrings then - showstate(reverse[t] or "") - end - if top>0 then - for i=1,top do - r=r+1;result[r]=encode[stack[i]] - end - top=0 - end - r=r+1;result[r]=chars[t] - i=i+1 - end - else - local a=actions[t] - if a then - local s=a(t) - if s then - i=i+s+1 - else - i=i+1 - end - else - if trace_charstrings then - showstate(reverse[t] or "") - end - top=0 - i=i+1 - end - end - end - end - local function setbias(globals,locals,nobias) - if nobias then - return 0,0 - else - local g=#globals - local l=#locals - return - ((g<1240 and 107) or (g<33900 and 1131) or 32768)+1, - ((l<1240 and 107) or (l<33900 and 1131) or 32768)+1 - end - end - local function processshape(tab,index,hack) - if not tab then - glyphs[index]={ - boundingbox={ 0,0,0,0 }, - width=0, - name=charset and charset[index] or nil, - } - return - end - tab=bytetable(tab) - x=0 - y=0 - width=false - lsb=0 - r=0 - top=0 - stems=0 - result={} - popped=3 - procidx=index - xmin=0 - xmax=0 - ymin=0 - ymax=0 - checked=false - if trace_charstrings then - report("glyph: %i",index) - report("data : % t",tab) - end - if regions then - updateregions(vsindex) - end - process(tab) - if hack then - return x,y - end - local boundingbox={ - round(xmin), - round(ymin), - round(xmax), - round(ymax), - } - if width==true or width==false then - width=defaultwidth - else - width=nominalwidth+width - end - local glyph=glyphs[index] - if justpass then - r=r+1 - result[r]=c_endchar - local stream=concat(result) - if glyph then - glyph.stream=stream - else - glyphs[index]={ stream=stream } - end - elseif glyph then - glyph.segments=keepcurve~=false and result or nil - glyph.boundingbox=boundingbox - if not glyph.width then - glyph.width=width - end - if charset and not glyph.name then - glyph.name=charset[index] - end - elseif keepcurve then - glyphs[index]={ - segments=result, - boundingbox=boundingbox, - width=width, - name=charset and charset[index] or nil, - } - else - glyphs[index]={ - boundingbox=boundingbox, - width=width, - name=charset and charset[index] or nil, - } - end - if trace_charstrings then - report("width : %s",tostring(width)) - report("boundingbox: % t",boundingbox) - end - end - startparsing=function(fontdata,data,streams) - reginit=false - axis=false - regions=data.regions - justpass=streams==true - popped=3 - seacs={} - if regions then - regions={ regions } - axis=data.factors or false - end - end - stopparsing=function(fontdata,data) - stack={} - glyphs=false - result={} - top=0 - locals=false - globals=false - strings=false - popped=3 - seacs={} - end - local function setwidths(private) - if not private then - return 0,0 - end - local privatedata=private.data - if not privatedata then - return 0,0 - end - return privatedata.nominalwidthx or 0,privatedata.defaultwidthx or 0 - end - parsecharstrings=function(fontdata,data,glphs,doshapes,tversion,streams,nobias) - local dictionary=data.dictionaries[1] - local charstrings=dictionary.charstrings - keepcurve=doshapes - version=tversion - strings=data.strings - globals=data.routines or {} - locals=dictionary.subroutines or {} - charset=dictionary.charset - vsindex=dictionary.vsindex or 0 - glyphs=glphs or {} - globalbias,localbias=setbias(globals,locals,nobias) - nominalwidth,defaultwidth=setwidths(dictionary.private) - if charstrings then - startparsing(fontdata,data,streams) - for index=1,#charstrings do - processshape(charstrings[index],index-1) - end - if justpass and next(seacs) then - local charset=data.dictionaries[1].charset - if charset then - local lookup=table.swapped(charset) - for index,v in next,seacs do - local bindex=lookup[standardnames[v.base]] - local aindex=lookup[standardnames[v.accent]] - local bglyph=bindex and glyphs[bindex] - local aglyph=aindex and glyphs[aindex] - if bglyph and aglyph then - local jp=justpass - justpass=false - local x,y=processshape(charstrings[bindex+1],bindex,true) - justpass=jp - local base=bglyph.stream - local accent=aglyph.stream - local moveto=encode[-x-v.asb+v.adx]..chars[22]..encode[-y+v.ady]..chars[ 4] - base=sub(base,1,#base-1) - glyphs[index].stream=base..moveto..accent - end - end - end - end - stopparsing(fontdata,data) - else - report("no charstrings") - end - return glyphs - end - parsecharstring=function(fontdata,data,dictionary,tab,glphs,index,doshapes,tversion,streams) - keepcurve=doshapes - version=tversion - strings=data.strings - globals=data.routines or {} - locals=dictionary.subroutines or {} - charset=false - vsindex=dictionary.vsindex or 0 - glyphs=glphs or {} - justpass=streams==true - seacs={} - globalbias,localbias=setbias(globals,locals,nobias) - nominalwidth,defaultwidth=setwidths(dictionary.private) - processshape(tab,index-1) - end -end -local function readglobals(f,data,version) - local routines=readlengths(f,version=="cff2") - for i=1,#routines do - routines[i]=readbytetable(f,routines[i]) - end - data.routines=routines -end -local function readencodings(f,data) - data.encodings={} -end -local function readcharsets(f,data,dictionary) - local header=data.header - local strings=data.strings - local nofglyphs=data.nofglyphs - local charsetoffset=dictionary.charset - if charsetoffset and charsetoffset~=0 then - setposition(f,header.offset+charsetoffset) - local format=readbyte(f) - local charset={ [0]=".notdef" } - dictionary.charset=charset - if format==0 then - for i=1,nofglyphs do - charset[i]=strings[readushort(f)] - end - elseif format==1 or format==2 then - local readcount=format==1 and readbyte or readushort - local i=1 - while i<=nofglyphs do - local sid=readushort(f) - local n=readcount(f) - for s=sid,sid+n do - charset[i]=strings[s] - i=i+1 - if i>nofglyphs then - break - end - end - end - else - report("cff parser: unsupported charset format %a",format) - end - else - dictionary.nocharset=true - dictionary.charset=nil - end -end -local function readprivates(f,data) - local header=data.header - local dictionaries=data.dictionaries - local private=dictionaries[1].private - if private then - setposition(f,header.offset+private.offset) - private.data=readstring(f,private.size) - end -end -local function readlocals(f,data,dictionary,version) - local header=data.header - local private=dictionary.private - if private then - local subroutineoffset=private.data.subroutines - if subroutineoffset~=0 then - setposition(f,header.offset+private.offset+subroutineoffset) - local subroutines=readlengths(f,version=="cff2") - for i=1,#subroutines do - subroutines[i]=readbytetable(f,subroutines[i]) - end - dictionary.subroutines=subroutines - private.data.subroutines=nil - else - dictionary.subroutines={} - end - else - dictionary.subroutines={} - end -end -local function readcharstrings(f,data,version) - local header=data.header - local dictionaries=data.dictionaries - local dictionary=dictionaries[1] - local stringtype=dictionary.charstringtype - local offset=dictionary.charstrings - if type(offset)~="number" then - elseif stringtype==2 then - setposition(f,header.offset+offset) - local charstrings=readlengths(f,version=="cff2") - local nofglyphs=#charstrings - for i=1,nofglyphs do - charstrings[i]=readstring(f,charstrings[i]) - end - data.nofglyphs=nofglyphs - dictionary.charstrings=charstrings - else - report("unsupported charstr type %i",stringtype) - data.nofglyphs=0 - dictionary.charstrings={} - end -end -local function readcidprivates(f,data) - local header=data.header - local dictionaries=data.dictionaries[1].cid.dictionaries - for i=1,#dictionaries do - local dictionary=dictionaries[i] - local private=dictionary.private - if private then - setposition(f,header.offset+private.offset) - private.data=readstring(f,private.size) - end - end - parseprivates(data,dictionaries) -end -readers.parsecharstrings=parsecharstrings -local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams) - local dictionaries=data.dictionaries - local dictionary=dictionaries[1] - local cid=not dictionary.private and dictionary.cid - readglobals(f,data,version) - readcharstrings(f,data,version) - if version=="cff2" then - dictionary.charset=nil - else - readencodings(f,data) - readcharsets(f,data,dictionary) - end - if cid then - local fdarray=cid.fdarray - if fdarray then - setposition(f,data.header.offset+fdarray) - local dictionaries=readlengths(f,version=="cff2") - local nofdictionaries=#dictionaries - if nofdictionaries>0 then - for i=1,nofdictionaries do - dictionaries[i]=readstring(f,dictionaries[i]) - end - parsedictionaries(data,dictionaries) - dictionary.private=dictionaries[1].private - if nofdictionaries>1 then - report("ignoring dictionaries > 1 in cid font") - end - end - end - end - readprivates(f,data) - parseprivates(data,data.dictionaries) - readlocals(f,data,dictionary,version) - startparsing(fontdata,data,streams) - parsecharstrings(fontdata,data,glyphs,doshapes,version,streams) - stopparsing(fontdata,data) -end -local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams) - local header=data.header - local dictionaries=data.dictionaries - local dictionary=dictionaries[1] - local cid=dictionary.cid - local cidselect=cid and cid.fdselect - readglobals(f,data,version) - readcharstrings(f,data,version) - if version~="cff2" then - readencodings(f,data) - end - local charstrings=dictionary.charstrings - local fdindex={} - local nofglyphs=data.nofglyphs - local maxindex=-1 - setposition(f,header.offset+cidselect) - local format=readbyte(f) - if format==1 then - for i=0,nofglyphs do - local index=readbyte(f) - fdindex[i]=index - if index>maxindex then - maxindex=index - end - end - elseif format==3 then - local nofranges=readushort(f) - local first=readushort(f) - local index=readbyte(f) - while true do - local last=readushort(f) - if index>maxindex then - maxindex=index - end - for i=first,last do - fdindex[i]=index - end - if last>=nofglyphs then - break - else - first=last+1 - index=readbyte(f) - end - end - else - end - if maxindex>=0 then - local cidarray=cid.fdarray - if cidarray then - setposition(f,header.offset+cidarray) - local dictionaries=readlengths(f,version=="cff2") - for i=1,#dictionaries do - dictionaries[i]=readstring(f,dictionaries[i]) - end - parsedictionaries(data,dictionaries) - cid.dictionaries=dictionaries - readcidprivates(f,data) - for i=1,#dictionaries do - readlocals(f,data,dictionaries[i],version) - end - startparsing(fontdata,data,streams) - for i=1,#charstrings do - parsecharstring(fontdata,data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version,streams) - end - stopparsing(fontdata,data) - else - report("no cid array") - end - end -end -local gotodatatable=readers.helpers.gotodatatable -local function cleanup(data,dictionaries) -end -function readers.cff(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"cff",specification.details or specification.glyphs) - if tableoffset then - local header=readheader(f) - if header.major~=1 then - report("only version %s is supported for table %a",1,"cff") - return - end - local glyphs=fontdata.glyphs - local names=readfontnames(f) - local dictionaries=readtopdictionaries(f) - local strings=readstrings(f) - local data={ - header=header, - names=names, - dictionaries=dictionaries, - strings=strings, - nofglyphs=fontdata.nofglyphs, - } - parsedictionaries(data,dictionaries,"cff") - local dic=dictionaries[1] - local cid=dic.cid - local cffinfo={ - familyname=dic.familyname, - fullname=dic.fullname, - boundingbox=dic.boundingbox, - weight=dic.weight, - italicangle=dic.italicangle, - underlineposition=dic.underlineposition, - underlinethickness=dic.underlinethickness, - defaultwidth=dic.defaultwidthx, - nominalwidth=dic.nominalwidthx, - monospaced=dic.monospaced, - } - fontdata.cidinfo=cid and { - registry=cid.registry, - ordering=cid.ordering, - supplement=cid.supplement, - } - fontdata.cffinfo=cffinfo - local all=specification.shapes or specification.streams or false - if specification.glyphs or all then - if cid and cid.fdselect then - readfdselect(f,fontdata,data,glyphs,all,"cff",specification.streams) - else - readnoselect(f,fontdata,data,glyphs,all,"cff",specification.streams) - end - end - local private=dic.private - if private then - local data=private.data - if type(data)=="table" then - cffinfo.defaultwidth=data.defaultwidthx or cffinfo.defaultwidth - cffinfo.nominalwidth=data.nominalwidthx or cffinfo.nominalwidth - cffinfo.bluevalues=data.bluevalues - cffinfo.otherblues=data.otherblues - cffinfo.familyblues=data.familyblues - cffinfo.familyotherblues=data.familyotherblues - cffinfo.bluescale=data.bluescale - cffinfo.blueshift=data.blueshift - cffinfo.bluefuzz=data.bluefuzz - cffinfo.stdhw=data.stdhw - cffinfo.stdvw=data.stdvw - end - end - cleanup(data,dictionaries) - end -end -function readers.cff2(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"cff2",specification.glyphs) - if tableoffset then - local header=readheader(f) - if header.major~=2 then - report("only version %s is supported for table %a",2,"cff2") - return - end - local glyphs=fontdata.glyphs - local dictionaries={ readstring(f,header.dsize) } - local data={ - header=header, - dictionaries=dictionaries, - nofglyphs=fontdata.nofglyphs, - } - parsedictionaries(data,dictionaries,"cff2") - local offset=dictionaries[1].vstore - if offset>0 then - local storeoffset=dictionaries[1].vstore+data.header.offset+2 - local regions,deltas=readers.helpers.readvariationdata(f,storeoffset,factors) - data.regions=regions - data.deltas=deltas - else - data.regions={} - data.deltas={} - end - data.factors=specification.factors - local cid=data.dictionaries[1].cid - local all=specification.shapes or specification.streams or false - if cid and cid.fdselect then - readfdselect(f,fontdata,data,glyphs,all,"cff2",specification.streams) - else - readnoselect(f,fontdata,data,glyphs,all,"cff2",specification.streams) - end - cleanup(data,dictionaries) - end -end -function readers.cffcheck(filename) - local f=io.open(filename,"rb") - if f then - local fontdata={ - glyphs={}, - } - local header=readheader(f) - if header.major~=1 then - report("only version %s is supported for table %a",1,"cff") - return - end - local names=readfontnames(f) - local dictionaries=readtopdictionaries(f) - local strings=readstrings(f) - local glyphs={} - local data={ - header=header, - names=names, - dictionaries=dictionaries, - strings=strings, - glyphs=glyphs, - nofglyphs=0, - } - parsedictionaries(data,dictionaries,"cff") - local cid=data.dictionaries[1].cid - if cid and cid.fdselect then - readfdselect(f,fontdata,data,glyphs,false) - else - readnoselect(f,fontdata,data,glyphs,false) - end - return data - end -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-cff”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ttf” ffffc827e1bcddc33a2b615340ecff7f] --- - -if not modules then modules={} end modules ['font-ttf']={ - version=1.001, - optimize=true, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next,type,unpack=next,type,unpack -local band,rshift=bit32.band,bit32.rshift -local sqrt,round=math.sqrt,math.round -local char,rep=string.char,string.rep -local concat=table.concat -local idiv=number.idiv -local setmetatableindex=table.setmetatableindex -local report=logs.reporter("otf reader","ttf") -local trace_deltas=false -local readers=fonts.handlers.otf.readers -local streamreader=readers.streamreader -local setposition=streamreader.setposition -local getposition=streamreader.getposition -local skipbytes=streamreader.skip -local readbyte=streamreader.readcardinal1 -local readushort=streamreader.readcardinal2 -local readulong=streamreader.readcardinal4 -local readchar=streamreader.readinteger1 -local readshort=streamreader.readinteger2 -local read2dot14=streamreader.read2dot14 -local readinteger=streamreader.readinteger1 -local readcardinaltable=streamreader.readcardinaltable -local readintegertable=streamreader.readintegertable -directives.register("fonts.streamreader",function() - streamreader=utilities.streams - setposition=streamreader.setposition - getposition=streamreader.getposition - skipbytes=streamreader.skip - readbyte=streamreader.readcardinal1 - readushort=streamreader.readcardinal2 - readulong=streamreader.readcardinal4 - readchar=streamreader.readinteger1 - readshort=streamreader.readinteger2 - read2dot14=streamreader.read2dot14 - readinteger=streamreader.readinteger1 - readcardinaltable=streamreader.readcardinaltable - readintegertable=streamreader.readintegertable -end) -local short=2 -local ushort=2 -local ulong=4 -local helpers=readers.helpers -local gotodatatable=helpers.gotodatatable -local function mergecomposites(glyphs,shapes) - local function merge(index,shape,components) - local contours={} - local points={} - local nofcontours=0 - local nofpoints=0 - local offset=0 - local deltas=shape.deltas - for i=1,#components do - local component=components[i] - local subindex=component.index - local subshape=shapes[subindex] - local subcontours=subshape.contours - local subpoints=subshape.points - if not subcontours then - local subcomponents=subshape.components - if subcomponents then - subcontours,subpoints=merge(subindex,subshape,subcomponents) - end - end - if subpoints then - local matrix=component.matrix - local xscale=matrix[1] - local xrotate=matrix[2] - local yrotate=matrix[3] - local yscale=matrix[4] - local xoffset=matrix[5] - local yoffset=matrix[6] - local count=#subpoints - if xscale==1 and yscale==1 and xrotate==0 and yrotate==0 then - for i=1,count do - local p=subpoints[i] - nofpoints=nofpoints+1 - points[nofpoints]={ - p[1]+xoffset, - p[2]+yoffset, - p[3] - } - end - else - for i=1,count do - local p=subpoints[i] - local x=p[1] - local y=p[2] - nofpoints=nofpoints+1 - points[nofpoints]={ - xscale*x+xrotate*y+xoffset, - yscale*y+yrotate*x+yoffset, - p[3] - } - end - end - local subcount=#subcontours - if subcount==1 then - nofcontours=nofcontours+1 - contours[nofcontours]=offset+subcontours[1] - else - for i=1,#subcontours do - nofcontours=nofcontours+1 - contours[nofcontours]=offset+subcontours[i] - end - end - offset=offset+count - else - report("missing contours composite %s, component %s of %s, glyph %s",index,i,#components,subindex) - end - end - shape.points=points - shape.contours=contours - shape.components=nil - return contours,points - end - for index=0,#glyphs do - local shape=shapes[index] - if shape then - local components=shape.components - if components then - merge(index,shape,components) - end - end - end -end -local function readnothing(f) - return { - type="nothing", - } -end -local function curveto(m_x,m_y,l_x,l_y,r_x,r_y) - return - l_x+2/3*(m_x-l_x),l_y+2/3*(m_y-l_y), - r_x+2/3*(m_x-r_x),r_y+2/3*(m_y-r_y), - r_x,r_y,"c" -end -local function applyaxis(glyph,shape,deltas,dowidth) - local points=shape.points - if points then - local nofpoints=#points - local h=nofpoints+2 - local l=nofpoints+1 - local dw=0 - local dl=0 - for i=1,#deltas do - local deltaset=deltas[i] - local xvalues=deltaset.xvalues - local yvalues=deltaset.yvalues - local dpoints=deltaset.points - local factor=deltaset.factor - if dpoints then - local nofdpoints=#dpoints - for i=1,nofdpoints do - local d=dpoints[i] - local p=points[d] - if p then - if xvalues then - local x=xvalues[i] - if x and x~=0 then - p[1]=p[1]+factor*x - end - end - if yvalues then - local y=yvalues[i] - if y and y~=0 then - p[2]=p[2]+factor*y - end - end - elseif dowidth then - if d==h then - local x=xvalues[i] - if x then - dw=dw+factor*x - end - elseif d==l then - local x=xvalues[i] - if x then - dl=dl+factor*x - end - end - end - end - else - for i=1,nofpoints do - local p=points[i] - if xvalues then - local x=xvalues[i] - if x and x~=0 then - p[1]=p[1]+factor*x - end - end - if yvalues then - local y=yvalues[i] - if y and y~=0 then - p[2]=p[2]+factor*y - end - end - end - if dowidth then - local x=xvalues[h] - if x then - dw=dw+factor*x - end - local x=xvalues[l] - if x then - dl=dl+factor*x - end - end - end - end - if dowidth then - local width=glyph.width or 0 - glyph.width=width+dw-dl - end - else - report("no points for glyph %a",glyph.name) - end -end -local quadratic=false -local function contours2outlines_normal(glyphs,shapes) - for index=0,#glyphs-1 do - local shape=shapes[index] - if shape then - local glyph=glyphs[index] - local contours=shape.contours - local points=shape.points - if contours then - local nofcontours=#contours - local segments={} - local nofsegments=0 - glyph.segments=segments - if nofcontours>0 then - local px=0 - local py=0 - local first=1 - for i=1,nofcontours do - local last=contours[i] - if last>=first then - local first_pt=points[first] - local first_on=first_pt[3] - if first==last then - first_pt[3]="m" - nofsegments=nofsegments+1 - segments[nofsegments]=first_pt - else - local first_on=first_pt[3] - local last_pt=points[last] - local last_on=last_pt[3] - local start=1 - local control_pt=false - if first_on then - start=2 - else - if last_on then - first_pt=last_pt - else - first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false } - end - control_pt=first_pt - end - local x=first_pt[1] - local y=first_pt[2] - if not done then - xmin=x - ymin=y - xmax=x - ymax=y - done=true - end - nofsegments=nofsegments+1 - segments[nofsegments]={ x,y,"m" } - if not quadratic then - px=x - py=y - end - local previous_pt=first_pt - for i=first,last do - local current_pt=points[i] - local current_on=current_pt[3] - local previous_on=previous_pt[3] - if previous_on then - if current_on then - local x,y=current_pt[1],current_pt[2] - nofsegments=nofsegments+1 - segments[nofsegments]={ x,y,"l" } - if not quadratic then - px,py=x,y - end - else - control_pt=current_pt - end - elseif current_on then - local x1=control_pt[1] - local y1=control_pt[2] - local x2=current_pt[1] - local y2=current_pt[2] - nofsegments=nofsegments+1 - if quadratic then - segments[nofsegments]={ x1,y1,x2,y2,"q" } - else - x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) - segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } - end - control_pt=false - else - local x2=(previous_pt[1]+current_pt[1])/2 - local y2=(previous_pt[2]+current_pt[2])/2 - local x1=control_pt[1] - local y1=control_pt[2] - nofsegments=nofsegments+1 - if quadratic then - segments[nofsegments]={ x1,y1,x2,y2,"q" } - else - x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) - segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } - end - control_pt=current_pt - end - previous_pt=current_pt - end - if first_pt==last_pt then - else - nofsegments=nofsegments+1 - local x2=first_pt[1] - local y2=first_pt[2] - if not control_pt then - segments[nofsegments]={ x2,y2,"l" } - elseif quadratic then - local x1=control_pt[1] - local y1=control_pt[2] - segments[nofsegments]={ x1,y1,x2,y2,"q" } - else - local x1=control_pt[1] - local y1=control_pt[2] - x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) - segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } - end - end - end - end - first=last+1 - end - end - end - end - end -end -local function contours2outlines_shaped(glyphs,shapes,keepcurve) - for index=0,#glyphs-1 do - local shape=shapes[index] - if shape then - local glyph=glyphs[index] - local contours=shape.contours - local points=shape.points - if contours then - local nofcontours=#contours - local segments=keepcurve and {} or nil - local nofsegments=0 - if keepcurve then - glyph.segments=segments - end - if nofcontours>0 then - local xmin,ymin,xmax,ymax,done=0,0,0,0,false - local px,py=0,0 - local first=1 - for i=1,nofcontours do - local last=contours[i] - if last>=first then - local first_pt=points[first] - local first_on=first_pt[3] - if first==last then - if keepcurve then - first_pt[3]="m" - nofsegments=nofsegments+1 - segments[nofsegments]=first_pt - end - else - local first_on=first_pt[3] - local last_pt=points[last] - local last_on=last_pt[3] - local start=1 - local control_pt=false - if first_on then - start=2 - else - if last_on then - first_pt=last_pt - else - first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false } - end - control_pt=first_pt - end - local x=first_pt[1] - local y=first_pt[2] - if not done then - xmin,ymin,xmax,ymax=x,y,x,y - done=true - else - if xxmax then xmax=x end - if yymax then ymax=y end - end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x,y,"m" } - end - if not quadratic then - px=x - py=y - end - local previous_pt=first_pt - for i=first,last do - local current_pt=points[i] - local current_on=current_pt[3] - local previous_on=previous_pt[3] - if previous_on then - if current_on then - local x=current_pt[1] - local y=current_pt[2] - if xxmax then xmax=x end - if yymax then ymax=y end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x,y,"l" } - end - if not quadratic then - px=x - py=y - end - else - control_pt=current_pt - end - elseif current_on then - local x1=control_pt[1] - local y1=control_pt[2] - local x2=current_pt[1] - local y2=current_pt[2] - if quadratic then - if x1xmax then xmax=x1 end - if y1ymax then ymax=y1 end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x1,y1,x2,y2,"q" } - end - else - x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) - if x1xmax then xmax=x1 end - if y1ymax then ymax=y1 end - if x2xmax then xmax=x2 end - if y2ymax then ymax=y2 end - if pxxmax then xmax=px end - if pyymax then ymax=py end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } - end - end - control_pt=false - else - local x2=(previous_pt[1]+current_pt[1])/2 - local y2=(previous_pt[2]+current_pt[2])/2 - local x1=control_pt[1] - local y1=control_pt[2] - if quadratic then - if x1xmax then xmax=x1 end - if y1ymax then ymax=y1 end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x1,y1,x2,y2,"q" } - end - else - x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) - if x1xmax then xmax=x1 end - if y1ymax then ymax=y1 end - if x2xmax then xmax=x2 end - if y2ymax then ymax=y2 end - if pxxmax then xmax=px end - if pyymax then ymax=py end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } - end - end - control_pt=current_pt - end - previous_pt=current_pt - end - if first_pt==last_pt then - elseif not control_pt then - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ first_pt[1],first_pt[2],"l" } - end - else - local x1=control_pt[1] - local y1=control_pt[2] - local x2=first_pt[1] - local y2=first_pt[2] - if x1xmax then xmax=x1 end - if y1ymax then ymax=y1 end - if quadratic then - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x1,y1,x2,y2,"q" } - end - else - x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) - if x2xmax then xmax=x2 end - if y2ymax then ymax=y2 end - if pxxmax then xmax=px end - if pyymax then ymax=py end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } - end - end - end - end - end - first=last+1 - end - glyph.boundingbox={ round(xmin),round(ymin),round(xmax),round(ymax) } - end - end - end - end -end -local c_zero=char(0) -local s_zero=char(0,0) -local function toushort(n) - return char(band(rshift(n,8),0xFF),band(n,0xFF)) -end -local function toshort(n) - if n<0 then - n=n+0x10000 - end - return char(band(rshift(n,8),0xFF),band(n,0xFF)) -end -local chars=setmetatableindex(function(t,k) - for i=0,255 do local v=char(i) t[i]=v end return t[k] -end) -local function repackpoints(glyphs,shapes) - local noboundingbox={ 0,0,0,0 } - local result={} - local xpoints={} - local ypoints={} - for index=0,#glyphs do - local shape=shapes[index] - if shape then - local r=0 - local glyph=glyphs[index] - local contours=shape.contours - local nofcontours=contours and #contours or 0 - local boundingbox=glyph.boundingbox or noboundingbox - r=r+1 result[r]=toshort(nofcontours) - r=r+1 result[r]=toshort(boundingbox[1]) - r=r+1 result[r]=toshort(boundingbox[2]) - r=r+1 result[r]=toshort(boundingbox[3]) - r=r+1 result[r]=toshort(boundingbox[4]) - if nofcontours>0 then - for i=1,nofcontours do - r=r+1 result[r]=toshort(contours[i]-1) - end - r=r+1 result[r]=s_zero - local points=shape.points - local currentx=0 - local currenty=0 - local x=0 - local y=0 - local lastflag=nil - local nofflags=0 - for i=1,#points do - local pt=points[i] - local px=pt[1] - local py=pt[2] - local fl=pt[3] and 0x01 or 0x00 - if px==currentx then - fl=fl+0x10 - else - local dx=round(px-currentx) - x=x+1 - if dx<-255 or dx>255 then - xpoints[x]=toshort(dx) - elseif dx<0 then - fl=fl+0x02 - xpoints[x]=chars[-dx] - elseif dx>0 then - fl=fl+0x12 - xpoints[x]=chars[dx] - else - fl=fl+0x02 - xpoints[x]=c_zero - end - end - if py==currenty then - fl=fl+0x20 - else - local dy=round(py-currenty) - y=y+1 - if dy<-255 or dy>255 then - ypoints[y]=toshort(dy) - elseif dy<0 then - fl=fl+0x04 - ypoints[y]=chars[-dy] - elseif dy>0 then - fl=fl+0x24 - ypoints[y]=chars[dy] - else - fl=fl+0x04 - ypoints[y]=c_zero - end - end - currentx=px - currenty=py - if lastflag==fl then - if nofflags==255 then - lastflag=lastflag+0x08 - r=r+1 result[r]=char(lastflag,nofflags-1) - nofflags=1 - lastflag=fl - else - nofflags=nofflags+1 - end - else - if nofflags==1 then - r=r+1 result[r]=chars[lastflag] - elseif nofflags==2 then - r=r+1 result[r]=char(lastflag,lastflag) - elseif nofflags>2 then - lastflag=lastflag+0x08 - r=r+1 result[r]=char(lastflag,nofflags-1) - end - nofflags=1 - lastflag=fl - end - end - if nofflags==1 then - r=r+1 result[r]=chars[lastflag] - elseif nofflags==2 then - r=r+1 result[r]=char(lastflag,lastflag) - elseif nofflags>2 then - lastflag=lastflag+0x08 - r=r+1 result[r]=char(lastflag,nofflags-1) - end - r=r+1 result[r]=concat(xpoints,"",1,x) - r=r+1 result[r]=concat(ypoints,"",1,y) - end - local stream=concat(result,"",1,r) - local length=#stream - local padding=idiv(length+3,4)*4-length - if padding>0 then - if padding==1 then - padding="\0" - elseif padding==2 then - padding="\0\0" - else - padding="\0\0\0" - end - padding=stream..padding - end - glyph.stream=stream - end - end -end -local flags={} -local function readglyph(f,nofcontours) - local points={} - local contours={} - for i=1,nofcontours do - contours[i]=readshort(f)+1 - end - local nofpoints=contours[nofcontours] - local nofinstructions=readushort(f) - skipbytes(f,nofinstructions) - local i=1 - while i<=nofpoints do - local flag=readbyte(f) - flags[i]=flag - if band(flag,0x08)~=0 then - local n=readbyte(f) - if n==1 then - i=i+1 - flags[i]=flag - else - for j=1,n do - i=i+1 - flags[i]=flag - end - end - end - i=i+1 - end - local x=0 - for i=1,nofpoints do - local flag=flags[i] - if band(flag,0x02)~=0 then - if band(flag,0x10)~=0 then - x=x+readbyte(f) - else - x=x-readbyte(f) - end - elseif band(flag,0x10)~=0 then - else - x=x+readshort(f) - end - points[i]={ x,0,band(flag,0x01)~=0 } - end - local y=0 - for i=1,nofpoints do - local flag=flags[i] - if band(flag,0x04)~=0 then - if band(flag,0x20)~=0 then - y=y+readbyte(f) - else - y=y-readbyte(f) - end - elseif band(flag,0x20)~=0 then - else - y=y+readshort(f) - end - points[i][2]=y - end - return { - type="glyph", - points=points, - contours=contours, - nofpoints=nofpoints, - } -end -local function readcomposite(f) - local components={} - local nofcomponents=0 - local instructions=false - while true do - local flags=readushort(f) - local index=readushort(f) - local f_xyarg=band(flags,0x0002)~=0 - local f_offset=band(flags,0x0800)~=0 - local xscale=1 - local xrotate=0 - local yrotate=0 - local yscale=1 - local xoffset=0 - local yoffset=0 - local base=false - local reference=false - if f_xyarg then - if band(flags,0x0001)~=0 then - xoffset=readshort(f) - yoffset=readshort(f) - else - xoffset=readchar(f) - yoffset=readchar(f) - end - else - if band(flags,0x0001)~=0 then - base=readshort(f) - reference=readshort(f) - else - base=readchar(f) - reference=readchar(f) - end - end - if band(flags,0x0008)~=0 then - xscale=read2dot14(f) - yscale=xscale - if f_xyarg and f_offset then - xoffset=xoffset*xscale - yoffset=yoffset*yscale - end - elseif band(flags,0x0040)~=0 then - xscale=read2dot14(f) - yscale=read2dot14(f) - if f_xyarg and f_offset then - xoffset=xoffset*xscale - yoffset=yoffset*yscale - end - elseif band(flags,0x0080)~=0 then - xscale=read2dot14(f) - xrotate=read2dot14(f) - yrotate=read2dot14(f) - yscale=read2dot14(f) - if f_xyarg and f_offset then - xoffset=xoffset*sqrt(xscale^2+xrotate^2) - yoffset=yoffset*sqrt(yrotate^2+yscale^2) - end - end - nofcomponents=nofcomponents+1 - components[nofcomponents]={ - index=index, - usemine=band(flags,0x0200)~=0, - round=band(flags,0x0006)~=0, - base=base, - reference=reference, - matrix={ xscale,xrotate,yrotate,yscale,xoffset,yoffset }, - } - if band(flags,0x0100)~=0 then - instructions=true - end - if band(flags,0x0020)==0 then - break - end - end - return { - type="composite", - components=components, - } -end -function readers.loca(f,fontdata,specification) - if specification.glyphs then - local datatable=fontdata.tables.loca - if datatable then - local offset=fontdata.tables.glyf.offset - local format=fontdata.fontheader.indextolocformat - local profile=fontdata.maximumprofile - local nofglyphs=profile and profile.nofglyphs - local locations={} - setposition(f,datatable.offset) - if format==1 then - if not nofglyphs then - nofglyphs=idiv(datatable.length,4)-1 - end - for i=0,nofglyphs do - locations[i]=offset+readulong(f) - end - fontdata.nofglyphs=nofglyphs - else - if not nofglyphs then - nofglyphs=idiv(datatable.length,2)-1 - end - for i=0,nofglyphs do - locations[i]=offset+readushort(f)*2 - end - end - fontdata.nofglyphs=nofglyphs - fontdata.locations=locations - end - end -end -function readers.glyf(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"glyf",specification.glyphs) - if tableoffset then - local locations=fontdata.locations - if locations then - local glyphs=fontdata.glyphs - local nofglyphs=fontdata.nofglyphs - local filesize=fontdata.filesize - local nothing={ 0,0,0,0 } - local shapes={} - local loadshapes=specification.shapes or specification.instance or specification.streams - for index=0,nofglyphs-1 do - local location=locations[index] - local length=locations[index+1]-location - if location>=filesize then - report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1) - fontdata.nofglyphs=index-1 - fontdata.badfont=true - break - elseif length>0 then - setposition(f,location) - local nofcontours=readshort(f) - glyphs[index].boundingbox={ - readshort(f), - readshort(f), - readshort(f), - readshort(f), - } - if not loadshapes then - elseif nofcontours==0 then - shapes[index]=readnothing(f) - elseif nofcontours>0 then - shapes[index]=readglyph(f,nofcontours) - else - shapes[index]=readcomposite(f,nofcontours) - end - else - if loadshapes then - shapes[index]=readnothing(f) - end - glyphs[index].boundingbox=nothing - end - end - if loadshapes then - if readers.gvar then - readers.gvar(f,fontdata,specification,glyphs,shapes) - end - mergecomposites(glyphs,shapes) - if specification.instance then - if specification.streams then - repackpoints(glyphs,shapes) - else - contours2outlines_shaped(glyphs,shapes,specification.shapes) - end - elseif specification.shapes then - if specification.streams then - repackpoints(glyphs,shapes) - else - contours2outlines_normal(glyphs,shapes) - end - elseif specification.streams then - repackpoints(glyphs,shapes) - end - end - end - end -end -local function readtuplerecord(f,nofaxis) - local record={} - for i=1,nofaxis do - record[i]=read2dot14(f) - end - return record -end -local function readpoints(f) - local count=readbyte(f) - if count==0 then - return nil,0 - else - if count<128 then - elseif band(count,0x80)~=0 then - count=band(count,0x7F)*256+readbyte(f) - else - end - local points={} - local p=0 - local n=1 - while p0 do - local control=readbyte(f) -if not control then - break -end - local allzero=band(control,0x80)~=0 - local runlength=band(control,0x3F)+1 - if allzero then - z=z+runlength - else - local runreader=band(control,0x40)~=0 and readshort or readinteger - if z>0 then - for i=1,z do - p=p+1 - deltas[p]=0 - end - z=0 - end - for i=1,runlength do - p=p+1 - deltas[p]=runreader(f) - end - end - nofpoints=nofpoints-runlength - end - if p>0 then - return deltas - else - end -end -local function readdeltas(f,nofpoints) - local deltas={} - local p=0 - while nofpoints>0 do - local control=readbyte(f) - if control then - local allzero=band(control,0x80)~=0 - local runlength=band(control,0x3F)+1 - if allzero then - for i=1,runlength do - p=p+1 - deltas[p]=0 - end - else - local runreader=band(control,0x40)~=0 and readshort or readinteger - for i=1,runlength do - p=p+1 - deltas[p]=runreader(f) - end - end - nofpoints=nofpoints-runlength - else - break - end - end - if p>0 then - return deltas - else - end -end -function readers.gvar(f,fontdata,specification,glyphdata,shapedata) - local instance=specification.instance - if not instance then - return - end - local factors=specification.factors - if not factors then - return - end - local tableoffset=gotodatatable(f,fontdata,"gvar",specification.variable or specification.shapes) - if tableoffset then - local version=readulong(f) - local nofaxis=readushort(f) - local noftuples=readushort(f) - local tupleoffset=tableoffset+readulong(f) - local nofglyphs=readushort(f) - local flags=readushort(f) - local dataoffset=tableoffset+readulong(f) - local data={} - local tuples={} - local glyphdata=fontdata.glyphs - local dowidth=not fontdata.variabledata.hvarwidths - if band(flags,0x0001)~=0 then - for i=1,nofglyphs+1 do - data[i]=dataoffset+readulong(f) - end - else - for i=1,nofglyphs+1 do - data[i]=dataoffset+2*readushort(f) - end - end - if noftuples>0 then - setposition(f,tupleoffset) - for i=1,noftuples do - tuples[i]=readtuplerecord(f,nofaxis) - end - end - local nextoffset=false - local startoffset=data[1] - for i=1,nofglyphs do - nextoffset=data[i+1] - local glyph=glyphdata[i-1] - local name=trace_deltas and glyph.name - if startoffset==nextoffset then - if name then - report("no deltas for glyph %a",name) - end - else - local shape=shapedata[i-1] - if not shape then - if name then - report("no shape for glyph %a",name) - end - else - lastoffset=startoffset - setposition(f,startoffset) - local flags=readushort(f) - local count=band(flags,0x0FFF) - local offset=startoffset+readushort(f) - local deltas={} - local allpoints=(shape.nofpoints or 0) - local shared=false - local nofshared=0 - if band(flags,0x8000)~=0 then - local current=getposition(f) - setposition(f,offset) - shared,nofshared=readpoints(f) - offset=getposition(f) - setposition(f,current) - end - for j=1,count do - local size=readushort(f) - local flags=readushort(f) - local index=band(flags,0x0FFF) - local haspeak=band(flags,0x8000)~=0 - local intermediate=band(flags,0x4000)~=0 - local private=band(flags,0x2000)~=0 - local peak=nil - local start=nil - local stop=nil - local xvalues=nil - local yvalues=nil - local points=shared - local nofpoints=nofshared - if haspeak then - peak=readtuplerecord(f,nofaxis) - else - if index+1>#tuples then - report("error, bad tuple index",index) - end - peak=tuples[index+1] - end - if intermediate then - start=readtuplerecord(f,nofaxis) - stop=readtuplerecord(f,nofaxis) - end - if size>0 then - local current=getposition(f) - setposition(f,offset) - if private then - points,nofpoints=readpoints(f) - end - if nofpoints==0 then - nofpoints=allpoints+4 - end - if nofpoints>0 then - xvalues=readdeltas(f,nofpoints) - yvalues=readdeltas(f,nofpoints) - end - offset=offset+size - setposition(f,current) - end - if not xvalues and not yvalues then - points=nil - end - local s=1 - for i=1,nofaxis do - local f=factors[i] - local peak=peak and peak [i] or 0 - local start=start and start[i] or (peak<0 and peak or 0) - local stop=stop and stop [i] or (peak>0 and peak or 0) - if start>peak or peak>stop then - elseif start<0 and stop>0 and peak~=0 then - elseif peak==0 then - elseif fstop then - s=0 - break - elseif fpeak then - s=s*(stop-f)/(stop-peak) - else - end - end - if s==0 then - if name then - report("no deltas applied for glyph %a",name) - end - else - deltas[#deltas+1]={ - factor=s, - points=points, - xvalues=xvalues, - yvalues=yvalues, - } - end - end - if shape.type=="glyph" then - applyaxis(glyph,shape,deltas,dowidth) - else - shape.deltas=deltas - end - end - end - startoffset=nextoffset - end - end -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ttf”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-dsp” 18c85a4857f45c31a3555bf1faac434a] --- - -if not modules then modules={} end modules ['font-dsp']={ - version=1.001, - optimize=true, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next,type,tonumber=next,type,tonumber -local band=bit32.band -local extract=bit32.extract -local bor=bit32.bor -local lshift=bit32.lshift -local rshift=bit32.rshift -local gsub=string.gsub -local lower=string.lower -local sub=string.sub -local strip=string.strip -local tohash=table.tohash -local concat=table.concat -local copy=table.copy -local reversed=table.reversed -local sort=table.sort -local insert=table.insert -local round=math.round -local settings_to_hash=utilities.parsers.settings_to_hash_colon_too -local setmetatableindex=table.setmetatableindex -local formatters=string.formatters -local sortedkeys=table.sortedkeys -local sortedhash=table.sortedhash -local sequenced=table.sequenced -local report=logs.reporter("otf reader") -local readers=fonts.handlers.otf.readers -local streamreader=readers.streamreader -local setposition=streamreader.setposition -local getposition=streamreader.getposition -local readuinteger=streamreader.readcardinal1 -local readushort=streamreader.readcardinal2 -local readulong=streamreader.readcardinal4 -local readinteger=streamreader.readinteger1 -local readshort=streamreader.readinteger2 -local readstring=streamreader.readstring -local readtag=streamreader.readtag -local readbytes=streamreader.readbytes -local readfixed=streamreader.readfixed4 -local read2dot14=streamreader.read2dot14 -local skipshort=streamreader.skipshort -local skipbytes=streamreader.skip -local readbytetable=streamreader.readbytetable -local readbyte=streamreader.readbyte -local readcardinaltable=streamreader.readcardinaltable -local readintegertable=streamreader.readintegertable -local readfword=readshort -local short=2 -local ushort=2 -local ulong=4 -directives.register("fonts.streamreader",function() - streamreader=utilities.streams - setposition=streamreader.setposition - getposition=streamreader.getposition - readuinteger=streamreader.readcardinal1 - readushort=streamreader.readcardinal2 - readulong=streamreader.readcardinal4 - readinteger=streamreader.readinteger1 - readshort=streamreader.readinteger2 - readstring=streamreader.readstring - readtag=streamreader.readtag - readbytes=streamreader.readbytes - readfixed=streamreader.readfixed4 - read2dot14=streamreader.read2dot14 - skipshort=streamreader.skipshort - skipbytes=streamreader.skip - readbytetable=streamreader.readbytetable - readbyte=streamreader.readbyte - readcardinaltable=streamreader.readcardinaltable - readintegertable=streamreader.readintegertable - readfword=readshort -end) -local gsubhandlers={} -local gposhandlers={} -readers.gsubhandlers=gsubhandlers -readers.gposhandlers=gposhandlers -local helpers=readers.helpers -local gotodatatable=helpers.gotodatatable -local setvariabledata=helpers.setvariabledata -local lookupidoffset=-1 -local classes={ - "base", - "ligature", - "mark", - "component", -} -local gsubtypes={ - "single", - "multiple", - "alternate", - "ligature", - "context", - "chainedcontext", - "extension", - "reversechainedcontextsingle", -} -local gpostypes={ - "single", - "pair", - "cursive", - "marktobase", - "marktoligature", - "marktomark", - "context", - "chainedcontext", - "extension", -} -local chaindirections={ - context=0, - chainedcontext=1, - reversechainedcontextsingle=-1, -} -local function setmetrics(data,where,tag,d) - local w=data[where] - if w then - local v=w[tag] - if v then - w[tag]=v+d - end - end -end -local variabletags={ - hasc=function(data,d) setmetrics(data,"windowsmetrics","typoascender",d) end, - hdsc=function(data,d) setmetrics(data,"windowsmetrics","typodescender",d) end, - hlgp=function(data,d) setmetrics(data,"windowsmetrics","typolinegap",d) end, - hcla=function(data,d) setmetrics(data,"windowsmetrics","winascent",d) end, - hcld=function(data,d) setmetrics(data,"windowsmetrics","windescent",d) end, - vasc=function(data,d) setmetrics(data,"vhea not done","ascent",d) end, - vdsc=function(data,d) setmetrics(data,"vhea not done","descent",d) end, - vlgp=function(data,d) setmetrics(data,"vhea not done","linegap",d) end, - xhgt=function(data,d) setmetrics(data,"windowsmetrics","xheight",d) end, - cpht=function(data,d) setmetrics(data,"windowsmetrics","capheight",d) end, - sbxs=function(data,d) setmetrics(data,"windowsmetrics","subscriptxsize",d) end, - sbys=function(data,d) setmetrics(data,"windowsmetrics","subscriptysize",d) end, - sbxo=function(data,d) setmetrics(data,"windowsmetrics","subscriptxoffset",d) end, - sbyo=function(data,d) setmetrics(data,"windowsmetrics","subscriptyoffset",d) end, - spxs=function(data,d) setmetrics(data,"windowsmetrics","superscriptxsize",d) end, - spys=function(data,d) setmetrics(data,"windowsmetrics","superscriptysize",d) end, - spxo=function(data,d) setmetrics(data,"windowsmetrics","superscriptxoffset",d) end, - spyo=function(data,d) setmetrics(data,"windowsmetrics","superscriptyoffset",d) end, - strs=function(data,d) setmetrics(data,"windowsmetrics","strikeoutsize",d) end, - stro=function(data,d) setmetrics(data,"windowsmetrics","strikeoutpos",d) end, - unds=function(data,d) setmetrics(data,"postscript","underlineposition",d) end, - undo=function(data,d) setmetrics(data,"postscript","underlinethickness",d) end, -} -local read_cardinal={ - streamreader.readcardinal1, - streamreader.readcardinal2, - streamreader.readcardinal3, - streamreader.readcardinal4, -} -local read_integer={ - streamreader.readinteger1, - streamreader.readinteger2, - streamreader.readinteger3, - streamreader.readinteger4, -} -local lookupnames={ - gsub={ - single="gsub_single", - multiple="gsub_multiple", - alternate="gsub_alternate", - ligature="gsub_ligature", - context="gsub_context", - chainedcontext="gsub_contextchain", - reversechainedcontextsingle="gsub_reversecontextchain", - }, - gpos={ - single="gpos_single", - pair="gpos_pair", - cursive="gpos_cursive", - marktobase="gpos_mark2base", - marktoligature="gpos_mark2ligature", - marktomark="gpos_mark2mark", - context="gpos_context", - chainedcontext="gpos_contextchain", - } -} -local lookupflags=setmetatableindex(function(t,k) - local v={ - band(k,0x0008)~=0 and true or false, - band(k,0x0004)~=0 and true or false, - band(k,0x0002)~=0 and true or false, - band(k,0x0001)~=0 and true or false, - } - t[k]=v - return v -end) -local function axistofactors(str) - local t=settings_to_hash(str) - for k,v in next,t do - t[k]=tonumber(v) or v - end - return t -end -local hash=table.setmetatableindex(function(t,k) - local v=sequenced(axistofactors(k),",") - t[k]=v - return v -end) -helpers.normalizedaxishash=hash -local cleanname=fonts.names and fonts.names.cleanname or function(name) - return name and (gsub(lower(name),"[^%a%d]","")) or nil -end -helpers.cleanname=cleanname -function helpers.normalizedaxis(str) - return hash[str] or str -end -local function getaxisscale(segments,minimum,default,maximum,user) - if not minimum or not default or not maximum then - return false - end - if usermaximum then - user=maximum - end - if userdefault then - default=(user-default)/(maximum-default) - else - default=0 - end - if not segments then - return default - end - local e - for i=1,#segments do - local s=segments[i] - if type(s)~="number" then - report("using default axis scale") - return default - elseif s[1]>=default then - if s[2]==default then - return default - else - e=i - break - end - end - end - if e then - local b=segments[e-1] - local e=segments[e] - return b[2]+(e[2]-b[2])*(default-b[1])/(e[1]-b[1]) - else - return false - end -end -local function getfactors(data,instancespec) - if instancespec==true then - elseif type(instancespec)~="string" or instancespec=="" then - return - end - local variabledata=data.variabledata - if not variabledata then - return - end - local instances=variabledata.instances - local axis=variabledata.axis - local segments=variabledata.segments - if instances and axis then - local values - if instancespec==true then - values={} - for i=1,#axis do - values[i]={ - value=axis[i].default, - } - end - else - for i=1,#instances do - local instance=instances[i] - if cleanname(instance.subfamily)==instancespec then - values=instance.values - break - end - end - end - if values then - local factors={} - for i=1,#axis do - local a=axis[i] - factors[i]=getaxisscale(segments,a.minimum,a.default,a.maximum,values[i].value) - end - return factors - end - local values=axistofactors(hash[instancespec] or instancespec) - if values then - local factors={} - for i=1,#axis do - local a=axis[i] - local d=a.default - factors[i]=getaxisscale(segments,a.minimum,d,a.maximum,values[a.name or a.tag] or d) - end - return factors - end - end -end -local function getscales(regions,factors) - local scales={} - for i=1,#regions do - local region=regions[i] - local s=1 - for j=1,#region do - local axis=region[j] - local f=factors[j] - local start=axis.start - local peak=axis.peak - local stop=axis.stop - if start>peak or peak>stop then - elseif start<0 and stop>0 and peak~=0 then - elseif peak==0 then - elseif fstop then - s=0 - break - elseif fpeak then - s=s*(stop-f)/(stop-peak) - else - end - end - scales[i]=s - end - return scales -end -helpers.getaxisscale=getaxisscale -helpers.getfactors=getfactors -helpers.getscales=getscales -helpers.axistofactors=axistofactors -local function readvariationdata(f,storeoffset,factors) - local position=getposition(f) - setposition(f,storeoffset) - local format=readushort(f) - local regionoffset=storeoffset+readulong(f) - local nofdeltadata=readushort(f) - local deltadata=readcardinaltable(f,nofdeltadata,ulong) - setposition(f,regionoffset) - local nofaxis=readushort(f) - local nofregions=readushort(f) - local regions={} - for i=1,nofregions do - local t={} - for i=1,nofaxis do - t[i]={ - start=read2dot14(f), - peak=read2dot14(f), - stop=read2dot14(f), - } - end - regions[i]=t - end - if factors then - for i=1,nofdeltadata do - setposition(f,storeoffset+deltadata[i]) - local nofdeltasets=readushort(f) - local nofshorts=readushort(f) - local nofregions=readushort(f) - local usedregions={} - local deltas={} - for i=1,nofregions do - usedregions[i]=regions[readushort(f)+1] - end - for i=1,nofdeltasets do - local t=readintegertable(f,nofshorts,short) - for i=nofshorts+1,nofregions do - t[i]=readinteger(f) - end - deltas[i]=t - end - deltadata[i]={ - regions=usedregions, - deltas=deltas, - scales=factors and getscales(usedregions,factors) or nil, - } - end - end - setposition(f,position) - return regions,deltadata -end -helpers.readvariationdata=readvariationdata -local function readcoverage(f,offset,simple) - setposition(f,offset) - local coverageformat=readushort(f) - if coverageformat==1 then - local nofcoverage=readushort(f) - if simple then - if nofcoverage==1 then - return { readushort(f) } - elseif nofcoverage==2 then - return { readushort(f),readushort(f) } - else - return readcardinaltable(f,nofcoverage,ushort) - end - elseif nofcoverage==1 then - return { [readushort(f)]=0 } - elseif nofcoverage==2 then - return { [readushort(f)]=0,[readushort(f)]=1 } - else - local coverage={} - for i=0,nofcoverage-1 do - coverage[readushort(f)]=i - end - return coverage - end - elseif coverageformat==2 then - local nofranges=readushort(f) - local coverage={} - local n=simple and 1 or 0 - for i=1,nofranges do - local firstindex=readushort(f) - local lastindex=readushort(f) - local coverindex=readushort(f) - if simple then - for i=firstindex,lastindex do - coverage[n]=i - n=n+1 - end - else - for i=firstindex,lastindex do - coverage[i]=n - n=n+1 - end - end - end - return coverage - else - report("unknown coverage format %a ",coverageformat) - return {} - end -end -local function readclassdef(f,offset,preset) - setposition(f,offset) - local classdefformat=readushort(f) - local classdef={} - if type(preset)=="number" then - for k=0,preset-1 do - classdef[k]=1 - end - end - if classdefformat==1 then - local index=readushort(f) - local nofclassdef=readushort(f) - for i=1,nofclassdef do - classdef[index]=readushort(f)+1 - index=index+1 - end - elseif classdefformat==2 then - local nofranges=readushort(f) - local n=0 - for i=1,nofranges do - local firstindex=readushort(f) - local lastindex=readushort(f) - local class=readushort(f)+1 - for i=firstindex,lastindex do - classdef[i]=class - end - end - else - report("unknown classdef format %a ",classdefformat) - end - if type(preset)=="table" then - for k in next,preset do - if not classdef[k] then - classdef[k]=1 - end - end - end - return classdef -end -local function classtocoverage(defs) - if defs then - local list={} - for index,class in next,defs do - local c=list[class] - if c then - c[#c+1]=index - else - list[class]={ index } - end - end - return list - end -end -local skips={ [0]=0, - 1, - 1, - 2, - 1, - 2, - 2, - 3, - 2, - 2, - 3, - 2, - 3, - 3, - 4, -} -local function readvariation(f,offset) - local p=getposition(f) - setposition(f,offset) - local outer=readushort(f) - local inner=readushort(f) - local format=readushort(f) - setposition(f,p) - if format==0x8000 then - return outer,inner - end -end -local function readposition(f,format,mainoffset,getdelta) - if format==0 then - return false - end - if format==0x04 then - local h=readshort(f) - if h==0 then - return true - else - return { 0,0,h,0 } - end - end - if format==0x05 then - local x=readshort(f) - local h=readshort(f) - if x==0 and h==0 then - return true - else - return { x,0,h,0 } - end - end - if format==0x44 then - local h=readshort(f) - if getdelta then - local d=readshort(f) - if d>0 then - local outer,inner=readvariation(f,mainoffset+d) - if outer then - h=h+getdelta(outer,inner) - end - end - else - skipshort(f,1) - end - if h==0 then - return true - else - return { 0,0,h,0 } - end - end - local x=band(format,0x1)~=0 and readshort(f) or 0 - local y=band(format,0x2)~=0 and readshort(f) or 0 - local h=band(format,0x4)~=0 and readshort(f) or 0 - local v=band(format,0x8)~=0 and readshort(f) or 0 - if format>=0x10 then - local X=band(format,0x10)~=0 and skipshort(f) or 0 - local Y=band(format,0x20)~=0 and skipshort(f) or 0 - local H=band(format,0x40)~=0 and skipshort(f) or 0 - local V=band(format,0x80)~=0 and skipshort(f) or 0 - local s=skips[extract(format,4,4)] - if s>0 then - skipshort(f,s) - end - if getdelta then - if X>0 then - local outer,inner=readvariation(f,mainoffset+X) - if outer then - x=x+getdelta(outer,inner) - end - end - if Y>0 then - local outer,inner=readvariation(f,mainoffset+Y) - if outer then - y=y+getdelta(outer,inner) - end - end - if H>0 then - local outer,inner=readvariation(f,mainoffset+H) - if outer then - h=h+getdelta(outer,inner) - end - end - if V>0 then - local outer,inner=readvariation(f,mainoffset+V) - if outer then - v=v+getdelta(outer,inner) - end - end - end - return { x,y,h,v } - elseif x==0 and y==0 and h==0 and v==0 then - return true - else - return { x,y,h,v } - end -end -local function readanchor(f,offset,getdelta) - if not offset or offset==0 then - return nil - end - setposition(f,offset) - local format=readshort(f) - local x=readshort(f) - local y=readshort(f) - if format==3 then - if getdelta then - local X=readshort(f) - local Y=readshort(f) - if X>0 then - local outer,inner=readvariation(f,offset+X) - if outer then - x=x+getdelta(outer,inner) - end - end - if Y>0 then - local outer,inner=readvariation(f,offset+Y) - if outer then - y=y+getdelta(outer,inner) - end - end - else - skipshort(f,2) - end - return { x,y } - else - return { x,y } - end -end -local function readfirst(f,offset) - if offset then - setposition(f,offset) - end - return { readushort(f) } -end -local function readarray(f,offset) - if offset then - setposition(f,offset) - end - local n=readushort(f) - if n==1 then - return { readushort(f) },1 - elseif n>0 then - return readcardinaltable(f,n,ushort),n - end -end -local function readcoveragearray(f,offset,t,simple) - if not t then - return nil - end - local n=#t - if n==0 then - return nil - end - for i=1,n do - t[i]=readcoverage(f,offset+t[i],simple) - end - return t -end -local function covered(subset,all) - local used,u - for i=1,#subset do - local s=subset[i] - if all[s] then - if used then - u=u+1 - used[u]=s - else - u=1 - used={ s } - end - end - end - return used -end -local function readlookuparray(f,noflookups,nofcurrent) - local lookups={} - if noflookups>0 then - local length=0 - for i=1,noflookups do - local index=readushort(f)+1 - if index>length then - length=index - end - local lookup=readushort(f)+1 - local list=lookups[index] - if list then - list[#list+1]=lookup - else - lookups[index]={ lookup } - end - end - for index=1,length do - if not lookups[index] then - lookups[index]=false - end - end - end - return lookups -end -local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local coverage=readushort(f) - local subclasssets=readarray(f) - local rules={} - if subclasssets then - coverage=readcoverage(f,tableoffset+coverage,true) - for i=1,#subclasssets do - local offset=subclasssets[i] - if offset>0 then - local firstcoverage=coverage[i] - local rulesoffset=tableoffset+offset - local subclassrules=readarray(f,rulesoffset) - for rule=1,#subclassrules do - setposition(f,rulesoffset+subclassrules[rule]) - local nofcurrent=readushort(f) - local noflookups=readushort(f) - local current={ { firstcoverage } } - for i=2,nofcurrent do - current[i]={ readushort(f) } - end - local lookups=readlookuparray(f,noflookups,nofcurrent) - rules[#rules+1]={ - current=current, - lookups=lookups - } - end - end - end - else - report("empty subclassset in %a subtype %i","unchainedcontext",subtype) - end - return { - format="glyphs", - rules=rules, - } - elseif subtype==2 then - local coverage=readushort(f) - local currentclassdef=readushort(f) - local subclasssets=readarray(f) - local rules={} - if subclasssets then - coverage=readcoverage(f,tableoffset+coverage) - currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage) - local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs) - for class=1,#subclasssets do - local offset=subclasssets[class] - if offset>0 then - local firstcoverage=currentclasses[class] - if firstcoverage then - firstcoverage=covered(firstcoverage,coverage) - if firstcoverage then - local rulesoffset=tableoffset+offset - local subclassrules=readarray(f,rulesoffset) - for rule=1,#subclassrules do - setposition(f,rulesoffset+subclassrules[rule]) - local nofcurrent=readushort(f) - local noflookups=readushort(f) - local current={ firstcoverage } - for i=2,nofcurrent do - current[i]=currentclasses[readushort(f)+1] - end - local lookups=readlookuparray(f,noflookups,nofcurrent) - rules[#rules+1]={ - current=current, - lookups=lookups - } - end - else - report("no coverage") - end - else - report("no coverage class") - end - end - end - else - report("empty subclassset in %a subtype %i","unchainedcontext",subtype) - end - return { - format="class", - rules=rules, - } - elseif subtype==3 then - local nofglyphs=readushort(f) - local noflookups=readushort(f) - local current=readcardinaltable(f,nofglyphs,ushort) - local lookups=readlookuparray(f,noflookups,#current) - current=readcoveragearray(f,tableoffset,current,true) - return { - format="coverage", - rules={ - { - current=current, - lookups=lookups, - } - } - } - else - report("unsupported subtype %a in %a %s",subtype,"unchainedcontext",what) - end -end -local function chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local coverage=readushort(f) - local subclasssets=readarray(f) - local rules={} - if subclasssets then - coverage=readcoverage(f,tableoffset+coverage,true) - for i=1,#subclasssets do - local offset=subclasssets[i] - if offset>0 then - local firstcoverage=coverage[i] - local rulesoffset=tableoffset+offset - local subclassrules=readarray(f,rulesoffset) - for rule=1,#subclassrules do - setposition(f,rulesoffset+subclassrules[rule]) - local nofbefore=readushort(f) - local before - if nofbefore>0 then - before={} - for i=1,nofbefore do - before[i]={ readushort(f) } - end - end - local nofcurrent=readushort(f) - local current={ { firstcoverage } } - for i=2,nofcurrent do - current[i]={ readushort(f) } - end - local nofafter=readushort(f) - local after - if nofafter>0 then - after={} - for i=1,nofafter do - after[i]={ readushort(f) } - end - end - local noflookups=readushort(f) - local lookups=readlookuparray(f,noflookups,nofcurrent) - rules[#rules+1]={ - before=before, - current=current, - after=after, - lookups=lookups, - } - end - end - end - else - report("empty subclassset in %a subtype %i","chainedcontext",subtype) - end - return { - format="glyphs", - rules=rules, - } - elseif subtype==2 then - local coverage=readushort(f) - local beforeclassdef=readushort(f) - local currentclassdef=readushort(f) - local afterclassdef=readushort(f) - local subclasssets=readarray(f) - local rules={} - if subclasssets then - local coverage=readcoverage(f,tableoffset+coverage) - local beforeclassdef=readclassdef(f,tableoffset+beforeclassdef,nofglyphs) - local currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage) - local afterclassdef=readclassdef(f,tableoffset+afterclassdef,nofglyphs) - local beforeclasses=classtocoverage(beforeclassdef,fontdata.glyphs) - local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs) - local afterclasses=classtocoverage(afterclassdef,fontdata.glyphs) - for class=1,#subclasssets do - local offset=subclasssets[class] - if offset>0 then - local firstcoverage=currentclasses[class] - if firstcoverage then - firstcoverage=covered(firstcoverage,coverage) - if firstcoverage then - local rulesoffset=tableoffset+offset - local subclassrules=readarray(f,rulesoffset) - for rule=1,#subclassrules do - setposition(f,rulesoffset+subclassrules[rule]) - local nofbefore=readushort(f) - local before - if nofbefore>0 then - before={} - for i=1,nofbefore do - before[i]=beforeclasses[readushort(f)+1] - end - end - local nofcurrent=readushort(f) - local current={ firstcoverage } - for i=2,nofcurrent do - current[i]=currentclasses[readushort(f)+1] - end - local nofafter=readushort(f) - local after - if nofafter>0 then - after={} - for i=1,nofafter do - after[i]=afterclasses[readushort(f)+1] - end - end - local noflookups=readushort(f) - local lookups=readlookuparray(f,noflookups,nofcurrent) - rules[#rules+1]={ - before=before, - current=current, - after=after, - lookups=lookups, - } - end - else - report("no coverage") - end - else - report("class is not covered") - end - end - end - else - report("empty subclassset in %a subtype %i","chainedcontext",subtype) - end - return { - format="class", - rules=rules, - } - elseif subtype==3 then - local before=readarray(f) - local current=readarray(f) - local after=readarray(f) - local noflookups=readushort(f) - local lookups=readlookuparray(f,noflookups,#current) - before=readcoveragearray(f,tableoffset,before,true) - current=readcoveragearray(f,tableoffset,current,true) - after=readcoveragearray(f,tableoffset,after,true) - return { - format="coverage", - rules={ - { - before=before, - current=current, - after=after, - lookups=lookups, - } - } - } - else - report("unsupported subtype %a in %a %s",subtype,"chainedcontext",what) - end -end -local function extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,types,handlers,what) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local lookuptype=types[readushort(f)] - local faroffset=readulong(f) - local handler=handlers[lookuptype] - if handler then - return handler(f,fontdata,lookupid,tableoffset+faroffset,0,glyphs,nofglyphs),lookuptype - else - report("no handler for lookuptype %a subtype %a in %s %s",lookuptype,subtype,what,"extension") - end - else - report("unsupported subtype %a in %s %s",subtype,what,"extension") - end -end -function gsubhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local coverage=readushort(f) - local delta=readshort(f) - local coverage=readcoverage(f,tableoffset+coverage) - for index in next,coverage do - local newindex=(index+delta)%65536 - if index>nofglyphs or newindex>nofglyphs then - report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs) - coverage[index]=nil - else - coverage[index]=newindex - end - end - return { - coverage=coverage - } - elseif subtype==2 then - local coverage=readushort(f) - local nofreplacements=readushort(f) - local replacements=readcardinaltable(f,nofreplacements,ushort) - local coverage=readcoverage(f,tableoffset+coverage) - for index,newindex in next,coverage do - newindex=newindex+1 - if index>nofglyphs or newindex>nofglyphs then - report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs) - coverage[index]=nil - else - coverage[index]=replacements[newindex] - end - end - return { - coverage=coverage - } - else - report("unsupported subtype %a in %a substitution",subtype,"single") - end -end -local function sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local coverage=readushort(f) - local nofsequence=readushort(f) - local sequences=readcardinaltable(f,nofsequence,ushort) - for i=1,nofsequence do - setposition(f,tableoffset+sequences[i]) - sequences[i]=readcardinaltable(f,readushort(f),ushort) - end - local coverage=readcoverage(f,tableoffset+coverage) - for index,newindex in next,coverage do - newindex=newindex+1 - if index>nofglyphs or newindex>nofglyphs then - report("invalid index in %s format %i: %i -> %i (max %i)",what,subtype,index,newindex,nofglyphs) - coverage[index]=nil - else - coverage[index]=sequences[newindex] - end - end - return { - coverage=coverage - } - else - report("unsupported subtype %a in %a substitution",subtype,what) - end -end -function gsubhandlers.multiple(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"multiple") -end -function gsubhandlers.alternate(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"alternate") -end -function gsubhandlers.ligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local coverage=readushort(f) - local nofsets=readushort(f) - local ligatures=readcardinaltable(f,nofsets,ushort) - for i=1,nofsets do - local offset=lookupoffset+offset+ligatures[i] - setposition(f,offset) - local n=readushort(f) - if n==1 then - ligatures[i]={ offset+readushort(f) } - else - local l={} - for i=1,n do - l[i]=offset+readushort(f) - end - ligatures[i]=l - end - end - local coverage=readcoverage(f,tableoffset+coverage) - for index,newindex in next,coverage do - local hash={} - local ligatures=ligatures[newindex+1] - for i=1,#ligatures do - local offset=ligatures[i] - setposition(f,offset) - local lig=readushort(f) - local cnt=readushort(f) - local hsh=hash - for i=2,cnt do - local c=readushort(f) - local h=hsh[c] - if not h then - h={} - hsh[c]=h - end - hsh=h - end - hsh.ligature=lig - end - coverage[index]=hash - end - return { - coverage=coverage - } - else - report("unsupported subtype %a in %a substitution",subtype,"ligature") - end -end -function gsubhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"context" -end -function gsubhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"chainedcontext" -end -function gsubhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gsubtypes,gsubhandlers,"substitution") -end -function gsubhandlers.reversechainedcontextsingle(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local current=readfirst(f) - local before=readarray(f) - local after=readarray(f) - local replacements=readarray(f) - current=readcoveragearray(f,tableoffset,current,true) - before=readcoveragearray(f,tableoffset,before,true) - after=readcoveragearray(f,tableoffset,after,true) - return { - format="reversecoverage", - rules={ - { - before=before, - current=current, - after=after, - replacements=replacements, - } - } - },"reversechainedcontextsingle" - else - report("unsupported subtype %a in %a substitution",subtype,"reversechainedcontextsingle") - end -end -local function readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta) - local done={} - for i=1,#sets do - local offset=sets[i] - local reused=done[offset] - if not reused then - offset=tableoffset+offset - setposition(f,offset) - local n=readushort(f) - reused={} - for i=1,n do - reused[i]={ - readushort(f), - readposition(f,format1,offset,getdelta), - readposition(f,format2,offset,getdelta), - } - end - done[offset]=reused - end - sets[i]=reused - end - return sets -end -local function readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,mainoffset,getdelta) - local classlist1={} - for i=1,nofclasses1 do - local classlist2={} - classlist1[i]=classlist2 - for j=1,nofclasses2 do - local one=readposition(f,format1,mainoffset,getdelta) - local two=readposition(f,format2,mainoffset,getdelta) - if one or two then - classlist2[j]={ one,two } - else - classlist2[j]=false - end - end - end - return classlist1 -end -function gposhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - local getdelta=fontdata.temporary.getdelta - if subtype==1 then - local coverage=readushort(f) - local format=readushort(f) - local value=readposition(f,format,tableoffset,getdelta) - local coverage=readcoverage(f,tableoffset+coverage) - for index,newindex in next,coverage do - coverage[index]=value - end - return { - format="single", - coverage=coverage, - } - elseif subtype==2 then - local coverage=readushort(f) - local format=readushort(f) - local nofvalues=readushort(f) - local values={} - for i=1,nofvalues do - values[i]=readposition(f,format,tableoffset,getdelta) - end - local coverage=readcoverage(f,tableoffset+coverage) - for index,newindex in next,coverage do - coverage[index]=values[newindex+1] - end - return { - format="single", - coverage=coverage, - } - else - report("unsupported subtype %a in %a positioning",subtype,"single") - end -end -function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - local getdelta=fontdata.temporary.getdelta - if subtype==1 then - local coverage=readushort(f) - local format1=readushort(f) - local format2=readushort(f) - local sets=readarray(f) - sets=readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta) - coverage=readcoverage(f,tableoffset+coverage) - local shared={} - for index,newindex in next,coverage do - local set=sets[newindex+1] - local hash={} - for i=1,#set do - local value=set[i] - if value then - local other=value[1] - local share=shared[value] - if share==nil then - local first=value[2] - local second=value[3] - if first or second then - share={ first,second or nil } - else - share=false - end - shared[value]=share - end - hash[other]=share or nil - end - end - coverage[index]=hash - end - return { - shared=shared and true or nil, - format="pair", - coverage=coverage, - } - elseif subtype==2 then - local coverage=readushort(f) - local format1=readushort(f) - local format2=readushort(f) - local classdef1=readushort(f) - local classdef2=readushort(f) - local nofclasses1=readushort(f) - local nofclasses2=readushort(f) - local classlist=readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,tableoffset,getdelta) - coverage=readcoverage(f,tableoffset+coverage) - classdef1=readclassdef(f,tableoffset+classdef1,coverage) - classdef2=readclassdef(f,tableoffset+classdef2,nofglyphs) - local usedcoverage={} - local shared={} - for g1,c1 in next,classdef1 do - if coverage[g1] then - local l1=classlist[c1] - if l1 then - local hash={} - for paired,class in next,classdef2 do - local offsets=l1[class] - if offsets then - local first=offsets[1] - local second=offsets[2] - if first or second then - local s1=shared[first] - if s1==nil then - s1={} - shared[first]=s1 - end - local s2=s1[second] - if s2==nil then - s2={ first,second or nil } - s1[second]=s2 - end - hash[paired]=s2 - end - end - end - usedcoverage[g1]=hash - end - end - end - return { - shared=shared and true or nil, - format="pair", - coverage=usedcoverage, - } - elseif subtype==3 then - report("yet unsupported subtype %a in %a positioning",subtype,"pair") - else - report("unsupported subtype %a in %a positioning",subtype,"pair") - end -end -function gposhandlers.cursive(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - local getdelta=fontdata.temporary.getdelta - if subtype==1 then - local coverage=tableoffset+readushort(f) - local nofrecords=readushort(f) - local records={} - for i=1,nofrecords do - local entry=readushort(f) - local exit=readushort(f) - records[i]={ - entry~=0 and (tableoffset+entry) or false, - exit~=0 and (tableoffset+exit ) or nil, - } - end - local cc=(fontdata.temporary.cursivecount or 0)+1 - fontdata.temporary.cursivecount=cc - cc="cc-"..cc - coverage=readcoverage(f,coverage) - for i=1,nofrecords do - local r=records[i] - records[i]={ - cc, - readanchor(f,r[1],getdelta) or false, - readanchor(f,r[2],getdelta) or nil, - } - end - for index,newindex in next,coverage do - coverage[index]=records[newindex+1] - end - return { - coverage=coverage, - } - else - report("unsupported subtype %a in %a positioning",subtype,"cursive") - end -end -local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,ligature) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - local getdelta=fontdata.temporary.getdelta - if subtype==1 then - local markcoverage=tableoffset+readushort(f) - local basecoverage=tableoffset+readushort(f) - local nofclasses=readushort(f) - local markoffset=tableoffset+readushort(f) - local baseoffset=tableoffset+readushort(f) - local markcoverage=readcoverage(f,markcoverage) - local basecoverage=readcoverage(f,basecoverage,true) - setposition(f,markoffset) - local markclasses={} - local nofmarkclasses=readushort(f) - local lastanchor=fontdata.lastanchor or 0 - local usedanchors={} - for i=1,nofmarkclasses do - local class=readushort(f)+1 - local offset=readushort(f) - if offset==0 then - markclasses[i]=false - else - markclasses[i]={ class,markoffset+offset } - end - usedanchors[class]=true - end - for i=1,nofmarkclasses do - local mc=markclasses[i] - if mc then - mc[2]=readanchor(f,mc[2],getdelta) - end - end - setposition(f,baseoffset) - local nofbaserecords=readushort(f) - local baserecords={} - if ligature then - for i=1,nofbaserecords do - local offset=readushort(f) - if offset==0 then - baserecords[i]=false - else - baserecords[i]=baseoffset+offset - end - end - for i=1,nofbaserecords do - local recordoffset=baserecords[i] - if recordoffset then - setposition(f,recordoffset) - local nofcomponents=readushort(f) - local components={} - for i=1,nofcomponents do - local classes={} - for i=1,nofclasses do - local offset=readushort(f) - if offset~=0 then - classes[i]=recordoffset+offset - else - classes[i]=false - end - end - components[i]=classes - end - baserecords[i]=components - end - end - local baseclasses={} - for i=1,nofclasses do - baseclasses[i]={} - end - for i=1,nofbaserecords do - local components=baserecords[i] - if components then - local b=basecoverage[i] - for c=1,#components do - local classes=components[c] - if classes then - for i=1,nofclasses do - local anchor=readanchor(f,classes[i],getdelta) - local bclass=baseclasses[i] - local bentry=bclass[b] - if bentry then - bentry[c]=anchor - else - bclass[b]={ [c]=anchor } - end - end - end - end - end - end - for index,newindex in next,markcoverage do - markcoverage[index]=markclasses[newindex+1] or nil - end - return { - format="ligature", - baseclasses=baseclasses, - coverage=markcoverage, - } - else - for i=1,nofbaserecords do - local r={} - for j=1,nofclasses do - local offset=readushort(f) - if offset==0 then - r[j]=false - else - r[j]=baseoffset+offset - end - end - baserecords[i]=r - end - local baseclasses={} - for i=1,nofclasses do - baseclasses[i]={} - end - for i=1,nofbaserecords do - local r=baserecords[i] - local b=basecoverage[i] - for j=1,nofclasses do - baseclasses[j][b]=readanchor(f,r[j],getdelta) - end - end - for index,newindex in next,markcoverage do - markcoverage[index]=markclasses[newindex+1] or nil - end - return { - format="base", - baseclasses=baseclasses, - coverage=markcoverage, - } - end - else - report("unsupported subtype %a in",subtype) - end -end -function gposhandlers.marktobase(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) -end -function gposhandlers.marktoligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,true) -end -function gposhandlers.marktomark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) -end -function gposhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"context" -end -function gposhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"chainedcontext" -end -function gposhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gpostypes,gposhandlers,"positioning") -end -do - local plugins={} - function plugins.size(f,fontdata,tableoffset,feature) - if fontdata.designsize then - else - local function check(offset) - setposition(f,offset) - local designsize=readushort(f) - if designsize>0 then - local fontstyleid=readushort(f) - local guimenuid=readushort(f) - local minsize=readushort(f) - local maxsize=readushort(f) - if minsize==0 and maxsize==0 and fontstyleid==0 and guimenuid==0 then - minsize=designsize - maxsize=designsize - end - if designsize>=minsize and designsize<=maxsize then - return minsize,maxsize,designsize - end - end - end - local minsize,maxsize,designsize=check(tableoffset+feature.offset+feature.parameters) - if not designsize then - minsize,maxsize,designsize=check(tableoffset+feature.parameters) - if designsize then - report("bad size feature in %a, falling back to wrong offset",fontdata.filename or "?") - else - report("bad size feature in %a,",fontdata.filename or "?") - end - end - if designsize then - fontdata.minsize=minsize - fontdata.maxsize=maxsize - fontdata.designsize=designsize - end - end - end - local function reorderfeatures(fontdata,scripts,features) - local scriptlangs={} - local featurehash={} - local featureorder={} - for script,languages in next,scripts do - for language,record in next,languages do - local hash={} - local list=record.featureindices - for k=1,#list do - local index=list[k] - local feature=features[index] - local lookups=feature.lookups - local tag=feature.tag - if tag then - hash[tag]=true - end - if lookups then - for i=1,#lookups do - local lookup=lookups[i] - local o=featureorder[lookup] - if o then - local okay=true - for i=1,#o do - if o[i]==tag then - okay=false - break - end - end - if okay then - o[#o+1]=tag - end - else - featureorder[lookup]={ tag } - end - local f=featurehash[lookup] - if f then - local h=f[tag] - if h then - local s=h[script] - if s then - s[language]=true - else - h[script]={ [language]=true } - end - else - f[tag]={ [script]={ [language]=true } } - end - else - featurehash[lookup]={ [tag]={ [script]={ [language]=true } } } - end - local h=scriptlangs[tag] - if h then - local s=h[script] - if s then - s[language]=true - else - h[script]={ [language]=true } - end - else - scriptlangs[tag]={ [script]={ [language]=true } } - end - end - end - end - end - end - return scriptlangs,featurehash,featureorder - end - local function readscriplan(f,fontdata,scriptoffset) - setposition(f,scriptoffset) - local nofscripts=readushort(f) - local scripts={} - for i=1,nofscripts do - scripts[readtag(f)]=scriptoffset+readushort(f) - end - local languagesystems=setmetatableindex("table") - for script,offset in next,scripts do - setposition(f,offset) - local defaultoffset=readushort(f) - local noflanguages=readushort(f) - local languages={} - if defaultoffset>0 then - languages.dflt=languagesystems[offset+defaultoffset] - end - for i=1,noflanguages do - local language=readtag(f) - local offset=offset+readushort(f) - languages[language]=languagesystems[offset] - end - scripts[script]=languages - end - for offset,usedfeatures in next,languagesystems do - if offset>0 then - setposition(f,offset) - local featureindices={} - usedfeatures.featureindices=featureindices - usedfeatures.lookuporder=readushort(f) - usedfeatures.requiredindex=readushort(f) - local noffeatures=readushort(f) - for i=1,noffeatures do - featureindices[i]=readushort(f)+1 - end - end - end - return scripts - end - local function readfeatures(f,fontdata,featureoffset) - setposition(f,featureoffset) - local features={} - local noffeatures=readushort(f) - for i=1,noffeatures do - features[i]={ - tag=readtag(f), - offset=readushort(f) - } - end - for i=1,noffeatures do - local feature=features[i] - local offset=featureoffset+feature.offset - setposition(f,offset) - local parameters=readushort(f) - local noflookups=readushort(f) - if noflookups>0 then - local lookups=readcardinaltable(f,noflookups,ushort) - feature.lookups=lookups - for j=1,noflookups do - lookups[j]=lookups[j]+1 - end - end - if parameters>0 then - feature.parameters=parameters - local plugin=plugins[feature.tag] - if plugin then - plugin(f,fontdata,featureoffset,feature) - end - end - end - return features - end - local function readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder) - setposition(f,lookupoffset) - local noflookups=readushort(f) - local lookups=readcardinaltable(f,noflookups,ushort) - for lookupid=1,noflookups do - local offset=lookups[lookupid] - setposition(f,lookupoffset+offset) - local subtables={} - local typebits=readushort(f) - local flagbits=readushort(f) - local lookuptype=lookuptypes[typebits] - local lookupflags=lookupflags[flagbits] - local nofsubtables=readushort(f) - for j=1,nofsubtables do - subtables[j]=offset+readushort(f) - end - local markclass=band(flagbits,0x0010)~=0 - if markclass then - markclass=readushort(f) - end - local markset=rshift(flagbits,8) - if markset>0 then - markclass=markset - end - lookups[lookupid]={ - type=lookuptype, - flags=lookupflags, - name=lookupid, - subtables=subtables, - markclass=markclass, - features=featurehash[lookupid], - order=featureorder[lookupid], - } - end - return lookups - end - local f_lookupname=formatters["%s_%s_%s"] - local function resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset) - local sequences=fontdata.sequences or {} - local sublookuplist=fontdata.sublookups or {} - fontdata.sequences=sequences - fontdata.sublookups=sublookuplist - local nofsublookups=#sublookuplist - local nofsequences=#sequences - local lastsublookup=nofsublookups - local lastsequence=nofsequences - local lookupnames=lookupnames[what] - local sublookuphash={} - local sublookupcheck={} - local glyphs=fontdata.glyphs - local nofglyphs=fontdata.nofglyphs or #glyphs - local noflookups=#lookups - local lookupprefix=sub(what,2,2) - local usedlookups=false - for lookupid=1,noflookups do - local lookup=lookups[lookupid] - local lookuptype=lookup.type - local subtables=lookup.subtables - local features=lookup.features - local handler=lookuphandlers[lookuptype] - if handler then - local nofsubtables=#subtables - local order=lookup.order - local flags=lookup.flags - if flags[1] then flags[1]="mark" end - if flags[2] then flags[2]="ligature" end - if flags[3] then flags[3]="base" end - local markclass=lookup.markclass - if nofsubtables>0 then - local steps={} - local nofsteps=0 - local oldtype=nil - for s=1,nofsubtables do - local step,lt=handler(f,fontdata,lookupid,lookupoffset,subtables[s],glyphs,nofglyphs) - if lt then - lookuptype=lt - if oldtype and lt~=oldtype then - report("messy %s lookup type %a and %a",what,lookuptype,oldtype) - end - oldtype=lookuptype - end - if not step then - report("unsupported %s lookup type %a",what,lookuptype) - else - nofsteps=nofsteps+1 - steps[nofsteps]=step - local rules=step.rules - if rules then - for i=1,#rules do - local rule=rules[i] - local before=rule.before - local current=rule.current - local after=rule.after - local replacements=rule.replacements - if before then - for i=1,#before do - before[i]=tohash(before[i]) - end - rule.before=reversed(before) - end - if current then - if replacements then - local first=current[1] - local hash={} - local repl={} - for i=1,#first do - local c=first[i] - hash[c]=true - repl[c]=replacements[i] - end - rule.current={ hash } - rule.replacements=repl - else - for i=1,#current do - current[i]=tohash(current[i]) - end - end - else - end - if after then - for i=1,#after do - after[i]=tohash(after[i]) - end - end - if usedlookups then - local lookups=rule.lookups - if lookups then - for k,v in next,lookups do - if v then - for k,v in next,v do - usedlookups[v]=usedlookups[v]+1 - end - end - end - end - end - end - end - end - end - if nofsteps~=nofsubtables then - report("bogus subtables removed in %s lookup type %a",what,lookuptype) - end - lookuptype=lookupnames[lookuptype] or lookuptype - if features then - nofsequences=nofsequences+1 - local l={ - index=nofsequences, - name=f_lookupname(lookupprefix,"s",lookupid+lookupidoffset), - steps=steps, - nofsteps=nofsteps, - type=lookuptype, - markclass=markclass or nil, - flags=flags, - order=order, - features=features, - } - sequences[nofsequences]=l - lookup.done=l - else - nofsublookups=nofsublookups+1 - local l={ - index=nofsublookups, - name=f_lookupname(lookupprefix,"l",lookupid+lookupidoffset), - steps=steps, - nofsteps=nofsteps, - type=lookuptype, - markclass=markclass or nil, - flags=flags, - } - sublookuplist[nofsublookups]=l - sublookuphash[lookupid]=nofsublookups - sublookupcheck[lookupid]=0 - lookup.done=l - end - else - report("no subtables for lookup %a",lookupid) - end - else - report("no handler for lookup %a with type %a",lookupid,lookuptype) - end - end - if usedlookups then - report("used %s lookups: % t",what,sortedkeys(usedlookups)) - end - local reported={} - local function report_issue(i,what,sequence,kind) - local name=sequence.name - if not reported[name] then - report("rule %i in %s lookup %a has %s lookups",i,what,name,kind) - reported[name]=true - end - end - for i=lastsequence+1,nofsequences do - local sequence=sequences[i] - local steps=sequence.steps - for i=1,#steps do - local step=steps[i] - local rules=step.rules - if rules then - for i=1,#rules do - local rule=rules[i] - local rlookups=rule.lookups - if not rlookups then - report_issue(i,what,sequence,"no") - elseif not next(rlookups) then - rule.lookups=nil - else - local length=#rlookups - for index=1,length do - local lookuplist=rlookups[index] - if lookuplist then - local length=#lookuplist - local found={} - local noffound=0 - for index=1,length do - local lookupid=lookuplist[index] - if lookupid then - local h=sublookuphash[lookupid] - if not h then - local lookup=lookups[lookupid] - if lookup then - local d=lookup.done - if d then - nofsublookups=nofsublookups+1 - local l={ - index=nofsublookups, - name=f_lookupname(lookupprefix,"d",lookupid+lookupidoffset), - derived=true, - steps=d.steps, - nofsteps=d.nofsteps, - type=d.lookuptype or "gsub_single", - markclass=d.markclass or nil, - flags=d.flags, - } - sublookuplist[nofsublookups]=copy(l) - sublookuphash[lookupid]=nofsublookups - sublookupcheck[lookupid]=1 - h=nofsublookups - else - report_issue(i,what,sequence,"missing") - rule.lookups=nil - break - end - else - report_issue(i,what,sequence,"bad") - rule.lookups=nil - break - end - else - sublookupcheck[lookupid]=sublookupcheck[lookupid]+1 - end - if h then - noffound=noffound+1 - found[noffound]=h - end - end - end - rlookups[index]=noffound>0 and found or false - else - rlookups[index]=false - end - end - end - end - end - end - end - for i,n in sortedhash(sublookupcheck) do - local l=lookups[i] - local t=l.type - if n==0 and t~="extension" then - local d=l.done - report("%s lookup %s of type %a is not used",what,d and d.name or l.name,t) - end - end - end - local function loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder) - setposition(f,variationsoffset) - local version=readulong(f) - local nofrecords=readulong(f) - local records={} - for i=1,nofrecords do - records[i]={ - conditions=readulong(f), - substitutions=readulong(f), - } - end - for i=1,nofrecords do - local record=records[i] - local offset=record.conditions - if offset==0 then - record.condition=nil - record.matchtype="always" - else - local offset=variationsoffset+offset - setposition(f,offset) - local nofconditions=readushort(f) - local conditions={} - for i=1,nofconditions do - conditions[i]=offset+readulong(f) - end - record.conditions=conditions - record.matchtype="condition" - end - end - for i=1,nofrecords do - local record=records[i] - if record.matchtype=="condition" then - local conditions=record.conditions - for i=1,#conditions do - setposition(f,conditions[i]) - conditions[i]={ - format=readushort(f), - axis=readushort(f), - minvalue=read2dot14(f), - maxvalue=read2dot14(f), - } - end - end - end - for i=1,nofrecords do - local record=records[i] - local offset=record.substitutions - if offset==0 then - record.substitutions={} - else - setposition(f,variationsoffset+offset) - local version=readulong(f) - local nofsubstitutions=readushort(f) - local substitutions={} - for i=1,nofsubstitutions do - substitutions[readushort(f)]=readulong(f) - end - for index,alternates in sortedhash(substitutions) do - if index==0 then - record.substitutions=false - else - local tableoffset=variationsoffset+offset+alternates - setposition(f,tableoffset) - local parameters=readulong(f) - local noflookups=readushort(f) - local lookups=readcardinaltable(f,noflookups,ushort) - record.substitutions=lookups - end - end - end - end - setvariabledata(fontdata,"features",records) - end - local function readscripts(f,fontdata,what,lookuptypes,lookuphandlers,lookupstoo) - local tableoffset=gotodatatable(f,fontdata,what,true) - if tableoffset then - local version=readulong(f) - local scriptoffset=tableoffset+readushort(f) - local featureoffset=tableoffset+readushort(f) - local lookupoffset=tableoffset+readushort(f) - local variationsoffset=version>0x00010000 and (tableoffset+readulong(f)) or 0 - if not scriptoffset then - return - end - local scripts=readscriplan(f,fontdata,scriptoffset) - local features=readfeatures(f,fontdata,featureoffset) - local scriptlangs,featurehash,featureorder=reorderfeatures(fontdata,scripts,features) - if fontdata.features then - fontdata.features[what]=scriptlangs - else - fontdata.features={ [what]=scriptlangs } - end - if not lookupstoo then - return - end - local lookups=readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder) - if lookups then - resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset) - end - if variationsoffset>0 then - loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder) - end - end - end - local function checkkerns(f,fontdata,specification) - local datatable=fontdata.tables.kern - if not datatable then - return - end - local features=fontdata.features - local gposfeatures=features and features.gpos - local name - if not gposfeatures or not gposfeatures.kern then - name="kern" - elseif specification.globalkerns then - name="globalkern" - else - report("ignoring global kern table, using gpos kern feature") - return - end - setposition(f,datatable.offset) - local version=readushort(f) - local noftables=readushort(f) - if noftables>1 then - report("adding global kern table as gpos feature %a",name) - local kerns=setmetatableindex("table") - for i=1,noftables do - local version=readushort(f) - local length=readushort(f) - local coverage=readushort(f) - local format=rshift(coverage,8) - if format==0 then - local nofpairs=readushort(f) - local searchrange=readushort(f) - local entryselector=readushort(f) - local rangeshift=readushort(f) - for i=1,nofpairs do - kerns[readushort(f)][readushort(f)]=readfword(f) - end - elseif format==2 then - else - end - end - local feature={ dflt={ dflt=true } } - if not features then - fontdata.features={ gpos={ [name]=feature } } - elseif not gposfeatures then - fontdata.features.gpos={ [name]=feature } - else - gposfeatures[name]=feature - end - local sequences=fontdata.sequences - if not sequences then - sequences={} - fontdata.sequences=sequences - end - local nofsequences=#sequences+1 - sequences[nofsequences]={ - index=nofsequences, - name=name, - steps={ - { - coverage=kerns, - format="kern", - }, - }, - nofsteps=1, - type="gpos_pair", - flags={ false,false,false,false }, - order={ name }, - features={ [name]=feature }, - } - else - report("ignoring empty kern table of feature %a",name) - end - end - function readers.gsub(f,fontdata,specification) - if specification.details then - readscripts(f,fontdata,"gsub",gsubtypes,gsubhandlers,specification.lookups) - end - end - function readers.gpos(f,fontdata,specification) - if specification.details then - readscripts(f,fontdata,"gpos",gpostypes,gposhandlers,specification.lookups) - if specification.lookups then - checkkerns(f,fontdata,specification) - end - end - end -end -function readers.gdef(f,fontdata,specification) - if not specification.glyphs then - return - end - local datatable=fontdata.tables.gdef - if datatable then - local tableoffset=datatable.offset - setposition(f,tableoffset) - local version=readulong(f) - local classoffset=readushort(f) - local attachmentoffset=readushort(f) - local ligaturecarets=readushort(f) - local markclassoffset=readushort(f) - local marksetsoffset=version>=0x00010002 and readushort(f) or 0 - local varsetsoffset=version>=0x00010003 and readulong(f) or 0 - local glyphs=fontdata.glyphs - local marks={} - local markclasses=setmetatableindex("table") - local marksets=setmetatableindex("table") - fontdata.marks=marks - fontdata.markclasses=markclasses - fontdata.marksets=marksets - if classoffset~=0 then - setposition(f,tableoffset+classoffset) - local classformat=readushort(f) - if classformat==1 then - local firstindex=readushort(f) - local lastindex=firstindex+readushort(f)-1 - for index=firstindex,lastindex do - local class=classes[readushort(f)] - if class=="mark" then - marks[index]=true - end - glyphs[index].class=class - end - elseif classformat==2 then - local nofranges=readushort(f) - for i=1,nofranges do - local firstindex=readushort(f) - local lastindex=readushort(f) - local class=classes[readushort(f)] - if class then - for index=firstindex,lastindex do - glyphs[index].class=class - if class=="mark" then - marks[index]=true - end - end - end - end - end - end - if markclassoffset~=0 then - setposition(f,tableoffset+markclassoffset) - local classformat=readushort(f) - if classformat==1 then - local firstindex=readushort(f) - local lastindex=firstindex+readushort(f)-1 - for index=firstindex,lastindex do - markclasses[readushort(f)][index]=true - end - elseif classformat==2 then - local nofranges=readushort(f) - for i=1,nofranges do - local firstindex=readushort(f) - local lastindex=readushort(f) - local class=markclasses[readushort(f)] - for index=firstindex,lastindex do - class[index]=true - end - end - end - end - if marksetsoffset~=0 then - marksetsoffset=tableoffset+marksetsoffset - setposition(f,marksetsoffset) - local format=readushort(f) - if format==1 then - local nofsets=readushort(f) - local sets=readcardinaltable(f,nofsets,ulong) - for i=1,nofsets do - local offset=sets[i] - if offset~=0 then - marksets[i]=readcoverage(f,marksetsoffset+offset) - end - end - end - end - local factors=specification.factors - if (specification.variable or factors) and varsetsoffset~=0 then - local regions,deltas=readvariationdata(f,tableoffset+varsetsoffset,factors) - if factors then - fontdata.temporary.getdelta=function(outer,inner) - local delta=deltas[outer+1] - if delta then - local d=delta.deltas[inner+1] - if d then - local scales=delta.scales - local dd=0 - for i=1,#scales do - local di=d[i] - if di then - dd=dd+scales[i]*di - else - break - end - end - return round(dd) - end - end - return 0 - end - end - end - end -end -local function readmathvalue(f) - local v=readshort(f) - skipshort(f,1) - return v -end -local function readmathconstants(f,fontdata,offset) - setposition(f,offset) - fontdata.mathconstants={ - ScriptPercentScaleDown=readshort(f), - ScriptScriptPercentScaleDown=readshort(f), - DelimitedSubFormulaMinHeight=readushort(f), - DisplayOperatorMinHeight=readushort(f), - MathLeading=readmathvalue(f), - AxisHeight=readmathvalue(f), - AccentBaseHeight=readmathvalue(f), - FlattenedAccentBaseHeight=readmathvalue(f), - SubscriptShiftDown=readmathvalue(f), - SubscriptTopMax=readmathvalue(f), - SubscriptBaselineDropMin=readmathvalue(f), - SuperscriptShiftUp=readmathvalue(f), - SuperscriptShiftUpCramped=readmathvalue(f), - SuperscriptBottomMin=readmathvalue(f), - SuperscriptBaselineDropMax=readmathvalue(f), - SubSuperscriptGapMin=readmathvalue(f), - SuperscriptBottomMaxWithSubscript=readmathvalue(f), - SpaceAfterScript=readmathvalue(f), - UpperLimitGapMin=readmathvalue(f), - UpperLimitBaselineRiseMin=readmathvalue(f), - LowerLimitGapMin=readmathvalue(f), - LowerLimitBaselineDropMin=readmathvalue(f), - StackTopShiftUp=readmathvalue(f), - StackTopDisplayStyleShiftUp=readmathvalue(f), - StackBottomShiftDown=readmathvalue(f), - StackBottomDisplayStyleShiftDown=readmathvalue(f), - StackGapMin=readmathvalue(f), - StackDisplayStyleGapMin=readmathvalue(f), - StretchStackTopShiftUp=readmathvalue(f), - StretchStackBottomShiftDown=readmathvalue(f), - StretchStackGapAboveMin=readmathvalue(f), - StretchStackGapBelowMin=readmathvalue(f), - FractionNumeratorShiftUp=readmathvalue(f), - FractionNumeratorDisplayStyleShiftUp=readmathvalue(f), - FractionDenominatorShiftDown=readmathvalue(f), - FractionDenominatorDisplayStyleShiftDown=readmathvalue(f), - FractionNumeratorGapMin=readmathvalue(f), - FractionNumeratorDisplayStyleGapMin=readmathvalue(f), - FractionRuleThickness=readmathvalue(f), - FractionDenominatorGapMin=readmathvalue(f), - FractionDenominatorDisplayStyleGapMin=readmathvalue(f), - SkewedFractionHorizontalGap=readmathvalue(f), - SkewedFractionVerticalGap=readmathvalue(f), - OverbarVerticalGap=readmathvalue(f), - OverbarRuleThickness=readmathvalue(f), - OverbarExtraAscender=readmathvalue(f), - UnderbarVerticalGap=readmathvalue(f), - UnderbarRuleThickness=readmathvalue(f), - UnderbarExtraDescender=readmathvalue(f), - RadicalVerticalGap=readmathvalue(f), - RadicalDisplayStyleVerticalGap=readmathvalue(f), - RadicalRuleThickness=readmathvalue(f), - RadicalExtraAscender=readmathvalue(f), - RadicalKernBeforeDegree=readmathvalue(f), - RadicalKernAfterDegree=readmathvalue(f), - RadicalDegreeBottomRaisePercent=readshort(f), - } -end -local function readmathglyphinfo(f,fontdata,offset) - setposition(f,offset) - local italics=readushort(f) - local accents=readushort(f) - local extensions=readushort(f) - local kerns=readushort(f) - local glyphs=fontdata.glyphs - if italics~=0 then - setposition(f,offset+italics) - local coverage=readushort(f) - local nofglyphs=readushort(f) - coverage=readcoverage(f,offset+italics+coverage,true) - setposition(f,offset+italics+4) - for i=1,nofglyphs do - local italic=readmathvalue(f) - if italic~=0 then - local glyph=glyphs[coverage[i]] - local math=glyph.math - if not math then - glyph.math={ italic=italic } - else - math.italic=italic - end - end - end - fontdata.hasitalics=true - end - if accents~=0 then - setposition(f,offset+accents) - local coverage=readushort(f) - local nofglyphs=readushort(f) - coverage=readcoverage(f,offset+accents+coverage,true) - setposition(f,offset+accents+4) - for i=1,nofglyphs do - local accent=readmathvalue(f) - if accent~=0 then - local glyph=glyphs[coverage[i]] - local math=glyph.math - if not math then - glyph.math={ accent=accent } - else - math.accent=accent - end - end - end - end - if extensions~=0 then - setposition(f,offset+extensions) - end - if kerns~=0 then - local kernoffset=offset+kerns - setposition(f,kernoffset) - local coverage=readushort(f) - local nofglyphs=readushort(f) - if nofglyphs>0 then - local function get(offset) - setposition(f,kernoffset+offset) - local n=readushort(f) - if n==0 then - local k=readmathvalue(f) - if k==0 then - else - return { { kern=k } } - end - else - local l={} - for i=1,n do - l[i]={ height=readmathvalue(f) } - end - for i=1,n do - l[i].kern=readmathvalue(f) - end - l[n+1]={ kern=readmathvalue(f) } - return l - end - end - local kernsets={} - for i=1,nofglyphs do - local topright=readushort(f) - local topleft=readushort(f) - local bottomright=readushort(f) - local bottomleft=readushort(f) - kernsets[i]={ - topright=topright~=0 and topright or nil, - topleft=topleft~=0 and topleft or nil, - bottomright=bottomright~=0 and bottomright or nil, - bottomleft=bottomleft~=0 and bottomleft or nil, - } - end - coverage=readcoverage(f,kernoffset+coverage,true) - for i=1,nofglyphs do - local kernset=kernsets[i] - if next(kernset) then - local k=kernset.topright if k then kernset.topright=get(k) end - local k=kernset.topleft if k then kernset.topleft=get(k) end - local k=kernset.bottomright if k then kernset.bottomright=get(k) end - local k=kernset.bottomleft if k then kernset.bottomleft=get(k) end - if next(kernset) then - local glyph=glyphs[coverage[i]] - local math=glyph.math - if math then - math.kerns=kernset - else - glyph.math={ kerns=kernset } - end - end - end - end - end - end -end -local function readmathvariants(f,fontdata,offset) - setposition(f,offset) - local glyphs=fontdata.glyphs - local minoverlap=readushort(f) - local vcoverage=readushort(f) - local hcoverage=readushort(f) - local vnofglyphs=readushort(f) - local hnofglyphs=readushort(f) - local vconstruction=readcardinaltable(f,vnofglyphs,ushort) - local hconstruction=readcardinaltable(f,hnofglyphs,ushort) - fontdata.mathconstants.MinConnectorOverlap=minoverlap - local function get(offset,coverage,nofglyphs,construction,kvariants,kparts,kitalic) - if coverage~=0 and nofglyphs>0 then - local coverage=readcoverage(f,offset+coverage,true) - for i=1,nofglyphs do - local c=construction[i] - if c~=0 then - local index=coverage[i] - local glyph=glyphs[index] - local math=glyph.math - setposition(f,offset+c) - local assembly=readushort(f) - local nofvariants=readushort(f) - if nofvariants>0 then - local variants,v=nil,0 - for i=1,nofvariants do - local variant=readushort(f) - if variant==index then - elseif variants then - v=v+1 - variants[v]=variant - else - v=1 - variants={ variant } - end - skipshort(f) - end - if not variants then - elseif not math then - math={ [kvariants]=variants } - glyph.math=math - else - math[kvariants]=variants - end - end - if assembly~=0 then - setposition(f,offset+c+assembly) - local italic=readmathvalue(f) - local nofparts=readushort(f) - local parts={} - for i=1,nofparts do - local p={ - glyph=readushort(f), - start=readushort(f), - ["end"]=readushort(f), - advance=readushort(f), - } - local flags=readushort(f) - if band(flags,0x0001)~=0 then - p.extender=1 - end - parts[i]=p - end - if not math then - math={ - [kparts]=parts - } - glyph.math=math - else - math[kparts]=parts - end - if italic and italic~=0 then - math[kitalic]=italic - end - end - end - end - end - end - get(offset,vcoverage,vnofglyphs,vconstruction,"vvariants","vparts","vitalic") - get(offset,hcoverage,hnofglyphs,hconstruction,"hvariants","hparts","hitalic") -end -function readers.math(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"math",specification.glyphs) - if tableoffset then - local version=readulong(f) - local constants=readushort(f) - local glyphinfo=readushort(f) - local variants=readushort(f) - if constants==0 then - report("the math table of %a has no constants",fontdata.filename) - else - readmathconstants(f,fontdata,tableoffset+constants) - end - if glyphinfo~=0 then - readmathglyphinfo(f,fontdata,tableoffset+glyphinfo) - end - if variants~=0 then - readmathvariants(f,fontdata,tableoffset+variants) - end - end -end -function readers.colr(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"colr",specification.glyphs) - if tableoffset then - local version=readushort(f) - if version~=0 then - report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"colr",fontdata.filename) - return - end - if not fontdata.tables.cpal then - report("color table %a in font %a has no mandate %a table","colr",fontdata.filename,"cpal") - fontdata.colorpalettes={} - end - local glyphs=fontdata.glyphs - local nofglyphs=readushort(f) - local baseoffset=readulong(f) - local layeroffset=readulong(f) - local noflayers=readushort(f) - local layerrecords={} - local maxclass=0 - setposition(f,tableoffset+layeroffset) - for i=1,noflayers do - local slot=readushort(f) - local class=readushort(f) - if class<0xFFFF then - class=class+1 - if class>maxclass then - maxclass=class - end - end - layerrecords[i]={ - slot=slot, - class=class, - } - end - fontdata.maxcolorclass=maxclass - setposition(f,tableoffset+baseoffset) - for i=0,nofglyphs-1 do - local glyphindex=readushort(f) - local firstlayer=readushort(f) - local noflayers=readushort(f) - local t={} - for i=1,noflayers do - t[i]=layerrecords[firstlayer+i] - end - glyphs[glyphindex].colors=t - end - end - fontdata.hascolor=true -end -function readers.cpal(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"cpal",specification.glyphs) - if tableoffset then - local version=readushort(f) - local nofpaletteentries=readushort(f) - local nofpalettes=readushort(f) - local nofcolorrecords=readushort(f) - local firstcoloroffset=readulong(f) - local colorrecords={} - local palettes=readcardinaltable(f,nofpalettes,ushort) - if version==1 then - local palettettypesoffset=readulong(f) - local palettelabelsoffset=readulong(f) - local paletteentryoffset=readulong(f) - end - setposition(f,tableoffset+firstcoloroffset) - for i=1,nofcolorrecords do - local b,g,r,a=readbytes(f,4) - colorrecords[i]={ - r,g,b,a~=255 and a or nil, - } - end - for i=1,nofpalettes do - local p={} - local o=palettes[i] - for j=1,nofpaletteentries do - p[j]=colorrecords[o+j] - end - palettes[i]=p - end - fontdata.colorpalettes=palettes - end -end -local compress=gzip and gzip.compress -local compressed=compress and gzip.compressed -function readers.svg(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"svg",specification.glyphs) - if tableoffset then - local version=readushort(f) - local glyphs=fontdata.glyphs - local indexoffset=tableoffset+readulong(f) - local reserved=readulong(f) - setposition(f,indexoffset) - local nofentries=readushort(f) - local entries={} - for i=1,nofentries do - entries[i]={ - first=readushort(f), - last=readushort(f), - offset=indexoffset+readulong(f), - length=readulong(f), - } - end - for i=1,nofentries do - local entry=entries[i] - setposition(f,entry.offset) - local data=readstring(f,entry.length) - if compressed and not compressed(data) then - data=compress(data) - end - entries[i]={ - first=entry.first, - last=entry.last, - data=data - } - end - fontdata.svgshapes=entries - end - fontdata.hascolor=true -end -function readers.sbix(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"sbix",specification.glyphs) - if tableoffset then - local version=readushort(f) - local flags=readushort(f) - local nofstrikes=readulong(f) - local strikes={} - local nofglyphs=fontdata.nofglyphs - for i=1,nofstrikes do - strikes[i]=readulong(f) - end - local shapes={} - local done=0 - for i=1,nofstrikes do - local strikeoffset=strikes[i]+tableoffset - setposition(f,strikeoffset) - strikes[i]={ - ppem=readushort(f), - ppi=readushort(f), - offset=strikeoffset - } - end - sort(strikes,function(a,b) - if b.ppem==a.ppem then - return b.ppi0 or fonts.handlers.typethree - for i=1,nofstrikes do - local strike=strikes[i] - local strikeppem=strike.ppem - local strikeppi=strike.ppi - local strikeoffset=strike.offset - setposition(f,strikeoffset) - for i=0,nofglyphs do - glyphs[i]=readulong(f) - end - local glyphoffset=glyphs[0] - for i=0,nofglyphs-1 do - local nextoffset=glyphs[i+1] - if not shapes[i] then - local datasize=nextoffset-glyphoffset - if datasize>0 then - setposition(f,strikeoffset+glyphoffset) - local x=readshort(f) - local y=readshort(f) - local tag=readtag(f) - local size=datasize-8 - local data=nil - local offset=nil - if delayed then - offset=getposition(f) - data=nil - else - data=readstring(f,size) - size=nil - end - shapes[i]={ - x=x, - y=y, - o=offset, - s=size, - data=data, - } - done=done+1 - if done==nofglyphs then - break - end - end - end - glyphoffset=nextoffset - end - end - fontdata.pngshapes=shapes - end -end -do - local function getmetrics(f) - return { - ascender=readinteger(f), - descender=readinteger(f), - widthmax=readuinteger(f), - caretslopedumerator=readinteger(f), - caretslopedenominator=readinteger(f), - caretoffset=readinteger(f), - minorigin=readinteger(f), - minadvance=readinteger(f), - maxbefore=readinteger(f), - minafter=readinteger(f), - pad1=readinteger(f), - pad2=readinteger(f), - } - end - local function getbigmetrics(f) - return { - height=readuinteger(f), - width=readuinteger(f), - horiBearingX=readinteger(f), - horiBearingY=readinteger(f), - horiAdvance=readuinteger(f), - vertBearingX=readinteger(f), - vertBearingY=readinteger(f), - vertAdvance=readuinteger(f), - } - end - local function getsmallmetrics(f) - return { - height=readuinteger(f), - width=readuinteger(f), - bearingX=readinteger(f), - bearingY=readinteger(f), - advance=readuinteger(f), - } - end - function readers.cblc(f,fontdata,specification) - local ctdttableoffset=gotodatatable(f,fontdata,"cbdt",specification.glyphs) - if not ctdttableoffset then - return - end - local cblctableoffset=gotodatatable(f,fontdata,"cblc",specification.glyphs) - if cblctableoffset then - local majorversion=readushort(f) - local minorversion=readushort(f) - local nofsizetables=readulong(f) - local sizetables={} - local shapes={} - local subtables={} - for i=1,nofsizetables do - sizetables[i]={ - subtables=readulong(f), - indexsize=readulong(f), - nofsubtables=readulong(f), - colorref=readulong(f), - hormetrics=getmetrics(f), - vermetrics=getmetrics(f), - firstindex=readushort(f), - lastindex=readushort(f), - ppemx=readbyte(f), - ppemy=readbyte(f), - bitdepth=readbyte(f), - flags=readbyte(f), - } - end - sort(sizetables,function(a,b) - if b.ppemx==a.ppemx then - return b.bitdepth0 or fonts.handlers.typethree - for index,subtable in sortedhash(shapes) do - if type(subtable)=="table" then - local data=nil - local size=nil - local metrics=default - local format=subtable.format - local offset=subtable.offsets[index] - setposition(f,offset) - if format==17 then - metrics=getsmallmetrics(f) - size=true - elseif format==18 then - metrics=getbigmetrics(f) - size=true - elseif format==19 then - metrics=subtable.metrics - size=true - else - end - if size then - size=readulong(f) - if delayed then - offset=getposition(f) - data=nil - else - offset=nil - data=readstring(f,size) - size=nil - end - else - offset=nil - end - local x=metrics.width - local y=metrics.height - shapes[index]={ - x=x, - y=y, - o=offset, - s=size, - data=data, - } - local glyph=glyphs[index] - if not glyph.boundingbox then - local width=glyph.width - local height=width*y/x - glyph.boundingbox={ 0,0,width,height } - end - else - shapes[index]={ - x=0, - y=0, - data="", - } - end - end - fontdata.pngshapes=shapes - end - end - function readers.cbdt(f,fontdata,specification) - end -end -function readers.stat(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"stat",true) - if tableoffset then - local extras=fontdata.extras - local version=readulong(f) - local axissize=readushort(f) - local nofaxis=readushort(f) - local axisoffset=readulong(f) - local nofvalues=readushort(f) - local valuesoffset=readulong(f) - local fallbackname=extras[readushort(f)] - local axis={} - local values={} - setposition(f,tableoffset+axisoffset) - for i=1,nofaxis do - local tag=readtag(f) - axis[i]={ - tag=tag, - name=lower(extras[readushort(f)] or tag), - ordering=readushort(f), - variants={} - } - end - setposition(f,tableoffset+valuesoffset) - for i=1,nofvalues do - values[i]=readushort(f) - end - for i=1,nofvalues do - setposition(f,tableoffset+valuesoffset+values[i]) - local format=readushort(f) - local index=readushort(f)+1 - local flags=readushort(f) - local name=lower(extras[readushort(f)] or "no name") - local value=readfixed(f) - local variant - if format==1 then - variant={ - flags=flags, - name=name, - value=value, - } - elseif format==2 then - variant={ - flags=flags, - name=name, - value=value, - minimum=readfixed(f), - maximum=readfixed(f), - } - elseif format==3 then - variant={ - flags=flags, - name=name, - value=value, - link=readfixed(f), - } - end - insert(axis[index].variants,variant) - end - sort(axis,function(a,b) - return a.ordering=lastto then - else - values[#values+1]={ from,to } - lastfrom,lastto=from,to - end - end - nofvalues=#values - if nofvalues>2 then - local some=values[1] - if some[1]==-1 and some[2]==-1 then - some=values[nofvalues] - if some[1]==1 and some[2]==1 then - for i=2,nofvalues-1 do - some=values[i] - if some[1]==0 and some[2]==0 then - return values - end - end - end - end - end - return false - end - local version=readulong(f) - local reserved=readushort(f) - local nofaxis=readushort(f) - local segments={} - for i=1,nofaxis do - segments[i]=collect() - end - setvariabledata(fontdata,"segments",segments) - end -end -function readers.fvar(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"fvar",true) - if tableoffset then - local version=readulong(f) - local offsettoaxis=tableoffset+readushort(f) - local reserved=skipshort(f) - local nofaxis=readushort(f) - local sizeofaxis=readushort(f) - local nofinstances=readushort(f) - local sizeofinstances=readushort(f) - local extras=fontdata.extras - local axis={} - local instances={} - setposition(f,offsettoaxis) - for i=1,nofaxis do - axis[i]={ - tag=readtag(f), - minimum=readfixed(f), - default=readfixed(f), - maximum=readfixed(f), - flags=readushort(f), - name=lower(extras[readushort(f)] or "bad name"), - } - local n=sizeofaxis-20 - if n>0 then - skipbytes(f,n) - elseif n<0 then - end - end - local nofbytes=2+2+2+nofaxis*4 - local readpsname=nofbytes<=sizeofinstances - local skippable=sizeofinstances-nofbytes - for i=1,nofinstances do - local subfamid=readushort(f) - local flags=readushort(f) - local values={} - for i=1,nofaxis do - values[i]={ - axis=axis[i].tag, - value=readfixed(f), - } - end - local psnameid=readpsname and readushort(f) or 0xFFFF - if subfamid==2 or subfamid==17 then - elseif subfamid==0xFFFF then - subfamid=nil - elseif subfamid<=256 or subfamid>=32768 then - subfamid=nil - end - if psnameid==6 then - elseif psnameid==0xFFFF then - psnameid=nil - elseif psnameid<=256 or psnameid>=32768 then - psnameid=nil - end - instances[i]={ - subfamily=extras[subfamid], - psname=psnameid and extras[psnameid] or nil, - values=values, - } - if skippable>0 then - skipbytes(f,skippable) - end - end - setvariabledata(fontdata,"axis",axis) - setvariabledata(fontdata,"instances",instances) - end -end -function readers.hvar(f,fontdata,specification) - local factors=specification.factors - if not factors then - return - end - local tableoffset=gotodatatable(f,fontdata,"hvar",specification.variable) - if not tableoffset then - return - end - local version=readulong(f) - local variationoffset=tableoffset+readulong(f) - local advanceoffset=tableoffset+readulong(f) - local lsboffset=tableoffset+readulong(f) - local rsboffset=tableoffset+readulong(f) - local regions={} - local variations={} - local innerindex={} - local outerindex={} - if variationoffset>0 then - regions,deltas=readvariationdata(f,variationoffset,factors) - end - if not regions then - return - end - if advanceoffset>0 then - setposition(f,advanceoffset) - local format=readushort(f) - local mapcount=readushort(f) - local entrysize=rshift(band(format,0x0030),4)+1 - local nofinnerbits=band(format,0x000F)+1 - local innermask=lshift(1,nofinnerbits)-1 - local readcardinal=read_cardinal[entrysize] - for i=0,mapcount-1 do - local mapdata=readcardinal(f) - outerindex[i]=rshift(mapdata,nofinnerbits) - innerindex[i]=band(mapdata,innermask) - end - setvariabledata(fontdata,"hvarwidths",true) - local glyphs=fontdata.glyphs - for i=0,fontdata.nofglyphs-1 do - local glyph=glyphs[i] - local width=glyph.width - if width then - local outer=outerindex[i] or 0 - local inner=innerindex[i] or i - if outer and inner then - local delta=deltas[outer+1] - if delta then - local d=delta.deltas[inner+1] - if d then - local scales=delta.scales - local deltaw=0 - for i=1,#scales do - local di=d[i] - if di then - deltaw=deltaw+scales[i]*di - else - break - end - end - glyph.width=width+round(deltaw) - end - end - end - end - end - end -end -function readers.vvar(f,fontdata,specification) - if not specification.variable then - return - end -end -function readers.mvar(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"mvar",specification.variable) - if tableoffset then - local version=readulong(f) - local reserved=skipshort(f,1) - local recordsize=readushort(f) - local nofrecords=readushort(f) - local offsettostore=tableoffset+readushort(f) - local dimensions={} - local factors=specification.factors - if factors then - local regions,deltas=readvariationdata(f,offsettostore,factors) - for i=1,nofrecords do - local tag=readtag(f) - local var=variabletags[tag] - if var then - local outer=readushort(f) - local inner=readushort(f) - local delta=deltas[outer+1] - if delta then - local d=delta.deltas[inner+1] - if d then - local scales=delta.scales - local dd=0 - for i=1,#scales do - dd=dd+scales[i]*d[i] - end - var(fontdata,round(dd)) - end - end - else - skipshort(f,2) - end - if recordsize>8 then - skipbytes(recordsize-8) - end - end - end - end -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-dsp”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oup” 6f46aa00ae1c20c43f8ffaf329dc8695] --- - -if not modules then modules={} end modules ['font-oup']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next,type=next,type -local P,R,S=lpeg.P,lpeg.R,lpeg.S -local lpegmatch=lpeg.match -local insert,remove,copy,unpack=table.insert,table.remove,table.copy,table.unpack -local formatters=string.formatters -local sortedkeys=table.sortedkeys -local sortedhash=table.sortedhash -local tohash=table.tohash -local setmetatableindex=table.setmetatableindex -local report_error=logs.reporter("otf reader","error") -local report_markwidth=logs.reporter("otf reader","markwidth") -local report_cleanup=logs.reporter("otf reader","cleanup") -local report_optimizations=logs.reporter("otf reader","merges") -local report_unicodes=logs.reporter("otf reader","unicodes") -local trace_markwidth=false trackers.register("otf.markwidth",function(v) trace_markwidth=v end) -local trace_cleanup=false trackers.register("otf.cleanups",function(v) trace_cleanups=v end) -local trace_optimizations=false trackers.register("otf.optimizations",function(v) trace_optimizations=v end) -local trace_unicodes=false trackers.register("otf.unicodes",function(v) trace_unicodes=v end) -local readers=fonts.handlers.otf.readers -local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -local f_private=formatters["P%05X"] -local f_unicode=formatters["U%05X"] -local f_index=formatters["I%05X"] -local f_character_y=formatters["%C"] -local f_character_n=formatters["[ %C ]"] -local check_duplicates=true -local check_soft_hyphen=true -directives.register("otf.checksofthyphen",function(v) - check_soft_hyphen=v -end) -local function replaced(list,index,replacement) - if type(list)=="number" then - return replacement - elseif type(replacement)=="table" then - local t={} - local n=index-1 - for i=1,n do - t[i]=list[i] - end - for i=1,#replacement do - n=n+1 - t[n]=replacement[i] - end - for i=index+1,#list do - n=n+1 - t[n]=list[i] - end - else - list[index]=replacement - return list - end -end -local function unifyresources(fontdata,indices) - local descriptions=fontdata.descriptions - local resources=fontdata.resources - if not descriptions or not resources then - return - end - local nofindices=#indices - local variants=fontdata.resources.variants - if variants then - for selector,unicodes in next,variants do - for unicode,index in next,unicodes do - unicodes[unicode]=indices[index] - end - end - end - local function remark(marks) - if marks then - local newmarks={} - for k,v in next,marks do - local u=indices[k] - if u then - newmarks[u]=v - elseif trace_optimizations then - report_optimizations("discarding mark %i",k) - end - end - return newmarks - end - end - local marks=resources.marks - if marks then - resources.marks=remark(marks) - end - local markclasses=resources.markclasses - if markclasses then - for class,marks in next,markclasses do - markclasses[class]=remark(marks) - end - end - local marksets=resources.marksets - if marksets then - for class,marks in next,marksets do - marksets[class]=remark(marks) - end - end - local done={} - local duplicates=check_duplicates and resources.duplicates - if duplicates and not next(duplicates) then - duplicates=false - end - local function recover(cover) - for i=1,#cover do - local c=cover[i] - if not done[c] then - local t={} - for k,v in next,c do - local ug=indices[k] - if ug then - t[ug]=v - else - report_error("case %i, bad index in unifying %s: %s of %s",1,"coverage",k,nofindices) - end - end - cover[i]=t - done[c]=d - end - end - end - local function recursed(c,kind) - local t={} - for g,d in next,c do - if type(d)=="table" then - local ug=indices[g] - if ug then - t[ug]=recursed(d,kind) - else - report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g,nofindices) - end - else - t[g]=indices[d] - end - end - return t - end - local function unifythem(sequences) - if not sequences then - return - end - for i=1,#sequences do - local sequence=sequences[i] - local kind=sequence.type - local steps=sequence.steps - local features=sequence.features - if steps then - for i=1,#steps do - local step=steps[i] - if kind=="gsub_single" then - local c=step.coverage - if c then - local t1=done[c] - if not t1 then - t1={} - if duplicates then - for g1,d1 in next,c do - local ug1=indices[g1] - if ug1 then - local ud1=indices[d1] - if ud1 then - t1[ug1]=ud1 - local dg1=duplicates[ug1] - if dg1 then - for u in next,dg1 do - t1[u]=ud1 - end - end - else - report_error("case %i, bad index in unifying %s: %s of %s",3,kind,d1,nofindices) - end - else - report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) - end - end - else - for g1,d1 in next,c do - local ug1=indices[g1] - if ug1 then - t1[ug1]=indices[d1] - else - report_error("fuzzy case %i in unifying %s: %i",2,kind,g1) - end - end - end - done[c]=t1 - end - step.coverage=t1 - end - elseif kind=="gpos_pair" then - local c=step.coverage - if c then - local t1=done[c] - if not t1 then - t1={} - for g1,d1 in next,c do - local ug1=indices[g1] - if ug1 then - local t2=done[d1] - if not t2 then - t2={} - for g2,d2 in next,d1 do - local ug2=indices[g2] - if ug2 then - t2[ug2]=d2 - else - report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g2,nofindices,nofindices) - end - end - done[d1]=t2 - end - t1[ug1]=t2 - else - report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) - end - end - done[c]=t1 - end - step.coverage=t1 - end - elseif kind=="gsub_ligature" then - local c=step.coverage - if c then - step.coverage=recursed(c,kind) - end - elseif kind=="gsub_alternate" or kind=="gsub_multiple" then - local c=step.coverage - if c then - local t1=done[c] - if not t1 then - t1={} - if duplicates then - for g1,d1 in next,c do - for i=1,#d1 do - local d1i=d1[i] - local d1u=indices[d1i] - if d1u then - d1[i]=d1u - else - report_error("case %i, bad index in unifying %s: %s of %s",1,kind,i,d1i,nofindices) - end - end - local ug1=indices[g1] - if ug1 then - t1[ug1]=d1 - local dg1=duplicates[ug1] - if dg1 then - for u in next,dg1 do - t1[u]=copy(d1) - end - end - else - report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) - end - end - else - for g1,d1 in next,c do - for i=1,#d1 do - local d1i=d1[i] - local d1u=indices[d1i] - if d1u then - d1[i]=d1u - else - report_error("case %i, bad index in unifying %s: %s of %s",2,kind,d1i,nofindices) - end - end - t1[indices[g1]]=d1 - end - end - done[c]=t1 - end - step.coverage=t1 - end - elseif kind=="gpos_single" then - local c=step.coverage - if c then - local t1=done[c] - if not t1 then - t1={} - if duplicates then - for g1,d1 in next,c do - local ug1=indices[g1] - if ug1 then - t1[ug1]=d1 - local dg1=duplicates[ug1] - if dg1 then - for u in next,dg1 do - t1[u]=d1 - end - end - else - report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) - end - end - else - for g1,d1 in next,c do - local ug1=indices[g1] - if ug1 then - t1[ug1]=d1 - else - report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) - end - end - end - done[c]=t1 - end - step.coverage=t1 - end - elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" or kind=="gpos_mark2ligature" then - local c=step.coverage - if c then - local t1=done[c] - if not t1 then - t1={} - for g1,d1 in next,c do - local ug1=indices[g1] - if ug1 then - t1[ug1]=d1 - else - report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) - end - end - done[c]=t1 - end - step.coverage=t1 - end - local c=step.baseclasses - if c then - local t1=done[c] - if not t1 then - for g1,d1 in next,c do - local t2=done[d1] - if not t2 then - t2={} - for g2,d2 in next,d1 do - local ug2=indices[g2] - if ug2 then - t2[ug2]=d2 - else - report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g2,nofindices) - end - end - done[d1]=t2 - end - c[g1]=t2 - end - done[c]=c - end - end - elseif kind=="gpos_cursive" then - local c=step.coverage - if c then - local t1=done[c] - if not t1 then - t1={} - if duplicates then - for g1,d1 in next,c do - local ug1=indices[g1] - if ug1 then - t1[ug1]=d1 - local dg1=duplicates[ug1] - if dg1 then - for u in next,dg1 do - t1[u]=copy(d1) - end - end - else - report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) - end - end - else - for g1,d1 in next,c do - local ug1=indices[g1] - if ug1 then - t1[ug1]=d1 - else - report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) - end - end - end - done[c]=t1 - end - step.coverage=t1 - end - end - local rules=step.rules - if rules then - for i=1,#rules do - local rule=rules[i] - local before=rule.before if before then recover(before) end - local after=rule.after if after then recover(after) end - local current=rule.current if current then recover(current) end - local replacements=rule.replacements - if replacements then - if not done[replacements] then - local r={} - for k,v in next,replacements do - r[indices[k]]=indices[v] - end - rule.replacements=r - done[replacements]=r - end - end - end - end - end - end - end - end - unifythem(resources.sequences) - unifythem(resources.sublookups) -end -local function copyduplicates(fontdata) - if check_duplicates then - local descriptions=fontdata.descriptions - local resources=fontdata.resources - local duplicates=resources.duplicates - if check_soft_hyphen then - local ds=descriptions[0xAD] - if not ds or ds.width==0 then - if ds then - descriptions[0xAD]=nil - if trace_unicodes then - report_unicodes("patching soft hyphen") - end - else - if trace_unicodes then - report_unicodes("adding soft hyphen") - end - end - if not duplicates then - duplicates={} - resources.duplicates=duplicates - end - local dh=duplicates[0x2D] - if dh then - dh[#dh+1]={ [0xAD]=true } - else - duplicates[0x2D]={ [0xAD]=true } - end - end - end - if duplicates then - for u,d in next,duplicates do - local du=descriptions[u] - if du then - local t={ f_character_y(u),"@",f_index(du.index),"->" } - local n=0 - local m=25 - for u in next,d do - if descriptions[u] then - if n0 then - t={} - n=0 - local loops=0 - while true do - loops=loops+1 - local old=nofmissing - for i=1,#ligatures do - recursed(ligatures[i]) - end - if nofmissing<=0 then - if trace_unicodes then - report_unicodes("all missings done in %s loops",loops) - end - return - elseif old==nofmissing then - break - end - end - t=nil - n=0 - end - if trace_unicodes and nofmissing>0 then - local done={} - for i,r in next,missing do - if r then - local data=descriptions[i] - local name=data and data.name or f_index(i) - if not ignore[name] then - done[name]=true - end - end - end - if next(done) then - report_unicodes("not unicoded: % t",sortedkeys(done)) - end - end -end -local firstprivate=fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000 -local puafirst=0xE000 -local pualast=0xF8FF -local function unifymissing(fontdata) - if not fonts.mappings then - require("font-map") - require("font-agl") - end - local unicodes={} - local resources=fontdata.resources - resources.unicodes=unicodes - for unicode,d in next,fontdata.descriptions do - if unicode=puafirst and unicode<=pualast then - else - local name=d.name - if name then - unicodes[name]=unicode - end - end - else - end - end - fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups) - resources.unicodes=nil -end -local function unifyglyphs(fontdata,usenames) - local private=fontdata.private or privateoffset - local glyphs=fontdata.glyphs - local indices={} - local descriptions={} - local names=usenames and {} - local resources=fontdata.resources - local zero=glyphs[0] - local zerocode=zero.unicode - if not zerocode then - zerocode=private - zero.unicode=zerocode - private=private+1 - end - descriptions[zerocode]=zero - if names then - local name=glyphs[0].name or f_private(zerocode) - indices[0]=name - names[name]=zerocode - else - indices[0]=zerocode - end - if names then - for index=1,#glyphs do - local glyph=glyphs[index] - local unicode=glyph.unicode - if not unicode then - unicode=private - local name=glyph.name or f_private(unicode) - indices[index]=name - names[name]=unicode - private=private+1 - elseif unicode>=firstprivate then - unicode=private - local name=glyph.name or f_private(unicode) - indices[index]=name - names[name]=unicode - private=private+1 - elseif unicode>=puafirst and unicode<=pualast then - local name=glyph.name or f_private(unicode) - indices[index]=name - names[name]=unicode - elseif descriptions[unicode] then - unicode=private - local name=glyph.name or f_private(unicode) - indices[index]=name - names[name]=unicode - private=private+1 - else - local name=glyph.name or f_unicode(unicode) - indices[index]=name - names[name]=unicode - end - descriptions[unicode]=glyph - end - elseif trace_unicodes then - for index=1,#glyphs do - local glyph=glyphs[index] - local unicode=glyph.unicode - if not unicode then - unicode=private - indices[index]=unicode - private=private+1 - elseif unicode>=firstprivate then - local name=glyph.name - if name then - report_unicodes("moving glyph %a indexed %05X from private %U to %U ",name,index,unicode,private) - else - report_unicodes("moving glyph indexed %05X from private %U to %U ",index,unicode,private) - end - unicode=private - indices[index]=unicode - private=private+1 - elseif unicode>=puafirst and unicode<=pualast then - local name=glyph.name - if name then - report_unicodes("keeping private unicode %U for glyph %a indexed %05X",unicode,name,index) - else - report_unicodes("keeping private unicode %U for glyph indexed %05X",unicode,index) - end - indices[index]=unicode - elseif descriptions[unicode] then - local name=glyph.name - if name then - report_unicodes("assigning duplicate unicode %U to %U for glyph %a indexed %05X ",unicode,private,name,index) - else - report_unicodes("assigning duplicate unicode %U to %U for glyph indexed %05X ",unicode,private,index) - end - unicode=private - indices[index]=unicode - private=private+1 - else - indices[index]=unicode - end - descriptions[unicode]=glyph - end - else - for index=1,#glyphs do - local glyph=glyphs[index] - local unicode=glyph.unicode - if not unicode then - unicode=private - indices[index]=unicode - private=private+1 - elseif unicode>=firstprivate then - local name=glyph.name - unicode=private - indices[index]=unicode - private=private+1 - elseif unicode>=puafirst and unicode<=pualast then - local name=glyph.name - indices[index]=unicode - elseif descriptions[unicode] then - local name=glyph.name - unicode=private - indices[index]=unicode - private=private+1 - else - indices[index]=unicode - end - descriptions[unicode]=glyph - end - end - for index=1,#glyphs do - local math=glyphs[index].math - if math then - local list=math.vparts - if list then - for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end - end - local list=math.hparts - if list then - for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end - end - local list=math.vvariants - if list then - for i=1,#list do list[i]=indices[list[i]] end - end - local list=math.hvariants - if list then - for i=1,#list do list[i]=indices[list[i]] end - end - end - end - local colorpalettes=resources.colorpalettes - if colorpalettes then - for index=1,#glyphs do - local colors=glyphs[index].colors - if colors then - for i=1,#colors do - local c=colors[i] - c.slot=indices[c.slot] - end - end - end - end - fontdata.private=private - fontdata.glyphs=nil - fontdata.names=names - fontdata.descriptions=descriptions - fontdata.hashmethod=hashmethod - return indices,names -end -local p_crappyname do - local p_hex=R("af","AF","09") - local p_digit=R("09") - local p_done=S("._-")^0+P(-1) - local p_alpha=R("az","AZ") - local p_ALPHA=R("AZ") - p_crappyname=( - lpeg.utfchartabletopattern({ "uni","u" },true)*S("Xx_")^0*p_hex^1 -+lpeg.utfchartabletopattern({ "identity","glyph","jamo" },true)*p_hex^1 -+lpeg.utfchartabletopattern({ "index","afii" },true)*p_digit^1 -+p_digit*p_hex^3+p_alpha*p_digit^1 -+P("aj")*p_digit^1+P("eh_")*(p_digit^1+p_ALPHA*p_digit^1)+(1-P("_"))^1*P("_uni")*p_hex^1+P("_")*P(1)^1 - )*p_done -end -local forcekeep=false -directives.register("otf.keepnames",function(v) - report_cleanup("keeping weird glyph names, expect larger files and more memory usage") - forcekeep=v -end) -local function stripredundant(fontdata) - local descriptions=fontdata.descriptions - if descriptions then - local n=0 - local c=0 - if (not context and fonts.privateoffsets.keepnames) or forcekeep then - for unicode,d in next,descriptions do - if d.class=="base" then - d.class=nil - c=c+1 - end - end - else - for unicode,d in next,descriptions do - local name=d.name - if name and lpegmatch(p_crappyname,name) then - d.name=nil - n=n+1 - end - if d.class=="base" then - d.class=nil - c=c+1 - end - end - end - if trace_cleanup then - if n>0 then - report_cleanup("%s bogus names removed (verbose unicode)",n) - end - if c>0 then - report_cleanup("%s base class tags removed (default is base)",c) - end - end - end -end -readers.stripredundant=stripredundant -function readers.getcomponents(fontdata) - local resources=fontdata.resources - if resources then - local sequences=resources.sequences - if sequences then - local collected={} - for i=1,#sequences do - local sequence=sequences[i] - if sequence.type=="gsub_ligature" then - local steps=sequence.steps - if steps then - local l={} - local function traverse(p,k,v) - if k=="ligature" then - collected[v]={ unpack(l) } - else - insert(l,k) - for k,vv in next,v do - traverse(p,k,vv) - end - remove(l) - end - end - for i=1,#steps do - local c=steps[i].coverage - if c then - for k,v in next,c do - traverse(k,k,v) - end - end - end - end - end - end - if next(collected) then - while true do - local done=false - for k,v in next,collected do - for i=1,#v do - local vi=v[i] - if vi==k then - collected[k]=nil - break - else - local c=collected[vi] - if c then - done=true - local t={} - local n=i-1 - for j=1,n do - t[j]=v[j] - end - for j=1,#c do - n=n+1 - t[n]=c[j] - end - for j=i+1,#v do - n=n+1 - t[n]=v[j] - end - collected[k]=t - break - end - end - end - end - if not done then - break - end - end - return collected - end - end - end -end -readers.unifymissing=unifymissing -function readers.rehash(fontdata,hashmethod) - if not (fontdata and fontdata.glyphs) then - return - end - if hashmethod=="indices" then - fontdata.hashmethod="indices" - elseif hashmethod=="names" then - fontdata.hashmethod="names" - local indices=unifyglyphs(fontdata,true) - unifyresources(fontdata,indices) - copyduplicates(fontdata) - unifymissing(fontdata) - else - fontdata.hashmethod="unicodes" - local indices=unifyglyphs(fontdata) - unifyresources(fontdata,indices) - copyduplicates(fontdata) - unifymissing(fontdata) - stripredundant(fontdata) - end -end -function readers.checkhash(fontdata) - local hashmethod=fontdata.hashmethod - if hashmethod=="unicodes" then - fontdata.names=nil - elseif hashmethod=="names" and fontdata.names then - unifyresources(fontdata,fontdata.names) - copyduplicates(fontdata) - fontdata.hashmethod="unicodes" - fontdata.names=nil - else - readers.rehash(fontdata,"unicodes") - end -end -function readers.addunicodetable(fontdata) - local resources=fontdata.resources - local unicodes=resources.unicodes - if not unicodes then - local descriptions=fontdata.descriptions - if descriptions then - unicodes={} - resources.unicodes=unicodes - for u,d in next,descriptions do - local n=d.name - if n then - unicodes[n]=u - end - end - end - end -end -local concat,sort=table.concat,table.sort -local next,type,tostring=next,type,tostring -local criterium=1 -local threshold=0 -local trace_packing=false trackers.register("otf.packing",function(v) trace_packing=v end) -local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) -local report_otf=logs.reporter("fonts","otf loading") -local function tabstr_normal(t) - local s={} - local n=0 - for k,v in next,t do - n=n+1 - if type(v)=="table" then - s[n]=k..">"..tabstr_normal(v) - elseif v==true then - s[n]=k.."+" - elseif v then - s[n]=k.."="..v - else - s[n]=k.."-" - end - end - if n==0 then - return "" - elseif n==1 then - return s[1] - else - sort(s) - return concat(s,",") - end -end -local function tabstr_flat(t) - local s={} - local n=0 - for k,v in next,t do - n=n+1 - s[n]=k.."="..v - end - if n==0 then - return "" - elseif n==1 then - return s[1] - else - sort(s) - return concat(s,",") - end -end -local function tabstr_mixed(t) - local s={} - local n=#t - if n==0 then - return "" - elseif n==1 then - local k=t[1] - if k==true then - return "++" - elseif k==false then - return "--" - else - return tostring(k) - end - else - for i=1,n do - local k=t[i] - if k==true then - s[i]="++" - elseif k==false then - s[i]="--" - else - s[i]=k - end - end - return concat(s,",") - end -end -local function tabstr_boolean(t) - local s={} - local n=0 - for k,v in next,t do - n=n+1 - if v then - s[n]=k.."+" - else - s[n]=k.."-" - end - end - if n==0 then - return "" - elseif n==1 then - return s[1] - else - sort(s) - return concat(s,",") - end -end -function readers.pack(data) - if data then - local h,t,c={},{},{} - local hh,tt,cc={},{},{} - local nt,ntt=0,0 - local function pack_normal(v) - local tag=tabstr_normal(v) - local ht=h[tag] - if ht then - c[ht]=c[ht]+1 - return ht - else - nt=nt+1 - t[nt]=v - h[tag]=nt - c[nt]=1 - return nt - end - end - local function pack_normal_cc(v) - local tag=tabstr_normal(v) - local ht=h[tag] - if ht then - c[ht]=c[ht]+1 - return ht - else - v[1]=0 - nt=nt+1 - t[nt]=v - h[tag]=nt - c[nt]=1 - return nt - end - end - local function pack_flat(v) - local tag=tabstr_flat(v) - local ht=h[tag] - if ht then - c[ht]=c[ht]+1 - return ht - else - nt=nt+1 - t[nt]=v - h[tag]=nt - c[nt]=1 - return nt - end - end - local function pack_indexed(v) - local tag=concat(v," ") - local ht=h[tag] - if ht then - c[ht]=c[ht]+1 - return ht - else - nt=nt+1 - t[nt]=v - h[tag]=nt - c[nt]=1 - return nt - end - end - local function pack_mixed(v) - local tag=tabstr_mixed(v) - local ht=h[tag] - if ht then - c[ht]=c[ht]+1 - return ht - else - nt=nt+1 - t[nt]=v - h[tag]=nt - c[nt]=1 - return nt - end - end - local function pack_boolean(v) - local tag=tabstr_boolean(v) - local ht=h[tag] - if ht then - c[ht]=c[ht]+1 - return ht - else - nt=nt+1 - t[nt]=v - h[tag]=nt - c[nt]=1 - return nt - end - end - local function pack_final(v) - if c[v]<=criterium then - return t[v] - else - local hv=hh[v] - if hv then - return hv - else - ntt=ntt+1 - tt[ntt]=t[v] - hh[v]=ntt - cc[ntt]=c[v] - return ntt - end - end - end - local function pack_final_cc(v) - if c[v]<=criterium then - return t[v] - else - local hv=hh[v] - if hv then - return hv - else - ntt=ntt+1 - tt[ntt]=t[v] - hh[v]=ntt - cc[ntt]=c[v] - return ntt - end - end - end - local function success(stage,pass) - if nt==0 then - if trace_loading or trace_packing then - report_otf("pack quality: nothing to pack") - end - return false - elseif nt>=threshold then - local one=0 - local two=0 - local rest=0 - if pass==1 then - for k,v in next,c do - if v==1 then - one=one+1 - elseif v==2 then - two=two+1 - else - rest=rest+1 - end - end - else - for k,v in next,cc do - if v>20 then - rest=rest+1 - elseif v>10 then - two=two+1 - else - one=one+1 - end - end - data.tables=tt - end - if trace_loading or trace_packing then - report_otf("pack quality: stage %s, pass %s, %s packed, 1-10:%s, 11-20:%s, rest:%s (criterium: %s)", - stage,pass,one+two+rest,one,two,rest,criterium) - end - return true - else - if trace_loading or trace_packing then - report_otf("pack quality: stage %s, pass %s, %s packed, aborting pack (threshold: %s)", - stage,pass,nt,threshold) - end - return false - end - end - local function packers(pass) - if pass==1 then - return pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc - else - return pack_final,pack_final,pack_final,pack_final,pack_final,pack_final_cc - end - end - local resources=data.resources - local sequences=resources.sequences - local sublookups=resources.sublookups - local features=resources.features - local palettes=resources.colorpalettes - local variable=resources.variabledata - local chardata=characters and characters.data - local descriptions=data.descriptions or data.glyphs - if not descriptions then - return - end - for pass=1,2 do - if trace_packing then - report_otf("start packing: stage 1, pass %s",pass) - end - local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass) - for unicode,description in next,descriptions do - local boundingbox=description.boundingbox - if boundingbox then - description.boundingbox=pack_indexed(boundingbox) - end - local math=description.math - if math then - local kerns=math.kerns - if kerns then - for tag,kern in next,kerns do - kerns[tag]=pack_normal(kern) - end - end - end - end - local function packthem(sequences) - for i=1,#sequences do - local sequence=sequences[i] - local kind=sequence.type - local steps=sequence.steps - local order=sequence.order - local features=sequence.features - local flags=sequence.flags - if steps then - for i=1,#steps do - local step=steps[i] - if kind=="gpos_pair" then - local c=step.coverage - if c then - if step.format~="pair" then - for g1,d1 in next,c do - c[g1]=pack_normal(d1) - end - elseif step.shared then - local shared={} - for g1,d1 in next,c do - for g2,d2 in next,d1 do - if not shared[d2] then - local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end - local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end - shared[d2]=true - end - end - end - if pass==2 then - step.shared=nil - end - else - for g1,d1 in next,c do - for g2,d2 in next,d1 do - local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end - local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end - end - end - end - end - elseif kind=="gpos_single" then - local c=step.coverage - if c then - if step.format=="single" then - for g1,d1 in next,c do - if d1 and d1~=true then - c[g1]=pack_indexed(d1) - end - end - else - step.coverage=pack_normal(c) - end - end - elseif kind=="gpos_cursive" then - local c=step.coverage - if c then - for g1,d1 in next,c do - local f=d1[2] if f then d1[2]=pack_indexed(f) end - local s=d1[3] if s then d1[3]=pack_indexed(s) end - end - end - elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then - local c=step.baseclasses - if c then - for g1,d1 in next,c do - for g2,d2 in next,d1 do - d1[g2]=pack_indexed(d2) - end - end - end - local c=step.coverage - if c then - for g1,d1 in next,c do - d1[2]=pack_indexed(d1[2]) - end - end - elseif kind=="gpos_mark2ligature" then - local c=step.baseclasses - if c then - for g1,d1 in next,c do - for g2,d2 in next,d1 do - for g3,d3 in next,d2 do - d2[g3]=pack_indexed(d3) - end - end - end - end - local c=step.coverage - if c then - for g1,d1 in next,c do - d1[2]=pack_indexed(d1[2]) - end - end - end - local rules=step.rules - if rules then - for i=1,#rules do - local rule=rules[i] - local r=rule.before if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end - local r=rule.after if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end - local r=rule.current if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end - local r=rule.replacements if r then rule.replacements=pack_flat (r) end - end - end - end - end - if order then - sequence.order=pack_indexed(order) - end - if features then - for script,feature in next,features do - features[script]=pack_normal(feature) - end - end - if flags then - sequence.flags=pack_normal(flags) - end - end - end - if sequences then - packthem(sequences) - end - if sublookups then - packthem(sublookups) - end - if features then - for k,list in next,features do - for feature,spec in next,list do - list[feature]=pack_normal(spec) - end - end - end - if palettes then - for i=1,#palettes do - local p=palettes[i] - for j=1,#p do - p[j]=pack_indexed(p[j]) - end - end - end - if variable then - local instances=variable.instances - if instances then - for i=1,#instances do - local v=instances[i].values - for j=1,#v do - v[j]=pack_normal(v[j]) - end - end - end - local function packdeltas(main) - if main then - local deltas=main.deltas - if deltas then - for i=1,#deltas do - local di=deltas[i] - local d=di.deltas - for j=1,#d do - d[j]=pack_indexed(d[j]) - end - di.regions=pack_indexed(di.regions) - end - end - local regions=main.regions - if regions then - for i=1,#regions do - local r=regions[i] - for j=1,#r do - r[j]=pack_normal(r[j]) - end - end - end - end - end - packdeltas(variable.global) - packdeltas(variable.horizontal) - packdeltas(variable.vertical) - packdeltas(variable.metrics) - end - if not success(1,pass) then - return - end - end - if nt>0 then - for pass=1,2 do - if trace_packing then - report_otf("start packing: stage 2, pass %s",pass) - end - local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass) - for unicode,description in next,descriptions do - local math=description.math - if math then - local kerns=math.kerns - if kerns then - math.kerns=pack_normal(kerns) - end - end - end - local function packthem(sequences) - for i=1,#sequences do - local sequence=sequences[i] - local kind=sequence.type - local steps=sequence.steps - local features=sequence.features - if steps then - for i=1,#steps do - local step=steps[i] - if kind=="gpos_pair" then - local c=step.coverage - if c then - if step.format=="pair" then - for g1,d1 in next,c do - for g2,d2 in next,d1 do - d1[g2]=pack_normal(d2) - end - end - end - end - elseif kind=="gpos_mark2ligature" then - local c=step.baseclasses - if c then - for g1,d1 in next,c do - for g2,d2 in next,d1 do - d1[g2]=pack_normal(d2) - end - end - end - end - local rules=step.rules - if rules then - for i=1,#rules do - local rule=rules[i] - local r=rule.before if r then rule.before=pack_normal(r) end - local r=rule.after if r then rule.after=pack_normal(r) end - local r=rule.current if r then rule.current=pack_normal(r) end - end - end - end - end - if features then - sequence.features=pack_normal(features) - end - end - end - if sequences then - packthem(sequences) - end - if sublookups then - packthem(sublookups) - end - if variable then - local function unpackdeltas(main) - if main then - local regions=main.regions - if regions then - main.regions=pack_normal(regions) - end - end - end - unpackdeltas(variable.global) - unpackdeltas(variable.horizontal) - unpackdeltas(variable.vertical) - unpackdeltas(variable.metrics) - end - end - for pass=1,2 do - if trace_packing then - report_otf("start packing: stage 3, pass %s",pass) - end - local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass) - local function packthem(sequences) - for i=1,#sequences do - local sequence=sequences[i] - local kind=sequence.type - local steps=sequence.steps - local features=sequence.features - if steps then - for i=1,#steps do - local step=steps[i] - if kind=="gpos_pair" then - local c=step.coverage - if c then - if step.format=="pair" then - for g1,d1 in next,c do - c[g1]=pack_normal(d1) - end - end - end - elseif kind=="gpos_cursive" then - local c=step.coverage - if c then - for g1,d1 in next,c do - c[g1]=pack_normal_cc(d1) - end - end - end - end - end - end - end - if sequences then - packthem(sequences) - end - if sublookups then - packthem(sublookups) - end - end - end - end -end -local unpacked_mt={ - __index=function(t,k) - t[k]=false - return k - end -} -function readers.unpack(data) - if data then - local tables=data.tables - if tables then - local resources=data.resources - local descriptions=data.descriptions or data.glyphs - local sequences=resources.sequences - local sublookups=resources.sublookups - local features=resources.features - local palettes=resources.colorpalettes - local variable=resources.variabledata - local unpacked={} - setmetatable(unpacked,unpacked_mt) - for unicode,description in next,descriptions do - local tv=tables[description.boundingbox] - if tv then - description.boundingbox=tv - end - local math=description.math - if math then - local kerns=math.kerns - if kerns then - local tm=tables[kerns] - if tm then - math.kerns=tm - kerns=unpacked[tm] - end - if kerns then - for k,kern in next,kerns do - local tv=tables[kern] - if tv then - kerns[k]=tv - end - end - end - end - end - end - local function unpackthem(sequences) - for i=1,#sequences do - local sequence=sequences[i] - local kind=sequence.type - local steps=sequence.steps - local order=sequence.order - local features=sequence.features - local flags=sequence.flags - local markclass=sequence.markclass - if features then - local tv=tables[features] - if tv then - sequence.features=tv - features=tv - end - for script,feature in next,features do - local tv=tables[feature] - if tv then - features[script]=tv - end - end - end - if steps then - for i=1,#steps do - local step=steps[i] - if kind=="gpos_pair" then - local c=step.coverage - if c then - if step.format=="pair" then - for g1,d1 in next,c do - local tv=tables[d1] - if tv then - c[g1]=tv - d1=tv - end - for g2,d2 in next,d1 do - local tv=tables[d2] - if tv then - d1[g2]=tv - d2=tv - end - local f=tables[d2[1]] if f then d2[1]=f end - local s=tables[d2[2]] if s then d2[2]=s end - end - end - else - for g1,d1 in next,c do - local tv=tables[d1] - if tv then - c[g1]=tv - end - end - end - end - elseif kind=="gpos_single" then - local c=step.coverage - if c then - if step.format=="single" then - for g1,d1 in next,c do - local tv=tables[d1] - if tv then - c[g1]=tv - end - end - else - local tv=tables[c] - if tv then - step.coverage=tv - end - end - end - elseif kind=="gpos_cursive" then - local c=step.coverage - if c then - for g1,d1 in next,c do - local tv=tables[d1] - if tv then - d1=tv - c[g1]=d1 - end - local f=tables[d1[2]] if f then d1[2]=f end - local s=tables[d1[3]] if s then d1[3]=s end - end - end - elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then - local c=step.baseclasses - if c then - for g1,d1 in next,c do - for g2,d2 in next,d1 do - local tv=tables[d2] - if tv then - d1[g2]=tv - end - end - end - end - local c=step.coverage - if c then - for g1,d1 in next,c do - local tv=tables[d1[2]] - if tv then - d1[2]=tv - end - end - end - elseif kind=="gpos_mark2ligature" then - local c=step.baseclasses - if c then - for g1,d1 in next,c do - for g2,d2 in next,d1 do - local tv=tables[d2] - if tv then - d2=tv - d1[g2]=d2 - end - for g3,d3 in next,d2 do - local tv=tables[d2[g3]] - if tv then - d2[g3]=tv - end - end - end - end - end - local c=step.coverage - if c then - for g1,d1 in next,c do - local tv=tables[d1[2]] - if tv then - d1[2]=tv - end - end - end - end - local rules=step.rules - if rules then - for i=1,#rules do - local rule=rules[i] - local before=rule.before - if before then - local tv=tables[before] - if tv then - rule.before=tv - before=tv - end - for i=1,#before do - local tv=tables[before[i]] - if tv then - before[i]=tv - end - end - end - local after=rule.after - if after then - local tv=tables[after] - if tv then - rule.after=tv - after=tv - end - for i=1,#after do - local tv=tables[after[i]] - if tv then - after[i]=tv - end - end - end - local current=rule.current - if current then - local tv=tables[current] - if tv then - rule.current=tv - current=tv - end - for i=1,#current do - local tv=tables[current[i]] - if tv then - current[i]=tv - end - end - end - local replacements=rule.replacements - if replacements then - local tv=tables[replacements] - if tv then - rule.replacements=tv - end - end - end - end - end - end - if order then - local tv=tables[order] - if tv then - sequence.order=tv - end - end - if flags then - local tv=tables[flags] - if tv then - sequence.flags=tv - end - end - end - end - if sequences then - unpackthem(sequences) - end - if sublookups then - unpackthem(sublookups) - end - if features then - for k,list in next,features do - for feature,spec in next,list do - local tv=tables[spec] - if tv then - list[feature]=tv - end - end - end - end - if palettes then - for i=1,#palettes do - local p=palettes[i] - for j=1,#p do - local tv=tables[p[j]] - if tv then - p[j]=tv - end - end - end - end - if variable then - local instances=variable.instances - if instances then - for i=1,#instances do - local v=instances[i].values - for j=1,#v do - local tv=tables[v[j]] - if tv then - v[j]=tv - end - end - end - end - local function unpackdeltas(main) - if main then - local deltas=main.deltas - if deltas then - for i=1,#deltas do - local di=deltas[i] - local d=di.deltas - local r=di.regions - for j=1,#d do - local tv=tables[d[j]] - if tv then - d[j]=tv - end - end - local tv=di.regions - if tv then - di.regions=tv - end - end - end - local regions=main.regions - if regions then - local tv=tables[regions] - if tv then - main.regions=tv - regions=tv - end - for i=1,#regions do - local r=regions[i] - for j=1,#r do - local tv=tables[r[j]] - if tv then - r[j]=tv - end - end - end - end - end - end - unpackdeltas(variable.global) - unpackdeltas(variable.horizontal) - unpackdeltas(variable.vertical) - unpackdeltas(variable.metrics) - end - data.tables=nil - end - end -end -local mt={ - __index=function(t,k) - if k=="height" then - local ht=t.boundingbox[4] - return ht<0 and 0 or ht - elseif k=="depth" then - local dp=-t.boundingbox[2] - return dp<0 and 0 or dp - elseif k=="width" then - return 0 - elseif k=="name" then - return forcenotdef and ".notdef" - end - end -} -local function sameformat(sequence,steps,first,nofsteps,kind) - return true -end -local function mergesteps_1(lookup,strict) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - local first=steps[1] - if strict then - local f=first.format - for i=2,nofsteps do - if steps[i].format~=f then - if trace_optimizations then - report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name) - end - return 0 - end - end - end - if trace_optimizations then - report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) - end - local target=first.coverage - for i=2,nofsteps do - local c=steps[i].coverage - if c then - for k,v in next,c do - if not target[k] then - target[k]=v - end - end - end - end - lookup.nofsteps=1 - lookup.merged=true - lookup.steps={ first } - return nofsteps-1 -end -local function mergesteps_2(lookup) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - local first=steps[1] - if strict then - local f=first.format - for i=2,nofsteps do - if steps[i].format~=f then - if trace_optimizations then - report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name) - end - return 0 - end - end - end - if trace_optimizations then - report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) - end - local target=first.coverage - for i=2,nofsteps do - local c=steps[i].coverage - if c then - for k,v in next,c do - local tk=target[k] - if tk then - for kk,vv in next,v do - if tk[kk]==nil then - tk[kk]=vv - end - end - else - target[k]=v - end - end - end - end - lookup.nofsteps=1 - lookup.merged=true - lookup.steps={ first } - return nofsteps-1 -end -local function mergesteps_3(lookup,strict) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - if trace_optimizations then - report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) - end - local coverage={} - for i=1,nofsteps do - local c=steps[i].coverage - if c then - for k,v in next,c do - local tk=coverage[k] - if tk then - if trace_optimizations then - report_optimizations("quitting merge due to multiple checks") - end - return nofsteps - else - coverage[k]=v - end - end - end - end - local first=steps[1] - local baseclasses={} - for i=1,nofsteps do - local offset=i*10 - local step=steps[i] - for k,v in sortedhash(step.baseclasses) do - baseclasses[offset+k]=v - end - for k,v in next,step.coverage do - v[1]=offset+v[1] - end - end - first.baseclasses=baseclasses - first.coverage=coverage - lookup.nofsteps=1 - lookup.merged=true - lookup.steps={ first } - return nofsteps-1 -end -local function nested(old,new) - for k,v in next,old do - if k=="ligature" then - if not new.ligature then - new.ligature=v - end - else - local n=new[k] - if n then - nested(v,n) - else - new[k]=v - end - end - end -end -local function mergesteps_4(lookup) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - local first=steps[1] - if trace_optimizations then - report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) - end - local target=first.coverage - for i=2,nofsteps do - local c=steps[i].coverage - if c then - for k,v in next,c do - local tk=target[k] - if tk then - nested(v,tk) - else - target[k]=v - end - end - end - end - lookup.nofsteps=1 - lookup.steps={ first } - return nofsteps-1 -end -local function mergesteps_5(lookup) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - local first=steps[1] - if trace_optimizations then - report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) - end - local target=first.coverage - local hash=nil - for k,v in next,target do - hash=v[1] - break - end - for i=2,nofsteps do - local c=steps[i].coverage - if c then - for k,v in next,c do - local tk=target[k] - if tk then - if not tk[2] then - tk[2]=v[2] - end - if not tk[3] then - tk[3]=v[3] - end - else - target[k]=v - v[1]=hash - end - end - end - end - lookup.nofsteps=1 - lookup.merged=true - lookup.steps={ first } - return nofsteps-1 -end -local function checkkerns(lookup) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - local kerned=0 - for i=1,nofsteps do - local step=steps[i] - if step.format=="pair" then - local coverage=step.coverage - local kerns=true - for g1,d1 in next,coverage do - if d1==true then - elseif not d1 then - elseif d1[1]~=0 or d1[2]~=0 or d1[4]~=0 then - kerns=false - break - end - end - if kerns then - if trace_optimizations then - report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) - end - local c={} - for g1,d1 in next,coverage do - if d1 and d1~=true then - c[g1]=d1[3] - end - end - step.coverage=c - step.format="move" - kerned=kerned+1 - end - end - end - return kerned -end -local function checkpairs(lookup) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - local kerned=0 - local function onlykerns(step) - local coverage=step.coverage - for g1,d1 in next,coverage do - for g2,d2 in next,d1 do - if d2[2] then - return false - else - local v=d2[1] - if v==true then - elseif v and (v[1]~=0 or v[2]~=0 or v[4]~=0) then - return false - end - end - end - end - return coverage - end - for i=1,nofsteps do - local step=steps[i] - if step.format=="pair" then - local coverage=onlykerns(step) - if coverage then - if trace_optimizations then - report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) - end - for g1,d1 in next,coverage do - local d={} - for g2,d2 in next,d1 do - local v=d2[1] - if v==true then - elseif v then - d[g2]=v[3] - end - end - coverage[g1]=d - end - step.format="move" - kerned=kerned+1 - end - end - end - return kerned -end -local compact_pairs=true -local compact_singles=true -local merge_pairs=true -local merge_singles=true -local merge_substitutions=true -local merge_alternates=true -local merge_multiples=true -local merge_ligatures=true -local merge_cursives=true -local merge_marks=true -directives.register("otf.compact.pairs",function(v) compact_pairs=v end) -directives.register("otf.compact.singles",function(v) compact_singles=v end) -directives.register("otf.merge.pairs",function(v) merge_pairs=v end) -directives.register("otf.merge.singles",function(v) merge_singles=v end) -directives.register("otf.merge.substitutions",function(v) merge_substitutions=v end) -directives.register("otf.merge.alternates",function(v) merge_alternates=v end) -directives.register("otf.merge.multiples",function(v) merge_multiples=v end) -directives.register("otf.merge.ligatures",function(v) merge_ligatures=v end) -directives.register("otf.merge.cursives",function(v) merge_cursives=v end) -directives.register("otf.merge.marks",function(v) merge_marks=v end) -function readers.compact(data) - if not data or data.compacted then - return - else - data.compacted=true - end - local resources=data.resources - local merged=0 - local kerned=0 - local allsteps=0 - local function compact(what) - local lookups=resources[what] - if lookups then - for i=1,#lookups do - local lookup=lookups[i] - local nofsteps=lookup.nofsteps - local kind=lookup.type - allsteps=allsteps+nofsteps - if nofsteps>1 then - local merg=merged - if kind=="gsub_single" then - if merge_substitutions then - merged=merged+mergesteps_1(lookup) - end - elseif kind=="gsub_alternate" then - if merge_alternates then - merged=merged+mergesteps_1(lookup) - end - elseif kind=="gsub_multiple" then - if merge_multiples then - merged=merged+mergesteps_1(lookup) - end - elseif kind=="gsub_ligature" then - if merge_ligatures then - merged=merged+mergesteps_4(lookup) - end - elseif kind=="gpos_single" then - if merge_singles then - merged=merged+mergesteps_1(lookup,true) - end - if compact_singles then - kerned=kerned+checkkerns(lookup) - end - elseif kind=="gpos_pair" then - if merge_pairs then - merged=merged+mergesteps_2(lookup) - end - if compact_pairs then - kerned=kerned+checkpairs(lookup) - end - elseif kind=="gpos_cursive" then - if merge_cursives then - merged=merged+mergesteps_5(lookup) - end - elseif kind=="gpos_mark2mark" or kind=="gpos_mark2base" or kind=="gpos_mark2ligature" then - if merge_marks then - merged=merged+mergesteps_3(lookup) - end - end - if merg~=merged then - lookup.merged=true - end - elseif nofsteps==1 then - local kern=kerned - if kind=="gpos_single" then - if compact_singles then - kerned=kerned+checkkerns(lookup) - end - elseif kind=="gpos_pair" then - if compact_pairs then - kerned=kerned+checkpairs(lookup) - end - end - if kern~=kerned then - end - end - end - elseif trace_optimizations then - report_optimizations("no lookups in %a",what) - end - end - compact("sequences") - compact("sublookups") - if trace_optimizations then - if merged>0 then - report_optimizations("%i steps of %i removed due to merging",merged,allsteps) - end - if kerned>0 then - report_optimizations("%i steps of %i steps turned from pairs into kerns",kerned,allsteps) - end - end -end -local function mergesteps(t,k) - if k=="merged" then - local merged={} - for i=1,#t do - local step=t[i] - local coverage=step.coverage - for k in next,coverage do - local m=merged[k] - if m then - m[2]=i - else - merged[k]={ i,i } - end - end - end - t.merged=merged - return merged - end -end -local function checkmerge(sequence) - local steps=sequence.steps - if steps then - setmetatableindex(steps,mergesteps) - end -end -local function checkflags(sequence,resources) - if not sequence.skiphash then - local flags=sequence.flags - if flags then - local skipmark=flags[1] - local skipligature=flags[2] - local skipbase=flags[3] - local markclass=sequence.markclass - local skipsome=skipmark or skipligature or skipbase or markclass or false - if skipsome then - sequence.skiphash=setmetatableindex(function(t,k) - local c=resources.classes[k] - local v=c==skipmark - or (markclass and c=="mark" and not markclass[k]) - or c==skipligature - or c==skipbase - or false - t[k]=v - return v - end) - else - sequence.skiphash=false - end - else - sequence.skiphash=false - end - end -end -local function checksteps(sequence) - local steps=sequence.steps - if steps then - for i=1,#steps do - steps[i].index=i - end - end -end -if fonts.helpers then - fonts.helpers.checkmerge=checkmerge - fonts.helpers.checkflags=checkflags - fonts.helpers.checksteps=checksteps -end -function readers.expand(data) - if not data or data.expanded then - return - else - data.expanded=true - end - local resources=data.resources - local sublookups=resources.sublookups - local sequences=resources.sequences - local markclasses=resources.markclasses - local descriptions=data.descriptions - if descriptions then - local defaultwidth=resources.defaultwidth or 0 - local defaultheight=resources.defaultheight or 0 - local defaultdepth=resources.defaultdepth or 0 - local basename=trace_markwidth and file.basename(resources.filename) - for u,d in next,descriptions do - local bb=d.boundingbox - local wd=d.width - if not wd then - d.width=defaultwidth - elseif trace_markwidth and wd~=0 and d.class=="mark" then - report_markwidth("mark %a with width %b found in %a",d.name or "",wd,basename) - end - if bb then - local ht=bb[4] - local dp=-bb[2] - if ht==0 or ht<0 then - else - d.height=ht - end - if dp==0 or dp<0 then - else - d.depth=dp - end - end - end - end - local function expandlookups(sequences) - if sequences then - for i=1,#sequences do - local sequence=sequences[i] - local steps=sequence.steps - if steps then - local nofsteps=sequence.nofsteps - local kind=sequence.type - local markclass=sequence.markclass - if markclass then - if not markclasses then - report_warning("missing markclasses") - sequence.markclass=false - else - sequence.markclass=markclasses[markclass] - end - end - for i=1,nofsteps do - local step=steps[i] - local baseclasses=step.baseclasses - if baseclasses then - local coverage=step.coverage - for k,v in next,coverage do - v[1]=baseclasses[v[1]] - end - elseif kind=="gpos_cursive" then - local coverage=step.coverage - for k,v in next,coverage do - v[1]=coverage - end - end - local rules=step.rules - if rules then - local rulehash={ n=0 } - local rulesize=0 - local coverage={} - local lookuptype=sequence.type - local nofrules=#rules - step.coverage=coverage - for currentrule=1,nofrules do - local rule=rules[currentrule] - local current=rule.current - local before=rule.before - local after=rule.after - local replacements=rule.replacements or false - local sequence={} - local nofsequences=0 - if before then - for n=1,#before do - nofsequences=nofsequences+1 - sequence[nofsequences]=before[n] - end - end - local start=nofsequences+1 - for n=1,#current do - nofsequences=nofsequences+1 - sequence[nofsequences]=current[n] - end - local stop=nofsequences - if after then - for n=1,#after do - nofsequences=nofsequences+1 - sequence[nofsequences]=after[n] - end - end - local lookups=rule.lookups or false - local subtype=nil - if lookups then - for i=1,#lookups do - local lookups=lookups[i] - if lookups then - for k,v in next,lookups do - local lookup=sublookups[v] - if lookup then - lookups[k]=lookup - if not subtype then - subtype=lookup.type - end - else - end - end - end - end - end - if sequence[1] then - sequence.n=#sequence - local ruledata={ - currentrule, - lookuptype, - sequence, - start, - stop, - lookups, - replacements, - subtype, - } - rulesize=rulesize+1 - rulehash[rulesize]=ruledata - rulehash.n=rulesize - if true then - for unic in next,sequence[start] do - local cu=coverage[unic] - if cu then - local n=#cu+1 - cu[n]=ruledata - cu.n=n - else - coverage[unic]={ ruledata,n=1 } - end - end - else - for unic in next,sequence[start] do - local cu=coverage[unic] - if cu then - else - coverage[unic]=rulehash - end - end - end - end - end - end - end - checkmerge(sequence) - checkflags(sequence,resources) - checksteps(sequence) - end - end - end - end - expandlookups(sequences) - expandlookups(sublookups) -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oup”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otl” 6c4b718ceacfb0cbeb2c03c423f97aec] --- - -if not modules then modules={} end modules ['font-otl']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files", -} -local lower=string.lower -local type,next,tonumber,tostring,unpack=type,next,tonumber,tostring,unpack -local abs=math.abs -local derivetable=table.derive -local formatters=string.formatters -local setmetatableindex=table.setmetatableindex -local allocate=utilities.storage.allocate -local registertracker=trackers.register -local registerdirective=directives.register -local starttiming=statistics.starttiming -local stoptiming=statistics.stoptiming -local elapsedtime=statistics.elapsedtime -local findbinfile=resolvers.findbinfile -local trace_loading=false registertracker("otf.loading",function(v) trace_loading=v end) -local trace_features=false registertracker("otf.features",function(v) trace_features=v end) -local trace_defining=false registertracker("fonts.defining",function(v) trace_defining=v end) -local report_otf=logs.reporter("fonts","otf loading") -local fonts=fonts -local otf=fonts.handlers.otf -otf.version=3.112 -otf.cache=containers.define("fonts","otl",otf.version,true) -otf.svgcache=containers.define("fonts","svg",otf.version,true) -otf.pngcache=containers.define("fonts","png",otf.version,true) -otf.pdfcache=containers.define("fonts","pdf",otf.version,true) -otf.mpscache=containers.define("fonts","mps",otf.version,true) -otf.svgenabled=false -otf.pngenabled=false -local otfreaders=otf.readers -local hashes=fonts.hashes -local definers=fonts.definers -local readers=fonts.readers -local constructors=fonts.constructors -local otffeatures=constructors.features.otf -local registerotffeature=otffeatures.register -local otfenhancers=constructors.enhancers.otf -local registerotfenhancer=otfenhancers.register -local forceload=false -local cleanup=0 -local syncspace=true -local forcenotdef=false -local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes -local wildcard="*" -local default="dflt" -local formats=fonts.formats -formats.otf="opentype" -formats.ttf="truetype" -formats.ttc="truetype" -registerdirective("fonts.otf.loader.cleanup",function(v) cleanup=tonumber(v) or (v and 1) or 0 end) -registerdirective("fonts.otf.loader.force",function(v) forceload=v end) -registerdirective("fonts.otf.loader.syncspace",function(v) syncspace=v end) -registerdirective("fonts.otf.loader.forcenotdef",function(v) forcenotdef=v end) -registerotfenhancer("check extra features",function() end) -local checkmemory=utilities.lua and utilities.lua.checkmemory -local threshold=100 -local tracememory=false -registertracker("fonts.otf.loader.memory",function(v) tracememory=v end) -if not checkmemory then - local collectgarbage=collectgarbage - checkmemory=function(previous,threshold) - local current=collectgarbage("count") - if previous then - local checked=(threshold or 64)*1024 - if current-previous>checked then - collectgarbage("collect") - current=collectgarbage("count") - end - end - return current - end -end -function otf.load(filename,sub,instance) - local base=file.basename(file.removesuffix(filename)) - local name=file.removesuffix(base) - local attr=lfs.attributes(filename) - local size=attr and attr.size or 0 - local time=attr and attr.modification or 0 - if sub=="" then - sub=false - end - local hash=name - if sub then - hash=hash.."-"..sub - end - if instance then - hash=hash.."-"..instance - end - hash=containers.cleanname(hash) - local data=containers.read(otf.cache,hash) - local reload=not data or data.size~=size or data.time~=time or data.tableversion~=otfreaders.tableversion - if forceload then - report_otf("forced reload of %a due to hard coded flag",filename) - reload=true - end - if reload then - report_otf("loading %a, hash %a",filename,hash) - starttiming(otfreaders,true) - data=otfreaders.loadfont(filename,sub or 1,instance) - if data then - local used=checkmemory() - local resources=data.resources - local svgshapes=resources.svgshapes - local pngshapes=resources.pngshapes - if cleanup==0 then - checkmemory(used,threshold,tracememory) - end - if svgshapes then - resources.svgshapes=nil - if otf.svgenabled then - local timestamp=os.date() - containers.write(otf.svgcache,hash,{ - svgshapes=svgshapes, - timestamp=timestamp, - }) - data.properties.svg={ - hash=hash, - timestamp=timestamp, - } - end - if cleanup>1 then - collectgarbage("collect") - else - checkmemory(used,threshold,tracememory) - end - end - if pngshapes then - resources.pngshapes=nil - if otf.pngenabled then - local timestamp=os.date() - containers.write(otf.pngcache,hash,{ - pngshapes=pngshapes, - timestamp=timestamp, - }) - data.properties.png={ - hash=hash, - timestamp=timestamp, - } - end - if cleanup>1 then - collectgarbage("collect") - else - checkmemory(used,threshold,tracememory) - end - end - otfreaders.compact(data) - if cleanup==0 then - checkmemory(used,threshold,tracememory) - end - otfreaders.rehash(data,"unicodes") - otfreaders.addunicodetable(data) - otfreaders.extend(data) - if cleanup==0 then - checkmemory(used,threshold,tracememory) - end - otfreaders.pack(data) - report_otf("loading done") - report_otf("saving %a in cache",filename) - data=containers.write(otf.cache,hash,data) - if cleanup>1 then - collectgarbage("collect") - else - checkmemory(used,threshold,tracememory) - end - stoptiming(otfreaders) - if elapsedtime then - report_otf("loading, optimizing, packing and caching time %s",elapsedtime(otfreaders)) - end - if cleanup>3 then - collectgarbage("collect") - else - checkmemory(used,threshold,tracememory) - end - data=containers.read(otf.cache,hash) - if cleanup>2 then - collectgarbage("collect") - else - checkmemory(used,threshold,tracememory) - end - else - stoptiming(otfreaders) - data=nil - report_otf("loading failed due to read error") - end - end - if data then - if trace_defining then - report_otf("loading from cache using hash %a",hash) - end - otfreaders.unpack(data) - otfreaders.expand(data) - otfreaders.addunicodetable(data) - otfenhancers.apply(data,filename,data) - if applyruntimefixes then - applyruntimefixes(filename,data) - end - data.metadata.math=data.resources.mathconstants - local classes=data.resources.classes - if not classes then - local descriptions=data.descriptions - classes=setmetatableindex(function(t,k) - local d=descriptions[k] - local v=(d and d.class or "base") or false - t[k]=v - return v - end) - data.resources.classes=classes - end - end - return data -end -function otf.setfeatures(tfmdata,features) - local okay=constructors.initializefeatures("otf",tfmdata,features,trace_features,report_otf) - if okay then - return constructors.collectprocessors("otf",tfmdata,features,trace_features,report_otf) - else - return {} - end -end -local function copytotfm(data,cache_id) - if data then - local metadata=data.metadata - local properties=derivetable(data.properties) - local descriptions=derivetable(data.descriptions) - local goodies=derivetable(data.goodies) - local characters={} - local parameters={} - local mathparameters={} - local resources=data.resources - local unicodes=resources.unicodes - local spaceunits=500 - local spacer="space" - local designsize=metadata.designsize or 100 - local minsize=metadata.minsize or designsize - local maxsize=metadata.maxsize or designsize - local mathspecs=metadata.math - if designsize==0 then - designsize=100 - minsize=100 - maxsize=100 - end - if mathspecs then - for name,value in next,mathspecs do - mathparameters[name]=value - end - end - for unicode in next,data.descriptions do - characters[unicode]={} - end - if mathspecs then - for unicode,character in next,characters do - local d=descriptions[unicode] - local m=d.math - if m then - local italic=m.italic - local vitalic=m.vitalic - local variants=m.hvariants - local parts=m.hparts - if variants then - local c=character - for i=1,#variants do - local un=variants[i] - c.next=un - c=characters[un] - end - c.horiz_variants=parts - elseif parts then - character.horiz_variants=parts - italic=m.hitalic - end - local variants=m.vvariants - local parts=m.vparts - if variants then - local c=character - for i=1,#variants do - local un=variants[i] - c.next=un - c=characters[un] - end - c.vert_variants=parts - elseif parts then - character.vert_variants=parts - end - if italic and italic~=0 then - character.italic=italic - end - if vitalic and vitalic~=0 then - character.vert_italic=vitalic - end - local accent=m.accent - if accent then - character.accent=accent - end - local kerns=m.kerns - if kerns then - character.mathkerns=kerns - end - end - end - end - local filename=constructors.checkedfilename(resources) - local fontname=metadata.fontname - local fullname=metadata.fullname or fontname - local psname=fontname or fullname - local subfont=metadata.subfontindex - local units=metadata.units or 1000 - if units==0 then - units=1000 - metadata.units=1000 - report_otf("changing %a units to %a",0,units) - end - local monospaced=metadata.monospaced - local charwidth=metadata.averagewidth - local charxheight=metadata.xheight - local italicangle=metadata.italicangle - local hasitalics=metadata.hasitalics - properties.monospaced=monospaced - properties.hasitalics=hasitalics - parameters.italicangle=italicangle - parameters.charwidth=charwidth - parameters.charxheight=charxheight - local space=0x0020 - local emdash=0x2014 - if monospaced then - if descriptions[space] then - spaceunits,spacer=descriptions[space].width,"space" - end - if not spaceunits and descriptions[emdash] then - spaceunits,spacer=descriptions[emdash].width,"emdash" - end - if not spaceunits and charwidth then - spaceunits,spacer=charwidth,"charwidth" - end - else - if descriptions[space] then - spaceunits,spacer=descriptions[space].width,"space" - end - if not spaceunits and descriptions[emdash] then - spaceunits,spacer=descriptions[emdash].width/2,"emdash/2" - end - if not spaceunits and charwidth then - spaceunits,spacer=charwidth,"charwidth" - end - end - spaceunits=tonumber(spaceunits) or units/2 - parameters.slant=0 - parameters.space=spaceunits - parameters.space_stretch=1*units/2 - parameters.space_shrink=1*units/3 - parameters.x_height=2*units/5 - parameters.quad=units - if spaceunits<2*units/5 then - end - if italicangle and italicangle~=0 then - parameters.italicangle=italicangle - parameters.italicfactor=math.cos(math.rad(90+italicangle)) - parameters.slant=- math.tan(italicangle*math.pi/180) - end - if monospaced then - parameters.space_stretch=0 - parameters.space_shrink=0 - elseif syncspace then - parameters.space_stretch=spaceunits/2 - parameters.space_shrink=spaceunits/3 - end - parameters.extra_space=parameters.space_shrink - if charxheight then - parameters.x_height=charxheight - else - local x=0x0078 - if x then - local x=descriptions[x] - if x then - parameters.x_height=x.height - end - end - end - parameters.designsize=(designsize/10)*65536 - parameters.minsize=(minsize/10)*65536 - parameters.maxsize=(maxsize/10)*65536 - parameters.ascender=abs(metadata.ascender or 0) - parameters.descender=abs(metadata.descender or 0) - parameters.units=units - parameters.vheight=metadata.defaultvheight - properties.space=spacer - properties.format=data.format or formats.otf - properties.filename=filename - properties.fontname=fontname - properties.fullname=fullname - properties.psname=psname - properties.name=filename or fullname - properties.subfont=subfont -if not CONTEXTLMTXMODE or CONTEXTLMTXMODE==0 then - properties.encodingbytes=2 -end - properties.private=properties.private or data.private or privateoffset - return { - characters=characters, - descriptions=descriptions, - parameters=parameters, - mathparameters=mathparameters, - resources=resources, - properties=properties, - goodies=goodies, - } - end -end -local converters={ - woff={ - cachename="webfonts", - action=otf.readers.woff2otf, - } -} -local function checkconversion(specification) - local filename=specification.filename - local converter=converters[lower(file.suffix(filename))] - if converter then - local base=file.basename(filename) - local name=file.removesuffix(base) - local attr=lfs.attributes(filename) - local size=attr and attr.size or 0 - local time=attr and attr.modification or 0 - if size>0 then - local cleanname=containers.cleanname(name) - local cachename=caches.setfirstwritablefile(cleanname,converter.cachename) - if not io.exists(cachename) or (time~=lfs.attributes(cachename).modification) then - report_otf("caching font %a in %a",filename,cachename) - converter.action(filename,cachename) - lfs.touch(cachename,time,time) - end - specification.filename=cachename - end - end -end -local function otftotfm(specification) - local cache_id=specification.hash - local tfmdata=containers.read(constructors.cache,cache_id) - if not tfmdata then - checkconversion(specification) - local name=specification.name - local sub=specification.sub - local subindex=specification.subindex - local filename=specification.filename - local features=specification.features.normal - local instance=specification.instance or (features and features.axis) - local rawdata=otf.load(filename,sub,instance) - if rawdata and next(rawdata) then - local descriptions=rawdata.descriptions - rawdata.lookuphash={} - tfmdata=copytotfm(rawdata,cache_id) - if tfmdata and next(tfmdata) then - local features=constructors.checkedfeatures("otf",features) - local shared=tfmdata.shared - if not shared then - shared={} - tfmdata.shared=shared - end - shared.rawdata=rawdata - shared.dynamics={} - tfmdata.changed={} - shared.features=features - shared.processes=otf.setfeatures(tfmdata,features) - end - end - containers.write(constructors.cache,cache_id,tfmdata) - end - return tfmdata -end -local function read_from_otf(specification) - local tfmdata=otftotfm(specification) - if tfmdata then - tfmdata.properties.name=specification.name - tfmdata.properties.sub=specification.sub - tfmdata=constructors.scale(tfmdata,specification) - local allfeatures=tfmdata.shared.features or specification.features.normal - constructors.applymanipulators("otf",tfmdata,allfeatures,trace_features,report_otf) - constructors.setname(tfmdata,specification) - fonts.loggers.register(tfmdata,file.suffix(specification.filename),specification) - end - return tfmdata -end -local function checkmathsize(tfmdata,mathsize) - local mathdata=tfmdata.shared.rawdata.metadata.math - local mathsize=tonumber(mathsize) - if mathdata then - local parameters=tfmdata.parameters - parameters.scriptpercentage=mathdata.ScriptPercentScaleDown - parameters.scriptscriptpercentage=mathdata.ScriptScriptPercentScaleDown - parameters.mathsize=mathsize - end -end -registerotffeature { - name="mathsize", - description="apply mathsize specified in the font", - initializers={ - base=checkmathsize, - node=checkmathsize, - } -} -function otf.collectlookups(rawdata,kind,script,language) - if not kind then - return - end - if not script then - script=default - end - if not language then - language=default - end - local lookupcache=rawdata.lookupcache - if not lookupcache then - lookupcache={} - rawdata.lookupcache=lookupcache - end - local kindlookup=lookupcache[kind] - if not kindlookup then - kindlookup={} - lookupcache[kind]=kindlookup - end - local scriptlookup=kindlookup[script] - if not scriptlookup then - scriptlookup={} - kindlookup[script]=scriptlookup - end - local languagelookup=scriptlookup[language] - if not languagelookup then - local sequences=rawdata.resources.sequences - local featuremap={} - local featurelist={} - if sequences then - for s=1,#sequences do - local sequence=sequences[s] - local features=sequence.features - if features then - features=features[kind] - if features then - features=features[script] or features[wildcard] - if features then - features=features[language] or features[wildcard] - if features then - if not featuremap[sequence] then - featuremap[sequence]=true - featurelist[#featurelist+1]=sequence - end - end - end - end - end - end - if #featurelist==0 then - featuremap,featurelist=false,false - end - else - featuremap,featurelist=false,false - end - languagelookup={ featuremap,featurelist } - scriptlookup[language]=languagelookup - end - return unpack(languagelookup) -end -local function getgsub(tfmdata,k,kind,value) - local shared=tfmdata.shared - local rawdata=shared and shared.rawdata - if rawdata then - local sequences=rawdata.resources.sequences - if sequences then - local properties=tfmdata.properties - local validlookups,lookuplist=otf.collectlookups(rawdata,kind,properties.script,properties.language) - if validlookups then - for i=1,#lookuplist do - local lookup=lookuplist[i] - local steps=lookup.steps - local nofsteps=lookup.nofsteps - for i=1,nofsteps do - local coverage=steps[i].coverage - if coverage then - local found=coverage[k] - if found then - return found,lookup.type - end - end - end - end - end - end - end -end -otf.getgsub=getgsub -function otf.getsubstitution(tfmdata,k,kind,value) - local found,kind=getgsub(tfmdata,k,kind,value) - if not found then - elseif kind=="gsub_single" then - return found - elseif kind=="gsub_alternate" then - local choice=tonumber(value) or 1 - return found[choice] or found[1] or k - end - return k -end -otf.getalternate=otf.getsubstitution -function otf.getmultiple(tfmdata,k,kind) - local found,kind=getgsub(tfmdata,k,kind) - if found and kind=="gsub_multiple" then - return found - end - return { k } -end -function otf.getkern(tfmdata,left,right,kind) - local kerns=getgsub(tfmdata,left,kind or "kern",true) - if kerns then - local found=kerns[right] - local kind=type(found) - if kind=="table" then - found=found[1][3] - elseif kind~="number" then - found=false - end - if found then - return found*tfmdata.parameters.factor - end - end - return 0 -end -local function check_otf(forced,specification,suffix) - local name=specification.name - if forced then - name=specification.forcedname - end - local fullname=findbinfile(name,suffix) or "" - if fullname=="" then - fullname=fonts.names.getfilename(name,suffix) or "" - end - if fullname~="" and not fonts.names.ignoredfile(fullname) then - specification.filename=fullname - return read_from_otf(specification) - end -end -local function opentypereader(specification,suffix) - local forced=specification.forced or "" - if formats[forced] then - return check_otf(true,specification,forced) - else - return check_otf(false,specification,suffix) - end -end -readers.opentype=opentypereader -function readers.otf(specification) return opentypereader(specification,"otf") end -function readers.ttf(specification) return opentypereader(specification,"ttf") end -function readers.ttc(specification) return opentypereader(specification,"ttf") end -function readers.woff(specification) - checkconversion(specification) - opentypereader(specification,"") -end -function otf.scriptandlanguage(tfmdata,attr) - local properties=tfmdata.properties - return properties.script or "dflt",properties.language or "dflt" -end -local function justset(coverage,unicode,replacement) - coverage[unicode]=replacement -end -otf.coverup={ - stepkey="steps", - actions={ - chainsubstitution=justset, - chainposition=justset, - substitution=justset, - alternate=justset, - multiple=justset, - kern=justset, - pair=justset, - single=justset, - ligature=function(coverage,unicode,ligature) - local first=ligature[1] - local tree=coverage[first] - if not tree then - tree={} - coverage[first]=tree - end - for i=2,#ligature do - local l=ligature[i] - local t=tree[l] - if not t then - t={} - tree[l]=t - end - tree=t - end - tree.ligature=unicode - end, - }, - register=function(coverage,featuretype,format) - return { - format=format, - coverage=coverage, - } - end -} - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otl”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oto” 2b1d6bc63b2ebf8f2655a15e1cda6541] --- - -if not modules then modules={} end modules ['font-oto']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local concat,unpack=table.concat,table.unpack -local insert,remove=table.insert,table.remove -local format,gmatch,gsub,find,match,lower,strip=string.format,string.gmatch,string.gsub,string.find,string.match,string.lower,string.strip -local type,next,tonumber,tostring=type,next,tonumber,tostring -local trace_baseinit=false trackers.register("otf.baseinit",function(v) trace_baseinit=v end) -local trace_singles=false trackers.register("otf.singles",function(v) trace_singles=v end) -local trace_multiples=false trackers.register("otf.multiples",function(v) trace_multiples=v end) -local trace_alternatives=false trackers.register("otf.alternatives",function(v) trace_alternatives=v end) -local trace_ligatures=false trackers.register("otf.ligatures",function(v) trace_ligatures=v end) -local trace_kerns=false trackers.register("otf.kerns",function(v) trace_kerns=v end) -local trace_preparing=false trackers.register("otf.preparing",function(v) trace_preparing=v end) -local report_prepare=logs.reporter("fonts","otf prepare") -local fonts=fonts -local otf=fonts.handlers.otf -local otffeatures=otf.features -local registerotffeature=otffeatures.register -otf.defaultbasealternate="none" -local getprivate=fonts.constructors.getprivate -local wildcard="*" -local default="dflt" -local formatters=string.formatters -local f_unicode=formatters["%U"] -local f_uniname=formatters["%U (%s)"] -local f_unilist=formatters["% t (% t)"] -local function gref(descriptions,n) - if type(n)=="number" then - local name=descriptions[n].name - if name then - return f_uniname(n,name) - else - return f_unicode(n) - end - elseif n then - local num={} - local nam={} - local j=0 - for i=1,#n do - local ni=n[i] - if tonumber(ni) then - j=j+1 - local di=descriptions[ni] - num[j]=f_unicode(ni) - nam[j]=di and di.name or "-" - end - end - return f_unilist(num,nam) - else - return "" - end -end -local function cref(feature,sequence) - return formatters["feature %a, type %a, chain lookup %a"](feature,sequence.type,sequence.name) -end -local function report_substitution(feature,sequence,descriptions,unicode,substitution) - if unicode==substitution then - report_prepare("%s: base substitution %s maps onto itself", - cref(feature,sequence), - gref(descriptions,unicode)) - else - report_prepare("%s: base substitution %s => %S", - cref(feature,sequence), - gref(descriptions,unicode), - gref(descriptions,substitution)) - end -end -local function report_alternate(feature,sequence,descriptions,unicode,replacement,value,comment) - if unicode==replacement then - report_prepare("%s: base alternate %s maps onto itself", - cref(feature,sequence), - gref(descriptions,unicode)) - else - report_prepare("%s: base alternate %s => %s (%S => %S)", - cref(feature,sequence), - gref(descriptions,unicode), - replacement and gref(descriptions,replacement), - value, - comment) - end -end -local function report_ligature(feature,sequence,descriptions,unicode,ligature) - report_prepare("%s: base ligature %s => %S", - cref(feature,sequence), - gref(descriptions,ligature), - gref(descriptions,unicode)) -end -local function report_kern(feature,sequence,descriptions,unicode,otherunicode,value) - report_prepare("%s: base kern %s + %s => %S", - cref(feature,sequence), - gref(descriptions,unicode), - gref(descriptions,otherunicode), - value) -end -local basehash,basehashes,applied={},1,{} -local function registerbasehash(tfmdata) - local properties=tfmdata.properties - local hash=concat(applied," ") - local base=basehash[hash] - if not base then - basehashes=basehashes+1 - base=basehashes - basehash[hash]=base - end - properties.basehash=base - properties.fullname=(properties.fullname or properties.name).."-"..base - applied={} -end -local function registerbasefeature(feature,value) - applied[#applied+1]=feature.."="..tostring(value) -end -local function makefake(tfmdata,name,present) - local private=getprivate(tfmdata) - local character={ intermediate=true,ligatures={} } - resources.unicodes[name]=private - tfmdata.characters[private]=character - tfmdata.descriptions[private]={ name=name } - present[name]=private - return character -end -local function make_1(present,tree,name) - for k,v in next,tree do - if k=="ligature" then - present[name]=v - else - make_1(present,v,name.."_"..k) - end - end -end -local function make_2(present,tfmdata,characters,tree,name,preceding,unicode,done) - for k,v in next,tree do - if k=="ligature" then - local character=characters[preceding] - if not character then - if trace_baseinit then - report_prepare("weird ligature in lookup %a, current %C, preceding %C",sequence.name,v,preceding) - end - character=makefake(tfmdata,name,present) - end - local ligatures=character.ligatures - if ligatures then - ligatures[unicode]={ char=v } - else - character.ligatures={ [unicode]={ char=v } } - end - if done then - local d=done[name] - if not d then - done[name]={ "dummy",v } - else - d[#d+1]=v - end - end - else - local code=present[name] or unicode - local name=name.."_"..k - make_2(present,tfmdata,characters,v,name,code,k,done) - end - end -end -local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist) - local characters=tfmdata.characters - local descriptions=tfmdata.descriptions - local resources=tfmdata.resources - local changed=tfmdata.changed - local ligatures={} - local alternate=tonumber(value) or true and 1 - local defaultalt=otf.defaultbasealternate - local trace_singles=trace_baseinit and trace_singles - local trace_alternatives=trace_baseinit and trace_alternatives - local trace_ligatures=trace_baseinit and trace_ligatures - if not changed then - changed={} - tfmdata.changed=changed - end - for i=1,#lookuplist do - local sequence=lookuplist[i] - local steps=sequence.steps - local kind=sequence.type - if kind=="gsub_single" then - for i=1,#steps do - for unicode,data in next,steps[i].coverage do - if unicode~=data then - changed[unicode]=data - end - if trace_singles then - report_substitution(feature,sequence,descriptions,unicode,data) - end - end - end - elseif kind=="gsub_alternate" then - for i=1,#steps do - for unicode,data in next,steps[i].coverage do - local replacement=data[alternate] - if replacement then - if unicode~=replacement then - changed[unicode]=replacement - end - if trace_alternatives then - report_alternate(feature,sequence,descriptions,unicode,replacement,value,"normal") - end - elseif defaultalt=="first" then - replacement=data[1] - if unicode~=replacement then - changed[unicode]=replacement - end - if trace_alternatives then - report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt) - end - elseif defaultalt=="last" then - replacement=data[#data] - if unicode~=replacement then - changed[unicode]=replacement - end - if trace_alternatives then - report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt) - end - else - if trace_alternatives then - report_alternate(feature,sequence,descriptions,unicode,replacement,value,"unknown") - end - end - end - end - elseif kind=="gsub_ligature" then - for i=1,#steps do - for unicode,data in next,steps[i].coverage do - ligatures[#ligatures+1]={ unicode,data,"" } - if trace_ligatures then - report_ligature(feature,sequence,descriptions,unicode,data) - end - end - end - end - end - local nofligatures=#ligatures - if nofligatures>0 then - local characters=tfmdata.characters - local present={} - local done=trace_baseinit and trace_ligatures and {} - for i=1,nofligatures do - local ligature=ligatures[i] - local unicode=ligature[1] - local tree=ligature[2] - make_1(present,tree,"ctx_"..unicode) - end - for i=1,nofligatures do - local ligature=ligatures[i] - local unicode=ligature[1] - local tree=ligature[2] - local lookupname=ligature[3] - make_2(present,tfmdata,characters,tree,"ctx_"..unicode,unicode,unicode,done,sequence) - end - end -end -local function preparepositionings(tfmdata,feature,value,validlookups,lookuplist) - local characters=tfmdata.characters - local descriptions=tfmdata.descriptions - local resources=tfmdata.resources - local properties=tfmdata.properties - local traceindeed=trace_baseinit and trace_kerns - for i=1,#lookuplist do - local sequence=lookuplist[i] - local steps=sequence.steps - local kind=sequence.type - local format=sequence.format - if kind=="gpos_pair" then - for i=1,#steps do - local step=steps[i] - local format=step.format - if format=="kern" or format=="move" then - for unicode,data in next,steps[i].coverage do - local character=characters[unicode] - local kerns=character.kerns - if not kerns then - kerns={} - character.kerns=kerns - end - if traceindeed then - for otherunicode,kern in next,data do - if not kerns[otherunicode] and kern~=0 then - kerns[otherunicode]=kern - report_kern(feature,sequence,descriptions,unicode,otherunicode,kern) - end - end - else - for otherunicode,kern in next,data do - if not kerns[otherunicode] and kern~=0 then - kerns[otherunicode]=kern - end - end - end - end - else - for unicode,data in next,steps[i].coverage do - local character=characters[unicode] - local kerns=character.kerns - for otherunicode,kern in next,data do - local other=kern[2] - if other==true or (not other and not (kerns and kerns[otherunicode])) then - local kern=kern[1] - if kern==true then - elseif kern[1]~=0 or kern[2]~=0 or kern[4]~=0 then - else - kern=kern[3] - if kern~=0 then - if kerns then - kerns[otherunicode]=kern - else - kerns={ [otherunicode]=kern } - character.kerns=kerns - end - if traceindeed then - report_kern(feature,sequence,descriptions,unicode,otherunicode,kern) - end - end - end - end - end - end - end - end - end - end -end -local function initializehashes(tfmdata) -end -local function checkmathreplacements(tfmdata,fullname,fixitalics) - if tfmdata.mathparameters then - local characters=tfmdata.characters - local changed=tfmdata.changed - if next(changed) then - if trace_preparing or trace_baseinit then - report_prepare("checking math replacements for %a",fullname) - end - for unicode,replacement in next,changed do - local u=characters[unicode] - local r=characters[replacement] - if u and r then - local n=u.next - local v=u.vert_variants - local h=u.horiz_variants - if fixitalics then - local ui=u.italic - if ui and not r.italic then - if trace_preparing then - report_prepare("using %i units of italic correction from %C for %U",ui,unicode,replacement) - end - r.italic=ui - end - end - if n and not r.next then - if trace_preparing then - report_prepare("forcing %s for %C substituted by %U","incremental step",unicode,replacement) - end - r.next=n - end - if v and not r.vert_variants then - if trace_preparing then - report_prepare("forcing %s for %C substituted by %U","vertical variants",unicode,replacement) - end - r.vert_variants=v - end - if h and not r.horiz_variants then - if trace_preparing then - report_prepare("forcing %s for %C substituted by %U","horizontal variants",unicode,replacement) - end - r.horiz_variants=h - end - else - if trace_preparing then - report_prepare("error replacing %C by %U",unicode,replacement) - end - end - end - end - end -end -local function featuresinitializer(tfmdata,value) - if true then - local starttime=trace_preparing and os.clock() - local features=tfmdata.shared.features - local fullname=tfmdata.properties.fullname or "?" - if features then - initializehashes(tfmdata) - local collectlookups=otf.collectlookups - local rawdata=tfmdata.shared.rawdata - local properties=tfmdata.properties - local script=properties.script - local language=properties.language - local rawresources=rawdata.resources - local rawfeatures=rawresources and rawresources.features - local basesubstitutions=rawfeatures and rawfeatures.gsub - local basepositionings=rawfeatures and rawfeatures.gpos - local substitutionsdone=false - local positioningsdone=false - if basesubstitutions or basepositionings then - local sequences=tfmdata.resources.sequences - for s=1,#sequences do - local sequence=sequences[s] - local sfeatures=sequence.features - if sfeatures then - local order=sequence.order - if order then - for i=1,#order do - local feature=order[i] - local value=features[feature] - if value then - local validlookups,lookuplist=collectlookups(rawdata,feature,script,language) - if not validlookups then - elseif basesubstitutions and basesubstitutions[feature] then - if trace_preparing then - report_prepare("filtering base %s feature %a for %a with value %a","sub",feature,fullname,value) - end - preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist) - registerbasefeature(feature,value) - substitutionsdone=true - elseif basepositionings and basepositionings[feature] then - if trace_preparing then - report_prepare("filtering base %a feature %a for %a with value %a","pos",feature,fullname,value) - end - preparepositionings(tfmdata,feature,value,validlookups,lookuplist) - registerbasefeature(feature,value) - positioningsdone=true - end - end - end - end - end - end - end - if substitutionsdone then - checkmathreplacements(tfmdata,fullname,features.fixitalics) - end - registerbasehash(tfmdata) - end - if trace_preparing then - report_prepare("preparation time is %0.3f seconds for %a",os.clock()-starttime,fullname) - end - end -end -registerotffeature { - name="features", - description="features", - default=true, - initializers={ - base=featuresinitializer, - } -} -otf.basemodeinitializer=featuresinitializer - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oto”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otj” 8de59cb9b043e5f73c6b9f7cc8f6978e] --- - -if not modules then modules={} end modules ['font-otj']={ - version=1.001, - optimize=true, - comment="companion to font-lib.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files", -} -if not nodes.properties then return end -local next,rawget,tonumber=next,rawget,tonumber -local fastcopy=table.fastcopy -local registertracker=trackers.register -local registerdirective=directives.register -local trace_injections=false registertracker("fonts.injections",function(v) trace_injections=v end) -local trace_marks=false registertracker("fonts.injections.marks",function(v) trace_marks=v end) -local trace_cursive=false registertracker("fonts.injections.cursive",function(v) trace_cursive=v end) -local trace_spaces=false registertracker("fonts.injections.spaces",function(v) trace_spaces=v end) -local report_injections=logs.reporter("fonts","injections") -local report_spaces=logs.reporter("fonts","spaces") -local attributes,nodes,node=attributes,nodes,node -fonts=fonts -local hashes=fonts.hashes -local fontdata=hashes.identifiers -local fontmarks=hashes.marks -nodes.injections=nodes.injections or {} -local injections=nodes.injections -local tracers=nodes.tracers -local setcolor=tracers and tracers.colors.set -local resetcolor=tracers and tracers.colors.reset -local nodecodes=nodes.nodecodes -local glyph_code=nodecodes.glyph -local disc_code=nodecodes.disc -local kern_code=nodecodes.kern -local glue_code=nodecodes.glue -local nuts=nodes.nuts -local nodepool=nuts.pool -local tonode=nuts.tonode -local tonut=nuts.tonut -local setfield=nuts.setfield -local getnext=nuts.getnext -local getprev=nuts.getprev -local getid=nuts.getid -local getfont=nuts.getfont -local getchar=nuts.getchar -local getoffsets=nuts.getoffsets -local getboth=nuts.getboth -local getdisc=nuts.getdisc -local setdisc=nuts.setdisc -local setoffsets=nuts.setoffsets -local ischar=nuts.ischar -local getkern=nuts.getkern -local setkern=nuts.setkern -local setlink=nuts.setlink -local setwidth=nuts.setwidth -local getwidth=nuts.getwidth -local nextchar=nuts.traversers.char -local nextglue=nuts.traversers.glue -local insert_node_before=nuts.insert_before -local insert_node_after=nuts.insert_after -local properties=nodes.properties.data -local fontkern=nuts.pool and nuts.pool.fontkern -local italickern=nuts.pool and nuts.pool.italickern -local useitalickerns=false -directives.register("fonts.injections.useitalics",function(v) - if v then - report_injections("using italics for space kerns (tracing only)") - end - useitalickerns=v -end) -if not fontkern then - local thekern=nuts.new("kern",0) - local setkern=nuts.setkern - local copy_node=nuts.copy_node - fontkern=function(k) - local n=copy_node(thekern) - setkern(n,k) - return n - end -end -if not italickern then - local thekern=nuts.new("kern",3) - local setkern=nuts.setkern - local copy_node=nuts.copy_node - italickern=function(k) - local n=copy_node(thekern) - setkern(n,k) - return n - end -end -function injections.installnewkern() end -local nofregisteredkerns=0 -local nofregisteredpositions=0 -local nofregisteredmarks=0 -local nofregisteredcursives=0 -local keepregisteredcounts=false -function injections.keepcounts() - keepregisteredcounts=true -end -function injections.resetcounts() - nofregisteredkerns=0 - nofregisteredpositions=0 - nofregisteredmarks=0 - nofregisteredcursives=0 - keepregisteredcounts=false -end -function injections.reset(n) - local p=rawget(properties,n) - if p then - p.injections=false - else - properties[n]=false - end -end -function injections.copy(target,source) - local sp=rawget(properties,source) - if sp then - local tp=rawget(properties,target) - local si=sp.injections - if si then - si=fastcopy(si) - if tp then - tp.injections=si - else - properties[target]={ - injections=si, - } - end - elseif tp then - tp.injections=false - else - properties[target]={ injections={} } - end - else - local tp=rawget(properties,target) - if tp then - tp.injections=false - else - properties[target]=false - end - end -end -function injections.setligaindex(n,index) - local p=rawget(properties,n) - if p then - local i=p.injections - if i then - i.ligaindex=index - else - p.injections={ - ligaindex=index - } - end - else - properties[n]={ - injections={ - ligaindex=index - } - } - end -end -function injections.getligaindex(n,default) - local p=rawget(properties,n) - if p then - local i=p.injections - if i then - return i.ligaindex or default - end - end - return default -end -function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext,r2lflag) - local dx=factor*(exit[1]-entry[1]) - local dy=-factor*(exit[2]-entry[2]) - local ws=tfmstart.width - local wn=tfmnext.width - nofregisteredcursives=nofregisteredcursives+1 - if rlmode<0 then - dx=-(dx+wn) - else - dx=dx-ws - end - if dx==0 then - dx=0 - end - local p=rawget(properties,start) - if p then - local i=p.injections - if i then - i.cursiveanchor=true - else - p.injections={ - cursiveanchor=true, - } - end - else - properties[start]={ - injections={ - cursiveanchor=true, - }, - } - end - local p=rawget(properties,nxt) - if p then - local i=p.injections - if i then - i.cursivex=dx - i.cursivey=dy - else - p.injections={ - cursivex=dx, - cursivey=dy, - } - end - else - properties[nxt]={ - injections={ - cursivex=dx, - cursivey=dy, - }, - } - end - return dx,dy,nofregisteredcursives -end -function injections.setposition(kind,current,factor,rlmode,spec,injection) - local x=factor*(spec[1] or 0) - local y=factor*(spec[2] or 0) - local w=factor*(spec[3] or 0) - local h=factor*(spec[4] or 0) - if x~=0 or w~=0 or y~=0 or h~=0 then - local yoffset=y-h - local leftkern=x - local rightkern=w-x - if leftkern~=0 or rightkern~=0 or yoffset~=0 then - nofregisteredpositions=nofregisteredpositions+1 - if rlmode and rlmode<0 then - leftkern,rightkern=rightkern,leftkern - end - if not injection then - injection="injections" - end - local p=rawget(properties,current) - if p then - local i=p[injection] - if i then - if leftkern~=0 then - i.leftkern=(i.leftkern or 0)+leftkern - end - if rightkern~=0 then - i.rightkern=(i.rightkern or 0)+rightkern - end - if yoffset~=0 then - i.yoffset=(i.yoffset or 0)+yoffset - end - elseif leftkern~=0 or rightkern~=0 then - p[injection]={ - leftkern=leftkern, - rightkern=rightkern, - yoffset=yoffset, - } - else - p[injection]={ - yoffset=yoffset, - } - end - elseif leftkern~=0 or rightkern~=0 then - properties[current]={ - [injection]={ - leftkern=leftkern, - rightkern=rightkern, - yoffset=yoffset, - }, - } - else - properties[current]={ - [injection]={ - yoffset=yoffset, - }, - } - end - return x,y,w,h,nofregisteredpositions - end - end - return x,y,w,h -end -function injections.setkern(current,factor,rlmode,x,injection) - local dx=factor*x - if dx~=0 then - nofregisteredkerns=nofregisteredkerns+1 - local p=rawget(properties,current) - if not injection then - injection="injections" - end - if p then - local i=p[injection] - if i then - i.leftkern=dx+(i.leftkern or 0) - else - p[injection]={ - leftkern=dx, - } - end - else - properties[current]={ - [injection]={ - leftkern=dx, - }, - } - end - return dx,nofregisteredkerns - else - return 0,0 - end -end -function injections.setmove(current,factor,rlmode,x,injection) - local dx=factor*x - if dx~=0 then - nofregisteredkerns=nofregisteredkerns+1 - local p=rawget(properties,current) - if not injection then - injection="injections" - end - if rlmode and rlmode<0 then - if p then - local i=p[injection] - if i then - i.rightkern=dx+(i.rightkern or 0) - else - p[injection]={ - rightkern=dx, - } - end - else - properties[current]={ - [injection]={ - rightkern=dx, - }, - } - end - else - if p then - local i=p[injection] - if i then - i.leftkern=dx+(i.leftkern or 0) - else - p[injection]={ - leftkern=dx, - } - end - else - properties[current]={ - [injection]={ - leftkern=dx, - }, - } - end - end - return dx,nofregisteredkerns - else - return 0,0 - end -end -function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmark) - local dx=factor*(ba[1]-ma[1]) - local dy=factor*(ba[2]-ma[2]) - nofregisteredmarks=nofregisteredmarks+1 - if rlmode>=0 then - dx=tfmbase.width-dx - end - local p=rawget(properties,start) - if p then - local i=p.injections - if i then - if i.markmark then - else - i.markx=dx - i.marky=dy - i.markdir=rlmode or 0 - i.markbase=nofregisteredmarks - i.markbasenode=base - i.markmark=mkmk - i.checkmark=checkmark - end - else - p.injections={ - markx=dx, - marky=dy, - markdir=rlmode or 0, - markbase=nofregisteredmarks, - markbasenode=base, - markmark=mkmk, - checkmark=checkmark, - } - end - else - properties[start]={ - injections={ - markx=dx, - marky=dy, - markdir=rlmode or 0, - markbase=nofregisteredmarks, - markbasenode=base, - markmark=mkmk, - checkmark=checkmark, - }, - } - end - return dx,dy,nofregisteredmarks -end -local function dir(n) - return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or "unset" -end -local function showchar(n,nested) - local char=getchar(n) - report_injections("%wfont %s, char %U, glyph %c",nested and 2 or 0,getfont(n),char,char) -end -local function show(n,what,nested,symbol) - if n then - local p=rawget(properties,n) - if p then - local i=p[what] - if i then - local leftkern=i.leftkern or 0 - local rightkern=i.rightkern or 0 - local yoffset=i.yoffset or 0 - local markx=i.markx or 0 - local marky=i.marky or 0 - local markdir=i.markdir or 0 - local markbase=i.markbase or 0 - local cursivex=i.cursivex or 0 - local cursivey=i.cursivey or 0 - local ligaindex=i.ligaindex or 0 - local cursbase=i.cursiveanchor - local margin=nested and 4 or 2 - if rightkern~=0 or yoffset~=0 then - report_injections("%w%s pair: lx %p, rx %p, dy %p",margin,symbol,leftkern,rightkern,yoffset) - elseif leftkern~=0 then - report_injections("%w%s kern: dx %p",margin,symbol,leftkern) - end - if markx~=0 or marky~=0 or markbase~=0 then - report_injections("%w%s mark: dx %p, dy %p, dir %s, base %s",margin,symbol,markx,marky,markdir,markbase~=0 and "yes" or "no") - end - if cursivex~=0 or cursivey~=0 then - if cursbase then - report_injections("%w%s curs: base dx %p, dy %p",margin,symbol,cursivex,cursivey) - else - report_injections("%w%s curs: dx %p, dy %p",margin,symbol,cursivex,cursivey) - end - elseif cursbase then - report_injections("%w%s curs: base",margin,symbol) - end - if ligaindex~=0 then - report_injections("%w%s liga: index %i",margin,symbol,ligaindex) - end - end - end - end -end -local function showsub(n,what,where) - report_injections("begin subrun: %s",where) - for n in nextchar,n do - showchar(n,where) - show(n,what,where," ") - end - report_injections("end subrun") -end -local function trace(head,where) - report_injections() - report_injections("begin run %s: %s kerns, %s positions, %s marks and %s cursives registered", - where or "",nofregisteredkerns,nofregisteredpositions,nofregisteredmarks,nofregisteredcursives) - local n=head - while n do - local id=getid(n) - if id==glyph_code then - showchar(n) - show(n,"injections",false," ") - show(n,"preinjections",false,"<") - show(n,"postinjections",false,">") - show(n,"replaceinjections",false,"=") - show(n,"emptyinjections",false,"*") - elseif id==disc_code then - local pre,post,replace=getdisc(n) - if pre then - showsub(pre,"preinjections","pre") - end - if post then - showsub(post,"postinjections","post") - end - if replace then - showsub(replace,"replaceinjections","replace") - end - show(n,"emptyinjections",false,"*") - end - n=getnext(n) - end - report_injections("end run") -end -local function show_result(head) - local current=head - local skipping=false - while current do - local id=getid(current) - if id==glyph_code then - local w=getwidth(current) - local x,y=getoffsets(current) - report_injections("char: %C, width %p, xoffset %p, yoffset %p",getchar(current),w,x,y) - skipping=false - elseif id==kern_code then - report_injections("kern: %p",getkern(current)) - skipping=false - elseif not skipping then - report_injections() - skipping=true - end - current=getnext(current) - end - report_injections() -end -local function inject_kerns_only(head,where) - if trace_injections then - trace(head,"kerns") - end - local current=head - local prev=nil - local next=nil - local prevdisc=nil - local pre=nil - local post=nil - local replace=nil - local pretail=nil - local posttail=nil - local replacetail=nil - while current do - local next=getnext(current) - local char,id=ischar(current) - if char then - local p=rawget(properties,current) - if p then - local i=p.injections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - if prev and getid(prev)==glue_code then - if useitalickerns then - head=insert_node_before(head,current,italickern(leftkern)) - else - setwidth(prev,getwidth(prev)+leftkern) - end - else - head=insert_node_before(head,current,fontkern(leftkern)) - end - end - end - if prevdisc then - local done=false - if post then - local i=p.postinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setlink(posttail,fontkern(leftkern)) - done=true - end - end - end - if replace then - local i=p.replaceinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setlink(replacetail,fontkern(leftkern)) - done=true - end - end - else - local i=p.emptyinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - replace=fontkern(leftkern) - done=true - end - end - end - if done then - setdisc(prevdisc,pre,post,replace) - end - end - end - prevdisc=nil - elseif char==false then - prevdisc=nil - elseif id==disc_code then - pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) - local done=false - if pre then - for n in nextchar,pre do - local p=rawget(properties,n) - if p then - local i=p.injections or p.preinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - pre=insert_node_before(pre,n,fontkern(leftkern)) - done=true - end - end - end - end - end - if post then - for n in nextchar,post do - local p=rawget(properties,n) - if p then - local i=p.injections or p.postinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - post=insert_node_before(post,n,fontkern(leftkern)) - done=true - end - end - end - end - end - if replace then - for n in nextchar,replace do - local p=rawget(properties,n) - if p then - local i=p.injections or p.replaceinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - replace=insert_node_before(replace,n,fontkern(leftkern)) - done=true - end - end - end - end - end - if done then - setdisc(current,pre,post,replace) - end - prevdisc=current - else - prevdisc=nil - end - prev=current - current=next - end - if keepregisteredcounts then - keepregisteredcounts=false - else - nofregisteredkerns=0 - end - if trace_injections then - show_result(head) - end - return head -end -local function inject_positions_only(head,where) - if trace_injections then - trace(head,"positions") - end - local current=head - local prev=nil - local next=nil - local prevdisc=nil - local prevglyph=nil - local pre=nil - local post=nil - local replace=nil - local pretail=nil - local posttail=nil - local replacetail=nil - while current do - local next=getnext(current) - local char,id=ischar(current) - if char then - local p=rawget(properties,current) - if p then - local i=p.injections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(current,false,yoffset) - end - local leftkern=i.leftkern - local rightkern=i.rightkern - if leftkern and leftkern~=0 then - if rightkern and leftkern==-rightkern then - setoffsets(current,leftkern,false) - rightkern=0 - elseif prev and getid(prev)==glue_code then - if useitalickerns then - head=insert_node_before(head,current,italickern(leftkern)) - else - setwidth(prev,getwidth(prev)+leftkern) - end - else - head=insert_node_before(head,current,fontkern(leftkern)) - end - end - if rightkern and rightkern~=0 then - if next and getid(next)==glue_code then - if useitalickerns then - insert_node_after(head,current,italickern(rightkern)) - else - setwidth(next,getwidth(next)+rightkern) - end - else - insert_node_after(head,current,fontkern(rightkern)) - end - end - else - local i=p.emptyinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - if next and getid(next)==disc_code then - if replace then - else - replace=fontkern(rightkern) - done=true - end - end - end - end - end - if prevdisc then - local done=false - if post then - local i=p.postinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setlink(posttail,fontkern(leftkern)) - done=true - end - end - end - if replace then - local i=p.replaceinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setlink(replacetail,fontkern(leftkern)) - done=true - end - end - else - local i=p.emptyinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - replace=fontkern(leftkern) - done=true - end - end - end - if done then - setdisc(prevdisc,pre,post,replace) - end - end - end - prevdisc=nil - prevglyph=current - elseif char==false then - prevdisc=nil - prevglyph=current - elseif id==disc_code then - pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) - local done=false - if pre then - for n in nextchar,pre do - local p=rawget(properties,n) - if p then - local i=p.injections or p.preinjections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(n,false,yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - pre=insert_node_before(pre,n,fontkern(leftkern)) - done=true - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(pre,n,fontkern(rightkern)) - done=true - end - end - end - end - end - if post then - for n in nextchar,post do - local p=rawget(properties,n) - if p then - local i=p.injections or p.postinjections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(n,false,yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - post=insert_node_before(post,n,fontkern(leftkern)) - done=true - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(post,n,fontkern(rightkern)) - done=true - end - end - end - end - end - if replace then - for n in nextchar,replace do - local p=rawget(properties,n) - if p then - local i=p.injections or p.replaceinjections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(n,false,yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - replace=insert_node_before(replace,n,fontkern(leftkern)) - done=true - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(replace,n,fontkern(rightkern)) - done=true - end - end - end - end - end - if prevglyph then - if pre then - local p=rawget(properties,prevglyph) - if p then - local i=p.preinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - pre=insert_node_before(pre,pre,fontkern(rightkern)) - done=true - end - end - end - end - if replace then - local p=rawget(properties,prevglyph) - if p then - local i=p.replaceinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - replace=insert_node_before(replace,replace,fontkern(rightkern)) - done=true - end - end - end - end - end - if done then - setdisc(current,pre,post,replace) - end - prevglyph=nil - prevdisc=current - else - prevglyph=nil - prevdisc=nil - end - prev=current - current=next - end - if keepregisteredcounts then - keepregisteredcounts=false - else - nofregisteredpositions=0 - end - if trace_injections then - show_result(head) - end - return head -end -local function showoffset(n,flag) - local x,y=getoffsets(n) - if x~=0 or y~=0 then - setcolor(n,"darkgray") - end -end -local function inject_everything(head,where) - if trace_injections then - trace(head,"everything") - end - local hascursives=nofregisteredcursives>0 - local hasmarks=nofregisteredmarks>0 - local current=head - local last=nil - local prev=nil - local next=nil - local prevdisc=nil - local prevglyph=nil - local pre=nil - local post=nil - local replace=nil - local pretail=nil - local posttail=nil - local replacetail=nil - local cursiveanchor=nil - local minc=0 - local maxc=0 - local glyphs={} - local marks={} - local nofmarks=0 - local function processmark(p,n,pn) - local px,py=getoffsets(p) - local nx,ny=getoffsets(n) - local ox=0 - local rightkern=nil - local pp=rawget(properties,p) - if pp then - pp=pp.injections - if pp then - rightkern=pp.rightkern - end - end - local markdir=pn.markdir - if rightkern then - ox=px-(pn.markx or 0)-rightkern - if markdir and markdir<0 then - if not pn.markmark then - ox=ox+(pn.leftkern or 0) - end - else - if false then - local leftkern=pp.leftkern - if leftkern then - ox=ox-leftkern - end - end - end - else - ox=px-(pn.markx or 0) - if markdir and markdir<0 then - if not pn.markmark then - local leftkern=pn.leftkern - if leftkern then - ox=ox+leftkern - end - end - end - if pn.checkmark then - local wn=getwidth(n) - if wn and wn~=0 then - wn=wn/2 - if trace_injections then - report_injections("correcting non zero width mark %C",getchar(n)) - end - insert_node_before(n,n,fontkern(-wn)) - insert_node_after(n,n,fontkern(-wn)) - end - end - end - local oy=ny+py+(pn.marky or 0) - if not pn.markmark then - local yoffset=pn.yoffset - if yoffset then - oy=oy+yoffset - end - end - setoffsets(n,ox,oy) - if trace_marks then - showoffset(n,true) - end - end - while current do - local next=getnext(current) - local char,id=ischar(current) - if char then - local p=rawget(properties,current) - if p then - local i=p.injections - if i then - local pm=i.markbasenode - if pm then - nofmarks=nofmarks+1 - marks[nofmarks]=current - else - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(current,false,yoffset) - end - if hascursives then - local cursivex=i.cursivex - if cursivex then - if cursiveanchor then - if cursivex~=0 then - i.leftkern=(i.leftkern or 0)+cursivex - end - if maxc==0 then - minc=1 - maxc=1 - glyphs[1]=cursiveanchor - else - maxc=maxc+1 - glyphs[maxc]=cursiveanchor - end - properties[cursiveanchor].cursivedy=i.cursivey - last=current - else - maxc=0 - end - elseif maxc>0 then - local nx,ny=getoffsets(current) - for i=maxc,minc,-1 do - local ti=glyphs[i] - ny=ny+properties[ti].cursivedy - setoffsets(ti,false,ny) - if trace_cursive then - showoffset(ti) - end - end - maxc=0 - cursiveanchor=nil - end - if i.cursiveanchor then - cursiveanchor=current - else - if maxc>0 then - local nx,ny=getoffsets(current) - for i=maxc,minc,-1 do - local ti=glyphs[i] - ny=ny+properties[ti].cursivedy - setoffsets(ti,false,ny) - if trace_cursive then - showoffset(ti) - end - end - maxc=0 - end - cursiveanchor=nil - end - end - local leftkern=i.leftkern - local rightkern=i.rightkern - if leftkern and leftkern~=0 then - if rightkern and leftkern==-rightkern then - setoffsets(current,leftkern,false) - rightkern=0 - elseif prev and getid(prev)==glue_code then - if useitalickerns then - head=insert_node_before(head,current,italickern(leftkern)) - else - setwidth(prev,getwidth(prev)+leftkern) - end - else - head=insert_node_before(head,current,fontkern(leftkern)) - end - end - if rightkern and rightkern~=0 then - if next and getid(next)==glue_code then - if useitalickerns then - insert_node_after(head,current,italickern(rightkern)) - else - setwidth(next,getwidth(next)+rightkern) - end - else - insert_node_after(head,current,fontkern(rightkern)) - end - end - end - else - local i=p.emptyinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - if next and getid(next)==disc_code then - if replace then - else - replace=fontkern(rightkern) - done=true - end - end - end - end - end - if prevdisc then - if p then - local done=false - if post then - local i=p.postinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setlink(posttail,fontkern(leftkern)) - done=true - end - end - end - if replace then - local i=p.replaceinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setlink(replacetail,fontkern(leftkern)) - done=true - end - end - else - local i=p.emptyinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - replace=fontkern(leftkern) - done=true - end - end - end - if done then - setdisc(prevdisc,pre,post,replace) - end - end - end - else - if hascursives and maxc>0 then - local nx,ny=getoffsets(current) - for i=maxc,minc,-1 do - local ti=glyphs[i] - ny=ny+properties[ti].cursivedy - local xi,yi=getoffsets(ti) - setoffsets(ti,xi,yi+ny) - end - maxc=0 - cursiveanchor=nil - end - end - prevdisc=nil - prevglyph=current - elseif char==false then - prevdisc=nil - prevglyph=current - elseif id==disc_code then - pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) - local done=false - if pre then - for n in nextchar,pre do - local p=rawget(properties,n) - if p then - local i=p.injections or p.preinjections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(n,false,yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - pre=insert_node_before(pre,n,fontkern(leftkern)) - done=true - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(pre,n,fontkern(rightkern)) - done=true - end - if hasmarks then - local pm=i.markbasenode - if pm then - processmark(pm,n,i) - end - end - end - end - end - end - if post then - for n in nextchar,post do - local p=rawget(properties,n) - if p then - local i=p.injections or p.postinjections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(n,false,yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - post=insert_node_before(post,n,fontkern(leftkern)) - done=true - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(post,n,fontkern(rightkern)) - done=true - end - if hasmarks then - local pm=i.markbasenode - if pm then - processmark(pm,n,i) - end - end - end - end - end - end - if replace then - for n in nextchar,replace do - local p=rawget(properties,n) - if p then - local i=p.injections or p.replaceinjections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(n,false,yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - replace=insert_node_before(replace,n,fontkern(leftkern)) - done=true - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(replace,n,fontkern(rightkern)) - done=true - end - if hasmarks then - local pm=i.markbasenode - if pm then - processmark(pm,n,i) - end - end - end - end - end - end - if prevglyph then - if pre then - local p=rawget(properties,prevglyph) - if p then - local i=p.preinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - pre=insert_node_before(pre,pre,fontkern(rightkern)) - done=true - end - end - end - end - if replace then - local p=rawget(properties,prevglyph) - if p then - local i=p.replaceinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - replace=insert_node_before(replace,replace,fontkern(rightkern)) - done=true - end - end - end - end - end - if done then - setdisc(current,pre,post,replace) - end - prevglyph=nil - prevdisc=current - else - prevglyph=nil - prevdisc=nil - end - prev=current - current=next - end - if hascursives and maxc>0 then - local nx,ny=getoffsets(last) - for i=maxc,minc,-1 do - local ti=glyphs[i] - ny=ny+properties[ti].cursivedy - setoffsets(ti,false,ny) - if trace_cursive then - showoffset(ti) - end - end - end - if nofmarks>0 then - for i=1,nofmarks do - local m=marks[i] - local p=rawget(properties,m) - local i=p.injections - local b=i.markbasenode - processmark(b,m,i) - end - elseif hasmarks then - end - if keepregisteredcounts then - keepregisteredcounts=false - else - nofregisteredkerns=0 - nofregisteredpositions=0 - nofregisteredmarks=0 - nofregisteredcursives=0 - end - if trace_injections then - show_result(head) - end - return head -end -local triggers=false -function nodes.injections.setspacekerns(font,sequence) - if triggers then - triggers[font]=sequence - else - triggers={ [font]=sequence } - end -end -local getthreshold -if context then - local threshold=1 - local parameters=fonts.hashes.parameters - directives.register("otf.threshold",function(v) threshold=tonumber(v) or 1 end) - getthreshold=function(font) - local p=parameters[font] - local f=p.factor - local s=p.spacing - local t=threshold*(s and s.width or p.space or 0)-2 - return t>0 and t or 0,f - end -else - injections.threshold=0 - getthreshold=function(font) - local p=fontdata[font].parameters - local f=p.factor - local s=p.spacing - local t=injections.threshold*(s and s.width or p.space or 0)-2 - return t>0 and t or 0,f - end -end -injections.getthreshold=getthreshold -function injections.isspace(n,threshold,id) - if (id or getid(n))==glue_code then - local w=getwidth(n) - if threshold and w>threshold then - return 32 - end - end -end -local getspaceboth=getboth -function injections.installgetspaceboth(gb) - getspaceboth=gb or getboth -end -local function injectspaces(head) - if not triggers then - return head - end - local lastfont=nil - local spacekerns=nil - local leftkerns=nil - local rightkerns=nil - local factor=0 - local threshold=0 - local leftkern=false - local rightkern=false - local function updatefont(font,trig) - leftkerns=trig.left - rightkerns=trig.right - lastfont=font - threshold, - factor=getthreshold(font) - end - for n in nextglue,head do - local prev,next=getspaceboth(n) - local prevchar=prev and ischar(prev) - local nextchar=next and ischar(next) - if nextchar then - local font=getfont(next) - local trig=triggers[font] - if trig then - if lastfont~=font then - updatefont(font,trig) - end - if rightkerns then - rightkern=rightkerns[nextchar] - end - end - end - if prevchar then - local font=getfont(prev) - local trig=triggers[font] - if trig then - if lastfont~=font then - updatefont(font,trig) - end - if leftkerns then - leftkern=leftkerns[prevchar] - end - end - end - if leftkern then - local old=getwidth(n) - if old>threshold then - if rightkern then - if useitalickerns then - local lnew=leftkern*factor - local rnew=rightkern*factor - if trace_spaces then - report_spaces("%C [%p + %p + %p] %C",prevchar,lnew,old,rnew,nextchar) - end - head=insert_node_before(head,n,italickern(lnew)) - insert_node_after(head,n,italickern(rnew)) - else - local new=old+(leftkern+rightkern)*factor - if trace_spaces then - report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar) - end - setwidth(n,new) - end - rightkern=false - else - if useitalickerns then - local new=leftkern*factor - if trace_spaces then - report_spaces("%C [%p + %p]",prevchar,old,new) - end - insert_node_after(head,n,italickern(new)) - else - local new=old+leftkern*factor - if trace_spaces then - report_spaces("%C [%p -> %p]",prevchar,old,new) - end - setwidth(n,new) - end - end - end - leftkern=false - elseif rightkern then - local old=getwidth(n) - if old>threshold then - if useitalickerns then - local new=rightkern*factor - if trace_spaces then - report_spaces("[%p + %p] %C",old,new,nextchar) - end - insert_node_after(head,n,italickern(new)) - else - local new=old+rightkern*factor - if trace_spaces then - report_spaces("[%p -> %p] %C",old,new,nextchar) - end - setwidth(n,new) - end - else - end - rightkern=false - end - end - triggers=false - return head -end -function injections.handler(head,where) - if triggers then - head=injectspaces(head) - end - if nofregisteredmarks>0 or nofregisteredcursives>0 then - if trace_injections then - report_injections("injection variant %a","everything") - end - return inject_everything(head,where) - elseif nofregisteredpositions>0 then - if trace_injections then - report_injections("injection variant %a","positions") - end - return inject_positions_only(head,where) - elseif nofregisteredkerns>0 then - if trace_injections then - report_injections("injection variant %a","kerns") - end - return inject_kerns_only(head,where) - else - return head - end -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otj”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ota” ad1d5de06400f88829509e1f3ff2b473] --- - -if not modules then modules={} end modules ['font-ota']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local type=type -local setmetatableindex=table.setmetatableindex -if not trackers then trackers={ register=function() end } end -local fonts,nodes,node=fonts,nodes,node -local allocate=utilities.storage.allocate -local otf=fonts.handlers.otf -local analyzers=fonts.analyzers -local initializers=allocate() -local methods=allocate() -analyzers.initializers=initializers -analyzers.methods=methods -local nuts=nodes.nuts -local tonut=nuts.tonut -local getnext=nuts.getnext -local getprev=nuts.getprev -local getprev=nuts.getprev -local getprop=nuts.getprop -local setprop=nuts.setprop -local getsubtype=nuts.getsubtype -local getchar=nuts.getchar -local ischar=nuts.ischar -local end_of_math=nuts.end_of_math -local nodecodes=nodes.nodecodes -local disc_code=nodecodes.disc -local math_code=nodecodes.math -local fontdata=fonts.hashes.identifiers -local categories=characters and characters.categories or {} -local chardata=characters and characters.data -local otffeatures=fonts.constructors.features.otf -local registerotffeature=otffeatures.register -local setstate=nuts.setstate -local getstate=nuts.getstate -if not setstate or not getstate then - setstate=function(n,v) - setprop(n,"state",v) - end - getstate=function(n,v) - local s=getprop(n,"state") - if v then - return s==v - else - return s - end - end - nuts.setstate=setstate - nuts.getstate=getstate -end -local s_init=1 local s_rphf=7 -local s_medi=2 local s_half=8 -local s_fina=3 local s_pref=9 -local s_isol=4 local s_blwf=10 -local s_mark=5 local s_pstf=11 -local s_rest=6 -local states=allocate { - init=s_init, - medi=s_medi, - med2=s_medi, - fina=s_fina, - fin2=s_fina, - fin3=s_fina, - isol=s_isol, - mark=s_mark, - rest=s_rest, - rphf=s_rphf, - half=s_half, - pref=s_pref, - blwf=s_blwf, - pstf=s_pstf, -} -local features=allocate { - init=s_init, - medi=s_medi, - med2=s_medi, - fina=s_fina, - fin2=s_fina, - fin3=s_fina, - isol=s_isol, - rphf=s_rphf, - half=s_half, - pref=s_pref, - blwf=s_blwf, - pstf=s_pstf, -} -analyzers.states=states -analyzers.features=features -analyzers.useunicodemarks=false -function analyzers.setstate(head,font) - local useunicodemarks=analyzers.useunicodemarks - local tfmdata=fontdata[font] - local descriptions=tfmdata.descriptions - local first,last,current,n,done=nil,nil,head,0,false - current=tonut(current) - while current do - local char,id=ischar(current,font) - if char and not getstate(current) then - done=true - local d=descriptions[char] - if d then - if d.class=="mark" then - done=true - setstate(current,s_mark) - elseif useunicodemarks and categories[char]=="mn" then - done=true - setstate(current,s_mark) - elseif n==0 then - first,last,n=current,current,1 - setstate(current,s_init) - else - last,n=current,n+1 - setstate(current,s_medi) - end - else - if first and first==last then - setstate(last,s_isol) - elseif last then - setstate(last,s_fina) - end - first,last,n=nil,nil,0 - end - elseif char==false then - if first and first==last then - setstate(last,s_isol) - elseif last then - setstate(last,s_fina) - end - first,last,n=nil,nil,0 - if id==math_code then - current=end_of_math(current) - end - elseif id==disc_code then - setstate(current,s_medi) - last=current - else - if first and first==last then - setstate(last,s_isol) - elseif last then - setstate(last,s_fina) - end - first,last,n=nil,nil,0 - if id==math_code then - current=end_of_math(current) - end - end - current=getnext(current) - end - if first and first==last then - setstate(last,s_isol) - elseif last then - setstate(last,s_fina) - end - return head,done -end -local function analyzeinitializer(tfmdata,value) - local script,language=otf.scriptandlanguage(tfmdata) - local action=initializers[script] - if not action then - elseif type(action)=="function" then - return action(tfmdata,value) - else - local action=action[language] - if action then - return action(tfmdata,value) - end - end -end -local function analyzeprocessor(head,font,attr) - local tfmdata=fontdata[font] - local script,language=otf.scriptandlanguage(tfmdata,attr) - local action=methods[script] - if not action then - elseif type(action)=="function" then - return action(head,font,attr) - else - action=action[language] - if action then - return action(head,font,attr) - end - end - return head,false -end -registerotffeature { - name="analyze", - description="analysis of character classes", - default=true, - initializers={ - node=analyzeinitializer, - }, - processors={ - position=1, - node=analyzeprocessor, - } -} -methods.latn=analyzers.setstate -local arab_warned={} -local function warning(current,what) - local char=getchar(current) - if not arab_warned[char] then - log.report("analyze","arab: character %C has no %a class",char,what) - arab_warned[char]=true - end -end -local mappers=allocate { - l=s_init, - d=s_medi, - c=s_medi, - r=s_fina, - u=s_isol, -} -local classifiers=characters.classifiers -if not classifiers then - local f_arabic,l_arabic=characters.blockrange("arabic") - local f_syriac,l_syriac=characters.blockrange("syriac") - local f_mandiac,l_mandiac=characters.blockrange("mandiac") - local f_nko,l_nko=characters.blockrange("nko") - local f_ext_a,l_ext_a=characters.blockrange("arabicextendeda") - classifiers=setmetatableindex(function(t,k) - if type(k)=="number" then - local c=chardata[k] - local v=false - if c then - local arabic=c.arabic - if arabic then - v=mappers[arabic] - if not v then - log.report("analyze","error in mapping arabic %C",k) - v=false - end - elseif (k>=f_arabic and k<=l_arabic) or - (k>=f_syriac and k<=l_syriac) or - (k>=f_mandiac and k<=l_mandiac) or - (k>=f_nko and k<=l_nko) or - (k>=f_ext_a and k<=l_ext_a) then - if categories[k]=="mn" then - v=s_mark - else - v=s_rest - end - end - end - t[k]=v - return v - end - end) - characters.classifiers=classifiers -end -function methods.arab(head,font,attr) - local first,last,c_first,c_last - local current=head - local done=false - current=tonut(current) - while current do - local char,id=ischar(current,font) - if char and not getstate(current) then - done=true - local classifier=classifiers[char] - if not classifier then - if last then - if c_last==s_medi or c_last==s_fina then - setstate(last,s_fina) - else - warning(last,"fina") - setstate(last,s_error) - end - first,last=nil,nil - elseif first then - if c_first==s_medi or c_first==s_fina then - setstate(first,s_isol) - else - warning(first,"isol") - setstate(first,s_error) - end - first=nil - end - elseif classifier==s_mark then - setstate(current,s_mark) - elseif classifier==s_isol then - if last then - if c_last==s_medi or c_last==s_fina then - setstate(last,s_fina) - else - warning(last,"fina") - setstate(last,s_error) - end - first,last=nil,nil - elseif first then - if c_first==s_medi or c_first==s_fina then - setstate(first,s_isol) - else - warning(first,"isol") - setstate(first,s_error) - end - first=nil - end - setstate(current,s_isol) - elseif classifier==s_medi then - if first then - last=current - c_last=classifier - setstate(current,s_medi) - else - setstate(current,s_init) - first=current - c_first=classifier - end - elseif classifier==s_fina then - if last then - if getstate(last)~=s_init then - setstate(last,s_medi) - end - setstate(current,s_fina) - first,last=nil,nil - elseif first then - setstate(current,s_fina) - first=nil - else - setstate(current,s_isol) - end - else - setstate(current,s_rest) - if last then - if c_last==s_medi or c_last==s_fina then - setstate(last,s_fina) - else - warning(last,"fina") - setstate(last,s_error) - end - first,last=nil,nil - elseif first then - if c_first==s_medi or c_first==s_fina then - setstate(first,s_isol) - else - warning(first,"isol") - setstate(first,s_error) - end - first=nil - end - end - else - if last then - if c_last==s_medi or c_last==s_fina then - setstate(last,s_fina) - else - warning(last,"fina") - setstate(last,s_error) - end - first,last=nil,nil - elseif first then - if c_first==s_medi or c_first==s_fina then - setstate(first,s_isol) - else - warning(first,"isol") - setstate(first,s_error) - end - first=nil - end - if id==math_code then - current=end_of_math(current) - end - end - current=getnext(current) - end - if last then - if c_last==s_medi or c_last==s_fina then - setstate(last,s_fina) - else - warning(last,"fina") - setstate(last,s_error) - end - elseif first then - if c_first==s_medi or c_first==s_fina then - setstate(first,s_isol) - else - warning(first,"isol") - setstate(first,s_error) - end - end - return head,done -end -methods.syrc=methods.arab -methods.mand=methods.arab -methods.nko=methods.arab -do - local joining=setmetatableindex(function(t,k) - if type(k)=="number" then - local c=chardata[k] - local v=false - if c then - local mongolian=c.mongolian - v=mongolian - end - t[k]=v - return v - end - end) - function methods.mong(head,font,attr) - local first,last - local current=head - local done=false - local prevjoin=nil - local prestate=nil - current=tonut(current) - local function wrapup() - if last then - if last~=first then - local s=getstate(last) - if s==s_medi then - setstate(last,s_fina) - elseif s==s_init then - setstate(last,s_isol) - end - end - last=nil - first=nil - prevjoin=nil - prestate=nil - end - end - while current do - local char,id=ischar(current,font) - if char and not getstate(current) then - local currjoin=joining[char] - done=true - if not last then - setstate(current,s_isol) - prevjoin=currjoin - first=current - last=current - prevstate=s_isol - elseif currjoin=="t" then - last=current - elseif prevjoin=="d" or prevjoin=="jc" or prevjoin=="l" then - if currjoin=="d" or prevjoin=="jc" or prevjoin=="r" then - local s=getstate(last) - if s==s_isol then - setstate(last,s_init) - elseif s==s_fina then - setstate(last,s_medi) - end - setstate(current,s_fina) - prevstate=s_fina - elseif prevjoin=="nj" or prevjoin=="l" then - local s=getstate(last) - if s==s_medi then - setstate(last,s_fina) - elseif s==s_init then - setstate(last,s_isol) - end - setstate(current,s_isol) - prevstate=s_isol - end - prevjoin=currjoin - last=current - elseif prevjoin=="nj" or prevjoin=="r" then - if s==s_medi then - setstate(last,s_fina) - elseif s==s_init then - setstate(last,s_isol) - end - setstate(current,s_isol) - prevjoin=currjoin - prevstate=s_isol - last=current - elseif last then - wrapup() - end - else - if last then - wrapup() - end - if id==math_code then - current=end_of_math(current) - end - end - current=getnext(current) - end - if last then - wrapup() - end - return head,done - end -end -directives.register("otf.analyze.useunicodemarks",function(v) - analyzers.useunicodemarks=v -end) - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ota”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ots” 91c79619c386e4a96954f3115f398b94] --- - -if not modules then modules={} end modules ['font-ots']={ - version=1.001, - optimize=true, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files", -} -local type,next,tonumber=type,next,tonumber -local random=math.random -local formatters=string.formatters -local insert=table.insert -local registertracker=trackers.register -local logs=logs -local trackers=trackers -local nodes=nodes -local attributes=attributes -local fonts=fonts -local otf=fonts.handlers.otf -local tracers=nodes.tracers -local trace_singles=false registertracker("otf.singles",function(v) trace_singles=v end) -local trace_multiples=false registertracker("otf.multiples",function(v) trace_multiples=v end) -local trace_alternatives=false registertracker("otf.alternatives",function(v) trace_alternatives=v end) -local trace_ligatures=false registertracker("otf.ligatures",function(v) trace_ligatures=v end) -local trace_contexts=false registertracker("otf.contexts",function(v) trace_contexts=v end) -local trace_marks=false registertracker("otf.marks",function(v) trace_marks=v end) -local trace_kerns=false registertracker("otf.kerns",function(v) trace_kerns=v end) -local trace_cursive=false registertracker("otf.cursive",function(v) trace_cursive=v end) -local trace_preparing=false registertracker("otf.preparing",function(v) trace_preparing=v end) -local trace_bugs=false registertracker("otf.bugs",function(v) trace_bugs=v end) -local trace_details=false registertracker("otf.details",function(v) trace_details=v end) -local trace_steps=false registertracker("otf.steps",function(v) trace_steps=v end) -local trace_skips=false registertracker("otf.skips",function(v) trace_skips=v end) -local trace_plugins=false registertracker("otf.plugins",function(v) trace_plugins=v end) -local trace_chains=false registertracker("otf.chains",function(v) trace_chains=v end) -local trace_kernruns=false registertracker("otf.kernruns",function(v) trace_kernruns=v end) -local trace_compruns=false registertracker("otf.compruns",function(v) trace_compruns=v end) -local trace_testruns=false registertracker("otf.testruns",function(v) trace_testruns=v end) -local forcediscretionaries=false -local forcepairadvance=false -directives.register("otf.forcediscretionaries",function(v) - forcediscretionaries=v -end) -directives.register("otf.forcepairadvance",function(v) - forcepairadvance=v -end) -local report_direct=logs.reporter("fonts","otf direct") -local report_subchain=logs.reporter("fonts","otf subchain") -local report_chain=logs.reporter("fonts","otf chain") -local report_process=logs.reporter("fonts","otf process") -local report_warning=logs.reporter("fonts","otf warning") -local report_run=logs.reporter("fonts","otf run") -registertracker("otf.substitutions","otf.singles","otf.multiples","otf.alternatives","otf.ligatures") -registertracker("otf.positions","otf.marks","otf.kerns","otf.cursive") -registertracker("otf.actions","otf.substitutions","otf.positions") -registertracker("otf.sample","otf.steps","otf.substitutions","otf.positions","otf.analyzing") -registertracker("otf.sample.silent","otf.steps=silent","otf.substitutions","otf.positions","otf.analyzing") -local nuts=nodes.nuts -local getnext=nuts.getnext -local setnext=nuts.setnext -local getprev=nuts.getprev -local setprev=nuts.setprev -local getboth=nuts.getboth -local setboth=nuts.setboth -local getid=nuts.getid -local getstate=nuts.getstate -local getsubtype=nuts.getsubtype -local setsubtype=nuts.setsubtype -local getchar=nuts.getchar -local setchar=nuts.setchar -local getdisc=nuts.getdisc -local setdisc=nuts.setdisc -local getreplace=nuts.getreplace -local setlink=nuts.setlink -local getwidth=nuts.getwidth -local getattr=nuts.getattr -local getglyphdata=nuts.getglyphdata -local copy_no_components=nuts.copy_no_components -local copy_only_glyphs=nuts.copy_only_glyphs -local count_components=nuts.count_components -local set_components=nuts.set_components -local get_components=nuts.get_components -local flush_components=nuts.flush_components -local ischar=nuts.ischar -local usesfont=nuts.uses_font -local insert_node_after=nuts.insert_after -local copy_node=nuts.copy -local copy_node_list=nuts.copy_list -local remove_node=nuts.remove -local find_node_tail=nuts.tail -local flush_node_list=nuts.flush_list -local flush_node=nuts.flush_node -local end_of_math=nuts.end_of_math -local start_of_par=nuts.start_of_par -local setmetatable=setmetatable -local setmetatableindex=table.setmetatableindex -local nextnode=nuts.traversers.node -local nodecodes=nodes.nodecodes -local glyphcodes=nodes.glyphcodes -local disccodes=nodes.disccodes -local glyph_code=nodecodes.glyph -local glue_code=nodecodes.glue -local disc_code=nodecodes.disc -local math_code=nodecodes.math -local dir_code=nodecodes.dir -local par_code=nodecodes.par -local lefttoright_code=nodes.dirvalues.lefttoright -local righttoleft_code=nodes.dirvalues.righttoleft -local discretionarydisc_code=disccodes.discretionary -local ligatureglyph_code=glyphcodes.ligature -local a_noligature=attributes.private("noligature") -local injections=nodes.injections -local setmark=injections.setmark -local setcursive=injections.setcursive -local setkern=injections.setkern -local setmove=injections.setmove -local setposition=injections.setposition -local resetinjection=injections.reset -local copyinjection=injections.copy -local setligaindex=injections.setligaindex -local getligaindex=injections.getligaindex -local fontdata=fonts.hashes.identifiers -local fontfeatures=fonts.hashes.features -local otffeatures=fonts.constructors.features.otf -local registerotffeature=otffeatures.register -local onetimemessage=fonts.loggers.onetimemessage or function() end -local getrandom=utilities and utilities.randomizer and utilities.randomizer.get -otf.defaultnodealternate="none" -local tfmdata=false -local characters=false -local descriptions=false -local marks=false -local classes=false -local currentfont=false -local factor=0 -local threshold=0 -local checkmarks=false -local discs=false -local spaces=false -local sweepnode=nil -local sweephead={} -local notmatchpre={} -local notmatchpost={} -local notmatchreplace={} -local handlers={} -local isspace=injections.isspace -local getthreshold=injections.getthreshold -local checkstep=(tracers and tracers.steppers.check) or function() end -local registerstep=(tracers and tracers.steppers.register) or function() end -local registermessage=(tracers and tracers.steppers.message) or function() end -local function logprocess(...) - if trace_steps then - registermessage(...) - if trace_steps=="silent" then - return - end - end - report_direct(...) -end -local function logwarning(...) - report_direct(...) -end -local gref do - local f_unicode=formatters["U+%X"] - local f_uniname=formatters["U+%X (%s)"] - local f_unilist=formatters["% t"] - gref=function(n) - if type(n)=="number" then - local description=descriptions[n] - local name=description and description.name - if name then - return f_uniname(n,name) - else - return f_unicode(n) - end - elseif n then - local t={} - for i=1,#n do - local ni=n[i] - if tonumber(ni) then - local di=descriptions[ni] - local nn=di and di.name - if nn then - t[#t+1]=f_uniname(ni,nn) - else - t[#t+1]=f_unicode(ni) - end - end - end - return f_unilist(t) - else - return "" - end - end -end -local function cref(dataset,sequence,index) - if not dataset then - return "no valid dataset" - end - local merged=sequence.merged and "merged " or "" - if index then - return formatters["feature %a, type %a, %schain lookup %a, index %a"]( - dataset[4],sequence.type,merged,sequence.name,index) - else - return formatters["feature %a, type %a, %schain lookup %a"]( - dataset[4],sequence.type,merged,sequence.name) - end -end -local function pref(dataset,sequence) - return formatters["feature %a, type %a, %slookup %a"]( - dataset[4],sequence.type,sequence.merged and "merged " or "",sequence.name) -end -local function mref(rlmode) - if not rlmode or rlmode>=0 then - return "l2r" - else - return "r2l" - end -end -local function flattendisk(head,disc) - local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) - local prev,next=getboth(disc) - local ishead=head==disc - setdisc(disc) - flush_node(disc) - if pre then - flush_node_list(pre) - end - if post then - flush_node_list(post) - end - if ishead then - if replace then - if next then - setlink(replacetail,next) - end - return replace,replace - elseif next then - return next,next - else - end - else - if replace then - if next then - setlink(replacetail,next) - end - setlink(prev,replace) - return head,replace - else - setlink(prev,next) - return head,next - end - end -end -local function appenddisc(disc,list) - local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) - local posthead=list - local replacehead=copy_node_list(list) - if post then - setlink(posttail,posthead) - else - post=posthead - end - if replace then - setlink(replacetail,replacehead) - else - replace=replacehead - end - setdisc(disc,pre,post,replace) -end -local function markstoligature(head,start,stop,char) - if start==stop and getchar(start)==char then - return head,start - else - local prev=getprev(start) - local next=getnext(stop) - setprev(start) - setnext(stop) - local base=copy_no_components(start,copyinjection) - if head==start then - head=base - end - resetinjection(base) - setchar(base,char) - setsubtype(base,ligatureglyph_code) - set_components(base,start) - setlink(prev,base,next) - flush_components(start) - return head,base - end -end -local no_left_ligature_code=1 -local no_right_ligature_code=2 -local no_left_kern_code=4 -local no_right_kern_code=8 -local has_glyph_option=node.direct.has_glyph_option or function(n,c) - if c==no_left_ligature_code or c==no_right_ligature_code then - return getattr(n,a_noligature)==1 - else - return false - end -end -local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks) - if has_glyph_option(start,no_right_ligature_code) then - return head,start - end - if start==stop and getchar(start)==char then - resetinjection(start) - setchar(start,char) - return head,start - end - local prev=getprev(start) - local next=getnext(stop) - local comp=start - setprev(start) - setnext(stop) - local base=copy_no_components(start,copyinjection) - if start==head then - head=base - end - resetinjection(base) - setchar(base,char) - setsubtype(base,ligatureglyph_code) - set_components(base,comp) - setlink(prev,base,next) - if not discfound then - local deletemarks=not skiphash or hasmarks - local components=start - local baseindex=0 - local componentindex=0 - local head=base - local current=base - while start do - local char=getchar(start) - if not marks[char] then - baseindex=baseindex+componentindex - componentindex=count_components(start,marks) - elseif not deletemarks then - setligaindex(start,baseindex+getligaindex(start,componentindex)) - if trace_marks then - logwarning("%s: keep ligature mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start)) - end - local n=copy_node(start) - copyinjection(n,start) - head,current=insert_node_after(head,current,n) - elseif trace_marks then - logwarning("%s: delete ligature mark %s",pref(dataset,sequence),gref(char)) - end - start=getnext(start) - end - local start=getnext(current) - while start do - local char=ischar(start) - if char then - if marks[char] then - setligaindex(start,baseindex+getligaindex(start,componentindex)) - if trace_marks then - logwarning("%s: set ligature mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start)) - end - start=getnext(start) - else - break - end - else - break - end - end - flush_components(components) - else - local discprev,discnext=getboth(discfound) - if discprev and discnext then - local pre,post,replace,pretail,posttail,replacetail=getdisc(discfound,true) - if not replace then - local prev=getprev(base) - local copied=copy_only_glyphs(comp) - if pre then - setlink(discprev,pre) - else - setnext(discprev) - end - pre=comp - if post then - setlink(posttail,discnext) - setprev(post) - else - post=discnext - setprev(discnext) - end - setlink(prev,discfound,next) - setboth(base) - set_components(base,copied) - replace=base - if forcediscretionaries then - setdisc(discfound,pre,post,replace,discretionarydisc_code) - else - setdisc(discfound,pre,post,replace) - end - base=prev - end - end - end - return head,base -end -local function multiple_glyphs(head,start,multiple,skiphash,what,stop) - local nofmultiples=#multiple - if nofmultiples>0 then - resetinjection(start) - setchar(start,multiple[1]) - if nofmultiples>1 then - local sn=getnext(start) - for k=2,nofmultiples do - local n=copy_node(start) - resetinjection(n) - setchar(n,multiple[k]) - insert_node_after(head,start,n) - start=n - end - if what==true then - elseif what>1 then - local m=multiple[nofmultiples] - for i=2,what do - local n=copy_node(start) - resetinjection(n) - setchar(n,m) - insert_node_after(head,start,n) - start=n - end - end - end - return head,start,true - else - if trace_multiples then - logprocess("no multiple for %s",gref(getchar(start))) - end - return head,start,false - end -end -local function get_alternative_glyph(start,alternatives,value) - local n=#alternatives - if n==1 then - return alternatives[1],trace_alternatives and "1 (only one present)" - elseif value=="random" then - local r=getrandom and getrandom("glyph",1,n) or random(1,n) - return alternatives[r],trace_alternatives and formatters["value %a, taking %a"](value,r) - elseif value=="first" then - return alternatives[1],trace_alternatives and formatters["value %a, taking %a"](value,1) - elseif value=="last" then - return alternatives[n],trace_alternatives and formatters["value %a, taking %a"](value,n) - end - value=value==true and 1 or tonumber(value) - if type(value)~="number" then - return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,1) - end - if value>n then - local defaultalt=otf.defaultnodealternate - if defaultalt=="first" then - return alternatives[n],trace_alternatives and formatters["invalid value %s, taking %a"](value,1) - elseif defaultalt=="last" then - return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,n) - else - return false,trace_alternatives and formatters["invalid value %a, %s"](value,"out of range") - end - elseif value==0 then - return getchar(start),trace_alternatives and formatters["invalid value %a, %s"](value,"no change") - elseif value<1 then - return alternatives[1],trace_alternatives and formatters["invalid value %a, taking %a"](value,1) - else - return alternatives[value],trace_alternatives and formatters["value %a, taking %a"](value,value) - end -end -function handlers.gsub_single(head,start,dataset,sequence,replacement) - if trace_singles then - logprocess("%s: replacing %s by single %s",pref(dataset,sequence),gref(getchar(start)),gref(replacement)) - end - resetinjection(start) - setchar(start,replacement) - return head,start,true -end -function handlers.gsub_alternate(head,start,dataset,sequence,alternative) - local kind=dataset[4] - local what=dataset[1] - local value=what==true and tfmdata.shared.features[kind] or what - local choice,comment=get_alternative_glyph(start,alternative,value) - if choice then - if trace_alternatives then - logprocess("%s: replacing %s by alternative %a to %s, %s",pref(dataset,sequence),gref(getchar(start)),gref(choice),comment) - end - resetinjection(start) - setchar(start,choice) - else - if trace_alternatives then - logwarning("%s: no variant %a for %s, %s",pref(dataset,sequence),value,gref(getchar(start)),comment) - end - end - return head,start,true -end -function handlers.gsub_multiple(head,start,dataset,sequence,multiple,rlmode,skiphash) - if trace_multiples then - logprocess("%s: replacing %s by multiple %s",pref(dataset,sequence),gref(getchar(start)),gref(multiple)) - end - return multiple_glyphs(head,start,multiple,skiphash,dataset[1]) -end -function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skiphash) - local current=getnext(start) - if not current then - return head,start,false,nil - end - local stop=nil - local startchar=getchar(start) - if skiphash and skiphash[startchar] then - while current do - local char=ischar(current,currentfont) - if char then - local lg=ligature[char] - if lg then - stop=current - ligature=lg - current=getnext(current) - else - break - end - else - break - end - end - if stop then - local lig=ligature.ligature - if lig then - if trace_ligatures then - local stopchar=getchar(stop) - head,start=markstoligature(head,start,stop,lig) - logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(getchar(start))) - else - head,start=markstoligature(head,start,stop,lig) - end - return head,start,true,false - else - end - end - else - local discfound=false - local hasmarks=marks[startchar] - while current do - local char,id=ischar(current,currentfont) - if char then - if skiphash and skiphash[char] then - current=getnext(current) - else - local lg=ligature[char] - if lg then - if marks[char] then - hasmarks=true - end - stop=current - ligature=lg - current=getnext(current) - else - break - end - end - elseif char==false then - break - elseif id==disc_code then - discfound=current - break - else - break - end - end - if discfound then - local pre,post,replace=getdisc(discfound) - local match - if replace then - local char=ischar(replace,currentfont) - if char and ligature[char] then - match=true - end - end - if not match and pre then - local char=ischar(pre,currentfont) - if char and ligature[char] then - match=true - end - end - if not match and not pre or not replace then - local n=getnext(discfound) - local char=ischar(n,currentfont) - if char and ligature[char] then - match=true - end - end - if match then - local ishead=head==start - local prev=getprev(start) - if stop then - setnext(stop) - local copy=copy_node_list(start) - local tail=stop - local liat=find_node_tail(copy) - if pre then - setlink(liat,pre) - end - if replace then - setlink(tail,replace) - end - pre=copy - replace=start - else - setnext(start) - local copy=copy_node(start) - if pre then - setlink(copy,pre) - end - if replace then - setlink(start,replace) - end - pre=copy - replace=start - end - setdisc(discfound,pre,post,replace) - if prev then - setlink(prev,discfound) - else - setprev(discfound) - head=discfound - end - start=discfound - return head,start,true,true - end - end - local lig=ligature.ligature - if lig then - if stop then - if trace_ligatures then - local stopchar=getchar(stop) - head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks) - logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig)) - else - head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks) - end - else - resetinjection(start) - setchar(start,lig) - if trace_ligatures then - logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(lig)) - end - end - return head,start,true,false - else - end - end - return head,start,false,false -end -function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) - if has_glyph_option(start,no_right_kern_code) then - return head,start,false - else - local startchar=getchar(start) - local format=step.format - if format=="single" or type(kerns)=="table" then - local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h) - end - else - local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k) - end - end - return head,start,true - end -end -function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) - if has_glyph_option(start,no_right_kern_code) then - return head,start,false - else - local snext=getnext(start) - if not snext then - return head,start,false - else - local prev=start - while snext do - local nextchar=ischar(snext,currentfont) - if nextchar then - if skiphash and skiphash[nextchar] then - prev=snext - snext=getnext(snext) - else - local krn=kerns[nextchar] - if not krn then - break - end - local format=step.format - if format=="pair" then - local a=krn[1] - local b=krn[2] - if a==true then - elseif a then - local x,y,w,h=setposition(1,start,factor,rlmode,a,injection) - if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") - end - end - if b==true then - start=snext - elseif b then - local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection) - if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") - end - start=snext - elseif forcepairadvance then - start=snext - end - return head,start,true - elseif krn~=0 then - local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection) - if trace_kerns then - logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections") - end - return head,start,true - else - break - end - end - else - break - end - end - return head,start,false - end - end -end -function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode,skiphash) - local markchar=getchar(start) - if marks[markchar] then - local base=getprev(start) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if marks[basechar] then - while base do - base=getprev(base) - if base then - basechar=ischar(base,currentfont) - if basechar then - if not marks[basechar] then - break - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) - end - return head,start,false - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) - end - return head,start,false - end - end - end - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) - if trace_marks then - logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)", - pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) - end - return head,start,true - elseif trace_bugs then - logwarning("%s: mark %s is not anchored to %s",pref(dataset,sequence),gref(markchar),gref(basechar)) - end - elseif trace_bugs then - logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),1) - end - elseif trace_bugs then - logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),2) - end - elseif trace_bugs then - logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar)) - end - return head,start,false -end -function handlers.gpos_mark2ligature(head,start,dataset,sequence,markanchors,rlmode,skiphash) - local markchar=getchar(start) - if marks[markchar] then - local base=getprev(start) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if marks[basechar] then - while base do - base=getprev(base) - if base then - basechar=ischar(base,currentfont) - if basechar then - if not marks[basechar] then - break - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) - end - return head,start,false - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) - end - return head,start,false - end - end - end - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - if ma then - local index=getligaindex(start) - ba=ba[index] - if ba then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) - if trace_marks then - logprocess("%s, index %s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)", - pref(dataset,sequence),index,bound,gref(markchar),gref(basechar),index,dx,dy) - end - return head,start,true - else - if trace_bugs then - logwarning("%s: no matching anchors for mark %s and baselig %s with index %a",pref(dataset,sequence),gref(markchar),gref(basechar),index) - end - end - end - elseif trace_bugs then - onetimemessage(currentfont,basechar,"no base anchors",report_fonts) - end - elseif trace_bugs then - logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),1) - end - elseif trace_bugs then - logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),2) - end - elseif trace_bugs then - logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar)) - end - return head,start,false -end -function handlers.gpos_mark2mark(head,start,dataset,sequence,markanchors,rlmode,skiphash) - local markchar=getchar(start) - if marks[markchar] then - local base=getprev(start) - local slc=getligaindex(start) - if slc then - while base do - local blc=getligaindex(base) - if blc and blc~=slc then - base=getprev(base) - else - break - end - end - end - if base then - local basechar=ischar(base,currentfont) - if basechar then - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) - if trace_marks then - logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)", - pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) - end - return head,start,true - end - end - end - elseif trace_bugs then - logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar)) - end - return head,start,false -end -function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,skiphash,step) - local startchar=getchar(start) - if marks[startchar] then - if trace_cursive then - logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar)) - end - else - local nxt=getnext(start) - while nxt do - local nextchar=ischar(nxt,currentfont) - if not nextchar then - break - elseif marks[nextchar] then - nxt=getnext(nxt) - else - local exit=exitanchors[3] - if exit then - local entry=exitanchors[1][nextchar] - if entry then - entry=entry[2] - if entry then - local r2lflag=sequence.flags[4] - local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag) - if trace_cursive then - logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode)) - end - return head,start,true - end - end - end - break - end - end - end - return head,start,false -end -local chainprocs={} -local function logprocess(...) - if trace_steps then - registermessage(...) - if trace_steps=="silent" then - return - end - end - report_subchain(...) -end -local logwarning=report_subchain -local function logprocess(...) - if trace_steps then - registermessage(...) - if trace_steps=="silent" then - return - end - end - report_chain(...) -end -local logwarning=report_chain -local function reversesub(head,start,stop,dataset,sequence,replacements,rlmode,skiphash) - local char=getchar(start) - local replacement=replacements[char] - if replacement then - if trace_singles then - logprocess("%s: single reverse replacement of %s by %s",cref(dataset,sequence),gref(char),gref(replacement)) - end - resetinjection(start) - setchar(start,replacement) - return head,start,true - else - return head,start,false - end -end -chainprocs.reversesub=reversesub -local function reportzerosteps(dataset,sequence) - logwarning("%s: no steps",cref(dataset,sequence)) -end -local function reportmoresteps(dataset,sequence) - logwarning("%s: more than 1 step",cref(dataset,sequence)) -end -local function getmapping(dataset,sequence,currentlookup) - local steps=currentlookup.steps - local nofsteps=currentlookup.nofsteps - if nofsteps==0 then - reportzerosteps(dataset,sequence) - currentlookup.mapping=false - return false - else - if nofsteps>1 then - reportmoresteps(dataset,sequence) - end - local mapping=steps[1].coverage - currentlookup.mapping=mapping - currentlookup.format=steps[1].format - return mapping - end -end -function chainprocs.gsub_remove(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - if trace_chains then - logprocess("%s: removing character %s",cref(dataset,sequence,chainindex),gref(getchar(start))) - end - head,start=remove_node(head,start,true) - return head,getprev(start),true -end -function chainprocs.gsub_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local current=start - while current do - local currentchar=ischar(current) - if currentchar then - local replacement=mapping[currentchar] - if not replacement or replacement=="" then - if trace_bugs then - logwarning("%s: no single for %s",cref(dataset,sequence,chainindex),gref(currentchar)) - end - else - if trace_singles then - logprocess("%s: replacing single %s by %s",cref(dataset,sequence,chainindex),gref(currentchar),gref(replacement)) - end - resetinjection(current) - setchar(current,replacement) - end - return head,start,true - elseif currentchar==false then - break - elseif current==stop then - break - else - current=getnext(current) - end - end - end - return head,start,false -end -function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local kind=dataset[4] - local what=dataset[1] - local value=what==true and tfmdata.shared.features[kind] or what - local current=start - while current do - local currentchar=ischar(current) - if currentchar then - local alternatives=mapping[currentchar] - if alternatives then - local choice,comment=get_alternative_glyph(current,alternatives,value) - if choice then - if trace_alternatives then - logprocess("%s: replacing %s by alternative %a to %s, %s",cref(dataset,sequence),gref(currentchar),choice,gref(choice),comment) - end - resetinjection(start) - setchar(start,choice) - else - if trace_alternatives then - logwarning("%s: no variant %a for %s, %s",cref(dataset,sequence),value,gref(currentchar),comment) - end - end - end - return head,start,true - elseif currentchar==false then - break - elseif current==stop then - break - else - current=getnext(current) - end - end - end - return head,start,false -end -function chainprocs.gsub_multiple(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local startchar=getchar(start) - local replacement=mapping[startchar] - if not replacement or replacement=="" then - if trace_bugs then - logwarning("%s: no multiple for %s",cref(dataset,sequence),gref(startchar)) - end - else - if trace_multiples then - logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement)) - end - return multiple_glyphs(head,start,replacement,skiphash,dataset[1],stop) - end - end - return head,start,false -end -function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local startchar=getchar(start) - local ligatures=mapping[startchar] - if not ligatures then - if trace_bugs then - logwarning("%s: no ligatures starting with %s",cref(dataset,sequence,chainindex),gref(startchar)) - end - else - local hasmarks=marks[startchar] - local current=getnext(start) - local discfound=false - local last=stop - local nofreplacements=1 - while current do - local id=getid(current) - if id==disc_code then - if not discfound then - discfound=current - end - if current==stop then - break - else - current=getnext(current) - end - else - local schar=getchar(current) - if skiphash and skiphash[schar] then - current=getnext(current) - else - local lg=ligatures[schar] - if lg then - ligatures=lg - last=current - nofreplacements=nofreplacements+1 - if marks[char] then - hasmarks=true - end - if current==stop then - break - else - current=getnext(current) - end - else - break - end - end - end - end - local ligature=ligatures.ligature - if ligature then - if chainindex then - stop=last - end - if trace_ligatures then - if start==stop then - logprocess("%s: replacing character %s by ligature %s case 3",cref(dataset,sequence,chainindex),gref(startchar),gref(ligature)) - else - logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)),gref(ligature)) - end - end - head,start=toligature(head,start,stop,ligature,dataset,sequence,skiphash,discfound,hasmarks) - return head,start,true,nofreplacements,discfound - elseif trace_bugs then - if start==stop then - logwarning("%s: replacing character %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar)) - else - logwarning("%s: replacing character %s upto %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop))) - end - end - end - end - return head,start,false,0,false -end -function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - if not has_glyph_option(start,no_right_kern_code) then - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local startchar=getchar(start) - local kerns=mapping[startchar] - if kerns then - local format=currentlookup.format - if format=="single" then - local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns) - if trace_kerns then - logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h) - end - else - local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k) - end - end - return head,start,true - end - end - end - return head,start,false -end -function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - if not has_glyph_option(start,no_right_kern_code) then - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local snext=getnext(start) - if snext then - local startchar=getchar(start) - local kerns=mapping[startchar] - if kerns then - local prev=start - while snext do - local nextchar=ischar(snext,currentfont) - if not nextchar then - break - end - if skiphash and skiphash[nextchar] then - prev=snext - snext=getnext(snext) - else - local krn=kerns[nextchar] - if not krn then - break - end - local format=currentlookup.format - if format=="pair" then - local a=krn[1] - local b=krn[2] - if a==true then - elseif a then - local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections") - if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) - end - end - if b==true then - start=snext - elseif b then - local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections") - if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) - end - start=snext - elseif forcepairadvance then - start=snext - end - return head,start,true - elseif krn~=0 then - local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn) - if trace_kerns then - logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar)) - end - return head,start,true - else - break - end - end - end - end - end - end - end - return head,start,false -end -function chainprocs.gpos_mark2base(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local markchar=getchar(start) - if marks[markchar] then - local markanchors=mapping[markchar] - if markanchors then - local base=getprev(start) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if marks[basechar] then - while base do - base=getprev(base) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if not marks[basechar] then - break - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) - end - return head,start,false - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) - end - return head,start,false - end - end - end - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - if ma then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) - if trace_marks then - logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)", - cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) - end - return head,start,true - end - end - elseif trace_bugs then - logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),1) - end - elseif trace_bugs then - logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),2) - end - elseif trace_bugs then - logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) - end - elseif trace_bugs then - logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) - end - end - return head,start,false -end -function chainprocs.gpos_mark2ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local markchar=getchar(start) - if marks[markchar] then - local markanchors=mapping[markchar] - if markanchors then - local base=getprev(start) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if marks[basechar] then - while base do - base=getprev(base) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if not marks[basechar] then - break - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,1) - end - return head,start,false - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,2) - end - return head,start,false - end - end - end - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - if ma then - local index=getligaindex(start) - ba=ba[index] - if ba then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) - if trace_marks then - logprocess("%s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)", - cref(dataset,sequence),a or bound,gref(markchar),gref(basechar),index,dx,dy) - end - return head,start,true - end - end - end - elseif trace_bugs then - logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),1) - end - elseif trace_bugs then - logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),2) - end - elseif trace_bugs then - logwarning("%s, mark %s has no anchors",cref(dataset,sequence),gref(markchar)) - end - elseif trace_bugs then - logwarning("%s, mark %s is no mark",cref(dataset,sequence),gref(markchar)) - end - end - return head,start,false -end -function chainprocs.gpos_mark2mark(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local markchar=getchar(start) - if marks[markchar] then - local markanchors=mapping[markchar] - if markanchors then - local base=getprev(start) - local slc=getligaindex(start) - if slc then - while base do - local blc=getligaindex(base) - if blc and blc~=slc then - base=getprev(base) - else - break - end - end - end - if base then - local basechar=ischar(base,currentfont) - if basechar then - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - if ma then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) - if trace_marks then - logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)", - cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) - end - return head,start,true - end - end - elseif trace_bugs then - logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),1) - end - elseif trace_bugs then - logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),2) - end - elseif trace_bugs then - logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) - end - elseif trace_bugs then - logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) - end - end - return head,start,false -end -function chainprocs.gpos_cursive(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local startchar=getchar(start) - local exitanchors=mapping[startchar] - if exitanchors then - if marks[startchar] then - if trace_cursive then - logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar)) - end - else - local nxt=getnext(start) - while nxt do - local nextchar=ischar(nxt,currentfont) - if not nextchar then - break - elseif marks[nextchar] then - nxt=getnext(nxt) - else - local exit=exitanchors[3] - if exit then - local entry=exitanchors[1][nextchar] - if entry then - entry=entry[2] - if entry then - local r2lflag=sequence.flags[4] - local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag) - if trace_cursive then - logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode)) - end - return head,start,true - end - end - elseif trace_bugs then - onetimemessage(currentfont,startchar,"no entry anchors",report_fonts) - end - break - end - end - end - elseif trace_cursive and trace_details then - logprocess("%s, cursive %s is already done",pref(dataset,sequence),gref(getchar(start)),alreadydone) - end - end - return head,start,false -end -local function show_skip(dataset,sequence,char,ck,class) - logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(dataset,sequence),gref(char),class,ck[1],ck[8] or ck[2]) -end -local userkern=nuts.pool and nuts.pool.newkern -do if not userkern then - local thekern=nuts.new("kern",1) - local setkern=nuts.setkern - userkern=function(k) - local n=copy_node(thekern) - setkern(n,k) - return n - end -end end -local function checked(head) - local current=head - while current do - if getid(current)==glue_code then - local kern=userkern(getwidth(current)) - if head==current then - local next=getnext(current) - if next then - setlink(kern,next) - end - flush_node(current) - head=kern - current=next - else - local prev,next=getboth(current) - setlink(prev,kern,next) - flush_node(current) - current=next - end - else - current=getnext(current) - end - end - return head -end -local function setdiscchecked(d,pre,post,replace) - if pre then pre=checked(pre) end - if post then post=checked(post) end - if replace then replace=checked(replace) end - setdisc(d,pre,post,replace) -end -local noflags={ false,false,false,false } -local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck) - local size=ck[5]-ck[4]+1 - local chainlookups=ck[6] - local done=false - if chainlookups then - if size==1 then - local chainlookup=chainlookups[1] - for j=1,#chainlookup do - local chainstep=chainlookup[j] - local chainkind=chainstep.type - local chainproc=chainprocs[chainkind] - if chainproc then - local ok - head,start,ok=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash) - if ok then - done=true - end - else - logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind) - end - end - else - local i=1 - local laststart=start - local nofchainlookups=#chainlookups - while start do - if skiphash then - while start do - local char=ischar(start,currentfont) - if char then - if skiphash and skiphash[char] then - start=getnext(start) - else - break - end - else - break - end - end - end - local chainlookup=chainlookups[i] - if chainlookup then - for j=1,#chainlookup do - local chainstep=chainlookup[j] - local chainkind=chainstep.type - local chainproc=chainprocs[chainkind] - if chainproc then - local ok,n - head,start,ok,n=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash,i) - if ok then - done=true - if n and n>1 and i+n>nofchainlookups then - i=size - break - end - end - else - logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind) - end - end - else - end - i=i+1 - if i>size or not start then - break - elseif start then - laststart=start - start=getnext(start) - end - end - if not start then - start=laststart - end - end - else - local replacements=ck[7] - if replacements then - head,start,done=reversesub(head,start,last,dataset,sequence,replacements,rlmode,skiphash) - else - done=true - if trace_contexts then - logprocess("%s: skipping match",cref(dataset,sequence)) - end - end - end - return head,start,done -end -local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) - if not start then - return head,start,false - end - local startishead=start==head - local seq=ck[3] - local f=ck[4] - local l=ck[5] - local s=#seq - local done=false - local sweepnode=sweepnode - local sweeptype=sweeptype - local sweepoverflow=false - local checkdisc=getprev(head) - local keepdisc=not sweepnode - local lookaheaddisc=nil - local backtrackdisc=nil - local current=start - local last=start - local prev=getprev(start) - local hasglue=false - local i=f - while i<=l do - local id=getid(current) - if id==glyph_code then - i=i+1 - last=current - current=getnext(current) - elseif id==glue_code then - i=i+1 - last=current - current=getnext(current) - hasglue=true - elseif id==disc_code then - if keepdisc then - keepdisc=false - lookaheaddisc=current - local replace=getreplace(current) - if not replace then - sweepoverflow=true - sweepnode=current - current=getnext(current) - else - while replace and i<=l do - if getid(replace)==glyph_code then - i=i+1 - end - replace=getnext(replace) - end - current=getnext(replace) - end - last=current - else - head,current=flattendisk(head,current) - end - else - last=current - current=getnext(current) - end - if current then - elseif sweepoverflow then - break - elseif sweeptype=="post" or sweeptype=="replace" then - current=getnext(sweepnode) - if current then - sweeptype=nil - sweepoverflow=true - else - break - end - else - break - end - end - if sweepoverflow then - local prev=current and getprev(current) - if not current or prev~=sweepnode then - local head=getnext(sweepnode) - local tail=nil - if prev then - tail=prev - setprev(current,sweepnode) - else - tail=find_node_tail(head) - end - setnext(sweepnode,current) - setprev(head) - setnext(tail) - appenddisc(sweepnode,head) - end - end - if l1 then - local current=prev - local i=f - local t=sweeptype=="pre" or sweeptype=="replace" - if not current and t and current==checkdisc then - current=getprev(sweepnode) - end - while current and i>1 do - local id=getid(current) - if id==glyph_code then - i=i-1 - elseif id==glue_code then - i=i-1 - hasglue=true - elseif id==disc_code then - if keepdisc then - keepdisc=false - if notmatchpost[current]~=notmatchreplace[current] then - backtrackdisc=current - end - local replace=getreplace(current) - while replace and i>1 do - if getid(replace)==glyph_code then - i=i-1 - end - replace=getnext(replace) - end - elseif notmatchpost[current]~=notmatchreplace[current] then - head,current=flattendisk(head,current) - end - end - current=getprev(current) - if t and current==checkdisc then - current=getprev(sweepnode) - end - end - end - local done=false - if lookaheaddisc then - local cf=start - local cl=getprev(lookaheaddisc) - local cprev=getprev(start) - local insertedmarks=0 - while cprev do - local char=ischar(cf,currentfont) - if char and marks[char] then - insertedmarks=insertedmarks+1 - cf=cprev - startishead=cf==head - cprev=getprev(cprev) - else - break - end - end - setlink(cprev,lookaheaddisc) - setprev(cf) - setnext(cl) - if startishead then - head=lookaheaddisc - end - local pre,post,replace=getdisc(lookaheaddisc) - local new=copy_node_list(cf) - local cnew=new - if pre then - setlink(find_node_tail(cf),pre) - end - if replace then - local tail=find_node_tail(new) - setlink(tail,replace) - end - for i=1,insertedmarks do - cnew=getnext(cnew) - end - cl=start - local clast=cnew - for i=f,l do - cl=getnext(cl) - clast=getnext(clast) - end - if not notmatchpre[lookaheaddisc] then - local ok=false - cf,start,ok=chainrun(cf,start,cl,dataset,sequence,rlmode,skiphash,ck) - if ok then - done=true - end - end - if not notmatchreplace[lookaheaddisc] then - local ok=false - new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck) - if ok then - done=true - end - end - if hasglue then - setdiscchecked(lookaheaddisc,cf,post,new) - else - setdisc(lookaheaddisc,cf,post,new) - end - start=getprev(lookaheaddisc) - sweephead[cf]=getnext(clast) or false - sweephead[new]=getnext(cl) or false - elseif backtrackdisc then - local cf=getnext(backtrackdisc) - local cl=start - local cnext=getnext(start) - local insertedmarks=0 - while cnext do - local char=ischar(cnext,currentfont) - if char and marks[char] then - insertedmarks=insertedmarks+1 - cl=cnext - cnext=getnext(cnext) - else - break - end - end - setlink(backtrackdisc,cnext) - setprev(cf) - setnext(cl) - local pre,post,replace,pretail,posttail,replacetail=getdisc(backtrackdisc,true) - local new=copy_node_list(cf) - local cnew=find_node_tail(new) - for i=1,insertedmarks do - cnew=getprev(cnew) - end - local clast=cnew - for i=f,l do - clast=getnext(clast) - end - if not notmatchpost[backtrackdisc] then - local ok=false - cf,start,ok=chainrun(cf,start,last,dataset,sequence,rlmode,skiphash,ck) - if ok then - done=true - end - end - if not notmatchreplace[backtrackdisc] then - local ok=false - new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck) - if ok then - done=true - end - end - if post then - setlink(posttail,cf) - else - post=cf - end - if replace then - setlink(replacetail,new) - else - replace=new - end - if hasglue then - setdiscchecked(backtrackdisc,pre,post,replace) - else - setdisc(backtrackdisc,pre,post,replace) - end - start=getprev(backtrackdisc) - sweephead[post]=getnext(clast) or false - sweephead[replace]=getnext(last) or false - else - local ok=false - head,start,ok=chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck) - if ok then - done=true - end - end - return head,start,done -end -local function chaintrac(head,start,dataset,sequence,rlmode,skiphash,ck,match,discseen,sweepnode) - local rule=ck[1] - local lookuptype=ck[8] or ck[2] - local nofseq=#ck[3] - local first=ck[4] - local last=ck[5] - local char=getchar(start) - logwarning("%s: rule %s %s at char %s for (%s,%s,%s) chars, lookuptype %a, %sdisc seen, %ssweeping", - cref(dataset,sequence),rule,match and "matches" or "nomatch", - gref(char),first-1,last-first+1,nofseq-last,lookuptype, - discseen and "" or "no ",sweepnode and "" or "not ") -end -local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,skiphash) - local sweepnode=sweepnode - local sweeptype=sweeptype - local postreplace - local prereplace - local checkdisc - local discseen - if sweeptype then - if sweeptype=="replace" then - postreplace=true - prereplace=true - else - postreplace=sweeptype=="post" - prereplace=sweeptype=="pre" - end - checkdisc=getprev(head) - end - local currentfont=currentfont - local skipped - local startprev, - startnext=getboth(start) - local done - local nofcontexts=contexts.n - local startchar=nofcontext==1 or ischar(start,currentfont) - for k=1,nofcontexts do - local ck=contexts[k] - local seq=ck[3] - local f=ck[4] - if not startchar or not seq[f][startchar] then - goto next - end - local s=seq.n - local l=ck[5] - local current=start - local last=start - if s==1 then - goto next - end - if l>f then - local discfound - local n=f+1 - last=startnext - while n<=l do - if postreplace and not last then - last=getnext(sweepnode) - sweeptype=nil - end - if last then - local char,id=ischar(last,currentfont) - if char then - if skiphash and skiphash[char] then - skipped=true - if trace_skips then - show_skip(dataset,sequence,char,ck,classes[char]) - end - last=getnext(last) - elseif seq[n][char] then - if nl then - break - end - pre=getnext(pre) - else - notmatchpre[last]=true - break - end - end - if n<=l then - notmatchpre[last]=true - end - else - notmatchpre[last]=true - end - if replace then - while replace do - if seq[n][getchar(replace)] then - n=n+1 - if n>l then - break - end - replace=getnext(replace) - else - notmatchreplace[last]=true - if notmatchpre[last] then - goto next - else - break - end - end - end - if notmatchpre[last] then - goto next - end - end - last=getnext(last) - else - goto next - end - else - goto next - end - end - end - if f>1 then - if startprev then - local prev=startprev - if prereplace and prev==checkdisc then - prev=getprev(sweepnode) - end - if prev then - local discfound - local n=f-1 - while n>=1 do - if prev then - local char,id=ischar(prev,currentfont) - if char then - if skiphash and skiphash[char] then - skipped=true - if trace_skips then - show_skip(dataset,sequence,char,ck,classes[char]) - end - prev=getprev(prev) - elseif seq[n][char] then - if n>1 then - prev=getprev(prev) - end - n=n-1 - elseif discfound then - notmatchreplace[discfound]=true - if notmatchpost[discfound] then - goto next - else - break - end - else - goto next - end - elseif char==false then - if discfound then - notmatchreplace[discfound]=true - if notmatchpost[discfound] then - goto next - end - else - goto next - end - break - elseif id==disc_code then - discseen=true - discfound=prev - notmatchpre[prev]=true - notmatchpost[prev]=nil - notmatchreplace[prev]=nil - local pre,post,replace,pretail,posttail,replacetail=getdisc(prev,true) - if pre~=start and post~=start and replace~=start then - if post then - local n=n - while posttail do - if seq[n][getchar(posttail)] then - n=n-1 - if posttail==post or n<1 then - break - else - posttail=getprev(posttail) - end - else - notmatchpost[prev]=true - break - end - end - if n>=1 then - notmatchpost[prev]=true - end - else - notmatchpost[prev]=true - end - if replace then - while replacetail do - if seq[n][getchar(replacetail)] then - n=n-1 - if replacetail==replace or n<1 then - break - else - replacetail=getprev(replacetail) - end - else - notmatchreplace[prev]=true - if notmatchpost[prev] then - goto next - else - break - end - end - end - else - end - end - prev=getprev(prev) - elseif id==glue_code then - local sn=seq[n] - if (sn[32] and spaces[prev]) or sn[0xFFFC] then - n=n-1 - prev=getprev(prev) - else - goto next - end - elseif seq[n][0xFFFC] then - n=n-1 - prev=getprev(prev) - else - goto next - end - else - goto next - end - end - else - goto next - end - else - goto next - end - end - if s>l then - local current=last and getnext(last) - if not current and postreplace then - current=getnext(sweepnode) - end - if current then - local discfound - local n=l+1 - while n<=s do - if current then - local char,id=ischar(current,currentfont) - if char then - if skiphash and skiphash[char] then - skipped=true - if trace_skips then - show_skip(dataset,sequence,char,ck,classes[char]) - end - current=getnext(current) - elseif seq[n][char] then - if ns then - break - else - pre=getnext(pre) - end - else - notmatchpre[current]=true - break - end - end - if n<=s then - notmatchpre[current]=true - end - else - notmatchpre[current]=true - end - if replace then - while replace do - if seq[n][getchar(replace)] then - n=n+1 - if n>s then - break - else - replace=getnext(replace) - end - else - notmatchreplace[current]=true - if notmatchpre[current] then - goto next - else - break - end - end - end - else - end - current=getnext(current) - elseif id==glue_code then - local sn=seq[n] - if (sn[32] and spaces[current]) or sn[0xFFFC] then - n=n+1 - current=getnext(current) - else - goto next - end - elseif seq[n][0xFFFC] then - n=n+1 - current=getnext(current) - else - goto next - end - else - goto next - end - end - else - goto next - end - end - if trace_contexts then - chaintrac(head,start,dataset,sequence,rlmode,skipped and skiphash,ck,true,discseen,sweepnode) - end - if discseen or sweepnode then - head,start,done=chaindisk(head,start,dataset,sequence,rlmode,skipped and skiphash,ck) - else - head,start,done=chainrun(head,start,last,dataset,sequence,rlmode,skipped and skiphash,ck) - end - if done then - break - end - ::next:: - end - if discseen then - notmatchpre={} - notmatchpost={} - notmatchreplace={} - end - return head,start,done -end -handlers.gsub_context=handle_contextchain -handlers.gsub_contextchain=handle_contextchain -handlers.gsub_reversecontextchain=handle_contextchain -handlers.gpos_contextchain=handle_contextchain -handlers.gpos_context=handle_contextchain -local function chained_contextchain(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash) - local steps=currentlookup.steps - local nofsteps=currentlookup.nofsteps - if nofsteps>1 then - reportmoresteps(dataset,sequence) - end - local l=steps[1].coverage[getchar(start)] - if l then - return handle_contextchain(head,start,dataset,sequence,l,rlmode,skiphash) - else - return head,start,false - end -end -chainprocs.gsub_context=chained_contextchain -chainprocs.gsub_contextchain=chained_contextchain -chainprocs.gsub_reversecontextchain=chained_contextchain -chainprocs.gpos_contextchain=chained_contextchain -chainprocs.gpos_context=chained_contextchain -local missing=setmetatableindex("table") -local logwarning=report_process -local resolved={} -local function logprocess(...) - if trace_steps then - registermessage(...) - if trace_steps=="silent" then - return - end - end - report_process(...) -end -local sequencelists=setmetatableindex(function(t,font) - local sequences=fontdata[font].resources.sequences - if not sequences or not next(sequences) then - sequences=false - end - t[font]=sequences - return sequences -end) -do - local autofeatures=fonts.analyzers.features - local featuretypes=otf.tables.featuretypes - local defaultscript=otf.features.checkeddefaultscript - local defaultlanguage=otf.features.checkeddefaultlanguage - local wildcard="*" - local default="dflt" - local function initialize(sequence,script,language,enabled,autoscript,autolanguage) - local features=sequence.features - if features then - local order=sequence.order - if order then - local featuretype=featuretypes[sequence.type or "unknown"] - for i=1,#order do - local kind=order[i] - local valid=enabled[kind] - if valid then - local scripts=features[kind] - local languages=scripts and ( - scripts[script] or - scripts[wildcard] or - (autoscript and defaultscript(featuretype,autoscript,scripts)) - ) - local enabled=languages and ( - languages[language] or - languages[wildcard] or - (autolanguage and defaultlanguage(featuretype,autolanguage,languages)) - ) - if enabled then - return { valid,autofeatures[kind] or false,sequence,kind } - end - end - end - else - end - end - return false - end - function otf.dataset(tfmdata,font) - local shared=tfmdata.shared - local properties=tfmdata.properties - local language=properties.language or "dflt" - local script=properties.script or "dflt" - local enabled=shared.features - local autoscript=enabled and enabled.autoscript - local autolanguage=enabled and enabled.autolanguage - local res=resolved[font] - if not res then - res={} - resolved[font]=res - end - local rs=res[script] - if not rs then - rs={} - res[script]=rs - end - local rl=rs[language] - if not rl then - rl={ - } - rs[language]=rl - local sequences=tfmdata.resources.sequences - if sequences then - for s=1,#sequences do - local v=enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage) - if v then - rl[#rl+1]=v - end - end - end - end - return rl - end -end -local function report_disc(what,n) - report_run("%s: %s > %s",what,n,languages.serializediscretionary(n)) -end -local function kernrun(disc,k_run,font,attr,...) - if trace_kernruns then - report_disc("kern",disc) - end - local prev,next=getboth(disc) - local nextstart=next - local done=false - local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) - local prevmarks=prev - while prevmarks do - local char=ischar(prevmarks,font) - if char and marks[char] then - prevmarks=getprev(prevmarks) - else - break - end - end - if prev and not ischar(prev,font) then - prev=false - end - if next and not ischar(next,font) then - next=false - end - if pre then - if k_run(pre,"injections",nil,font,attr,...) then - done=true - end - if prev then - setlink(prev,pre) - if k_run(prevmarks,"preinjections",pre,font,attr,...) then - done=true - end - setprev(pre) - setlink(prev,disc) - end - end - if post then - if k_run(post,"injections",nil,font,attr,...) then - done=true - end - if next then - setlink(posttail,next) - if k_run(posttail,"postinjections",next,font,attr,...) then - done=true - end - setnext(posttail) - setlink(disc,next) - end - end - if replace then - if k_run(replace,"injections",nil,font,attr,...) then - done=true - end - if prev then - setlink(prev,replace) - if k_run(prevmarks,"replaceinjections",replace,font,attr,...) then - done=true - end - setprev(replace) - setlink(prev,disc) - end - if next then - setlink(replacetail,next) - if k_run(replacetail,"replaceinjections",next,font,attr,...) then - done=true - end - setnext(replacetail) - setlink(disc,next) - end - elseif prev and next then - setlink(prev,next) - if k_run(prevmarks,"emptyinjections",next,font,attr,...) then - done=true - end - setlink(prev,disc,next) - end - if done and trace_testruns then - report_disc("done",disc) - end - return nextstart,done -end -local function comprun(disc,c_run,...) - if trace_compruns then - report_disc("comp",disc) - end - local pre,post,replace=getdisc(disc) - local renewed=false - if pre then - sweepnode=disc - sweeptype="pre" - local new,done=c_run(pre,...) - if done then - pre=new - renewed=true - end - end - if post then - sweepnode=disc - sweeptype="post" - local new,done=c_run(post,...) - if done then - post=new - renewed=true - end - end - if replace then - sweepnode=disc - sweeptype="replace" - local new,done=c_run(replace,...) - if done then - replace=new - renewed=true - end - end - sweepnode=nil - sweeptype=nil - if renewed then - if trace_testruns then - report_disc("done",disc) - end - setdisc(disc,pre,post,replace) - end - return getnext(disc),renewed -end -local function testrun(disc,t_run,c_run,...) - if trace_testruns then - report_disc("test",disc) - end - local prev,next=getboth(disc) - if not next then - return - end - local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) - local renewed=false - if post or replace then - if post then - setlink(posttail,next) - else - post=next - end - if replace then - setlink(replacetail,next) - else - replace=next - end - local d_post=t_run(post,next,...) - local d_replace=t_run(replace,next,...) - if d_post>0 or d_replace>0 then - local d=d_replace>d_post and d_replace or d_post - local head=getnext(disc) - local tail=head - for i=2,d do - local nx=getnext(tail) - local id=getid(nx) - if id==disc_code then - head,tail=flattendisk(head,nx) - elseif id==glyph_code then - tail=nx - else - break - end - end - next=getnext(tail) - setnext(tail) - setprev(head) - local new=copy_node_list(head) - if posttail then - setlink(posttail,head) - else - post=head - end - if replacetail then - setlink(replacetail,new) - else - replace=new - end - else - if posttail then - setnext(posttail) - else - post=nil - end - if replacetail then - setnext(replacetail) - else - replace=nil - end - end - setlink(disc,next) - end - if trace_testruns then - report_disc("more",disc) - end - if pre then - sweepnode=disc - sweeptype="pre" - local new,ok=c_run(pre,...) - if ok then - pre=new - renewed=true - end - end - if post then - sweepnode=disc - sweeptype="post" - local new,ok=c_run(post,...) - if ok then - post=new - renewed=true - end - end - if replace then - sweepnode=disc - sweeptype="replace" - local new,ok=c_run(replace,...) - if ok then - replace=new - renewed=true - end - end - sweepnode=nil - sweeptype=nil - if renewed then - setdisc(disc,pre,post,replace) - if trace_testruns then - report_disc("done",disc) - end - end - return getnext(disc),renewed -end -local nesting=0 -local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) - local done=false - local sweep=sweephead[head] - local start - if sweep then - start=sweep - sweephead[head]=false - else - start=head - end - while start do - local char,id=ischar(start,font) - if char then - local a - if attr then - a=getglyphdata(start) - end - if not a or (a==attr) then - local lookupmatch=lookupcache[char] - if lookupmatch then - local ok - head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if ok then - done=true - end - end - if start then - start=getnext(start) - end - else - start=getnext(start) - end - elseif char==false then - return head,done - elseif sweep then - return head,done - else - start=getnext(start) - end - end - return head,done -end -local function t_run_single(start,stop,font,attr,lookupcache) - local lastd=nil - while start~=stop do - local char=ischar(start,font) - if char then - local a - if attr then - a=getglyphdata(start) - end - local startnext=getnext(start) - if not a or (a==attr) then - local lookupmatch=lookupcache[char] - if lookupmatch then - local s=startnext - local ss=nil - local sstop=s==stop - if not s then - s=ss - ss=nil - end - while getid(s)==disc_code do - ss=getnext(s) - s=getreplace(s) - if not s then - s=ss - ss=nil - end - end - local l=nil - local d=0 - while s do - local char=ischar(s,font) - if char then - local lg=lookupmatch[char] - if lg then - if sstop then - d=1 - elseif d>0 then - d=d+1 - end - l=lg - s=getnext(s) - sstop=s==stop - if not s then - s=ss - ss=nil - end - while getid(s)==disc_code do - ss=getnext(s) - s=getreplace(s) - if not s then - s=ss - ss=nil - end - end - lookupmatch=lg - else - break - end - else - break - end - end - if l and l.ligature then - lastd=d - end - else - end - else - end - if lastd then - return lastd - end - start=startnext - else - break - end - end - return 0 -end -local function k_run_single(sub,injection,last,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) - local a - if attr then - a=getglyphdata(sub) - end - if not a or (a==attr) then - for n in nextnode,sub do - if n==last then - break - end - local char=ischar(n,font) - if char then - local lookupmatch=lookupcache[char] - if lookupmatch then - local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection) - if ok then - return true - end - end - end - end - end -end -local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) - local done=false - local sweep=sweephead[head] - local start - if sweep then - start=sweep - sweephead[head]=false - else - start=head - end - while start do - local char=ischar(start,font) - if char then - local a - if attr then - a=getglyphdata(start) - end - if not a or (a==attr) then - for i=1,nofsteps do - local step=steps[i] - local lookupcache=step.coverage - local lookupmatch=lookupcache[char] - if lookupmatch then - local ok - head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if ok then - done=true - break - elseif not start then - break - end - end - end - if start then - start=getnext(start) - end - else - start=getnext(start) - end - elseif char==false then - return head,done - elseif sweep then - return head,done - else - start=getnext(start) - end - end - return head,done -end -local function t_run_multiple(start,stop,font,attr,steps,nofsteps) - local lastd=nil - while start~=stop do - local char=ischar(start,font) - if char then - local a - if attr then - a=getglyphdata(start) - end - local startnext=getnext(start) - if not a or (a==attr) then - for i=1,nofsteps do - local step=steps[i] - local lookupcache=step.coverage - local lookupmatch=lookupcache[char] - if lookupmatch then - local s=startnext - local ss=nil - local sstop=s==stop - if not s then - s=ss - ss=nil - end - while getid(s)==disc_code do - ss=getnext(s) - s=getreplace(s) - if not s then - s=ss - ss=nil - end - end - local l=nil - local d=0 - while s do - local char=ischar(s) - if char then - local lg=lookupmatch[char] - if lg then - if sstop then - d=1 - elseif d>0 then - d=d+1 - end - l=lg - s=getnext(s) - sstop=s==stop - if not s then - s=ss - ss=nil - end - while getid(s)==disc_code do - ss=getnext(s) - s=getreplace(s) - if not s then - s=ss - ss=nil - end - end - lookupmatch=lg - else - break - end - else - break - end - end - if l and l.ligature then - lastd=d - end - end - end - else - end - if lastd then - return lastd - end - start=startnext - else - break - end - end - return 0 -end -local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) - local a - if attr then - a=getglyphdata(sub) - end - if not a or (a==attr) then - for n in nextnode,sub do - if n==last then - break - end - local char=ischar(n) - if char then - for i=1,nofsteps do - local step=steps[i] - local lookupcache=step.coverage - local lookupmatch=lookupcache[char] - if lookupmatch then - local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection) - if ok then - return true - end - end - end - end - end - end -end -local txtdirstate,pardirstate do - local getdirection=nuts.getdirection - txtdirstate=function(start,stack,top,rlparmode) - local dir,pop=getdirection(start) - if pop then - if top==1 then - return 0,rlparmode - else - top=top-1 - if stack[top]==righttoleft_code then - return top,-1 - else - return top,1 - end - end - elseif dir==lefttoright_code then - top=top+1 - stack[top]=lefttoright_code - return top,1 - elseif dir==righttoleft_code then - top=top+1 - stack[top]=righttoleft_code - return top,-1 - else - return top,rlparmode - end - end - pardirstate=function(start) - local dir=getdirection(start) - if dir==lefttoright_code then - return 1,1 - elseif dir==righttoleft_code then - return -1,-1 - else - return 0,0 - end - end -end -otf.helpers=otf.helpers or {} -otf.helpers.txtdirstate=txtdirstate -otf.helpers.pardirstate=pardirstate -do - local fastdisc=true - local testdics=false - directives.register("otf.fastdisc",function(v) fastdisc=v end) - local otfdataset=nil - local getfastdisc={ __index=function(t,k) - local v=usesfont(k,currentfont) - t[k]=v - return v - end } - local getfastspace={ __index=function(t,k) - local v=isspace(k,threshold) or false - t[k]=v - return v - end } - function otf.featuresprocessor(head,font,attr,direction,n) - local sequences=sequencelists[font] - nesting=nesting+1 - if nesting==1 then - currentfont=font - tfmdata=fontdata[font] - descriptions=tfmdata.descriptions - characters=tfmdata.characters - local resources=tfmdata.resources - marks=resources.marks - classes=resources.classes - threshold, - factor=getthreshold(font) - checkmarks=tfmdata.properties.checkmarks - if not otfdataset then - otfdataset=otf.dataset - end - discs=fastdisc and n and n>1 and setmetatable({},getfastdisc) - spaces=setmetatable({},getfastspace) - elseif currentfont~=font then - report_warning("nested call with a different font, level %s, quitting",nesting) - nesting=nesting-1 - return head,false - end - if trace_steps then - checkstep(head) - end - local initialrl=0 - if getid(head)==par_code and start_of_par(head) then - initialrl=pardirstate(head) - elseif direction==righttoleft_code then - initialrl=-1 - end - local datasets=otfdataset(tfmdata,font,attr) - local dirstack={ nil } - sweephead={} - for s=1,#datasets do - local dataset=datasets[s] - local attribute=dataset[2] - local sequence=dataset[3] - local rlparmode=initialrl - local topstack=0 - local typ=sequence.type - local gpossing=typ=="gpos_single" or typ=="gpos_pair" - local forcetestrun=typ=="gsub_ligature" - local handler=handlers[typ] - local steps=sequence.steps - local nofsteps=sequence.nofsteps - local skiphash=sequence.skiphash - if not steps then - local h,ok=handler(head,dataset,sequence,initialrl,font,attr) - if h and h~=head then - head=h - end - elseif typ=="gsub_reversecontextchain" then - local start=find_node_tail(head) - local rlmode=0 - local merged=steps.merged - while start do - local char=ischar(start,font) - if char then - local m=merged[char] - if m then - local a - if attr then - a=getglyphdata(start) - end - if not a or (a==attr) then - for i=m[1],m[2] do - local step=steps[i] - local lookupcache=step.coverage - local lookupmatch=lookupcache[char] - if lookupmatch then - local ok - head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if ok then - break - end - end - end - if start then - start=getprev(start) - end - else - start=getprev(start) - end - else - start=getprev(start) - end - else - start=getprev(start) - end - end - else - local start=head - local rlmode=initialrl - if nofsteps==1 then - local step=steps[1] - local lookupcache=step.coverage - while start do - local char,id=ischar(start,font) - if char then - if skiphash and skiphash[char] then - start=getnext(start) - else - local lookupmatch=lookupcache[char] - if lookupmatch then - local a - if attr then - if getglyphdata(start)==attr and (not attribute or getstate(start,attribute)) then - a=true - end - elseif not attribute or getstate(start,attribute) then - a=true - end - if a then - local ok,df - head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if df then - elseif start then - start=getnext(start) - end - else - start=getnext(start) - end - else - start=getnext(start) - end - end - elseif char==false or id==glue_code then - start=getnext(start) - elseif id==disc_code then - if not discs or discs[start]==true then - local ok - if gpossing then - start,ok=kernrun(start,k_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) - elseif forcetestrun then - start,ok=testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) - else - start,ok=comprun(start,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) - end - else - start=getnext(start) - end - elseif id==math_code then - start=getnext(end_of_math(start)) - elseif id==dir_code then - topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode) - start=getnext(start) - else - start=getnext(start) - end - end - else - local merged=steps.merged - while start do - local char,id=ischar(start,font) - if char then - if skiphash and skiphash[char] then - start=getnext(start) - else - local m=merged[char] - if m then - local a - if attr then - if getglyphdata(start)==attr and (not attribute or getstate(start,attribute)) then - a=true - end - elseif not attribute or getstate(start,attribute) then - a=true - end - if a then - local ok,df - for i=m[1],m[2] do - local step=steps[i] - local lookupcache=step.coverage - local lookupmatch=lookupcache[char] - if lookupmatch then - head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if df then - break - elseif ok then - break - elseif not start then - break - end - end - end - if df then - elseif start then - start=getnext(start) - end - else - start=getnext(start) - end - else - start=getnext(start) - end - end - elseif char==false or id==glue_code then - start=getnext(start) - elseif id==disc_code then - if not discs or discs[start]==true then - local ok - if gpossing then - start,ok=kernrun(start,k_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) - elseif forcetestrun then - start,ok=testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) - else - start,ok=comprun(start,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) - end - else - start=getnext(start) - end - elseif id==math_code then - start=getnext(end_of_math(start)) - elseif id==dir_code then - topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode) - start=getnext(start) - else - start=getnext(start) - end - end - end - end - if trace_steps then - registerstep(head) - end - end - nesting=nesting-1 - return head - end - function otf.datasetpositionprocessor(head,font,direction,dataset) - currentfont=font - tfmdata=fontdata[font] - descriptions=tfmdata.descriptions - characters=tfmdata.characters - local resources=tfmdata.resources - marks=resources.marks - classes=resources.classes - threshold, - factor=getthreshold(font) - checkmarks=tfmdata.properties.checkmarks - if type(dataset)=="number" then - dataset=otfdataset(tfmdata,font,0)[dataset] - end - local sequence=dataset[3] - local typ=sequence.type - local handler=handlers[typ] - local steps=sequence.steps - local nofsteps=sequence.nofsteps - local done=false - local dirstack={ nil } - local start=head - local initialrl=(direction==righttoleft_code) and -1 or 0 - local rlmode=initialrl - local rlparmode=initialrl - local topstack=0 - local merged=steps.merged - local position=0 - while start do - local char,id=ischar(start,font) - if char then - position=position+1 - local m=merged[char] - if m then - if skiphash and skiphash[char] then - start=getnext(start) - else - for i=m[1],m[2] do - local step=steps[i] - local lookupcache=step.coverage - local lookupmatch=lookupcache[char] - if lookupmatch then - local ok - head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if ok then - break - elseif not start then - break - end - end - end - if start then - start=getnext(start) - end - end - else - start=getnext(start) - end - elseif char==false or id==glue_code then - start=getnext(start) - elseif id==math_code then - start=getnext(end_of_math(start)) - elseif id==dir_code then - topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode) - start=getnext(start) - else - start=getnext(start) - end - end - return head - end -end -local plugins={} -otf.plugins=plugins -local report=logs.reporter("fonts") -function otf.registerplugin(name,f) - if type(name)=="string" and type(f)=="function" then - plugins[name]={ name,f } - report() - report("plugin %a has been loaded, please be aware of possible side effects",name) - report() - if logs.pushtarget then - logs.pushtarget("log") - end - report("Plugins are not officially supported unless stated otherwise. This is because") - report("they bypass the regular font handling and therefore some features in ConTeXt") - report("(especially those related to fonts) might not work as expected or might not work") - report("at all. Some plugins are for testing and development only and might change") - report("whenever we feel the need for it.") - report() - if logs.poptarget then - logs.poptarget() - end - end -end -function otf.plugininitializer(tfmdata,value) - if type(value)=="string" then - tfmdata.shared.plugin=plugins[value] - end -end -function otf.pluginprocessor(head,font,attr,direction) - local s=fontdata[font].shared - local p=s and s.plugin - if p then - if trace_plugins then - report_process("applying plugin %a",p[1]) - end - return p[2](head,font,attr,direction) - else - return head,false - end -end -function otf.featuresinitializer(tfmdata,value) -end -registerotffeature { - name="features", - description="features", - default=true, - initializers={ - position=1, - node=otf.featuresinitializer, - plug=otf.plugininitializer, - }, - processors={ - node=otf.featuresprocessor, - plug=otf.pluginprocessor, - } -} -local function markinitializer(tfmdata,value) - local properties=tfmdata.properties - properties.checkmarks=value -end -registerotffeature { - name="checkmarks", - description="check mark widths", - default=true, - initializers={ - node=markinitializer, - }, -} -otf.handlers=handlers -if context then - return -else -end -local setspacekerns=nodes.injections.setspacekerns if not setspacekerns then os.exit() end -local tag="kern" - function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr) - local shared=fontdata[font].shared - local features=shared and shared.features - local enabled=features and features.spacekern and features[tag] - if enabled then - setspacekerns(font,sequence) - end - return head,enabled - end -local function hasspacekerns(data) - local resources=data.resources - local sequences=resources.sequences - local validgpos=resources.features.gpos - if validgpos and sequences then - for i=1,#sequences do - local sequence=sequences[i] - local steps=sequence.steps - if steps and sequence.features[tag] then - local kind=sequence.type - if kind=="gpos_pair" or kind=="gpos_single" then - for i=1,#steps do - local step=steps[i] - local coverage=step.coverage - local rules=step.rules - if rules then - elseif not coverage then - elseif kind=="gpos_single" then - elseif kind=="gpos_pair" then - local format=step.format - if format=="move" or format=="kern" then - local kerns=coverage[32] - if kerns then - return true - end - for k,v in next,coverage do - if v[32] then - return true - end - end - elseif format=="pair" then - local kerns=coverage[32] - if kerns then - for k,v in next,kerns do - local one=v[1] - if one and one~=true then - return true - end - end - end - for k,v in next,coverage do - local kern=v[32] - if kern then - local one=kern[1] - if one and one~=true then - return true - end - end - end - end - end - end - end - end - end - end - return false -end -otf.readers.registerextender { - name="spacekerns", - action=function(data) - data.properties.hasspacekerns=hasspacekerns(data) - end -} -local function spaceinitializer(tfmdata,value) - local resources=tfmdata.resources - local spacekerns=resources and resources.spacekerns - if value and spacekerns==nil then - local rawdata=tfmdata.shared and tfmdata.shared.rawdata - local properties=rawdata.properties - if properties and properties.hasspacekerns then - local sequences=resources.sequences - local validgpos=resources.features.gpos - if validgpos and sequences then - local left={} - local right={} - local last=0 - local feat=nil - for i=1,#sequences do - local sequence=sequences[i] - local steps=sequence.steps - if steps then - local kern=sequence.features[tag] - if kern then - local kind=sequence.type - if kind=="gpos_pair" or kind=="gpos_single" then - if feat then - for script,languages in next,kern do - local f=feat[script] - if f then - for l in next,languages do - f[l]=true - end - else - feat[script]=languages - end - end - else - feat=kern - end - for i=1,#steps do - local step=steps[i] - local coverage=step.coverage - local rules=step.rules - if rules then - elseif not coverage then - elseif kind=="gpos_single" then - elseif kind=="gpos_pair" then - local format=step.format - if format=="move" or format=="kern" then - local kerns=coverage[32] - if kerns then - for k,v in next,kerns do - right[k]=v - end - end - for k,v in next,coverage do - local kern=v[32] - if kern then - left[k]=kern - end - end - elseif format=="pair" then - local kerns=coverage[32] - if kerns then - for k,v in next,kerns do - local one=v[1] - if one and one~=true then - right[k]=one[3] - end - end - end - for k,v in next,coverage do - local kern=v[32] - if kern then - local one=kern[1] - if one and one~=true then - left[k]=one[3] - end - end - end - end - end - end - last=i - end - else - end - end - end - left=next(left) and left or false - right=next(right) and right or false - if left or right then - spacekerns={ - left=left, - right=right, - } - if last>0 then - local triggersequence={ - features={ [tag]=feat or { dflt={ dflt=true,} } }, - flags=noflags, - name="trigger_space_kerns", - order={ tag }, - type="trigger_space_kerns", - left=left, - right=right, - } - insert(sequences,last,triggersequence) - end - end - end - end - resources.spacekerns=spacekerns - end - return spacekerns -end -registerotffeature { - name="spacekern", - description="space kern injection", - default=true, - initializers={ - node=spaceinitializer, - }, -} - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ots”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-osd” 73c9531c79df5ada320cb20777f7ed49] --- - -if not modules then modules={} end modules ['font-osd']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Kai Eigner, TAT Zetwerk / Hans Hagen, PRAGMA ADE", - copyright="TAT Zetwerk / PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local insert,imerge,copy,tohash=table.insert,table.imerge,table.copy,table.tohash -local next,type=next,type -local report=logs.reporter("otf","devanagari") -fonts=fonts or {} -fonts.analyzers=fonts.analyzers or {} -fonts.analyzers.methods=fonts.analyzers.methods or { node={ otf={} } } -local otf=fonts.handlers.otf -local handlers=otf.handlers -local methods=fonts.analyzers.methods -local otffeatures=fonts.constructors.features.otf -local registerotffeature=otffeatures.register -local nuts=nodes.nuts -local getnext=nuts.getnext -local getprev=nuts.getprev -local getboth=nuts.getboth -local getid=nuts.getid -local getchar=nuts.getchar -local getfont=nuts.getfont -local getsubtype=nuts.getsubtype -local setlink=nuts.setlink -local setnext=nuts.setnext -local setprev=nuts.setprev -local setchar=nuts.setchar -local getprop=nuts.getprop -local setprop=nuts.setprop -local getstate=nuts.getstate -local setstate=nuts.setstate -local ischar=nuts.ischar -local insert_node_after=nuts.insert_after -local copy_node=nuts.copy -local remove_node=nuts.remove -local flush_list=nuts.flush_list -local flush_node=nuts.flush_node -local copyinjection=nodes.injections.copy -local unsetvalue=attributes.unsetvalue -local fontdata=fonts.hashes.identifiers -local a_syllabe=attributes.private('syllabe') -local dotted_circle=0x25CC -local c_nbsp=0x00A0 -local c_zwnj=0x200C -local c_zwj=0x200D -local states=fonts.analyzers.states -local s_rphf=states.rphf -local s_half=states.half -local s_pref=states.pref -local s_blwf=states.blwf -local s_pstf=states.pstf -local s_init=states.init -local replace_all_nbsp=nil -replace_all_nbsp=function(head) - replace_all_nbsp=typesetters and typesetters.characters and typesetters.characters.replacenbspaces or function(head) - return head - end - return replace_all_nbsp(head) -end -local processcharacters=nil -if context then - local fontprocesses=fonts.hashes.processes - function processcharacters(head,font) - local processors=fontprocesses[font] - for i=1,#processors do - head=processors[i](head,font,0) - end - return head - end -else - function processcharacters(head,font) - local processors=fontdata[font].shared.processes - for i=1,#processors do - head=processors[i](head,font,0) - end - return head - end -end -local indicgroups=characters and characters.indicgroups -if not indicgroups and characters then - local indic={ - c={}, - i={}, - d={}, - m={}, - s={}, - o={}, - } - local indicmarks={ - l={}, - t={}, - b={}, - r={}, - s={}, - } - local indicclasses={ - nukta={}, - halant={}, - ra={}, - anudatta={}, - } - local indicorders={ - bp={}, - ap={}, - bs={}, - as={}, - bh={}, - ah={}, - bm={}, - am={}, - } - for k,v in next,characters.data do - local i=v.indic - if i then - indic[i][k]=true - i=v.indicmark - if i then - if i=="s" then - local s=v.specials - indicmarks[i][k]={ s[2],s[3] } - else - indicmarks[i][k]=true - end - end - i=v.indicclass - if i then - indicclasses[i][k]=true - end - i=v.indicorder - if i then - indicorders[i][k]=true - end - end - end - indicgroups={ - consonant=indic.c, - independent_vowel=indic.i, - dependent_vowel=indic.d, - vowel_modifier=indic.m, - stress_tone_mark=indic.s, - pre_mark=indicmarks.l, - above_mark=indicmarks.t, - below_mark=indicmarks.b, - post_mark=indicmarks.r, - twopart_mark=indicmarks.s, - nukta=indicclasses.nukta, - halant=indicclasses.halant, - ra=indicclasses.ra, - anudatta=indicclasses.anudatta, - before_postscript=indicorders.bp, - after_postscript=indicorders.ap, - before_half=indicorders.bh, - after_half=indicorders.ah, - before_subscript=indicorders.bs, - after_subscript=indicorders.as, - before_main=indicorders.bm, - after_main=indicorders.am, - } - indic=nil - indicmarks=nil - indicclasses=nil - indicorders=nil - characters.indicgroups=indicgroups -end -local consonant=indicgroups.consonant -local independent_vowel=indicgroups.independent_vowel -local dependent_vowel=indicgroups.dependent_vowel -local vowel_modifier=indicgroups.vowel_modifier -local stress_tone_mark=indicgroups.stress_tone_mark -local pre_mark=indicgroups.pre_mark -local above_mark=indicgroups.above_mark -local below_mark=indicgroups.below_mark -local post_mark=indicgroups.post_mark -local twopart_mark=indicgroups.twopart_mark -local nukta=indicgroups.nukta -local halant=indicgroups.halant -local ra=indicgroups.ra -local anudatta=indicgroups.anudatta -local before_postscript=indicgroups.before_postscript -local after_postscript=indicgroups.after_postscript -local before_half=indicgroups.before_half -local after_half=indicgroups.after_half -local before_subscript=indicgroups.before_subscript -local after_subscript=indicgroups.after_subscript -local before_main=indicgroups.before_main -local after_main=indicgroups.after_main -local mark_four=table.merged ( - pre_mark, - above_mark, - below_mark, - post_mark -) -local mark_above_below_post=table.merged ( - above_mark, - below_mark, - post_mark -) -local zw_char={ - [c_zwnj]=true, - [c_zwj ]=true, -} -local dflt_true={ - dflt=true, -} -local two_defaults={} -local one_defaults={} -local false_flags={ false,false,false,false } -local sequence_reorder_matras={ - features={ dv01=two_defaults }, - flags=false_flags, - name="dv01_reorder_matras", - order={ "dv01" }, - type="devanagari_reorder_matras", - nofsteps=1, - steps={ - { - coverage=pre_mark, - } - } -} -local sequence_reorder_reph={ - features={ dv02=two_defaults }, - flags=false_flags, - name="dv02_reorder_reph", - order={ "dv02" }, - type="devanagari_reorder_reph", - nofsteps=1, - steps={ - { - coverage={}, - } - } -} -local sequence_reorder_pre_base_reordering_consonants={ - features={ dv03=one_defaults }, - flags=false_flags, - name="dv03_reorder_pre_base_reordering_consonants", - order={ "dv03" }, - type="devanagari_reorder_pre_base_reordering_consonants", - nofsteps=1, - steps={ - { - coverage={}, - } - } -} -local sequence_remove_joiners={ - features={ dv04=one_defaults }, - flags=false_flags, - name="dv04_remove_joiners", - order={ "dv04" }, - type="devanagari_remove_joiners", - nofsteps=1, - steps={ - { - coverage=zw_char, - }, - } -} -local basic_shaping_forms={ - akhn=true, - blwf=true, - cjct=true, - half=true, - nukt=true, - pref=true, - pstf=true, - rkrf=true, - rphf=true, - vatu=true, - locl=true, -} -local valid={ - abvs=true, - akhn=true, - blwf=true, - calt=true, - cjct=true, - half=true, - haln=true, - nukt=true, - pref=true, - pres=true, - pstf=true, - psts=true, - rkrf=true, - rphf=true, - vatu=true, - pres=true, - abvs=true, - blws=true, - psts=true, - haln=true, - calt=true, - locl=true, -} -local scripts={} -local scripts_one={ "deva","mlym","beng","gujr","guru","knda","orya","taml","telu" } -local scripts_two={ "dev2","mlm2","bng2","gjr2","gur2","knd2","ory2","tml2","tel2" } -local nofscripts=#scripts_one -for i=1,nofscripts do - local one=scripts_one[i] - local two=scripts_two[i] - scripts[one]=true - scripts[two]=true - two_defaults[two]=dflt_true - one_defaults[one]=dflt_true - one_defaults[two]=dflt_true -end -local function valid_one(s) for i=1,nofscripts do if s[scripts_one[i]] then return true end end end -local function valid_two(s) for i=1,nofscripts do if s[scripts_two[i]] then return true end end end -local function initializedevanagi(tfmdata) - local script,language=otf.scriptandlanguage(tfmdata,attr) - if scripts[script] then - local resources=tfmdata.resources - local devanagari=resources.devanagari - if not devanagari then - report("adding devanagari features to font") - local gsubfeatures=resources.features.gsub - local sequences=resources.sequences - local sharedfeatures=tfmdata.shared.features - gsubfeatures["dv01"]=two_defaults - gsubfeatures["dv02"]=two_defaults - gsubfeatures["dv03"]=one_defaults - gsubfeatures["dv04"]=one_defaults - local reorder_pre_base_reordering_consonants=copy(sequence_reorder_pre_base_reordering_consonants) - local reorder_reph=copy(sequence_reorder_reph) - local reorder_matras=copy(sequence_reorder_matras) - local remove_joiners=copy(sequence_remove_joiners) - local lastmatch=0 - for s=1,#sequences do - local features=sequences[s].features - if features then - for k,v in next,features do - if k=="locl" then - local steps=sequences[s].steps - local nofsteps=sequences[s].nofsteps - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - for k,v in next,pre_mark do - local locl=coverage[k] - if locl then - if #locl>0 then - for j=1,#locl do - local ck=locl[j] - local f=ck[4] - local chainlookups=ck[6] - if chainlookups then - local chainlookup=chainlookups[f] - for j=1,#chainlookup do - local chainstep=chainlookup[j] - local steps=chainstep.steps - local nofsteps=chainstep.nofsteps - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - locl=coverage[k] - end - end - end - end - end - end - if locl then - reorder_matras.steps[1].coverage[locl]=true - end - end - end - end - end - end - if basic_shaping_forms[k] then - lastmatch=lastmatch+1 - if s~=lastmatch then - table.insert(sequences,lastmatch,table.remove(sequences,s)) - end - end - end - end - end - local insertindex=lastmatch+1 - if tfmdata.properties.language then - dflt_true[tfmdata.properties.language]=true - end - insert(sequences,insertindex,reorder_pre_base_reordering_consonants) - insert(sequences,insertindex,reorder_reph) - insert(sequences,insertindex,reorder_matras) - insert(sequences,insertindex,remove_joiners) - local blwfcache={} - local vatucache={} - local pstfcache={} - local seqsubset={} - local rephstep={ - coverage={} - } - local devanagari={ - reph=false, - vattu=false, - blwfcache=blwfcache, - vatucache=vatucache, - pstfcache=pstfcache, - seqsubset=seqsubset, - reorderreph=rephstep, - } - reorder_reph.steps={ rephstep } - local pre_base_reordering_consonants={} - reorder_pre_base_reordering_consonants.steps[1].coverage=pre_base_reordering_consonants - resources.devanagari=devanagari - for s=1,#sequences do - local sequence=sequences[s] - local steps=sequence.steps - local nofsteps=sequence.nofsteps - local features=sequence.features - local has_rphf=features.rphf - local has_blwf=features.blwf - local has_vatu=features.vatu - local has_pstf=features.pstf - if has_rphf and has_rphf[script] then - devanagari.reph=true - elseif (has_blwf and has_blwf[script] ) or (has_vatu and has_vatu[script] ) then - devanagari.vattu=true - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - for k,v in next,coverage do - for h,w in next,halant do - if v[h] then - if not blwfcache[k] then - blwfcache[k]=v - end - end - if has_vatu and has_vatu[script] and not vatucache[k] then - vatucache[k]=v - end - end - end - end - end - elseif has_pstf and has_pstf[script] then - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - for k,v in next,coverage do - if not pstfcache[k] then - pstfcache[k]=v - end - end - for k,v in next,ra do - local r=coverage[k] - if r then - local found=false - if #r>0 then - for j=1,#r do - local ck=r[j] - local f=ck[4] - local chainlookups=ck[6] - if chainlookups and chainlookups[f] then - local chainlookup=chainlookups[f] - for j=1,#chainlookup do - local chainstep=chainlookup[j] - local steps=chainstep.steps - local nofsteps=chainstep.nofsteps - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - local h=coverage[k] - if h then - for k,v in next,h do - found=v and v.ligature - if found then - pre_base_reordering_consonants[found]=true - break - end - end - if found then - break - end - end - end - end - end - end - end - else - for k,v in next,r do - found=v and v.ligature - if found then - pre_base_reordering_consonants[found]=true - break - end - end - end - if found then - break - end - end - end - end - end - end - for kind,spec in next,features do - if valid[kind] and valid_two(spec)then - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - local reph,rephbase=false,false - if kind=="rphf" then - for k,v in next,ra do - local r=coverage[k] - if r then - rephbase=k - local h=false - if #r>0 then - for j=1,#r do - local ck=r[j] - local f=ck[4] - local chainlookups=ck[6] - if chainlookups then - local chainlookup=chainlookups[f] - for j=1,#chainlookup do - local chainstep=chainlookup[j] - local steps=chainstep.steps - local nofsteps=chainstep.nofsteps - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - local r=coverage[k] - if r then - for k,v in next,halant do - local h=r[k] - if h then - reph=h.ligature or false - break - end - end - if h then - break - end - end - end - end - end - end - end - else - for k,v in next,halant do - local h=r[k] - if h then - reph=h.ligature or false - break - end - end - end - if reph then - break - end - end - end - end - seqsubset[#seqsubset+1]={ kind,coverage,reph,rephbase } - end - end - end - if kind=="pref" then - local steps=sequence.steps - local nofsteps=sequence.nofsteps - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - for k,v in next,halant do - local h=coverage[k] - if h then - local found=false - if #h>0 then - for j=1,#h do - local ck=h[j] - local f=ck[4] - local chainlookups=ck[6] - if chainlookups then - local chainlookup=chainlookups[f] - for j=1,#chainlookup do - local chainstep=chainlookup[j] - local steps=chainstep.steps - local nofsteps=chainstep.nofsteps - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - local h=coverage[k] - if h then - for k,v in next,h do - found=v and v.ligature - if found then - pre_base_reordering_consonants[found]=true - break - end - end - if found then - break - end - end - end - end - end - end - end - else - for k,v in next,h do - found=v and v.ligature - if found then - pre_base_reordering_consonants[found]=true - break - end - end - end - if found then - break - end - end - end - end - end - end - end - end - if two_defaults[script] then - sharedfeatures["dv01"]=true - sharedfeatures["dv02"]=true - sharedfeatures["dv03"]=true - sharedfeatures["dv04"]=true - elseif one_defaults[script] then - sharedfeatures["dv03"]=true - sharedfeatures["dv04"]=true - end - if script=="mlym" or script=="taml" then - devanagari.left_matra_before_base=true - end - end - end -end -registerotffeature { - name="devanagari", - description="inject additional features", - default=true, - initializers={ - node=initializedevanagi, - }, -} -local show_syntax_errors=false -local function inject_syntax_error(head,current,char) - local signal=copy_node(current) - copyinjection(signal,current) - if pre_mark[char] then - setchar(signal,dotted_circle) - else - setchar(current,dotted_circle) - end - return insert_node_after(head,current,signal) -end -local function initialize_one(font,attr) - local tfmdata=fontdata[font] - local datasets=otf.dataset(tfmdata,font,attr) - local devanagaridata=datasets.devanagari - if not devanagaridata then - devanagaridata={ - reph=false, - vattu=false, - blwfcache={}, - vatucache={}, - pstfcache={}, - } - datasets.devanagari=devanagaridata - local resources=tfmdata.resources - local devanagari=resources.devanagari - for s=1,#datasets do - local dataset=datasets[s] - if dataset and dataset[1] then - local kind=dataset[4] - if kind=="rphf" then - devanagaridata.reph=true - elseif kind=="blwf" or kind=="vatu" then - devanagaridata.vattu=true - devanagaridata.blwfcache=devanagari.blwfcache - devanagaridata.vatucache=devanagari.vatucache - devanagaridata.pstfcache=devanagari.pstfcache - end - end - end - end - return devanagaridata.reph,devanagaridata.vattu,devanagaridata.blwfcache,devanagaridata.vatucache,devanagaridata.pstfcache -end -local function contextchain(contexts,n) - local char=getchar(n) - for k=1,#contexts do - local ck=contexts[k] - local seq=ck[3] - local f=ck[4] - local l=ck[5] - if (l-f)==1 and seq[f+1][char] then - local ok=true - local c=n - for i=l+1,#seq do - c=getnext(c) - if not c or not seq[i][ischar(c)] then - ok=false - break - end - end - if ok then - c=getprev(n) - for i=1,f-1 do - c=getprev(c) - if not c or not seq[f-i][ischar(c)] then - ok=false - end - end - end - if ok then - return true - end - end - end - return false -end -local function order_matras(c) - local cn=getnext(c) - local char=getchar(cn) - while dependent_vowel[char] do - local next=getnext(cn) - local cc=c - local cchar=getchar(cc) - while cc~=cn do - if (above_mark[char] and (below_mark[cchar] or post_mark[cchar])) or (below_mark[char] and (post_mark[cchar])) then - local prev,next=getboth(cn) - if next then - setprev(next,prev) - end - setnext(prev,next) - setnext(getprev(cc),cn) - setprev(cn,getprev(cc)) - setnext(cn,cc) - setprev(cc,cn) - break - end - cc=getnext(cc) - cchar=getchar(cc) - end - cn=next - char=getchar(cn) - end -end -local function reorder_one(head,start,stop,font,attr,nbspaces) - local reph,vattu,blwfcache,vatucache,pstfcache=initialize_one(font,attr) - local devanagari=fontdata[font].resources.devanagari - local current=start - local n=getnext(start) - local base=nil - local firstcons=nil - local lastcons=nil - local basefound=false - if reph and ra[getchar(start)] and halant[getchar(n)] then - if n==stop then - return head,stop,nbspaces - end - if getchar(getnext(n))==c_zwj then - current=start - else - current=getnext(n) - setstate(start,s_rphf) - end - end - if getchar(current)==c_nbsp then - if current==stop then - stop=getprev(stop) - head=remove_node(head,current) - flush_node(current) - return head,stop,nbspaces - else - nbspaces=nbspaces+1 - base=current - firstcons=current - lastcons=current - current=getnext(current) - if current~=stop then - local char=getchar(current) - if nukta[char] then - current=getnext(current) - char=getchar(current) - end - if char==c_zwj and current~=stop then - local next=getnext(current) - if next~=stop and halant[getchar(next)] then - current=next - next=getnext(current) - local tmp=next and getnext(next) or nil - local changestop=next==stop - local tempcurrent=copy_node(next) - copyinjection(tempcurrent,next) - local nextcurrent=copy_node(current) - copyinjection(nextcurrent,current) - setlink(tempcurrent,nextcurrent) - setstate(tempcurrent,s_blwf) - tempcurrent=processcharacters(tempcurrent,font) - setstate(tempcurrent,unsetvalue) - if getchar(next)==getchar(tempcurrent) then - flush_list(tempcurrent) - if show_syntax_errors then - head,current=inject_syntax_error(head,current,char) - end - else - setchar(current,getchar(tempcurrent)) - local freenode=getnext(current) - setlink(current,tmp) - flush_node(freenode) - flush_list(tempcurrent) - if changestop then - stop=current - end - end - end - end - end - end - end - while not basefound do - local char=getchar(current) - if consonant[char] then - setstate(current,s_half) - if not firstcons then - firstcons=current - end - lastcons=current - if not base then - base=current - elseif blwfcache[char] then - setstate(current,s_blwf) - elseif pstfcache[char] then - setstate(current,s_pstf) - else - base=current - end - end - basefound=current==stop - current=getnext(current) - end - if base~=lastcons then - local np=base - local n=getnext(base) - local ch=getchar(n) - if nukta[ch] then - np=n - n=getnext(n) - ch=getchar(n) - end - if halant[ch] then - if lastcons~=stop then - local ln=getnext(lastcons) - if nukta[getchar(ln)] then - lastcons=ln - end - end - local nn=getnext(n) - local ln=getnext(lastcons) - setlink(np,nn) - setnext(lastcons,n) - if ln then - setprev(ln,n) - end - setnext(n,ln) - setprev(n,lastcons) - if lastcons==stop then - stop=n - end - end - end - n=getnext(start) - if n~=stop and ra[getchar(start)] and halant[getchar(n)] and not zw_char[getchar(getnext(n))] then - local matra=base - if base~=stop then - local next=getnext(base) - if dependent_vowel[getchar(next)] then - matra=next - end - end - local sp=getprev(start) - local nn=getnext(n) - local mn=getnext(matra) - setlink(sp,nn) - setlink(matra,start) - setlink(n,mn) - if head==start then - head=nn - end - start=nn - if matra==stop then - stop=n - end - end - local current=start - while current~=stop do - local next=getnext(current) - if next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwnj then - setstate(current,unsetvalue) - end - current=next - end - if base~=stop and getstate(base) then - local next=getnext(base) - if halant[getchar(next)] and not (next~=stop and getchar(getnext(next))==c_zwj) then - setstate(base,unsetvalue) - end - end - local current,allreordered,moved=start,false,{ [base]=true } - local a,b,p,bn=base,base,base,getnext(base) - if base~=stop and nukta[getchar(bn)] then - a,b,p=bn,bn,bn - end - while not allreordered do - local c=current - local n=getnext(current) - local l=nil - if c~=stop then - local ch=getchar(n) - if nukta[ch] then - c=n - n=getnext(n) - ch=getchar(n) - end - if c~=stop then - if halant[ch] then - c=n - n=getnext(n) - ch=getchar(n) - end - local tpm=twopart_mark[ch] - while tpm do - local extra=copy_node(n) - copyinjection(extra,n) - ch=tpm[1] - setchar(n,ch) - setchar(extra,tpm[2]) - head=insert_node_after(head,current,extra) - tpm=twopart_mark[ch] - end - while c~=stop and dependent_vowel[ch] do - c=n - n=getnext(n) - ch=getchar(n) - end - if c~=stop then - if vowel_modifier[ch] then - c=n - n=getnext(n) - ch=getchar(n) - end - if c~=stop and stress_tone_mark[ch] then - c=n - n=getnext(n) - end - end - end - end - local bp=getprev(firstcons) - local cn=getnext(current) - local last=getnext(c) - while cn~=last do - if pre_mark[getchar(cn)] then - if devanagari.left_matra_before_base then - local prev,next=getboth(cn) - setlink(prev,next) - if cn==stop then - stop=getprev(cn) - end - if base==start then - if head==start then - head=cn - end - start=cn - end - setlink(getprev(base),cn) - setlink(cn,base) - cn=next - else - if bp then - setnext(bp,cn) - end - local prev,next=getboth(cn) - if next then - setprev(next,prev) - end - setnext(prev,next) - if cn==stop then - stop=prev - end - setprev(cn,bp) - setlink(cn,firstcons) - if firstcons==start then - if head==start then - head=cn - end - start=cn - end - cn=next - end - elseif current~=base and dependent_vowel[getchar(cn)] then - local prev,next=getboth(cn) - if next then - setprev(next,prev) - end - setnext(prev,next) - if cn==stop then - stop=prev - end - setlink(b,cn,getnext(b)) - order_matras(cn) - cn=next - elseif current==base and dependent_vowel[getchar(cn)] then - local cnn=getnext(cn) - order_matras(cn) - cn=cnn - while cn~=last and dependent_vowel[getchar(cn)] do - cn=getnext(cn) - end - else - cn=getnext(cn) - end - end - allreordered=c==stop - current=getnext(c) - end - if reph or vattu then - local current,cns=start,nil - while current~=stop do - local c=current - local n=getnext(current) - if ra[getchar(current)] and halant[getchar(n)] then - c=n - n=getnext(n) - local b,bn=base,base - while bn~=stop do - local next=getnext(bn) - if dependent_vowel[getchar(next)] then - b=next - end - bn=next - end - if getstate(current,s_rphf) then - if b~=current then - if current==start then - if head==start then - head=n - end - start=n - end - if b==stop then - stop=c - end - local prev=getprev(current) - setlink(prev,n) - local next=getnext(b) - setlink(c,next) - setlink(b,current) - end - elseif cns and getnext(cns)~=current then - local cp=getprev(current) - local cnsn=getnext(cns) - setlink(cp,n) - setlink(cns,current) - setlink(c,cnsn) - if c==stop then - stop=cp - break - end - current=getprev(n) - end - else - local char=getchar(current) - if consonant[char] then - cns=current - local next=getnext(cns) - if halant[getchar(next)] then - cns=next - end - if not vatucache[char] then - next=getnext(cns) - while dependent_vowel[getchar(next)] do - cns=next - next=getnext(cns) - end - end - elseif char==c_nbsp then - nbspaces=nbspaces+1 - cns=current - local next=getnext(cns) - if halant[getchar(next)] then - cns=next - end - if not vatucache[char] then - next=getnext(cns) - while dependent_vowel[getchar(next)] do - cns=next - next=getnext(cns) - end - end - end - end - current=getnext(current) - end - end - if getchar(base)==c_nbsp then - nbspaces=nbspaces-1 - if base==stop then - stop=getprev(stop) - end - head=remove_node(head,base) - flush_node(base) - end - return head,stop,nbspaces -end -function handlers.devanagari_reorder_matras(head,start) - local current=start - local startfont=getfont(start) - local startattr=getprop(start,a_syllabe) - while current do - local char=ischar(current,startfont) - local next=getnext(current) - if char and getprop(current,a_syllabe)==startattr then - if halant[char] then - if next then - local char=ischar(next,startfont) - if char and zw_char[char] and getprop(next,a_syllabe)==startattr then - current=next - next=getnext(current) - end - end - local startnext=getnext(start) - head=remove_node(head,start) - setlink(start,next) - setlink(current,start) - start=startnext - break - end - else - break - end - current=next - end - return head,start,true -end -local rephbase={} -function handlers.devanagari_reorder_reph(head,start) - local current=getnext(start) - local startnext=nil - local startprev=nil - local startfont=getfont(start) - local startattr=getprop(start,a_syllabe) - ::step_1:: - local char=ischar(start,startfont) - local rephbase=rephbase[startfont][char] - if char and after_subscript[rephbase] then - goto step_5 - end - ::step_2:: - if char and not after_postscript[rephbase] then - while current do - local char=ischar(current,startfont) - if char and getprop(current,a_syllabe)==startattr then - if halant[char] then - local next=getnext(current) - if next then - local nextchar=ischar(next,startfont) - if nextchar and zw_char[nextchar] and getprop(next,a_syllabe)==startattr then - current=next - next=getnext(current) - end - end - startnext=getnext(start) - head=remove_node(head,start) - setlink(start,next) - setlink(current,start) - start=startnext - startattr=getprop(start,a_syllabe) - break - end - current=getnext(current) - else - break - end - end - end - ::step_3:: - if not startnext then - if char and after_main[rephbase] then - current=getnext(start) - while current do - local char=ischar(current,startfont) - if char and getprop(current,a_syllabe)==startattr then - if consonant[char] and not getstate(current,s_pref) then - startnext=getnext(start) - head=remove_node(head,start) - setlink(current,start) - setlink(start,getnext(current)) - start=startnext - startattr=getprop(start,a_syllabe) - break - end - current=getnext(current) - else - break - end - end - end - end - ::step_4:: - if not startnext then - if char and before_postscript[rephbase] then - current=getnext(start) - local c=nil - while current do - local char=ischar(current,startfont) - if char and getprop(current,a_syllabe)==startattr then - if getstate(current,s_pstf) then - startnext=getnext(start) - head=remove_node(head,start) - setlink(getprev(current),start) - setlink(start,current) - start=startnext - startattr=getprop(start,a_syllabe) - break - elseif not c and (vowel_modifier[char] or stress_tone_mark[char] ) then - c=current - end - current=getnext(current) - else - if c then - startnext=getnext(start) - head=remove_node(head,start) - setlink(getprev(c),start) - setlink(start,c) - start=startnext - startattr=getprop(start,a_syllabe) - end - break - end - end - end - end - ::step_5:: - if not startnext then - current=getnext(start) - local c=nil - while current do - local char=ischar(current,startfont) - if char and getprop(current,a_syllabe)==startattr then - local state=getstate(current) - if before_subscript[rephbase] and (state==s_blwf or state==s_pstf) then - c=current - elseif after_subscript[rephbase] and (state==s_pstf) then - c=current - end - current=getnext(current) - else - break - end - end - if c then - startnext=getnext(start) - head=remove_node(head,start) - setlink(getprev(c),start) - setlink(start,c) - start=startnext - startattr=getprop(start,a_syllabe) - end - end - ::step_6:: - if not startnext then - current=start - local next=getnext(current) - while next do - local nextchar=ischar(next,startfont) - if nextchar and getprop(next,a_syllabe)==startattr then - current=next - next=getnext(current) - else - break - end - end - if start~=current then - startnext=getnext(start) - head=remove_node(head,start) - setlink(start,getnext(current)) - setlink(current,start) - start=startnext - end - end - return head,start,true -end -local reordered_pre_base_reordering_consonants={} -function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start) - if reordered_pre_base_reordering_consonants[start] then - return head,start,true - end - local current=start - local startfont=getfont(start) - local startattr=getprop(start,a_syllabe) - while current do - local char=ischar(current,startfont) - local next=getnext(current) - if char and getprop(current,a_syllabe)==startattr then - if halant[char] then - if next then - local char=ischar(next,startfont) - if char and zw_char[char] and getprop(next,a_syllabe)==startattr then - current=next - next=getnext(current) - end - end - local startnext=getnext(start) - head=remove_node(head,start) - setlink(start,next) - setlink(current,start) - reordered_pre_base_reordering_consonants[start]=true - start=startnext - return head,start,true - end - else - break - end - current=next - end - local startattr=getprop(start,a_syllabe) - local current=getprev(start) - while current and getprop(current,a_syllabe)==startattr do - local char=ischar(current) - if (not dependent_vowel[char] and (not getstate(current) or getstate(current,s_init))) then - startnext=getnext(start) - head=remove_node(head,start) - if current==head then - setlink(start,current) - head=start - else - setlink(getprev(current),start) - setlink(start,current) - end - reordered_pre_base_reordering_consonants[start]=true - start=startnext - break - end - current=getprev(current) - end - return head,start,true -end -function handlers.devanagari_remove_joiners(head,start,kind,lookupname,replacement) - local stop=getnext(start) - local font=getfont(start) - local last=start - while stop do - local char=ischar(stop,font) - if char and (char==c_zwnj or char==c_zwj) then - last=stop - stop=getnext(stop) - else - break - end - end - local prev=getprev(start) - if stop then - setnext(last) - setlink(prev,stop) - elseif prev then - setnext(prev) - end - if head==start then - head=stop - end - flush_list(start) - return head,stop,true -end -local function initialize_two(font,attr) - local devanagari=fontdata[font].resources.devanagari - if devanagari then - return devanagari.seqsubset or {},devanagari.reorderreph or {} - else - return {},{} - end -end -local function reorder_two(head,start,stop,font,attr,nbspaces) - local seqsubset,reorderreph=initialize_two(font,attr) - local halfpos=nil - local basepos=nil - local subpos=nil - local postpos=nil - reorderreph.coverage={} - rephbase[font]={} - for i=1,#seqsubset do - local subset=seqsubset[i] - local kind=subset[1] - local lookupcache=subset[2] - if kind=="rphf" then - reorderreph.coverage[subset[3]]=true - rephbase[font][subset[3]]=subset[4] - local current=start - local last=getnext(stop) - while current~=last do - if current~=stop then - local c=getchar(current) - local found=lookupcache[c] - if found then - local next=getnext(current) - if found[getchar(next)] or contextchain(found,next) then - local afternext=next~=stop and getnext(next) - if afternext and zw_char[getchar(afternext)] then - current=afternext - elseif current==start then - setstate(current,s_rphf) - current=next - else - current=next - end - end - end - end - current=getnext(current) - end - elseif kind=="pref" then - local current=start - local last=getnext(stop) - while current~=last do - if current~=stop then - local c=getchar(current) - local found=lookupcache[c] - if found then - local next=getnext(current) - if found[getchar(next)] or contextchain(found,next) then - if (not getstate(current) and not getstate(next)) then - setstate(current,s_pref) - setstate(next,s_pref) - current=next - end - end - end - end - current=getnext(current) - end - elseif kind=="half" then - local current=start - local last=getnext(stop) - while current~=last do - if current~=stop then - local c=getchar(current) - local found=lookupcache[c] - if found then - local next=getnext(current) - if found[getchar(next)] or contextchain(found,next) then - if next~=stop and getchar(getnext(next))==c_zwnj then - current=next - elseif (not getstate(current)) then - setstate(current,s_half) - if not halfpos then - halfpos=current - end - end - current=getnext(current) - end - end - end - current=getnext(current) - end - elseif kind=="blwf" or kind=="vatu" then - local current=start - local last=getnext(stop) - while current~=last do - if current~=stop then - local c=getchar(current) - local found=lookupcache[c] - if found then - local next=getnext(current) - if found[getchar(next)] or contextchain(found,next) then - if (not getstate(current) and not getstate(next)) then - setstate(current,s_blwf) - setstate(next,s_blwf) - current=next - subpos=current - end - end - end - end - current=getnext(current) - end - elseif kind=="pstf" then - local current=start - local last=getnext(stop) - while current~=last do - if current~=stop then - local c=getchar(current) - local found=lookupcache[c] - if found then - local next=getnext(current) - if found[getchar(next)] or contextchain(found,next) then - if (not getstate(current) and not getstate(next)) then - setstate(current,s_pstf) - setstate(next,s_pstf) - current=next - postpos=current - end - end - end - end - current=getnext(current) - end - end - end - local current,base,firstcons=start,nil,nil - if getstate(start,s_rphf) then - current=getnext(getnext(start)) - end - if current~=getnext(stop) and getchar(current)==c_nbsp then - if current==stop then - stop=getprev(stop) - head=remove_node(head,current) - flush_node(current) - return head,stop,nbspaces - else - nbspaces=nbspaces+1 - base=current - current=getnext(current) - if current~=stop then - local char=getchar(current) - if nukta[char] then - current=getnext(current) - char=getchar(current) - end - if char==c_zwj then - local next=getnext(current) - if current~=stop and next~=stop and halant[getchar(next)] then - current=next - next=getnext(current) - local tmp=getnext(next) - local changestop=next==stop - setnext(next) - setstate(current,s_pref) - current=processcharacters(current,font) - setstate(current,s_blwf) - current=processcharacters(current,font) - setstate(current,s_pstf) - current=processcharacters(current,font) - setstate(current,unsetvalue) - if halant[getchar(current)] then - setnext(getnext(current),tmp) - if show_syntax_errors then - head,current=inject_syntax_error(head,current,char) - end - else - setnext(current,tmp) - if changestop then - stop=current - end - end - end - end - end - end - else - local last=getnext(stop) - while current~=last do - local next=getnext(current) - if consonant[getchar(current)] then - if not (current~=stop and next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwj) then - if not firstcons then - firstcons=current - end - local a=getstate(current) - if not (a==s_blwf or a==s_pstf or (a~=s_rphf and a~=s_blwf and ra[getchar(current)])) then - base=current - end - end - end - current=next - end - if not base then - base=firstcons - end - end - if not base then - if getstate(start,s_rphf) then - setstate(start,unsetvalue) - end - return head,stop,nbspaces - else - if getstate(base) then - setstate(base,unsetvalue) - end - basepos=base - end - if not halfpos then - halfpos=base - end - if not subpos then - subpos=base - end - if not postpos then - postpos=subpos or base - end - local moved={} - local current=start - local last=getnext(stop) - while current~=last do - local char=getchar(current) - local target=nil - local cn=getnext(current) - local tpm=twopart_mark[char] - while tpm do - local extra=copy_node(current) - copyinjection(extra,current) - char=tpm[1] - setchar(current,char) - setchar(extra,tpm[2]) - head=insert_node_after(head,current,extra) - tpm=twopart_mark[char] - end - if not moved[current] and dependent_vowel[char] then - if pre_mark[char] then - moved[current]=true - local prev,next=getboth(current) - setlink(prev,next) - if current==stop then - stop=getprev(current) - end - local pos - if before_main[char] then - pos=basepos - else - pos=halfpos - end - local ppos=getprev(pos) - while ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) do - if getstate(ppos,s_pref) then - pos=ppos - end - ppos=getprev(ppos) - end - local ppos=getprev(pos) - while ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) and halant[ischar(ppos)] do - ppos=getprev(ppos) - if ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) and consonant[ischar(ppos)] then - pos=ppos - ppos=getprev(ppos) - else - break - end - end - if pos==start then - if head==start then - head=current - end - start=current - end - setlink(getprev(pos),current) - setlink(current,pos) - elseif above_mark[char] then - target=basepos - if subpos==basepos then - subpos=current - end - if postpos==basepos then - postpos=current - end - basepos=current - elseif below_mark[char] then - target=subpos - if postpos==subpos then - postpos=current - end - subpos=current - elseif post_mark[char] then - local n=getnext(postpos) - while n do - local v=ischar(n,font) - if nukta[v] or stress_tone_mark[v] or vowel_modifier[v] then - postpos=n - else - break - end - n=getnext(n) - end - target=postpos - postpos=current - end - if mark_above_below_post[char] then - local prev=getprev(current) - if prev~=target then - local next=getnext(current) - setlink(prev,next) - if current==stop then - stop=prev - end - setlink(current,getnext(target)) - setlink(target,current) - end - end - end - current=cn - end - local current=getnext(start) - local last=getnext(stop) - while current~=last do - local char=getchar(current) - local cn=getnext(current) - if halant[char] and ra[ischar(cn)] and (not getstate(cn,s_rphf)) and (not getstate(cn,s_blwf)) then - if after_main[ischar(cn)] then - local prev=getprev(current) - local next=getnext(cn) - local bpn=getnext(basepos) - while bpn and dependent_vowel[ischar(bpn)] do - basepos=bpn - bpn=getnext(bpn) - end - if basepos~=prev then - setlink(prev,next) - setlink(cn,getnext(basepos)) - setlink(basepos,current) - if cn==stop then - stop=prev - end - cn=next - end - end - end - current=cn - end - local current=start - local c=nil - while current~=stop do - local char=getchar(current) - if halant[char] or stress_tone_mark[char] then - if not c then - c=current - end - else - c=nil - end - local next=getnext(current) - if c and nukta[getchar(next)] then - if head==c then - head=next - end - if stop==next then - stop=current - end - setlink(getprev(c),next) - local nextnext=getnext(next) - setnext(current,nextnext) - local nextnextnext=getnext(nextnext) - if nextnextnext then - setprev(nextnextnext,current) - end - setlink(nextnext,c) - end - if stop==current then break end - current=getnext(current) - end - if getchar(base)==c_nbsp then - if base==stop then - stop=getprev(stop) - end - nbspaces=nbspaces-1 - head=remove_node(head,base) - flush_node(base) - end - return head,stop,nbspaces -end -local separator={} -imerge(separator,consonant) -imerge(separator,independent_vowel) -imerge(separator,dependent_vowel) -imerge(separator,vowel_modifier) -imerge(separator,stress_tone_mark) -for k,v in next,nukta do separator[k]=true end -for k,v in next,halant do separator[k]=true end -local function analyze_next_chars_one(c,font,variant) - local n=getnext(c) - if not n then - return c - end - if variant==1 then - local v=ischar(n,font) - if v and nukta[v] then - n=getnext(n) - if n then - v=ischar(n,font) - end - end - if n and v then - local nn=getnext(n) - if nn then - local vv=ischar(nn,font) - if vv then - local nnn=getnext(nn) - if nnn then - local vvv=ischar(nnn,font) - if vvv then - if vv==c_zwj and consonant[vvv] then - c=nnn - elseif (vv==c_zwnj or vv==c_zwj) and halant[vvv] then - local nnnn=getnext(nnn) - if nnnn then - local vvvv=ischar(nnnn,font) - if vvvv and consonant[vvvv] then - c=nnnn - end - end - end - end - end - end - end - end - elseif variant==2 then - local v=ischar(n,font) - if v and nukta[v] then - c=n - end - n=getnext(c) - if n then - v=ischar(n,font) - if v then - local nn=getnext(n) - if nn then - local vv=ischar(nn,font) - if vv and zw_char[v] then - n=nn - v=vv - nn=getnext(nn) - vv=nn and ischar(nn,font) - end - if vv and halant[v] and consonant[vv] then - c=nn - end - end - end - end - end - local n=getnext(c) - if not n then - return c - end - local v=ischar(n,font) - if not v then - return c - end - local already_pre_mark - local already_above_mark - local already_below_mark - local already_post_mark - while dependent_vowel[v] do - local vowels=twopart_mark[v] or { v } - for k,v in next,vowels do - if pre_mark[v] and not already_pre_mark then - already_pre_mark=true - elseif above_mark[v] and not already_above_mark then - already_above_mark=true - elseif below_mark[v] and not already_below_mark then - already_below_mark=true - elseif post_mark[v] and not already_post_mark then - already_post_mark=true - else - return c - end - end - c=getnext(c) - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if nukta[v] then - c=getnext(c) - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if halant[v] then - c=getnext(c) - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if vowel_modifier[v] then - c=getnext(c) - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if stress_tone_mark[v] then - c=getnext(c) - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if stress_tone_mark[v] then - return n - else - return c - end -end -local function analyze_next_chars_two(c,font) - local n=getnext(c) - if not n then - return c - end - local v=ischar(n,font) - if v and nukta[v] then - c=n - end - n=c - while true do - local nn=getnext(n) - if nn then - local vv=ischar(nn,font) - if vv then - if halant[vv] then - n=nn - local nnn=getnext(nn) - if nnn then - local vvv=ischar(nnn,font) - if vvv and zw_char[vvv] then - n=nnn - end - end - elseif vv==c_zwnj or vv==c_zwj then - local nnn=getnext(nn) - if nnn then - local vvv=ischar(nnn,font) - if vvv and halant[vvv] then - n=nnn - end - end - else - break - end - local nn=getnext(n) - if nn then - local vv=ischar(nn,font) - if vv and consonant[vv] then - n=nn - local nnn=getnext(nn) - if nnn then - local vvv=ischar(nnn,font) - if vvv and nukta[vvv] then - n=nnn - end - end - c=n - else - break - end - else - break - end - else - break - end - else - break - end - end - if not c then - return - end - local n=getnext(c) - if not n then - return c - end - local v=ischar(n,font) - if not v then - return c - end - if anudatta[v] then - c=n - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if halant[v] then - c=n - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - if v==c_zwnj or v==c_zwj then - c=n - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - else - local already_pre_mark - local already_above_mark - local already_below_mark - local already_post_mark - while dependent_vowel[v] do - local vowels=twopart_mark[v] or { v } - for k,v in next,vowels do - if pre_mark[v] and not already_pre_mark then - already_pre_mark=true - elseif above_mark[v] and not already_above_mark then - already_above_mark=true - elseif below_mark[v] and not already_below_mark then - already_below_mark=true - elseif post_mark[v] and not already_post_mark then - already_post_mark=true - else - return c - end - end - c=n - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if nukta[v] then - c=n - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if halant[v] then - c=n - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - end - if vowel_modifier[v] then - c=n - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if stress_tone_mark[v] then - c=n - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if stress_tone_mark[v] then - return n - else - return c - end -end -local function method_one(head,font,attr) - local current=head - local start=true - local done=false - local nbspaces=0 - local syllabe=0 - while current do - local char=ischar(current,font) - if char then - done=true - local syllablestart=current - local syllableend=nil - local c=current - local n=getnext(c) - local first=char - if n and ra[first] then - local second=ischar(n,font) - if second and halant[second] then - local n=getnext(n) - if n then - local third=ischar(n,font) - if third then - c=n - first=third - end - end - end - end - local standalone=first==c_nbsp - if standalone then - local prev=getprev(current) - if prev then - local prevchar=ischar(prev,font) - if not prevchar then - elseif not separator[prevchar] then - else - standalone=false - end - else - end - end - if standalone then - local syllableend=analyze_next_chars_one(c,font,2) - current=getnext(syllableend) - if syllablestart~=syllableend then - head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces) - current=getnext(current) - end - else - if consonant[char] then - local prevc=true - while prevc do - prevc=false - local n=getnext(current) - if not n then - break - end - local v=ischar(n,font) - if not v then - break - end - if nukta[v] then - n=getnext(n) - if not n then - break - end - v=ischar(n,font) - if not v then - break - end - end - if halant[v] then - n=getnext(n) - if not n then - break - end - v=ischar(n,font) - if not v then - break - end - if v==c_zwnj or v==c_zwj then - n=getnext(n) - if not n then - break - end - v=ischar(n,font) - if not v then - break - end - end - if consonant[v] then - prevc=true - current=n - end - end - end - local n=getnext(current) - if n then - local v=ischar(n,font) - if v and nukta[v] then - current=n - n=getnext(current) - end - end - syllableend=current - current=n - if current then - local v=ischar(current,font) - if not v then - elseif halant[v] then - local n=getnext(current) - if n then - local v=ischar(n,font) - if v and zw_char[v] then - syllableend=n - current=getnext(n) - else - syllableend=current - current=n - end - else - syllableend=current - current=n - end - else - if dependent_vowel[v] then - syllableend=current - current=getnext(current) - v=ischar(current,font) - end - if v and vowel_modifier[v] then - syllableend=current - current=getnext(current) - v=ischar(current,font) - end - if v and stress_tone_mark[v] then - syllableend=current - current=getnext(current) - end - end - end - if syllablestart~=syllableend then - if syllableend then - syllabe=syllabe+1 - local c=syllablestart - local n=getnext(syllableend) - while c~=n do - setprop(c,a_syllabe,syllabe) - c=getnext(c) - end - end - head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces) - current=getnext(current) - end - elseif independent_vowel[char] then - syllableend=current - current=getnext(current) - if current then - local v=ischar(current,font) - if v then - if vowel_modifier[v] then - syllableend=current - current=getnext(current) - v=ischar(current,font) - end - if v and stress_tone_mark[v] then - syllableend=current - current=getnext(current) - end - end - end - else - if show_syntax_errors then - local mark=mark_four[char] - if mark then - head,current=inject_syntax_error(head,current,char) - end - end - current=getnext(current) - end - end - else - current=getnext(current) - end - start=false - end - if nbspaces>0 then - head=replace_all_nbsp(head) - end - current=head - local n=0 - while current do - local char=ischar(current,font) - if char then - if n==0 and not getstate(current) then - setstate(current,s_init) - end - n=n+1 - else - n=0 - end - current=getnext(current) - end - return head,done -end -local function method_two(head,font,attr) - local current=head - local start=true - local done=false - local syllabe=0 - local nbspaces=0 - while current do - local syllablestart=nil - local syllableend=nil - local char=ischar(current,font) - if char then - done=true - syllablestart=current - local c=current - local n=getnext(current) - if n and ra[char] then - local nextchar=ischar(n,font) - if nextchar and halant[nextchar] then - local n=getnext(n) - if n then - local nextnextchar=ischar(n,font) - if nextnextchar then - c=n - char=nextnextchar - end - end - end - end - if independent_vowel[char] then - current=analyze_next_chars_one(c,font,1) - syllableend=current - else - local standalone=char==c_nbsp - if standalone then - nbspaces=nbspaces+1 - local p=getprev(current) - if not p then - elseif ischar(p,font) then - elseif not separator[getchar(p)] then - else - standalone=false - end - end - if standalone then - current=analyze_next_chars_one(c,font,2) - syllableend=current - elseif consonant[getchar(current)] then - current=analyze_next_chars_two(current,font) - syllableend=current - end - end - end - if syllableend then - syllabe=syllabe+1 - local c=syllablestart - local n=getnext(syllableend) - while c~=n do - setprop(c,a_syllabe,syllabe) - c=getnext(c) - end - end - if syllableend and syllablestart~=syllableend then - head,current,nbspaces=reorder_two(head,syllablestart,syllableend,font,attr,nbspaces) - end - if not syllableend and show_syntax_errors then - local char=ischar(current,font) - if char and not getstate(current) then - local mark=mark_four[char] - if mark then - head,current=inject_syntax_error(head,current,char) - end - end - end - start=false - current=getnext(current) - end - if nbspaces>0 then - head=replace_all_nbsp(head) - end - current=head - local n=0 - while current do - local char=ischar(current,font) - if char then - if n==0 and not getstate(current) then - setstate(current,s_init) - end - n=n+1 - else - n=0 - end - current=getnext(current) - end - return head,done -end -for i=1,nofscripts do - methods[scripts_one[i]]=method_one - methods[scripts_two[i]]=method_two -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-osd”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ocl” 797b5c71bf819c5f4fb314a4d646e9a7] --- - -if not modules then modules={} end modules ['font-ocl']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local tostring,tonumber,next=tostring,tonumber,next -local round,max=math.round,math.round -local gsub,find=string.gsub,string.find -local sortedkeys,sortedhash,concat=table.sortedkeys,table.sortedhash,table.concat -local setmetatableindex=table.setmetatableindex -local formatters=string.formatters -local tounicode=fonts.mappings.tounicode -local helpers=fonts.helpers -local charcommand=helpers.commands.char -local rightcommand=helpers.commands.right -local leftcommand=helpers.commands.left -local downcommand=helpers.commands.down -local otf=fonts.handlers.otf -local otfregister=otf.features.register -local f_color=formatters["%.3f %.3f %.3f rg"] -local f_gray=formatters["%.3f g"] -if context then - local startactualtext=nil - local stopactualtext=nil - function otf.getactualtext(s) - if not startactualtext then - startactualtext=backends.codeinjections.startunicodetoactualtextdirect - stopactualtext=backends.codeinjections.stopunicodetoactualtextdirect - end - return startactualtext(s),stopactualtext() - end -else - local tounicode=fonts.mappings.tounicode16 - function otf.getactualtext(s) - return - "/Span << /ActualText >> BDC", - "EMC" - end -end -local sharedpalettes={} -local hash=setmetatableindex(function(t,k) - local v={ "pdf","direct",k } - t[k]=v - return v -end) -if context then - local colors=attributes.list[attributes.private('color')] or {} - local transparencies=attributes.list[attributes.private('transparency')] or {} - function otf.registerpalette(name,values) - sharedpalettes[name]=values - local color=lpdf.color - local transparency=lpdf.transparency - local register=colors.register - for i=1,#values do - local v=values[i] - if v=="textcolor" then - values[i]=false - else - local c=nil - local t=nil - if type(v)=="table" then - c=register(name,"rgb", - max(round((v.r or 0)*255),255)/255, - max(round((v.g or 0)*255),255)/255, - max(round((v.b or 0)*255),255)/255 - ) - else - c=colors[v] - t=transparencies[v] - end - if c and t then - values[i]=hash[color(1,c).." "..transparency(t)] - elseif c then - values[i]=hash[color(1,c)] - elseif t then - values[i]=hash[color(1,t)] - end - end - end - end -else - function otf.registerpalette(name,values) - sharedpalettes[name]=values - for i=1,#values do - local v=values[i] - if v then - values[i]=hash[f_color( - max(round((v.r or 0)*255),255)/255, - max(round((v.g or 0)*255),255)/255, - max(round((v.b or 0)*255),255)/255 - )] - end - end - end -end -local function convert(t,k) - local v={} - for i=1,#k do - local p=k[i] - local r,g,b=p[1],p[2],p[3] - if r==g and g==b then - v[i]=hash[f_gray(r/255)] - else - v[i]=hash[f_color(r/255,g/255,b/255)] - end - end - t[k]=v - return v -end -local mode={ "pdf","mode","font" } -local push={ "pdf","page","q" } -local pop={ "pdf","page","Q" } -local function initializeoverlay(tfmdata,kind,value) - if value then - local resources=tfmdata.resources - local palettes=resources.colorpalettes - if palettes then - local converted=resources.converted - if not converted then - converted=setmetatableindex(convert) - resources.converted=converted - end - local colorvalues=sharedpalettes[value] - local default=false - if colorvalues then - default=colorvalues[#colorvalues] - else - colorvalues=converted[palettes[tonumber(value) or 1] or palettes[1]] or {} - end - local classes=#colorvalues - if classes==0 then - return - end - local characters=tfmdata.characters - local descriptions=tfmdata.descriptions - local properties=tfmdata.properties - properties.virtualized=true - tfmdata.fonts={ - { id=0 } - } - local getactualtext=otf.getactualtext - local b,e=getactualtext(tounicode(0xFFFD)) - local actualb={ "pdf","page",b } - local actuale={ "pdf","page",e } - for unicode,character in next,characters do - local description=descriptions[unicode] - if description then - local colorlist=description.colors - if colorlist then - local u=description.unicode or characters[unicode].unicode - local w=character.width or 0 - local s=#colorlist - local goback=w~=0 and leftcommand[w] or nil - local t={ - mode, - not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) }, - push, - } - local n=3 - local l=nil - for i=1,s do - local entry=colorlist[i] - local v=colorvalues[entry.class] or default - if v and l~=v then - n=n+1 t[n]=v - l=v - end - n=n+1 t[n]=charcommand[entry.slot] - if s>1 and i temp-otf-svg-shape.log","w") - end - end - local new=nil - local function inkscapeformat(suffix) - if new==nil then - new=os.resultof("inkscape --version") or "" - new=new=="" or not find(new,"Inkscape%s*0") - end - return new and "filename" or suffix - end - function otfsvg.topdf(svgshapes,tfmdata) - local pdfshapes={} - local inkscape=runner() - if inkscape then - local descriptions=tfmdata.descriptions - local nofshapes=#svgshapes - local f_svgfile=formatters["temp-otf-svg-shape-%i.svg"] - local f_pdffile=formatters["temp-otf-svg-shape-%i.pdf"] - local f_convert=formatters["%s --export-%s=%s\n"] - local filterglyph=otfsvg.filterglyph - local nofdone=0 - local processed={} - report_svg("processing %i svg containers",nofshapes) - statistics.starttiming() - for i=1,nofshapes do - local entry=svgshapes[i] - for index=entry.first,entry.last do - local data=filterglyph(entry,index) - if data and data~="" then - local svgfile=f_svgfile(index) - local pdffile=f_pdffile(index) - savedata(svgfile,data) - inkscape:write(f_convert(svgfile,inkscapeformat("pdf"),pdffile)) - processed[index]=true - nofdone=nofdone+1 - if nofdone%25==0 then - report_svg("%i shapes submitted",nofdone) - end - end - end - end - if nofdone%25~=0 then - report_svg("%i shapes submitted",nofdone) - end - report_svg("processing can be going on for a while") - inkscape:write("quit\n") - inkscape:close() - report_svg("processing %i pdf results",nofshapes) - for index in next,processed do - local svgfile=f_svgfile(index) - local pdffile=f_pdffile(index) - local pdfdata=loaddata(pdffile) - if pdfdata and pdfdata~="" then - pdfshapes[index]={ - data=pdfdata, - } - end - remove(svgfile) - remove(pdffile) - end - local characters=tfmdata.characters - for k,v in next,characters do - local d=descriptions[k] - local i=d.index - if i then - local p=pdfshapes[i] - if p then - local w=d.width - local l=d.boundingbox[1] - local r=d.boundingbox[3] - p.scale=(r-l)/w - p.x=l - end - end - end - if not next(pdfshapes) then - report_svg("there are no converted shapes, fix your setup") - end - statistics.stoptiming() - if statistics.elapsedseconds then - report_svg("svg conversion time %s",statistics.elapsedseconds() or "-") - end - end - return pdfshapes - end -end -local function initializesvg(tfmdata,kind,value) - if value and otf.svgenabled then - local svg=tfmdata.properties.svg - local hash=svg and svg.hash - local timestamp=svg and svg.timestamp - if not hash then - return - end - local pdffile=containers.read(otf.pdfcache,hash) - local pdfshapes=pdffile and pdffile.pdfshapes - if not pdfshapes or pdffile.timestamp~=timestamp or not next(pdfshapes) then - local svgfile=containers.read(otf.svgcache,hash) - local svgshapes=svgfile and svgfile.svgshapes - pdfshapes=svgshapes and otfsvg.topdf(svgshapes,tfmdata,otf.pdfcache.writable,hash) or {} - containers.write(otf.pdfcache,hash,{ - pdfshapes=pdfshapes, - timestamp=timestamp, - }) - end - pdftovirtual(tfmdata,pdfshapes,"svg") - return true - end -end -otfregister { - name="svg", - description="svg glyphs", - manipulators={ - base=initializesvg, - node=initializesvg, - } -} -local otfpng=otf.png or {} -otf.png=otfpng -otf.pngenabled=true -do - local report_png=logs.reporter("fonts","png conversion") - local loaddata=io.loaddata - local savedata=io.savedata - local remove=os.remove - local runner=sandbox and sandbox.registerrunner { - name="otfpng", - program="gm", - template="convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log", - } - if not runner then - runner=function() - return os.execute("gm convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log") - end - end - function otfpng.topdf(pngshapes) - local pdfshapes={} - local pngfile="temp-otf-png-shape.png" - local pdffile="temp-otf-png-shape.pdf" - local nofdone=0 - local indices=sortedkeys(pngshapes) - local nofindices=#indices - report_png("processing %i png containers",nofindices) - statistics.starttiming() - for i=1,nofindices do - local index=indices[i] - local entry=pngshapes[index] - local data=entry.data - local x=entry.x - local y=entry.y - savedata(pngfile,data) - runner() - pdfshapes[index]={ - x=x~=0 and x or nil, - y=y~=0 and y or nil, - data=loaddata(pdffile), - } - nofdone=nofdone+1 - if nofdone%100==0 then - report_png("%i shapes processed",nofdone) - end - end - report_png("processing %i pdf results",nofindices) - remove(pngfile) - remove(pdffile) - statistics.stoptiming() - if statistics.elapsedseconds then - report_png("png conversion time %s",statistics.elapsedseconds() or "-") - end - return pdfshapes - end -end -local function initializepng(tfmdata,kind,value) - if value and otf.pngenabled then - local png=tfmdata.properties.png - local hash=png and png.hash - local timestamp=png and png.timestamp - if not hash then - return - end - local pdffile=containers.read(otf.pdfcache,hash) - local pdfshapes=pdffile and pdffile.pdfshapes - if not pdfshapes or pdffile.timestamp~=timestamp then - local pngfile=containers.read(otf.pngcache,hash) - local pngshapes=pngfile and pngfile.pngshapes - pdfshapes=pngshapes and otfpng.topdf(pngshapes) or {} - containers.write(otf.pdfcache,hash,{ - pdfshapes=pdfshapes, - timestamp=timestamp, - }) - end - pdftovirtual(tfmdata,pdfshapes,"png") - return true - end -end -otfregister { - name="sbix", - description="sbix glyphs", - manipulators={ - base=initializepng, - node=initializepng, - } -} -otfregister { - name="cblc", - description="cblc glyphs", - manipulators={ - base=initializepng, - node=initializepng, - } -} -if context then - local function initializecolor(tfmdata,kind,value) - if value=="auto" then - return - initializeoverlay(tfmdata,kind,value) or - initializesvg(tfmdata,kind,value) or - initializepng(tfmdata,kind,value) - elseif value=="overlay" then - return initializeoverlay(tfmdata,kind,value) - elseif value=="svg" then - return initializesvg(tfmdata,kind,value) - elseif value=="png" or value=="bitmap" then - return initializepng(tfmdata,kind,value) - else - end - end - otfregister { - name="color", - description="color glyphs", - manipulators={ - base=initializecolor, - node=initializecolor, - } - } -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ocl”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otc” 0f12230ea07b5151f75d52726977e91f] --- - -if not modules then modules={} end modules ['font-otc']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local insert,sortedkeys,sortedhash,tohash=table.insert,table.sortedkeys,table.sortedhash,table.tohash -local type,next,tonumber=type,next,tonumber -local lpegmatch=lpeg.match -local utfbyte,utflen=utf.byte,utf.len -local sortedhash=table.sortedhash -local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) -local report_otf=logs.reporter("fonts","otf loading") -local fonts=fonts -local otf=fonts.handlers.otf -local registerotffeature=otf.features.register -local setmetatableindex=table.setmetatableindex -local fonthelpers=fonts.helpers -local checkmerge=fonthelpers.checkmerge -local checkflags=fonthelpers.checkflags -local checksteps=fonthelpers.checksteps -local normalized={ - substitution="substitution", - single="substitution", - ligature="ligature", - alternate="alternate", - multiple="multiple", - kern="kern", - pair="pair", - single="single", - chainsubstitution="chainsubstitution", - chainposition="chainposition", -} -local types={ - substitution="gsub_single", - ligature="gsub_ligature", - alternate="gsub_alternate", - multiple="gsub_multiple", - kern="gpos_pair", - pair="gpos_pair", - single="gpos_single", - chainsubstitution="gsub_contextchain", - chainposition="gpos_contextchain", -} -local names={ - gsub_single="gsub", - gsub_multiple="gsub", - gsub_alternate="gsub", - gsub_ligature="gsub", - gsub_context="gsub", - gsub_contextchain="gsub", - gsub_reversecontextchain="gsub", - gpos_single="gpos", - gpos_pair="gpos", - gpos_cursive="gpos", - gpos_mark2base="gpos", - gpos_mark2ligature="gpos", - gpos_mark2mark="gpos", - gpos_context="gpos", - gpos_contextchain="gpos", -} -setmetatableindex(types,function(t,k) t[k]=k return k end) -local everywhere={ ["*"]={ ["*"]=true } } -local noflags={ false,false,false,false } -local function getrange(sequences,category) - local count=#sequences - local first=nil - local last=nil - for i=1,count do - local t=sequences[i].type - if t and names[t]==category then - if not first then - first=i - end - last=i - end - end - return first or 1,last or count -end -local function validspecification(specification,name) - local dataset=specification.dataset - if dataset then - elseif specification[1] then - dataset=specification - specification={ dataset=dataset } - else - dataset={ { data=specification.data } } - specification.data=nil - specification.dataset=dataset - end - local first=dataset[1] - if first then - first=first.data - end - if not first then - report_otf("invalid feature specification, no dataset") - return - end - if type(name)~="string" then - name=specification.name or first.name - end - if type(name)~="string" then - report_otf("invalid feature specification, no name") - return - end - local n=#dataset - if n>0 then - for i=1,n do - setmetatableindex(dataset[i],specification) - end - return specification,name - end -end -local function addfeature(data,feature,specifications) - if not specifications then - report_otf("missing specification") - return - end - local descriptions=data.descriptions - local resources=data.resources - local features=resources.features - local sequences=resources.sequences - if not features or not sequences then - report_otf("missing specification") - return - end - local alreadydone=resources.alreadydone - if not alreadydone then - alreadydone={} - resources.alreadydone=alreadydone - end - if alreadydone[specifications] then - return - else - alreadydone[specifications]=true - end - local fontfeatures=resources.features or everywhere - local unicodes=resources.unicodes - local splitter=lpeg.splitter(" ",unicodes) - local done=0 - local skip=0 - local aglunicodes=false - local privateslot=fonthelpers.privateslot - local specifications=validspecification(specifications,feature) - if not specifications then - return - end - local p=lpeg.P("P")*(lpeg.patterns.hexdigit^1/function(s) return tonumber(s,16) end)*lpeg.P(-1) - local function tounicode(code) - if not code then - return - end - if type(code)=="number" then - return code - end - local u=unicodes[code] - if u then - return u - end - if utflen(code)==1 then - u=utfbyte(code) - if u then - return u - end - end - if privateslot then - u=privateslot(code) - if u then - return u - end - end - local u=lpegmatch(p,code) - if u then - return u - end - if not aglunicodes then - aglunicodes=fonts.encodings.agl.unicodes - end - local u=aglunicodes[code] - if u then - return u - end - end - local coverup=otf.coverup - local coveractions=coverup.actions - local stepkey=coverup.stepkey - local register=coverup.register - local function prepare_substitution(list,featuretype,nocheck) - local coverage={} - local cover=coveractions[featuretype] - for code,replacement in next,list do - local unicode=tounicode(code) - local description=descriptions[unicode] - if not nocheck and not description then - skip=skip+1 - else - if type(replacement)=="table" then - replacement=replacement[1] - end - replacement=tounicode(replacement) - if replacement and (nocheck or descriptions[replacement]) then - cover(coverage,unicode,replacement) - done=done+1 - else - skip=skip+1 - end - end - end - return coverage - end - local function prepare_alternate(list,featuretype,nocheck) - local coverage={} - local cover=coveractions[featuretype] - for code,replacement in next,list do - local unicode=tounicode(code) - local description=descriptions[unicode] - if not nocheck and not description then - skip=skip+1 - elseif type(replacement)=="table" then - local r={} - for i=1,#replacement do - local u=tounicode(replacement[i]) - r[i]=(nocheck or descriptions[u]) and u or unicode - end - cover(coverage,unicode,r) - done=done+1 - else - local u=tounicode(replacement) - if u then - cover(coverage,unicode,{ u }) - done=done+1 - else - skip=skip+1 - end - end - end - return coverage - end - local function prepare_multiple(list,featuretype,nocheck) - local coverage={} - local cover=coveractions[featuretype] - for code,replacement in next,list do - local unicode=tounicode(code) - local description=descriptions[unicode] - if not nocheck and not description then - skip=skip+1 - elseif type(replacement)=="table" then - local r={} - local n=0 - for i=1,#replacement do - local u=tounicode(replacement[i]) - if nocheck or descriptions[u] then - n=n+1 - r[n]=u - end - end - if n>0 then - cover(coverage,unicode,r) - done=done+1 - else - skip=skip+1 - end - else - local u=tounicode(replacement) - if u then - cover(coverage,unicode,{ u }) - done=done+1 - else - skip=skip+1 - end - end - end - return coverage - end - local function prepare_ligature(list,featuretype,nocheck) - local coverage={} - local cover=coveractions[featuretype] - for code,ligature in next,list do - local unicode=tounicode(code) - local description=descriptions[unicode] - if not nocheck and not description then - skip=skip+1 - else - if type(ligature)=="string" then - ligature={ lpegmatch(splitter,ligature) } - end - local present=true - for i=1,#ligature do - local l=ligature[i] - local u=tounicode(l) - if nocheck or descriptions[u] then - ligature[i]=u - else - present=false - break - end - end - if present then - cover(coverage,unicode,ligature) - done=done+1 - else - skip=skip+1 - end - end - end - return coverage - end - local function resetspacekerns() - data.properties.hasspacekerns=true - data.resources .spacekerns=nil - end - local function prepare_kern(list,featuretype) - local coverage={} - local cover=coveractions[featuretype] - local isspace=false - for code,replacement in next,list do - local unicode=tounicode(code) - local description=descriptions[unicode] - if description and type(replacement)=="table" then - local r={} - for k,v in next,replacement do - local u=tounicode(k) - if u then - r[u]=v - if u==32 then - isspace=true - end - end - end - if next(r) then - cover(coverage,unicode,r) - done=done+1 - if unicode==32 then - isspace=true - end - else - skip=skip+1 - end - else - skip=skip+1 - end - end - if isspace then - resetspacekerns() - end - return coverage - end - local function prepare_pair(list,featuretype) - local coverage={} - local cover=coveractions[featuretype] - if cover then - for code,replacement in next,list do - local unicode=tounicode(code) - local description=descriptions[unicode] - if description and type(replacement)=="table" then - local r={} - for k,v in next,replacement do - local u=tounicode(k) - if u then - r[u]=v - if u==32 then - isspace=true - end - end - end - if next(r) then - cover(coverage,unicode,r) - done=done+1 - if unicode==32 then - isspace=true - end - else - skip=skip+1 - end - else - skip=skip+1 - end - end - if isspace then - resetspacekerns() - end - else - report_otf("unknown cover type %a",featuretype) - end - return coverage - end - local prepare_single=prepare_pair - local function prepare_chain(list,featuretype,sublookups) - local rules=list.rules - local coverage={} - if rules then - local rulehash={} - local rulesize=0 - local lookuptype=types[featuretype] - for nofrules=1,#rules do - local rule=rules[nofrules] - local current=rule.current - local before=rule.before - local after=rule.after - local replacements=rule.replacements or false - local sequence={} - local nofsequences=0 - if before then - for n=1,#before do - nofsequences=nofsequences+1 - sequence[nofsequences]=before[n] - end - end - local start=nofsequences+1 - for n=1,#current do - nofsequences=nofsequences+1 - sequence[nofsequences]=current[n] - end - local stop=nofsequences - if after then - for n=1,#after do - nofsequences=nofsequences+1 - sequence[nofsequences]=after[n] - end - end - local lookups=rule.lookups or false - local subtype=nil - if lookups and sublookups then - for k,v in sortedhash(lookups) do - local t=type(v) - if t=="table" then - for i=1,#v do - local vi=v[i] - if type(vi)~="table" then - v[i]={ vi } - end - end - elseif t=="number" then - local lookup=sublookups[v] - if lookup then - lookups[k]={ lookup } - if not subtype then - subtype=lookup.type - end - elseif v==0 then - lookups[k]={ { type="gsub_remove" } } - else - lookups[k]=false - end - else - lookups[k]=false - end - end - end - if nofsequences>0 then - local hashed={} - for i=1,nofsequences do - local t={} - local s=sequence[i] - for i=1,#s do - local u=tounicode(s[i]) - if u then - t[u]=true - end - end - hashed[i]=t - end - sequence=hashed - rulesize=rulesize+1 - rulehash[rulesize]={ - nofrules, - lookuptype, - sequence, - start, - stop, - lookups, - replacements, - subtype, - } - for unic in sortedhash(sequence[start]) do - local cu=coverage[unic] - if not cu then - coverage[unic]=rulehash - end - end - sequence.n=nofsequences - end - end - rulehash.n=rulesize - end - return coverage - end - local dataset=specifications.dataset - local function report(name,category,position,first,last,sequences) - report_otf("injecting name %a of category %a at position %i in [%i,%i] of [%i,%i]", - name,category,position,first,last,1,#sequences) - end - local function inject(specification,sequences,sequence,first,last,category,name) - local position=specification.position or false - if not position then - position=specification.prepend - if position==true then - if trace_loading then - report(name,category,first,first,last,sequences) - end - insert(sequences,first,sequence) - return - end - end - if not position then - position=specification.append - if position==true then - if trace_loading then - report(name,category,last+1,first,last,sequences) - end - insert(sequences,last+1,sequence) - return - end - end - local kind=type(position) - if kind=="string" then - local index=false - for i=first,last do - local s=sequences[i] - local f=s.features - if f then - for k in sortedhash(f) do - if k==position then - index=i - break - end - end - if index then - break - end - end - end - if index then - position=index - else - position=last+1 - end - elseif kind=="number" then - if position<0 then - position=last-position+1 - end - if position>last then - position=last+1 - elseif position0 then - for k,v in next,askedfeatures do - if v[1] then - askedfeatures[k]=tohash(v) - end - end - if featureflags[1] then featureflags[1]="mark" end - if featureflags[2] then featureflags[2]="ligature" end - if featureflags[3] then featureflags[3]="base" end - local steptype=types[featuretype] - local sequence={ - chain=featurechain, - features={ [feature]=askedfeatures }, - flags=featureflags, - name=feature, - order=featureorder, - [stepkey]=steps, - nofsteps=nofsteps, - type=steptype, - } - checkflags(sequence,resources) - checkmerge(sequence) - checksteps(sequence) - local first,last=getrange(sequences,category) - inject(specification,sequences,sequence,first,last,category,feature) - local features=fontfeatures[category] - if not features then - features={} - fontfeatures[category]=features - end - local k=features[feature] - if not k then - k={} - features[feature]=k - end - for script,languages in next,askedfeatures do - local kk=k[script] - if not kk then - kk={} - k[script]=kk - end - for language,value in next,languages do - kk[language]=value - end - end - end - end - end - if trace_loading then - report_otf("registering feature %a, affected glyphs %a, skipped glyphs %a",feature,done,skip) - end -end -otf.enhancers.addfeature=addfeature -local extrafeatures={} -local knownfeatures={} -function otf.addfeature(name,specification) - if type(name)=="table" then - specification=name - end - if type(specification)~="table" then - report_otf("invalid feature specification, no valid table") - return - end - specification,name=validspecification(specification,name) - if name and specification then - local slot=knownfeatures[name] - if not slot then - slot=#extrafeatures+1 - knownfeatures[name]=slot - elseif specification.overload==false then - slot=#extrafeatures+1 - knownfeatures[name]=slot - else - end - specification.name=name - extrafeatures[slot]=specification - end -end -local function enhance(data,filename,raw) - for slot=1,#extrafeatures do - local specification=extrafeatures[slot] - addfeature(data,specification.name,specification) - end -end -otf.enhancers.enhance=enhance -otf.enhancers.register("check extra features",enhance) - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otc”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-onr” 6d161533f3437435e12a0ad64866df44] --- - -if not modules then modules={} end modules ['font-onr']={ - version=1.001, - optimize=true, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local fonts,logs,trackers,resolvers=fonts,logs,trackers,resolvers -local next,type,tonumber,rawset=next,type,tonumber,rawset -local match,lower,gsub,strip,find=string.match,string.lower,string.gsub,string.strip,string.find -local char,byte,sub=string.char,string.byte,string.sub -local abs=math.abs -local bxor,rshift=bit32.bxor,bit32.rshift -local P,S,R,V,Cmt,C,Ct,Cs,Carg,Cf,Cg,Cc=lpeg.P,lpeg.S,lpeg.R,lpeg.V,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cf,lpeg.Cg,lpeg.Cc -local lpegmatch,patterns=lpeg.match,lpeg.patterns -local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end) -local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end) -local report_afm=logs.reporter("fonts","afm loading") -local report_pfb=logs.reporter("fonts","pfb loading") -local handlers=fonts.handlers -local afm=handlers.afm or {} -handlers.afm=afm -local readers=afm.readers or {} -afm.readers=readers -afm.version=1.513 -local get_indexes,get_shapes -do - local decrypt - do - local r,c1,c2,n=0,0,0,0 - local function step(c) - local cipher=byte(c) - local plain=bxor(cipher,rshift(r,8)) - r=((cipher+r)*c1+c2)%65536 - return char(plain) - end - decrypt=function(binary,initial,seed) - r,c1,c2,n=initial,52845,22719,seed - binary=gsub(binary,".",step) - return sub(binary,n+1) - end - end - local charstrings=P("/CharStrings") - local subroutines=P("/Subrs") - local encoding=P("/Encoding") - local dup=P("dup") - local put=P("put") - local array=P("array") - local name=P("/")*C((R("az","AZ","09")+S("-_."))^1) - local digits=R("09")^1 - local cardinal=digits/tonumber - local spaces=P(" ")^1 - local spacing=patterns.whitespace^0 - local routines,vector,chars,n,m - local initialize=function(str,position,size) - n=0 - m=size - return position+1 - end - local setroutine=function(str,position,index,size,filename) - if routines[index] then - return false - end - local forward=position+size - local stream=decrypt(sub(str,position+1,forward),4330,4) - routines[index]={ byte(stream,1,#stream) } - n=n+1 - if n>=m then - return #str - end - return forward+1 - end - local setvector=function(str,position,name,size,filename) - local forward=position+tonumber(size) - if n>=m then - return #str - elseif forward<#str then - if n==0 and name~=".notdef" then - report_pfb("reserving .notdef at index 0 in %a",filename) - n=n+1 - end - vector[n]=name - n=n+1 - return forward - else - return #str - end - end - local setshapes=function(str,position,name,size,filename) - local forward=position+tonumber(size) - local stream=sub(str,position+1,forward) - if n>m then - return #str - elseif forward<#str then - if n==0 and name~=".notdef" then - report_pfb("reserving .notdef at index 0 in %a",filename) - n=n+1 - end - vector[n]=name - n=n+1 - chars [n]=decrypt(stream,4330,4) - return forward - else - return #str - end - end - local p_rd=spacing*(P("RD")+P("-|")) - local p_np=spacing*(P("NP")+P("|")) - local p_nd=spacing*(P("ND")+P("|")) - local p_filterroutines= - (1-subroutines)^0*subroutines*spaces*Cmt(cardinal,initialize)*(Cmt(cardinal*spaces*cardinal*p_rd*Carg(1),setroutine)*p_np+(1-p_nd))^1 - local p_filtershapes= - (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*p_rd*Carg(1),setshapes)*p_nd+P(1))^1 - local p_filternames=Ct ( - (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*Carg(1),setvector)+P(1))^1 - ) - local p_filterencoding=(1-encoding)^0*encoding*spaces*digits*spaces*array*(1-dup)^0*Cf( - Ct("")*Cg(spacing*dup*spaces*cardinal*spaces*name*spaces*put)^1 -,rawset) - local key=spacing*P("/")*R("az","AZ") - local str=spacing*Cs { (P("(")/"")*((1-P("\\(")-P("\\)")-S("()"))+V(1))^0*(P(")")/"") } - local num=spacing*(R("09")+S("+-."))^1/tonumber - local arr=spacing*Ct (S("[{")*(num)^0*spacing*S("]}")) - local boo=spacing*(P("true")*Cc(true)+P("false")*Cc(false)) - local nam=spacing*P("/")*Cs(R("az","AZ")^1) - local p_filtermetadata=( - P("/")*Carg(1)*(( - C("version")*str+C("Copyright")*str+C("Notice")*str+C("FullName")*str+C("FamilyName")*str+C("Weight")*str+C("ItalicAngle")*num+C("isFixedPitch")*boo+C("UnderlinePosition")*num+C("UnderlineThickness")*num+C("FontName")*nam+C("FontMatrix")*arr+C("FontBBox")*arr - ) )/function(t,k,v) t[lower(k)]=v end+P(1) - )^0*Carg(1) - local function loadpfbvector(filename,shapestoo,streams) - local data=io.loaddata(resolvers.findfile(filename)) - if not data then - report_pfb("no data in %a",filename) - return - end - if not (find(data,"!PS-AdobeFont-",1,true) or find(data,"%!FontType1",1,true)) then - report_pfb("no font in %a",filename) - return - end - local ascii,binary=match(data,"(.*)eexec%s+......(.*)") - if not binary then - report_pfb("no binary data in %a",filename) - return - end - binary=decrypt(binary,55665,4) - local names={} - local encoding=lpegmatch(p_filterencoding,ascii) - local metadata=lpegmatch(p_filtermetadata,ascii,1,{}) - local glyphs={} - routines,vector,chars={},{},{} - if shapestoo or streams then - lpegmatch(p_filterroutines,binary,1,filename) - lpegmatch(p_filtershapes,binary,1,filename) - local data={ - dictionaries={ - { - charstrings=chars, - charset=vector, - subroutines=routines, - } - }, - } - fonts.handlers.otf.readers.parsecharstrings(false,data,glyphs,true,"cff",streams,true) - else - lpegmatch(p_filternames,binary,1,filename) - end - names=vector - routines,vector,chars=nil,nil,nil - return names,encoding,glyphs,metadata - end - local pfb=handlers.pfb or {} - handlers.pfb=pfb - pfb.loadvector=loadpfbvector - get_indexes=function(data,pfbname) - local vector=loadpfbvector(pfbname) - if vector then - local characters=data.characters - if trace_loading then - report_afm("getting index data from %a",pfbname) - end - for index=0,#vector do - local name=vector[index] - local char=characters[name] - if char then - if trace_indexing then - report_afm("glyph %a has index %a",name,index) - end - char.index=index - else - if trace_indexing then - report_afm("glyph %a has index %a but no data",name,index) - end - end - end - end - end - get_shapes=function(pfbname) - local vector,encoding,glyphs=loadpfbvector(pfbname,true) - return glyphs - end -end -local spacer=patterns.spacer -local whitespace=patterns.whitespace -local lineend=patterns.newline -local spacing=spacer^0 -local number=spacing*S("+-")^-1*(R("09")+S("."))^1/tonumber -local name=spacing*C((1-whitespace)^1) -local words=spacing*((1-lineend)^1/strip) -local rest=(1-lineend)^0 -local fontdata=Carg(1) -local semicolon=spacing*P(";") -local plus=spacing*P("plus")*number -local minus=spacing*P("minus")*number -local function addkernpair(data,one,two,value) - local chr=data.characters[one] - if chr then - local kerns=chr.kerns - if kerns then - kerns[two]=tonumber(value) - else - chr.kerns={ [two]=tonumber(value) } - end - end -end -local p_kernpair=(fontdata*P("KPX")*name*name*number)/addkernpair -local chr=false -local ind=0 -local function start(data,version) - data.metadata.afmversion=version - ind=0 - chr={} -end -local function stop() - ind=0 - chr=false -end -local function setindex(i) - if i<0 then - ind=ind+1 - else - ind=i - end - chr={ - index=ind - } -end -local function setwidth(width) - chr.width=width -end -local function setname(data,name) - data.characters[name]=chr -end -local function setboundingbox(boundingbox) - chr.boundingbox=boundingbox -end -local function setligature(plus,becomes) - local ligatures=chr.ligatures - if ligatures then - ligatures[plus]=becomes - else - chr.ligatures={ [plus]=becomes } - end -end -local p_charmetric=(( - P("C")*number/setindex+P("WX")*number/setwidth+P("N")*fontdata*name/setname+P("B")*Ct((number)^4)/setboundingbox+P("L")*(name)^2/setligature - )*semicolon )^1 -local p_charmetrics=P("StartCharMetrics")*number*(p_charmetric+(1-P("EndCharMetrics")))^0*P("EndCharMetrics") -local p_kernpairs=P("StartKernPairs")*number*(p_kernpair+(1-P("EndKernPairs" )))^0*P("EndKernPairs" ) -local function set_1(data,key,a) data.metadata[lower(key)]=a end -local function set_2(data,key,a,b) data.metadata[lower(key)]={ a,b } end -local function set_3(data,key,a,b,c) data.metadata[lower(key)]={ a,b,c } end -local p_parameters=P(false)+fontdata*((P("FontName")+P("FullName")+P("FamilyName"))/lower)*words/function(data,key,value) - data.metadata[key]=value - end+fontdata*((P("Weight")+P("Version"))/lower)*name/function(data,key,value) - data.metadata[key]=value - end+fontdata*P("IsFixedPitch")*name/function(data,pitch) - data.metadata.monospaced=toboolean(pitch,true) - end+fontdata*P("FontBBox")*Ct(number^4)/function(data,boundingbox) - data.metadata.boundingbox=boundingbox - end+fontdata*((P("CharWidth")+P("CapHeight")+P("XHeight")+P("Descender")+P("Ascender")+P("ItalicAngle"))/lower)*number/function(data,key,value) - data.metadata[key]=value - end+P("Comment")*spacing*(P(false)+(fontdata*C("DESIGNSIZE")*number*rest)/set_1 -+(fontdata*C("TFM designsize")*number*rest)/set_1+(fontdata*C("DesignSize")*number*rest)/set_1+(fontdata*C("CODINGSCHEME")*words*rest)/set_1 -+(fontdata*C("CHECKSUM")*number*words*rest)/set_1 -+(fontdata*C("SPACE")*number*plus*minus*rest)/set_3 -+(fontdata*C("QUAD")*number*rest)/set_1 -+(fontdata*C("EXTRASPACE")*number*rest)/set_1 -+(fontdata*C("NUM")*number*number*number*rest)/set_3 -+(fontdata*C("DENOM")*number*number*rest)/set_2 -+(fontdata*C("SUP")*number*number*number*rest)/set_3 -+(fontdata*C("SUB")*number*number*rest)/set_2 -+(fontdata*C("SUPDROP")*number*rest)/set_1 -+(fontdata*C("SUBDROP")*number*rest)/set_1 -+(fontdata*C("DELIM")*number*number*rest)/set_2 -+(fontdata*C("AXISHEIGHT")*number*rest)/set_1 - ) -local fullparser=(P("StartFontMetrics")*fontdata*name/start )*(p_charmetrics+p_kernpairs+p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop ) -local infoparser=(P("StartFontMetrics")*fontdata*name/start )*(p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop ) -local function read(filename,parser) - local afmblob=io.loaddata(filename) - if afmblob then - local data={ - resources={ - filename=resolvers.unresolve(filename), - version=afm.version, - creator="context mkiv", - }, - properties={ - hasitalics=false, - }, - goodies={}, - metadata={ - filename=file.removesuffix(file.basename(filename)) - }, - characters={ - }, - descriptions={ - }, - } - if trace_loading then - report_afm("parsing afm file %a",filename) - end - lpegmatch(parser,afmblob,1,data) - return data - else - if trace_loading then - report_afm("no valid afm file %a",filename) - end - return nil - end -end -function readers.loadfont(afmname,pfbname) - local data=read(resolvers.findfile(afmname),fullparser) - if data then - if not pfbname or pfbname=="" then - pfbname=resolvers.findfile(file.replacesuffix(file.nameonly(afmname),"pfb")) - end - if pfbname and pfbname~="" then - data.resources.filename=resolvers.unresolve(pfbname) - get_indexes(data,pfbname) - return data - else - report_afm("no pfb file for %a",afmname) - end - end -end -function readers.loadshapes(filename) - local fullname=resolvers.findfile(filename) or "" - if fullname=="" then - return { - filename="not found: "..filename, - glyphs={} - } - else - return { - filename=fullname, - format="opentype", - glyphs=get_shapes(fullname) or {}, - units=1000, - } - end -end -function readers.getinfo(filename) - local data=read(resolvers.findfile(filename),infoparser) - if data then - return data.metadata - end -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-onr”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-one” 53cd565030e919da984b50471cc3be37] --- - -if not modules then modules={} end modules ['font-one']={ - version=1.001, - optimize=true, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local fonts,logs,trackers,containers,resolvers=fonts,logs,trackers,containers,resolvers -local next,type,tonumber,rawget=next,type,tonumber,rawget -local match,gsub=string.match,string.gsub -local abs=math.abs -local P,S,R,Cmt,C,Ct,Cs,Carg=lpeg.P,lpeg.S,lpeg.R,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg -local lpegmatch,patterns=lpeg.match,lpeg.patterns -local sortedhash=table.sortedhash -local trace_features=false trackers.register("afm.features",function(v) trace_features=v end) -local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end) -local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end) -local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) -local report_afm=logs.reporter("fonts","afm loading") -local setmetatableindex=table.setmetatableindex -local derivetable=table.derive -local findbinfile=resolvers.findbinfile -local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -local definers=fonts.definers -local readers=fonts.readers -local constructors=fonts.constructors -local afm=constructors.handlers.afm -local pfb=constructors.handlers.pfb -local otf=fonts.handlers.otf -local otfreaders=otf.readers -local otfenhancers=otf.enhancers -local afmfeatures=constructors.features.afm -local registerafmfeature=afmfeatures.register -local afmenhancers=constructors.enhancers.afm -local registerafmenhancer=afmenhancers.register -afm.version=1.513 -afm.cache=containers.define("fonts","one",afm.version,true) -afm.autoprefixed=true -afm.helpdata={} -afm.syncspace=true -local overloads=fonts.mappings.overloads -local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes -function afm.load(filename) - filename=resolvers.findfile(filename,'afm') or "" - if filename~="" and not fonts.names.ignoredfile(filename) then - local name=file.removesuffix(file.basename(filename)) - local data=containers.read(afm.cache,name) - local attr=lfs.attributes(filename) - local size=attr and attr.size or 0 - local time=attr and attr.modification or 0 - local pfbfile=file.replacesuffix(name,"pfb") - local pfbname=resolvers.findfile(pfbfile,"pfb") or "" - if pfbname=="" then - pfbname=resolvers.findfile(file.basename(pfbfile),"pfb") or "" - end - local pfbsize=0 - local pfbtime=0 - if pfbname~="" then - local attr=lfs.attributes(pfbname) - pfbsize=attr.size or 0 - pfbtime=attr.modification or 0 - end - if not data or data.size~=size or data.time~=time or data.pfbsize~=pfbsize or data.pfbtime~=pfbtime then - report_afm("reading %a",filename) - data=afm.readers.loadfont(filename,pfbname) - if data then - afmenhancers.apply(data,filename) - fonts.mappings.addtounicode(data,filename) - otfreaders.stripredundant(data) - otfreaders.pack(data) - data.size=size - data.time=time - data.pfbsize=pfbsize - data.pfbtime=pfbtime - report_afm("saving %a in cache",name) - data=containers.write(afm.cache,name,data) - data=containers.read(afm.cache,name) - end - end - if data then - otfreaders.unpack(data) - otfreaders.expand(data) - otfreaders.addunicodetable(data) - otfenhancers.apply(data,filename,data) - if applyruntimefixes then - applyruntimefixes(filename,data) - end - end - return data - end -end -local uparser=fonts.mappings.makenameparser() -local function enhance_unify_names(data,filename) - local unicodevector=fonts.encodings.agl.unicodes - local unicodes={} - local names={} - local private=data.private or privateoffset - local descriptions=data.descriptions - for name,blob in sortedhash(data.characters) do - local code=unicodevector[name] - if not code then - code=lpegmatch(uparser,name) - if type(code)~="number" then - code=private - private=private+1 - report_afm("assigning private slot %U for unknown glyph name %a",code,name) - end - end - local index=blob.index - unicodes[name]=code - names[name]=index - blob.name=name - descriptions[code]={ - boundingbox=blob.boundingbox, - width=blob.width, - kerns=blob.kerns, - index=index, - name=name, - } - end - for unicode,description in next,descriptions do - local kerns=description.kerns - if kerns then - local krn={} - for name,kern in next,kerns do - local unicode=unicodes[name] - if unicode then - krn[unicode]=kern - else - end - end - description.kerns=krn - end - end - data.characters=nil - data.private=private - local resources=data.resources - local filename=resources.filename or file.removesuffix(file.basename(filename)) - resources.filename=resolvers.unresolve(filename) - resources.unicodes=unicodes - resources.marks={} -end -local everywhere={ ["*"]={ ["*"]=true } } -local noflags={ false,false,false,false } -local function enhance_normalize_features(data) - local ligatures=setmetatableindex("table") - local kerns=setmetatableindex("table") - local extrakerns=setmetatableindex("table") - for u,c in next,data.descriptions do - local l=c.ligatures - local k=c.kerns - local e=c.extrakerns - if l then - ligatures[u]=l - for u,v in next,l do - l[u]={ ligature=v } - end - c.ligatures=nil - end - if k then - kerns[u]=k - for u,v in next,k do - k[u]=v - end - c.kerns=nil - end - if e then - extrakerns[u]=e - for u,v in next,e do - e[u]=v - end - c.extrakerns=nil - end - end - local features={ - gpos={}, - gsub={}, - } - local sequences={ - } - if next(ligatures) then - features.gsub.liga=everywhere - data.properties.hasligatures=true - sequences[#sequences+1]={ - features={ - liga=everywhere, - }, - flags=noflags, - name="s_s_0", - nofsteps=1, - order={ "liga" }, - type="gsub_ligature", - steps={ - { - coverage=ligatures, - }, - }, - } - end - if next(kerns) then - features.gpos.kern=everywhere - data.properties.haskerns=true - sequences[#sequences+1]={ - features={ - kern=everywhere, - }, - flags=noflags, - name="p_s_0", - nofsteps=1, - order={ "kern" }, - type="gpos_pair", - steps={ - { - format="kern", - coverage=kerns, - }, - }, - } - end - if next(extrakerns) then - features.gpos.extrakerns=everywhere - data.properties.haskerns=true - sequences[#sequences+1]={ - features={ - extrakerns=everywhere, - }, - flags=noflags, - name="p_s_1", - nofsteps=1, - order={ "extrakerns" }, - type="gpos_pair", - steps={ - { - format="kern", - coverage=extrakerns, - }, - }, - } - end - data.resources.features=features - data.resources.sequences=sequences -end -local function enhance_fix_names(data) - for k,v in next,data.descriptions do - local n=v.name - local r=overloads[n] - if r then - local name=r.name - if trace_indexing then - report_afm("renaming characters %a to %a",n,name) - end - v.name=name - v.unicode=r.unicode - end - end -end -local addthem=function(rawdata,ligatures) - if ligatures then - local descriptions=rawdata.descriptions - local resources=rawdata.resources - local unicodes=resources.unicodes - for ligname,ligdata in next,ligatures do - local one=descriptions[unicodes[ligname]] - if one then - for _,pair in next,ligdata do - local two=unicodes[pair[1]] - local three=unicodes[pair[2]] - if two and three then - local ol=one.ligatures - if ol then - if not ol[two] then - ol[two]=three - end - else - one.ligatures={ [two]=three } - end - end - end - end - end - end -end -local function enhance_add_ligatures(rawdata) - addthem(rawdata,afm.helpdata.ligatures) -end -local function enhance_add_extra_kerns(rawdata) - local descriptions=rawdata.descriptions - local resources=rawdata.resources - local unicodes=resources.unicodes - local function do_it_left(what) - if what then - for unicode,description in next,descriptions do - local kerns=description.kerns - if kerns then - local extrakerns - for complex,simple in next,what do - complex=unicodes[complex] - simple=unicodes[simple] - if complex and simple then - local ks=kerns[simple] - if ks and not kerns[complex] then - if extrakerns then - extrakerns[complex]=ks - else - extrakerns={ [complex]=ks } - end - end - end - end - if extrakerns then - description.extrakerns=extrakerns - end - end - end - end - end - local function do_it_copy(what) - if what then - for complex,simple in next,what do - complex=unicodes[complex] - simple=unicodes[simple] - if complex and simple then - local complexdescription=descriptions[complex] - if complexdescription then - local simpledescription=descriptions[complex] - if simpledescription then - local extrakerns - local kerns=simpledescription.kerns - if kerns then - for unicode,kern in next,kerns do - if extrakerns then - extrakerns[unicode]=kern - else - extrakerns={ [unicode]=kern } - end - end - end - local extrakerns=simpledescription.extrakerns - if extrakerns then - for unicode,kern in next,extrakerns do - if extrakerns then - extrakerns[unicode]=kern - else - extrakerns={ [unicode]=kern } - end - end - end - if extrakerns then - complexdescription.extrakerns=extrakerns - end - end - end - end - end - end - end - do_it_left(afm.helpdata.leftkerned) - do_it_left(afm.helpdata.bothkerned) - do_it_copy(afm.helpdata.bothkerned) - do_it_copy(afm.helpdata.rightkerned) -end -local function adddimensions(data) - if data then - for unicode,description in next,data.descriptions do - local bb=description.boundingbox - if bb then - local ht=bb[4] - local dp=-bb[2] - if ht==0 or ht<0 then - else - description.height=ht - end - if dp==0 or dp<0 then - else - description.depth=dp - end - end - end - end -end -local function copytotfm(data) - if data and data.descriptions then - local metadata=data.metadata - local resources=data.resources - local properties=derivetable(data.properties) - local descriptions=derivetable(data.descriptions) - local goodies=derivetable(data.goodies) - local characters={} - local parameters={} - local unicodes=resources.unicodes - for unicode,description in next,data.descriptions do - characters[unicode]={} - end - local filename=constructors.checkedfilename(resources) - local fontname=metadata.fontname or metadata.fullname - local fullname=metadata.fullname or metadata.fontname - local endash=0x2013 - local emdash=0x2014 - local space=0x0020 - local spacer="space" - local spaceunits=500 - local monospaced=metadata.monospaced - local charwidth=metadata.charwidth - local italicangle=metadata.italicangle - local charxheight=metadata.xheight and metadata.xheight>0 and metadata.xheight - properties.monospaced=monospaced - parameters.italicangle=italicangle - parameters.charwidth=charwidth - parameters.charxheight=charxheight - local d_endash=descriptions[endash] - local d_emdash=descriptions[emdash] - local d_space=descriptions[space] - if not d_space or d_space==0 then - d_space=d_endash - end - if d_space then - spaceunits,spacer=d_space.width or 0,"space" - end - if properties.monospaced then - if spaceunits==0 and d_emdash then - spaceunits,spacer=d_emdash.width or 0,"emdash" - end - else - if spaceunits==0 and d_endash then - spaceunits,spacer=d_emdash.width or 0,"endash" - end - end - if spaceunits==0 and charwidth then - spaceunits,spacer=charwidth or 0,"charwidth" - end - if spaceunits==0 then - spaceunits=tonumber(spaceunits) or 500 - end - if spaceunits==0 then - spaceunits=500 - end - parameters.slant=0 - parameters.space=spaceunits - parameters.space_stretch=500 - parameters.space_shrink=333 - parameters.x_height=400 - parameters.quad=1000 - if italicangle and italicangle~=0 then - parameters.italicangle=italicangle - parameters.italicfactor=math.cos(math.rad(90+italicangle)) - parameters.slant=- math.tan(italicangle*math.pi/180) - end - if monospaced then - parameters.space_stretch=0 - parameters.space_shrink=0 - elseif afm.syncspace then - parameters.space_stretch=spaceunits/2 - parameters.space_shrink=spaceunits/3 - end - parameters.extra_space=parameters.space_shrink - if charxheight then - parameters.x_height=charxheight - else - local x=0x0078 - if x then - local x=descriptions[x] - if x then - parameters.x_height=x.height - end - end - end - if metadata.sup then - local dummy={ 0,0,0 } - parameters[ 1]=metadata.designsize or 0 - parameters[ 2]=metadata.checksum or 0 - parameters[ 3], - parameters[ 4], - parameters[ 5]=unpack(metadata.space or dummy) - parameters[ 6]=metadata.quad or 0 - parameters[ 7]=metadata.extraspace or 0 - parameters[ 8], - parameters[ 9], - parameters[10]=unpack(metadata.num or dummy) - parameters[11], - parameters[12]=unpack(metadata.denom or dummy) - parameters[13], - parameters[14], - parameters[15]=unpack(metadata.sup or dummy) - parameters[16], - parameters[17]=unpack(metadata.sub or dummy) - parameters[18]=metadata.supdrop or 0 - parameters[19]=metadata.subdrop or 0 - parameters[20], - parameters[21]=unpack(metadata.delim or dummy) - parameters[22]=metadata.axisheight or 0 - end - parameters.designsize=(metadata.designsize or 10)*65536 - parameters.ascender=abs(metadata.ascender or 0) - parameters.descender=abs(metadata.descender or 0) - parameters.units=1000 - properties.spacer=spacer - properties.format=fonts.formats[filename] or "type1" - properties.filename=filename - properties.fontname=fontname - properties.fullname=fullname - properties.psname=fullname - properties.name=filename or fullname or fontname - properties.private=properties.private or data.private or privateoffset -if not CONTEXTLMTXMODE or CONTEXTLMTXMODE==0 then - properties.encodingbytes=2 -end - if next(characters) then - return { - characters=characters, - descriptions=descriptions, - parameters=parameters, - resources=resources, - properties=properties, - goodies=goodies, - } - end - end - return nil -end -function afm.setfeatures(tfmdata,features) - local okay=constructors.initializefeatures("afm",tfmdata,features,trace_features,report_afm) - if okay then - return constructors.collectprocessors("afm",tfmdata,features,trace_features,report_afm) - else - return {} - end -end -local function addtables(data) - local resources=data.resources - local lookuptags=resources.lookuptags - local unicodes=resources.unicodes - if not lookuptags then - lookuptags={} - resources.lookuptags=lookuptags - end - setmetatableindex(lookuptags,function(t,k) - local v=type(k)=="number" and ("lookup "..k) or k - t[k]=v - return v - end) - if not unicodes then - unicodes={} - resources.unicodes=unicodes - setmetatableindex(unicodes,function(t,k) - setmetatableindex(unicodes,nil) - for u,d in next,data.descriptions do - local n=d.name - if n then - t[n]=u - end - end - return rawget(t,k) - end) - end - constructors.addcoreunicodes(unicodes) -end -local function afmtotfm(specification) - local afmname=specification.filename or specification.name - if specification.forced=="afm" or specification.format=="afm" then - if trace_loading then - report_afm("forcing afm format for %a",afmname) - end - else - local tfmname=findbinfile(afmname,"ofm") or "" - if tfmname~="" then - if trace_loading then - report_afm("fallback from afm to tfm for %a",afmname) - end - return - end - end - if afmname~="" then - local features=constructors.checkedfeatures("afm",specification.features.normal) - specification.features.normal=features - constructors.hashinstance(specification,true) - specification=definers.resolve(specification) - local cache_id=specification.hash - local tfmdata=containers.read(constructors.cache,cache_id) - if not tfmdata then - local rawdata=afm.load(afmname) - if rawdata and next(rawdata) then - addtables(rawdata) - adddimensions(rawdata) - tfmdata=copytotfm(rawdata) - if tfmdata and next(tfmdata) then - local shared=tfmdata.shared - if not shared then - shared={} - tfmdata.shared=shared - end - shared.rawdata=rawdata - shared.dynamics={} - tfmdata.changed={} - shared.features=features - shared.processes=afm.setfeatures(tfmdata,features) - end - elseif trace_loading then - report_afm("no (valid) afm file found with name %a",afmname) - end - tfmdata=containers.write(constructors.cache,cache_id,tfmdata) - end - return tfmdata - end -end -local function read_from_afm(specification) - local tfmdata=afmtotfm(specification) - if tfmdata then - tfmdata.properties.name=specification.name - tfmdata=constructors.scale(tfmdata,specification) - local allfeatures=tfmdata.shared.features or specification.features.normal - constructors.applymanipulators("afm",tfmdata,allfeatures,trace_features,report_afm) - fonts.loggers.register(tfmdata,'afm',specification) - end - return tfmdata -end -registerafmfeature { - name="mode", - description="mode", - initializers={ - base=otf.modeinitializer, - node=otf.modeinitializer, - } -} -registerafmfeature { - name="features", - description="features", - default=true, - initializers={ - node=otf.nodemodeinitializer, - base=otf.basemodeinitializer, - }, - processors={ - node=otf.featuresprocessor, - } -} -fonts.formats.afm="type1" -fonts.formats.pfb="type1" -local function check_afm(specification,fullname) - local foundname=findbinfile(fullname,'afm') or "" - if foundname=="" then - foundname=fonts.names.getfilename(fullname,"afm") or "" - end - if fullname and foundname=="" and afm.autoprefixed then - local encoding,shortname=match(fullname,"^(.-)%-(.*)$") - if encoding and shortname and fonts.encodings.known[encoding] then - shortname=findbinfile(shortname,'afm') or "" - if shortname~="" then - foundname=shortname - if trace_defining then - report_afm("stripping encoding prefix from filename %a",afmname) - end - end - end - end - if foundname~="" then - specification.filename=foundname - specification.format="afm" - return read_from_afm(specification) - end -end -function readers.afm(specification,method) - local fullname=specification.filename or "" - local tfmdata=nil - if fullname=="" then - local forced=specification.forced or "" - if forced~="" then - tfmdata=check_afm(specification,specification.name.."."..forced) - end - if not tfmdata then - local check_tfm=readers.check_tfm - method=(check_tfm and (method or definers.method or "afm or tfm")) or "afm" - if method=="tfm" then - tfmdata=check_tfm(specification,specification.name) - elseif method=="afm" then - tfmdata=check_afm(specification,specification.name) - elseif method=="tfm or afm" then - tfmdata=check_tfm(specification,specification.name) or check_afm(specification,specification.name) - else - tfmdata=check_afm(specification,specification.name) or check_tfm(specification,specification.name) - end - end - else - tfmdata=check_afm(specification,fullname) - end - return tfmdata -end -function readers.pfb(specification,method) - local original=specification.specification - if trace_defining then - report_afm("using afm reader for %a",original) - end - specification.forced="afm" - local function swap(name) - local value=specification[swap] - if value then - specification[swap]=gsub("%.pfb",".afm",1) - end - end - swap("filename") - swap("fullname") - swap("forcedname") - swap("specification") - return readers.afm(specification,method) -end -registerafmenhancer("unify names",enhance_unify_names) -registerafmenhancer("add ligatures",enhance_add_ligatures) -registerafmenhancer("add extra kerns",enhance_add_extra_kerns) -registerafmenhancer("normalize features",enhance_normalize_features) -registerafmenhancer("check extra features",otfenhancers.enhance) -registerafmenhancer("fix names",enhance_fix_names) - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-one”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-afk” 9da14e0fb22129c053acc599d1312544] --- - -if not modules then modules={} end modules ['font-afk']={ - version=1.001, - comment="companion to font-lib.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files", - dataonly=true, -} -local allocate=utilities.storage.allocate -fonts.handlers.afm.helpdata={ - ligatures=allocate { - ['f']={ - { 'f','ff' }, - { 'i','fi' }, - { 'l','fl' }, - }, - ['ff']={ - { 'i','ffi' } - }, - ['fi']={ - { 'i','fii' } - }, - ['fl']={ - { 'i','fli' } - }, - ['s']={ - { 't','st' } - }, - ['i']={ - { 'j','ij' } - }, - }, - texligatures=allocate { - ['quoteleft']={ - { 'quoteleft','quotedblleft' } - }, - ['quoteright']={ - { 'quoteright','quotedblright' } - }, - ['hyphen']={ - { 'hyphen','endash' } - }, - ['endash']={ - { 'hyphen','emdash' } - } - }, - leftkerned=allocate { - AEligature="A",aeligature="a", - OEligature="O",oeligature="o", - IJligature="I",ijligature="i", - AE="A",ae="a", - OE="O",oe="o", - IJ="I",ij="i", - Ssharp="S",ssharp="s", - }, - rightkerned=allocate { - AEligature="E",aeligature="e", - OEligature="E",oeligature="e", - IJligature="J",ijligature="j", - AE="E",ae="e", - OE="E",oe="e", - IJ="J",ij="j", - Ssharp="S",ssharp="s", - }, - bothkerned=allocate { - Acircumflex="A",acircumflex="a", - Ccircumflex="C",ccircumflex="c", - Ecircumflex="E",ecircumflex="e", - Gcircumflex="G",gcircumflex="g", - Hcircumflex="H",hcircumflex="h", - Icircumflex="I",icircumflex="i", - Jcircumflex="J",jcircumflex="j", - Ocircumflex="O",ocircumflex="o", - Scircumflex="S",scircumflex="s", - Ucircumflex="U",ucircumflex="u", - Wcircumflex="W",wcircumflex="w", - Ycircumflex="Y",ycircumflex="y", - Agrave="A",agrave="a", - Egrave="E",egrave="e", - Igrave="I",igrave="i", - Ograve="O",ograve="o", - Ugrave="U",ugrave="u", - Ygrave="Y",ygrave="y", - Atilde="A",atilde="a", - Itilde="I",itilde="i", - Otilde="O",otilde="o", - Utilde="U",utilde="u", - Ntilde="N",ntilde="n", - Adiaeresis="A",adiaeresis="a",Adieresis="A",adieresis="a", - Ediaeresis="E",ediaeresis="e",Edieresis="E",edieresis="e", - Idiaeresis="I",idiaeresis="i",Idieresis="I",idieresis="i", - Odiaeresis="O",odiaeresis="o",Odieresis="O",odieresis="o", - Udiaeresis="U",udiaeresis="u",Udieresis="U",udieresis="u", - Ydiaeresis="Y",ydiaeresis="y",Ydieresis="Y",ydieresis="y", - Aacute="A",aacute="a", - Cacute="C",cacute="c", - Eacute="E",eacute="e", - Iacute="I",iacute="i", - Lacute="L",lacute="l", - Nacute="N",nacute="n", - Oacute="O",oacute="o", - Racute="R",racute="r", - Sacute="S",sacute="s", - Uacute="U",uacute="u", - Yacute="Y",yacute="y", - Zacute="Z",zacute="z", - Dstroke="D",dstroke="d", - Hstroke="H",hstroke="h", - Tstroke="T",tstroke="t", - Cdotaccent="C",cdotaccent="c", - Edotaccent="E",edotaccent="e", - Gdotaccent="G",gdotaccent="g", - Idotaccent="I",idotaccent="i", - Zdotaccent="Z",zdotaccent="z", - Amacron="A",amacron="a", - Emacron="E",emacron="e", - Imacron="I",imacron="i", - Omacron="O",omacron="o", - Umacron="U",umacron="u", - Ccedilla="C",ccedilla="c", - Kcedilla="K",kcedilla="k", - Lcedilla="L",lcedilla="l", - Ncedilla="N",ncedilla="n", - Rcedilla="R",rcedilla="r", - Scedilla="S",scedilla="s", - Tcedilla="T",tcedilla="t", - Ohungarumlaut="O",ohungarumlaut="o", - Uhungarumlaut="U",uhungarumlaut="u", - Aogonek="A",aogonek="a", - Eogonek="E",eogonek="e", - Iogonek="I",iogonek="i", - Uogonek="U",uogonek="u", - Aring="A",aring="a", - Uring="U",uring="u", - Abreve="A",abreve="a", - Ebreve="E",ebreve="e", - Gbreve="G",gbreve="g", - Ibreve="I",ibreve="i", - Obreve="O",obreve="o", - Ubreve="U",ubreve="u", - Ccaron="C",ccaron="c", - Dcaron="D",dcaron="d", - Ecaron="E",ecaron="e", - Lcaron="L",lcaron="l", - Ncaron="N",ncaron="n", - Rcaron="R",rcaron="r", - Scaron="S",scaron="s", - Tcaron="T",tcaron="t", - Zcaron="Z",zcaron="z", - dotlessI="I",dotlessi="i", - dotlessJ="J",dotlessj="j", - AEligature="AE",aeligature="ae",AE="AE",ae="ae", - OEligature="OE",oeligature="oe",OE="OE",oe="oe", - IJligature="IJ",ijligature="ij",IJ="IJ",ij="ij", - Lstroke="L",lstroke="l",Lslash="L",lslash="l", - Ostroke="O",ostroke="o",Oslash="O",oslash="o", - Ssharp="SS",ssharp="ss", - Aumlaut="A",aumlaut="a", - Eumlaut="E",eumlaut="e", - Iumlaut="I",iumlaut="i", - Oumlaut="O",oumlaut="o", - Uumlaut="U",uumlaut="u", - } -} - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-afk”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-tfm” f0eb5e2a8068b17ad401bb7efdba1630] --- - -if not modules then modules={} end modules ['luatex-fonts-tfm']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next,type=next,type -local match,format=string.match,string.format -local concat,sortedhash=table.concat,table.sortedhash -local idiv=number.idiv -local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) -local trace_features=false trackers.register("tfm.features",function(v) trace_features=v end) -local report_defining=logs.reporter("fonts","defining") -local report_tfm=logs.reporter("fonts","tfm loading") -local findbinfile=resolvers.findbinfile -local setmetatableindex=table.setmetatableindex -local fonts=fonts -local handlers=fonts.handlers -local helpers=fonts.helpers -local readers=fonts.readers -local constructors=fonts.constructors -local encodings=fonts.encodings -local tfm=constructors.handlers.tfm -tfm.version=1.000 -tfm.maxnestingdepth=5 -tfm.maxnestingsize=65536*1024 -local otf=fonts.handlers.otf -local otfenhancers=otf.enhancers -local tfmfeatures=constructors.features.tfm -local registertfmfeature=tfmfeatures.register -local tfmenhancers=constructors.enhancers.tfm -local registertfmenhancer=tfmenhancers.register -local charcommand=helpers.commands.char -constructors.resolvevirtualtoo=false -fonts.formats.tfm="type1" -fonts.formats.ofm="type1" -function tfm.setfeatures(tfmdata,features) - local okay=constructors.initializefeatures("tfm",tfmdata,features,trace_features,report_tfm) - if okay then - return constructors.collectprocessors("tfm",tfmdata,features,trace_features,report_tfm) - else - return {} - end -end -local depth={} -local loadtfm=font.read_tfm -local loadvf=font.read_vf -local function read_from_tfm(specification) - local filename=specification.filename - local size=specification.size - depth[filename]=(depth[filename] or 0)+1 - if trace_defining then - report_defining("loading tfm file %a at size %s",filename,size) - end - local tfmdata=loadtfm(filename,size) - if tfmdata then - local features=specification.features and specification.features.normal or {} - local features=constructors.checkedfeatures("tfm",features) - specification.features.normal=features - local newtfmdata=(depth[filename]==1) and tfm.reencode(tfmdata,specification) - if newtfmdata then - tfmdata=newtfmdata - end - local resources=tfmdata.resources or {} - local properties=tfmdata.properties or {} - local parameters=tfmdata.parameters or {} - local shared=tfmdata.shared or {} - shared.features=features - shared.resources=resources - properties.name=tfmdata.name - properties.fontname=tfmdata.fontname - properties.psname=tfmdata.psname - properties.fullname=tfmdata.fullname - properties.filename=specification.filename - properties.format=tfmdata.format or fonts.formats.tfm - properties.usedbitmap=tfmdata.usedbitmap - tfmdata.properties=properties - tfmdata.resources=resources - tfmdata.parameters=parameters - tfmdata.shared=shared - shared.rawdata={ resources=resources } - shared.features=features - if newtfmdata then - if not resources.marks then - resources.marks={} - end - if not resources.sequences then - resources.sequences={} - end - if not resources.features then - resources.features={ - gsub={}, - gpos={}, - } - end - if not tfmdata.changed then - tfmdata.changed={} - end - if not tfmdata.descriptions then - tfmdata.descriptions=tfmdata.characters - end - otf.readers.addunicodetable(tfmdata) - tfmenhancers.apply(tfmdata,filename) - constructors.applymanipulators("tfm",tfmdata,features,trace_features,report_tfm) - otf.readers.unifymissing(tfmdata) - fonts.mappings.addtounicode(tfmdata,filename) - tfmdata.tounicode=1 - local tounicode=fonts.mappings.tounicode - for unicode,v in next,tfmdata.characters do - local u=v.unicode - if u then - v.tounicode=tounicode(u) - end - end - if tfmdata.usedbitmap then - tfm.addtounicode(tfmdata) - end - end - shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil - if size<0 then - size=idiv(65536*-size,100) - end - parameters.factor=1 - parameters.units=1000 - parameters.size=size - parameters.slant=parameters.slant or parameters[1] or 0 - parameters.space=parameters.space or parameters[2] or 0 - parameters.space_stretch=parameters.space_stretch or parameters[3] or 0 - parameters.space_shrink=parameters.space_shrink or parameters[4] or 0 - parameters.x_height=parameters.x_height or parameters[5] or 0 - parameters.quad=parameters.quad or parameters[6] or 0 - parameters.extra_space=parameters.extra_space or parameters[7] or 0 - constructors.enhanceparameters(parameters) - properties.private=properties.private or tfmdata.private or privateoffset - if newtfmdata then - elseif constructors.resolvevirtualtoo then - fonts.loggers.register(tfmdata,file.suffix(filename),specification) - local vfname=findbinfile(specification.name,'ovf') - if vfname and vfname~="" then - local vfdata=loadvf(vfname,size) - if vfdata then - local chars=tfmdata.characters - for k,v in next,vfdata.characters do - chars[k].commands=v.commands - end - properties.virtualized=true - tfmdata.fonts=vfdata.fonts - tfmdata.type="virtual" - local fontlist=vfdata.fonts - local name=file.nameonly(filename) - for i=1,#fontlist do - local n=fontlist[i].name - local s=fontlist[i].size - local d=depth[filename] - s=constructors.scaled(s,vfdata.designsize) - if d>tfm.maxnestingdepth then - report_defining("too deeply nested virtual font %a with size %a, max nesting depth %s",n,s,tfm.maxnestingdepth) - fontlist[i]={ id=0 } - elseif (d>1) and (s>tfm.maxnestingsize) then - report_defining("virtual font %a exceeds size %s",n,s) - fontlist[i]={ id=0 } - else - local t,id=constructors.readanddefine(n,s) - fontlist[i]={ id=id } - end - end - end - end - end - properties.haskerns=true - properties.hasligatures=true - properties.hasitalics=true - resources.unicodes={} - resources.lookuptags={} - depth[filename]=depth[filename]-1 - return tfmdata - else - depth[filename]=depth[filename]-1 - end -end -local function check_tfm(specification,fullname) - local foundname=findbinfile(fullname,'tfm') or "" - if foundname=="" then - foundname=findbinfile(fullname,'ofm') or "" - end - if foundname=="" then - foundname=fonts.names.getfilename(fullname,"tfm") or "" - end - if foundname~="" then - specification.filename=foundname - specification.format="ofm" - return read_from_tfm(specification) - elseif trace_defining then - report_defining("loading tfm with name %a fails",specification.name) - end -end -readers.check_tfm=check_tfm -function readers.tfm(specification) - local fullname=specification.filename or "" - if fullname=="" then - local forced=specification.forced or "" - if forced~="" then - fullname=specification.name.."."..forced - else - fullname=specification.name - end - end - return check_tfm(specification,fullname) -end -readers.ofm=readers.tfm -do - local outfiles={} - local tfmcache=table.setmetatableindex(function(t,tfmdata) - local id=font.define(tfmdata) - t[tfmdata]=id - return id - end) - local encdone=table.setmetatableindex("table") - function tfm.reencode(tfmdata,specification) - local features=specification.features - if not features then - return - end - local features=features.normal - if not features then - return - end - local tfmfile=file.basename(tfmdata.name) - local encfile=features.reencode - local pfbfile=features.pfbfile - local bitmap=features.bitmap - if not encfile then - return - end - local pfbfile=outfiles[tfmfile] - if pfbfile==nil then - if bitmap then - pfbfile=false - elseif type(pfbfile)~="string" then - pfbfile=tfmfile - end - if type(pfbfile)=="string" then - pfbfile=file.addsuffix(pfbfile,"pfb") - report_tfm("using type1 shapes from %a for %a",pfbfile,tfmfile) - else - report_tfm("using bitmap shapes for %a",tfmfile) - pfbfile=false - end - outfiles[tfmfile]=pfbfile - end - local encoding=false - local vector=false - if type(pfbfile)=="string" then - local pfb=constructors.handlers.pfb - if pfb and pfb.loadvector then - local v,e=pfb.loadvector(pfbfile) - if v then - vector=v - end - if e then - encoding=e - end - end - end - if type(encfile)=="string" and encfile~="auto" then - encoding=fonts.encodings.load(file.addsuffix(encfile,"enc")) - if encoding then - encoding=encoding.vector - end - end - if not encoding then - report_tfm("bad encoding for %a, quitting",tfmfile) - return - end - local unicoding=fonts.encodings.agl and fonts.encodings.agl.unicodes - local virtualid=tfmcache[tfmdata] - local tfmdata=table.copy(tfmdata) - local characters={} - local originals=tfmdata.characters - local indices={} - local parentfont={ "font",1 } - local private=tfmdata.privateoffset or constructors.privateoffset - local reported=encdone[tfmfile][encfile] - local backmap=vector and table.swapped(vector) - local done={} - for index,name in sortedhash(encoding) do - local unicode=unicoding[name] - local original=originals[index] - if original then - if unicode then - original.unicode=unicode - else - unicode=private - private=private+1 - if not reported then - report_tfm("glyph %a in font %a with encoding %a gets unicode %U",name,tfmfile,encfile,unicode) - end - end - characters[unicode]=original - indices[index]=unicode - original.name=name - if backmap then - original.index=backmap[name] - else - original.commands={ parentfont,charcommand[index] } - original.oindex=index - end - done[name]=true - elseif not done[name] then - report_tfm("bad index %a in font %a with name %a",index,tfmfile,name) - end - end - encdone[tfmfile][encfile]=true - for k,v in next,characters do - local kerns=v.kerns - if kerns then - local t={} - for k,v in next,kerns do - local i=indices[k] - if i then - t[i]=v - end - end - v.kerns=next(t) and t or nil - end - local ligatures=v.ligatures - if ligatures then - local t={} - for k,v in next,ligatures do - local i=indices[k] - if i then - t[i]=v - v.char=indices[v.char] - end - end - v.ligatures=next(t) and t or nil - end - end - tfmdata.fonts={ { id=virtualid } } - tfmdata.characters=characters - tfmdata.fullname=tfmdata.fullname or tfmdata.name - tfmdata.psname=file.nameonly(pfbfile or tfmdata.name) - tfmdata.filename=pfbfile - tfmdata.encodingbytes=2 - tfmdata.format="type1" - tfmdata.tounicode=1 - tfmdata.embedding="subset" - tfmdata.usedbitmap=bitmap and virtualid - tfmdata.private=private - return tfmdata - end -end -do - local template=[[ -/CIDInit /ProcSet findresource begin - 12 dict begin - begincmap - /CIDSystemInfo << /Registry (TeX) /Ordering (bitmap-%s) /Supplement 0 >> def - /CMapName /TeX-bitmap-%s def - /CMapType 2 def - 1 begincodespacerange - <00> - endcodespacerange - %s beginbfchar -%s - endbfchar - endcmap -CMapName currentdict /CMap defineresource pop end -end -end -]] - local flushstreamobject=lpdf and lpdf.flushstreamobject - local setfontattributes=lpdf and lpdf.setfontattributes - if not flushstreamobject then - flushstreamobject=function(data) - return pdf.obj { immediate=true,type="stream",string=data } - end - end - if not setfontattributes then - setfontattributes=function(id,data) - return pdf.setfontattributes(id,data) - end - end - function tfm.addtounicode(tfmdata) - local id=tfmdata.usedbitmap - local map={} - local char={} - for k,v in next,tfmdata.characters do - local index=v.oindex - local tounicode=v.tounicode - if index and tounicode then - map[index]=tounicode - end - end - for k,v in sortedhash(map) do - char[#char+1]=format("<%02X> <%s>",k,v) - end - char=concat(char,"\n") - local stream=format(template,id,id,#char,char) - local reference=flushstreamobject(stream,nil,true) - setfontattributes(id,format("/ToUnicode %i 0 R",reference)) - end -end -do - local everywhere={ ["*"]={ ["*"]=true } } - local noflags={ false,false,false,false } - local function enhance_normalize_features(data) - local ligatures=setmetatableindex("table") - local kerns=setmetatableindex("table") - local characters=data.characters - for u,c in next,characters do - local l=c.ligatures - local k=c.kerns - if l then - ligatures[u]=l - for u,v in next,l do - l[u]={ ligature=v.char } - end - c.ligatures=nil - end - if k then - kerns[u]=k - for u,v in next,k do - k[u]=v - end - c.kerns=nil - end - end - for u,l in next,ligatures do - for k,v in next,l do - local vl=v.ligature - local dl=ligatures[vl] - if dl then - for kk,vv in next,dl do - v[kk]=vv - end - end - end - end - local features={ - gpos={}, - gsub={}, - } - local sequences={ - } - if next(ligatures) then - features.gsub.liga=everywhere - data.properties.hasligatures=true - sequences[#sequences+1]={ - features={ - liga=everywhere, - }, - flags=noflags, - name="s_s_0", - nofsteps=1, - order={ "liga" }, - type="gsub_ligature", - steps={ - { - coverage=ligatures, - }, - }, - } - end - if next(kerns) then - features.gpos.kern=everywhere - data.properties.haskerns=true - sequences[#sequences+1]={ - features={ - kern=everywhere, - }, - flags=noflags, - name="p_s_0", - nofsteps=1, - order={ "kern" }, - type="gpos_pair", - steps={ - { - format="kern", - coverage=kerns, - }, - }, - } - end - data.resources.features=features - data.resources.sequences=sequences - data.shared.resources=data.shared.resources or resources - end - registertfmenhancer("normalize features",enhance_normalize_features) - registertfmenhancer("check extra features",otfenhancers.enhance) -end -registertfmfeature { - name="mode", - description="mode", - initializers={ - base=otf.modeinitializer, - node=otf.modeinitializer, - } -} -registertfmfeature { - name="features", - description="features", - default=true, - initializers={ - base=otf.basemodeinitializer, - node=otf.nodemodeinitializer, - }, - processors={ - node=otf.featuresprocessor, - } -} - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-tfm”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-lua” 1fbfdf7b689b2bdfd0e3bb9bf74ce136] --- - -if not modules then modules={} end modules ['font-lua']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) -local report_lua=logs.reporter("fonts","lua loading") -local fonts=fonts -local readers=fonts.readers -fonts.formats.lua="lua" -local function check_lua(specification,fullname) - local fullname=resolvers.findfile(fullname) or "" - if fullname~="" then - local loader=loadfile(fullname) - loader=loader and loader() - return loader and loader(specification) - end -end -readers.check_lua=check_lua -function readers.lua(specification) - local original=specification.specification - if trace_defining then - report_lua("using lua reader for %a",original) - end - local fullname=specification.filename or "" - if fullname=="" then - local forced=specification.forced or "" - if forced~="" then - fullname=specification.name.."."..forced - else - fullname=specification.name - end - end - return check_lua(specification,fullname) -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-lua”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-def” b9d908c2338b7dc443ce9d1e9fcb7139] --- - -if not modules then modules={} end modules ['font-def']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local lower,gsub=string.lower,string.gsub -local tostring,next=tostring,next -local lpegmatch=lpeg.match -local suffixonly,removesuffix,basename=file.suffix,file.removesuffix,file.basename -local formatters=string.formatters -local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys -local allocate=utilities.storage.allocate -local trace_defining=false trackers .register("fonts.defining",function(v) trace_defining=v end) -local directive_embedall=false directives.register("fonts.embedall",function(v) directive_embedall=v end) -trackers.register("fonts.loading","fonts.defining","otf.loading","afm.loading","tfm.loading") -local report_defining=logs.reporter("fonts","defining") -local fonts=fonts -local fontdata=fonts.hashes.identifiers -local readers=fonts.readers -local definers=fonts.definers -local specifiers=fonts.specifiers -local constructors=fonts.constructors -local fontgoodies=fonts.goodies -readers.sequence=allocate { 'otf','ttf','afm','tfm','lua' } -local variants=allocate() -specifiers.variants=variants -definers.methods=definers.methods or {} -local internalized=allocate() -local loadedfonts=constructors.loadedfonts -local designsizes=constructors.designsizes -local resolvefile=fontgoodies and fontgoodies.filenames and fontgoodies.filenames.resolve or function(s) return s end -local function makespecification(specification,lookup,name,sub,method,detail,size) - size=size or 655360 - if not lookup or lookup=="" then - lookup=definers.defaultlookup - end - if trace_defining then - report_defining("specification %a, lookup %a, name %a, sub %a, method %a, detail %a", - specification,lookup,name,sub,method,detail) - end - local t={ - lookup=lookup, - specification=specification, - size=size, - name=name, - sub=sub, - method=method, - detail=detail, - resolved="", - forced="", - features={}, - } - return t -end -definers.makespecification=makespecification -if context then - local splitter,splitspecifiers=nil,"" - local P,C,S,Cc,Cs=lpeg.P,lpeg.C,lpeg.S,lpeg.Cc,lpeg.Cs - local left=P("(") - local right=P(")") - local colon=P(":") - local space=P(" ") - local lbrace=P("{") - local rbrace=P("}") - definers.defaultlookup="file" - local prefixpattern=P(false) - local function addspecifier(symbol) - splitspecifiers=splitspecifiers..symbol - local method=S(splitspecifiers) - local lookup=C(prefixpattern)*colon - local sub=left*C(P(1-left-right-method)^1)*right - local specification=C(method)*C(P(1)^1) - local name=Cs((lbrace/"")*(1-rbrace)^1*(rbrace/"")+(1-sub-specification)^1) - splitter=P((lookup+Cc(""))*name*(sub+Cc(""))*(specification+Cc(""))) - end - local function addlookup(str) - prefixpattern=prefixpattern+P(str) - end - definers.addlookup=addlookup - addlookup("file") - addlookup("name") - addlookup("spec") - local function getspecification(str) - return lpegmatch(splitter,str or "") - end - definers.getspecification=getspecification - function definers.registersplit(symbol,action,verbosename) - addspecifier(symbol) - variants[symbol]=action - if verbosename then - variants[verbosename]=action - end - end - function definers.analyze(specification,size) - local lookup,name,sub,method,detail=getspecification(specification or "") - return makespecification(specification,lookup,name,sub,method,detail,size) - end -end -definers.resolvers=definers.resolvers or {} -local resolvers=definers.resolvers -function resolvers.file(specification) - local name=resolvefile(specification.name) - local suffix=lower(suffixonly(name)) - if fonts.formats[suffix] then - specification.forced=suffix - specification.forcedname=name - specification.name=removesuffix(name) - else - specification.name=name - end -end -function resolvers.name(specification) - local resolve=fonts.names.resolve - if resolve then - local resolved,sub,subindex,instance=resolve(specification.name,specification.sub,specification) - if resolved then - specification.resolved=resolved - specification.sub=sub - specification.subindex=subindex - if instance then - specification.instance=instance - local features=specification.features - if not features then - features={} - specification.features=features - end - local normal=features.normal - if not normal then - normal={} - features.normal=normal - end - normal.instance=instance - end - local suffix=lower(suffixonly(resolved)) - if fonts.formats[suffix] then - specification.forced=suffix - specification.forcedname=resolved - specification.name=removesuffix(resolved) - else - specification.name=resolved - end - end - else - resolvers.file(specification) - end -end -function resolvers.spec(specification) - local resolvespec=fonts.names.resolvespec - if resolvespec then - local resolved,sub,subindex=resolvespec(specification.name,specification.sub,specification) - if resolved then - specification.resolved=resolved - specification.sub=sub - specification.subindex=subindex - specification.forced=lower(suffixonly(resolved)) - specification.forcedname=resolved - specification.name=removesuffix(resolved) - end - else - resolvers.name(specification) - end -end -function definers.resolve(specification) - if not specification.resolved or specification.resolved=="" then - local r=resolvers[specification.lookup] - if r then - r(specification) - end - end - if specification.forced=="" then - specification.forced=nil - specification.forcedname=nil - end - specification.hash=lower(specification.name..' @ '..constructors.hashfeatures(specification)) - if specification.sub and specification.sub~="" then - specification.hash=specification.sub..' @ '..specification.hash - end - return specification -end -function definers.applypostprocessors(tfmdata) - local postprocessors=tfmdata.postprocessors - if postprocessors then - local properties=tfmdata.properties - for i=1,#postprocessors do - local extrahash=postprocessors[i](tfmdata) - if type(extrahash)=="string" and extrahash~="" then - extrahash=gsub(lower(extrahash),"[^a-z]","-") - properties.fullname=formatters["%s-%s"](properties.fullname,extrahash) - end - end - end - return tfmdata -end -local function checkembedding(tfmdata) - local properties=tfmdata.properties - local embedding - if directive_embedall then - embedding="full" - elseif properties and properties.filename and constructors.dontembed[properties.filename] then - embedding="no" - else - embedding="subset" - end - if properties then - properties.embedding=embedding - else - tfmdata.properties={ embedding=embedding } - end - tfmdata.embedding=embedding -end -local function checkfeatures(tfmdata) - local resources=tfmdata.resources - local shared=tfmdata.shared - if resources and shared then - local features=resources.features - local usedfeatures=shared.features - if features and usedfeatures then - local usedlanguage=usedfeatures.language or "dflt" - local usedscript=usedfeatures.script or "dflt" - local function check(what) - if what then - local foundlanguages={} - for feature,scripts in next,what do - if usedscript=="auto" or scripts["*"] then - elseif not scripts[usedscript] then - else - for script,languages in next,scripts do - if languages["*"] then - elseif context and not languages[usedlanguage] then - report_defining("font %!font:name!, feature %a, script %a, no language %a", - tfmdata,feature,script,usedlanguage) - end - end - end - for script,languages in next,scripts do - for language in next,languages do - foundlanguages[language]=true - end - end - end - if false then - foundlanguages["*"]=nil - foundlanguages=sortedkeys(foundlanguages) - for feature,scripts in sortedhash(what) do - for script,languages in next,scripts do - if not languages["*"] then - for i=1,#foundlanguages do - local language=foundlanguages[i] - if context and not languages[language] then - report_defining("font %!font:name!, feature %a, script %a, no language %a", - tfmdata,feature,script,language) - end - end - end - end - end - end - end - end - check(features.gsub) - check(features.gpos) - end - end -end -function definers.loadfont(specification) - local hash=constructors.hashinstance(specification) - local tfmdata=loadedfonts[hash] - if not tfmdata then - local forced=specification.forced or "" - if forced~="" then - local reader=readers[lower(forced)] - tfmdata=reader and reader(specification) - if not tfmdata then - report_defining("forced type %a of %a not found",forced,specification.name) - end - else - local sequence=readers.sequence - for s=1,#sequence do - local reader=sequence[s] - if readers[reader] then - if trace_defining then - report_defining("trying (reader sequence driven) type %a for %a with file %a",reader,specification.name,specification.filename) - end - tfmdata=readers[reader](specification) - if tfmdata then - break - else - specification.filename=nil - end - end - end - end - if tfmdata then - tfmdata=definers.applypostprocessors(tfmdata) - checkembedding(tfmdata) - loadedfonts[hash]=tfmdata - designsizes[specification.hash]=tfmdata.parameters.designsize - checkfeatures(tfmdata) - end - end - if not tfmdata then - report_defining("font with asked name %a is not found using lookup %a",specification.name,specification.lookup) - end - return tfmdata -end -function constructors.readanddefine(name,size) - local specification=definers.analyze(name,size) - local method=specification.method - if method and variants[method] then - specification=variants[method](specification) - end - specification=definers.resolve(specification) - local hash=constructors.hashinstance(specification) - local id=definers.registered(hash) - if not id then - local tfmdata=definers.loadfont(specification) - if tfmdata then - tfmdata.properties.hash=hash - id=font.define(tfmdata) - definers.register(tfmdata,id) - else - id=0 - end - end - return fontdata[id],id -end -function definers.registered(hash) - local id=internalized[hash] - return id,id and fontdata[id] -end -function definers.register(tfmdata,id) - if tfmdata and id then - local hash=tfmdata.properties.hash - if not hash then - report_defining("registering font, id %a, name %a, invalid hash",id,tfmdata.properties.filename or "?") - elseif not internalized[hash] then - internalized[hash]=id - if trace_defining then - report_defining("registering font, id %s, hash %a",id,hash) - end - fontdata[id]=tfmdata - end - end -end -function definers.read(specification,size,id) - statistics.starttiming(fonts) - if type(specification)=="string" then - specification=definers.analyze(specification,size) - end - local method=specification.method - if method and variants[method] then - specification=variants[method](specification) - end - specification=definers.resolve(specification) - local hash=constructors.hashinstance(specification) - local tfmdata=definers.registered(hash) - if tfmdata then - if trace_defining then - report_defining("already hashed: %s",hash) - end - else - tfmdata=definers.loadfont(specification) - if tfmdata then - tfmdata.original=specification.specification - if trace_defining then - report_defining("loaded and hashed: %s",hash) - end - tfmdata.properties.hash=hash - if id then - definers.register(tfmdata,id) - end - else - if trace_defining then - report_defining("not loaded and hashed: %s",hash) - end - end - end - if not tfmdata then - report_defining("unknown font %a, loading aborted",specification.name) - elseif trace_defining and type(tfmdata)=="table" then - local properties=tfmdata.properties or {} - local parameters=tfmdata.parameters or {} - report_defining("using %a font with id %a, name %a, size %a, bytes %a, encoding %a, fullname %a, filename %a", - properties.format or "unknown",id or "-",properties.name,parameters.size,properties.encodingbytes, - properties.encodingname,properties.fullname,basename(properties.filename)) - end - statistics.stoptiming(fonts) - return tfmdata -end -function font.getfont(id) - return fontdata[id] -end -if not context then - callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)") -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-def”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-shp” 5ff497c993112d4fef4c148348d964eb] --- - -if not modules then modules={} end modules ['font-shp']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local tonumber,next=tonumber,next -local concat=table.concat -local formatters,lower=string.formatters,string.lower -local otf=fonts.handlers.otf -local afm=fonts.handlers.afm -local pfb=fonts.handlers.pfb -local hashes=fonts.hashes -local identifiers=hashes.identifiers -local version=0.009 -local shapescache=containers.define("fonts","shapes",version,true) -local streamscache=containers.define("fonts","streams",version,true) -local compact_streams=false -directives.register("fonts.streams.compact",function(v) compact_streams=v end) -local function packoutlines(data,makesequence) - local subfonts=data.subfonts - if subfonts then - for i=1,#subfonts do - packoutlines(subfonts[i],makesequence) - end - return - end - local common=data.segments - if common then - return - end - local glyphs=data.glyphs - if not glyphs then - return - end - if makesequence then - for index=0,#glyphs do - local glyph=glyphs[index] - if glyph then - local segments=glyph.segments - if segments then - local sequence={} - local nofsequence=0 - for i=1,#segments do - local segment=segments[i] - local nofsegment=#segment - nofsequence=nofsequence+1 - sequence[nofsequence]=segment[nofsegment] - for i=1,nofsegment-1 do - nofsequence=nofsequence+1 - sequence[nofsequence]=segment[i] - end - end - glyph.sequence=sequence - glyph.segments=nil - end - end - end - else - local hash={} - local common={} - local reverse={} - local last=0 - for index=0,#glyphs do - local glyph=glyphs[index] - if glyph then - local segments=glyph.segments - if segments then - for i=1,#segments do - local h=concat(segments[i]," ") - hash[h]=(hash[h] or 0)+1 - end - end - end - end - for index=0,#glyphs do - local glyph=glyphs[index] - if glyph then - local segments=glyph.segments - if segments then - for i=1,#segments do - local segment=segments[i] - local h=concat(segment," ") - if hash[h]>1 then - local idx=reverse[h] - if not idx then - last=last+1 - reverse[h]=last - common[last]=segment - idx=last - end - segments[i]=idx - end - end - end - end - end - if last>0 then - data.segments=common - end - end -end -local function unpackoutlines(data) - local subfonts=data.subfonts - if subfonts then - for i=1,#subfonts do - unpackoutlines(subfonts[i]) - end - return - end - local common=data.segments - if not common then - return - end - local glyphs=data.glyphs - if not glyphs then - return - end - for index=0,#glyphs do - local glyph=glyphs[index] - if glyph then - local segments=glyph.segments - if segments then - for i=1,#segments do - local c=common[segments[i]] - if c then - segments[i]=c - end - end - end - end - end - data.segments=nil -end -local readers=otf.readers -local cleanname=otf.readers.helpers.cleanname -local function makehash(filename,sub,instance) - local name=cleanname(file.basename(filename)) - if instance then - return formatters["%s-%s-%s"](name,sub or 0,cleanname(instance)) - else - return formatters["%s-%s"] (name,sub or 0) - end -end -local function loadoutlines(cache,filename,sub,instance) - local base=file.basename(filename) - local name=file.removesuffix(base) - local kind=file.suffix(filename) - local attr=lfs.attributes(filename) - local size=attr and attr.size or 0 - local time=attr and attr.modification or 0 - local sub=tonumber(sub) - if size>0 and (kind=="otf" or kind=="ttf" or kind=="tcc") then - local hash=makehash(filename,sub,instance) - data=containers.read(cache,hash) - if not data or data.time~=time or data.size~=size then - data=otf.readers.loadshapes(filename,sub,instance) - if data then - data.size=size - data.format=data.format or (kind=="otf" and "opentype") or "truetype" - data.time=time - packoutlines(data) - containers.write(cache,hash,data) - data=containers.read(cache,hash) - end - end - unpackoutlines(data) - elseif size>0 and (kind=="pfb") then - local hash=containers.cleanname(base) - data=containers.read(cache,hash) - if not data or data.time~=time or data.size~=size then - data=afm.readers.loadshapes(filename) - if data then - data.size=size - data.format="type1" - data.time=time - packoutlines(data) - containers.write(cache,hash,data) - data=containers.read(cache,hash) - end - end - unpackoutlines(data) - else - data={ - filename=filename, - size=0, - time=time, - format="unknown", - units=1000, - glyphs={} - } - end - return data -end -local function cachethem(cache,hash,data) - containers.write(cache,hash,data,compact_streams) - return containers.read(cache,hash) -end -local function loadstreams(cache,filename,sub,instance) - local base=file.basename(filename) - local name=file.removesuffix(base) - local kind=lower(file.suffix(filename)) - local attr=lfs.attributes(filename) - local size=attr and attr.size or 0 - local time=attr and attr.modification or 0 - local sub=tonumber(sub) - if size>0 and (kind=="otf" or kind=="ttf" or kind=="ttc") then - local hash=makehash(filename,sub,instance) - data=containers.read(cache,hash) - if not data or data.time~=time or data.size~=size then - data=otf.readers.loadshapes(filename,sub,instance,true) - if data then - local glyphs=data.glyphs - local streams={} - if glyphs then - for i=0,#glyphs do - local glyph=glyphs[i] - if glyph then - streams[i]=glyph.stream or "" - else - streams[i]="" - end - end - end - data.streams=streams - data.glyphs=nil - data.size=size - data.format=data.format or (kind=="otf" and "opentype") or "truetype" - data.time=time - data=cachethem(cache,hash,data) - end - end - elseif size>0 and (kind=="pfb") then - local hash=makehash(filename,sub,instance) - data=containers.read(cache,hash) - if not data or data.time~=time or data.size~=size then - local names,encoding,streams,metadata=pfb.loadvector(filename,false,true) - if streams then - local fontbbox=metadata.fontbbox or { 0,0,0,0 } - for i=0,#streams do - streams[i]=streams[i].stream or "\14" - end - data={ - filename=filename, - size=size, - time=time, - format="type1", - streams=streams, - fontheader={ - fontversion=metadata.version, - units=1000, - xmin=fontbbox[1], - ymin=fontbbox[2], - xmax=fontbbox[3], - ymax=fontbbox[4], - }, - horizontalheader={ - ascender=0, - descender=0, - }, - maximumprofile={ - nofglyphs=#streams+1, - }, - names={ - copyright=metadata.copyright, - family=metadata.familyname, - fullname=metadata.fullname, - fontname=metadata.fontname, - subfamily=metadata.subfamilyname, - trademark=metadata.trademark, - notice=metadata.notice, - version=metadata.version, - }, - cffinfo={ - familyname=metadata.familyname, - fullname=metadata.fullname, - italicangle=metadata.italicangle, - monospaced=metadata.isfixedpitch and true or false, - underlineposition=metadata.underlineposition, - underlinethickness=metadata.underlinethickness, - weight=metadata.weight, - }, - } - data=cachethem(cache,hash,data) - end - end - else - data={ - filename=filename, - size=0, - time=time, - format="unknown", - streams={} - } - end - return data -end -local loadedshapes={} -local loadedstreams={} -local function loadoutlinedata(fontdata,streams) - local properties=fontdata.properties - local filename=properties.filename - local subindex=fontdata.subindex - local instance=properties.instance - local hash=makehash(filename,subindex,instance) - local loaded=loadedshapes[hash] - if not loaded then - loaded=loadoutlines(shapescache,filename,subindex,instance) - loadedshapes[hash]=loaded - end - return loaded -end -hashes.shapes=table.setmetatableindex(function(t,k) - local f=identifiers[k] - if f then - return loadoutlinedata(f) - end -end) -local function getstreamhash(fontid) - local fontdata=identifiers[fontid] - if fontdata then - local properties=fontdata.properties - return makehash(properties.filename,properties.subfont,properties.instance) - end -end -local function loadstreamdata(fontdata) - local properties=fontdata.properties - local shared=fontdata.shared - local rawdata=shared and shared.rawdata - local metadata=rawdata and rawdata.metadata - local filename=properties.filename - local subindex=metadata and metadata.subfontindex - local instance=properties.instance - local hash=makehash(filename,subindex,instance) - local loaded=loadedstreams[hash] - if not loaded then - loaded=loadstreams(streamscache,filename,subindex,instance) - loadedstreams[hash]=loaded - end - return loaded -end -hashes.streams=table.setmetatableindex(function(t,k) - local f=identifiers[k] - if f then - return loadstreamdata(f) - end -end) -otf.loadoutlinedata=loadoutlinedata -otf.loadstreamdata=loadstreamdata -otf.loadshapes=loadshapes -otf.getstreamhash=getstreamhash -local streams=fonts.hashes.streams -callback.register("glyph_stream_provider",function(id,index,mode) - if id>0 then - local streams=streams[id].streams - if streams then - return streams[index] or "" - end - end - return "" -end) - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-shp”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-def” f435e0875f203f343157baeff876ec9c] --- - -if not modules then modules={} end modules ['luatex-fonts-def']={ - version=1.001, - comment="companion to luatex-*.tex", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -if context then - os.exit() -end -local fonts=fonts -fonts.constructors.namemode="specification" -function fonts.definers.getspecification(str) - return "",str,"",":",str -end -local list={} -local function issome () list.lookup='name' end -local function isfile () list.lookup='file' end -local function isname () list.lookup='name' end -local function thename(s) list.name=s end -local function issub (v) list.sub=v end -local function iscrap (s) list.crap=string.lower(s) end -local function iskey (k,v) list[k]=v end -local function istrue (s) list[s]=true end -local function isfalse(s) list[s]=false end -local P,S,R,C,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs -local spaces=P(" ")^0 -local namespec=Cs((P("{")/"")*(1-S("}"))^0*(P("}")/"")+(1-S("/:("))^0) -local crapspec=spaces*P("/")*(((1-P(":"))^0)/iscrap)*spaces -local filename_1=P("file:")/isfile*(namespec/thename) -local filename_2=P("[")*P(true)/isfile*(((1-P("]"))^0)/thename)*P("]") -local fontname_1=P("name:")/isname*(namespec/thename) -local fontname_2=P(true)/issome*(namespec/thename) -local sometext=R("az","AZ","09")^1 -local somekey=R("az","AZ","09")^1 -local somevalue=(P("{")/"")*(1-P("}"))^0*(P("}")/"")+(1-S(";"))^1 -local truevalue=P("+")*spaces*(sometext/istrue) -local falsevalue=P("-")*spaces*(sometext/isfalse) -local keyvalue=(C(somekey)*spaces*P("=")*spaces*C(somevalue))/iskey -local somevalue=sometext/istrue -local subvalue=P("(")*(C(P(1-S("()"))^1)/issub)*P(")") -local option=spaces*(keyvalue+falsevalue+truevalue+somevalue)*spaces -local options=P(":")*spaces*(P(";")^0*option)^0 -local pattern=(filename_1+filename_2+fontname_1+fontname_2)*subvalue^0*crapspec^0*options^0 -function fonts.definers.analyze(str,size) - local specification=fonts.definers.makespecification(str,nil,nil,nil,":",nil,size) - list={} - lpeg.match(pattern,str) - list.crap=nil - if list.name then - specification.name=list.name - list.name=nil - end - if list.lookup then - specification.lookup=list.lookup - list.lookup=nil - end - if list.sub then - specification.sub=list.sub - list.sub=nil - end - specification.features.normal=fonts.handlers.otf.features.normalize(list) - list=nil - return specification -end -function fonts.definers.applypostprocessors(tfmdata) - local postprocessors=tfmdata.postprocessors - if postprocessors then - for i=1,#postprocessors do - local extrahash=postprocessors[i](tfmdata) - if type(extrahash)=="string" and extrahash~="" then - extrahash=string.gsub(lower(extrahash),"[^a-z]","-") - tfmdata.properties.fullname=format("%s-%s",tfmdata.properties.fullname,extrahash) - end - end - end - return tfmdata -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-def”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-ext” 32013cbc5d5d336be8b1d1e5879d86c4] --- - -if not modules then modules={} end modules ['luatex-fonts-ext']={ - version=1.001, - comment="companion to luatex-*.tex", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -if context then - os.exit() -end -local byte=string.byte -local fonts=fonts -local handlers=fonts.handlers -local otf=handlers.otf -local afm=handlers.afm -local registerotffeature=otf.features.register -local registerafmfeature=afm.features.register -function fonts.loggers.onetimemessage() end -fonts.protrusions=fonts.protrusions or {} -fonts.protrusions.setups=fonts.protrusions.setups or {} -local setups=fonts.protrusions.setups -setups['default']={ - factor=1, - left=1, - right=1, - [0x002C]={ 0,1 }, - [0x002E]={ 0,1 }, - [0x003A]={ 0,1 }, - [0x003B]={ 0,1 }, - [0x002D]={ 0,1 }, - [0x2013]={ 0,0.50 }, - [0x2014]={ 0,0.33 }, - [0x3001]={ 0,1 }, - [0x3002]={ 0,1 }, - [0x060C]={ 0,1 }, - [0x061B]={ 0,1 }, - [0x06D4]={ 0,1 }, -} -local function initializeprotrusion(tfmdata,value) - if value then - local setup=setups[value] - if setup then - local factor,left,right=setup.factor or 1,setup.left or 1,setup.right or 1 - local emwidth=tfmdata.parameters.quad - tfmdata.parameters.protrusion={ - auto=true, - } - for i,chr in next,tfmdata.characters do - local v,pl,pr=setup[i],nil,nil - if v then - pl,pr=v[1],v[2] - end - if pl and pl~=0 then chr.left_protruding=left*pl*factor end - if pr and pr~=0 then chr.right_protruding=right*pr*factor end - end - end - end -end -local specification={ - name="protrusion", - description="shift characters into the left and or right margin", - initializers={ - base=initializeprotrusion, - node=initializeprotrusion, - } -} -registerotffeature(specification) -registerafmfeature(specification) -fonts.expansions=fonts.expansions or {} -fonts.expansions.setups=fonts.expansions.setups or {} -local setups=fonts.expansions.setups -setups['default']={ - stretch=2, - shrink=2, - step=.5, - factor=1, - [byte('A')]=0.5,[byte('B')]=0.7,[byte('C')]=0.7,[byte('D')]=0.5,[byte('E')]=0.7, - [byte('F')]=0.7,[byte('G')]=0.5,[byte('H')]=0.7,[byte('K')]=0.7,[byte('M')]=0.7, - [byte('N')]=0.7,[byte('O')]=0.5,[byte('P')]=0.7,[byte('Q')]=0.5,[byte('R')]=0.7, - [byte('S')]=0.7,[byte('U')]=0.7,[byte('W')]=0.7,[byte('Z')]=0.7, - [byte('a')]=0.7,[byte('b')]=0.7,[byte('c')]=0.7,[byte('d')]=0.7,[byte('e')]=0.7, - [byte('g')]=0.7,[byte('h')]=0.7,[byte('k')]=0.7,[byte('m')]=0.7,[byte('n')]=0.7, - [byte('o')]=0.7,[byte('p')]=0.7,[byte('q')]=0.7,[byte('s')]=0.7,[byte('u')]=0.7, - [byte('w')]=0.7,[byte('z')]=0.7, - [byte('2')]=0.7,[byte('3')]=0.7,[byte('6')]=0.7,[byte('8')]=0.7,[byte('9')]=0.7, -} -local function initializeexpansion(tfmdata,value) - if value then - local setup=setups[value] - if setup then - local factor=setup.factor or 1 - tfmdata.parameters.expansion={ - stretch=10*(setup.stretch or 0), - shrink=10*(setup.shrink or 0), - step=10*(setup.step or 0), - auto=true, - } - for i,chr in next,tfmdata.characters do - local v=setup[i] - if v and v~=0 then - chr.expansion_factor=v*factor - else - chr.expansion_factor=factor - end - end - end - end -end -local specification={ - name="expansion", - description="apply hz optimization", - initializers={ - base=initializeexpansion, - node=initializeexpansion, - } -} -registerotffeature(specification) -registerafmfeature(specification) -if not otf.features.normalize then - otf.features.normalize=function(t) - if t.rand then - t.rand="random" - end - return t - end -end -function fonts.helpers.nametoslot(name) - local t=type(name) - if t=="string" then - local tfmdata=fonts.hashes.identifiers[currentfont()] - local shared=tfmdata and tfmdata.shared - local fntdata=shared and shared.rawdata - return fntdata and fntdata.resources.unicodes[name] - elseif t=="number" then - return n - end -end -fonts.encodings=fonts.encodings or {} -local reencodings={} -fonts.encodings.reencodings=reencodings -local function specialreencode(tfmdata,value) - local encoding=value and reencodings[value] - if encoding then - local temp={} - local char=tfmdata.characters - for k,v in next,encoding do - temp[k]=char[v] - end - for k,v in next,temp do - char[k]=temp[k] - end - return string.format("reencoded:%s",value) - end -end -local function initialize(tfmdata,value) - tfmdata.postprocessors=tfmdata.postprocessors or {} - table.insert(tfmdata.postprocessors, - function(tfmdata) - return specialreencode(tfmdata,value) - end - ) -end -registerotffeature { - name="reencode", - description="reencode characters", - manipulators={ - base=initialize, - node=initialize, - } -} -local function initialize(tfmdata,key,value) - if value then - tfmdata.mathparameters=nil - end -end -registerotffeature { - name="ignoremathconstants", - description="ignore math constants table", - initializers={ - base=initialize, - node=initialize, - } -} - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-ext”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-tex” ceb087ef6fa2f89aed7179f60ddf8f35] --- - -if not modules then modules={} end modules ['font-imp-tex']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next=next -local fonts=fonts -local otf=fonts.handlers.otf -local registerotffeature=otf.features.register -local addotffeature=otf.addfeature -local specification={ - type="ligature", - order={ "tlig" }, - prepend=true, - data={ - [0x2013]={ 0x002D,0x002D }, - [0x2014]={ 0x002D,0x002D,0x002D }, - }, -} -addotffeature("tlig",specification) -registerotffeature { - name="tlig", - description="tex ligatures", -} -local specification={ - type="substitution", - order={ "trep" }, - prepend=true, - data={ - [0x0027]=0x2019, - }, -} -addotffeature("trep",specification) -registerotffeature { - name="trep", - description="tex replacements", -} -local anum_arabic={ - [0x0030]=0x0660, - [0x0031]=0x0661, - [0x0032]=0x0662, - [0x0033]=0x0663, - [0x0034]=0x0664, - [0x0035]=0x0665, - [0x0036]=0x0666, - [0x0037]=0x0667, - [0x0038]=0x0668, - [0x0039]=0x0669, -} -local anum_persian={ - [0x0030]=0x06F0, - [0x0031]=0x06F1, - [0x0032]=0x06F2, - [0x0033]=0x06F3, - [0x0034]=0x06F4, - [0x0035]=0x06F5, - [0x0036]=0x06F6, - [0x0037]=0x06F7, - [0x0038]=0x06F8, - [0x0039]=0x06F9, -} -local function valid(data) - local features=data.resources.features - if features then - for k,v in next,features do - for k,v in next,v do - if v.arab then - return true - end - end - end - end -end -local specification={ - { - type="substitution", - features={ arab={ urd=true,dflt=true } }, - order={ "anum" }, - data=anum_arabic, - valid=valid, - }, - { - type="substitution", - features={ arab={ urd=true } }, - order={ "anum" }, - data=anum_persian, - valid=valid, - }, -} -addotffeature("anum",specification) -registerotffeature { - name="anum", - description="arabic digits", -} - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-tex”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-ligatures” 26ffcf089391445f7af59536c8814364] --- - -if not modules then modules={} end modules ['font-imp-ligatures']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local lpegmatch=lpeg.match -local utfsplit=utf.split -local settings_to_array=utilities.parsers.settings_to_array -local fonts=fonts -local otf=fonts.handlers.otf -local registerotffeature=otf.features.register -local addotffeature=otf.addfeature -local lookups={} -local protect={} -local revert={} -local zwjchar=0x200C -local zwj={ zwjchar } -addotffeature { - name="blockligatures", - type="chainsubstitution", - nocheck=true, - prepend=true, - future=true, - lookups={ - { - type="multiple", - data=lookups, - }, - }, - data={ - rules=protect, - } -} -addotffeature { - name="blockligatures", - type="chainsubstitution", - nocheck=true, - append=true, - overload=false, - lookups={ - { - type="ligature", - data=lookups, - }, - }, - data={ - rules=revert, - } -} -registerotffeature { - name='blockligatures', - description='block certain ligatures', -} -local splitter=lpeg.splitat(":") -local function blockligatures(str) - local t=settings_to_array(str) - for i=1,#t do - local ti=t[i] - local before,current,after=lpegmatch(splitter,ti) - if current and after then - if before then - before=utfsplit(before) - for i=1,#before do - before[i]={ before[i] } - end - end - if current then - current=utfsplit(current) - end - if after then - after=utfsplit(after) - for i=1,#after do - after[i]={ after[i] } - end - end - else - before=nil - current=utfsplit(ti) - after=nil - end - if #current>1 then - local one=current[1] - local two=current[2] - lookups[one]={ one,zwjchar } - local one={ one } - local two={ two } - local new=#protect+1 - protect[new]={ - before=before, - current={ one,two }, - after=after, - lookups={ 1 }, - } - revert[new]={ - current={ one,zwj }, - after={ two }, - lookups={ 1 }, - } - end - end -end -otf.helpers.blockligatures=blockligatures -if context then - interfaces.implement { - name="blockligatures", - arguments="string", - actions=blockligatures, - } -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-ligatures”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-italics” ae563638fa29a4ff3e8e4d1e81fd35ae] --- - -if not modules then modules={} end modules ['font-imp-italics']={ - version=1.001, - comment="companion to font-ini.mkiv and hand-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next=next -local fonts=fonts -local handlers=fonts.handlers -local registerotffeature=handlers.otf.features.register -local registerafmfeature=handlers.afm.features.register -local function initialize(tfmdata,key,value) - for unicode,character in next,tfmdata.characters do - local olditalic=character.italic - if olditalic and olditalic~=0 then - character.width=character.width+olditalic - character.italic=0 - end - end -end -local specification={ - name="italicwidths", - description="add italic to width", - manipulators={ - base=initialize, - node=initialize, - } -} -registerotffeature(specification) -registerafmfeature(specification) -local function initialize(tfmdata,value) - if value then - local parameters=tfmdata.parameters - local italicangle=parameters.italicangle - if italicangle and italicangle~=0 then - local properties=tfmdata.properties - local factor=tonumber(value) or 1 - properties.hasitalics=true - properties.autoitalicamount=factor*(parameters.uwidth or 40)/2 - end - end -end -local specification={ - name="itlc", - description="italic correction", - initializers={ - base=initialize, - node=initialize, - } -} -registerotffeature(specification) -registerafmfeature(specification) -if context then - local function initialize(tfmdata,value) - tfmdata.properties.textitalics=toboolean(value) - end - local specification={ - name="textitalics", - description="use alternative text italic correction", - initializers={ - base=initialize, - node=initialize, - } - } - registerotffeature(specification) - registerafmfeature(specification) - local letter=characters.is_letter - local always=true - local function collapseitalics(tfmdata,key,value) - local threshold=value==true and 100 or tonumber(value) - if threshold and threshold>0 then - if threshold>100 then - threshold=100 - end - for unicode,data in next,tfmdata.characters do - if always or letter[unicode] or letter[data.unicode] then - local italic=data.italic - if italic and italic~=0 then - local width=data.width - if width and width~=0 then - local delta=threshold*italic/100 - data.width=width+delta - data.italic=italic-delta - end - end - end - end - end - end - local dimensions_specification={ - name="collapseitalics", - description="collapse italics", - manipulators={ - base=collapseitalics, - node=collapseitalics, - } - } - registerotffeature(dimensions_specification) - registerafmfeature(dimensions_specification) -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-italics”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-effects” a2dde5e071fcb3fc7b90f2bcd5aa4f22] --- - -if not modules then modules={} end modules ['font-imp-effects']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next,type,tonumber=next,type,tonumber -local is_boolean=string.is_boolean -local fonts=fonts -local handlers=fonts.handlers -local registerotffeature=handlers.otf.features.register -local registerafmfeature=handlers.afm.features.register -local settings_to_hash=utilities.parsers.settings_to_hash_colon_too -local helpers=fonts.helpers -local prependcommands=helpers.prependcommands -local charcommand=helpers.commands.char -local leftcommand=helpers.commands.left -local rightcommand=helpers.commands.right -local upcommand=helpers.commands.up -local downcommand=helpers.commands.down -local dummycommand=helpers.commands.dummy -local report_effect=logs.reporter("fonts","effect") -local report_slant=logs.reporter("fonts","slant") -local report_extend=logs.reporter("fonts","extend") -local report_squeeze=logs.reporter("fonts","squeeze") -local trace=false -trackers.register("fonts.effect",function(v) trace=v end) -trackers.register("fonts.slant",function(v) trace=v end) -trackers.register("fonts.extend",function(v) trace=v end) -trackers.register("fonts.squeeze",function(v) trace=v end) -local function initializeslant(tfmdata,value) - value=tonumber(value) - if not value then - value=0 - elseif value>1 then - value=1 - elseif value<-1 then - value=-1 - end - if trace then - report_slant("applying %0.3f",value) - end - tfmdata.parameters.slantfactor=value -end -local specification={ - name="slant", - description="slant glyphs", - initializers={ - base=initializeslant, - node=initializeslant, - } -} -registerotffeature(specification) -registerafmfeature(specification) -local function initializeextend(tfmdata,value) - value=tonumber(value) - if not value then - value=0 - elseif value>10 then - value=10 - elseif value<-10 then - value=-10 - end - if trace then - report_extend("applying %0.3f",value) - end - tfmdata.parameters.extendfactor=value -end -local specification={ - name="extend", - description="scale glyphs horizontally", - initializers={ - base=initializeextend, - node=initializeextend, - } -} -registerotffeature(specification) -registerafmfeature(specification) -local function initializesqueeze(tfmdata,value) - value=tonumber(value) - if not value then - value=0 - elseif value>10 then - value=10 - elseif value<-10 then - value=-10 - end - if trace then - report_squeeze("applying %0.3f",value) - end - tfmdata.parameters.squeezefactor=value -end -local specification={ - name="squeeze", - description="scale glyphs vertically", - initializers={ - base=initializesqueeze, - node=initializesqueeze, - } -} -registerotffeature(specification) -registerafmfeature(specification) -local effects={ - inner=0, - normal=0, - outer=1, - outline=1, - both=2, - hidden=3, -} -local function initializeeffect(tfmdata,value) - local spec - if type(value)=="number" then - spec={ width=value } - else - spec=settings_to_hash(value) - end - local effect=spec.effect or "both" - local width=tonumber(spec.width) or 0 - local mode=effects[effect] - if not mode then - report_effect("invalid effect %a",effect) - elseif width==0 and mode==0 then - report_effect("invalid width %a for effect %a",width,effect) - else - local parameters=tfmdata.parameters - local properties=tfmdata.properties - parameters.mode=mode - parameters.width=width*1000 - if is_boolean(spec.auto)==true then - local squeeze=1-width/20 - local average=(1-squeeze)*width*100 - spec.squeeze=squeeze - spec.extend=1+width/2 - spec.wdelta=average - spec.hdelta=average/2 - spec.ddelta=average/2 - spec.vshift=average/2 - end - local factor=tonumber(spec.factor) or 0 - local hfactor=tonumber(spec.hfactor) or factor - local vfactor=tonumber(spec.vfactor) or factor - local delta=tonumber(spec.delta) or 1 - local wdelta=tonumber(spec.wdelta) or delta - local hdelta=tonumber(spec.hdelta) or delta - local ddelta=tonumber(spec.ddelta) or hdelta - local vshift=tonumber(spec.vshift) or 0 - local slant=spec.slant - local extend=spec.extend - local squeeze=spec.squeeze - if slant then - initializeslant(tfmdata,slant) - end - if extend then - initializeextend(tfmdata,extend) - end - if squeeze then - initializesqueeze(tfmdata,squeeze) - end - properties.effect={ - effect=effect, - width=width, - factor=factor, - hfactor=hfactor, - vfactor=vfactor, - wdelta=wdelta, - hdelta=hdelta, - ddelta=ddelta, - vshift=vshift, - slant=tfmdata.parameters.slantfactor, - extend=tfmdata.parameters.extendfactor, - squeeze=tfmdata.parameters.squeezefactor, - } - end -end -local rules={ - "RadicalRuleThickness", - "OverbarRuleThickness", - "FractionRuleThickness", - "UnderbarRuleThickness", -} -local setmathparameters -local setmathcharacters -if CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 then - setmathparameters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) - if delta~=0 then - for i=1,#rules do - local name=rules[i] - local value=mathparameters[name] - if value then - mathparameters[name]=(squeeze or 1)*(value+dy) - end - end - end - end - setmathcharacters=function() - end -else - setmathparameters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) - if delta~=0 then - for i=1,#rules do - local name=rules[i] - local value=mathparameters[name] - if value then - mathparameters[name]=(squeeze or 1)*(value+dy) - end - end - end - end - setmathcharacters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) - local function wdpatch(char) - if wsnap~=0 then - char.width=char.width+wdelta/2 - end - end - local function htpatch(char) - if hsnap~=0 then - local height=char.height - if height then - char.height=char.height+2*dy - end - end - end - local character=characters[0x221A] - if character and character.next then - local char=character - local next=character.next - wdpatch(char) - htpatch(char) - while next do - char=characters[next] - wdpatch(char) - htpatch(char) - next=char.next - end - if char then - local v=char.vert_variants - if v then - local top=v[#v] - if top then - local char=characters[top.glyph] - htpatch(char) - end - end - end - end - end -end -local shiftmode=CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 -local function manipulateeffect(tfmdata) - local effect=tfmdata.properties.effect - if effect then - local characters=tfmdata.characters - local parameters=tfmdata.parameters - local mathparameters=tfmdata.mathparameters - local multiplier=effect.width*100 - local factor=parameters.factor - local hfactor=parameters.hfactor - local vfactor=parameters.vfactor - local wdelta=effect.wdelta*hfactor*multiplier - local hdelta=effect.hdelta*vfactor*multiplier - local ddelta=effect.ddelta*vfactor*multiplier - local vshift=effect.vshift*vfactor*multiplier - local squeeze=effect.squeeze - local hshift=wdelta/2 - local dx=multiplier*vfactor - local dy=vshift - local factor=(1+effect.factor)*factor - local hfactor=(1+effect.hfactor)*hfactor - local vfactor=(1+effect.vfactor)*vfactor - if shiftmode then - parameters.hshift=hshift - parameters.vshift=vshift - else - vshift=vshift~=0 and upcommand[vshift] or false - hshift=rightcommand[hshift] - end - for unicode,character in next,characters do - local oldwidth=character.width - local oldheight=character.height - local olddepth=character.depth - if oldwidth and oldwidth>0 then - character.width=oldwidth+wdelta - if not shiftmode then - local commands=character.commands - if vshift then - if commands then - prependcommands (commands, - hshift, - vshift - ) - else - character.commands={ - hshift, - vshift, - charcommand[unicode] - } - end - else - if commands then - prependcommands (commands, - hshift - ) - else - character.commands={ - hshift, - charcommand[unicode] - } - end - end - end - end - if oldheight and oldheight>0 then - character.height=oldheight+hdelta - end - if olddepth and olddepth>0 then - character.depth=olddepth+ddelta - end - end - if mathparameters then - setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) - setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) - end - parameters.factor=factor - parameters.hfactor=hfactor - parameters.vfactor=vfactor - if trace then - report_effect("applying") - report_effect(" effect : %s",effect.effect) - report_effect(" width : %s => %s",effect.width,multiplier) - report_effect(" factor : %s => %s",effect.factor,factor ) - report_effect(" hfactor : %s => %s",effect.hfactor,hfactor) - report_effect(" vfactor : %s => %s",effect.vfactor,vfactor) - report_effect(" wdelta : %s => %s",effect.wdelta,wdelta) - report_effect(" hdelta : %s => %s",effect.hdelta,hdelta) - report_effect(" ddelta : %s => %s",effect.ddelta,ddelta) - end - end -end -local specification={ - name="effect", - description="apply effects to glyphs", - initializers={ - base=initializeeffect, - node=initializeeffect, - }, - manipulators={ - base=manipulateeffect, - node=manipulateeffect, - }, -} -registerotffeature(specification) -registerafmfeature(specification) -local function initializeoutline(tfmdata,value) - value=tonumber(value) - if not value then - value=0 - else - value=tonumber(value) or 0 - end - local parameters=tfmdata.parameters - local properties=tfmdata.properties - parameters.mode=effects.outline - parameters.width=value*1000 - properties.effect={ - effect=effect, - width=width, - } -end -local specification={ - name="outline", - description="outline glyphs", - initializers={ - base=initializeoutline, - node=initializeoutline, - } -} -registerotffeature(specification) -registerafmfeature(specification) - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-effects”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-lig” fbd251eea3810a43a8d5542319361d68] --- - - -fonts.handlers.otf.addfeature { - ["dataset"]={ - { - ["data"]={ - ["À"]={ "A","̀" }, - ["Á"]={ "A","́" }, - ["Â"]={ "A","̂" }, - ["Ã"]={ "A","̃" }, - ["Ä"]={ "A","̈" }, - ["Å"]={ "A","̊" }, - ["Ç"]={ "C","̧" }, - ["È"]={ "E","̀" }, - ["É"]={ "E","́" }, - ["Ê"]={ "E","̂" }, - ["Ë"]={ "E","̈" }, - ["Ì"]={ "I","̀" }, - ["Í"]={ "I","́" }, - ["Î"]={ "I","̂" }, - ["Ï"]={ "I","̈" }, - ["Ñ"]={ "N","̃" }, - ["Ò"]={ "O","̀" }, - ["Ó"]={ "O","́" }, - ["Ô"]={ "O","̂" }, - ["Õ"]={ "O","̃" }, - ["Ö"]={ "O","̈" }, - ["Ù"]={ "U","̀" }, - ["Ú"]={ "U","́" }, - ["Û"]={ "U","̂" }, - ["Ü"]={ "U","̈" }, - ["Ý"]={ "Y","́" }, - ["à"]={ "a","̀" }, - ["á"]={ "a","́" }, - ["â"]={ "a","̂" }, - ["ã"]={ "a","̃" }, - ["ä"]={ "a","̈" }, - ["å"]={ "a","̊" }, - ["ç"]={ "c","̧" }, - ["è"]={ "e","̀" }, - ["é"]={ "e","́" }, - ["ê"]={ "e","̂" }, - ["ë"]={ "e","̈" }, - ["ì"]={ "i","̀" }, - ["í"]={ "i","́" }, - ["î"]={ "i","̂" }, - ["ï"]={ "i","̈" }, - ["ñ"]={ "n","̃" }, - ["ò"]={ "o","̀" }, - ["ó"]={ "o","́" }, - ["ô"]={ "o","̂" }, - ["õ"]={ "o","̃" }, - ["ö"]={ "o","̈" }, - ["ù"]={ "u","̀" }, - ["ú"]={ "u","́" }, - ["û"]={ "u","̂" }, - ["ü"]={ "u","̈" }, - ["ý"]={ "y","́" }, - ["ÿ"]={ "y","̈" }, - ["Ā"]={ "A","̄" }, - ["ā"]={ "a","̄" }, - ["Ă"]={ "A","̆" }, - ["ă"]={ "a","̆" }, - ["Ą"]={ "A","̨" }, - ["ą"]={ "a","̨" }, - ["Ć"]={ "C","́" }, - ["ć"]={ "c","́" }, - ["Ĉ"]={ "C","̂" }, - ["ĉ"]={ "c","̂" }, - ["Ċ"]={ "C","̇" }, - ["ċ"]={ "c","̇" }, - ["Č"]={ "C","̌" }, - ["č"]={ "c","̌" }, - ["Ď"]={ "D","̌" }, - ["ď"]={ "d","̌" }, - ["Ē"]={ "E","̄" }, - ["ē"]={ "e","̄" }, - ["Ĕ"]={ "E","̆" }, - ["ĕ"]={ "e","̆" }, - ["Ė"]={ "E","̇" }, - ["ė"]={ "e","̇" }, - ["Ę"]={ "E","̨" }, - ["ę"]={ "e","̨" }, - ["Ě"]={ "E","̌" }, - ["ě"]={ "e","̌" }, - ["Ĝ"]={ "G","̂" }, - ["ĝ"]={ "g","̂" }, - ["Ğ"]={ "G","̆" }, - ["ğ"]={ "g","̆" }, - ["Ġ"]={ "G","̇" }, - ["ġ"]={ "g","̇" }, - ["Ģ"]={ "G","̧" }, - ["ģ"]={ "g","̧" }, - ["Ĥ"]={ "H","̂" }, - ["ĥ"]={ "h","̂" }, - ["Ĩ"]={ "I","̃" }, - ["ĩ"]={ "i","̃" }, - ["Ī"]={ "I","̄" }, - ["ī"]={ "i","̄" }, - ["Ĭ"]={ "I","̆" }, - ["ĭ"]={ "i","̆" }, - ["Į"]={ "I","̨" }, - ["į"]={ "i","̨" }, - ["İ"]={ "I","̇" }, - ["Ĵ"]={ "J","̂" }, - ["ĵ"]={ "j","̂" }, - ["Ķ"]={ "K","̧" }, - ["ķ"]={ "k","̧" }, - ["Ĺ"]={ "L","́" }, - ["ĺ"]={ "l","́" }, - ["Ļ"]={ "L","̧" }, - ["ļ"]={ "l","̧" }, - ["Ľ"]={ "L","̌" }, - ["ľ"]={ "l","̌" }, - ["Ń"]={ "N","́" }, - ["ń"]={ "n","́" }, - ["Ņ"]={ "N","̧" }, - ["ņ"]={ "n","̧" }, - ["Ň"]={ "N","̌" }, - ["ň"]={ "n","̌" }, - ["Ō"]={ "O","̄" }, - ["ō"]={ "o","̄" }, - ["Ŏ"]={ "O","̆" }, - ["ŏ"]={ "o","̆" }, - ["Ő"]={ "O","̋" }, - ["ő"]={ "o","̋" }, - ["Ŕ"]={ "R","́" }, - ["ŕ"]={ "r","́" }, - ["Ŗ"]={ "R","̧" }, - ["ŗ"]={ "r","̧" }, - ["Ř"]={ "R","̌" }, - ["ř"]={ "r","̌" }, - ["Ś"]={ "S","́" }, - ["ś"]={ "s","́" }, - ["Ŝ"]={ "S","̂" }, - ["ŝ"]={ "s","̂" }, - ["Ş"]={ "S","̧" }, - ["ş"]={ "s","̧" }, - ["Š"]={ "S","̌" }, - ["š"]={ "s","̌" }, - ["Ţ"]={ "T","̧" }, - ["ţ"]={ "t","̧" }, - ["Ť"]={ "T","̌" }, - ["ť"]={ "t","̌" }, - ["Ũ"]={ "U","̃" }, - ["ũ"]={ "u","̃" }, - ["Ū"]={ "U","̄" }, - ["ū"]={ "u","̄" }, - ["Ŭ"]={ "U","̆" }, - ["ŭ"]={ "u","̆" }, - ["Ů"]={ "U","̊" }, - ["ů"]={ "u","̊" }, - ["Ű"]={ "U","̋" }, - ["ű"]={ "u","̋" }, - ["Ų"]={ "U","̨" }, - ["ų"]={ "u","̨" }, - ["Ŵ"]={ "W","̂" }, - ["ŵ"]={ "w","̂" }, - ["Ŷ"]={ "Y","̂" }, - ["ŷ"]={ "y","̂" }, - ["Ÿ"]={ "Y","̈" }, - ["Ź"]={ "Z","́" }, - ["ź"]={ "z","́" }, - ["Ż"]={ "Z","̇" }, - ["ż"]={ "z","̇" }, - ["Ž"]={ "Z","̌" }, - ["ž"]={ "z","̌" }, - ["Ơ"]={ "O","̛" }, - ["ơ"]={ "o","̛" }, - ["Ư"]={ "U","̛" }, - ["ư"]={ "u","̛" }, - ["Ǎ"]={ "A","̌" }, - ["ǎ"]={ "a","̌" }, - ["Ǐ"]={ "I","̌" }, - ["ǐ"]={ "i","̌" }, - ["Ǒ"]={ "O","̌" }, - ["ǒ"]={ "o","̌" }, - ["Ǔ"]={ "U","̌" }, - ["ǔ"]={ "u","̌" }, - ["Ǖ"]={ "Ü","̄" }, - ["ǖ"]={ "ü","̄" }, - ["Ǘ"]={ "Ü","́" }, - ["ǘ"]={ "ü","́" }, - ["Ǚ"]={ "Ü","̌" }, - ["ǚ"]={ "ü","̌" }, - ["Ǜ"]={ "Ü","̀" }, - ["ǜ"]={ "ü","̀" }, - ["Ǟ"]={ "Ä","̄" }, - ["ǟ"]={ "ä","̄" }, - ["Ǡ"]={ "Ȧ","̄" }, - ["ǡ"]={ "ȧ","̄" }, - ["Ǣ"]={ "Æ","̄" }, - ["ǣ"]={ "æ","̄" }, - ["Ǧ"]={ "G","̌" }, - ["ǧ"]={ "g","̌" }, - ["Ǩ"]={ "K","̌" }, - ["ǩ"]={ "k","̌" }, - ["Ǫ"]={ "O","̨" }, - ["ǫ"]={ "o","̨" }, - ["Ǭ"]={ "Ǫ","̄" }, - ["ǭ"]={ "ǫ","̄" }, - ["Ǯ"]={ "Ʒ","̌" }, - ["ǯ"]={ "ʒ","̌" }, - ["ǰ"]={ "j","̌" }, - ["Ǵ"]={ "G","́" }, - ["ǵ"]={ "g","́" }, - ["Ǹ"]={ "N","̀" }, - ["ǹ"]={ "n","̀" }, - ["Ǻ"]={ "Å","́" }, - ["ǻ"]={ "å","́" }, - ["Ǽ"]={ "Æ","́" }, - ["ǽ"]={ "æ","́" }, - ["Ǿ"]={ "Ø","́" }, - ["ǿ"]={ "ø","́" }, - ["Ȁ"]={ "A","̏" }, - ["ȁ"]={ "a","̏" }, - ["Ȃ"]={ "A","̑" }, - ["ȃ"]={ "a","̑" }, - ["Ȅ"]={ "E","̏" }, - ["ȅ"]={ "e","̏" }, - ["Ȇ"]={ "E","̑" }, - ["ȇ"]={ "e","̑" }, - ["Ȉ"]={ "I","̏" }, - ["ȉ"]={ "i","̏" }, - ["Ȋ"]={ "I","̑" }, - ["ȋ"]={ "i","̑" }, - ["Ȍ"]={ "O","̏" }, - ["ȍ"]={ "o","̏" }, - ["Ȏ"]={ "O","̑" }, - ["ȏ"]={ "o","̑" }, - ["Ȑ"]={ "R","̏" }, - ["ȑ"]={ "r","̏" }, - ["Ȓ"]={ "R","̑" }, - ["ȓ"]={ "r","̑" }, - ["Ȕ"]={ "U","̏" }, - ["ȕ"]={ "u","̏" }, - ["Ȗ"]={ "U","̑" }, - ["ȗ"]={ "u","̑" }, - ["Ș"]={ "S","̦" }, - ["ș"]={ "s","̦" }, - ["Ț"]={ "T","̦" }, - ["ț"]={ "t","̦" }, - ["Ȟ"]={ "H","̌" }, - ["ȟ"]={ "h","̌" }, - ["Ȧ"]={ "A","̇" }, - ["ȧ"]={ "a","̇" }, - ["Ȩ"]={ "E","̧" }, - ["ȩ"]={ "e","̧" }, - ["Ȫ"]={ "Ö","̄" }, - ["ȫ"]={ "ö","̄" }, - ["Ȭ"]={ "Õ","̄" }, - ["ȭ"]={ "õ","̄" }, - ["Ȯ"]={ "O","̇" }, - ["ȯ"]={ "o","̇" }, - ["Ȱ"]={ "Ȯ","̄" }, - ["ȱ"]={ "ȯ","̄" }, - ["Ȳ"]={ "Y","̄" }, - ["ȳ"]={ "y","̄" }, - ["̈́"]={ "̈","́" }, - ["΅"]={ "¨","́" }, - ["Ά"]={ "Α","́" }, - ["Έ"]={ "Ε","́" }, - ["Ή"]={ "Η","́" }, - ["Ί"]={ "Ι","́" }, - ["Ό"]={ "Ο","́" }, - ["Ύ"]={ "Υ","́" }, - ["Ώ"]={ "Ω","́" }, - ["ΐ"]={ "ϊ","́" }, - ["Ϊ"]={ "Ι","̈" }, - ["Ϋ"]={ "Υ","̈" }, - ["ά"]={ "α","́" }, - ["έ"]={ "ε","́" }, - ["ή"]={ "η","́" }, - ["ί"]={ "ι","́" }, - ["ΰ"]={ "ϋ","́" }, - ["ϊ"]={ "ι","̈" }, - ["ϋ"]={ "υ","̈" }, - ["ό"]={ "ο","́" }, - ["ύ"]={ "υ","́" }, - ["ώ"]={ "ω","́" }, - ["ϓ"]={ "ϒ","́" }, - ["ϔ"]={ "ϒ","̈" }, - ["Ѐ"]={ "Е","̀" }, - ["Ё"]={ "Е","̈" }, - ["Ѓ"]={ "Г","́" }, - ["Ї"]={ "І","̈" }, - ["Ќ"]={ "К","́" }, - ["Ѝ"]={ "И","̀" }, - ["Ў"]={ "У","̆" }, - ["Й"]={ "И","̆" }, - ["й"]={ "и","̆" }, - ["ѐ"]={ "е","̀" }, - ["ё"]={ "е","̈" }, - ["ѓ"]={ "г","́" }, - ["ї"]={ "і","̈" }, - ["ќ"]={ "к","́" }, - ["ѝ"]={ "и","̀" }, - ["ў"]={ "у","̆" }, - ["Ѷ"]={ "Ѵ","̏" }, - ["ѷ"]={ "ѵ","̏" }, - ["Ӂ"]={ "Ж","̆" }, - ["ӂ"]={ "ж","̆" }, - ["Ӑ"]={ "А","̆" }, - ["ӑ"]={ "а","̆" }, - ["Ӓ"]={ "А","̈" }, - ["ӓ"]={ "а","̈" }, - ["Ӗ"]={ "Е","̆" }, - ["ӗ"]={ "е","̆" }, - ["Ӛ"]={ "Ә","̈" }, - ["ӛ"]={ "ә","̈" }, - ["Ӝ"]={ "Ж","̈" }, - ["ӝ"]={ "ж","̈" }, - ["Ӟ"]={ "З","̈" }, - ["ӟ"]={ "з","̈" }, - ["Ӣ"]={ "И","̄" }, - ["ӣ"]={ "и","̄" }, - ["Ӥ"]={ "И","̈" }, - ["ӥ"]={ "и","̈" }, - ["Ӧ"]={ "О","̈" }, - ["ӧ"]={ "о","̈" }, - ["Ӫ"]={ "Ө","̈" }, - ["ӫ"]={ "ө","̈" }, - ["Ӭ"]={ "Э","̈" }, - ["ӭ"]={ "э","̈" }, - ["Ӯ"]={ "У","̄" }, - ["ӯ"]={ "у","̄" }, - ["Ӱ"]={ "У","̈" }, - ["ӱ"]={ "у","̈" }, - ["Ӳ"]={ "У","̋" }, - ["ӳ"]={ "у","̋" }, - ["Ӵ"]={ "Ч","̈" }, - ["ӵ"]={ "ч","̈" }, - ["Ӹ"]={ "Ы","̈" }, - ["ӹ"]={ "ы","̈" }, - ["آ"]={ "ا","ٓ" }, - ["أ"]={ "ا","ٔ" }, - ["ؤ"]={ "و","ٔ" }, - ["إ"]={ "ا","ٕ" }, - ["ئ"]={ "ي","ٔ" }, - ["ۀ"]={ "ە","ٔ" }, - ["ۂ"]={ "ہ","ٔ" }, - ["ۓ"]={ "ے","ٔ" }, - ["ऩ"]={ "न","़" }, - ["ऱ"]={ "र","़" }, - ["ऴ"]={ "ळ","़" }, - ["क़"]={ "क","़" }, - ["ख़"]={ "ख","़" }, - ["ग़"]={ "ग","़" }, - ["ज़"]={ "ज","़" }, - ["ड़"]={ "ड","़" }, - ["ढ़"]={ "ढ","़" }, - ["फ़"]={ "फ","़" }, - ["य़"]={ "य","़" }, - ["ো"]={ "ে","া" }, - ["ৌ"]={ "ে","ৗ" }, - ["ড়"]={ "ড","়" }, - ["ঢ়"]={ "ঢ","়" }, - ["য়"]={ "য","়" }, - ["ਲ਼"]={ "ਲ","਼" }, - ["ਸ਼"]={ "ਸ","਼" }, - ["ਖ਼"]={ "ਖ","਼" }, - ["ਗ਼"]={ "ਗ","਼" }, - ["ਜ਼"]={ "ਜ","਼" }, - ["ਫ਼"]={ "ਫ","਼" }, - ["ୈ"]={ "େ","ୖ" }, - ["ୋ"]={ "େ","ା" }, - ["ୌ"]={ "େ","ୗ" }, - ["ଡ଼"]={ "ଡ","଼" }, - ["ଢ଼"]={ "ଢ","଼" }, - ["ஔ"]={ "ஒ","ௗ" }, - ["ொ"]={ "ெ","ா" }, - ["ோ"]={ "ே","ா" }, - ["ௌ"]={ "ெ","ௗ" }, - ["ై"]={ "ె","ౖ" }, - ["ೀ"]={ "ಿ","ೕ" }, - ["ೇ"]={ "ೆ","ೕ" }, - ["ೈ"]={ "ೆ","ೖ" }, - ["ೊ"]={ "ೆ","ೂ" }, - ["ೋ"]={ "ೊ","ೕ" }, - ["ൊ"]={ "െ","ാ" }, - ["ോ"]={ "േ","ാ" }, - ["ൌ"]={ "െ","ൗ" }, - ["ේ"]={ "ෙ","්" }, - ["ො"]={ "ෙ","ා" }, - ["ෝ"]={ "ො","්" }, - ["ෞ"]={ "ෙ","ෟ" }, - ["གྷ"]={ "ག","ྷ" }, - ["ཌྷ"]={ "ཌ","ྷ" }, - ["དྷ"]={ "ད","ྷ" }, - ["བྷ"]={ "བ","ྷ" }, - ["ཛྷ"]={ "ཛ","ྷ" }, - ["ཀྵ"]={ "ཀ","ྵ" }, - ["ཱི"]={ "ཱ","ི" }, - ["ཱུ"]={ "ཱ","ུ" }, - ["ྲྀ"]={ "ྲ","ྀ" }, - ["ླྀ"]={ "ླ","ྀ" }, - ["ཱྀ"]={ "ཱ","ྀ" }, - ["ྒྷ"]={ "ྒ","ྷ" }, - ["ྜྷ"]={ "ྜ","ྷ" }, - ["ྡྷ"]={ "ྡ","ྷ" }, - ["ྦྷ"]={ "ྦ","ྷ" }, - ["ྫྷ"]={ "ྫ","ྷ" }, - ["ྐྵ"]={ "ྐ","ྵ" }, - ["ဦ"]={ "ဥ","ီ" }, - ["ᬆ"]={ "ᬅ","ᬵ" }, - ["ᬈ"]={ "ᬇ","ᬵ" }, - ["ᬊ"]={ "ᬉ","ᬵ" }, - ["ᬌ"]={ "ᬋ","ᬵ" }, - ["ᬎ"]={ "ᬍ","ᬵ" }, - ["ᬒ"]={ "ᬑ","ᬵ" }, - ["ᬻ"]={ "ᬺ","ᬵ" }, - ["ᬽ"]={ "ᬼ","ᬵ" }, - ["ᭀ"]={ "ᬾ","ᬵ" }, - ["ᭁ"]={ "ᬿ","ᬵ" }, - ["ᭃ"]={ "ᭂ","ᬵ" }, - ["Ḁ"]={ "A","̥" }, - ["ḁ"]={ "a","̥" }, - ["Ḃ"]={ "B","̇" }, - ["ḃ"]={ "b","̇" }, - ["Ḅ"]={ "B","̣" }, - ["ḅ"]={ "b","̣" }, - ["Ḇ"]={ "B","̱" }, - ["ḇ"]={ "b","̱" }, - ["Ḉ"]={ "Ç","́" }, - ["ḉ"]={ "ç","́" }, - ["Ḋ"]={ "D","̇" }, - ["ḋ"]={ "d","̇" }, - ["Ḍ"]={ "D","̣" }, - ["ḍ"]={ "d","̣" }, - ["Ḏ"]={ "D","̱" }, - ["ḏ"]={ "d","̱" }, - ["Ḑ"]={ "D","̧" }, - ["ḑ"]={ "d","̧" }, - ["Ḓ"]={ "D","̭" }, - ["ḓ"]={ "d","̭" }, - ["Ḕ"]={ "Ē","̀" }, - ["ḕ"]={ "ē","̀" }, - ["Ḗ"]={ "Ē","́" }, - ["ḗ"]={ "ē","́" }, - ["Ḙ"]={ "E","̭" }, - ["ḙ"]={ "e","̭" }, - ["Ḛ"]={ "E","̰" }, - ["ḛ"]={ "e","̰" }, - ["Ḝ"]={ "Ȩ","̆" }, - ["ḝ"]={ "ȩ","̆" }, - ["Ḟ"]={ "F","̇" }, - ["ḟ"]={ "f","̇" }, - ["Ḡ"]={ "G","̄" }, - ["ḡ"]={ "g","̄" }, - ["Ḣ"]={ "H","̇" }, - ["ḣ"]={ "h","̇" }, - ["Ḥ"]={ "H","̣" }, - ["ḥ"]={ "h","̣" }, - ["Ḧ"]={ "H","̈" }, - ["ḧ"]={ "h","̈" }, - ["Ḩ"]={ "H","̧" }, - ["ḩ"]={ "h","̧" }, - ["Ḫ"]={ "H","̮" }, - ["ḫ"]={ "h","̮" }, - ["Ḭ"]={ "I","̰" }, - ["ḭ"]={ "i","̰" }, - ["Ḯ"]={ "Ï","́" }, - ["ḯ"]={ "ï","́" }, - ["Ḱ"]={ "K","́" }, - ["ḱ"]={ "k","́" }, - ["Ḳ"]={ "K","̣" }, - ["ḳ"]={ "k","̣" }, - ["Ḵ"]={ "K","̱" }, - ["ḵ"]={ "k","̱" }, - ["Ḷ"]={ "L","̣" }, - ["ḷ"]={ "l","̣" }, - ["Ḹ"]={ "Ḷ","̄" }, - ["ḹ"]={ "ḷ","̄" }, - ["Ḻ"]={ "L","̱" }, - ["ḻ"]={ "l","̱" }, - ["Ḽ"]={ "L","̭" }, - ["ḽ"]={ "l","̭" }, - ["Ḿ"]={ "M","́" }, - ["ḿ"]={ "m","́" }, - ["Ṁ"]={ "M","̇" }, - ["ṁ"]={ "m","̇" }, - ["Ṃ"]={ "M","̣" }, - ["ṃ"]={ "m","̣" }, - ["Ṅ"]={ "N","̇" }, - ["ṅ"]={ "n","̇" }, - ["Ṇ"]={ "N","̣" }, - ["ṇ"]={ "n","̣" }, - ["Ṉ"]={ "N","̱" }, - ["ṉ"]={ "n","̱" }, - ["Ṋ"]={ "N","̭" }, - ["ṋ"]={ "n","̭" }, - ["Ṍ"]={ "Õ","́" }, - ["ṍ"]={ "õ","́" }, - ["Ṏ"]={ "Õ","̈" }, - ["ṏ"]={ "õ","̈" }, - ["Ṑ"]={ "Ō","̀" }, - ["ṑ"]={ "ō","̀" }, - ["Ṓ"]={ "Ō","́" }, - ["ṓ"]={ "ō","́" }, - ["Ṕ"]={ "P","́" }, - ["ṕ"]={ "p","́" }, - ["Ṗ"]={ "P","̇" }, - ["ṗ"]={ "p","̇" }, - ["Ṙ"]={ "R","̇" }, - ["ṙ"]={ "r","̇" }, - ["Ṛ"]={ "R","̣" }, - ["ṛ"]={ "r","̣" }, - ["Ṝ"]={ "Ṛ","̄" }, - ["ṝ"]={ "ṛ","̄" }, - ["Ṟ"]={ "R","̱" }, - ["ṟ"]={ "r","̱" }, - ["Ṡ"]={ "S","̇" }, - ["ṡ"]={ "s","̇" }, - ["Ṣ"]={ "S","̣" }, - ["ṣ"]={ "s","̣" }, - ["Ṥ"]={ "Ś","̇" }, - ["ṥ"]={ "ś","̇" }, - ["Ṧ"]={ "Š","̇" }, - ["ṧ"]={ "š","̇" }, - ["Ṩ"]={ "Ṣ","̇" }, - ["ṩ"]={ "ṣ","̇" }, - ["Ṫ"]={ "T","̇" }, - ["ṫ"]={ "t","̇" }, - ["Ṭ"]={ "T","̣" }, - ["ṭ"]={ "t","̣" }, - ["Ṯ"]={ "T","̱" }, - ["ṯ"]={ "t","̱" }, - ["Ṱ"]={ "T","̭" }, - ["ṱ"]={ "t","̭" }, - ["Ṳ"]={ "U","̤" }, - ["ṳ"]={ "u","̤" }, - ["Ṵ"]={ "U","̰" }, - ["ṵ"]={ "u","̰" }, - ["Ṷ"]={ "U","̭" }, - ["ṷ"]={ "u","̭" }, - ["Ṹ"]={ "Ũ","́" }, - ["ṹ"]={ "ũ","́" }, - ["Ṻ"]={ "Ū","̈" }, - ["ṻ"]={ "ū","̈" }, - ["Ṽ"]={ "V","̃" }, - ["ṽ"]={ "v","̃" }, - ["Ṿ"]={ "V","̣" }, - ["ṿ"]={ "v","̣" }, - ["Ẁ"]={ "W","̀" }, - ["ẁ"]={ "w","̀" }, - ["Ẃ"]={ "W","́" }, - ["ẃ"]={ "w","́" }, - ["Ẅ"]={ "W","̈" }, - ["ẅ"]={ "w","̈" }, - ["Ẇ"]={ "W","̇" }, - ["ẇ"]={ "w","̇" }, - ["Ẉ"]={ "W","̣" }, - ["ẉ"]={ "w","̣" }, - ["Ẋ"]={ "X","̇" }, - ["ẋ"]={ "x","̇" }, - ["Ẍ"]={ "X","̈" }, - ["ẍ"]={ "x","̈" }, - ["Ẏ"]={ "Y","̇" }, - ["ẏ"]={ "y","̇" }, - ["Ẑ"]={ "Z","̂" }, - ["ẑ"]={ "z","̂" }, - ["Ẓ"]={ "Z","̣" }, - ["ẓ"]={ "z","̣" }, - ["Ẕ"]={ "Z","̱" }, - ["ẕ"]={ "z","̱" }, - ["ẖ"]={ "h","̱" }, - ["ẗ"]={ "t","̈" }, - ["ẘ"]={ "w","̊" }, - ["ẙ"]={ "y","̊" }, - ["ẛ"]={ "ſ","̇" }, - ["Ạ"]={ "A","̣" }, - ["ạ"]={ "a","̣" }, - ["Ả"]={ "A","̉" }, - ["ả"]={ "a","̉" }, - ["Ấ"]={ "Â","́" }, - ["ấ"]={ "â","́" }, - ["Ầ"]={ "Â","̀" }, - ["ầ"]={ "â","̀" }, - ["Ẩ"]={ "Â","̉" }, - ["ẩ"]={ "â","̉" }, - ["Ẫ"]={ "Â","̃" }, - ["ẫ"]={ "â","̃" }, - ["Ậ"]={ "Ạ","̂" }, - ["ậ"]={ "ạ","̂" }, - ["Ắ"]={ "Ă","́" }, - ["ắ"]={ "ă","́" }, - ["Ằ"]={ "Ă","̀" }, - ["ằ"]={ "ă","̀" }, - ["Ẳ"]={ "Ă","̉" }, - ["ẳ"]={ "ă","̉" }, - ["Ẵ"]={ "Ă","̃" }, - ["ẵ"]={ "ă","̃" }, - ["Ặ"]={ "Ạ","̆" }, - ["ặ"]={ "ạ","̆" }, - ["Ẹ"]={ "E","̣" }, - ["ẹ"]={ "e","̣" }, - ["Ẻ"]={ "E","̉" }, - ["ẻ"]={ "e","̉" }, - ["Ẽ"]={ "E","̃" }, - ["ẽ"]={ "e","̃" }, - ["Ế"]={ "Ê","́" }, - ["ế"]={ "ê","́" }, - ["Ề"]={ "Ê","̀" }, - ["ề"]={ "ê","̀" }, - ["Ể"]={ "Ê","̉" }, - ["ể"]={ "ê","̉" }, - ["Ễ"]={ "Ê","̃" }, - ["ễ"]={ "ê","̃" }, - ["Ệ"]={ "Ẹ","̂" }, - ["ệ"]={ "ẹ","̂" }, - ["Ỉ"]={ "I","̉" }, - ["ỉ"]={ "i","̉" }, - ["Ị"]={ "I","̣" }, - ["ị"]={ "i","̣" }, - ["Ọ"]={ "O","̣" }, - ["ọ"]={ "o","̣" }, - ["Ỏ"]={ "O","̉" }, - ["ỏ"]={ "o","̉" }, - ["Ố"]={ "Ô","́" }, - ["ố"]={ "ô","́" }, - ["Ồ"]={ "Ô","̀" }, - ["ồ"]={ "ô","̀" }, - ["Ổ"]={ "Ô","̉" }, - ["ổ"]={ "ô","̉" }, - ["Ỗ"]={ "Ô","̃" }, - ["ỗ"]={ "ô","̃" }, - ["Ộ"]={ "Ọ","̂" }, - ["ộ"]={ "ọ","̂" }, - ["Ớ"]={ "Ơ","́" }, - ["ớ"]={ "ơ","́" }, - ["Ờ"]={ "Ơ","̀" }, - ["ờ"]={ "ơ","̀" }, - ["Ở"]={ "Ơ","̉" }, - ["ở"]={ "ơ","̉" }, - ["Ỡ"]={ "Ơ","̃" }, - ["ỡ"]={ "ơ","̃" }, - ["Ợ"]={ "Ơ","̣" }, - ["ợ"]={ "ơ","̣" }, - ["Ụ"]={ "U","̣" }, - ["ụ"]={ "u","̣" }, - ["Ủ"]={ "U","̉" }, - ["ủ"]={ "u","̉" }, - ["Ứ"]={ "Ư","́" }, - ["ứ"]={ "ư","́" }, - ["Ừ"]={ "Ư","̀" }, - ["ừ"]={ "ư","̀" }, - ["Ử"]={ "Ư","̉" }, - ["ử"]={ "ư","̉" }, - ["Ữ"]={ "Ư","̃" }, - ["ữ"]={ "ư","̃" }, - ["Ự"]={ "Ư","̣" }, - ["ự"]={ "ư","̣" }, - ["Ỳ"]={ "Y","̀" }, - ["ỳ"]={ "y","̀" }, - ["Ỵ"]={ "Y","̣" }, - ["ỵ"]={ "y","̣" }, - ["Ỷ"]={ "Y","̉" }, - ["ỷ"]={ "y","̉" }, - ["Ỹ"]={ "Y","̃" }, - ["ỹ"]={ "y","̃" }, - ["ἀ"]={ "α","̓" }, - ["ἁ"]={ "α","̔" }, - ["ἂ"]={ "ἀ","̀" }, - ["ἃ"]={ "ἁ","̀" }, - ["ἄ"]={ "ἀ","́" }, - ["ἅ"]={ "ἁ","́" }, - ["ἆ"]={ "ἀ","͂" }, - ["ἇ"]={ "ἁ","͂" }, - ["Ἀ"]={ "Α","̓" }, - ["Ἁ"]={ "Α","̔" }, - ["Ἂ"]={ "Ἀ","̀" }, - ["Ἃ"]={ "Ἁ","̀" }, - ["Ἄ"]={ "Ἀ","́" }, - ["Ἅ"]={ "Ἁ","́" }, - ["Ἆ"]={ "Ἀ","͂" }, - ["Ἇ"]={ "Ἁ","͂" }, - ["ἐ"]={ "ε","̓" }, - ["ἑ"]={ "ε","̔" }, - ["ἒ"]={ "ἐ","̀" }, - ["ἓ"]={ "ἑ","̀" }, - ["ἔ"]={ "ἐ","́" }, - ["ἕ"]={ "ἑ","́" }, - ["Ἐ"]={ "Ε","̓" }, - ["Ἑ"]={ "Ε","̔" }, - ["Ἒ"]={ "Ἐ","̀" }, - ["Ἓ"]={ "Ἑ","̀" }, - ["Ἔ"]={ "Ἐ","́" }, - ["Ἕ"]={ "Ἑ","́" }, - ["ἠ"]={ "η","̓" }, - ["ἡ"]={ "η","̔" }, - ["ἢ"]={ "ἠ","̀" }, - ["ἣ"]={ "ἡ","̀" }, - ["ἤ"]={ "ἠ","́" }, - ["ἥ"]={ "ἡ","́" }, - ["ἦ"]={ "ἠ","͂" }, - ["ἧ"]={ "ἡ","͂" }, - ["Ἠ"]={ "Η","̓" }, - ["Ἡ"]={ "Η","̔" }, - ["Ἢ"]={ "Ἠ","̀" }, - ["Ἣ"]={ "Ἡ","̀" }, - ["Ἤ"]={ "Ἠ","́" }, - ["Ἥ"]={ "Ἡ","́" }, - ["Ἦ"]={ "Ἠ","͂" }, - ["Ἧ"]={ "Ἡ","͂" }, - ["ἰ"]={ "ι","̓" }, - ["ἱ"]={ "ι","̔" }, - ["ἲ"]={ "ἰ","̀" }, - ["ἳ"]={ "ἱ","̀" }, - ["ἴ"]={ "ἰ","́" }, - ["ἵ"]={ "ἱ","́" }, - ["ἶ"]={ "ἰ","͂" }, - ["ἷ"]={ "ἱ","͂" }, - ["Ἰ"]={ "Ι","̓" }, - ["Ἱ"]={ "Ι","̔" }, - ["Ἲ"]={ "Ἰ","̀" }, - ["Ἳ"]={ "Ἱ","̀" }, - ["Ἴ"]={ "Ἰ","́" }, - ["Ἵ"]={ "Ἱ","́" }, - ["Ἶ"]={ "Ἰ","͂" }, - ["Ἷ"]={ "Ἱ","͂" }, - ["ὀ"]={ "ο","̓" }, - ["ὁ"]={ "ο","̔" }, - ["ὂ"]={ "ὀ","̀" }, - ["ὃ"]={ "ὁ","̀" }, - ["ὄ"]={ "ὀ","́" }, - ["ὅ"]={ "ὁ","́" }, - ["Ὀ"]={ "Ο","̓" }, - ["Ὁ"]={ "Ο","̔" }, - ["Ὂ"]={ "Ὀ","̀" }, - ["Ὃ"]={ "Ὁ","̀" }, - ["Ὄ"]={ "Ὀ","́" }, - ["Ὅ"]={ "Ὁ","́" }, - ["ὐ"]={ "υ","̓" }, - ["ὑ"]={ "υ","̔" }, - ["ὒ"]={ "ὐ","̀" }, - ["ὓ"]={ "ὑ","̀" }, - ["ὔ"]={ "ὐ","́" }, - ["ὕ"]={ "ὑ","́" }, - ["ὖ"]={ "ὐ","͂" }, - ["ὗ"]={ "ὑ","͂" }, - ["Ὑ"]={ "Υ","̔" }, - ["Ὓ"]={ "Ὑ","̀" }, - ["Ὕ"]={ "Ὑ","́" }, - ["Ὗ"]={ "Ὑ","͂" }, - ["ὠ"]={ "ω","̓" }, - ["ὡ"]={ "ω","̔" }, - ["ὢ"]={ "ὠ","̀" }, - ["ὣ"]={ "ὡ","̀" }, - ["ὤ"]={ "ὠ","́" }, - ["ὥ"]={ "ὡ","́" }, - ["ὦ"]={ "ὠ","͂" }, - ["ὧ"]={ "ὡ","͂" }, - ["Ὠ"]={ "Ω","̓" }, - ["Ὡ"]={ "Ω","̔" }, - ["Ὢ"]={ "Ὠ","̀" }, - ["Ὣ"]={ "Ὡ","̀" }, - ["Ὤ"]={ "Ὠ","́" }, - ["Ὥ"]={ "Ὡ","́" }, - ["Ὦ"]={ "Ὠ","͂" }, - ["Ὧ"]={ "Ὡ","͂" }, - ["ὰ"]={ "α","̀" }, - ["ὲ"]={ "ε","̀" }, - ["ὴ"]={ "η","̀" }, - ["ὶ"]={ "ι","̀" }, - ["ὸ"]={ "ο","̀" }, - ["ὺ"]={ "υ","̀" }, - ["ὼ"]={ "ω","̀" }, - ["ᾀ"]={ "ἀ","ͅ" }, - ["ᾁ"]={ "ἁ","ͅ" }, - ["ᾂ"]={ "ἂ","ͅ" }, - ["ᾃ"]={ "ἃ","ͅ" }, - ["ᾄ"]={ "ἄ","ͅ" }, - ["ᾅ"]={ "ἅ","ͅ" }, - ["ᾆ"]={ "ἆ","ͅ" }, - ["ᾇ"]={ "ἇ","ͅ" }, - ["ᾈ"]={ "Ἀ","ͅ" }, - ["ᾉ"]={ "Ἁ","ͅ" }, - ["ᾊ"]={ "Ἂ","ͅ" }, - ["ᾋ"]={ "Ἃ","ͅ" }, - ["ᾌ"]={ "Ἄ","ͅ" }, - ["ᾍ"]={ "Ἅ","ͅ" }, - ["ᾎ"]={ "Ἆ","ͅ" }, - ["ᾏ"]={ "Ἇ","ͅ" }, - ["ᾐ"]={ "ἠ","ͅ" }, - ["ᾑ"]={ "ἡ","ͅ" }, - ["ᾒ"]={ "ἢ","ͅ" }, - ["ᾓ"]={ "ἣ","ͅ" }, - ["ᾔ"]={ "ἤ","ͅ" }, - ["ᾕ"]={ "ἥ","ͅ" }, - ["ᾖ"]={ "ἦ","ͅ" }, - ["ᾗ"]={ "ἧ","ͅ" }, - ["ᾘ"]={ "Ἠ","ͅ" }, - ["ᾙ"]={ "Ἡ","ͅ" }, - ["ᾚ"]={ "Ἢ","ͅ" }, - ["ᾛ"]={ "Ἣ","ͅ" }, - ["ᾜ"]={ "Ἤ","ͅ" }, - ["ᾝ"]={ "Ἥ","ͅ" }, - ["ᾞ"]={ "Ἦ","ͅ" }, - ["ᾟ"]={ "Ἧ","ͅ" }, - ["ᾠ"]={ "ὠ","ͅ" }, - ["ᾡ"]={ "ὡ","ͅ" }, - ["ᾢ"]={ "ὢ","ͅ" }, - ["ᾣ"]={ "ὣ","ͅ" }, - ["ᾤ"]={ "ὤ","ͅ" }, - ["ᾥ"]={ "ὥ","ͅ" }, - ["ᾦ"]={ "ὦ","ͅ" }, - ["ᾧ"]={ "ὧ","ͅ" }, - ["ᾨ"]={ "Ὠ","ͅ" }, - ["ᾩ"]={ "Ὡ","ͅ" }, - ["ᾪ"]={ "Ὢ","ͅ" }, - ["ᾫ"]={ "Ὣ","ͅ" }, - ["ᾬ"]={ "Ὤ","ͅ" }, - ["ᾭ"]={ "Ὥ","ͅ" }, - ["ᾮ"]={ "Ὦ","ͅ" }, - ["ᾯ"]={ "Ὧ","ͅ" }, - ["ᾰ"]={ "α","̆" }, - ["ᾱ"]={ "α","̄" }, - ["ᾲ"]={ "ὰ","ͅ" }, - ["ᾳ"]={ "α","ͅ" }, - ["ᾴ"]={ "ά","ͅ" }, - ["ᾶ"]={ "α","͂" }, - ["ᾷ"]={ "ᾶ","ͅ" }, - ["Ᾰ"]={ "Α","̆" }, - ["Ᾱ"]={ "Α","̄" }, - ["Ὰ"]={ "Α","̀" }, - ["ᾼ"]={ "Α","ͅ" }, - ["῁"]={ "¨","͂" }, - ["ῂ"]={ "ὴ","ͅ" }, - ["ῃ"]={ "η","ͅ" }, - ["ῄ"]={ "ή","ͅ" }, - ["ῆ"]={ "η","͂" }, - ["ῇ"]={ "ῆ","ͅ" }, - ["Ὲ"]={ "Ε","̀" }, - ["Ὴ"]={ "Η","̀" }, - ["ῌ"]={ "Η","ͅ" }, - ["῍"]={ "᾿","̀" }, - ["῎"]={ "᾿","́" }, - ["῏"]={ "᾿","͂" }, - ["ῐ"]={ "ι","̆" }, - ["ῑ"]={ "ι","̄" }, - ["ῒ"]={ "ϊ","̀" }, - ["ῖ"]={ "ι","͂" }, - ["ῗ"]={ "ϊ","͂" }, - ["Ῐ"]={ "Ι","̆" }, - ["Ῑ"]={ "Ι","̄" }, - ["Ὶ"]={ "Ι","̀" }, - ["῝"]={ "῾","̀" }, - ["῞"]={ "῾","́" }, - ["῟"]={ "῾","͂" }, - ["ῠ"]={ "υ","̆" }, - ["ῡ"]={ "υ","̄" }, - ["ῢ"]={ "ϋ","̀" }, - ["ῤ"]={ "ρ","̓" }, - ["ῥ"]={ "ρ","̔" }, - ["ῦ"]={ "υ","͂" }, - ["ῧ"]={ "ϋ","͂" }, - ["Ῠ"]={ "Υ","̆" }, - ["Ῡ"]={ "Υ","̄" }, - ["Ὺ"]={ "Υ","̀" }, - ["Ῥ"]={ "Ρ","̔" }, - ["῭"]={ "¨","̀" }, - ["ῲ"]={ "ὼ","ͅ" }, - ["ῳ"]={ "ω","ͅ" }, - ["ῴ"]={ "ώ","ͅ" }, - ["ῶ"]={ "ω","͂" }, - ["ῷ"]={ "ῶ","ͅ" }, - ["Ὸ"]={ "Ο","̀" }, - ["Ὼ"]={ "Ω","̀" }, - ["ῼ"]={ "Ω","ͅ" }, - ["↚"]={ "←","̸" }, - ["↛"]={ "→","̸" }, - ["↮"]={ "↔","̸" }, - ["⇍"]={ "⇐","̸" }, - ["⇎"]={ "⇔","̸" }, - ["⇏"]={ "⇒","̸" }, - ["∄"]={ "∃","̸" }, - ["∉"]={ "∈","̸" }, - ["∌"]={ "∋","̸" }, - ["∤"]={ "∣","̸" }, - ["∦"]={ "∥","̸" }, - ["≁"]={ "∼","̸" }, - ["≄"]={ "≃","̸" }, - ["≇"]={ "≅","̸" }, - ["≉"]={ "≈","̸" }, - ["≠"]={ "=","̸" }, - ["≢"]={ "≡","̸" }, - ["≭"]={ "≍","̸" }, - ["≮"]={ "<","̸" }, - ["≯"]={ ">","̸" }, - ["≰"]={ "≤","̸" }, - ["≱"]={ "≥","̸" }, - ["≴"]={ "≲","̸" }, - ["≵"]={ "≳","̸" }, - ["≸"]={ "≶","̸" }, - ["≹"]={ "≷","̸" }, - ["⊀"]={ "≺","̸" }, - ["⊁"]={ "≻","̸" }, - ["⊄"]={ "⊂","̸" }, - ["⊅"]={ "⊃","̸" }, - ["⊈"]={ "⊆","̸" }, - ["⊉"]={ "⊇","̸" }, - ["⊬"]={ "⊢","̸" }, - ["⊭"]={ "⊨","̸" }, - ["⊮"]={ "⊩","̸" }, - ["⊯"]={ "⊫","̸" }, - ["⋠"]={ "≼","̸" }, - ["⋡"]={ "≽","̸" }, - ["⋢"]={ "⊑","̸" }, - ["⋣"]={ "⊒","̸" }, - ["⋪"]={ "⊲","̸" }, - ["⋫"]={ "⊳","̸" }, - ["⋬"]={ "⊴","̸" }, - ["⋭"]={ "⊵","̸" }, - ["⫝̸"]={ "⫝","̸" }, - ["が"]={ "か","゙" }, - ["ぎ"]={ "き","゙" }, - ["ぐ"]={ "く","゙" }, - ["げ"]={ "け","゙" }, - ["ご"]={ "こ","゙" }, - ["ざ"]={ "さ","゙" }, - ["じ"]={ "し","゙" }, - ["ず"]={ "す","゙" }, - ["ぜ"]={ "せ","゙" }, - ["ぞ"]={ "そ","゙" }, - ["だ"]={ "た","゙" }, - ["ぢ"]={ "ち","゙" }, - ["づ"]={ "つ","゙" }, - ["で"]={ "て","゙" }, - ["ど"]={ "と","゙" }, - ["ば"]={ "は","゙" }, - ["ぱ"]={ "は","゚" }, - ["び"]={ "ひ","゙" }, - ["ぴ"]={ "ひ","゚" }, - ["ぶ"]={ "ふ","゙" }, - ["ぷ"]={ "ふ","゚" }, - ["べ"]={ "へ","゙" }, - ["ぺ"]={ "へ","゚" }, - ["ぼ"]={ "ほ","゙" }, - ["ぽ"]={ "ほ","゚" }, - ["ゔ"]={ "う","゙" }, - ["ゞ"]={ "ゝ","゙" }, - ["ガ"]={ "カ","゙" }, - ["ギ"]={ "キ","゙" }, - ["グ"]={ "ク","゙" }, - ["ゲ"]={ "ケ","゙" }, - ["ゴ"]={ "コ","゙" }, - ["ザ"]={ "サ","゙" }, - ["ジ"]={ "シ","゙" }, - ["ズ"]={ "ス","゙" }, - ["ゼ"]={ "セ","゙" }, - ["ゾ"]={ "ソ","゙" }, - ["ダ"]={ "タ","゙" }, - ["ヂ"]={ "チ","゙" }, - ["ヅ"]={ "ツ","゙" }, - ["デ"]={ "テ","゙" }, - ["ド"]={ "ト","゙" }, - ["バ"]={ "ハ","゙" }, - ["パ"]={ "ハ","゚" }, - ["ビ"]={ "ヒ","゙" }, - ["ピ"]={ "ヒ","゚" }, - ["ブ"]={ "フ","゙" }, - ["プ"]={ "フ","゚" }, - ["ベ"]={ "ヘ","゙" }, - ["ペ"]={ "ヘ","゚" }, - ["ボ"]={ "ホ","゙" }, - ["ポ"]={ "ホ","゚" }, - ["ヴ"]={ "ウ","゙" }, - ["ヷ"]={ "ワ","゙" }, - ["ヸ"]={ "ヰ","゙" }, - ["ヹ"]={ "ヱ","゙" }, - ["ヺ"]={ "ヲ","゙" }, - ["ヾ"]={ "ヽ","゙" }, - ["יִ"]={ "י","ִ" }, - ["ײַ"]={ "ײ","ַ" }, - ["שׁ"]={ "ש","ׁ" }, - ["שׂ"]={ "ש","ׂ" }, - ["שּׁ"]={ "שּ","ׁ" }, - ["שּׂ"]={ "שּ","ׂ" }, - ["אַ"]={ "א","ַ" }, - ["אָ"]={ "א","ָ" }, - ["אּ"]={ "א","ּ" }, - ["בּ"]={ "ב","ּ" }, - ["גּ"]={ "ג","ּ" }, - ["דּ"]={ "ד","ּ" }, - ["הּ"]={ "ה","ּ" }, - ["וּ"]={ "ו","ּ" }, - ["זּ"]={ "ז","ּ" }, - ["טּ"]={ "ט","ּ" }, - ["יּ"]={ "י","ּ" }, - ["ךּ"]={ "ך","ּ" }, - ["כּ"]={ "כ","ּ" }, - ["לּ"]={ "ל","ּ" }, - ["מּ"]={ "מ","ּ" }, - ["נּ"]={ "נ","ּ" }, - ["סּ"]={ "ס","ּ" }, - ["ףּ"]={ "ף","ּ" }, - ["פּ"]={ "פ","ּ" }, - ["צּ"]={ "צ","ּ" }, - ["קּ"]={ "ק","ּ" }, - ["רּ"]={ "ר","ּ" }, - ["שּ"]={ "ש","ּ" }, - ["תּ"]={ "ת","ּ" }, - ["וֹ"]={ "ו","ֹ" }, - ["בֿ"]={ "ב","ֿ" }, - ["כֿ"]={ "כ","ֿ" }, - ["פֿ"]={ "פ","ֿ" }, - ["𑂚"]={ "𑂙","𑂺" }, - ["𑂜"]={ "𑂛","𑂺" }, - ["𑂫"]={ "𑂥","𑂺" }, - ["𑄮"]={ "𑄱","𑄧" }, - ["𑄯"]={ "𑄲","𑄧" }, - ["𑍋"]={ "𑍇","𑌾" }, - ["𑍌"]={ "𑍇","𑍗" }, - ["𑒻"]={ "𑒹","𑒺" }, - ["𑒼"]={ "𑒹","𑒰" }, - ["𑒾"]={ "𑒹","𑒽" }, - ["𑖺"]={ "𑖸","𑖯" }, - ["𑖻"]={ "𑖹","𑖯" }, - ["𝅗𝅥"]={ "𝅗","𝅥" }, - ["𝅘𝅥"]={ "𝅘","𝅥" }, - ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" }, - ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" }, - ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" }, - ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" }, - ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" }, - ["𝆹𝅥"]={ "𝆹","𝅥" }, - ["𝆺𝅥"]={ "𝆺","𝅥" }, - ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" }, - ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" }, - ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" }, - ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" }, - }, - }, - { - ["data"]={ - ["À"]={ "A","̀" }, - ["Á"]={ "A","́" }, - ["Â"]={ "A","̂" }, - ["Ã"]={ "A","̃" }, - ["Ä"]={ "A","̈" }, - ["Å"]={ "A","̊" }, - ["Ç"]={ "C","̧" }, - ["È"]={ "E","̀" }, - ["É"]={ "E","́" }, - ["Ê"]={ "E","̂" }, - ["Ë"]={ "E","̈" }, - ["Ì"]={ "I","̀" }, - ["Í"]={ "I","́" }, - ["Î"]={ "I","̂" }, - ["Ï"]={ "I","̈" }, - ["Ñ"]={ "N","̃" }, - ["Ò"]={ "O","̀" }, - ["Ó"]={ "O","́" }, - ["Ô"]={ "O","̂" }, - ["Õ"]={ "O","̃" }, - ["Ö"]={ "O","̈" }, - ["Ù"]={ "U","̀" }, - ["Ú"]={ "U","́" }, - ["Û"]={ "U","̂" }, - ["Ü"]={ "U","̈" }, - ["Ý"]={ "Y","́" }, - ["à"]={ "a","̀" }, - ["á"]={ "a","́" }, - ["â"]={ "a","̂" }, - ["ã"]={ "a","̃" }, - ["ä"]={ "a","̈" }, - ["å"]={ "a","̊" }, - ["ç"]={ "c","̧" }, - ["è"]={ "e","̀" }, - ["é"]={ "e","́" }, - ["ê"]={ "e","̂" }, - ["ë"]={ "e","̈" }, - ["ì"]={ "i","̀" }, - ["í"]={ "i","́" }, - ["î"]={ "i","̂" }, - ["ï"]={ "i","̈" }, - ["ñ"]={ "n","̃" }, - ["ò"]={ "o","̀" }, - ["ó"]={ "o","́" }, - ["ô"]={ "o","̂" }, - ["õ"]={ "o","̃" }, - ["ö"]={ "o","̈" }, - ["ù"]={ "u","̀" }, - ["ú"]={ "u","́" }, - ["û"]={ "u","̂" }, - ["ü"]={ "u","̈" }, - ["ý"]={ "y","́" }, - ["ÿ"]={ "y","̈" }, - ["Ā"]={ "A","̄" }, - ["ā"]={ "a","̄" }, - ["Ă"]={ "A","̆" }, - ["ă"]={ "a","̆" }, - ["Ą"]={ "A","̨" }, - ["ą"]={ "a","̨" }, - ["Ć"]={ "C","́" }, - ["ć"]={ "c","́" }, - ["Ĉ"]={ "C","̂" }, - ["ĉ"]={ "c","̂" }, - ["Ċ"]={ "C","̇" }, - ["ċ"]={ "c","̇" }, - ["Č"]={ "C","̌" }, - ["č"]={ "c","̌" }, - ["Ď"]={ "D","̌" }, - ["ď"]={ "d","̌" }, - ["Ē"]={ "E","̄" }, - ["ē"]={ "e","̄" }, - ["Ĕ"]={ "E","̆" }, - ["ĕ"]={ "e","̆" }, - ["Ė"]={ "E","̇" }, - ["ė"]={ "e","̇" }, - ["Ę"]={ "E","̨" }, - ["ę"]={ "e","̨" }, - ["Ě"]={ "E","̌" }, - ["ě"]={ "e","̌" }, - ["Ĝ"]={ "G","̂" }, - ["ĝ"]={ "g","̂" }, - ["Ğ"]={ "G","̆" }, - ["ğ"]={ "g","̆" }, - ["Ġ"]={ "G","̇" }, - ["ġ"]={ "g","̇" }, - ["Ģ"]={ "G","̧" }, - ["ģ"]={ "g","̧" }, - ["Ĥ"]={ "H","̂" }, - ["ĥ"]={ "h","̂" }, - ["Ĩ"]={ "I","̃" }, - ["ĩ"]={ "i","̃" }, - ["Ī"]={ "I","̄" }, - ["ī"]={ "i","̄" }, - ["Ĭ"]={ "I","̆" }, - ["ĭ"]={ "i","̆" }, - ["Į"]={ "I","̨" }, - ["į"]={ "i","̨" }, - ["İ"]={ "I","̇" }, - ["Ĵ"]={ "J","̂" }, - ["ĵ"]={ "j","̂" }, - ["Ķ"]={ "K","̧" }, - ["ķ"]={ "k","̧" }, - ["Ĺ"]={ "L","́" }, - ["ĺ"]={ "l","́" }, - ["Ļ"]={ "L","̧" }, - ["ļ"]={ "l","̧" }, - ["Ľ"]={ "L","̌" }, - ["ľ"]={ "l","̌" }, - ["Ń"]={ "N","́" }, - ["ń"]={ "n","́" }, - ["Ņ"]={ "N","̧" }, - ["ņ"]={ "n","̧" }, - ["Ň"]={ "N","̌" }, - ["ň"]={ "n","̌" }, - ["Ō"]={ "O","̄" }, - ["ō"]={ "o","̄" }, - ["Ŏ"]={ "O","̆" }, - ["ŏ"]={ "o","̆" }, - ["Ő"]={ "O","̋" }, - ["ő"]={ "o","̋" }, - ["Ŕ"]={ "R","́" }, - ["ŕ"]={ "r","́" }, - ["Ŗ"]={ "R","̧" }, - ["ŗ"]={ "r","̧" }, - ["Ř"]={ "R","̌" }, - ["ř"]={ "r","̌" }, - ["Ś"]={ "S","́" }, - ["ś"]={ "s","́" }, - ["Ŝ"]={ "S","̂" }, - ["ŝ"]={ "s","̂" }, - ["Ş"]={ "S","̧" }, - ["ş"]={ "s","̧" }, - ["Š"]={ "S","̌" }, - ["š"]={ "s","̌" }, - ["Ţ"]={ "T","̧" }, - ["ţ"]={ "t","̧" }, - ["Ť"]={ "T","̌" }, - ["ť"]={ "t","̌" }, - ["Ũ"]={ "U","̃" }, - ["ũ"]={ "u","̃" }, - ["Ū"]={ "U","̄" }, - ["ū"]={ "u","̄" }, - ["Ŭ"]={ "U","̆" }, - ["ŭ"]={ "u","̆" }, - ["Ů"]={ "U","̊" }, - ["ů"]={ "u","̊" }, - ["Ű"]={ "U","̋" }, - ["ű"]={ "u","̋" }, - ["Ų"]={ "U","̨" }, - ["ų"]={ "u","̨" }, - ["Ŵ"]={ "W","̂" }, - ["ŵ"]={ "w","̂" }, - ["Ŷ"]={ "Y","̂" }, - ["ŷ"]={ "y","̂" }, - ["Ÿ"]={ "Y","̈" }, - ["Ź"]={ "Z","́" }, - ["ź"]={ "z","́" }, - ["Ż"]={ "Z","̇" }, - ["ż"]={ "z","̇" }, - ["Ž"]={ "Z","̌" }, - ["ž"]={ "z","̌" }, - ["Ơ"]={ "O","̛" }, - ["ơ"]={ "o","̛" }, - ["Ư"]={ "U","̛" }, - ["ư"]={ "u","̛" }, - ["Ǎ"]={ "A","̌" }, - ["ǎ"]={ "a","̌" }, - ["Ǐ"]={ "I","̌" }, - ["ǐ"]={ "i","̌" }, - ["Ǒ"]={ "O","̌" }, - ["ǒ"]={ "o","̌" }, - ["Ǔ"]={ "U","̌" }, - ["ǔ"]={ "u","̌" }, - ["Ǖ"]={ "Ü","̄" }, - ["ǖ"]={ "ü","̄" }, - ["Ǘ"]={ "Ü","́" }, - ["ǘ"]={ "ü","́" }, - ["Ǚ"]={ "Ü","̌" }, - ["ǚ"]={ "ü","̌" }, - ["Ǜ"]={ "Ü","̀" }, - ["ǜ"]={ "ü","̀" }, - ["Ǟ"]={ "Ä","̄" }, - ["ǟ"]={ "ä","̄" }, - ["Ǡ"]={ "Ȧ","̄" }, - ["ǡ"]={ "ȧ","̄" }, - ["Ǣ"]={ "Æ","̄" }, - ["ǣ"]={ "æ","̄" }, - ["Ǧ"]={ "G","̌" }, - ["ǧ"]={ "g","̌" }, - ["Ǩ"]={ "K","̌" }, - ["ǩ"]={ "k","̌" }, - ["Ǫ"]={ "O","̨" }, - ["ǫ"]={ "o","̨" }, - ["Ǭ"]={ "Ǫ","̄" }, - ["ǭ"]={ "ǫ","̄" }, - ["Ǯ"]={ "Ʒ","̌" }, - ["ǯ"]={ "ʒ","̌" }, - ["ǰ"]={ "j","̌" }, - ["Ǵ"]={ "G","́" }, - ["ǵ"]={ "g","́" }, - ["Ǹ"]={ "N","̀" }, - ["ǹ"]={ "n","̀" }, - ["Ǻ"]={ "Å","́" }, - ["ǻ"]={ "å","́" }, - ["Ǽ"]={ "Æ","́" }, - ["ǽ"]={ "æ","́" }, - ["Ǿ"]={ "Ø","́" }, - ["ǿ"]={ "ø","́" }, - ["Ȁ"]={ "A","̏" }, - ["ȁ"]={ "a","̏" }, - ["Ȃ"]={ "A","̑" }, - ["ȃ"]={ "a","̑" }, - ["Ȅ"]={ "E","̏" }, - ["ȅ"]={ "e","̏" }, - ["Ȇ"]={ "E","̑" }, - ["ȇ"]={ "e","̑" }, - ["Ȉ"]={ "I","̏" }, - ["ȉ"]={ "i","̏" }, - ["Ȋ"]={ "I","̑" }, - ["ȋ"]={ "i","̑" }, - ["Ȍ"]={ "O","̏" }, - ["ȍ"]={ "o","̏" }, - ["Ȏ"]={ "O","̑" }, - ["ȏ"]={ "o","̑" }, - ["Ȑ"]={ "R","̏" }, - ["ȑ"]={ "r","̏" }, - ["Ȓ"]={ "R","̑" }, - ["ȓ"]={ "r","̑" }, - ["Ȕ"]={ "U","̏" }, - ["ȕ"]={ "u","̏" }, - ["Ȗ"]={ "U","̑" }, - ["ȗ"]={ "u","̑" }, - ["Ș"]={ "S","̦" }, - ["ș"]={ "s","̦" }, - ["Ț"]={ "T","̦" }, - ["ț"]={ "t","̦" }, - ["Ȟ"]={ "H","̌" }, - ["ȟ"]={ "h","̌" }, - ["Ȧ"]={ "A","̇" }, - ["ȧ"]={ "a","̇" }, - ["Ȩ"]={ "E","̧" }, - ["ȩ"]={ "e","̧" }, - ["Ȫ"]={ "Ö","̄" }, - ["ȫ"]={ "ö","̄" }, - ["Ȭ"]={ "Õ","̄" }, - ["ȭ"]={ "õ","̄" }, - ["Ȯ"]={ "O","̇" }, - ["ȯ"]={ "o","̇" }, - ["Ȱ"]={ "Ȯ","̄" }, - ["ȱ"]={ "ȯ","̄" }, - ["Ȳ"]={ "Y","̄" }, - ["ȳ"]={ "y","̄" }, - ["̈́"]={ "̈","́" }, - ["΅"]={ "¨","́" }, - ["Ά"]={ "Α","́" }, - ["Έ"]={ "Ε","́" }, - ["Ή"]={ "Η","́" }, - ["Ί"]={ "Ι","́" }, - ["Ό"]={ "Ο","́" }, - ["Ύ"]={ "Υ","́" }, - ["Ώ"]={ "Ω","́" }, - ["ΐ"]={ "ϊ","́" }, - ["Ϊ"]={ "Ι","̈" }, - ["Ϋ"]={ "Υ","̈" }, - ["ά"]={ "α","́" }, - ["έ"]={ "ε","́" }, - ["ή"]={ "η","́" }, - ["ί"]={ "ι","́" }, - ["ΰ"]={ "ϋ","́" }, - ["ϊ"]={ "ι","̈" }, - ["ϋ"]={ "υ","̈" }, - ["ό"]={ "ο","́" }, - ["ύ"]={ "υ","́" }, - ["ώ"]={ "ω","́" }, - ["ϓ"]={ "ϒ","́" }, - ["ϔ"]={ "ϒ","̈" }, - ["Ѐ"]={ "Е","̀" }, - ["Ё"]={ "Е","̈" }, - ["Ѓ"]={ "Г","́" }, - ["Ї"]={ "І","̈" }, - ["Ќ"]={ "К","́" }, - ["Ѝ"]={ "И","̀" }, - ["Ў"]={ "У","̆" }, - ["Й"]={ "И","̆" }, - ["й"]={ "и","̆" }, - ["ѐ"]={ "е","̀" }, - ["ё"]={ "е","̈" }, - ["ѓ"]={ "г","́" }, - ["ї"]={ "і","̈" }, - ["ќ"]={ "к","́" }, - ["ѝ"]={ "и","̀" }, - ["ў"]={ "у","̆" }, - ["Ѷ"]={ "Ѵ","̏" }, - ["ѷ"]={ "ѵ","̏" }, - ["Ӂ"]={ "Ж","̆" }, - ["ӂ"]={ "ж","̆" }, - ["Ӑ"]={ "А","̆" }, - ["ӑ"]={ "а","̆" }, - ["Ӓ"]={ "А","̈" }, - ["ӓ"]={ "а","̈" }, - ["Ӗ"]={ "Е","̆" }, - ["ӗ"]={ "е","̆" }, - ["Ӛ"]={ "Ә","̈" }, - ["ӛ"]={ "ә","̈" }, - ["Ӝ"]={ "Ж","̈" }, - ["ӝ"]={ "ж","̈" }, - ["Ӟ"]={ "З","̈" }, - ["ӟ"]={ "з","̈" }, - ["Ӣ"]={ "И","̄" }, - ["ӣ"]={ "и","̄" }, - ["Ӥ"]={ "И","̈" }, - ["ӥ"]={ "и","̈" }, - ["Ӧ"]={ "О","̈" }, - ["ӧ"]={ "о","̈" }, - ["Ӫ"]={ "Ө","̈" }, - ["ӫ"]={ "ө","̈" }, - ["Ӭ"]={ "Э","̈" }, - ["ӭ"]={ "э","̈" }, - ["Ӯ"]={ "У","̄" }, - ["ӯ"]={ "у","̄" }, - ["Ӱ"]={ "У","̈" }, - ["ӱ"]={ "у","̈" }, - ["Ӳ"]={ "У","̋" }, - ["ӳ"]={ "у","̋" }, - ["Ӵ"]={ "Ч","̈" }, - ["ӵ"]={ "ч","̈" }, - ["Ӹ"]={ "Ы","̈" }, - ["ӹ"]={ "ы","̈" }, - ["آ"]={ "ا","ٓ" }, - ["أ"]={ "ا","ٔ" }, - ["ؤ"]={ "و","ٔ" }, - ["إ"]={ "ا","ٕ" }, - ["ئ"]={ "ي","ٔ" }, - ["ۀ"]={ "ە","ٔ" }, - ["ۂ"]={ "ہ","ٔ" }, - ["ۓ"]={ "ے","ٔ" }, - ["ऩ"]={ "न","़" }, - ["ऱ"]={ "र","़" }, - ["ऴ"]={ "ळ","़" }, - ["क़"]={ "क","़" }, - ["ख़"]={ "ख","़" }, - ["ग़"]={ "ग","़" }, - ["ज़"]={ "ज","़" }, - ["ड़"]={ "ड","़" }, - ["ढ़"]={ "ढ","़" }, - ["फ़"]={ "फ","़" }, - ["य़"]={ "य","़" }, - ["ো"]={ "ে","া" }, - ["ৌ"]={ "ে","ৗ" }, - ["ড়"]={ "ড","়" }, - ["ঢ়"]={ "ঢ","়" }, - ["য়"]={ "য","়" }, - ["ਲ਼"]={ "ਲ","਼" }, - ["ਸ਼"]={ "ਸ","਼" }, - ["ਖ਼"]={ "ਖ","਼" }, - ["ਗ਼"]={ "ਗ","਼" }, - ["ਜ਼"]={ "ਜ","਼" }, - ["ਫ਼"]={ "ਫ","਼" }, - ["ୈ"]={ "େ","ୖ" }, - ["ୋ"]={ "େ","ା" }, - ["ୌ"]={ "େ","ୗ" }, - ["ଡ଼"]={ "ଡ","଼" }, - ["ଢ଼"]={ "ଢ","଼" }, - ["ஔ"]={ "ஒ","ௗ" }, - ["ொ"]={ "ெ","ா" }, - ["ோ"]={ "ே","ா" }, - ["ௌ"]={ "ெ","ௗ" }, - ["ై"]={ "ె","ౖ" }, - ["ೀ"]={ "ಿ","ೕ" }, - ["ೇ"]={ "ೆ","ೕ" }, - ["ೈ"]={ "ೆ","ೖ" }, - ["ೊ"]={ "ೆ","ೂ" }, - ["ೋ"]={ "ೊ","ೕ" }, - ["ൊ"]={ "െ","ാ" }, - ["ോ"]={ "േ","ാ" }, - ["ൌ"]={ "െ","ൗ" }, - ["ේ"]={ "ෙ","්" }, - ["ො"]={ "ෙ","ා" }, - ["ෝ"]={ "ො","්" }, - ["ෞ"]={ "ෙ","ෟ" }, - ["གྷ"]={ "ག","ྷ" }, - ["ཌྷ"]={ "ཌ","ྷ" }, - ["དྷ"]={ "ད","ྷ" }, - ["བྷ"]={ "བ","ྷ" }, - ["ཛྷ"]={ "ཛ","ྷ" }, - ["ཀྵ"]={ "ཀ","ྵ" }, - ["ཱི"]={ "ཱ","ི" }, - ["ཱུ"]={ "ཱ","ུ" }, - ["ྲྀ"]={ "ྲ","ྀ" }, - ["ླྀ"]={ "ླ","ྀ" }, - ["ཱྀ"]={ "ཱ","ྀ" }, - ["ྒྷ"]={ "ྒ","ྷ" }, - ["ྜྷ"]={ "ྜ","ྷ" }, - ["ྡྷ"]={ "ྡ","ྷ" }, - ["ྦྷ"]={ "ྦ","ྷ" }, - ["ྫྷ"]={ "ྫ","ྷ" }, - ["ྐྵ"]={ "ྐ","ྵ" }, - ["ဦ"]={ "ဥ","ီ" }, - ["ᬆ"]={ "ᬅ","ᬵ" }, - ["ᬈ"]={ "ᬇ","ᬵ" }, - ["ᬊ"]={ "ᬉ","ᬵ" }, - ["ᬌ"]={ "ᬋ","ᬵ" }, - ["ᬎ"]={ "ᬍ","ᬵ" }, - ["ᬒ"]={ "ᬑ","ᬵ" }, - ["ᬻ"]={ "ᬺ","ᬵ" }, - ["ᬽ"]={ "ᬼ","ᬵ" }, - ["ᭀ"]={ "ᬾ","ᬵ" }, - ["ᭁ"]={ "ᬿ","ᬵ" }, - ["ᭃ"]={ "ᭂ","ᬵ" }, - ["Ḁ"]={ "A","̥" }, - ["ḁ"]={ "a","̥" }, - ["Ḃ"]={ "B","̇" }, - ["ḃ"]={ "b","̇" }, - ["Ḅ"]={ "B","̣" }, - ["ḅ"]={ "b","̣" }, - ["Ḇ"]={ "B","̱" }, - ["ḇ"]={ "b","̱" }, - ["Ḉ"]={ "Ç","́" }, - ["ḉ"]={ "ç","́" }, - ["Ḋ"]={ "D","̇" }, - ["ḋ"]={ "d","̇" }, - ["Ḍ"]={ "D","̣" }, - ["ḍ"]={ "d","̣" }, - ["Ḏ"]={ "D","̱" }, - ["ḏ"]={ "d","̱" }, - ["Ḑ"]={ "D","̧" }, - ["ḑ"]={ "d","̧" }, - ["Ḓ"]={ "D","̭" }, - ["ḓ"]={ "d","̭" }, - ["Ḕ"]={ "Ē","̀" }, - ["ḕ"]={ "ē","̀" }, - ["Ḗ"]={ "Ē","́" }, - ["ḗ"]={ "ē","́" }, - ["Ḙ"]={ "E","̭" }, - ["ḙ"]={ "e","̭" }, - ["Ḛ"]={ "E","̰" }, - ["ḛ"]={ "e","̰" }, - ["Ḝ"]={ "Ȩ","̆" }, - ["ḝ"]={ "ȩ","̆" }, - ["Ḟ"]={ "F","̇" }, - ["ḟ"]={ "f","̇" }, - ["Ḡ"]={ "G","̄" }, - ["ḡ"]={ "g","̄" }, - ["Ḣ"]={ "H","̇" }, - ["ḣ"]={ "h","̇" }, - ["Ḥ"]={ "H","̣" }, - ["ḥ"]={ "h","̣" }, - ["Ḧ"]={ "H","̈" }, - ["ḧ"]={ "h","̈" }, - ["Ḩ"]={ "H","̧" }, - ["ḩ"]={ "h","̧" }, - ["Ḫ"]={ "H","̮" }, - ["ḫ"]={ "h","̮" }, - ["Ḭ"]={ "I","̰" }, - ["ḭ"]={ "i","̰" }, - ["Ḯ"]={ "Ï","́" }, - ["ḯ"]={ "ï","́" }, - ["Ḱ"]={ "K","́" }, - ["ḱ"]={ "k","́" }, - ["Ḳ"]={ "K","̣" }, - ["ḳ"]={ "k","̣" }, - ["Ḵ"]={ "K","̱" }, - ["ḵ"]={ "k","̱" }, - ["Ḷ"]={ "L","̣" }, - ["ḷ"]={ "l","̣" }, - ["Ḹ"]={ "Ḷ","̄" }, - ["ḹ"]={ "ḷ","̄" }, - ["Ḻ"]={ "L","̱" }, - ["ḻ"]={ "l","̱" }, - ["Ḽ"]={ "L","̭" }, - ["ḽ"]={ "l","̭" }, - ["Ḿ"]={ "M","́" }, - ["ḿ"]={ "m","́" }, - ["Ṁ"]={ "M","̇" }, - ["ṁ"]={ "m","̇" }, - ["Ṃ"]={ "M","̣" }, - ["ṃ"]={ "m","̣" }, - ["Ṅ"]={ "N","̇" }, - ["ṅ"]={ "n","̇" }, - ["Ṇ"]={ "N","̣" }, - ["ṇ"]={ "n","̣" }, - ["Ṉ"]={ "N","̱" }, - ["ṉ"]={ "n","̱" }, - ["Ṋ"]={ "N","̭" }, - ["ṋ"]={ "n","̭" }, - ["Ṍ"]={ "Õ","́" }, - ["ṍ"]={ "õ","́" }, - ["Ṏ"]={ "Õ","̈" }, - ["ṏ"]={ "õ","̈" }, - ["Ṑ"]={ "Ō","̀" }, - ["ṑ"]={ "ō","̀" }, - ["Ṓ"]={ "Ō","́" }, - ["ṓ"]={ "ō","́" }, - ["Ṕ"]={ "P","́" }, - ["ṕ"]={ "p","́" }, - ["Ṗ"]={ "P","̇" }, - ["ṗ"]={ "p","̇" }, - ["Ṙ"]={ "R","̇" }, - ["ṙ"]={ "r","̇" }, - ["Ṛ"]={ "R","̣" }, - ["ṛ"]={ "r","̣" }, - ["Ṝ"]={ "Ṛ","̄" }, - ["ṝ"]={ "ṛ","̄" }, - ["Ṟ"]={ "R","̱" }, - ["ṟ"]={ "r","̱" }, - ["Ṡ"]={ "S","̇" }, - ["ṡ"]={ "s","̇" }, - ["Ṣ"]={ "S","̣" }, - ["ṣ"]={ "s","̣" }, - ["Ṥ"]={ "Ś","̇" }, - ["ṥ"]={ "ś","̇" }, - ["Ṧ"]={ "Š","̇" }, - ["ṧ"]={ "š","̇" }, - ["Ṩ"]={ "Ṣ","̇" }, - ["ṩ"]={ "ṣ","̇" }, - ["Ṫ"]={ "T","̇" }, - ["ṫ"]={ "t","̇" }, - ["Ṭ"]={ "T","̣" }, - ["ṭ"]={ "t","̣" }, - ["Ṯ"]={ "T","̱" }, - ["ṯ"]={ "t","̱" }, - ["Ṱ"]={ "T","̭" }, - ["ṱ"]={ "t","̭" }, - ["Ṳ"]={ "U","̤" }, - ["ṳ"]={ "u","̤" }, - ["Ṵ"]={ "U","̰" }, - ["ṵ"]={ "u","̰" }, - ["Ṷ"]={ "U","̭" }, - ["ṷ"]={ "u","̭" }, - ["Ṹ"]={ "Ũ","́" }, - ["ṹ"]={ "ũ","́" }, - ["Ṻ"]={ "Ū","̈" }, - ["ṻ"]={ "ū","̈" }, - ["Ṽ"]={ "V","̃" }, - ["ṽ"]={ "v","̃" }, - ["Ṿ"]={ "V","̣" }, - ["ṿ"]={ "v","̣" }, - ["Ẁ"]={ "W","̀" }, - ["ẁ"]={ "w","̀" }, - ["Ẃ"]={ "W","́" }, - ["ẃ"]={ "w","́" }, - ["Ẅ"]={ "W","̈" }, - ["ẅ"]={ "w","̈" }, - ["Ẇ"]={ "W","̇" }, - ["ẇ"]={ "w","̇" }, - ["Ẉ"]={ "W","̣" }, - ["ẉ"]={ "w","̣" }, - ["Ẋ"]={ "X","̇" }, - ["ẋ"]={ "x","̇" }, - ["Ẍ"]={ "X","̈" }, - ["ẍ"]={ "x","̈" }, - ["Ẏ"]={ "Y","̇" }, - ["ẏ"]={ "y","̇" }, - ["Ẑ"]={ "Z","̂" }, - ["ẑ"]={ "z","̂" }, - ["Ẓ"]={ "Z","̣" }, - ["ẓ"]={ "z","̣" }, - ["Ẕ"]={ "Z","̱" }, - ["ẕ"]={ "z","̱" }, - ["ẖ"]={ "h","̱" }, - ["ẗ"]={ "t","̈" }, - ["ẘ"]={ "w","̊" }, - ["ẙ"]={ "y","̊" }, - ["ẛ"]={ "ſ","̇" }, - ["Ạ"]={ "A","̣" }, - ["ạ"]={ "a","̣" }, - ["Ả"]={ "A","̉" }, - ["ả"]={ "a","̉" }, - ["Ấ"]={ "Â","́" }, - ["ấ"]={ "â","́" }, - ["Ầ"]={ "Â","̀" }, - ["ầ"]={ "â","̀" }, - ["Ẩ"]={ "Â","̉" }, - ["ẩ"]={ "â","̉" }, - ["Ẫ"]={ "Â","̃" }, - ["ẫ"]={ "â","̃" }, - ["Ậ"]={ "Ạ","̂" }, - ["ậ"]={ "ạ","̂" }, - ["Ắ"]={ "Ă","́" }, - ["ắ"]={ "ă","́" }, - ["Ằ"]={ "Ă","̀" }, - ["ằ"]={ "ă","̀" }, - ["Ẳ"]={ "Ă","̉" }, - ["ẳ"]={ "ă","̉" }, - ["Ẵ"]={ "Ă","̃" }, - ["ẵ"]={ "ă","̃" }, - ["Ặ"]={ "Ạ","̆" }, - ["ặ"]={ "ạ","̆" }, - ["Ẹ"]={ "E","̣" }, - ["ẹ"]={ "e","̣" }, - ["Ẻ"]={ "E","̉" }, - ["ẻ"]={ "e","̉" }, - ["Ẽ"]={ "E","̃" }, - ["ẽ"]={ "e","̃" }, - ["Ế"]={ "Ê","́" }, - ["ế"]={ "ê","́" }, - ["Ề"]={ "Ê","̀" }, - ["ề"]={ "ê","̀" }, - ["Ể"]={ "Ê","̉" }, - ["ể"]={ "ê","̉" }, - ["Ễ"]={ "Ê","̃" }, - ["ễ"]={ "ê","̃" }, - ["Ệ"]={ "Ẹ","̂" }, - ["ệ"]={ "ẹ","̂" }, - ["Ỉ"]={ "I","̉" }, - ["ỉ"]={ "i","̉" }, - ["Ị"]={ "I","̣" }, - ["ị"]={ "i","̣" }, - ["Ọ"]={ "O","̣" }, - ["ọ"]={ "o","̣" }, - ["Ỏ"]={ "O","̉" }, - ["ỏ"]={ "o","̉" }, - ["Ố"]={ "Ô","́" }, - ["ố"]={ "ô","́" }, - ["Ồ"]={ "Ô","̀" }, - ["ồ"]={ "ô","̀" }, - ["Ổ"]={ "Ô","̉" }, - ["ổ"]={ "ô","̉" }, - ["Ỗ"]={ "Ô","̃" }, - ["ỗ"]={ "ô","̃" }, - ["Ộ"]={ "Ọ","̂" }, - ["ộ"]={ "ọ","̂" }, - ["Ớ"]={ "Ơ","́" }, - ["ớ"]={ "ơ","́" }, - ["Ờ"]={ "Ơ","̀" }, - ["ờ"]={ "ơ","̀" }, - ["Ở"]={ "Ơ","̉" }, - ["ở"]={ "ơ","̉" }, - ["Ỡ"]={ "Ơ","̃" }, - ["ỡ"]={ "ơ","̃" }, - ["Ợ"]={ "Ơ","̣" }, - ["ợ"]={ "ơ","̣" }, - ["Ụ"]={ "U","̣" }, - ["ụ"]={ "u","̣" }, - ["Ủ"]={ "U","̉" }, - ["ủ"]={ "u","̉" }, - ["Ứ"]={ "Ư","́" }, - ["ứ"]={ "ư","́" }, - ["Ừ"]={ "Ư","̀" }, - ["ừ"]={ "ư","̀" }, - ["Ử"]={ "Ư","̉" }, - ["ử"]={ "ư","̉" }, - ["Ữ"]={ "Ư","̃" }, - ["ữ"]={ "ư","̃" }, - ["Ự"]={ "Ư","̣" }, - ["ự"]={ "ư","̣" }, - ["Ỳ"]={ "Y","̀" }, - ["ỳ"]={ "y","̀" }, - ["Ỵ"]={ "Y","̣" }, - ["ỵ"]={ "y","̣" }, - ["Ỷ"]={ "Y","̉" }, - ["ỷ"]={ "y","̉" }, - ["Ỹ"]={ "Y","̃" }, - ["ỹ"]={ "y","̃" }, - ["ἀ"]={ "α","̓" }, - ["ἁ"]={ "α","̔" }, - ["ἂ"]={ "ἀ","̀" }, - ["ἃ"]={ "ἁ","̀" }, - ["ἄ"]={ "ἀ","́" }, - ["ἅ"]={ "ἁ","́" }, - ["ἆ"]={ "ἀ","͂" }, - ["ἇ"]={ "ἁ","͂" }, - ["Ἀ"]={ "Α","̓" }, - ["Ἁ"]={ "Α","̔" }, - ["Ἂ"]={ "Ἀ","̀" }, - ["Ἃ"]={ "Ἁ","̀" }, - ["Ἄ"]={ "Ἀ","́" }, - ["Ἅ"]={ "Ἁ","́" }, - ["Ἆ"]={ "Ἀ","͂" }, - ["Ἇ"]={ "Ἁ","͂" }, - ["ἐ"]={ "ε","̓" }, - ["ἑ"]={ "ε","̔" }, - ["ἒ"]={ "ἐ","̀" }, - ["ἓ"]={ "ἑ","̀" }, - ["ἔ"]={ "ἐ","́" }, - ["ἕ"]={ "ἑ","́" }, - ["Ἐ"]={ "Ε","̓" }, - ["Ἑ"]={ "Ε","̔" }, - ["Ἒ"]={ "Ἐ","̀" }, - ["Ἓ"]={ "Ἑ","̀" }, - ["Ἔ"]={ "Ἐ","́" }, - ["Ἕ"]={ "Ἑ","́" }, - ["ἠ"]={ "η","̓" }, - ["ἡ"]={ "η","̔" }, - ["ἢ"]={ "ἠ","̀" }, - ["ἣ"]={ "ἡ","̀" }, - ["ἤ"]={ "ἠ","́" }, - ["ἥ"]={ "ἡ","́" }, - ["ἦ"]={ "ἠ","͂" }, - ["ἧ"]={ "ἡ","͂" }, - ["Ἠ"]={ "Η","̓" }, - ["Ἡ"]={ "Η","̔" }, - ["Ἢ"]={ "Ἠ","̀" }, - ["Ἣ"]={ "Ἡ","̀" }, - ["Ἤ"]={ "Ἠ","́" }, - ["Ἥ"]={ "Ἡ","́" }, - ["Ἦ"]={ "Ἠ","͂" }, - ["Ἧ"]={ "Ἡ","͂" }, - ["ἰ"]={ "ι","̓" }, - ["ἱ"]={ "ι","̔" }, - ["ἲ"]={ "ἰ","̀" }, - ["ἳ"]={ "ἱ","̀" }, - ["ἴ"]={ "ἰ","́" }, - ["ἵ"]={ "ἱ","́" }, - ["ἶ"]={ "ἰ","͂" }, - ["ἷ"]={ "ἱ","͂" }, - ["Ἰ"]={ "Ι","̓" }, - ["Ἱ"]={ "Ι","̔" }, - ["Ἲ"]={ "Ἰ","̀" }, - ["Ἳ"]={ "Ἱ","̀" }, - ["Ἴ"]={ "Ἰ","́" }, - ["Ἵ"]={ "Ἱ","́" }, - ["Ἶ"]={ "Ἰ","͂" }, - ["Ἷ"]={ "Ἱ","͂" }, - ["ὀ"]={ "ο","̓" }, - ["ὁ"]={ "ο","̔" }, - ["ὂ"]={ "ὀ","̀" }, - ["ὃ"]={ "ὁ","̀" }, - ["ὄ"]={ "ὀ","́" }, - ["ὅ"]={ "ὁ","́" }, - ["Ὀ"]={ "Ο","̓" }, - ["Ὁ"]={ "Ο","̔" }, - ["Ὂ"]={ "Ὀ","̀" }, - ["Ὃ"]={ "Ὁ","̀" }, - ["Ὄ"]={ "Ὀ","́" }, - ["Ὅ"]={ "Ὁ","́" }, - ["ὐ"]={ "υ","̓" }, - ["ὑ"]={ "υ","̔" }, - ["ὒ"]={ "ὐ","̀" }, - ["ὓ"]={ "ὑ","̀" }, - ["ὔ"]={ "ὐ","́" }, - ["ὕ"]={ "ὑ","́" }, - ["ὖ"]={ "ὐ","͂" }, - ["ὗ"]={ "ὑ","͂" }, - ["Ὑ"]={ "Υ","̔" }, - ["Ὓ"]={ "Ὑ","̀" }, - ["Ὕ"]={ "Ὑ","́" }, - ["Ὗ"]={ "Ὑ","͂" }, - ["ὠ"]={ "ω","̓" }, - ["ὡ"]={ "ω","̔" }, - ["ὢ"]={ "ὠ","̀" }, - ["ὣ"]={ "ὡ","̀" }, - ["ὤ"]={ "ὠ","́" }, - ["ὥ"]={ "ὡ","́" }, - ["ὦ"]={ "ὠ","͂" }, - ["ὧ"]={ "ὡ","͂" }, - ["Ὠ"]={ "Ω","̓" }, - ["Ὡ"]={ "Ω","̔" }, - ["Ὢ"]={ "Ὠ","̀" }, - ["Ὣ"]={ "Ὡ","̀" }, - ["Ὤ"]={ "Ὠ","́" }, - ["Ὥ"]={ "Ὡ","́" }, - ["Ὦ"]={ "Ὠ","͂" }, - ["Ὧ"]={ "Ὡ","͂" }, - ["ὰ"]={ "α","̀" }, - ["ὲ"]={ "ε","̀" }, - ["ὴ"]={ "η","̀" }, - ["ὶ"]={ "ι","̀" }, - ["ὸ"]={ "ο","̀" }, - ["ὺ"]={ "υ","̀" }, - ["ὼ"]={ "ω","̀" }, - ["ᾀ"]={ "ἀ","ͅ" }, - ["ᾁ"]={ "ἁ","ͅ" }, - ["ᾂ"]={ "ἂ","ͅ" }, - ["ᾃ"]={ "ἃ","ͅ" }, - ["ᾄ"]={ "ἄ","ͅ" }, - ["ᾅ"]={ "ἅ","ͅ" }, - ["ᾆ"]={ "ἆ","ͅ" }, - ["ᾇ"]={ "ἇ","ͅ" }, - ["ᾈ"]={ "Ἀ","ͅ" }, - ["ᾉ"]={ "Ἁ","ͅ" }, - ["ᾊ"]={ "Ἂ","ͅ" }, - ["ᾋ"]={ "Ἃ","ͅ" }, - ["ᾌ"]={ "Ἄ","ͅ" }, - ["ᾍ"]={ "Ἅ","ͅ" }, - ["ᾎ"]={ "Ἆ","ͅ" }, - ["ᾏ"]={ "Ἇ","ͅ" }, - ["ᾐ"]={ "ἠ","ͅ" }, - ["ᾑ"]={ "ἡ","ͅ" }, - ["ᾒ"]={ "ἢ","ͅ" }, - ["ᾓ"]={ "ἣ","ͅ" }, - ["ᾔ"]={ "ἤ","ͅ" }, - ["ᾕ"]={ "ἥ","ͅ" }, - ["ᾖ"]={ "ἦ","ͅ" }, - ["ᾗ"]={ "ἧ","ͅ" }, - ["ᾘ"]={ "Ἠ","ͅ" }, - ["ᾙ"]={ "Ἡ","ͅ" }, - ["ᾚ"]={ "Ἢ","ͅ" }, - ["ᾛ"]={ "Ἣ","ͅ" }, - ["ᾜ"]={ "Ἤ","ͅ" }, - ["ᾝ"]={ "Ἥ","ͅ" }, - ["ᾞ"]={ "Ἦ","ͅ" }, - ["ᾟ"]={ "Ἧ","ͅ" }, - ["ᾠ"]={ "ὠ","ͅ" }, - ["ᾡ"]={ "ὡ","ͅ" }, - ["ᾢ"]={ "ὢ","ͅ" }, - ["ᾣ"]={ "ὣ","ͅ" }, - ["ᾤ"]={ "ὤ","ͅ" }, - ["ᾥ"]={ "ὥ","ͅ" }, - ["ᾦ"]={ "ὦ","ͅ" }, - ["ᾧ"]={ "ὧ","ͅ" }, - ["ᾨ"]={ "Ὠ","ͅ" }, - ["ᾩ"]={ "Ὡ","ͅ" }, - ["ᾪ"]={ "Ὢ","ͅ" }, - ["ᾫ"]={ "Ὣ","ͅ" }, - ["ᾬ"]={ "Ὤ","ͅ" }, - ["ᾭ"]={ "Ὥ","ͅ" }, - ["ᾮ"]={ "Ὦ","ͅ" }, - ["ᾯ"]={ "Ὧ","ͅ" }, - ["ᾰ"]={ "α","̆" }, - ["ᾱ"]={ "α","̄" }, - ["ᾲ"]={ "ὰ","ͅ" }, - ["ᾳ"]={ "α","ͅ" }, - ["ᾴ"]={ "ά","ͅ" }, - ["ᾶ"]={ "α","͂" }, - ["ᾷ"]={ "ᾶ","ͅ" }, - ["Ᾰ"]={ "Α","̆" }, - ["Ᾱ"]={ "Α","̄" }, - ["Ὰ"]={ "Α","̀" }, - ["ᾼ"]={ "Α","ͅ" }, - ["῁"]={ "¨","͂" }, - ["ῂ"]={ "ὴ","ͅ" }, - ["ῃ"]={ "η","ͅ" }, - ["ῄ"]={ "ή","ͅ" }, - ["ῆ"]={ "η","͂" }, - ["ῇ"]={ "ῆ","ͅ" }, - ["Ὲ"]={ "Ε","̀" }, - ["Ὴ"]={ "Η","̀" }, - ["ῌ"]={ "Η","ͅ" }, - ["῍"]={ "᾿","̀" }, - ["῎"]={ "᾿","́" }, - ["῏"]={ "᾿","͂" }, - ["ῐ"]={ "ι","̆" }, - ["ῑ"]={ "ι","̄" }, - ["ῒ"]={ "ϊ","̀" }, - ["ῖ"]={ "ι","͂" }, - ["ῗ"]={ "ϊ","͂" }, - ["Ῐ"]={ "Ι","̆" }, - ["Ῑ"]={ "Ι","̄" }, - ["Ὶ"]={ "Ι","̀" }, - ["῝"]={ "῾","̀" }, - ["῞"]={ "῾","́" }, - ["῟"]={ "῾","͂" }, - ["ῠ"]={ "υ","̆" }, - ["ῡ"]={ "υ","̄" }, - ["ῢ"]={ "ϋ","̀" }, - ["ῤ"]={ "ρ","̓" }, - ["ῥ"]={ "ρ","̔" }, - ["ῦ"]={ "υ","͂" }, - ["ῧ"]={ "ϋ","͂" }, - ["Ῠ"]={ "Υ","̆" }, - ["Ῡ"]={ "Υ","̄" }, - ["Ὺ"]={ "Υ","̀" }, - ["Ῥ"]={ "Ρ","̔" }, - ["῭"]={ "¨","̀" }, - ["ῲ"]={ "ὼ","ͅ" }, - ["ῳ"]={ "ω","ͅ" }, - ["ῴ"]={ "ώ","ͅ" }, - ["ῶ"]={ "ω","͂" }, - ["ῷ"]={ "ῶ","ͅ" }, - ["Ὸ"]={ "Ο","̀" }, - ["Ὼ"]={ "Ω","̀" }, - ["ῼ"]={ "Ω","ͅ" }, - ["↚"]={ "←","̸" }, - ["↛"]={ "→","̸" }, - ["↮"]={ "↔","̸" }, - ["⇍"]={ "⇐","̸" }, - ["⇎"]={ "⇔","̸" }, - ["⇏"]={ "⇒","̸" }, - ["∄"]={ "∃","̸" }, - ["∉"]={ "∈","̸" }, - ["∌"]={ "∋","̸" }, - ["∤"]={ "∣","̸" }, - ["∦"]={ "∥","̸" }, - ["≁"]={ "∼","̸" }, - ["≄"]={ "≃","̸" }, - ["≇"]={ "≅","̸" }, - ["≉"]={ "≈","̸" }, - ["≠"]={ "=","̸" }, - ["≢"]={ "≡","̸" }, - ["≭"]={ "≍","̸" }, - ["≮"]={ "<","̸" }, - ["≯"]={ ">","̸" }, - ["≰"]={ "≤","̸" }, - ["≱"]={ "≥","̸" }, - ["≴"]={ "≲","̸" }, - ["≵"]={ "≳","̸" }, - ["≸"]={ "≶","̸" }, - ["≹"]={ "≷","̸" }, - ["⊀"]={ "≺","̸" }, - ["⊁"]={ "≻","̸" }, - ["⊄"]={ "⊂","̸" }, - ["⊅"]={ "⊃","̸" }, - ["⊈"]={ "⊆","̸" }, - ["⊉"]={ "⊇","̸" }, - ["⊬"]={ "⊢","̸" }, - ["⊭"]={ "⊨","̸" }, - ["⊮"]={ "⊩","̸" }, - ["⊯"]={ "⊫","̸" }, - ["⋠"]={ "≼","̸" }, - ["⋡"]={ "≽","̸" }, - ["⋢"]={ "⊑","̸" }, - ["⋣"]={ "⊒","̸" }, - ["⋪"]={ "⊲","̸" }, - ["⋫"]={ "⊳","̸" }, - ["⋬"]={ "⊴","̸" }, - ["⋭"]={ "⊵","̸" }, - ["⫝̸"]={ "⫝","̸" }, - ["が"]={ "か","゙" }, - ["ぎ"]={ "き","゙" }, - ["ぐ"]={ "く","゙" }, - ["げ"]={ "け","゙" }, - ["ご"]={ "こ","゙" }, - ["ざ"]={ "さ","゙" }, - ["じ"]={ "し","゙" }, - ["ず"]={ "す","゙" }, - ["ぜ"]={ "せ","゙" }, - ["ぞ"]={ "そ","゙" }, - ["だ"]={ "た","゙" }, - ["ぢ"]={ "ち","゙" }, - ["づ"]={ "つ","゙" }, - ["で"]={ "て","゙" }, - ["ど"]={ "と","゙" }, - ["ば"]={ "は","゙" }, - ["ぱ"]={ "は","゚" }, - ["び"]={ "ひ","゙" }, - ["ぴ"]={ "ひ","゚" }, - ["ぶ"]={ "ふ","゙" }, - ["ぷ"]={ "ふ","゚" }, - ["べ"]={ "へ","゙" }, - ["ぺ"]={ "へ","゚" }, - ["ぼ"]={ "ほ","゙" }, - ["ぽ"]={ "ほ","゚" }, - ["ゔ"]={ "う","゙" }, - ["ゞ"]={ "ゝ","゙" }, - ["ガ"]={ "カ","゙" }, - ["ギ"]={ "キ","゙" }, - ["グ"]={ "ク","゙" }, - ["ゲ"]={ "ケ","゙" }, - ["ゴ"]={ "コ","゙" }, - ["ザ"]={ "サ","゙" }, - ["ジ"]={ "シ","゙" }, - ["ズ"]={ "ス","゙" }, - ["ゼ"]={ "セ","゙" }, - ["ゾ"]={ "ソ","゙" }, - ["ダ"]={ "タ","゙" }, - ["ヂ"]={ "チ","゙" }, - ["ヅ"]={ "ツ","゙" }, - ["デ"]={ "テ","゙" }, - ["ド"]={ "ト","゙" }, - ["バ"]={ "ハ","゙" }, - ["パ"]={ "ハ","゚" }, - ["ビ"]={ "ヒ","゙" }, - ["ピ"]={ "ヒ","゚" }, - ["ブ"]={ "フ","゙" }, - ["プ"]={ "フ","゚" }, - ["ベ"]={ "ヘ","゙" }, - ["ペ"]={ "ヘ","゚" }, - ["ボ"]={ "ホ","゙" }, - ["ポ"]={ "ホ","゚" }, - ["ヴ"]={ "ウ","゙" }, - ["ヷ"]={ "ワ","゙" }, - ["ヸ"]={ "ヰ","゙" }, - ["ヹ"]={ "ヱ","゙" }, - ["ヺ"]={ "ヲ","゙" }, - ["ヾ"]={ "ヽ","゙" }, - ["יִ"]={ "י","ִ" }, - ["ײַ"]={ "ײ","ַ" }, - ["שׁ"]={ "ש","ׁ" }, - ["שׂ"]={ "ש","ׂ" }, - ["שּׁ"]={ "שּ","ׁ" }, - ["שּׂ"]={ "שּ","ׂ" }, - ["אַ"]={ "א","ַ" }, - ["אָ"]={ "א","ָ" }, - ["אּ"]={ "א","ּ" }, - ["בּ"]={ "ב","ּ" }, - ["גּ"]={ "ג","ּ" }, - ["דּ"]={ "ד","ּ" }, - ["הּ"]={ "ה","ּ" }, - ["וּ"]={ "ו","ּ" }, - ["זּ"]={ "ז","ּ" }, - ["טּ"]={ "ט","ּ" }, - ["יּ"]={ "י","ּ" }, - ["ךּ"]={ "ך","ּ" }, - ["כּ"]={ "כ","ּ" }, - ["לּ"]={ "ל","ּ" }, - ["מּ"]={ "מ","ּ" }, - ["נּ"]={ "נ","ּ" }, - ["סּ"]={ "ס","ּ" }, - ["ףּ"]={ "ף","ּ" }, - ["פּ"]={ "פ","ּ" }, - ["צּ"]={ "צ","ּ" }, - ["קּ"]={ "ק","ּ" }, - ["רּ"]={ "ר","ּ" }, - ["שּ"]={ "ש","ּ" }, - ["תּ"]={ "ת","ּ" }, - ["וֹ"]={ "ו","ֹ" }, - ["בֿ"]={ "ב","ֿ" }, - ["כֿ"]={ "כ","ֿ" }, - ["פֿ"]={ "פ","ֿ" }, - ["𑂚"]={ "𑂙","𑂺" }, - ["𑂜"]={ "𑂛","𑂺" }, - ["𑂫"]={ "𑂥","𑂺" }, - ["𑄮"]={ "𑄱","𑄧" }, - ["𑄯"]={ "𑄲","𑄧" }, - ["𑍋"]={ "𑍇","𑌾" }, - ["𑍌"]={ "𑍇","𑍗" }, - ["𑒻"]={ "𑒹","𑒺" }, - ["𑒼"]={ "𑒹","𑒰" }, - ["𑒾"]={ "𑒹","𑒽" }, - ["𑖺"]={ "𑖸","𑖯" }, - ["𑖻"]={ "𑖹","𑖯" }, - ["𝅗𝅥"]={ "𝅗","𝅥" }, - ["𝅘𝅥"]={ "𝅘","𝅥" }, - ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" }, - ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" }, - ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" }, - ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" }, - ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" }, - ["𝆹𝅥"]={ "𝆹","𝅥" }, - ["𝆺𝅥"]={ "𝆺","𝅥" }, - ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" }, - ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" }, - ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" }, - ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" }, - }, - }, - }, - ["name"]="collapse", - ["prepend"]=true, - ["type"]="ligature", -} - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-lig”] --- - - -do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-gbn” 10ecdf01e7c926e5128ad8a9dff4d677] --- - -if not modules then modules={} end modules ['luatex-fonts-gbn']={ - version=1.001, - comment="companion to luatex-*.tex", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -if context then - os.exit() -end -local next=next -local fonts=fonts -local nodes=nodes -local nuts=nodes.nuts -local traverse_id=nuts.traverse_id -local flush_node=nuts.flush_node -local glyph_code=nodes.nodecodes.glyph -local disc_code=nodes.nodecodes.disc -local tonode=nuts.tonode -local tonut=nuts.tonut -local getfont=nuts.getfont -local getchar=nuts.getchar -local getid=nuts.getid -local getboth=nuts.getboth -local getprev=nuts.getprev -local getnext=nuts.getnext -local getdisc=nuts.getdisc -local setchar=nuts.setchar -local setlink=nuts.setlink -local setprev=nuts.setprev -local n_ligaturing=node.ligaturing -local n_kerning=node.kerning -local d_ligaturing=nuts.ligaturing -local d_kerning=nuts.kerning -local basemodepass=true -local function l_warning() logs.report("fonts","don't call 'node.ligaturing' directly") l_warning=nil end -local function k_warning() logs.report("fonts","don't call 'node.kerning' directly") k_warning=nil end -function node.ligaturing(...) - if basemodepass and l_warning then - l_warning() - end - return n_ligaturing(...) -end -function node.kerning(...) - if basemodepass and k_warning then - k_warning() - end - return n_kerning(...) -end -function nuts.ligaturing(...) - if basemodepass and l_warning then - l_warning() - end - return d_ligaturing(...) -end -function nuts.kerning(...) - if basemodepass and k_warning then - k_warning() - end - return d_kerning(...) -end -function nodes.handlers.setbasemodepass(v) - basemodepass=v -end -local function nodepass(head,groupcode,size,packtype,direction) - local fontdata=fonts.hashes.identifiers - if fontdata then - local usedfonts={} - local basefonts={} - local prevfont=nil - local basefont=nil - local variants=nil - local redundant=nil - local nofused=0 - for n in traverse_id(glyph_code,head) do - local font=getfont(n) - if font~=prevfont then - if basefont then - basefont[2]=getprev(n) - end - prevfont=font - local used=usedfonts[font] - if not used then - local tfmdata=fontdata[font] - if tfmdata then - local shared=tfmdata.shared - if shared then - local processors=shared.processes - if processors and #processors>0 then - usedfonts[font]=processors - nofused=nofused+1 - elseif basemodepass then - basefont={ n,nil } - basefonts[#basefonts+1]=basefont - end - end - local resources=tfmdata.resources - variants=resources and resources.variants - variants=variants and next(variants) and variants or false - end - else - local tfmdata=fontdata[prevfont] - if tfmdata then - local resources=tfmdata.resources - variants=resources and resources.variants - variants=variants and next(variants) and variants or false - end - end - end - if variants then - local char=getchar(n) - if (char>=0xFE00 and char<=0xFE0F) or (char>=0xE0100 and char<=0xE01EF) then - local hash=variants[char] - if hash then - local p=getprev(n) - if p and getid(p)==glyph_code then - local variant=hash[getchar(p)] - if variant then - setchar(p,variant) - end - end - end - if not redundant then - redundant={ n } - else - redundant[#redundant+1]=n - end - end - end - end - local nofbasefonts=#basefonts - if redundant then - for i=1,#redundant do - local r=redundant[i] - local p,n=getboth(r) - if r==head then - head=n - setprev(n) - else - setlink(p,n) - end - if nofbasefonts>0 then - for i=1,nofbasefonts do - local bi=basefonts[i] - if r==bi[1] then - bi[1]=n - end - if r==bi[2] then - bi[2]=n - end - end - end - flush_node(r) - end - end - for d in traverse_id(disc_code,head) do - local _,_,r=getdisc(d) - if r then - for n in traverse_id(glyph_code,r) do - local font=getfont(n) - if font~=prevfont then - prevfont=font - local used=usedfonts[font] - if not used then - local tfmdata=fontdata[font] - if tfmdata then - local shared=tfmdata.shared - if shared then - local processors=shared.processes - if processors and #processors>0 then - usedfonts[font]=processors - nofused=nofused+1 - end - end - end - end - end - end - end - end - if next(usedfonts) then - for font,processors in next,usedfonts do - for i=1,#processors do - head=processors[i](head,font,0,direction,nofused) or head - end - end - end - if basemodepass and nofbasefonts>0 then - for i=1,nofbasefonts do - local range=basefonts[i] - local start=range[1] - local stop=range[2] - if start then - local front=head==start - local prev,next - if stop then - next=getnext(stop) - start,stop=d_ligaturing(start,stop) - start,stop=d_kerning(start,stop) - else - prev=getprev(start) - start=d_ligaturing(start) - start=d_kerning(start) - end - if prev then - setlink(prev,start) - end - if next then - setlink(stop,next) - end - if front and head~=start then - head=start - end - end - end - end - end - return head -end -local function basepass(head) - if basemodepass then - head=d_ligaturing(head) - head=d_kerning(head) - end - return head -end -local protectpass=node.direct.protect_glyphs -local injectpass=nodes.injections.handler -function nodes.handlers.nodepass(head,...) - if head then - return tonode(nodepass(tonut(head),...)) - end -end -function nodes.handlers.basepass(head) - if head then - return tonode(basepass(tonut(head))) - end -end -function nodes.handlers.injectpass(head) - if head then - return tonode(injectpass(tonut(head))) - end -end -function nodes.handlers.protectpass(head) - if head then - protectpass(tonut(head)) - return head - end -end -function nodes.simple_font_handler(head,groupcode,size,packtype,direction) - if head then - head=tonut(head) - head=nodepass(head,groupcode,size,packtype,direction) - head=injectpass(head) - if not basemodepass then - head=basepass(head) - end - protectpass(head) - head=tonode(head) - end - return head -end - -end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-gbn”] --- - - ---- vim:ft=lua:sw=2:ts=8:et:tw=79 diff --git a/macros/luatex/generic/luaotfload/fontloader-2021-01-07.lua b/macros/luatex/generic/luaotfload/fontloader-2021-01-07.lua new file mode 100644 index 0000000000..e333584b00 --- /dev/null +++ b/macros/luatex/generic/luaotfload/fontloader-2021-01-07.lua @@ -0,0 +1,35115 @@ +--[[info----------------------------------------------------------------------- + Luaotfload fontloader package + build 2021-01-07 23:19:37 +------------------------------------------------------------------------------- + + © 2021 PRAGMA ADE / ConTeXt Development Team + + The code in this file is provided under the GPL v2.0 license. See the + file COPYING in the Luaotfload repository for details. + + Report bugs to https://github.com/latex3/luaotfload + + This file has been assembled from components taken from Context. See + the Luaotfload documentation for details: + + $ texdoc luaotfload + $ man 1 luaotfload-tool + $ man 5 luaotfload.conf + + Included files: + + · fontloader-data-con.lua + · fontloader-basics-nod.lua + · fontloader-basics-chr.lua + · fontloader-font-ini.lua + · fontloader-fonts-mis.lua + · fontloader-font-con.lua + · fontloader-fonts-enc.lua + · fontloader-font-cid.lua + · fontloader-font-map.lua + · fontloader-font-vfc.lua + · fontloader-font-otr.lua + · fontloader-font-oti.lua + · fontloader-font-ott.lua + · fontloader-font-cff.lua + · fontloader-font-ttf.lua + · fontloader-font-dsp.lua + · fontloader-font-oup.lua + · fontloader-font-otl.lua + · fontloader-font-oto.lua + · fontloader-font-otj.lua + · fontloader-font-ota.lua + · fontloader-font-ots.lua + · fontloader-font-osd.lua + · fontloader-font-ocl.lua + · fontloader-font-otc.lua + · fontloader-font-onr.lua + · fontloader-font-one.lua + · fontloader-font-afk.lua + · fontloader-fonts-tfm.lua + · fontloader-font-lua.lua + · fontloader-font-def.lua + · fontloader-font-shp.lua + · fontloader-fonts-def.lua + · fontloader-fonts-ext.lua + · fontloader-font-imp-tex.lua + · fontloader-font-imp-ligatures.lua + · fontloader-font-imp-italics.lua + · fontloader-font-imp-effects.lua + · fontloader-fonts-lig.lua + · fontloader-fonts-gbn.lua + +--info]]----------------------------------------------------------------------- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “data-con” 23a0f5386d46a1c157ae82a373e35fa0] --- + +if not modules then modules={} end modules ['data-con']={ + version=1.100, + comment="companion to luat-lib.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local setmetatable=setmetatable +local format,lower,gsub=string.format,string.lower,string.gsub +local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end) +local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end) +local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end) +containers=containers or {} +local containers=containers +containers.usecache=true +local getwritablepath=caches.getwritablepath +local getreadablepaths=caches.getreadablepaths +local cacheiswritable=caches.is_writable +local loaddatafromcache=caches.loaddata +local savedataincache=caches.savedata +local report_containers=logs.reporter("resolvers","containers") +local allocated={} +local mt={ + __index=function(t,k) + if k=="writable" then + local writable=getwritablepath(t.category,t.subcategory) or { "." } + t.writable=writable + return writable + elseif k=="readables" then + local readables=getreadablepaths(t.category,t.subcategory) or { "." } + t.readables=readables + return readables + end + end, + __storage__=true +} +function containers.define(category,subcategory,version,enabled) + if category and subcategory then + local c=allocated[category] + if not c then + c={} + allocated[category]=c + end + local s=c[subcategory] + if not s then + s={ + category=category, + subcategory=subcategory, + storage={}, + enabled=enabled, + version=version or math.pi, + trace=false, + } + setmetatable(s,mt) + c[subcategory]=s + end + return s + end +end +function containers.is_usable(container,name) + return container.enabled and caches and cacheiswritable(container.writable,name) +end +function containers.is_valid(container,name) + if name and name~="" then + local storage=container.storage[name] + return storage and storage.cache_version==container.version + else + return false + end +end +function containers.read(container,name) + local storage=container.storage + local stored=storage[name] + if not stored and container.enabled and caches and containers.usecache then + stored=loaddatafromcache(container.readables,name,container.writable) + if stored and stored.cache_version==container.version then + if trace_cache or trace_containers then + report_containers("action %a, category %a, name %a","load",container.subcategory,name) + end + else + stored=nil + end + storage[name]=stored + elseif stored then + if trace_cache or trace_containers then + report_containers("action %a, category %a, name %a","reuse",container.subcategory,name) + end + end + return stored +end +function containers.write(container,name,data,fast) + if data then + data.cache_version=container.version + if container.enabled and caches then + local unique=data.unique + local shared=data.shared + data.unique=nil + data.shared=nil + savedataincache(container.writable,name,data,fast) + if trace_cache or trace_containers then + report_containers("action %a, category %a, name %a","save",container.subcategory,name) + end + data.unique=unique + data.shared=shared + end + if trace_cache or trace_containers then + report_containers("action %a, category %a, name %a","store",container.subcategory,name) + end + container.storage[name]=data + end + return data +end +function containers.content(container,name) + return container.storage[name] +end +function containers.cleanname(name) + return (gsub(lower(name),"[^%w\128-\255]+","-")) +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “data-con”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “basics-nod” 4b5c3c63e19df1b3f37fae7f87c25bda] --- + +if not modules then modules={} end modules ['luatex-fonts-nod']={ + version=1.001, + comment="companion to luatex-fonts.lua", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +if context then + os.exit() +end +if tex.attribute[0]~=0 then + texio.write_nl("log","!") + texio.write_nl("log","! Attribute 0 is reserved for ConTeXt's font feature management and has to be") + texio.write_nl("log","! set to zero. Also, some attributes in the range 1-255 are used for special") + texio.write_nl("log","! purposes so setting them at the TeX end might break the font handler.") + texio.write_nl("log","!") + tex.attribute[0]=0 +end +attributes=attributes or {} +attributes.unsetvalue=-0x7FFFFFFF +local numbers,last={},127 +attributes.private=attributes.private or function(name) + local number=numbers[name] + if not number then + if last<255 then + last=last+1 + end + number=last + numbers[name]=number + end + return number +end +nodes={} +nodes.handlers={} +local nodecodes={} +local glyphcodes=node.subtypes("glyph") +local disccodes=node.subtypes("disc") +for k,v in next,node.types() do + v=string.gsub(v,"_","") + nodecodes[k]=v + nodecodes[v]=k +end +for k,v in next,glyphcodes do + glyphcodes[v]=k +end +for k,v in next,disccodes do + disccodes[v]=k +end +nodes.nodecodes=nodecodes +nodes.glyphcodes=glyphcodes +nodes.disccodes=disccodes +nodes.dirvalues={ lefttoright=0,righttoleft=1 } +nodes.handlers.protectglyphs=node.protect_glyphs +nodes.handlers.unprotectglyphs=node.unprotect_glyphs +local direct=node.direct +local nuts={} +nodes.nuts=nuts +local tonode=direct.tonode +local tonut=direct.todirect +nodes.tonode=tonode +nodes.tonut=tonut +nuts.tonode=tonode +nuts.tonut=tonut +nuts.getattr=direct.get_attribute +nuts.getboth=direct.getboth +nuts.getchar=direct.getchar +nuts.getdirection=direct.getdirection +nuts.getdisc=direct.getdisc +nuts.getreplace=direct.getreplace +nuts.getfield=direct.getfield +nuts.getfont=direct.getfont +nuts.getid=direct.getid +nuts.getkern=direct.getkern +nuts.getlist=direct.getlist +nuts.getnext=direct.getnext +nuts.getoffsets=direct.getoffsets +nuts.getoptions=direct.getoptions or function() return 0 end +nuts.getprev=direct.getprev +nuts.getsubtype=direct.getsubtype +nuts.getwidth=direct.getwidth +nuts.setattr=direct.setfield +nuts.setboth=direct.setboth +nuts.setchar=direct.setchar +nuts.setcomponents=direct.setcomponents +nuts.setdirection=direct.setdirection +nuts.setdisc=direct.setdisc +nuts.setreplace=direct.setreplace +nuts.setfield=setfield +nuts.setkern=direct.setkern +nuts.setlink=direct.setlink +nuts.setlist=direct.setlist +nuts.setnext=direct.setnext +nuts.setoffsets=direct.setoffsets +nuts.setprev=direct.setprev +nuts.setsplit=direct.setsplit +nuts.setsubtype=direct.setsubtype +nuts.setwidth=direct.setwidth +nuts.getglyphdata=nuts.getattr +nuts.setglyphdata=nuts.setattr +nuts.ischar=direct.is_char +nuts.isglyph=direct.is_glyph +nuts.copy=direct.copy +nuts.copy_list=direct.copy_list +nuts.copy_node=direct.copy +nuts.end_of_math=direct.end_of_math +nuts.flush=direct.flush +nuts.flush_list=direct.flush_list +nuts.flush_node=direct.flush_node +nuts.free=direct.free +nuts.insert_after=direct.insert_after +nuts.insert_before=direct.insert_before +nuts.is_node=direct.is_node +nuts.kerning=direct.kerning +nuts.ligaturing=direct.ligaturing +nuts.new=direct.new +nuts.remove=direct.remove +nuts.tail=direct.tail +nuts.traverse=direct.traverse +nuts.traverse_char=direct.traverse_char +nuts.traverse_glyph=direct.traverse_glyph +nuts.traverse_id=direct.traverse_id +local propertydata=direct.get_properties_table() +nodes.properties={ data=propertydata } +if direct.set_properties_mode then + direct.set_properties_mode(true,true) + function direct.set_properties_mode() end +end +nuts.getprop=function(n,k) + local p=propertydata[n] + if p then + return p[k] + end +end +nuts.setprop=function(n,k,v) + if v then + local p=propertydata[n] + if p then + p[k]=v + else + propertydata[n]={ [k]=v } + end + end +end +nodes.setprop=nodes.setproperty +nodes.getprop=nodes.getproperty +local setprev=nuts.setprev +local setnext=nuts.setnext +local getnext=nuts.getnext +local setlink=nuts.setlink +local getfield=nuts.getfield +local setfield=nuts.setfield +local getsubtype=nuts.getsubtype +local isglyph=nuts.isglyph +local find_tail=nuts.tail +local flush_list=nuts.flush_list +local flush_node=nuts.flush_node +local traverse_id=nuts.traverse_id +local copy_node=nuts.copy_node +local glyph_code=nodes.nodecodes.glyph +local ligature_code=nodes.glyphcodes.ligature +do + local p=nodecodes.localpar or nodecodes.local_par + if p then + nodecodes.par=p + nodecodes[p]="par" + nodecodes.localpar=p + nodecodes.local_par=p + end +end +do + local get_components=node.direct.getcomponents + local set_components=node.direct.setcomponents + local function copy_no_components(g,copyinjection) + local components=get_components(g) + if components then + set_components(g) + local n=copy_node(g) + if copyinjection then + copyinjection(n,g) + end + set_components(g,components) + return n + else + local n=copy_node(g) + if copyinjection then + copyinjection(n,g) + end + return n + end + end + local function copy_only_glyphs(current) + local head=nil + local previous=nil + for n in traverse_id(glyph_code,current) do + n=copy_node(n) + if head then + setlink(previous,n) + else + head=n + end + previous=n + end + return head + end + local function count_components(start,marks) + local char=isglyph(start) + if char then + if getsubtype(start)==ligature_code then + local n=0 + local components=get_components(start) + while components do + n=n+count_components(components,marks) + components=getnext(components) + end + return n + elseif not marks[char] then + return 1 + end + end + return 0 + end + local function flush_components() + end + nuts.set_components=set_components + nuts.get_components=get_components + nuts.copy_only_glyphs=copy_only_glyphs + nuts.copy_no_components=copy_no_components + nuts.count_components=count_components + nuts.flush_components=flush_components +end +nuts.uses_font=direct.uses_font +do + local dummy=tonut(node.new("glyph")) + nuts.traversers={ + glyph=nuts.traverse_id(nodecodes.glyph,dummy), + glue=nuts.traverse_id(nodecodes.glue,dummy), + disc=nuts.traverse_id(nodecodes.disc,dummy), + boundary=nuts.traverse_id(nodecodes.boundary,dummy), + char=nuts.traverse_char(dummy), + node=nuts.traverse(dummy), + } +end +if not nuts.setreplace then + local getdisc=nuts.getdisc + local setfield=nuts.setfield + function nuts.getreplace(n) + local _,_,h,_,_,t=getdisc(n,true) + return h,t + end + function nuts.setreplace(n,h) + setfield(n,"replace",h) + end +end +do + local getsubtype=nuts.getsubtype + function nuts.start_of_par(n) + local s=getsubtype(n) + return s==0 or s==2 + end +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “basics-nod”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “basics-chr” 64fafe4eaf55d64aead6513c1e74a024] --- + + +characters=characters or {} +characters.blockrange={} +characters.classifiers={ + [768]=5, + [769]=5, + [770]=5, + [771]=5, + [772]=5, + [773]=5, + [774]=5, + [775]=5, + [776]=5, + [777]=5, + [778]=5, + [779]=5, + [780]=5, + [781]=5, + [782]=5, + [783]=5, + [784]=5, + [785]=5, + [786]=5, + [787]=5, + [788]=5, + [789]=5, + [790]=5, + [791]=5, + [792]=5, + [793]=5, + [794]=5, + [795]=5, + [796]=5, + [797]=5, + [798]=5, + [799]=5, + [800]=5, + [801]=5, + [802]=5, + [803]=5, + [804]=5, + [805]=5, + [806]=5, + [807]=5, + [808]=5, + [809]=5, + [810]=5, + [811]=5, + [812]=5, + [813]=5, + [814]=5, + [815]=5, + [816]=5, + [817]=5, + [818]=5, + [819]=5, + [820]=5, + [821]=5, + [822]=5, + [823]=5, + [824]=5, + [825]=5, + [826]=5, + [827]=5, + [828]=5, + [829]=5, + [830]=5, + [831]=5, + [832]=5, + [833]=5, + [834]=5, + [835]=5, + [836]=5, + [837]=5, + [838]=5, + [839]=5, + [840]=5, + [841]=5, + [842]=5, + [843]=5, + [844]=5, + [845]=5, + [846]=5, + [847]=5, + [848]=5, + [849]=5, + [850]=5, + [851]=5, + [852]=5, + [853]=5, + [854]=5, + [855]=5, + [856]=5, + [857]=5, + [858]=5, + [859]=5, + [860]=5, + [861]=5, + [862]=5, + [863]=5, + [864]=5, + [865]=5, + [866]=5, + [867]=5, + [868]=5, + [869]=5, + [870]=5, + [871]=5, + [872]=5, + [873]=5, + [874]=5, + [875]=5, + [876]=5, + [877]=5, + [878]=5, + [879]=5, + [1155]=5, + [1156]=5, + [1157]=5, + [1158]=5, + [1159]=5, + [1425]=5, + [1426]=5, + [1427]=5, + [1428]=5, + [1429]=5, + [1430]=5, + [1431]=5, + [1432]=5, + [1433]=5, + [1434]=5, + [1435]=5, + [1436]=5, + [1437]=5, + [1438]=5, + [1439]=5, + [1440]=5, + [1441]=5, + [1442]=5, + [1443]=5, + [1444]=5, + [1445]=5, + [1446]=5, + [1447]=5, + [1448]=5, + [1449]=5, + [1450]=5, + [1451]=5, + [1452]=5, + [1453]=5, + [1454]=5, + [1455]=5, + [1456]=5, + [1457]=5, + [1458]=5, + [1459]=5, + [1460]=5, + [1461]=5, + [1462]=5, + [1463]=5, + [1464]=5, + [1465]=5, + [1466]=5, + [1467]=5, + [1468]=5, + [1469]=5, + [1471]=5, + [1473]=5, + [1474]=5, + [1476]=5, + [1477]=5, + [1479]=5, + [1536]=4, + [1537]=4, + [1538]=4, + [1539]=4, + [1540]=4, + [1541]=4, + [1542]=6, + [1543]=6, + [1544]=4, + [1545]=6, + [1546]=6, + [1547]=4, + [1548]=6, + [1549]=6, + [1550]=6, + [1551]=6, + [1552]=5, + [1553]=5, + [1554]=5, + [1555]=5, + [1556]=5, + [1557]=5, + [1558]=5, + [1559]=5, + [1560]=5, + [1561]=5, + [1562]=5, + [1563]=6, + [1564]=6, + [1566]=6, + [1567]=6, + [1568]=2, + [1569]=4, + [1570]=3, + [1571]=3, + [1572]=3, + [1573]=3, + [1574]=2, + [1575]=3, + [1576]=2, + [1577]=3, + [1578]=2, + [1579]=2, + [1580]=2, + [1581]=2, + [1582]=2, + [1583]=3, + [1584]=3, + [1585]=3, + [1586]=3, + [1587]=2, + [1588]=2, + [1589]=2, + [1590]=2, + [1591]=2, + [1592]=2, + [1593]=2, + [1594]=2, + [1595]=2, + [1596]=2, + [1597]=2, + [1598]=2, + [1599]=2, + [1600]=2, + [1601]=2, + [1602]=2, + [1603]=2, + [1604]=2, + [1605]=2, + [1606]=2, + [1607]=2, + [1608]=3, + [1609]=2, + [1610]=2, + [1611]=5, + [1612]=5, + [1613]=5, + [1614]=5, + [1615]=5, + [1616]=5, + [1617]=5, + [1618]=5, + [1619]=5, + [1620]=5, + [1621]=5, + [1622]=5, + [1623]=5, + [1624]=5, + [1625]=5, + [1626]=5, + [1627]=5, + [1628]=5, + [1629]=5, + [1630]=5, + [1631]=5, + [1632]=6, + [1633]=6, + [1634]=6, + [1635]=6, + [1636]=6, + [1637]=6, + [1638]=6, + [1639]=6, + [1640]=6, + [1641]=6, + [1642]=6, + [1643]=6, + [1644]=6, + [1645]=6, + [1646]=2, + [1647]=2, + [1648]=5, + [1649]=3, + [1650]=3, + [1651]=3, + [1652]=4, + [1653]=3, + [1654]=3, + [1655]=3, + [1656]=2, + [1657]=2, + [1658]=2, + [1659]=2, + [1660]=2, + [1661]=2, + [1662]=2, + [1663]=2, + [1664]=2, + [1665]=2, + [1666]=2, + [1667]=2, + [1668]=2, + [1669]=2, + [1670]=2, + [1671]=2, + [1672]=3, + [1673]=3, + [1674]=3, + [1675]=3, + [1676]=3, + [1677]=3, + [1678]=3, + [1679]=3, + [1680]=3, + [1681]=3, + [1682]=3, + [1683]=3, + [1684]=3, + [1685]=3, + [1686]=3, + [1687]=3, + [1688]=3, + [1689]=3, + [1690]=2, + [1691]=2, + [1692]=2, + [1693]=2, + [1694]=2, + [1695]=2, + [1696]=2, + [1697]=2, + [1698]=2, + [1699]=2, + [1700]=2, + [1701]=2, + [1702]=2, + [1703]=2, + [1704]=2, + [1705]=2, + [1706]=2, + [1707]=2, + [1708]=2, + [1709]=2, + [1710]=2, + [1711]=2, + [1712]=2, + [1713]=2, + [1714]=2, + [1715]=2, + [1716]=2, + [1717]=2, + [1718]=2, + [1719]=2, + [1720]=2, + [1721]=2, + [1722]=2, + [1723]=2, + [1724]=2, + [1725]=2, + [1726]=2, + [1727]=2, + [1728]=3, + [1729]=2, + [1730]=2, + [1731]=3, + [1732]=3, + [1733]=3, + [1734]=3, + [1735]=3, + [1736]=3, + [1737]=3, + [1738]=3, + [1739]=3, + [1740]=2, + [1741]=3, + [1742]=2, + [1743]=3, + [1744]=2, + [1745]=2, + [1746]=3, + [1747]=3, + [1748]=6, + [1749]=3, + [1750]=5, + [1751]=5, + [1752]=5, + [1753]=5, + [1754]=5, + [1755]=5, + [1756]=5, + [1757]=4, + [1758]=6, + [1759]=5, + [1760]=5, + [1761]=5, + [1762]=5, + [1763]=5, + [1764]=5, + [1765]=6, + [1766]=6, + [1767]=5, + [1768]=5, + [1769]=6, + [1770]=5, + [1771]=5, + [1772]=5, + [1773]=5, + [1774]=3, + [1775]=3, + [1776]=6, + [1777]=6, + [1778]=6, + [1779]=6, + [1780]=6, + [1781]=6, + [1782]=6, + [1783]=6, + [1784]=6, + [1785]=6, + [1786]=2, + [1787]=2, + [1788]=2, + [1789]=6, + [1790]=6, + [1791]=2, + [1792]=6, + [1793]=6, + [1794]=6, + [1795]=6, + [1796]=6, + [1797]=6, + [1798]=6, + [1799]=6, + [1800]=6, + [1801]=6, + [1802]=6, + [1803]=6, + [1804]=6, + [1805]=6, + [1808]=3, + [1809]=5, + [1810]=2, + [1811]=2, + [1812]=2, + [1813]=3, + [1814]=3, + [1815]=3, + [1816]=3, + [1817]=3, + [1818]=2, + [1819]=2, + [1820]=2, + [1821]=2, + [1822]=3, + [1823]=2, + [1824]=2, + [1825]=2, + [1826]=2, + [1827]=2, + [1828]=2, + [1829]=2, + [1830]=2, + [1831]=2, + [1832]=3, + [1833]=2, + [1834]=3, + [1835]=2, + [1836]=3, + [1837]=2, + [1838]=2, + [1839]=3, + [1840]=5, + [1841]=5, + [1842]=5, + [1843]=5, + [1844]=5, + [1845]=5, + [1846]=5, + [1847]=5, + [1848]=5, + [1849]=5, + [1850]=5, + [1851]=5, + [1852]=5, + [1853]=5, + [1854]=5, + [1855]=5, + [1856]=5, + [1857]=5, + [1858]=5, + [1859]=5, + [1860]=5, + [1861]=5, + [1862]=5, + [1863]=5, + [1864]=5, + [1865]=5, + [1866]=5, + [1869]=3, + [1870]=2, + [1871]=2, + [1872]=2, + [1873]=2, + [1874]=2, + [1875]=2, + [1876]=2, + [1877]=2, + [1878]=2, + [1879]=2, + [1880]=2, + [1881]=3, + [1882]=3, + [1883]=3, + [1884]=2, + [1885]=2, + [1886]=2, + [1887]=2, + [1888]=2, + [1889]=2, + [1890]=2, + [1891]=2, + [1892]=2, + [1893]=2, + [1894]=2, + [1895]=2, + [1896]=2, + [1897]=2, + [1898]=2, + [1899]=3, + [1900]=3, + [1901]=2, + [1902]=2, + [1903]=2, + [1904]=2, + [1905]=3, + [1906]=2, + [1907]=3, + [1908]=3, + [1909]=2, + [1910]=2, + [1911]=2, + [1912]=3, + [1913]=3, + [1914]=2, + [1915]=2, + [1916]=2, + [1917]=2, + [1918]=2, + [1919]=2, + [1958]=5, + [1959]=5, + [1960]=5, + [1961]=5, + [1962]=5, + [1963]=5, + [1964]=5, + [1965]=5, + [1966]=5, + [1967]=5, + [1968]=5, + [1984]=6, + [1985]=6, + [1986]=6, + [1987]=6, + [1988]=6, + [1989]=6, + [1990]=6, + [1991]=6, + [1992]=6, + [1993]=6, + [1994]=2, + [1995]=2, + [1996]=2, + [1997]=2, + [1998]=2, + [1999]=2, + [2000]=2, + [2001]=2, + [2002]=2, + [2003]=2, + [2004]=2, + [2005]=2, + [2006]=2, + [2007]=2, + [2008]=2, + [2009]=2, + [2010]=2, + [2011]=2, + [2012]=2, + [2013]=2, + [2014]=2, + [2015]=2, + [2016]=2, + [2017]=2, + [2018]=2, + [2019]=2, + [2020]=2, + [2021]=2, + [2022]=2, + [2023]=2, + [2024]=2, + [2025]=2, + [2026]=2, + [2027]=5, + [2028]=5, + [2029]=5, + [2030]=5, + [2031]=5, + [2032]=5, + [2033]=5, + [2034]=5, + [2035]=5, + [2036]=6, + [2037]=6, + [2038]=6, + [2039]=6, + [2040]=6, + [2041]=6, + [2042]=2, + [2045]=5, + [2046]=6, + [2047]=6, + [2070]=5, + [2071]=5, + [2072]=5, + [2073]=5, + [2075]=5, + [2076]=5, + [2077]=5, + [2078]=5, + [2079]=5, + [2080]=5, + [2081]=5, + [2082]=5, + [2083]=5, + [2085]=5, + [2086]=5, + [2087]=5, + [2089]=5, + [2090]=5, + [2091]=5, + [2092]=5, + [2093]=5, + [2112]=3, + [2113]=2, + [2114]=2, + [2115]=2, + [2116]=2, + [2117]=2, + [2118]=3, + [2119]=3, + [2120]=2, + [2121]=3, + [2122]=2, + [2123]=2, + [2124]=2, + [2125]=2, + [2126]=2, + [2127]=2, + [2128]=2, + [2129]=2, + [2130]=2, + [2131]=2, + [2132]=3, + [2133]=2, + [2134]=4, + [2135]=4, + [2136]=4, + [2137]=5, + [2138]=5, + [2139]=5, + [2144]=2, + [2145]=4, + [2146]=2, + [2147]=2, + [2148]=2, + [2149]=2, + [2150]=4, + [2151]=3, + [2152]=2, + [2153]=3, + [2154]=3, + [2208]=2, + [2209]=2, + [2210]=2, + [2211]=2, + [2212]=2, + [2213]=2, + [2214]=2, + [2215]=2, + [2216]=2, + [2217]=2, + [2218]=3, + [2219]=3, + [2220]=3, + [2221]=4, + [2222]=3, + [2223]=2, + [2224]=2, + [2225]=3, + [2226]=3, + [2227]=2, + [2228]=2, + [2230]=2, + [2231]=2, + [2232]=2, + [2233]=3, + [2234]=2, + [2235]=2, + [2236]=2, + [2237]=2, + [2259]=5, + [2260]=5, + [2261]=5, + [2262]=5, + [2263]=5, + [2264]=5, + [2265]=5, + [2266]=5, + [2267]=5, + [2268]=5, + [2269]=5, + [2270]=5, + [2271]=5, + [2272]=5, + [2273]=5, + [2274]=4, + [2275]=5, + [2276]=5, + [2277]=5, + [2278]=5, + [2279]=5, + [2280]=5, + [2281]=5, + [2282]=5, + [2283]=5, + [2284]=5, + [2285]=5, + [2286]=5, + [2287]=5, + [2288]=5, + [2289]=5, + [2290]=5, + [2291]=5, + [2292]=5, + [2293]=5, + [2294]=5, + [2295]=5, + [2296]=5, + [2297]=5, + [2298]=5, + [2299]=5, + [2300]=5, + [2301]=5, + [2302]=5, + [2303]=5, + [2304]=5, + [2305]=5, + [2306]=5, + [2362]=5, + [2364]=5, + [2369]=5, + [2370]=5, + [2371]=5, + [2372]=5, + [2373]=5, + [2374]=5, + [2375]=5, + [2376]=5, + [2381]=5, + [2385]=5, + [2386]=5, + [2387]=5, + [2388]=5, + [2389]=5, + [2390]=5, + [2391]=5, + [2402]=5, + [2403]=5, + [2433]=5, + [2492]=5, + [2497]=5, + [2498]=5, + [2499]=5, + [2500]=5, + [2509]=5, + [2530]=5, + [2531]=5, + [2558]=5, + [2561]=5, + [2562]=5, + [2620]=5, + [2625]=5, + [2626]=5, + [2631]=5, + [2632]=5, + [2635]=5, + [2636]=5, + [2637]=5, + [2641]=5, + [2672]=5, + [2673]=5, + [2677]=5, + [2689]=5, + [2690]=5, + [2748]=5, + [2753]=5, + [2754]=5, + [2755]=5, + [2756]=5, + [2757]=5, + [2759]=5, + [2760]=5, + [2765]=5, + [2786]=5, + [2787]=5, + [2810]=5, + [2811]=5, + [2812]=5, + [2813]=5, + [2814]=5, + [2815]=5, + [2817]=5, + [2876]=5, + [2879]=5, + [2881]=5, + [2882]=5, + [2883]=5, + [2884]=5, + [2893]=5, + [2902]=5, + [2914]=5, + [2915]=5, + [2946]=5, + [3008]=5, + [3021]=5, + [3072]=5, + [3076]=5, + [3134]=5, + [3135]=5, + [3136]=5, + [3142]=5, + [3143]=5, + [3144]=5, + [3146]=5, + [3147]=5, + [3148]=5, + [3149]=5, + [3157]=5, + [3158]=5, + [3170]=5, + [3171]=5, + [3201]=5, + [3260]=5, + [3263]=5, + [3270]=5, + [3276]=5, + [3277]=5, + [3298]=5, + [3299]=5, + [3328]=5, + [3329]=5, + [3387]=5, + [3388]=5, + [3393]=5, + [3394]=5, + [3395]=5, + [3396]=5, + [3405]=5, + [3426]=5, + [3427]=5, + [3530]=5, + [3538]=5, + [3539]=5, + [3540]=5, + [3542]=5, + [3633]=5, + [3636]=5, + [3637]=5, + [3638]=5, + [3639]=5, + [3640]=5, + [3641]=5, + [3642]=5, + [3655]=5, + [3656]=5, + [3657]=5, + [3658]=5, + [3659]=5, + [3660]=5, + [3661]=5, + [3662]=5, + [3761]=5, + [3764]=5, + [3765]=5, + [3766]=5, + [3767]=5, + [3768]=5, + [3769]=5, + [3770]=5, + [3771]=5, + [3772]=5, + [3784]=5, + [3785]=5, + [3786]=5, + [3787]=5, + [3788]=5, + [3789]=5, + [3864]=5, + [3865]=5, + [3893]=5, + [3895]=5, + [3897]=5, + [3953]=5, + [3954]=5, + [3955]=5, + [3956]=5, + [3957]=5, + [3958]=5, + [3959]=5, + [3960]=5, + [3961]=5, + [3962]=5, + [3963]=5, + [3964]=5, + [3965]=5, + [3966]=5, + [3968]=5, + [3969]=5, + [3970]=5, + [3971]=5, + [3972]=5, + [3974]=5, + [3975]=5, + [3981]=5, + [3982]=5, + [3983]=5, + [3984]=5, + [3985]=5, + [3986]=5, + [3987]=5, + [3988]=5, + [3989]=5, + [3990]=5, + [3991]=5, + [3993]=5, + [3994]=5, + [3995]=5, + [3996]=5, + [3997]=5, + [3998]=5, + [3999]=5, + [4000]=5, + [4001]=5, + [4002]=5, + [4003]=5, + [4004]=5, + [4005]=5, + [4006]=5, + [4007]=5, + [4008]=5, + [4009]=5, + [4010]=5, + [4011]=5, + [4012]=5, + [4013]=5, + [4014]=5, + [4015]=5, + [4016]=5, + [4017]=5, + [4018]=5, + [4019]=5, + [4020]=5, + [4021]=5, + [4022]=5, + [4023]=5, + [4024]=5, + [4025]=5, + [4026]=5, + [4027]=5, + [4028]=5, + [4038]=5, + [4141]=5, + [4142]=5, + [4143]=5, + [4144]=5, + [4146]=5, + [4147]=5, + [4148]=5, + [4149]=5, + [4150]=5, + [4151]=5, + [4153]=5, + [4154]=5, + [4157]=5, + [4158]=5, + [4184]=5, + [4185]=5, + [4190]=5, + [4191]=5, + [4192]=5, + [4209]=5, + [4210]=5, + [4211]=5, + [4212]=5, + [4226]=5, + [4229]=5, + [4230]=5, + [4237]=5, + [4253]=5, + [4957]=5, + [4958]=5, + [4959]=5, + [5906]=5, + [5907]=5, + [5908]=5, + [5938]=5, + [5939]=5, + [5940]=5, + [5970]=5, + [5971]=5, + [6002]=5, + [6003]=5, + [6071]=5, + [6072]=5, + [6073]=5, + [6074]=5, + [6075]=5, + [6076]=5, + [6077]=5, + [6086]=5, + [6089]=5, + [6090]=5, + [6091]=5, + [6092]=5, + [6093]=5, + [6094]=5, + [6095]=5, + [6096]=5, + [6097]=5, + [6098]=5, + [6099]=5, + [6109]=5, + [6150]=4, + [6151]=2, + [6154]=2, + [6155]=5, + [6156]=5, + [6157]=5, + [6158]=4, + [6176]=2, + [6177]=2, + [6178]=2, + [6179]=2, + [6180]=2, + [6181]=2, + [6182]=2, + [6183]=2, + [6184]=2, + [6185]=2, + [6186]=2, + [6187]=2, + [6188]=2, + [6189]=2, + [6190]=2, + [6191]=2, + [6192]=2, + [6193]=2, + [6194]=2, + [6195]=2, + [6196]=2, + [6197]=2, + [6198]=2, + [6199]=2, + [6200]=2, + [6201]=2, + [6202]=2, + [6203]=2, + [6204]=2, + [6205]=2, + [6206]=2, + [6207]=2, + [6208]=2, + [6209]=2, + [6210]=2, + [6211]=2, + [6212]=2, + [6213]=2, + [6214]=2, + [6215]=2, + [6216]=2, + [6217]=2, + [6218]=2, + [6219]=2, + [6220]=2, + [6221]=2, + [6222]=2, + [6223]=2, + [6224]=2, + [6225]=2, + [6226]=2, + [6227]=2, + [6228]=2, + [6229]=2, + [6230]=2, + [6231]=2, + [6232]=2, + [6233]=2, + [6234]=2, + [6235]=2, + [6236]=2, + [6237]=2, + [6238]=2, + [6239]=2, + [6240]=2, + [6241]=2, + [6242]=2, + [6243]=2, + [6244]=2, + [6245]=2, + [6246]=2, + [6247]=2, + [6248]=2, + [6249]=2, + [6250]=2, + [6251]=2, + [6252]=2, + [6253]=2, + [6254]=2, + [6255]=2, + [6256]=2, + [6257]=2, + [6258]=2, + [6259]=2, + [6260]=2, + [6261]=2, + [6262]=2, + [6263]=2, + [6264]=2, + [6272]=4, + [6273]=4, + [6274]=4, + [6275]=4, + [6276]=4, + [6279]=2, + [6280]=2, + [6281]=2, + [6282]=2, + [6283]=2, + [6284]=2, + [6285]=2, + [6286]=2, + [6287]=2, + [6288]=2, + [6289]=2, + [6290]=2, + [6291]=2, + [6292]=2, + [6293]=2, + [6294]=2, + [6295]=2, + [6296]=2, + [6297]=2, + [6298]=2, + [6299]=2, + [6300]=2, + [6301]=2, + [6302]=2, + [6303]=2, + [6304]=2, + [6305]=2, + [6306]=2, + [6307]=2, + [6308]=2, + [6309]=2, + [6310]=2, + [6311]=2, + [6312]=2, + [6313]=5, + [6314]=2, + [6432]=5, + [6433]=5, + [6434]=5, + [6439]=5, + [6440]=5, + [6450]=5, + [6457]=5, + [6458]=5, + [6459]=5, + [6679]=5, + [6680]=5, + [6742]=5, + [6744]=5, + [6745]=5, + [6746]=5, + [6747]=5, + [6748]=5, + [6749]=5, + [6750]=5, + [6752]=5, + [6754]=5, + [6757]=5, + [6758]=5, + [6759]=5, + [6760]=5, + [6761]=5, + [6762]=5, + [6763]=5, + [6764]=5, + [6771]=5, + [6772]=5, + [6773]=5, + [6774]=5, + [6775]=5, + [6776]=5, + [6777]=5, + [6778]=5, + [6779]=5, + [6780]=5, + [6783]=5, + [6832]=5, + [6833]=5, + [6834]=5, + [6835]=5, + [6836]=5, + [6837]=5, + [6838]=5, + [6839]=5, + [6840]=5, + [6841]=5, + [6842]=5, + [6843]=5, + [6844]=5, + [6845]=5, + [6912]=5, + [6913]=5, + [6914]=5, + [6915]=5, + [6964]=5, + [6966]=5, + [6967]=5, + [6968]=5, + [6969]=5, + [6970]=5, + [6972]=5, + [6978]=5, + [7019]=5, + [7020]=5, + [7021]=5, + [7022]=5, + [7023]=5, + [7024]=5, + [7025]=5, + [7026]=5, + [7027]=5, + [7040]=5, + [7041]=5, + [7074]=5, + [7075]=5, + [7076]=5, + [7077]=5, + [7080]=5, + [7081]=5, + [7083]=5, + [7142]=5, + [7144]=5, + [7145]=5, + [7149]=5, + [7151]=5, + [7152]=5, + [7153]=5, + [7212]=5, + [7213]=5, + [7214]=5, + [7215]=5, + [7216]=5, + [7217]=5, + [7218]=5, + [7219]=5, + [7222]=5, + [7223]=5, + [7376]=5, + [7377]=5, + [7378]=5, + [7380]=5, + [7381]=5, + [7382]=5, + [7383]=5, + [7384]=5, + [7385]=5, + [7386]=5, + [7387]=5, + [7388]=5, + [7389]=5, + [7390]=5, + [7391]=5, + [7392]=5, + [7394]=5, + [7395]=5, + [7396]=5, + [7397]=5, + [7398]=5, + [7399]=5, + [7400]=5, + [7405]=5, + [7412]=5, + [7416]=5, + [7417]=5, + [7616]=5, + [7617]=5, + [7618]=5, + [7619]=5, + [7620]=5, + [7621]=5, + [7622]=5, + [7623]=5, + [7624]=5, + [7625]=5, + [7626]=5, + [7627]=5, + [7628]=5, + [7629]=5, + [7630]=5, + [7631]=5, + [7632]=5, + [7633]=5, + [7634]=5, + [7635]=5, + [7636]=5, + [7637]=5, + [7638]=5, + [7639]=5, + [7640]=5, + [7641]=5, + [7642]=5, + [7643]=5, + [7644]=5, + [7645]=5, + [7646]=5, + [7647]=5, + [7648]=5, + [7649]=5, + [7650]=5, + [7651]=5, + [7652]=5, + [7653]=5, + [7654]=5, + [7655]=5, + [7656]=5, + [7657]=5, + [7658]=5, + [7659]=5, + [7660]=5, + [7661]=5, + [7662]=5, + [7663]=5, + [7664]=5, + [7665]=5, + [7666]=5, + [7667]=5, + [7668]=5, + [7669]=5, + [7670]=5, + [7671]=5, + [7672]=5, + [7673]=5, + [7675]=5, + [7676]=5, + [7677]=5, + [7678]=5, + [7679]=5, + [8204]=4, + [8205]=2, + [8239]=4, + [8294]=4, + [8295]=4, + [8296]=4, + [8297]=4, + [8400]=5, + [8401]=5, + [8402]=5, + [8403]=5, + [8404]=5, + [8405]=5, + [8406]=5, + [8407]=5, + [8408]=5, + [8409]=5, + [8410]=5, + [8411]=5, + [8412]=5, + [8417]=5, + [8421]=5, + [8422]=5, + [8423]=5, + [8424]=5, + [8425]=5, + [8426]=5, + [8427]=5, + [8428]=5, + [8429]=5, + [8430]=5, + [8431]=5, + [8432]=5, + [11503]=5, + [11504]=5, + [11505]=5, + [11647]=5, + [11744]=5, + [11745]=5, + [11746]=5, + [11747]=5, + [11748]=5, + [11749]=5, + [11750]=5, + [11751]=5, + [11752]=5, + [11753]=5, + [11754]=5, + [11755]=5, + [11756]=5, + [11757]=5, + [11758]=5, + [11759]=5, + [11760]=5, + [11761]=5, + [11762]=5, + [11763]=5, + [11764]=5, + [11765]=5, + [11766]=5, + [11767]=5, + [11768]=5, + [11769]=5, + [11770]=5, + [11771]=5, + [11772]=5, + [11773]=5, + [11774]=5, + [11775]=5, + [12330]=5, + [12331]=5, + [12332]=5, + [12333]=5, + [12334]=5, + [12335]=5, + [12441]=5, + [12442]=5, + [42607]=5, + [42612]=5, + [42613]=5, + [42614]=5, + [42615]=5, + [42616]=5, + [42617]=5, + [42618]=5, + [42619]=5, + [42620]=5, + [42621]=5, + [42654]=5, + [42655]=5, + [42736]=5, + [42737]=5, + [43014]=5, + [43019]=5, + [43045]=5, + [43046]=5, + [43072]=2, + [43073]=2, + [43074]=2, + [43075]=2, + [43076]=2, + [43077]=2, + [43078]=2, + [43079]=2, + [43080]=2, + [43081]=2, + [43082]=2, + [43083]=2, + [43084]=2, + [43085]=2, + [43086]=2, + [43087]=2, + [43088]=2, + [43089]=2, + [43090]=2, + [43091]=2, + [43092]=2, + [43093]=2, + [43094]=2, + [43095]=2, + [43096]=2, + [43097]=2, + [43098]=2, + [43099]=2, + [43100]=2, + [43101]=2, + [43102]=2, + [43103]=2, + [43104]=2, + [43105]=2, + [43106]=2, + [43107]=2, + [43108]=2, + [43109]=2, + [43110]=2, + [43111]=2, + [43112]=2, + [43113]=2, + [43114]=2, + [43115]=2, + [43116]=2, + [43117]=2, + [43118]=2, + [43119]=2, + [43120]=2, + [43121]=2, + [43122]=1, + [43123]=4, + [43204]=5, + [43205]=5, + [43232]=5, + [43233]=5, + [43234]=5, + [43235]=5, + [43236]=5, + [43237]=5, + [43238]=5, + [43239]=5, + [43240]=5, + [43241]=5, + [43242]=5, + [43243]=5, + [43244]=5, + [43245]=5, + [43246]=5, + [43247]=5, + [43248]=5, + [43249]=5, + [43263]=5, + [43302]=5, + [43303]=5, + [43304]=5, + [43305]=5, + [43306]=5, + [43307]=5, + [43308]=5, + [43309]=5, + [43335]=5, + [43336]=5, + [43337]=5, + [43338]=5, + [43339]=5, + [43340]=5, + [43341]=5, + [43342]=5, + [43343]=5, + [43344]=5, + [43345]=5, + [43392]=5, + [43393]=5, + [43394]=5, + [43443]=5, + [43446]=5, + [43447]=5, + [43448]=5, + [43449]=5, + [43452]=5, + [43493]=5, + [43561]=5, + [43562]=5, + [43563]=5, + [43564]=5, + [43565]=5, + [43566]=5, + [43569]=5, + [43570]=5, + [43573]=5, + [43574]=5, + [43587]=5, + [43596]=5, + [43644]=5, + [43696]=5, + [43698]=5, + [43699]=5, + [43700]=5, + [43703]=5, + [43704]=5, + [43710]=5, + [43711]=5, + [43713]=5, + [43756]=5, + [43757]=5, + [43766]=5, + [44005]=5, + [44008]=5, + [44013]=5, + [64286]=5, + [65056]=5, + [65057]=5, + [65058]=5, + [65059]=5, + [65060]=5, + [65061]=5, + [65062]=5, + [65063]=5, + [65064]=5, + [65065]=5, + [65066]=5, + [65067]=5, + [65068]=5, + [65069]=5, + [65070]=5, + [65071]=5, + [66045]=5, + [66272]=5, + [66422]=5, + [66423]=5, + [66424]=5, + [66425]=5, + [66426]=5, + [68097]=5, + [68098]=5, + [68099]=5, + [68101]=5, + [68102]=5, + [68108]=5, + [68109]=5, + [68110]=5, + [68111]=5, + [68152]=5, + [68153]=5, + [68154]=5, + [68159]=5, + [68288]=2, + [68289]=2, + [68290]=2, + [68291]=2, + [68292]=2, + [68293]=3, + [68294]=4, + [68295]=3, + [68296]=4, + [68297]=3, + [68298]=3, + [68299]=4, + [68300]=4, + [68301]=1, + [68302]=3, + [68303]=3, + [68304]=3, + [68305]=3, + [68306]=3, + [68307]=2, + [68308]=2, + [68309]=2, + [68310]=2, + [68311]=1, + [68312]=2, + [68313]=2, + [68314]=2, + [68315]=2, + [68316]=2, + [68317]=3, + [68318]=2, + [68319]=2, + [68320]=2, + [68321]=3, + [68322]=4, + [68323]=4, + [68324]=3, + [68325]=5, + [68326]=5, + [68331]=2, + [68332]=2, + [68333]=2, + [68334]=2, + [68335]=3, + [68480]=2, + [68481]=3, + [68482]=2, + [68483]=3, + [68484]=3, + [68485]=3, + [68486]=2, + [68487]=2, + [68488]=2, + [68489]=3, + [68490]=2, + [68491]=2, + [68492]=3, + [68493]=2, + [68494]=3, + [68495]=3, + [68496]=2, + [68497]=3, + [68521]=3, + [68522]=3, + [68523]=3, + [68524]=3, + [68525]=2, + [68526]=2, + [68527]=4, + [68864]=1, + [68865]=2, + [68866]=2, + [68867]=2, + [68868]=2, + [68869]=2, + [68870]=2, + [68871]=2, + [68872]=2, + [68873]=2, + [68874]=2, + [68875]=2, + [68876]=2, + [68877]=2, + [68878]=2, + [68879]=2, + [68880]=2, + [68881]=2, + [68882]=2, + [68883]=2, + [68884]=2, + [68885]=2, + [68886]=2, + [68887]=2, + [68888]=2, + [68889]=2, + [68890]=2, + [68891]=2, + [68892]=2, + [68893]=2, + [68894]=2, + [68895]=2, + [68896]=2, + [68897]=2, + [68898]=3, + [68899]=2, + [68900]=5, + [68901]=5, + [68902]=5, + [68903]=5, + [69424]=2, + [69425]=2, + [69426]=2, + [69427]=3, + [69428]=2, + [69429]=2, + [69430]=2, + [69431]=2, + [69432]=2, + [69433]=2, + [69434]=2, + [69435]=2, + [69436]=2, + [69437]=2, + [69438]=2, + [69439]=2, + [69440]=2, + [69441]=2, + [69442]=2, + [69443]=2, + [69444]=2, + [69445]=4, + [69446]=5, + [69447]=5, + [69448]=5, + [69449]=5, + [69450]=5, + [69451]=5, + [69452]=5, + [69453]=5, + [69454]=5, + [69455]=5, + [69456]=5, + [69457]=2, + [69458]=2, + [69459]=2, + [69460]=3, + [69633]=5, + [69688]=5, + [69689]=5, + [69690]=5, + [69691]=5, + [69692]=5, + [69693]=5, + [69694]=5, + [69695]=5, + [69696]=5, + [69697]=5, + [69698]=5, + [69699]=5, + [69700]=5, + [69701]=5, + [69702]=5, + [69759]=5, + [69760]=5, + [69761]=5, + [69811]=5, + [69812]=5, + [69813]=5, + [69814]=5, + [69817]=5, + [69818]=5, + [69821]=4, + [69837]=4, + [69888]=5, + [69889]=5, + [69890]=5, + [69927]=5, + [69928]=5, + [69929]=5, + [69930]=5, + [69931]=5, + [69933]=5, + [69934]=5, + [69935]=5, + [69936]=5, + [69937]=5, + [69938]=5, + [69939]=5, + [69940]=5, + [70003]=5, + [70016]=5, + [70017]=5, + [70070]=5, + [70071]=5, + [70072]=5, + [70073]=5, + [70074]=5, + [70075]=5, + [70076]=5, + [70077]=5, + [70078]=5, + [70090]=5, + [70091]=5, + [70092]=5, + [70191]=5, + [70192]=5, + [70193]=5, + [70196]=5, + [70198]=5, + [70199]=5, + [70206]=5, + [70367]=5, + [70371]=5, + [70372]=5, + [70373]=5, + [70374]=5, + [70375]=5, + [70376]=5, + [70377]=5, + [70378]=5, + [70400]=5, + [70401]=5, + [70459]=5, + [70460]=5, + [70464]=5, + [70502]=5, + [70503]=5, + [70504]=5, + [70505]=5, + [70506]=5, + [70507]=5, + [70508]=5, + [70512]=5, + [70513]=5, + [70514]=5, + [70515]=5, + [70516]=5, + [70712]=5, + [70713]=5, + [70714]=5, + [70715]=5, + [70716]=5, + [70717]=5, + [70718]=5, + [70719]=5, + [70722]=5, + [70723]=5, + [70724]=5, + [70726]=5, + [70750]=5, + [70835]=5, + [70836]=5, + [70837]=5, + [70838]=5, + [70839]=5, + [70840]=5, + [70842]=5, + [70847]=5, + [70848]=5, + [70850]=5, + [70851]=5, + [71090]=5, + [71091]=5, + [71092]=5, + [71093]=5, + [71100]=5, + [71101]=5, + [71103]=5, + [71104]=5, + [71132]=5, + [71133]=5, + [71219]=5, + [71220]=5, + [71221]=5, + [71222]=5, + [71223]=5, + [71224]=5, + [71225]=5, + [71226]=5, + [71229]=5, + [71231]=5, + [71232]=5, + [71339]=5, + [71341]=5, + [71344]=5, + [71345]=5, + [71346]=5, + [71347]=5, + [71348]=5, + [71349]=5, + [71351]=5, + [71453]=5, + [71454]=5, + [71455]=5, + [71458]=5, + [71459]=5, + [71460]=5, + [71461]=5, + [71463]=5, + [71464]=5, + [71465]=5, + [71466]=5, + [71467]=5, + [71727]=5, + [71728]=5, + [71729]=5, + [71730]=5, + [71731]=5, + [71732]=5, + [71733]=5, + [71734]=5, + [71735]=5, + [71737]=5, + [71738]=5, + [72148]=5, + [72149]=5, + [72150]=5, + [72151]=5, + [72154]=5, + [72155]=5, + [72160]=5, + [72193]=5, + [72194]=5, + [72195]=5, + [72196]=5, + [72197]=5, + [72198]=5, + [72201]=5, + [72202]=5, + [72243]=5, + [72244]=5, + [72245]=5, + [72246]=5, + [72247]=5, + [72248]=5, + [72251]=5, + [72252]=5, + [72253]=5, + [72254]=5, + [72263]=5, + [72273]=5, + [72274]=5, + [72275]=5, + [72276]=5, + [72277]=5, + [72278]=5, + [72281]=5, + [72282]=5, + [72283]=5, + [72330]=5, + [72331]=5, + [72332]=5, + [72333]=5, + [72334]=5, + [72335]=5, + [72336]=5, + [72337]=5, + [72338]=5, + [72339]=5, + [72340]=5, + [72341]=5, + [72342]=5, + [72344]=5, + [72345]=5, + [72752]=5, + [72753]=5, + [72754]=5, + [72755]=5, + [72756]=5, + [72757]=5, + [72758]=5, + [72760]=5, + [72761]=5, + [72762]=5, + [72763]=5, + [72764]=5, + [72765]=5, + [72767]=5, + [72850]=5, + [72851]=5, + [72852]=5, + [72853]=5, + [72854]=5, + [72855]=5, + [72856]=5, + [72857]=5, + [72858]=5, + [72859]=5, + [72860]=5, + [72861]=5, + [72862]=5, + [72863]=5, + [72864]=5, + [72865]=5, + [72866]=5, + [72867]=5, + [72868]=5, + [72869]=5, + [72870]=5, + [72871]=5, + [72874]=5, + [72875]=5, + [72876]=5, + [72877]=5, + [72878]=5, + [72879]=5, + [72880]=5, + [72882]=5, + [72883]=5, + [72885]=5, + [72886]=5, + [73009]=5, + [73010]=5, + [73011]=5, + [73012]=5, + [73013]=5, + [73014]=5, + [73018]=5, + [73020]=5, + [73021]=5, + [73023]=5, + [73024]=5, + [73025]=5, + [73026]=5, + [73027]=5, + [73028]=5, + [73029]=5, + [73031]=5, + [73104]=5, + [73105]=5, + [73109]=5, + [73111]=5, + [73459]=5, + [73460]=5, + [92912]=5, + [92913]=5, + [92914]=5, + [92915]=5, + [92916]=5, + [92976]=5, + [92977]=5, + [92978]=5, + [92979]=5, + [92980]=5, + [92981]=5, + [92982]=5, + [94031]=5, + [94095]=5, + [94096]=5, + [94097]=5, + [94098]=5, + [113821]=5, + [113822]=5, + [119143]=5, + [119144]=5, + [119145]=5, + [119163]=5, + [119164]=5, + [119165]=5, + [119166]=5, + [119167]=5, + [119168]=5, + [119169]=5, + [119170]=5, + [119173]=5, + [119174]=5, + [119175]=5, + [119176]=5, + [119177]=5, + [119178]=5, + [119179]=5, + [119210]=5, + [119211]=5, + [119212]=5, + [119213]=5, + [119362]=5, + [119363]=5, + [119364]=5, + [121344]=5, + [121345]=5, + [121346]=5, + [121347]=5, + [121348]=5, + [121349]=5, + [121350]=5, + [121351]=5, + [121352]=5, + [121353]=5, + [121354]=5, + [121355]=5, + [121356]=5, + [121357]=5, + [121358]=5, + [121359]=5, + [121360]=5, + [121361]=5, + [121362]=5, + [121363]=5, + [121364]=5, + [121365]=5, + [121366]=5, + [121367]=5, + [121368]=5, + [121369]=5, + [121370]=5, + [121371]=5, + [121372]=5, + [121373]=5, + [121374]=5, + [121375]=5, + [121376]=5, + [121377]=5, + [121378]=5, + [121379]=5, + [121380]=5, + [121381]=5, + [121382]=5, + [121383]=5, + [121384]=5, + [121385]=5, + [121386]=5, + [121387]=5, + [121388]=5, + [121389]=5, + [121390]=5, + [121391]=5, + [121392]=5, + [121393]=5, + [121394]=5, + [121395]=5, + [121396]=5, + [121397]=5, + [121398]=5, + [121403]=5, + [121404]=5, + [121405]=5, + [121406]=5, + [121407]=5, + [121408]=5, + [121409]=5, + [121410]=5, + [121411]=5, + [121412]=5, + [121413]=5, + [121414]=5, + [121415]=5, + [121416]=5, + [121417]=5, + [121418]=5, + [121419]=5, + [121420]=5, + [121421]=5, + [121422]=5, + [121423]=5, + [121424]=5, + [121425]=5, + [121426]=5, + [121427]=5, + [121428]=5, + [121429]=5, + [121430]=5, + [121431]=5, + [121432]=5, + [121433]=5, + [121434]=5, + [121435]=5, + [121436]=5, + [121437]=5, + [121438]=5, + [121439]=5, + [121440]=5, + [121441]=5, + [121442]=5, + [121443]=5, + [121444]=5, + [121445]=5, + [121446]=5, + [121447]=5, + [121448]=5, + [121449]=5, + [121450]=5, + [121451]=5, + [121452]=5, + [121461]=5, + [121476]=5, + [121499]=5, + [121500]=5, + [121501]=5, + [121502]=5, + [121503]=5, + [121505]=5, + [121506]=5, + [121507]=5, + [121508]=5, + [121509]=5, + [121510]=5, + [121511]=5, + [121512]=5, + [121513]=5, + [121514]=5, + [121515]=5, + [121516]=5, + [121517]=5, + [121518]=5, + [121519]=5, + [122880]=5, + [122881]=5, + [122882]=5, + [122883]=5, + [122884]=5, + [122885]=5, + [122886]=5, + [122888]=5, + [122889]=5, + [122890]=5, + [122891]=5, + [122892]=5, + [122893]=5, + [122894]=5, + [122895]=5, + [122896]=5, + [122897]=5, + [122898]=5, + [122899]=5, + [122900]=5, + [122901]=5, + [122902]=5, + [122903]=5, + [122904]=5, + [122907]=5, + [122908]=5, + [122909]=5, + [122910]=5, + [122911]=5, + [122912]=5, + [122913]=5, + [122915]=5, + [122916]=5, + [122918]=5, + [122919]=5, + [122920]=5, + [122921]=5, + [122922]=5, + [123184]=5, + [123185]=5, + [123186]=5, + [123187]=5, + [123188]=5, + [123189]=5, + [123190]=5, + [123628]=5, + [123629]=5, + [123630]=5, + [123631]=5, + [125136]=5, + [125137]=5, + [125138]=5, + [125139]=5, + [125140]=5, + [125141]=5, + [125142]=5, + [125184]=2, + [125185]=2, + [125186]=2, + [125187]=2, + [125188]=2, + [125189]=2, + [125190]=2, + [125191]=2, + [125192]=2, + [125193]=2, + [125194]=2, + [125195]=2, + [125196]=2, + [125197]=2, + [125198]=2, + [125199]=2, + [125200]=2, + [125201]=2, + [125202]=2, + [125203]=2, + [125204]=2, + [125205]=2, + [125206]=2, + [125207]=2, + [125208]=2, + [125209]=2, + [125210]=2, + [125211]=2, + [125212]=2, + [125213]=2, + [125214]=2, + [125215]=2, + [125216]=2, + [125217]=2, + [125218]=2, + [125219]=2, + [125220]=2, + [125221]=2, + [125222]=2, + [125223]=2, + [125224]=2, + [125225]=2, + [125226]=2, + [125227]=2, + [125228]=2, + [125229]=2, + [125230]=2, + [125231]=2, + [125232]=2, + [125233]=2, + [125234]=2, + [125235]=2, + [125236]=2, + [125237]=2, + [125238]=2, + [125239]=2, + [125240]=2, + [125241]=2, + [125242]=2, + [125243]=2, + [125244]=2, + [125245]=2, + [125246]=2, + [125247]=2, + [125248]=2, + [125249]=2, + [125250]=2, + [125251]=2, + [125252]=5, + [125253]=5, + [125254]=5, + [125255]=5, + [125256]=5, + [125257]=5, + [125258]=5, + [1042752]=5, +} +characters.indicgroups={ + ["above_mark"]={ + [2304]=true, + [2305]=true, + [2306]=true, + [2362]=true, + [2373]=true, + [2374]=true, + [2375]=true, + [2376]=true, + [2385]=true, + [2387]=true, + [2388]=true, + [2389]=true, + [2631]=true, + [2632]=true, + [2635]=true, + [2636]=true, + [2690]=true, + [2757]=true, + [2759]=true, + [2760]=true, + [2879]=true, + [3008]=true, + [3021]=true, + [3134]=true, + [3135]=true, + [3136]=true, + [3142]=true, + [3143]=true, + [3146]=true, + [3147]=true, + [3148]=true, + [3149]=true, + [3263]=true, + [3270]=true, + [3406]=true, + [4141]=true, + [4142]=true, + [4146]=true, + [4147]=true, + [4148]=true, + [4149]=true, + [4150]=true, + [4154]=true, + [4209]=true, + [4210]=true, + [4211]=true, + [4212]=true, + [4229]=true, + [4230]=true, + [4253]=true, + [43232]=true, + [43233]=true, + [43234]=true, + [43235]=true, + [43236]=true, + [43237]=true, + [43238]=true, + [43239]=true, + [43240]=true, + [43241]=true, + [43242]=true, + [43243]=true, + [43244]=true, + [43245]=true, + [43246]=true, + [43247]=true, + [43248]=true, + [43249]=true, + [43493]=true, + [43644]=true, + }, + ["after_half"]={}, + ["after_main"]={ + [2864]=true, + [2879]=true, + [2902]=true, + [3376]=true, + }, + ["after_postscript"]={ + [2433]=true, + [2494]=true, + [2496]=true, + [2519]=true, + [2561]=true, + [2562]=true, + [2622]=true, + [2624]=true, + [2625]=true, + [2626]=true, + [2672]=true, + [2673]=true, + [2735]=true, + [2750]=true, + [2752]=true, + [2753]=true, + [2754]=true, + [2755]=true, + [2756]=true, + [2761]=true, + [2763]=true, + [2764]=true, + [2786]=true, + [2787]=true, + [2878]=true, + [2880]=true, + [2903]=true, + [2992]=true, + [3006]=true, + [3007]=true, + [3009]=true, + [3010]=true, + [3031]=true, + [3120]=true, + [3248]=true, + [3390]=true, + [3391]=true, + [3392]=true, + [3393]=true, + [3394]=true, + [3395]=true, + [3415]=true, + }, + ["after_subscript"]={ + [2366]=true, + [2368]=true, + [2369]=true, + [2370]=true, + [2371]=true, + [2372]=true, + [2373]=true, + [2374]=true, + [2375]=true, + [2376]=true, + [2377]=true, + [2378]=true, + [2379]=true, + [2380]=true, + [2402]=true, + [2403]=true, + [2480]=true, + [2497]=true, + [2498]=true, + [2499]=true, + [2500]=true, + [2530]=true, + [2531]=true, + [2544]=true, + [2631]=true, + [2632]=true, + [2635]=true, + [2636]=true, + [2757]=true, + [2759]=true, + [2760]=true, + [2881]=true, + [2882]=true, + [2883]=true, + [3008]=true, + [3139]=true, + [3140]=true, + [3267]=true, + [3268]=true, + [3285]=true, + [3286]=true, + }, + ["anudatta"]={ + [2386]=true, + }, + ["before_half"]={ + [2367]=true, + [2382]=true, + [2495]=true, + [2503]=true, + [2504]=true, + [2623]=true, + [2751]=true, + [2887]=true, + }, + ["before_main"]={ + [3014]=true, + [3015]=true, + [3016]=true, + [3398]=true, + [3399]=true, + [3400]=true, + }, + ["before_postscript"]={ + [2352]=true, + [2736]=true, + }, + ["before_subscript"]={ + [2608]=true, + [2817]=true, + [3134]=true, + [3135]=true, + [3136]=true, + [3137]=true, + [3138]=true, + [3142]=true, + [3143]=true, + [3146]=true, + [3147]=true, + [3148]=true, + [3157]=true, + [3158]=true, + [3262]=true, + [3263]=true, + [3265]=true, + [3266]=true, + [3270]=true, + [3276]=true, + [3298]=true, + [3299]=true, + }, + ["below_mark"]={ + [2364]=true, + [2369]=true, + [2370]=true, + [2371]=true, + [2372]=true, + [2381]=true, + [2386]=true, + [2390]=true, + [2391]=true, + [2402]=true, + [2403]=true, + [2492]=true, + [2497]=true, + [2498]=true, + [2499]=true, + [2500]=true, + [2509]=true, + [2620]=true, + [2625]=true, + [2626]=true, + [2637]=true, + [2748]=true, + [2753]=true, + [2754]=true, + [2755]=true, + [2756]=true, + [2765]=true, + [2876]=true, + [2881]=true, + [2882]=true, + [2883]=true, + [2884]=true, + [2893]=true, + [2914]=true, + [2915]=true, + [3009]=true, + [3010]=true, + [3170]=true, + [3171]=true, + [3260]=true, + [3286]=true, + [3298]=true, + [3299]=true, + [3426]=true, + [3427]=true, + [4143]=true, + [4144]=true, + [4151]=true, + [4153]=true, + [4157]=true, + [4158]=true, + [4184]=true, + [4185]=true, + [4190]=true, + [4191]=true, + [4192]=true, + [4226]=true, + [4237]=true, + }, + ["consonant"]={ + [2325]=true, + [2326]=true, + [2327]=true, + [2328]=true, + [2329]=true, + [2330]=true, + [2331]=true, + [2332]=true, + [2333]=true, + [2334]=true, + [2335]=true, + [2336]=true, + [2337]=true, + [2338]=true, + [2339]=true, + [2340]=true, + [2341]=true, + [2342]=true, + [2343]=true, + [2344]=true, + [2345]=true, + [2346]=true, + [2347]=true, + [2348]=true, + [2349]=true, + [2350]=true, + [2351]=true, + [2352]=true, + [2353]=true, + [2354]=true, + [2355]=true, + [2356]=true, + [2357]=true, + [2358]=true, + [2359]=true, + [2360]=true, + [2361]=true, + [2392]=true, + [2393]=true, + [2394]=true, + [2395]=true, + [2396]=true, + [2397]=true, + [2398]=true, + [2399]=true, + [2424]=true, + [2425]=true, + [2426]=true, + [2453]=true, + [2454]=true, + [2455]=true, + [2456]=true, + [2457]=true, + [2458]=true, + [2459]=true, + [2460]=true, + [2461]=true, + [2462]=true, + [2463]=true, + [2464]=true, + [2465]=true, + [2466]=true, + [2467]=true, + [2468]=true, + [2469]=true, + [2470]=true, + [2471]=true, + [2472]=true, + [2474]=true, + [2475]=true, + [2476]=true, + [2477]=true, + [2478]=true, + [2479]=true, + [2480]=true, + [2482]=true, + [2486]=true, + [2487]=true, + [2488]=true, + [2489]=true, + [2510]=true, + [2524]=true, + [2525]=true, + [2527]=true, + [2581]=true, + [2582]=true, + [2583]=true, + [2584]=true, + [2585]=true, + [2586]=true, + [2587]=true, + [2588]=true, + [2589]=true, + [2590]=true, + [2591]=true, + [2592]=true, + [2593]=true, + [2594]=true, + [2595]=true, + [2596]=true, + [2597]=true, + [2598]=true, + [2599]=true, + [2600]=true, + [2602]=true, + [2603]=true, + [2604]=true, + [2605]=true, + [2606]=true, + [2607]=true, + [2608]=true, + [2610]=true, + [2611]=true, + [2613]=true, + [2614]=true, + [2616]=true, + [2617]=true, + [2649]=true, + [2650]=true, + [2651]=true, + [2652]=true, + [2654]=true, + [2709]=true, + [2710]=true, + [2711]=true, + [2712]=true, + [2713]=true, + [2714]=true, + [2715]=true, + [2716]=true, + [2717]=true, + [2718]=true, + [2719]=true, + [2720]=true, + [2721]=true, + [2722]=true, + [2723]=true, + [2724]=true, + [2725]=true, + [2726]=true, + [2727]=true, + [2728]=true, + [2730]=true, + [2731]=true, + [2732]=true, + [2733]=true, + [2734]=true, + [2735]=true, + [2736]=true, + [2738]=true, + [2739]=true, + [2741]=true, + [2742]=true, + [2743]=true, + [2744]=true, + [2745]=true, + [2837]=true, + [2838]=true, + [2839]=true, + [2840]=true, + [2841]=true, + [2842]=true, + [2843]=true, + [2844]=true, + [2845]=true, + [2846]=true, + [2847]=true, + [2848]=true, + [2849]=true, + [2850]=true, + [2851]=true, + [2852]=true, + [2853]=true, + [2854]=true, + [2855]=true, + [2856]=true, + [2858]=true, + [2859]=true, + [2860]=true, + [2861]=true, + [2862]=true, + [2863]=true, + [2864]=true, + [2866]=true, + [2867]=true, + [2869]=true, + [2870]=true, + [2871]=true, + [2872]=true, + [2873]=true, + [2908]=true, + [2909]=true, + [2929]=true, + [2965]=true, + [2969]=true, + [2970]=true, + [2972]=true, + [2974]=true, + [2975]=true, + [2979]=true, + [2980]=true, + [2984]=true, + [2985]=true, + [2986]=true, + [2990]=true, + [2991]=true, + [2992]=true, + [2993]=true, + [2994]=true, + [2995]=true, + [2996]=true, + [2997]=true, + [2998]=true, + [2999]=true, + [3000]=true, + [3001]=true, + [3093]=true, + [3094]=true, + [3095]=true, + [3096]=true, + [3097]=true, + [3098]=true, + [3099]=true, + [3100]=true, + [3101]=true, + [3102]=true, + [3103]=true, + [3104]=true, + [3105]=true, + [3106]=true, + [3107]=true, + [3108]=true, + [3109]=true, + [3110]=true, + [3111]=true, + [3112]=true, + [3114]=true, + [3115]=true, + [3116]=true, + [3117]=true, + [3118]=true, + [3119]=true, + [3120]=true, + [3121]=true, + [3122]=true, + [3123]=true, + [3124]=true, + [3125]=true, + [3126]=true, + [3127]=true, + [3128]=true, + [3129]=true, + [3133]=true, + [3221]=true, + [3222]=true, + [3223]=true, + [3224]=true, + [3225]=true, + [3226]=true, + [3227]=true, + [3228]=true, + [3229]=true, + [3230]=true, + [3231]=true, + [3232]=true, + [3233]=true, + [3234]=true, + [3235]=true, + [3236]=true, + [3237]=true, + [3238]=true, + [3239]=true, + [3240]=true, + [3242]=true, + [3243]=true, + [3244]=true, + [3245]=true, + [3246]=true, + [3247]=true, + [3248]=true, + [3249]=true, + [3250]=true, + [3251]=true, + [3253]=true, + [3254]=true, + [3255]=true, + [3256]=true, + [3257]=true, + [3294]=true, + [3349]=true, + [3350]=true, + [3351]=true, + [3352]=true, + [3353]=true, + [3354]=true, + [3355]=true, + [3356]=true, + [3357]=true, + [3358]=true, + [3359]=true, + [3360]=true, + [3361]=true, + [3362]=true, + [3363]=true, + [3364]=true, + [3365]=true, + [3366]=true, + [3367]=true, + [3368]=true, + [3369]=true, + [3370]=true, + [3371]=true, + [3372]=true, + [3373]=true, + [3374]=true, + [3375]=true, + [3376]=true, + [3377]=true, + [3378]=true, + [3379]=true, + [3380]=true, + [3381]=true, + [3382]=true, + [3383]=true, + [3384]=true, + [3385]=true, + [3386]=true, + [4096]=true, + [4097]=true, + [4098]=true, + [4099]=true, + [4100]=true, + [4101]=true, + [4102]=true, + [4103]=true, + [4104]=true, + [4105]=true, + [4106]=true, + [4107]=true, + [4108]=true, + [4109]=true, + [4110]=true, + [4111]=true, + [4112]=true, + [4113]=true, + [4114]=true, + [4115]=true, + [4116]=true, + [4117]=true, + [4118]=true, + [4119]=true, + [4120]=true, + [4121]=true, + [4122]=true, + [4123]=true, + [4124]=true, + [4125]=true, + [4126]=true, + [4127]=true, + [4128]=true, + [4155]=true, + [4156]=true, + [4157]=true, + [4158]=true, + [4159]=true, + [4176]=true, + [4177]=true, + [4186]=true, + [4187]=true, + [4188]=true, + [4189]=true, + [4190]=true, + [4191]=true, + [4192]=true, + [4193]=true, + [4197]=true, + [4198]=true, + [4206]=true, + [4207]=true, + [4208]=true, + [4213]=true, + [4214]=true, + [4215]=true, + [4216]=true, + [4217]=true, + [4218]=true, + [4219]=true, + [4220]=true, + [4221]=true, + [4222]=true, + [4223]=true, + [4224]=true, + [4225]=true, + [4226]=true, + [4238]=true, + [43488]=true, + [43489]=true, + [43490]=true, + [43491]=true, + [43492]=true, + [43495]=true, + [43496]=true, + [43497]=true, + [43498]=true, + [43499]=true, + [43500]=true, + [43501]=true, + [43502]=true, + [43503]=true, + [43514]=true, + [43515]=true, + [43516]=true, + [43517]=true, + [43518]=true, + [43616]=true, + [43617]=true, + [43618]=true, + [43619]=true, + [43620]=true, + [43621]=true, + [43622]=true, + [43623]=true, + [43624]=true, + [43625]=true, + [43626]=true, + [43628]=true, + [43629]=true, + [43630]=true, + [43631]=true, + [43633]=true, + [43634]=true, + [43635]=true, + [43636]=true, + [43637]=true, + [43638]=true, + [43642]=true, + [43646]=true, + [43647]=true, + }, + ["dependent_vowel"]={ + [2362]=true, + [2363]=true, + [2366]=true, + [2367]=true, + [2368]=true, + [2369]=true, + [2370]=true, + [2371]=true, + [2372]=true, + [2373]=true, + [2374]=true, + [2375]=true, + [2376]=true, + [2377]=true, + [2378]=true, + [2379]=true, + [2380]=true, + [2382]=true, + [2383]=true, + [2389]=true, + [2390]=true, + [2391]=true, + [2402]=true, + [2403]=true, + [2494]=true, + [2495]=true, + [2497]=true, + [2498]=true, + [2499]=true, + [2500]=true, + [2503]=true, + [2504]=true, + [2507]=true, + [2508]=true, + [2622]=true, + [2623]=true, + [2624]=true, + [2625]=true, + [2626]=true, + [2631]=true, + [2632]=true, + [2635]=true, + [2636]=true, + [2750]=true, + [2751]=true, + [2752]=true, + [2753]=true, + [2754]=true, + [2755]=true, + [2756]=true, + [2757]=true, + [2759]=true, + [2760]=true, + [2761]=true, + [2763]=true, + [2764]=true, + [2878]=true, + [2879]=true, + [2880]=true, + [2881]=true, + [2882]=true, + [2883]=true, + [2884]=true, + [2887]=true, + [2888]=true, + [2891]=true, + [2892]=true, + [2914]=true, + [2915]=true, + [3006]=true, + [3007]=true, + [3008]=true, + [3009]=true, + [3010]=true, + [3014]=true, + [3015]=true, + [3016]=true, + [3018]=true, + [3019]=true, + [3020]=true, + [3134]=true, + [3135]=true, + [3136]=true, + [3137]=true, + [3138]=true, + [3139]=true, + [3140]=true, + [3142]=true, + [3143]=true, + [3144]=true, + [3146]=true, + [3147]=true, + [3148]=true, + [3170]=true, + [3171]=true, + [3262]=true, + [3263]=true, + [3264]=true, + [3265]=true, + [3266]=true, + [3267]=true, + [3268]=true, + [3270]=true, + [3271]=true, + [3272]=true, + [3274]=true, + [3275]=true, + [3276]=true, + [3285]=true, + [3286]=true, + [3298]=true, + [3299]=true, + [3390]=true, + [3391]=true, + [3392]=true, + [3393]=true, + [3394]=true, + [3395]=true, + [3396]=true, + [3398]=true, + [3399]=true, + [3400]=true, + [3402]=true, + [3403]=true, + [3404]=true, + [3415]=true, + [3426]=true, + [3427]=true, + [4139]=true, + [4140]=true, + [4141]=true, + [4142]=true, + [4143]=true, + [4144]=true, + [4145]=true, + [4146]=true, + [4147]=true, + [4148]=true, + [4149]=true, + [4182]=true, + [4183]=true, + [4184]=true, + [4185]=true, + [4194]=true, + [4199]=true, + [4200]=true, + [4209]=true, + [4210]=true, + [4211]=true, + [4212]=true, + [4227]=true, + [4228]=true, + [4229]=true, + [4230]=true, + [4252]=true, + [4253]=true, + [43493]=true, + }, + ["halant"]={ + [2381]=true, + [2509]=true, + [2637]=true, + [2765]=true, + [2893]=true, + [3021]=true, + [3149]=true, + [3277]=true, + [3405]=true, + }, + ["independent_vowel"]={ + [2308]=true, + [2309]=true, + [2310]=true, + [2311]=true, + [2312]=true, + [2313]=true, + [2314]=true, + [2315]=true, + [2316]=true, + [2317]=true, + [2318]=true, + [2319]=true, + [2320]=true, + [2321]=true, + [2322]=true, + [2323]=true, + [2324]=true, + [2400]=true, + [2401]=true, + [2418]=true, + [2419]=true, + [2420]=true, + [2421]=true, + [2422]=true, + [2423]=true, + [2437]=true, + [2438]=true, + [2439]=true, + [2440]=true, + [2441]=true, + [2442]=true, + [2443]=true, + [2444]=true, + [2447]=true, + [2448]=true, + [2451]=true, + [2452]=true, + [2528]=true, + [2529]=true, + [2530]=true, + [2531]=true, + [2565]=true, + [2566]=true, + [2567]=true, + [2568]=true, + [2569]=true, + [2570]=true, + [2575]=true, + [2576]=true, + [2579]=true, + [2580]=true, + [2693]=true, + [2694]=true, + [2695]=true, + [2696]=true, + [2697]=true, + [2698]=true, + [2699]=true, + [2700]=true, + [2701]=true, + [2703]=true, + [2704]=true, + [2705]=true, + [2707]=true, + [2708]=true, + [2784]=true, + [2785]=true, + [2786]=true, + [2787]=true, + [2821]=true, + [2822]=true, + [2823]=true, + [2824]=true, + [2825]=true, + [2826]=true, + [2827]=true, + [2828]=true, + [2831]=true, + [2832]=true, + [2835]=true, + [2836]=true, + [2912]=true, + [2913]=true, + [2949]=true, + [2950]=true, + [2951]=true, + [2952]=true, + [2953]=true, + [2954]=true, + [2958]=true, + [2959]=true, + [2960]=true, + [2962]=true, + [2963]=true, + [2964]=true, + [3077]=true, + [3078]=true, + [3079]=true, + [3080]=true, + [3081]=true, + [3082]=true, + [3083]=true, + [3084]=true, + [3086]=true, + [3087]=true, + [3088]=true, + [3090]=true, + [3091]=true, + [3092]=true, + [3168]=true, + [3169]=true, + [3205]=true, + [3206]=true, + [3207]=true, + [3208]=true, + [3209]=true, + [3210]=true, + [3211]=true, + [3212]=true, + [3214]=true, + [3215]=true, + [3216]=true, + [3218]=true, + [3219]=true, + [3220]=true, + [3296]=true, + [3297]=true, + [3333]=true, + [3334]=true, + [3335]=true, + [3336]=true, + [3337]=true, + [3338]=true, + [3339]=true, + [3340]=true, + [3342]=true, + [3343]=true, + [3344]=true, + [3346]=true, + [3347]=true, + [3348]=true, + [3423]=true, + [3424]=true, + [3425]=true, + [4129]=true, + [4130]=true, + [4131]=true, + [4132]=true, + [4133]=true, + [4134]=true, + [4135]=true, + [4136]=true, + [4137]=true, + [4138]=true, + [4178]=true, + [4179]=true, + [4180]=true, + [4181]=true, + }, + ["nukta"]={ + [2364]=true, + [2492]=true, + [2620]=true, + [2748]=true, + [2876]=true, + [3260]=true, + }, + ["post_mark"]={ + [2307]=true, + [2363]=true, + [2366]=true, + [2368]=true, + [2377]=true, + [2378]=true, + [2379]=true, + [2380]=true, + [2383]=true, + [2494]=true, + [2496]=true, + [2622]=true, + [2624]=true, + [2750]=true, + [2752]=true, + [2761]=true, + [2763]=true, + [2764]=true, + [2878]=true, + [2880]=true, + [3006]=true, + [3007]=true, + [3137]=true, + [3138]=true, + [3139]=true, + [3140]=true, + [3262]=true, + [3265]=true, + [3266]=true, + [3267]=true, + [3268]=true, + [3276]=true, + [3285]=true, + [3390]=true, + [3391]=true, + [3392]=true, + [3393]=true, + [3394]=true, + [3395]=true, + [3396]=true, + [3415]=true, + [4139]=true, + [4140]=true, + [4152]=true, + [4155]=true, + [4182]=true, + [4183]=true, + [4194]=true, + [4195]=true, + [4196]=true, + [4199]=true, + [4200]=true, + [4201]=true, + [4202]=true, + [4203]=true, + [4204]=true, + [4205]=true, + [4227]=true, + [4231]=true, + [4232]=true, + [4233]=true, + [4234]=true, + [4235]=true, + [4236]=true, + [4239]=true, + [4250]=true, + [4251]=true, + [4252]=true, + [43643]=true, + [43645]=true, + }, + ["pre_mark"]={ + [2367]=true, + [2382]=true, + [2495]=true, + [2503]=true, + [2504]=true, + [2623]=true, + [2751]=true, + [2887]=true, + [3014]=true, + [3015]=true, + [3016]=true, + [3398]=true, + [3399]=true, + [3400]=true, + [4145]=true, + [4228]=true, + }, + ["ra"]={ + [2352]=true, + [2480]=true, + [2544]=true, + [2608]=true, + [2736]=true, + [2864]=true, + [2992]=true, + [3120]=true, + [3248]=true, + [3376]=true, + }, + ["stress_tone_mark"]={ + [2385]=true, + [2386]=true, + [2387]=true, + [2388]=true, + [4151]=true, + [4195]=true, + [4196]=true, + [4201]=true, + [4202]=true, + [4203]=true, + [4204]=true, + [4205]=true, + [4231]=true, + [4232]=true, + [4233]=true, + [4234]=true, + [4235]=true, + [4236]=true, + [4237]=true, + [4239]=true, + [4250]=true, + [4251]=true, + [43643]=true, + [43644]=true, + [43645]=true, + }, + ["twopart_mark"]={ + [2507]={ 2503,2494 }, + [2508]={ 2503,2519 }, + [2888]={ 2887,2902 }, + [2891]={ 2887,2878 }, + [2892]={ 2887,2903 }, + [3018]={ 3014,3006 }, + [3019]={ 3015,3006 }, + [3020]={ 3014,3031 }, + [3144]={ 3142,3158 }, + [3264]={ 3263,3285 }, + [3271]={ 3270,3285 }, + [3272]={ 3270,3286 }, + [3274]={ 3270,3266 }, + [3275]={ 3274,3285 }, + [3402]={ 3398,3390 }, + [3403]={ 3399,3390 }, + [3404]={ 3398,3415 }, + }, + ["vowel_modifier"]={ + [2304]=true, + [2305]=true, + [2306]=true, + [2307]=true, + [2433]=true, + [3330]=true, + [3331]=true, + [4150]=true, + [4152]=true, + [4153]=true, + [4154]=true, + [43232]=true, + [43233]=true, + [43234]=true, + [43235]=true, + [43236]=true, + [43237]=true, + [43238]=true, + [43239]=true, + [43240]=true, + [43241]=true, + [43242]=true, + [43243]=true, + [43244]=true, + [43245]=true, + [43246]=true, + [43247]=true, + [43249]=true, + }, +} + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “basics-chr”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-ini” 5343de60613adb24cdd7a8d2ee1d153c] --- + +if not modules then modules={} end modules ['font-ini']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local allocate=utilities.storage.allocate +local sortedhash=table.sortedhash +fonts=fonts or {} +local fonts=fonts +local identifiers=allocate() +fonts.hashes=fonts.hashes or { identifiers=identifiers } +fonts.tables=fonts.tables or {} +fonts.helpers=fonts.helpers or {} +fonts.tracers=fonts.tracers or {} +fonts.specifiers=fonts.specifiers or {} +fonts.analyzers={} +fonts.readers={} +fonts.definers={ methods={} } +fonts.loggers={ register=function() end } +if context then + font.originaleach=font.each + function font.each() + return sortedhash(identifiers) + end + fontloader=nil +end +fonts.privateoffsets={ + textbase=0xF0000, + textextrabase=0xFD000, + mathextrabase=0xFE000, + mathbase=0xFF000, + keepnames=false, +} +if node and not tex.getfontoffamily then + tex.getfontoffamily=node.family_font +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-ini”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “fonts-mis” 17e967c9ec4d001deefd43ddf25e98f7] --- + +if not modules then modules={} end modules ['luatex-font-mis']={ + version=1.001, + comment="companion to luatex-*.tex", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +if context then + os.exit() +end +local currentfont=font.current +local hashes=fonts.hashes +local identifiers=hashes.identifiers or {} +local marks=hashes.marks or {} +hashes.identifiers=identifiers +hashes.marks=marks +table.setmetatableindex(marks,function(t,k) + if k==true then + return marks[currentfont()] + else + local resources=identifiers[k].resources or {} + local marks=resources.marks or {} + t[k]=marks + return marks + end +end) +function font.each() + return table.sortedhash(fonts.hashes.identifiers) +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “fonts-mis”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-con” 724e5dd14aec2d4d189f8619898004cf] --- + +if not modules then modules={} end modules ['font-con']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next,tostring,tonumber,rawget=next,tostring,tonumber,rawget +local format,match,lower,gsub,find=string.format,string.match,string.lower,string.gsub,string.find +local sort,insert,concat=table.sort,table.insert,table.concat +local sortedkeys,sortedhash,serialize,fastcopy=table.sortedkeys,table.sortedhash,table.serialize,table.fastcopy +local derivetable=table.derive +local ioflush=io.flush +local round=math.round +local setmetatable,getmetatable,rawget,rawset=setmetatable,getmetatable,rawget,rawset +local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) +local trace_scaling=false trackers.register("fonts.scaling",function(v) trace_scaling=v end) +local report_defining=logs.reporter("fonts","defining") +local fonts=fonts +local constructors=fonts.constructors or {} +fonts.constructors=constructors +local handlers=fonts.handlers or {} +fonts.handlers=handlers +local allocate=utilities.storage.allocate +local setmetatableindex=table.setmetatableindex +constructors.dontembed=allocate() +constructors.namemode="fullpath" +constructors.version=1.01 +constructors.cache=containers.define("fonts","constructors",constructors.version,false) +constructors.privateoffset=fonts.privateoffsets.textbase or 0xF0000 +constructors.cacheintex=true +constructors.addtounicode=true +constructors.fixprotrusion=true +local designsizes=allocate() +constructors.designsizes=designsizes +local loadedfonts=allocate() +constructors.loadedfonts=loadedfonts +local factors={ + pt=65536.0, + bp=65781.8, +} +function constructors.setfactor(f) + constructors.factor=factors[f or 'pt'] or factors.pt +end +constructors.setfactor() +function constructors.scaled(scaledpoints,designsize) + if scaledpoints<0 then + local factor=constructors.factor + if designsize then + if designsize>factor then + return (- scaledpoints/1000)*designsize + else + return (- scaledpoints/1000)*designsize*factor + end + else + return (- scaledpoints/1000)*10*factor + end + else + return scaledpoints + end +end +function constructors.getprivate(tfmdata) + local properties=tfmdata.properties + local private=properties.private + properties.private=private+1 + return private +end +function constructors.setmathparameter(tfmdata,name,value) + local m=tfmdata.mathparameters + local c=tfmdata.MathConstants + if m then + m[name]=value + end + if c and c~=m then + c[name]=value + end +end +function constructors.getmathparameter(tfmdata,name) + local p=tfmdata.mathparameters or tfmdata.MathConstants + if p then + return p[name] + end +end +function constructors.cleanuptable(tfmdata) +end +function constructors.calculatescale(tfmdata,scaledpoints) + local parameters=tfmdata.parameters + if scaledpoints<0 then + scaledpoints=(- scaledpoints/1000)*(tfmdata.designsize or parameters.designsize) + end + return scaledpoints,scaledpoints/(parameters.units or 1000) +end +local unscaled={ + ScriptPercentScaleDown=true, + ScriptScriptPercentScaleDown=true, + RadicalDegreeBottomRaisePercent=true, + NoLimitSupFactor=true, + NoLimitSubFactor=true, +} +function constructors.assignmathparameters(target,original) + local mathparameters=original.mathparameters + if mathparameters and next(mathparameters) then + local targetparameters=target.parameters + local targetproperties=target.properties + local targetmathparameters={} + local factor=targetproperties.math_is_scaled and 1 or targetparameters.factor + for name,value in next,mathparameters do + if unscaled[name] then + targetmathparameters[name]=value + else + targetmathparameters[name]=value*factor + end + end + if not targetmathparameters.FractionDelimiterSize then + targetmathparameters.FractionDelimiterSize=1.01*targetparameters.size + end + if not mathparameters.FractionDelimiterDisplayStyleSize then + targetmathparameters.FractionDelimiterDisplayStyleSize=2.40*targetparameters.size + end + if not targetmathparameters.SpaceBeforeScript then + targetmathparameters.SpaceBeforeScript=targetmathparameters.SpaceAfterScript + end + target.mathparameters=targetmathparameters + end +end +function constructors.beforecopyingcharacters(target,original) +end +function constructors.aftercopyingcharacters(target,original) +end +local nofinstances=0 +local instances=setmetatableindex(function(t,k) + nofinstances=nofinstances+1 + t[k]=nofinstances + return nofinstances +end) +function constructors.trytosharefont(target,tfmdata) + local properties=target.properties + local instance=properties.instance + if instance then + local fullname=target.fullname + local fontname=target.fontname + local psname=target.psname + local format=tfmdata.properties.format + if format=="opentype" then + target.streamprovider=1 + elseif format=="truetype" then + target.streamprovider=2 + else + target.streamprovider=0 + end + if target.streamprovider>0 then + if fullname then + fullname=fullname..":"..instances[instance] + target.fullname=fullname + end + if fontname then + fontname=fontname..":"..instances[instance] + target.fontname=fontname + end + if psname then + psname=psname..":"..instances[instance] + target.psname=psname + end + end + end +end +local synonyms={ + exheight="x_height", + xheight="x_height", + ex="x_height", + emwidth="quad", + em="quad", + spacestretch="space_stretch", + stretch="space_stretch", + spaceshrink="space_shrink", + shrink="space_shrink", + extraspace="extra_space", + xspace="extra_space", + slantperpoint="slant", +} +function constructors.enhanceparameters(parameters) + local mt=getmetatable(parameters) + local getter=function(t,k) + if not k then + return nil + end + local s=synonyms[k] + if s then + return rawget(t,s) or (mt and mt[s]) or nil + end + if k=="spacing" then + return { + width=t.space, + stretch=t.space_stretch, + shrink=t.space_shrink, + extra=t.extra_space, + } + end + return mt and mt[k] or nil + end + local setter=function(t,k,v) + if not k then + return 0 + end + local s=synonyms[k] + if s then + rawset(t,s,v) + elseif k=="spacing" then + if type(v)=="table" then + rawset(t,"space",v.width or 0) + rawset(t,"space_stretch",v.stretch or 0) + rawset(t,"space_shrink",v.shrink or 0) + rawset(t,"extra_space",v.extra or 0) + end + else + rawset(t,k,v) + end + end + setmetatable(parameters,{ + __index=getter, + __newindex=setter, + }) +end +local function mathkerns(v,vdelta) + local k={} + for i=1,#v do + local entry=v[i] + local height=entry.height + local kern=entry.kern + k[i]={ + height=height and vdelta*height or 0, + kern=kern and vdelta*kern or 0, + } + end + return k +end +local psfake=0 +local function fixedpsname(psname,fallback) + local usedname=psname + if psname and psname~="" then + if find(psname," ",1,true) then + usedname=gsub(psname,"[%s]+","-") + else + end + elseif not fallback or fallback=="" then + psfake=psfake+1 + psname="fakename-"..psfake + else + psname=fallback + usedname=gsub(psname,"[^a-zA-Z0-9]+","-") + end + return usedname,psname~=usedname +end +function constructors.scale(tfmdata,specification) + local target={} + if tonumber(specification) then + specification={ size=specification } + end + target.specification=specification + local scaledpoints=specification.size + local relativeid=specification.relativeid + local properties=tfmdata.properties or {} + local goodies=tfmdata.goodies or {} + local resources=tfmdata.resources or {} + local descriptions=tfmdata.descriptions or {} + local characters=tfmdata.characters or {} + local changed=tfmdata.changed or {} + local shared=tfmdata.shared or {} + local parameters=tfmdata.parameters or {} + local mathparameters=tfmdata.mathparameters or {} + local targetcharacters={} + local targetdescriptions=derivetable(descriptions) + local targetparameters=derivetable(parameters) + local targetproperties=derivetable(properties) + local targetgoodies=goodies + target.characters=targetcharacters + target.descriptions=targetdescriptions + target.parameters=targetparameters + target.properties=targetproperties + target.goodies=targetgoodies + target.shared=shared + target.resources=resources + target.unscaled=tfmdata + local mathsize=tonumber(specification.mathsize) or 0 + local textsize=tonumber(specification.textsize) or scaledpoints + local forcedsize=tonumber(parameters.mathsize ) or 0 + local extrafactor=tonumber(specification.factor ) or 1 + if (mathsize==2 or forcedsize==2) and parameters.scriptpercentage then + scaledpoints=parameters.scriptpercentage*textsize/100 + elseif (mathsize==3 or forcedsize==3) and parameters.scriptscriptpercentage then + scaledpoints=parameters.scriptscriptpercentage*textsize/100 + elseif forcedsize>1000 then + scaledpoints=forcedsize + else + end + targetparameters.mathsize=mathsize + targetparameters.textsize=textsize + targetparameters.forcedsize=forcedsize + targetparameters.extrafactor=extrafactor + local addtounicode=constructors.addtounicode + local tounicode=fonts.mappings.tounicode + local unknowncode=tounicode(0xFFFD) + local defaultwidth=resources.defaultwidth or 0 + local defaultheight=resources.defaultheight or 0 + local defaultdepth=resources.defaultdepth or 0 + local units=parameters.units or 1000 + targetproperties.language=properties.language or "dflt" + targetproperties.script=properties.script or "dflt" + targetproperties.mode=properties.mode or "base" + targetproperties.method=properties.method + local askedscaledpoints=scaledpoints + local scaledpoints,delta=constructors.calculatescale(tfmdata,scaledpoints,nil,specification) + local hdelta=delta + local vdelta=delta + target.designsize=parameters.designsize + target.units=units + target.units_per_em=units + local direction=properties.direction or tfmdata.direction or 0 + target.direction=direction + properties.direction=direction + target.size=scaledpoints + target.encodingbytes=properties.encodingbytes or 1 + target.subfont=properties.subfont + target.embedding=properties.embedding or "subset" + target.tounicode=1 + target.cidinfo=properties.cidinfo + target.format=properties.format + target.cache=constructors.cacheintex and "yes" or "renew" + local original=properties.original or tfmdata.original + local fontname=properties.fontname or tfmdata.fontname + local fullname=properties.fullname or tfmdata.fullname + local filename=properties.filename or tfmdata.filename + local psname=properties.psname or tfmdata.psname + local name=properties.name or tfmdata.name + local psname,psfixed=fixedpsname(psname,fontname or fullname or file.nameonly(filename)) + target.original=original + target.fontname=fontname + target.fullname=fullname + target.filename=filename + target.psname=psname + target.name=name + properties.fontname=fontname + properties.fullname=fullname + properties.filename=filename + properties.psname=psname + properties.name=name + local expansion=parameters.expansion + if expansion then + target.stretch=expansion.stretch + target.shrink=expansion.shrink + target.step=expansion.step + end + local slantfactor=parameters.slantfactor or 0 + if slantfactor~=0 then + target.slant=slantfactor*1000 + else + target.slant=0 + end + local extendfactor=parameters.extendfactor or 0 + if extendfactor~=0 and extendfactor~=1 then + hdelta=hdelta*extendfactor + target.extend=extendfactor*1000 + else + target.extend=1000 + end + local squeezefactor=parameters.squeezefactor or 0 + if squeezefactor~=0 and squeezefactor~=1 then + vdelta=vdelta*squeezefactor + target.squeeze=squeezefactor*1000 + else + target.squeeze=1000 + end + local mode=parameters.mode or 0 + if mode~=0 then + target.mode=mode + end + local width=parameters.width or 0 + if width~=0 then + target.width=width*delta*1000/655360 + end + targetparameters.factor=delta + targetparameters.hfactor=hdelta + targetparameters.vfactor=vdelta + targetparameters.size=scaledpoints + targetparameters.units=units + targetparameters.scaledpoints=askedscaledpoints + targetparameters.mode=mode + targetparameters.width=width + local isvirtual=properties.virtualized or tfmdata.type=="virtual" + local hasquality=parameters.expansion or parameters.protrusion + local hasitalics=properties.hasitalics + local autoitalicamount=properties.autoitalicamount + local stackmath=not properties.nostackmath + local haskerns=properties.haskerns or properties.mode=="base" + local hasligatures=properties.hasligatures or properties.mode=="base" + local realdimensions=properties.realdimensions + local writingmode=properties.writingmode or "horizontal" + local identity=properties.identity or "horizontal" + local vfonts=target.fonts + if vfonts and #vfonts>0 then + target.fonts=fastcopy(vfonts) + elseif isvirtual then + target.fonts={ { id=0 } } + end + if changed and not next(changed) then + changed=false + end + target.type=isvirtual and "virtual" or "real" + target.writingmode=writingmode=="vertical" and "vertical" or "horizontal" + target.identity=identity=="vertical" and "vertical" or "horizontal" + target.postprocessors=tfmdata.postprocessors + local targetslant=(parameters.slant or parameters[1] or 0)*factors.pt + local targetspace=(parameters.space or parameters[2] or 0)*hdelta + local targetspace_stretch=(parameters.space_stretch or parameters[3] or 0)*hdelta + local targetspace_shrink=(parameters.space_shrink or parameters[4] or 0)*hdelta + local targetx_height=(parameters.x_height or parameters[5] or 0)*vdelta + local targetquad=(parameters.quad or parameters[6] or 0)*hdelta + local targetextra_space=(parameters.extra_space or parameters[7] or 0)*hdelta + targetparameters.slant=targetslant + targetparameters.space=targetspace + targetparameters.space_stretch=targetspace_stretch + targetparameters.space_shrink=targetspace_shrink + targetparameters.x_height=targetx_height + targetparameters.quad=targetquad + targetparameters.extra_space=targetextra_space + local hshift=parameters.hshift + if hshift then + targetparameters.hshift=delta*hshift + end + local vshift=parameters.vshift + if vshift then + targetparameters.vshift=delta*vshift + end + local ascender=parameters.ascender + if ascender then + targetparameters.ascender=delta*ascender + end + local descender=parameters.descender + if descender then + targetparameters.descender=delta*descender + end + constructors.enhanceparameters(targetparameters) + local protrusionfactor=constructors.fixprotrusion and ((targetquad~=0 and 1000/targetquad) or 1) or 1 + local scaledwidth=defaultwidth*hdelta + local scaledheight=defaultheight*vdelta + local scaleddepth=defaultdepth*vdelta + local hasmath=(properties.hasmath or next(mathparameters)) and true + if hasmath then + constructors.assignmathparameters(target,tfmdata) + properties.hasmath=true + target.nomath=false + target.MathConstants=target.mathparameters + local oldmath=properties.oldmath + targetproperties.oldmath=oldmath + target.oldmath=oldmath + else + properties.hasmath=false + target.nomath=true + target.mathparameters=nil + end + if hasmath then + local mathitalics=properties.mathitalics + if mathitalics==false then + if trace_defining then + report_defining("%s italics %s for font %a, fullname %a, filename %a","math",hasitalics and "ignored" or "disabled",name,fullname,filename) + end + hasitalics=false + autoitalicamount=false + end + else + local textitalics=properties.textitalics + if textitalics==false then + if trace_defining then + report_defining("%s italics %s for font %a, fullname %a, filename %a","text",hasitalics and "ignored" or "disabled",name,fullname,filename) + end + hasitalics=false + autoitalicamount=false + end + end + if trace_defining then + report_defining("defining tfm, name %a, fullname %a, filename %a, %spsname %a, hscale %a, vscale %a, math %a, italics %a", + name,fullname,filename,psfixed and "(fixed) " or "",psname,hdelta,vdelta, + hasmath and "enabled" or "disabled",hasitalics and "enabled" or "disabled") + end + constructors.beforecopyingcharacters(target,tfmdata) + local sharedkerns={} + for unicode,character in next,characters do + local chr,description,index + if changed then + local c=changed[unicode] + if c and c~=unicode then + if c then + description=descriptions[c] or descriptions[unicode] or character + character=characters[c] or character + index=description.index or c + else + description=descriptions[unicode] or character + index=description.index or unicode + end + else + description=descriptions[unicode] or character + index=description.index or unicode + end + else + description=descriptions[unicode] or character + index=description.index or unicode + end + local width=description.width + local height=description.height + local depth=description.depth + local isunicode=description.unicode + if realdimensions then + if not height or height==0 then + local bb=description.boundingbox + local ht=bb[4] + if ht~=0 then + height=ht + end + if not depth or depth==0 then + local dp=-bb[2] + if dp~=0 then + depth=dp + end + end + elseif not depth or depth==0 then + local dp=-description.boundingbox[2] + if dp~=0 then + depth=dp + end + end + end + if width then width=hdelta*width else width=scaledwidth end + if height then height=vdelta*height else height=scaledheight end + if depth and depth~=0 then + depth=delta*depth + if isunicode then + chr={ + index=index, + height=height, + depth=depth, + width=width, + unicode=isunicode, + } + else + chr={ + index=index, + height=height, + depth=depth, + width=width, + } + end + else + if isunicode then + chr={ + index=index, + height=height, + width=width, + unicode=isunicode, + } + else + chr={ + index=index, + height=height, + width=width, + } + end + end + if addtounicode then + chr.tounicode=isunicode and tounicode(isunicode) or unknowncode + end + if hasquality then + local ve=character.expansion_factor + if ve then + chr.expansion_factor=ve*1000 + end + local vl=character.left_protruding + if vl then + chr.left_protruding=protrusionfactor*width*vl + end + local vr=character.right_protruding + if vr then + chr.right_protruding=protrusionfactor*width*vr + end + end + if hasmath then + local vn=character.next + if vn then + chr.next=vn + else + local vv=character.vert_variants + if vv then + local t={} + for i=1,#vv do + local vvi=vv[i] + local s=vvi["start"] or 0 + local e=vvi["end"] or 0 + local a=vvi["advance"] or 0 + t[i]={ + ["start"]=s==0 and 0 or s*vdelta, + ["end"]=e==0 and 0 or e*vdelta, + ["advance"]=a==0 and 0 or a*vdelta, + ["extender"]=vvi["extender"], + ["glyph"]=vvi["glyph"], + } + end + chr.vert_variants=t + else + local hv=character.horiz_variants + if hv then + local t={} + for i=1,#hv do + local hvi=hv[i] + local s=hvi["start"] or 0 + local e=hvi["end"] or 0 + local a=hvi["advance"] or 0 + t[i]={ + ["start"]=s==0 and 0 or s*hdelta, + ["end"]=e==0 and 0 or e*hdelta, + ["advance"]=a==0 and 0 or a*hdelta, + ["extender"]=hvi["extender"], + ["glyph"]=hvi["glyph"], + } + end + chr.horiz_variants=t + end + end + end + local vi=character.vert_italic + if vi and vi~=0 then + chr.vert_italic=vi*hdelta + end + local va=character.accent + if va then + chr.top_accent=vdelta*va + end + if stackmath then + local mk=character.mathkerns + if mk then + local tr=mk.topright + local tl=mk.topleft + local br=mk.bottomright + local bl=mk.bottomleft + chr.mathkern={ + top_right=tr and mathkerns(tr,vdelta) or nil, + top_left=tl and mathkerns(tl,vdelta) or nil, + bottom_right=br and mathkerns(br,vdelta) or nil, + bottom_left=bl and mathkerns(bl,vdelta) or nil, + } + end + end + if hasitalics then + local vi=character.italic + if vi and vi~=0 then + chr.italic=vi*hdelta + end + end + elseif autoitalicamount then + local vi=description.italic + if not vi then + local bb=description.boundingbox + if bb then + local vi=bb[3]-description.width+autoitalicamount + if vi>0 then + chr.italic=vi*hdelta + end + else + end + elseif vi~=0 then + chr.italic=vi*hdelta + end + elseif hasitalics then + local vi=character.italic + if vi and vi~=0 then + chr.italic=vi*hdelta + end + end + if haskerns then + local vk=character.kerns + if vk then + local s=sharedkerns[vk] + if not s then + s={} + for k,v in next,vk do s[k]=v*hdelta end + sharedkerns[vk]=s + end + chr.kerns=s + end + end + if hasligatures then + local vl=character.ligatures + if vl then + if true then + chr.ligatures=vl + else + local tt={} + for i,l in next,vl do + tt[i]=l + end + chr.ligatures=tt + end + end + end + if isvirtual then + local vc=character.commands + if vc then + local ok=false + for i=1,#vc do + local key=vc[i][1] + if key=="right" or key=="down" or key=="rule" then + ok=true + break + end + end + if ok then + local tt={} + for i=1,#vc do + local ivc=vc[i] + local key=ivc[1] + if key=="right" then + tt[i]={ key,ivc[2]*hdelta } + elseif key=="down" then + tt[i]={ key,ivc[2]*vdelta } + elseif key=="rule" then + tt[i]={ key,ivc[2]*vdelta,ivc[3]*hdelta } + else + tt[i]=ivc + end + end + chr.commands=tt + else + chr.commands=vc + end + end + end + targetcharacters[unicode]=chr + end + properties.setitalics=hasitalics + constructors.aftercopyingcharacters(target,tfmdata) + constructors.trytosharefont(target,tfmdata) + local vfonts=target.fonts + if isvirtual or target.type=="virtual" or properties.virtualized then + properties.virtualized=true + target.type="virtual" + if not vfonts or #vfonts==0 then + target.fonts={ { id=0 } } + end + elseif vfonts then + properties.virtualized=true + target.type="virtual" + if #vfonts==0 then + target.fonts={ { id=0 } } + end + end + return target +end +function constructors.finalize(tfmdata) + if tfmdata.properties and tfmdata.properties.finalized then + return + end + if not tfmdata.characters then + return nil + end + if not tfmdata.goodies then + tfmdata.goodies={} + end + local parameters=tfmdata.parameters + if not parameters then + return nil + end + if not parameters.expansion then + parameters.expansion={ + stretch=tfmdata.stretch or 0, + shrink=tfmdata.shrink or 0, + step=tfmdata.step or 0, + } + end + if not parameters.size then + parameters.size=tfmdata.size + end + if not parameters.mode then + parameters.mode=0 + end + if not parameters.width then + parameters.width=0 + end + if not parameters.slantfactor then + parameters.slantfactor=(tfmdata.slant or 0)/1000 + end + if not parameters.extendfactor then + parameters.extendfactor=(tfmdata.extend or 1000)/1000 + end + if not parameters.squeezefactor then + parameters.squeezefactor=(tfmdata.squeeze or 1000)/1000 + end + local designsize=parameters.designsize + if designsize then + parameters.minsize=tfmdata.minsize or designsize + parameters.maxsize=tfmdata.maxsize or designsize + else + designsize=factors.pt*10 + parameters.designsize=designsize + parameters.minsize=designsize + parameters.maxsize=designsize + end + parameters.minsize=tfmdata.minsize or parameters.designsize + parameters.maxsize=tfmdata.maxsize or parameters.designsize + if not parameters.units then + parameters.units=tfmdata.units or tfmdata.units_per_em or 1000 + end + if not tfmdata.descriptions then + local descriptions={} + setmetatableindex(descriptions,function(t,k) local v={} t[k]=v return v end) + tfmdata.descriptions=descriptions + end + local properties=tfmdata.properties + if not properties then + properties={} + tfmdata.properties=properties + end + if not properties.virtualized then + properties.virtualized=tfmdata.type=="virtual" + end + properties.fontname=properties.fontname or tfmdata.fontname + properties.filename=properties.filename or tfmdata.filename + properties.fullname=properties.fullname or tfmdata.fullname + properties.name=properties.name or tfmdata.name + properties.psname=properties.psname or tfmdata.psname + properties.encodingbytes=tfmdata.encodingbytes or 1 + properties.subfont=tfmdata.subfont or nil + properties.embedding=tfmdata.embedding or "subset" + properties.tounicode=tfmdata.tounicode or 1 + properties.cidinfo=tfmdata.cidinfo or nil + properties.format=tfmdata.format or "type1" + properties.direction=tfmdata.direction or 0 + properties.writingmode=tfmdata.writingmode or "horizontal" + properties.identity=tfmdata.identity or "horizontal" + properties.usedbitmap=tfmdata.usedbitmap + if not tfmdata.resources then + tfmdata.resources={} + end + if not tfmdata.shared then + tfmdata.shared={} + end + if not properties.hasmath then + properties.hasmath=not tfmdata.nomath + end + tfmdata.MathConstants=nil + tfmdata.postprocessors=nil + tfmdata.fontname=nil + tfmdata.filename=nil + tfmdata.fullname=nil + tfmdata.name=nil + tfmdata.psname=nil + tfmdata.encodingbytes=nil + tfmdata.subfont=nil + tfmdata.embedding=nil + tfmdata.tounicode=nil + tfmdata.cidinfo=nil + tfmdata.format=nil + tfmdata.direction=nil + tfmdata.type=nil + tfmdata.nomath=nil + tfmdata.designsize=nil + tfmdata.size=nil + tfmdata.stretch=nil + tfmdata.shrink=nil + tfmdata.step=nil + tfmdata.slant=nil + tfmdata.extend=nil + tfmdata.squeeze=nil + tfmdata.mode=nil + tfmdata.width=nil + tfmdata.units=nil + tfmdata.units_per_em=nil + tfmdata.cache=nil + properties.finalized=true + return tfmdata +end +local hashmethods={} +constructors.hashmethods=hashmethods +function constructors.hashfeatures(specification) + local features=specification.features + if features then + local t,n={},0 + for category,list in sortedhash(features) do + if next(list) then + local hasher=hashmethods[category] + if hasher then + local hash=hasher(list) + if hash then + n=n+1 + t[n]=category..":"..hash + end + end + end + end + if n>0 then + return concat(t," & ") + end + end + return "unknown" +end +hashmethods.normal=function(list) + local s={} + local n=0 + for k,v in next,list do + if not k then + elseif k=="number" or k=="features" then + else + n=n+1 + if type(v)=="table" then + local t={} + local m=0 + for k,v in next,v do + m=m+1 + t[m]=k..'='..tostring(v) + end + sort(t) + s[n]=k..'={'..concat(t,",").."}" + else + s[n]=k..'='..tostring(v) + end + end + end + if n>0 then + sort(s) + return concat(s,"+") + end +end +function constructors.hashinstance(specification,force) + local hash=specification.hash + local size=specification.size + local fallbacks=specification.fallbacks + if force or not hash then + hash=constructors.hashfeatures(specification) + specification.hash=hash + end + if size<1000 and designsizes[hash] then + size=round(constructors.scaled(size,designsizes[hash])) + else + size=round(size) + end + specification.size=size + if fallbacks then + return hash..' @ '..size..' @ '..fallbacks + else + return hash..' @ '..size + end +end +function constructors.setname(tfmdata,specification) + if constructors.namemode=="specification" then + local specname=specification.specification + if specname then + tfmdata.properties.name=specname + if trace_defining then + report_otf("overloaded fontname %a",specname) + end + end + end +end +function constructors.checkedfilename(data) + local foundfilename=data.foundfilename + if not foundfilename then + local askedfilename=data.filename or "" + if askedfilename~="" then + askedfilename=resolvers.resolve(askedfilename) + foundfilename=resolvers.findbinfile(askedfilename,"") or "" + if foundfilename=="" then + report_defining("source file %a is not found",askedfilename) + foundfilename=resolvers.findbinfile(file.basename(askedfilename),"") or "" + if foundfilename~="" then + report_defining("using source file %a due to cache mismatch",foundfilename) + end + end + end + data.foundfilename=foundfilename + end + return foundfilename +end +local formats=allocate() +fonts.formats=formats +setmetatableindex(formats,function(t,k) + local l=lower(k) + if rawget(t,k) then + t[k]=l + return l + end + return rawget(t,file.suffix(l)) +end) +do + local function setindeed(mode,source,target,group,name,position) + local action=source[mode] + if not action then + return + end + local t=target[mode] + if not t then + report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode) + os.exit() + elseif position then + insert(t,position,{ name=name,action=action }) + else + for i=1,#t do + local ti=t[i] + if ti.name==name then + ti.action=action + return + end + end + insert(t,{ name=name,action=action }) + end + end + local function set(group,name,target,source) + target=target[group] + if not target then + report_defining("fatal target error in setting feature %a, group %a",name,group) + os.exit() + end + local source=source[group] + if not source then + report_defining("fatal source error in setting feature %a, group %a",name,group) + os.exit() + end + local position=source.position + setindeed("node",source,target,group,name,position) + setindeed("base",source,target,group,name,position) + setindeed("plug",source,target,group,name,position) + end + local function register(where,specification) + local name=specification.name + if name and name~="" then + local default=specification.default + local description=specification.description + local initializers=specification.initializers + local processors=specification.processors + local manipulators=specification.manipulators + local modechecker=specification.modechecker + if default then + where.defaults[name]=default + end + if description and description~="" then + where.descriptions[name]=description + end + if initializers then + set('initializers',name,where,specification) + end + if processors then + set('processors',name,where,specification) + end + if manipulators then + set('manipulators',name,where,specification) + end + if modechecker then + where.modechecker=modechecker + end + end + end + constructors.registerfeature=register + function constructors.getfeatureaction(what,where,mode,name) + what=handlers[what].features + if what then + where=what[where] + if where then + mode=where[mode] + if mode then + for i=1,#mode do + local m=mode[i] + if m.name==name then + return m.action + end + end + end + end + end + end + local newfeatures={} + constructors.newfeatures=newfeatures + constructors.features=newfeatures + local function setnewfeatures(what) + local handler=handlers[what] + local features=handler.features + if not features then + local tables=handler.tables + local statistics=handler.statistics + features=allocate { + defaults={}, + descriptions=tables and tables.features or {}, + used=statistics and statistics.usedfeatures or {}, + initializers={ base={},node={},plug={} }, + processors={ base={},node={},plug={} }, + manipulators={ base={},node={},plug={} }, + } + features.register=function(specification) return register(features,specification) end + handler.features=features + end + return features + end + setmetatable(newfeatures,{ + __call=function(t,k) local v=t[k] return v end, + __index=function(t,k) local v=setnewfeatures(k) t[k]=v return v end, + }) +end +do + local newhandler={} + constructors.handlers=newhandler + constructors.newhandler=newhandler + local function setnewhandler(what) + local handler=handlers[what] + if not handler then + handler={} + handlers[what]=handler + end + return handler + end + setmetatable(newhandler,{ + __call=function(t,k) local v=t[k] return v end, + __index=function(t,k) local v=setnewhandler(k) t[k]=v return v end, + }) +end +do + local newenhancer={} + constructors.enhancers=newenhancer + constructors.newenhancer=newenhancer + local function setnewenhancer(format) + local handler=handlers[format] + local enhancers=handler.enhancers + if not enhancers then + local actions=allocate() + local before=allocate() + local after=allocate() + local order=allocate() + local known={} + local nofsteps=0 + local patches={ before=before,after=after } + local trace=false + local report=logs.reporter("fonts",format.." enhancing") + trackers.register(format..".loading",function(v) trace=v end) + local function enhance(name,data,filename,raw) + local enhancer=actions[name] + if enhancer then + if trace then + report("apply enhancement %a to file %a",name,filename) + ioflush() + end + enhancer(data,filename,raw) + else + end + end + local function apply(data,filename,raw) + local basename=file.basename(lower(filename)) + if trace then + report("%s enhancing file %a","start",filename) + end + ioflush() + for e=1,nofsteps do + local enhancer=order[e] + local b=before[enhancer] + if b then + for pattern,action in next,b do + if find(basename,pattern) then + action(data,filename,raw) + end + end + end + enhance(enhancer,data,filename,raw) + local a=after[enhancer] + if a then + for pattern,action in next,a do + if find(basename,pattern) then + action(data,filename,raw) + end + end + end + ioflush() + end + if trace then + report("%s enhancing file %a","stop",filename) + end + ioflush() + end + local function register(what,action) + if action then + if actions[what] then + else + nofsteps=nofsteps+1 + order[nofsteps]=what + known[what]=nofsteps + end + actions[what]=action + else + report("bad enhancer %a",what) + end + end + local function patch(what,where,pattern,action) + local pw=patches[what] + if pw then + local ww=pw[where] + if ww then + ww[pattern]=action + else + pw[where]={ [pattern]=action } + if not known[where] then + nofsteps=nofsteps+1 + order[nofsteps]=where + known[where]=nofsteps + end + end + end + end + enhancers={ + register=register, + apply=apply, + patch=patch, + report=report, + patches={ + register=patch, + report=report, + }, + } + handler.enhancers=enhancers + end + return enhancers + end + setmetatable(newenhancer,{ + __call=function(t,k) local v=t[k] return v end, + __index=function(t,k) local v=setnewenhancer(k) t[k]=v return v end, + }) +end +function constructors.checkedfeatures(what,features) + local defaults=handlers[what].features.defaults + if features and next(features) then + features=fastcopy(features) + for key,value in next,defaults do + if features[key]==nil then + features[key]=value + end + end + return features + else + return fastcopy(defaults) + end +end +function constructors.initializefeatures(what,tfmdata,features,trace,report) + if features and next(features) then + local properties=tfmdata.properties or {} + local whathandler=handlers[what] + local whatfeatures=whathandler.features + local whatmodechecker=whatfeatures.modechecker + local mode=properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features,features.mode)) or features.mode or "base" + properties.mode=mode + features.mode=mode + local done={} + while true do + local redo=false + local initializers=whatfeatures.initializers[mode] + if initializers then + for i=1,#initializers do + local step=initializers[i] + local feature=step.name + local value=features[feature] + if not value then + elseif done[feature] then + else + local action=step.action + if trace then + report("initializing feature %a to %a for mode %a for font %a",feature, + value,mode,tfmdata.properties.fullname) + end + action(tfmdata,value,features) + if mode~=properties.mode or mode~=features.mode then + if whatmodechecker then + properties.mode=whatmodechecker(tfmdata,features,properties.mode) + features.mode=properties.mode + end + if mode~=properties.mode then + mode=properties.mode + redo=true + end + end + done[feature]=true + end + if redo then + break + end + end + if not redo then + break + end + else + break + end + end + properties.mode=mode + return true + else + return false + end +end +function constructors.collectprocessors(what,tfmdata,features,trace,report) + local processes={} + local nofprocesses=0 + if features and next(features) then + local properties=tfmdata.properties + local whathandler=handlers[what] + local whatfeatures=whathandler.features + local whatprocessors=whatfeatures.processors + local mode=properties.mode + local processors=whatprocessors[mode] + if processors then + for i=1,#processors do + local step=processors[i] + local feature=step.name + if features[feature] then + local action=step.action + if trace then + report("installing feature processor %a for mode %a for font %a",feature,mode,tfmdata.properties.fullname) + end + if action then + nofprocesses=nofprocesses+1 + processes[nofprocesses]=action + end + end + end + elseif trace then + report("no feature processors for mode %a for font %a",mode,properties.fullname) + end + end + return processes +end +function constructors.applymanipulators(what,tfmdata,features,trace,report) + if features and next(features) then + local properties=tfmdata.properties + local whathandler=handlers[what] + local whatfeatures=whathandler.features + local whatmanipulators=whatfeatures.manipulators + local mode=properties.mode + local manipulators=whatmanipulators[mode] + if manipulators then + for i=1,#manipulators do + local step=manipulators[i] + local feature=step.name + local value=features[feature] + if value then + local action=step.action + if trace then + report("applying feature manipulator %a for mode %a for font %a",feature,mode,properties.fullname) + end + if action then + action(tfmdata,feature,value) + end + end + end + end + end +end +function constructors.addcoreunicodes(unicodes) + if not unicodes then + unicodes={} + end + unicodes.space=0x0020 + unicodes.hyphen=0x002D + unicodes.zwj=0x200D + unicodes.zwnj=0x200C + return unicodes +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-con”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “fonts-enc” 5ff4ca50493d7c4ecea0e15c203099f0] --- + +if not modules then modules={} end modules ['luatex-font-enc']={ + version=1.001, + comment="companion to luatex-*.tex", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +if context then + os.exit() +end +local fonts=fonts +local encodings={} +fonts.encodings=encodings +encodings.agl={} +encodings.known={} +setmetatable(encodings.agl,{ __index=function(t,k) + if k=="unicodes" then + logs.report("fonts","loading (extended) adobe glyph list") + local unicodes=dofile(resolvers.findfile("font-age.lua")) + encodings.agl={ unicodes=unicodes } + return unicodes + else + return nil + end +end }) +encodings.cache=containers.define("fonts","enc",encodings.version,true) +function encodings.load(filename) + local name=file.removesuffix(filename) + local data=containers.read(encodings.cache,name) + if data then + return data + end + local vector,tag,hash,unicodes={},"",{},{} + local foundname=resolvers.findfile(filename,'enc') + if foundname and foundname~="" then + local ok,encoding,size=resolvers.loadbinfile(foundname) + if ok and encoding then + encoding=string.gsub(encoding,"%%(.-)\n","") + local unicoding=encodings.agl.unicodes + local tag,vec=string.match(encoding,"/(%w+)%s*%[(.*)%]%s*def") + local i=0 + for ch in string.gmatch(vec,"/([%a%d%.]+)") do + if ch~=".notdef" then + vector[i]=ch + if not hash[ch] then + hash[ch]=i + else + end + local u=unicoding[ch] + if u then + unicodes[u]=i + end + end + i=i+1 + end + end + end + local data={ + name=name, + tag=tag, + vector=vector, + hash=hash, + unicodes=unicodes + } + return containers.write(encodings.cache,name,data) +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “fonts-enc”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-cid” 22b0367742fb253deef84ef7ccf5e8de] --- + +if not modules then modules={} end modules ['font-cid']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local format,match,lower=string.format,string.match,string.lower +local tonumber=tonumber +local P,S,R,C,V,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.match +local fonts,logs,trackers=fonts,logs,trackers +local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) +local report_otf=logs.reporter("fonts","otf loading") +local cid={} +fonts.cid=cid +local cidmap={} +local cidmax=10 +local number=C(R("09","af","AF")^1) +local space=S(" \n\r\t") +local spaces=space^0 +local period=P(".") +local periods=period*period +local name=P("/")*C((1-space)^1) +local unicodes,names={},{} +local function do_one(a,b) + unicodes[tonumber(a)]=tonumber(b,16) +end +local function do_range(a,b,c) + c=tonumber(c,16) + for i=tonumber(a),tonumber(b) do + unicodes[i]=c + c=c+1 + end +end +local function do_name(a,b) + names[tonumber(a)]=b +end +local grammar=P { "start", + start=number*spaces*number*V("series"), + series=(spaces*(V("one")+V("range")+V("named")))^1, + one=(number*spaces*number)/do_one, + range=(number*periods*number*spaces*number)/do_range, + named=(number*spaces*name)/do_name +} +local function loadcidfile(filename) + local data=io.loaddata(filename) + if data then + unicodes,names={},{} + lpegmatch(grammar,data) + local supplement,registry,ordering=match(filename,"^(.-)%-(.-)%-()%.(.-)$") + return { + supplement=supplement, + registry=registry, + ordering=ordering, + filename=filename, + unicodes=unicodes, + names=names, + } + end +end +cid.loadfile=loadcidfile +local template="%s-%s-%s.cidmap" +local function locate(registry,ordering,supplement) + local filename=format(template,registry,ordering,supplement) + local hashname=lower(filename) + local found=cidmap[hashname] + if not found then + if trace_loading then + report_otf("checking cidmap, registry %a, ordering %a, supplement %a, filename %a",registry,ordering,supplement,filename) + end + local fullname=resolvers.findfile(filename,'cid') or "" + if fullname~="" then + found=loadcidfile(fullname) + if found then + if trace_loading then + report_otf("using cidmap file %a",filename) + end + cidmap[hashname]=found + found.usedname=file.basename(filename) + end + end + end + return found +end +function cid.getmap(specification) + if not specification then + report_otf("invalid cidinfo specification, table expected") + return + end + local registry=specification.registry + local ordering=specification.ordering + local supplement=specification.supplement + local filename=format(registry,ordering,supplement) + local lowername=lower(filename) + local found=cidmap[lowername] + if found then + return found + end + if ordering=="Identity" then + local found={ + supplement=supplement, + registry=registry, + ordering=ordering, + filename=filename, + unicodes={}, + names={}, + } + cidmap[lowername]=found + return found + end + if trace_loading then + report_otf("cidmap needed, registry %a, ordering %a, supplement %a",registry,ordering,supplement) + end + found=locate(registry,ordering,supplement) + if not found then + local supnum=tonumber(supplement) + local cidnum=nil + if supnum0 then + for s=supnum-1,0,-1 do + local c=locate(registry,ordering,s) + if c then + found,cidnum=c,s + break + end + end + end + registry=lower(registry) + ordering=lower(ordering) + if found and cidnum>0 then + for s=0,cidnum-1 do + local filename=format(template,registry,ordering,s) + if not cidmap[filename] then + cidmap[filename]=found + end + end + end + end + return found +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-cid”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-map” c4a39db5ad822b348aa61bca5f4a599a] --- + +if not modules then modules={} end modules ['font-map']={ + version=1.001, + optimize=true, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local tonumber,next,type=tonumber,next,type +local match,format,find,concat,gsub,lower=string.match,string.format,string.find,table.concat,string.gsub,string.lower +local P,R,S,C,Ct,Cc,lpegmatch=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.match +local formatters=string.formatters +local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys +local idiv=number.idiv +local trace_loading=false trackers.register("fonts.loading",function(v) trace_loading=v end) +local trace_mapping=false trackers.register("fonts.mapping",function(v) trace_mapping=v end) +local report_fonts=logs.reporter("fonts","loading") +local force_ligatures=false directives.register("fonts.mapping.forceligatures",function(v) force_ligatures=v end) +local fonts=fonts or {} +local mappings=fonts.mappings or {} +fonts.mappings=mappings +local allocate=utilities.storage.allocate +local hex=R("AF","af","09") +local hexfour=(hex*hex*hex^-2)/function(s) return tonumber(s,16) end +local hexsix=(hex*hex*hex^-4)/function(s) return tonumber(s,16) end +local dec=(R("09")^1)/tonumber +local period=P(".") +local unicode=(P("uni")+P("UNI"))*(hexfour*(period+P(-1))*Cc(false)+Ct(hexfour^1)*Cc(true)) +local ucode=(P("u")+P("U") )*(hexsix*(period+P(-1))*Cc(false)+Ct(hexsix^1)*Cc(true)) +local index=P("index")*dec*Cc(false) +local parser=unicode+ucode+index +local parsers={} +local function makenameparser(str) + if not str or str=="" then + return parser + else + local p=parsers[str] + if not p then + p=P(str)*period*dec*Cc(false) + parsers[str]=p + end + return p + end +end +local f_single=formatters["%04X"] +local f_double=formatters["%04X%04X"] +local s_unknown="FFFD" +local function tounicode16(unicode) + if unicode<0xD7FF or (unicode>0xDFFF and unicode<=0xFFFF) then + return f_single(unicode) + elseif unicode>=0x00E000 and unicode<=0x00F8FF then + return s_unknown + elseif unicode>=0x0F0000 and unicode<=0x0FFFFF then + return s_unknown + elseif unicode>=0x100000 and unicode<=0x10FFFF then + return s_unknown + elseif unicode>=0x00D800 and unicode<=0x00DFFF then + return s_unknown + else + unicode=unicode-0x10000 + return f_double(idiv(k,0x400)+0xD800,unicode%0x400+0xDC00) + end +end +local function tounicode16sequence(unicodes) + local t={} + for l=1,#unicodes do + local u=unicodes[l] + if u<0xD7FF or (u>0xDFFF and u<=0xFFFF) then + t[l]=f_single(u) + elseif unicode>=0x00E000 and unicode<=0x00F8FF then + t[l]=s_unknown + elseif unicode>=0x0F0000 and unicode<=0x0FFFFF then + t[l]=s_unknown + elseif unicode>=0x100000 and unicode<=0x10FFFF then + t[l]=s_unknown + elseif unicode>=0x00D7FF and unicode<=0x00DFFF then + t[l]=s_unknown + else + u=u-0x10000 + t[l]=f_double(idiv(k,0x400)+0xD800,u%0x400+0xDC00) + end + end + return concat(t) +end +local hash={} +local conc={} +table.setmetatableindex(hash,function(t,k) + local v + if k<0xD7FF or (k>0xDFFF and k<=0xFFFF) then + v=f_single(k) + else + local k=k-0x10000 + v=f_double(idiv(k,0x400)+0xD800,k%0x400+0xDC00) + end + t[k]=v + return v +end) +local function tounicode(k) + if type(k)=="table" then + local n=#k + for l=1,n do + conc[l]=hash[k[l]] + end + return concat(conc,"",1,n) + elseif k>=0x00E000 and k<=0x00F8FF then + return s_unknown + elseif k>=0x0F0000 and k<=0x0FFFFF then + return s_unknown + elseif k>=0x100000 and k<=0x10FFFF then + return s_unknown + elseif k>=0x00D7FF and k<=0x00DFFF then + return s_unknown + else + return hash[k] + end +end +local function fromunicode16(str) + if #str==4 then + return tonumber(str,16) + else + local l,r=match(str,"(....)(....)") + return 0x10000+(tonumber(l,16)-0xD800)*0x400+tonumber(r,16)-0xDC00 + end +end +mappings.makenameparser=makenameparser +mappings.tounicode=tounicode +mappings.tounicode16=tounicode16 +mappings.tounicode16sequence=tounicode16sequence +mappings.fromunicode16=fromunicode16 +local ligseparator=P("_") +local varseparator=P(".") +local namesplitter=Ct(C((1-ligseparator-varseparator)^1)*(ligseparator*C((1-ligseparator-varseparator)^1))^0) +do + local overloads={ + IJ={ name="I_J",unicode={ 0x49,0x4A },mess=0x0132 }, + ij={ name="i_j",unicode={ 0x69,0x6A },mess=0x0133 }, + ff={ name="f_f",unicode={ 0x66,0x66 },mess=0xFB00 }, + fi={ name="f_i",unicode={ 0x66,0x69 },mess=0xFB01 }, + fl={ name="f_l",unicode={ 0x66,0x6C },mess=0xFB02 }, + ffi={ name="f_f_i",unicode={ 0x66,0x66,0x69 },mess=0xFB03 }, + ffl={ name="f_f_l",unicode={ 0x66,0x66,0x6C },mess=0xFB04 }, + fj={ name="f_j",unicode={ 0x66,0x6A } }, + fk={ name="f_k",unicode={ 0x66,0x6B } }, + } + local o=allocate {} + for k,v in next,overloads do + local name=v.name + local mess=v.mess + if name then + o[name]=v + end + if mess then + o[mess]=v + end + o[k]=v + end + mappings.overloads=o +end +function mappings.addtounicode(data,filename,checklookups,forceligatures) + local resources=data.resources + local unicodes=resources.unicodes + if not unicodes then + if trace_mapping then + report_fonts("no unicode list, quitting tounicode for %a",filename) + end + return + end + local properties=data.properties + local descriptions=data.descriptions + local overloads=mappings.overloads + unicodes['space']=unicodes['space'] or 32 + unicodes['hyphen']=unicodes['hyphen'] or 45 + unicodes['zwj']=unicodes['zwj'] or 0x200D + unicodes['zwnj']=unicodes['zwnj'] or 0x200C + local private=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 + local unicodevector=fonts.encodings.agl.unicodes or {} + local contextvector=fonts.encodings.agl.ctxcodes or {} + local missing={} + local nofmissing=0 + local oparser=nil + local cidnames=nil + local cidcodes=nil + local cidinfo=properties.cidinfo + local usedmap=cidinfo and fonts.cid.getmap(cidinfo) + local uparser=makenameparser() + if usedmap then + oparser=usedmap and makenameparser(cidinfo.ordering) + cidnames=usedmap.names + cidcodes=usedmap.unicodes + end + local ns=0 + local nl=0 + local dlist=sortedkeys(descriptions) + for i=1,#dlist do + local du=dlist[i] + local glyph=descriptions[du] + local name=glyph.name + if name then + local overload=overloads[name] or overloads[du] + if overload then + glyph.unicode=overload.unicode + else + local gu=glyph.unicode + if not gu or gu==-1 or du>=private or (du>=0xE000 and du<=0xF8FF) or du==0xFFFE or du==0xFFFF then + local unicode=unicodevector[name] or contextvector[name] + if unicode then + glyph.unicode=unicode + ns=ns+1 + end + if (not unicode) and usedmap then + local foundindex=lpegmatch(oparser,name) + if foundindex then + unicode=cidcodes[foundindex] + if unicode then + glyph.unicode=unicode + ns=ns+1 + else + local reference=cidnames[foundindex] + if reference then + local foundindex=lpegmatch(oparser,reference) + if foundindex then + unicode=cidcodes[foundindex] + if unicode then + glyph.unicode=unicode + ns=ns+1 + end + end + if not unicode or unicode=="" then + local foundcodes,multiple=lpegmatch(uparser,reference) + if foundcodes then + glyph.unicode=foundcodes + if multiple then + nl=nl+1 + unicode=true + else + ns=ns+1 + unicode=foundcodes + end + end + end + end + end + end + end + if not unicode or unicode=="" then + local split=lpegmatch(namesplitter,name) + local nsplit=split and #split or 0 + if nsplit==0 then + elseif nsplit==1 then + local base=split[1] + local u=unicodes[base] or unicodevector[base] or contextvector[name] + if not u then + elseif type(u)=="table" then + if u[1]=private then + break + end + n=n+1 + t[n]=u[1] + else + if u>=private then + break + end + n=n+1 + t[n]=u + end + end + if n>0 then + if n==1 then + unicode=t[1] + else + unicode=t + end + glyph.unicode=unicode + end + end + nl=nl+1 + end + if not unicode or unicode=="" then + local foundcodes,multiple=lpegmatch(uparser,name) + if foundcodes then + glyph.unicode=foundcodes + if multiple then + nl=nl+1 + unicode=true + else + ns=ns+1 + unicode=foundcodes + end + end + end + local r=overloads[unicode] + if r then + unicode=r.unicode + glyph.unicode=unicode + end + if not unicode then + missing[du]=true + nofmissing=nofmissing+1 + end + else + end + end + else + local overload=overloads[du] + if overload then + glyph.unicode=overload.unicode + elseif not glyph.unicode then + missing[du]=true + nofmissing=nofmissing+1 + end + end + end + if type(checklookups)=="function" then + checklookups(data,missing,nofmissing) + end + local unicoded=0 + local collected=fonts.handlers.otf.readers.getcomponents(data) + local function resolve(glyph,u) + local n=#u + for i=1,n do + if u[i]>private then + n=0 + break + end + end + if n>0 then + if n>1 then + glyph.unicode=u + else + glyph.unicode=u[1] + end + unicoded=unicoded+1 + end + end + if not collected then + elseif forceligatures or force_ligatures then + for i=1,#dlist do + local du=dlist[i] + if du>=private or (du>=0xE000 and du<=0xF8FF) then + local u=collected[du] + if u then + resolve(descriptions[du],u) + end + end + end + else + for i=1,#dlist do + local du=dlist[i] + if du>=private or (du>=0xE000 and du<=0xF8FF) then + local glyph=descriptions[du] + if glyph.class=="ligature" and not glyph.unicode then + local u=collected[du] + if u then + resolve(glyph,u) + end + end + end + end + end + if trace_mapping and unicoded>0 then + report_fonts("%n ligature tounicode mappings deduced from gsub ligature features",unicoded) + end + if trace_mapping then + for i=1,#dlist do + local du=dlist[i] + local glyph=descriptions[du] + local name=glyph.name or "-" + local index=glyph.index or 0 + local unicode=glyph.unicode + if unicode then + if type(unicode)=="table" then + local unicodes={} + for i=1,#unicode do + unicodes[i]=formatters("%U",unicode[i]) + end + report_fonts("internal slot %U, name %a, unicode %U, tounicode % t",index,name,du,unicodes) + else + report_fonts("internal slot %U, name %a, unicode %U, tounicode %U",index,name,du,unicode) + end + else + report_fonts("internal slot %U, name %a, unicode %U",index,name,du) + end + end + end + if trace_loading and (ns>0 or nl>0) then + report_fonts("%s tounicode entries added, ligatures %s",nl+ns,ns) + end +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-map”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-vfc” a81c29eda98cd62cbebdb6c93544b50d] --- + +if not modules then modules={} end modules ['font-vfc']={ + version=1.001, + comment="companion to font-ini.mkiv and hand-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local select,type=select,type +local insert=table.insert +local fonts=fonts +local helpers=fonts.helpers +local setmetatableindex=table.setmetatableindex +local push={ "push" } +local pop={ "pop" } +local dummy={ "comment" } +function helpers.prependcommands(commands,...) + insert(commands,1,push) + for i=select("#",...),1,-1 do + local s=(select(i,...)) + if s then + insert(commands,1,s) + end + end + insert(commands,pop) + return commands +end +function helpers.appendcommands(commands,...) + insert(commands,1,push) + insert(commands,pop) + for i=1,select("#",...) do + local s=(select(i,...)) + if s then + insert(commands,s) + end + end + return commands +end +function helpers.prependcommandtable(commands,t) + insert(commands,1,push) + for i=#t,1,-1 do + local s=t[i] + if s then + insert(commands,1,s) + end + end + insert(commands,pop) + return commands +end +function helpers.appendcommandtable(commands,t) + insert(commands,1,push) + insert(commands,pop) + for i=1,#t do + local s=t[i] + if s then + insert(commands,s) + end + end + return commands +end +local char=setmetatableindex(function(t,k) + local v={ "slot",0,k } + t[k]=v + return v +end) +local right=setmetatableindex(function(t,k) + local v={ "right",k } + t[k]=v + return v +end) +local left=setmetatableindex(function(t,k) + local v={ "right",-k } + t[k]=v + return v +end) +local down=setmetatableindex(function(t,k) + local v={ "down",k } + t[k]=v + return v +end) +local up=setmetatableindex(function(t,k) + local v={ "down",-k } + t[k]=v + return v +end) +helpers.commands=utilities.storage.allocate { + char=char, + right=right, + left=left, + down=down, + up=up, + push=push, + pop=pop, + dummy=dummy, +} + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-vfc”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-otr” 64dcbbc7107538723990e1119a80a9f8] --- + +if not modules then modules={} end modules ['font-otr']={ + version=1.001, + optimize=true, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next,type,tonumber,rawget=next,type,tonumber,rawget +local byte,lower,char,gsub=string.byte,string.lower,string.char,string.gsub +local fullstrip=string.fullstrip +local floor,round=math.floor,math.round +local P,R,S,C,Cs,Cc,Ct,Carg,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg,lpeg.Cmt +local lpegmatch=lpeg.match +local rshift=bit32.rshift +local setmetatableindex=table.setmetatableindex +local sortedkeys=table.sortedkeys +local sortedhash=table.sortedhash +local stripstring=string.nospaces +local utf16_to_utf8_be=utf.utf16_to_utf8_be +local report=logs.reporter("otf reader") +local report_cmap=logs.reporter("otf reader","cmap") +local trace_cmap=false trackers.register("otf.cmap",function(v) trace_cmap=v end) +local trace_cmap_details=false trackers.register("otf.cmap.details",function(v) trace_cmap_details=v end) +fonts=fonts or {} +local handlers=fonts.handlers or {} +fonts.handlers=handlers +local otf=handlers.otf or {} +handlers.otf=otf +local readers=otf.readers or {} +otf.readers=readers +local streamreader=utilities.files +local streamwriter=utilities.files +readers.streamreader=streamreader +readers.streamwriter=streamwriter +local openfile=streamreader.open +local closefile=streamreader.close +local setposition=streamreader.setposition +local skipshort=streamreader.skipshort +local readbytes=streamreader.readbytes +local readstring=streamreader.readstring +local readbyte=streamreader.readcardinal1 +local readushort=streamreader.readcardinal2 +local readuint=streamreader.readcardinal3 +local readulong=streamreader.readcardinal4 +local readshort=streamreader.readinteger2 +local readlong=streamreader.readinteger4 +local readfixed=streamreader.readfixed4 +local read2dot14=streamreader.read2dot14 +local readfword=readshort +local readufword=readushort +local readoffset=readushort +local readcardinaltable=streamreader.readcardinaltable +local readintegertable=streamreader.readintegertable +function streamreader.readtag(f) + return lower(stripstring(readstring(f,4))) +end +local short=2 +local ushort=2 +local ulong=4 +directives.register("fonts.streamreader",function() + streamreader=utilities.streams + openfile=streamreader.open + closefile=streamreader.close + setposition=streamreader.setposition + skipshort=streamreader.skipshort + readbytes=streamreader.readbytes + readstring=streamreader.readstring + readbyte=streamreader.readcardinal1 + readushort=streamreader.readcardinal2 + readuint=streamreader.readcardinal3 + readulong=streamreader.readcardinal4 + readshort=streamreader.readinteger2 + readlong=streamreader.readinteger4 + readfixed=streamreader.readfixed4 + read2dot14=streamreader.read2dot14 + readfword=readshort + readufword=readushort + readoffset=readushort + readcardinaltable=streamreader.readcardinaltable + readintegertable=streamreader.readintegertable + function streamreader.readtag(f) + return lower(stripstring(readstring(f,4))) + end +end) +local function readlongdatetime(f) + local a,b,c,d,e,f,g,h=readbytes(f,8) + return 0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h +end +local tableversion=0.004 +readers.tableversion=tableversion +local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 +local reservednames={ [0]="copyright", + "family", + "subfamily", + "uniqueid", + "fullname", + "version", + "postscriptname", + "trademark", + "manufacturer", + "designer", + "description", + "vendorurl", + "designerurl", + "license", + "licenseurl", + "reserved", + "typographicfamily", + "typographicsubfamily", + "compatiblefullname", + "sampletext", + "cidfindfontname", + "wwsfamily", + "wwssubfamily", + "lightbackgroundpalette", + "darkbackgroundpalette", + "variationspostscriptnameprefix", +} +local platforms={ [0]="unicode", + "macintosh", + "iso", + "windows", + "custom", +} +local encodings={ + unicode={ [0]="unicode 1.0 semantics", + "unicode 1.1 semantics", + "iso/iec 10646", + "unicode 2.0 bmp", + "unicode 2.0 full", + "unicode variation sequences", + "unicode full repertoire", + }, + macintosh={ [0]="roman","japanese","chinese (traditional)","korean","arabic","hebrew","greek","russian", + "rsymbol","devanagari","gurmukhi","gujarati","oriya","bengali","tamil","telugu","kannada", + "malayalam","sinhalese","burmese","khmer","thai","laotian","georgian","armenian", + "chinese (simplified)","tibetan","mongolian","geez","slavic","vietnamese","sindhi", + "uninterpreted", + }, + iso={ [0]="7-bit ascii", + "iso 10646", + "iso 8859-1", + }, + windows={ [0]="symbol", + "unicode bmp", + "shiftjis", + "prc", + "big5", + "wansung", + "johab", + "reserved 7", + "reserved 8", + "reserved 9", + "unicode ucs-4", + }, + custom={ + } +} +local decoders={ + unicode={}, + macintosh={}, + iso={}, + windows={ + ["unicode semantics"]=utf16_to_utf8_be, + ["unicode bmp"]=utf16_to_utf8_be, + ["unicode full"]=utf16_to_utf8_be, + ["unicode 1.0 semantics"]=utf16_to_utf8_be, + ["unicode 1.1 semantics"]=utf16_to_utf8_be, + ["unicode 2.0 bmp"]=utf16_to_utf8_be, + ["unicode 2.0 full"]=utf16_to_utf8_be, + ["unicode variation sequences"]=utf16_to_utf8_be, + ["unicode full repertoire"]=utf16_to_utf8_be, + }, + custom={}, +} +local languages={ + unicode={ + [ 0]="english", + }, + macintosh={ + [ 0]="english", + }, + iso={}, + windows={ + [0x0409]="english - united states", + }, + custom={}, +} +local standardromanencoding={ [0]= + "notdef",".null","nonmarkingreturn","space","exclam","quotedbl", + "numbersign","dollar","percent","ampersand","quotesingle","parenleft", + "parenright","asterisk","plus","comma","hyphen","period","slash", + "zero","one","two","three","four","five","six","seven","eight", + "nine","colon","semicolon","less","equal","greater","question","at", + "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O", + "P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft", + "backslash","bracketright","asciicircum","underscore","grave","a","b", + "c","d","e","f","g","h","i","j","k","l","m","n","o","p","q", + "r","s","t","u","v","w","x","y","z","braceleft","bar", + "braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute", + "Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex", + "adieresis","atilde","aring","ccedilla","eacute","egrave", + "ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis", + "ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute", + "ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling", + "section","bullet","paragraph","germandbls","registered","copyright", + "trademark","acute","dieresis","notequal","AE","Oslash","infinity", + "plusminus","lessequal","greaterequal","yen","mu","partialdiff", + "summation","product","pi","integral","ordfeminine","ordmasculine", + "Omega","ae","oslash","questiondown","exclamdown","logicalnot", + "radical","florin","approxequal","Delta","guillemotleft", + "guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde", + "Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright", + "quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis", + "fraction","currency","guilsinglleft","guilsinglright","fi","fl", + "daggerdbl","periodcentered","quotesinglbase","quotedblbase", + "perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave", + "Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex", + "apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi", + "circumflex","tilde","macron","breve","dotaccent","ring","cedilla", + "hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron", + "Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn", + "thorn","minus","multiply","onesuperior","twosuperior","threesuperior", + "onehalf","onequarter","threequarters","franc","Gbreve","gbreve", + "Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron", + "dcroat", +} +local weights={ + [100]="thin", + [200]="extralight", + [300]="light", + [400]="normal", + [500]="medium", + [600]="semibold", + [700]="bold", + [800]="extrabold", + [900]="black", +} +local widths={ + [1]="ultracondensed", + [2]="extracondensed", + [3]="condensed", + [4]="semicondensed", + [5]="normal", + [6]="semiexpanded", + [7]="expanded", + [8]="extraexpanded", + [9]="ultraexpanded", +} +setmetatableindex(weights,function(t,k) + local r=floor((k+50)/100)*100 + local v=(r>900 and "black") or rawget(t,r) or "normal" + return v +end) +setmetatableindex(widths,function(t,k) + return "normal" +end) +local panoseweights={ + [ 0]="normal", + [ 1]="normal", + [ 2]="verylight", + [ 3]="light", + [ 4]="thin", + [ 5]="book", + [ 6]="medium", + [ 7]="demi", + [ 8]="bold", + [ 9]="heavy", + [10]="black", +} +local panosewidths={ + [ 0]="normal", + [ 1]="normal", + [ 2]="normal", + [ 3]="normal", + [ 4]="normal", + [ 5]="expanded", + [ 6]="condensed", + [ 7]="veryexpanded", + [ 8]="verycondensed", + [ 9]="monospaced", +} +local helpers={} +readers.helpers=helpers +local function gotodatatable(f,fontdata,tag,criterium) + if criterium and f then + local tables=fontdata.tables + if tables then + local datatable=tables[tag] + if datatable then + local tableoffset=datatable.offset + setposition(f,tableoffset) + return tableoffset + end + else + report("no tables") + end + end +end +local function reportskippedtable(f,fontdata,tag,criterium) + if criterium and f then + local tables=fontdata.tables + if tables then + local datatable=tables[tag] + if datatable then + report("loading of table %a skipped",tag) + end + else + report("no tables") + end + end +end +local function setvariabledata(fontdata,tag,data) + local variabledata=fontdata.variabledata + if variabledata then + variabledata[tag]=data + else + fontdata.variabledata={ [tag]=data } + end +end +helpers.gotodatatable=gotodatatable +helpers.setvariabledata=setvariabledata +helpers.reportskippedtable=reportskippedtable +local platformnames={ + postscriptname=true, + fullname=true, + family=true, + subfamily=true, + typographicfamily=true, + typographicsubfamily=true, + compatiblefullname=true, +} +local platformextras={ + uniqueid=true, + version=true, + copyright=true, + license=true, + licenseurl=true, + manufacturer=true, + vendorurl=true, +} +function readers.name(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"name",true) + if tableoffset then + local format=readushort(f) + local nofnames=readushort(f) + local offset=readushort(f) + local start=tableoffset+offset + local namelists={ + unicode={}, + windows={}, + macintosh={}, + } + for i=1,nofnames do + local platform=platforms[readushort(f)] + if platform then + local namelist=namelists[platform] + if namelist then + local encoding=readushort(f) + local language=readushort(f) + local encodings=encodings[platform] + local languages=languages[platform] + if encodings and languages then + local encoding=encodings[encoding] + local language=languages[language] + if encoding and language then + local index=readushort(f) + local name=reservednames[index] + namelist[#namelist+1]={ + platform=platform, + encoding=encoding, + language=language, + name=name, + index=index, + length=readushort(f), + offset=start+readushort(f), + } + else + skipshort(f,3) + end + else + skipshort(f,3) + end + else + skipshort(f,5) + end + else + skipshort(f,5) + end + end + local names={} + local done={} + local extras={} + local function decoded(platform,encoding,content) + local decoder=decoders[platform] + if decoder then + decoder=decoder[encoding] + end + if decoder then + return decoder(content) + else + return content + end + end + local function filter(platform,e,l) + local namelist=namelists[platform] + for i=1,#namelist do + local name=namelist[i] + local nametag=name.name + local index=name.index + if not done[nametag or i] then + local encoding=name.encoding + local language=name.language + if (not e or encoding==e) and (not l or language==l) then + setposition(f,name.offset) + local content=decoded(platform,encoding,readstring(f,name.length)) + if nametag then + names[nametag]={ + content=content, + platform=platform, + encoding=encoding, + language=language, + } + end + extras[index]=content + done[nametag or i]=true + end + end + end + end + filter("windows","unicode bmp","english - united states") + filter("macintosh","roman","english") + filter("windows") + filter("macintosh") + filter("unicode") + fontdata.names=names + fontdata.extras=extras + if specification.platformnames then + local collected={} + local platformextras=specification.platformextras and platformextras + for platform,namelist in next,namelists do + local filtered=false + for i=1,#namelist do + local entry=namelist[i] + local name=entry.name + if platformnames[name] or (platformextras and platformextras[name]) then + setposition(f,entry.offset) + local content=decoded(platform,entry.encoding,readstring(f,entry.length)) + if filtered then + filtered[name]=content + else + filtered={ [name]=content } + end + end + end + if filtered then + collected[platform]=filtered + end + end + fontdata.platformnames=collected + end + else + fontdata.names={} + end +end +local validutf=lpeg.patterns.validutf8 +local function getname(fontdata,key) + local names=fontdata.names + if names then + local value=names[key] + if value then + local content=value.content + return lpegmatch(validutf,content) and content or nil + end + end +end +readers["os/2"]=function(f,fontdata) + local tableoffset=gotodatatable(f,fontdata,"os/2",true) + if tableoffset then + local version=readushort(f) + local windowsmetrics={ + version=version, + averagewidth=readshort(f), + weightclass=readushort(f), + widthclass=readushort(f), + fstype=readushort(f), + subscriptxsize=readshort(f), + subscriptysize=readshort(f), + subscriptxoffset=readshort(f), + subscriptyoffset=readshort(f), + superscriptxsize=readshort(f), + superscriptysize=readshort(f), + superscriptxoffset=readshort(f), + superscriptyoffset=readshort(f), + strikeoutsize=readshort(f), + strikeoutpos=readshort(f), + familyclass=readshort(f), + panose={ readbytes(f,10) }, + unicoderanges={ readulong(f),readulong(f),readulong(f),readulong(f) }, + vendor=readstring(f,4), + fsselection=readushort(f), + firstcharindex=readushort(f), + lastcharindex=readushort(f), + typoascender=readshort(f), + typodescender=readshort(f), + typolinegap=readshort(f), + winascent=readushort(f), + windescent=readushort(f), + } + if version>=1 then + windowsmetrics.codepageranges={ readulong(f),readulong(f) } + end + if version>=2 then + windowsmetrics.xheight=readshort(f) + windowsmetrics.capheight=readshort(f) + windowsmetrics.defaultchar=readushort(f) + windowsmetrics.breakchar=readushort(f) + end + windowsmetrics.weight=windowsmetrics.weightclass and weights[windowsmetrics.weightclass] + windowsmetrics.width=windowsmetrics.widthclass and widths [windowsmetrics.widthclass] + windowsmetrics.panoseweight=panoseweights[windowsmetrics.panose[3]] + windowsmetrics.panosewidth=panosewidths [windowsmetrics.panose[4]] + fontdata.windowsmetrics=windowsmetrics + else + fontdata.windowsmetrics={} + end +end +readers.head=function(f,fontdata) + local tableoffset=gotodatatable(f,fontdata,"head",true) + if tableoffset then + local version=readulong(f) + local fontversion=readulong(f) + local fontheader={ + version=version, + fontversion=number.to16dot16(fontversion), + fontversionnumber=fontversion, + checksum=readushort(f)*0x10000+readushort(f), + magic=readulong(f), + flags=readushort(f), + units=readushort(f), + created=readlongdatetime(f), + modified=readlongdatetime(f), + xmin=readshort(f), + ymin=readshort(f), + xmax=readshort(f), + ymax=readshort(f), + macstyle=readushort(f), + smallpixels=readushort(f), + directionhint=readshort(f), + indextolocformat=readshort(f), + glyphformat=readshort(f), + } + fontdata.fontheader=fontheader + else + fontdata.fontheader={} + end + fontdata.nofglyphs=0 +end +readers.hhea=function(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"hhea",specification.details) + if tableoffset then + fontdata.horizontalheader={ + version=readulong(f), + ascender=readfword(f), + descender=readfword(f), + linegap=readfword(f), + maxadvancewidth=readufword(f), + minleftsidebearing=readfword(f), + minrightsidebearing=readfword(f), + maxextent=readfword(f), + caretsloperise=readshort(f), + caretsloperun=readshort(f), + caretoffset=readshort(f), + reserved_1=readshort(f), + reserved_2=readshort(f), + reserved_3=readshort(f), + reserved_4=readshort(f), + metricdataformat=readshort(f), + nofmetrics=readushort(f), + } + else + fontdata.horizontalheader={ + nofmetrics=0, + } + end +end +readers.vhea=function(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"vhea",specification.details) + if tableoffset then + fontdata.verticalheader={ + version=readulong(f), + ascender=readfword(f), + descender=readfword(f), + linegap=readfword(f), + maxadvanceheight=readufword(f), + mintopsidebearing=readfword(f), + minbottomsidebearing=readfword(f), + maxextent=readfword(f), + caretsloperise=readshort(f), + caretsloperun=readshort(f), + caretoffset=readshort(f), + reserved_1=readshort(f), + reserved_2=readshort(f), + reserved_3=readshort(f), + reserved_4=readshort(f), + metricdataformat=readshort(f), + nofmetrics=readushort(f), + } + else + fontdata.verticalheader={ + nofmetrics=0, + } + end +end +readers.maxp=function(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"maxp",specification.details) + if tableoffset then + local version=readulong(f) + local nofglyphs=readushort(f) + fontdata.nofglyphs=nofglyphs + if version==0x00005000 then + fontdata.maximumprofile={ + version=version, + nofglyphs=nofglyphs, + } + elseif version==0x00010000 then + fontdata.maximumprofile={ + version=version, + nofglyphs=nofglyphs, + points=readushort(f), + contours=readushort(f), + compositepoints=readushort(f), + compositecontours=readushort(f), + zones=readushort(f), + twilightpoints=readushort(f), + storage=readushort(f), + functiondefs=readushort(f), + instructiondefs=readushort(f), + stackelements=readushort(f), + sizeofinstructions=readushort(f), + componentelements=readushort(f), + componentdepth=readushort(f), + } + else + fontdata.maximumprofile={ + version=version, + nofglyphs=0, + } + end + end +end +readers.hmtx=function(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"hmtx",specification.glyphs) + if tableoffset then + local horizontalheader=fontdata.horizontalheader + local nofmetrics=horizontalheader.nofmetrics + local glyphs=fontdata.glyphs + local nofglyphs=fontdata.nofglyphs + local width=0 + local leftsidebearing=0 + for i=0,nofmetrics-1 do + local glyph=glyphs[i] + width=readshort(f) + leftsidebearing=readshort(f) + if width~=0 then + glyph.width=width + end + end + for i=nofmetrics,nofglyphs-1 do + local glyph=glyphs[i] + if width~=0 then + glyph.width=width + end + end + end +end +readers.vmtx=function(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"vmtx",specification.glyphs) + if tableoffset then + local verticalheader=fontdata.verticalheader + local nofmetrics=verticalheader.nofmetrics + local glyphs=fontdata.glyphs + local nofglyphs=fontdata.nofglyphs + local vheight=0 + local vdefault=verticalheader.ascender-verticalheader.descender + local topsidebearing=0 + for i=0,nofmetrics-1 do + local glyph=glyphs[i] + vheight=readushort(f) + topsidebearing=readshort(f) + if vheight~=0 and vheight~=vdefault then + glyph.vheight=vheight + end + if topsidebearing~=0 then + glyph.tsb=topsidebearing + end + end + for i=nofmetrics,nofglyphs-1 do + local glyph=glyphs[i] + if vheight~=0 and vheight~=vdefault then + glyph.vheight=vheight + end + end + end +end +readers.vorg=function(f,fontdata,specification) + reportskippedtable(f,fontdata,"vorg",specification.glyphs) +end +readers.post=function(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"post",true) + if tableoffset then + local version=readulong(f) + fontdata.postscript={ + version=version, + italicangle=round(1000*readfixed(f))/1000, + underlineposition=readfword(f), + underlinethickness=readfword(f), + monospaced=readulong(f), + minmemtype42=readulong(f), + maxmemtype42=readulong(f), + minmemtype1=readulong(f), + maxmemtype1=readulong(f), + } + if not specification.glyphs then + elseif version==0x00010000 then + for index=0,#standardromanencoding do + glyphs[index].name=standardromanencoding[index] + end + elseif version==0x00020000 then + local glyphs=fontdata.glyphs + local nofglyphs=readushort(f) + local indices={} + local names={} + local maxnames=0 + for i=0,nofglyphs-1 do + local nameindex=readushort(f) + if nameindex>=258 then + maxnames=maxnames+1 + nameindex=nameindex-257 + indices[nameindex]=i + else + glyphs[i].name=standardromanencoding[nameindex] + end + end + for i=1,maxnames do + local mapping=indices[i] + if not mapping then + report("quit post name fetching at %a of %a: %s",i,maxnames,"no index") + break + else + local length=readbyte(f) + if length>0 then + glyphs[mapping].name=readstring(f,length) + else + report("quit post name fetching at %a of %a: %s",i,maxnames,"overflow") + break + end + end + end + end + else + fontdata.postscript={} + end +end +readers.cff=function(f,fontdata,specification) + reportskippedtable(f,fontdata,"cff",specification.glyphs) +end +local formatreaders={} +local duplicatestoo=true +local sequence={ + { 3,1,4 }, + { 3,10,12 }, + { 0,3,4 }, + { 0,3,12 }, + { 0,1,4 }, + { 0,1,12 }, + { 0,0,6 }, + { 3,0,6 }, + { 3,0,4 }, + { 0,5,14 }, + { 0,4,12 }, + { 3,10,13 }, +} +local supported={} +for i=1,#sequence do + local si=sequence[i] + local sp,se,sf=si[1],si[2],si[3] + local p=supported[sp] + if not p then + p={} + supported[sp]=p + end + local e=p[se] + if not e then + e={} + p[se]=e + end + e[sf]=true +end +formatreaders[4]=function(f,fontdata,offset) + setposition(f,offset+2) + local length=readushort(f) + local language=readushort(f) + local nofsegments=readushort(f)/2 + skipshort(f,3) + local mapping=fontdata.mapping + local glyphs=fontdata.glyphs + local duplicates=fontdata.duplicates + local nofdone=0 + local endchars=readcardinaltable(f,nofsegments,ushort) + local reserved=readushort(f) + local startchars=readcardinaltable(f,nofsegments,ushort) + local deltas=readcardinaltable(f,nofsegments,ushort) + local offsets=readcardinaltable(f,nofsegments,ushort) + local size=(length-2*2-5*2-4*2*nofsegments)/2 + local indices=readcardinaltable(f,size-1,ushort) + for segment=1,nofsegments do + local startchar=startchars[segment] + local endchar=endchars[segment] + local offset=offsets[segment] + local delta=deltas[segment] + if startchar==0xFFFF and endchar==0xFFFF then + elseif startchar==0xFFFF and offset==0 then + elseif offset==0xFFFF then + elseif offset==0 then + if trace_cmap_details then + report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,(startchar+delta)%65536) + end + for unicode=startchar,endchar do + local index=(unicode+delta)%65536 + if index and index>0 then + local glyph=glyphs[index] + if glyph then + local gu=glyph.unicode + if not gu then + glyph.unicode=unicode + nofdone=nofdone+1 + elseif gu~=unicode then + if duplicatestoo then + local d=duplicates[gu] + if d then + d[unicode]=true + else + duplicates[gu]={ [unicode]=true } + end + else + report("duplicate case 1: %C %04i %s",unicode,index,glyphs[index].name) + end + end + if not mapping[index] then + mapping[index]=unicode + end + end + end + end + else + local shift=(segment-nofsegments+offset/2)-startchar + if trace_cmap_details then + report_cmap("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,(startchar+delta)%65536) + end + for unicode=startchar,endchar do + local slot=shift+unicode + local index=indices[slot] + if index and index>0 then + index=(index+delta)%65536 + local glyph=glyphs[index] + if glyph then + local gu=glyph.unicode + if not gu then + glyph.unicode=unicode + nofdone=nofdone+1 + elseif gu~=unicode then + if duplicatestoo then + local d=duplicates[gu] + if d then + d[unicode]=true + else + duplicates[gu]={ [unicode]=true } + end + else + report("duplicate case 2: %C %04i %s",unicode,index,glyphs[index].name) + end + end + if not mapping[index] then + mapping[index]=unicode + end + end + end + end + end + end + return nofdone +end +formatreaders[6]=function(f,fontdata,offset) + setposition(f,offset) + local format=readushort(f) + local length=readushort(f) + local language=readushort(f) + local mapping=fontdata.mapping + local glyphs=fontdata.glyphs + local duplicates=fontdata.duplicates + local start=readushort(f) + local count=readushort(f) + local stop=start+count-1 + local nofdone=0 + if trace_cmap_details then + report_cmap("format 6 from %C to %C",2,start,stop) + end + for unicode=start,stop do + local index=readushort(f) + if index>0 then + local glyph=glyphs[index] + if glyph then + local gu=glyph.unicode + if not gu then + glyph.unicode=unicode + nofdone=nofdone+1 + elseif gu~=unicode then + end + if not mapping[index] then + mapping[index]=unicode + end + end + end + end + return nofdone +end +formatreaders[12]=function(f,fontdata,offset) + setposition(f,offset+2+2+4+4) + local mapping=fontdata.mapping + local glyphs=fontdata.glyphs + local duplicates=fontdata.duplicates + local nofgroups=readulong(f) + local nofdone=0 + for i=1,nofgroups do + local first=readulong(f) + local last=readulong(f) + local index=readulong(f) + if trace_cmap_details then + report_cmap("format 12 from %C to %C starts at index %i",first,last,index) + end + for unicode=first,last do + local glyph=glyphs[index] + if glyph then + local gu=glyph.unicode + if not gu then + glyph.unicode=unicode + nofdone=nofdone+1 + elseif gu~=unicode then + local d=duplicates[gu] + if d then + d[unicode]=true + else + duplicates[gu]={ [unicode]=true } + end + end + if not mapping[index] then + mapping[index]=unicode + end + end + index=index+1 + end + end + return nofdone +end +formatreaders[13]=function(f,fontdata,offset) + setposition(f,offset+2+2+4+4) + local mapping=fontdata.mapping + local glyphs=fontdata.glyphs + local duplicates=fontdata.duplicates + local nofgroups=readulong(f) + local nofdone=0 + for i=1,nofgroups do + local first=readulong(f) + local last=readulong(f) + local index=readulong(f) + if first=privateoffset then + local limit=privateoffset-1 + report("format 13 from %C to %C pruned to %C",first,last,limit) + last=limit + end + for unicode=first,last do + list[unicode]=true + end + nofdone=nofdone+last-first+1 + else + report("format 13 from %C to %C ignored",first,last) + end + end + return nofdone +end +formatreaders[14]=function(f,fontdata,offset) + if offset and offset~=0 then + setposition(f,offset) + local format=readushort(f) + local length=readulong(f) + local nofrecords=readulong(f) + local records={} + local variants={} + local nofdone=0 + fontdata.variants=variants + for i=1,nofrecords do + records[i]={ + selector=readuint(f), + default=readulong(f), + other=readulong(f), + } + end + for i=1,nofrecords do + local record=records[i] + local selector=record.selector + local default=record.default + local other=record.other + local other=record.other + if other~=0 then + setposition(f,offset+other) + local mapping={} + local count=readulong(f) + for i=1,count do + mapping[readuint(f)]=readushort(f) + end + nofdone=nofdone+count + variants[selector]=mapping + end + end + return nofdone + else + return 0 + end +end +local function checkcmap(f,fontdata,records,platform,encoding,format) + local pdata=records[platform] + if not pdata then + if trace_cmap_details then + report_cmap("skipped, %s, p=%i e=%i f=%i","no platform",platform,encoding,format) + end + return 0 + end + local edata=pdata[encoding] + if not edata then + if trace_cmap_details then + report_cmap("skipped, %s, p=%i e=%i f=%i","no encoding",platform,encoding,format) + end + return 0 + end + local fdata=edata[format] + if not fdata then + if trace_cmap_details then + report_cmap("skipped, %s, p=%i e=%i f=%i","no format",platform,encoding,format) + end + return 0 + elseif type(fdata)~="number" then + if trace_cmap_details then + report_cmap("skipped, %s, p=%i e=%i f=%i","already done",platform,encoding,format) + end + return 0 + end + edata[format]=true + local reader=formatreaders[format] + if not reader then + if trace_cmap_details then + report_cmap("skipped, %s, p=%i e=%i f=%i","unsupported format",platform,encoding,format) + end + return 0 + end + local n=reader(f,fontdata,fdata) or 0 + if trace_cmap_details or trace_cmap then + local p=platforms[platform] + local e=encodings[p] + report_cmap("checked, platform %i (%s), encoding %i (%s), format %i, new unicodes %i", + platform,p,encoding,e and e[encoding] or "?",format,n) + end + return n +end +function readers.cmap(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"cmap",specification.glyphs) + if tableoffset then + local version=readushort(f) + local noftables=readushort(f) + local records={} + local unicodecid=false + local variantcid=false + local variants={} + local duplicates=fontdata.duplicates or {} + fontdata.duplicates=duplicates + for i=1,noftables do + local platform=readushort(f) + local encoding=readushort(f) + local offset=readulong(f) + local record=records[platform] + if not record then + records[platform]={ + [encoding]={ + offsets={ offset }, + formats={}, + } + } + else + local subtables=record[encoding] + if not subtables then + record[encoding]={ + offsets={ offset }, + formats={}, + } + else + local offsets=subtables.offsets + offsets[#offsets+1]=offset + end + end + end + if trace_cmap then + report("found cmaps:") + end + for platform,record in sortedhash(records) do + local p=platforms[platform] + local e=encodings[p] + local sp=supported[platform] + local ps=p or "?" + if trace_cmap then + if sp then + report(" platform %i: %s",platform,ps) + else + report(" platform %i: %s (unsupported)",platform,ps) + end + end + for encoding,subtables in sortedhash(record) do + local se=sp and sp[encoding] + local es=e and e[encoding] or "?" + if trace_cmap then + if se then + report(" encoding %i: %s",encoding,es) + else + report(" encoding %i: %s (unsupported)",encoding,es) + end + end + local offsets=subtables.offsets + local formats=subtables.formats + for i=1,#offsets do + local offset=tableoffset+offsets[i] + setposition(f,offset) + formats[readushort(f)]=offset + end + record[encoding]=formats + if trace_cmap then + local list=sortedkeys(formats) + for i=1,#list do + if not (se and se[list[i]]) then + list[i]=list[i].." (unsupported)" + end + end + report(" formats: % t",list) + end + end + end + local ok=false + for i=1,#sequence do + local si=sequence[i] + local sp,se,sf=si[1],si[2],si[3] + if checkcmap(f,fontdata,records,sp,se,sf)>0 then + ok=true + end + end + if not ok then + report("no useable unicode cmap found") + end + fontdata.cidmaps={ + version=version, + noftables=noftables, + records=records, + } + else + fontdata.cidmaps={} + end +end +function readers.loca(f,fontdata,specification) + reportskippedtable(f,fontdata,"loca",specification.glyphs) +end +function readers.glyf(f,fontdata,specification) + reportskippedtable(f,fontdata,"glyf",specification.glyphs) +end +function readers.colr(f,fontdata,specification) + reportskippedtable(f,fontdata,"colr",specification.glyphs) +end +function readers.cpal(f,fontdata,specification) + reportskippedtable(f,fontdata,"cpal",specification.glyphs) +end +function readers.svg(f,fontdata,specification) + reportskippedtable(f,fontdata,"svg",specification.glyphs) +end +function readers.sbix(f,fontdata,specification) + reportskippedtable(f,fontdata,"sbix",specification.glyphs) +end +function readers.cbdt(f,fontdata,specification) + reportskippedtable(f,fontdata,"cbdt",specification.glyphs) +end +function readers.cblc(f,fontdata,specification) + reportskippedtable(f,fontdata,"cblc",specification.glyphs) +end +function readers.ebdt(f,fontdata,specification) + reportskippedtable(f,fontdata,"ebdt",specification.glyphs) +end +function readers.ebsc(f,fontdata,specification) + reportskippedtable(f,fontdata,"ebsc",specification.glyphs) +end +function readers.eblc(f,fontdata,specification) + reportskippedtable(f,fontdata,"eblc",specification.glyphs) +end +function readers.kern(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"kern",specification.kerns) + if tableoffset then + local version=readushort(f) + local noftables=readushort(f) + for i=1,noftables do + local version=readushort(f) + local length=readushort(f) + local coverage=readushort(f) + local format=rshift(coverage,8) + if format==0 then + local nofpairs=readushort(f) + local searchrange=readushort(f) + local entryselector=readushort(f) + local rangeshift=readushort(f) + local kerns={} + local glyphs=fontdata.glyphs + for i=1,nofpairs do + local left=readushort(f) + local right=readushort(f) + local kern=readfword(f) + local glyph=glyphs[left] + local kerns=glyph.kerns + if kerns then + kerns[right]=kern + else + glyph.kerns={ [right]=kern } + end + end + elseif format==2 then + report("todo: kern classes") + else + report("todo: kerns") + end + end + end +end +function readers.gdef(f,fontdata,specification) + reportskippedtable(f,fontdata,"gdef",specification.details) +end +function readers.gsub(f,fontdata,specification) + reportskippedtable(f,fontdata,"gsub",specification.details) +end +function readers.gpos(f,fontdata,specification) + reportskippedtable(f,fontdata,"gpos",specification.details) +end +function readers.math(f,fontdata,specification) + reportskippedtable(f,fontdata,"math",specification.details) +end +local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo,instancenames) + local fontdata=sub and maindata.subfonts and maindata.subfonts[sub] or maindata + local names=fontdata.names + local info=nil + if names then + local metrics=fontdata.windowsmetrics or {} + local postscript=fontdata.postscript or {} + local fontheader=fontdata.fontheader or {} + local cffinfo=fontdata.cffinfo or {} + local verticalheader=fontdata.verticalheader or {} + local filename=fontdata.filename + local weight=getname(fontdata,"weight") or (cffinfo and cffinfo.weight) or (metrics and metrics.weight) + local width=getname(fontdata,"width") or (cffinfo and cffinfo.width ) or (metrics and metrics.width ) + local fontname=getname(fontdata,"postscriptname") + local fullname=getname(fontdata,"fullname") + local family=getname(fontdata,"family") + local subfamily=getname(fontdata,"subfamily") + local familyname=getname(fontdata,"typographicfamily") + local subfamilyname=getname(fontdata,"typographicsubfamily") + local compatiblename=getname(fontdata,"compatiblefullname") + if rawfamilynames then + else + if not familyname then familyname=family end + if not subfamilyname then subfamilyname=subfamily end + end + if platformnames then + platformnames=fontdata.platformnames + end + if instancenames then + local variabledata=fontdata.variabledata + if variabledata then + local instances=variabledata and variabledata.instances + if instances then + instancenames={} + for i=1,#instances do + instancenames[i]=lower(stripstring(instances[i].subfamily)) + end + else + instancenames=nil + end + else + instancenames=nil + end + end + info={ + subfontindex=fontdata.subfontindex or sub or 0, + version=getname(fontdata,"version"), + fontname=fontname, + fullname=fullname, + family=family, + subfamily=subfamily, + familyname=familyname, + subfamilyname=subfamilyname, + compatiblename=compatiblename, + weight=weight and lower(weight), + width=width and lower(width), + pfmweight=metrics.weightclass or 400, + pfmwidth=metrics.widthclass or 5, + panosewidth=metrics.panosewidth, + panoseweight=metrics.panoseweight, + italicangle=postscript.italicangle or 0, + units=fontheader.units or 0, + designsize=fontdata.designsize, + minsize=fontdata.minsize, + maxsize=fontdata.maxsize, + boundingbox=fontheader and { fontheader.xmin or 0,fontheader.ymin or 0,fontheader.xmax or 0,fontheader.ymax or 0 } or nil, + monospaced=(tonumber(postscript.monospaced or 0)>0) or metrics.panosewidth=="monospaced", + averagewidth=metrics.averagewidth, + xheight=metrics.xheight, + capheight=metrics.capheight or fontdata.maxy, + ascender=metrics.typoascender, + descender=metrics.typodescender, + platformnames=platformnames or nil, + instancenames=instancenames or nil, + tableoffsets=fontdata.tableoffsets, + defaultvheight=(verticalheader.ascender or 0)-(verticalheader.descender or 0) + } + if metricstoo then + local keys={ + "version", + "ascender","descender","linegap", + "maxadvancewidth","maxadvanceheight","maxextent", + "minbottomsidebearing","mintopsidebearing", + } + local h=fontdata.horizontalheader or {} + local v=fontdata.verticalheader or {} + if h then + local th={} + local tv={} + for i=1,#keys do + local key=keys[i] + th[key]=h[key] or 0 + tv[key]=v[key] or 0 + end + info.horizontalmetrics=th + info.verticalmetrics=tv + end + end + elseif n then + info={ + filename=fontdata.filename, + comment="there is no info for subfont "..n, + } + else + info={ + filename=fontdata.filename, + comment="there is no info", + } + end + return info +end +local function loadtables(f,specification,offset) + if offset then + setposition(f,offset) + end + local tables={} + local basename=file.basename(specification.filename) + local filesize=specification.filesize + local filetime=specification.filetime + local fontdata={ + filename=basename, + filesize=filesize, + filetime=filetime, + version=readstring(f,4), + noftables=readushort(f), + searchrange=readushort(f), + entryselector=readushort(f), + rangeshift=readushort(f), + tables=tables, + foundtables=false, + } + for i=1,fontdata.noftables do + local tag=lower(stripstring(readstring(f,4))) + local checksum=readushort(f)*0x10000+readushort(f) + local offset=readulong(f) + local length=readulong(f) + if offset+length>filesize then + report("bad %a table in file %a",tag,basename) + end + tables[tag]={ + checksum=checksum, + offset=offset, + length=length, + } + end + fontdata.foundtables=sortedkeys(tables) + if tables.cff or tables.cff2 then + fontdata.format="opentype" + else + fontdata.format="truetype" + end + return fontdata,tables +end +local function prepareglyps(fontdata) + local glyphs=setmetatableindex(function(t,k) + local v={ + index=k, + } + t[k]=v + return v + end) + fontdata.glyphs=glyphs + fontdata.mapping={} +end +local function readtable(tag,f,fontdata,specification,...) + local reader=readers[tag] + if reader then + reader(f,fontdata,specification,...) + end +end +local function readdata(f,offset,specification) + local fontdata,tables=loadtables(f,specification,offset) + if specification.glyphs then + prepareglyps(fontdata) + end + fontdata.temporary={} + readtable("name",f,fontdata,specification) + local askedname=specification.askedname + if askedname then + local fullname=getname(fontdata,"fullname") or "" + local cleanname=gsub(askedname,"[^a-zA-Z0-9]","") + local foundname=gsub(fullname,"[^a-zA-Z0-9]","") + if lower(cleanname)~=lower(foundname) then + return + end + end + readtable("stat",f,fontdata,specification) + readtable("avar",f,fontdata,specification) + readtable("fvar",f,fontdata,specification) + local variabledata=fontdata.variabledata + if variabledata then + local instances=variabledata.instances + local axis=variabledata.axis + if axis and (not instances or #instances==0) then + instances={} + variabledata.instances=instances + local function add(n,subfamily,value) + local values={} + for i=1,#axis do + local a=axis[i] + values[i]={ + axis=a.tag, + value=i==n and value or a.default, + } + end + instances[#instances+1]={ + subfamily=subfamily, + values=values, + } + end + for i=1,#axis do + local a=axis[i] + local tag=a.tag + add(i,"default"..tag,a.default) + add(i,"minimum"..tag,a.minimum) + add(i,"maximum"..tag,a.maximum) + end + end + end + if not specification.factors then + local instance=specification.instance + if type(instance)=="string" then + local factors=helpers.getfactors(fontdata,instance) + if factors then + specification.factors=factors + fontdata.factors=factors + fontdata.instance=instance + report("user instance: %s, factors: % t",instance,factors) + else + report("user instance: %s, bad factors",instance) + end + end + end + if not fontdata.factors then + if fontdata.variabledata then + local factors=helpers.getfactors(fontdata,true) + if factors then + specification.factors=factors + fontdata.factors=factors + end + else + end + end + readtable("os/2",f,fontdata,specification) + readtable("head",f,fontdata,specification) + readtable("maxp",f,fontdata,specification) + readtable("hhea",f,fontdata,specification) + readtable("vhea",f,fontdata,specification) + readtable("hmtx",f,fontdata,specification) + readtable("vmtx",f,fontdata,specification) + readtable("vorg",f,fontdata,specification) + readtable("post",f,fontdata,specification) + readtable("mvar",f,fontdata,specification) + readtable("hvar",f,fontdata,specification) + readtable("vvar",f,fontdata,specification) + readtable("gdef",f,fontdata,specification) + readtable("cff",f,fontdata,specification) + readtable("cff2",f,fontdata,specification) + readtable("cmap",f,fontdata,specification) + readtable("loca",f,fontdata,specification) + readtable("glyf",f,fontdata,specification) + readtable("colr",f,fontdata,specification) + readtable("cpal",f,fontdata,specification) + readtable("svg",f,fontdata,specification) + readtable("sbix",f,fontdata,specification) + readtable("cbdt",f,fontdata,specification) + readtable("cblc",f,fontdata,specification) + readtable("ebdt",f,fontdata,specification) + readtable("eblc",f,fontdata,specification) + readtable("kern",f,fontdata,specification) + readtable("gsub",f,fontdata,specification) + readtable("gpos",f,fontdata,specification) + readtable("math",f,fontdata,specification) + fontdata.locations=nil + fontdata.cidmaps=nil + fontdata.dictionaries=nil + if specification.tableoffsets then + fontdata.tableoffsets=tables + setmetatableindex(tables,{ + version=fontdata.version, + noftables=fontdata.noftables, + searchrange=fontdata.searchrange, + entryselector=fontdata.entryselector, + rangeshift=fontdata.rangeshift, + }) + end + return fontdata +end +local function loadfontdata(specification) + local filename=specification.filename + local fileattr=lfs.attributes(filename) + local filesize=fileattr and fileattr.size or 0 + local filetime=fileattr and fileattr.modification or 0 + local f=openfile(filename,true) + if not f then + report("unable to open %a",filename) + elseif filesize==0 then + report("empty file %a",filename) + closefile(f) + else + specification.filesize=filesize + specification.filetime=filetime + local version=readstring(f,4) + local fontdata=nil + if version=="OTTO" or version=="true" or version=="\0\1\0\0" then + fontdata=readdata(f,0,specification) + elseif version=="ttcf" then + local subfont=tonumber(specification.subfont) + local ttcversion=readulong(f) + local nofsubfonts=readulong(f) + local offsets=readcardinaltable(f,nofsubfonts,ulong) + if subfont then + if subfont>=1 and subfont<=nofsubfonts then + fontdata=readdata(f,offsets[subfont],specification) + else + report("no subfont %a in file %a",subfont,filename) + end + else + subfont=specification.subfont + if type(subfont)=="string" and subfont~="" then + specification.askedname=subfont + for i=1,nofsubfonts do + fontdata=readdata(f,offsets[i],specification) + if fontdata then + fontdata.subfontindex=i + report("subfont named %a has index %a",subfont,i) + break + end + end + if not fontdata then + report("no subfont named %a",subfont) + end + else + local subfonts={} + fontdata={ + filename=filename, + filesize=filesize, + filetime=filetime, + version=version, + subfonts=subfonts, + ttcversion=ttcversion, + nofsubfonts=nofsubfonts, + } + for i=1,nofsubfonts do + subfonts[i]=readdata(f,offsets[i],specification) + end + end + end + else + report("unknown version %a in file %a",version,filename) + end + closefile(f) + return fontdata or {} + end +end +local function loadfont(specification,n,instance) + if type(specification)=="string" then + specification={ + filename=specification, + info=true, + details=true, + glyphs=true, + shapes=true, + kerns=true, + variable=true, + globalkerns=true, + lookups=true, + subfont=n or true, + tounicode=false, + instance=instance + } + end + if specification.shapes or specification.lookups or specification.kerns then + specification.glyphs=true + end + if specification.glyphs then + specification.details=true + end + if specification.details then + specification.info=true + end + if specification.platformnames then + specification.platformnames=true + end + if specification.instance or instance then + specification.variable=true + specification.instance=specification.instance or instance + end + local function message(str) + report("fatal error in file %a: %s\n%s",specification.filename,str,debug and debug.traceback()) + end + local ok,result=xpcall(loadfontdata,message,specification) + if ok then + return result + end +end +function readers.loadshapes(filename,n,instance,streams) + local fontdata=loadfont { + filename=filename, + shapes=true, + streams=streams, + variable=true, + subfont=n, + instance=instance, + } + if fontdata then + for k,v in next,fontdata.glyphs do + v.class=nil + v.index=nil + v.math=nil + end + local names=fontdata.names + if names then + for k,v in next,names do + names[k]=fullstrip(v.content) + end + end + end + return fontdata and { + filename=filename, + format=fontdata.format, + glyphs=fontdata.glyphs, + units=fontdata.fontheader.units, + cffinfo=fontdata.cffinfo, + fontheader=fontdata.fontheader, + horizontalheader=fontdata.horizontalheader, + verticalheader=fontdata.verticalheader, + maximumprofile=fontdata.maximumprofile, + names=fontdata.names, + postscript=fontdata.postscript, + } or { + filename=filename, + format="unknown", + glyphs={}, + units=0, + } +end +function readers.loadfont(filename,n,instance) + local fontdata=loadfont { + filename=filename, + glyphs=true, + shapes=false, + lookups=true, + variable=true, + subfont=n, + instance=instance, + } + if fontdata then + return { + tableversion=tableversion, + creator="context mkiv", + size=fontdata.filesize, + time=fontdata.filetime, + glyphs=fontdata.glyphs, + descriptions=fontdata.descriptions, + format=fontdata.format, + goodies={}, + metadata=getinfo(fontdata,n,false,false,true,true), + properties={ + hasitalics=fontdata.hasitalics or false, + maxcolorclass=fontdata.maxcolorclass, + hascolor=fontdata.hascolor or false, + instance=fontdata.instance, + factors=fontdata.factors, + nofsubfonts=fontdata.subfonts and #fontdata.subfonts or nil, + }, + resources={ + filename=filename, + private=privateoffset, + duplicates=fontdata.duplicates or {}, + features=fontdata.features or {}, + sublookups=fontdata.sublookups or {}, + marks=fontdata.marks or {}, + markclasses=fontdata.markclasses or {}, + marksets=fontdata.marksets or {}, + sequences=fontdata.sequences or {}, + variants=fontdata.variants, + version=getname(fontdata,"version"), + cidinfo=fontdata.cidinfo, + mathconstants=fontdata.mathconstants, + colorpalettes=fontdata.colorpalettes, + svgshapes=fontdata.svgshapes, + pngshapes=fontdata.pngshapes, + variabledata=fontdata.variabledata, + foundtables=fontdata.foundtables, + }, + } + end +end +function readers.getinfo(filename,specification) + local subfont=nil + local platformnames=false + local rawfamilynames=false + local instancenames=true + local tableoffsets=false + if type(specification)=="table" then + subfont=tonumber(specification.subfont) + platformnames=specification.platformnames + rawfamilynames=specification.rawfamilynames + tableoffsets=specification.tableoffsets + else + subfont=tonumber(specification) + end + local fontdata=loadfont { + filename=filename, + details=true, + platformnames=platformnames, + instancenames=true, + tableoffsets=tableoffsets, + } + if fontdata then + local subfonts=fontdata.subfonts + if not subfonts then + return getinfo(fontdata,nil,platformnames,rawfamilynames,false,instancenames) + elseif not subfont then + local info={} + for i=1,#subfonts do + info[i]=getinfo(fontdata,i,platformnames,rawfamilynames,false,instancenames) + end + return info + elseif subfont>=1 and subfont<=#subfonts then + return getinfo(fontdata,subfont,platformnames,rawfamilynames,false,instancenames) + else + return { + filename=filename, + comment="there is no subfont "..subfont.." in this file" + } + end + else + return { + filename=filename, + comment="the file cannot be opened for reading", + } + end +end +function readers.rehash(fontdata,hashmethod) + report("the %a helper is not yet implemented","rehash") +end +function readers.checkhash(fontdata) + report("the %a helper is not yet implemented","checkhash") +end +function readers.pack(fontdata,hashmethod) + report("the %a helper is not yet implemented","pack") +end +function readers.unpack(fontdata) + report("the %a helper is not yet implemented","unpack") +end +function readers.expand(fontdata) + report("the %a helper is not yet implemented","unpack") +end +function readers.compact(fontdata) + report("the %a helper is not yet implemented","compact") +end +local extenders={} +function readers.registerextender(extender) + extenders[#extenders+1]=extender +end +function readers.extend(fontdata) + for i=1,#extenders do + local extender=extenders[i] + local name=extender.name or "unknown" + local action=extender.action + if action then + action(fontdata) + end + end +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-otr”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-oti” 309a75f9c14b77d87e94eba827dc4e71] --- + +if not modules then modules={} end modules ['font-oti']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local lower=string.lower +local fonts=fonts +local constructors=fonts.constructors +local otf=constructors.handlers.otf +local otffeatures=constructors.features.otf +local registerotffeature=otffeatures.register +local otftables=otf.tables or {} +otf.tables=otftables +local allocate=utilities.storage.allocate +registerotffeature { + name="features", + description="initialization of feature handler", + default=true, +} +local function setmode(tfmdata,value) + if value then + tfmdata.properties.mode=lower(value) + end +end +otf.modeinitializer=setmode +local function setlanguage(tfmdata,value) + if value then + local cleanvalue=lower(value) + local languages=otftables and otftables.languages + local properties=tfmdata.properties + if not languages then + properties.language=cleanvalue + elseif languages[value] then + properties.language=cleanvalue + else + properties.language="dflt" + end + end +end +local function setscript(tfmdata,value) + if value then + local cleanvalue=lower(value) + local scripts=otftables and otftables.scripts + local properties=tfmdata.properties + if not scripts then + properties.script=cleanvalue + elseif scripts[value] then + properties.script=cleanvalue + else + properties.script="dflt" + end + end +end +registerotffeature { + name="mode", + description="mode", + initializers={ + base=setmode, + node=setmode, + plug=setmode, + } +} +registerotffeature { + name="language", + description="language", + initializers={ + base=setlanguage, + node=setlanguage, + plug=setlanguage, + } +} +registerotffeature { + name="script", + description="script", + initializers={ + base=setscript, + node=setscript, + plug=setscript, + } +} +otftables.featuretypes=allocate { + gpos_single="position", + gpos_pair="position", + gpos_cursive="position", + gpos_mark2base="position", + gpos_mark2ligature="position", + gpos_mark2mark="position", + gpos_context="position", + gpos_contextchain="position", + gsub_single="substitution", + gsub_multiple="substitution", + gsub_alternate="substitution", + gsub_ligature="substitution", + gsub_context="substitution", + gsub_contextchain="substitution", + gsub_reversecontextchain="substitution", + gsub_reversesub="substitution", +} +function otffeatures.checkeddefaultscript(featuretype,autoscript,scripts) + if featuretype=="position" then + local default=scripts.dflt + if default then + if autoscript=="position" or autoscript==true then + return default + else + report_otf("script feature %s not applied, enable default positioning") + end + else + end + elseif featuretype=="substitution" then + local default=scripts.dflt + if default then + if autoscript=="substitution" or autoscript==true then + return default + end + end + end +end +function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages) + if featuretype=="position" then + local default=languages.dflt + if default then + if autolanguage=="position" or autolanguage==true then + return default + else + report_otf("language feature %s not applied, enable default positioning") + end + else + end + elseif featuretype=="substitution" then + local default=languages.dflt + if default then + if autolanguage=="substitution" or autolanguage==true then + return default + end + end + end +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-oti”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-ott” 673ed11e1d159997f535bfec5fa73808] --- + +if not modules then modules={} end modules ["font-ott"]={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files", +} +local type,next,tonumber,tostring,rawget,rawset=type,next,tonumber,tostring,rawget,rawset +local gsub,lower,format,match,gmatch,find=string.gsub,string.lower,string.format,string.match,string.gmatch,string.find +local sequenced=table.sequenced +local is_boolean=string.is_boolean +local setmetatableindex=table.setmetatableindex +local setmetatablenewindex=table.setmetatablenewindex +local allocate=utilities.storage.allocate +local fonts=fonts +local otf=fonts.handlers.otf +local otffeatures=otf.features +local tables=otf.tables or {} +otf.tables=tables +local statistics=otf.statistics or {} +otf.statistics=statistics +local scripts=allocate { + ["adlm"]="adlam", + ["aghb"]="caucasian albanian", + ["ahom"]="ahom", + ["arab"]="arabic", + ["armi"]="imperial aramaic", + ["armn"]="armenian", + ["avst"]="avestan", + ["bali"]="balinese", + ["bamu"]="bamum", + ["bass"]="bassa vah", + ["batk"]="batak", + ["beng"]="bengali", + ["bhks"]="bhaiksuki", + ["bng2"]="bengali variant 2", + ["bopo"]="bopomofo", + ["brah"]="brahmi", + ["brai"]="braille", + ["bugi"]="buginese", + ["buhd"]="buhid", + ["byzm"]="byzantine music", + ["cakm"]="chakma", + ["cans"]="canadian syllabics", + ["cari"]="carian", + ["cham"]="cham", + ["cher"]="cherokee", + ["copt"]="coptic", + ["cprt"]="cypriot syllabary", + ["cyrl"]="cyrillic", + ["dev2"]="devanagari variant 2", + ["deva"]="devanagari", + ["dogr"]="dogra", + ["dsrt"]="deseret", + ["dupl"]="duployan", + ["egyp"]="egyptian heiroglyphs", + ["elba"]="elbasan", + ["ethi"]="ethiopic", + ["geor"]="georgian", + ["gjr2"]="gujarati variant 2", + ["glag"]="glagolitic", + ["gong"]="gunjala gondi", + ["gonm"]="masaram gondi", + ["goth"]="gothic", + ["gran"]="grantha", + ["grek"]="greek", + ["gujr"]="gujarati", + ["gur2"]="gurmukhi variant 2", + ["guru"]="gurmukhi", + ["hang"]="hangul", + ["hani"]="cjk ideographic", + ["hano"]="hanunoo", + ["hatr"]="hatran", + ["hebr"]="hebrew", + ["hluw"]="anatolian hieroglyphs", + ["hmng"]="pahawh hmong", + ["hung"]="old hungarian", + ["ital"]="old italic", + ["jamo"]="hangul jamo", + ["java"]="javanese", + ["kali"]="kayah li", + ["kana"]="hiragana and katakana", + ["khar"]="kharosthi", + ["khmr"]="khmer", + ["khoj"]="khojki", + ["knd2"]="kannada variant 2", + ["knda"]="kannada", + ["kthi"]="kaithi", + ["lana"]="tai tham", + ["lao" ]="lao", + ["latn"]="latin", + ["lepc"]="lepcha", + ["limb"]="limbu", + ["lina"]="linear a", + ["linb"]="linear b", + ["lisu"]="lisu", + ["lyci"]="lycian", + ["lydi"]="lydian", + ["mahj"]="mahajani", + ["maka"]="makasar", + ["mand"]="mandaic and mandaean", + ["mani"]="manichaean", + ["marc"]="marchen", + ["math"]="mathematical alphanumeric symbols", + ["medf"]="medefaidrin", + ["mend"]="mende kikakui", + ["merc"]="meroitic cursive", + ["mero"]="meroitic hieroglyphs", + ["mlm2"]="malayalam variant 2", + ["mlym"]="malayalam", + ["modi"]="modi", + ["mong"]="mongolian", + ["mroo"]="mro", + ["mtei"]="meitei Mayek", + ["mult"]="multani", + ["musc"]="musical symbols", + ["mym2"]="myanmar variant 2", + ["mymr"]="myanmar", + ["narb"]="old north arabian", + ["nbat"]="nabataean", + ["newa"]="newa", + ["nko" ]='n"ko', + ["nshu"]="nüshu", + ["ogam"]="ogham", + ["olck"]="ol chiki", + ["orkh"]="old turkic and orkhon runic", + ["ory2"]="odia variant 2", + ["orya"]="oriya", + ["osge"]="osage", + ["osma"]="osmanya", + ["palm"]="palmyrene", + ["pauc"]="pau cin hau", + ["perm"]="old permic", + ["phag"]="phags-pa", + ["phli"]="inscriptional pahlavi", + ["phlp"]="psalter pahlavi", + ["phnx"]="phoenician", + ["plrd"]="miao", + ["prti"]="inscriptional parthian", + ["rjng"]="rejang", + ["rohg"]="hanifi rohingya", + ["runr"]="runic", + ["samr"]="samaritan", + ["sarb"]="old south arabian", + ["saur"]="saurashtra", + ["sgnw"]="sign writing", + ["shaw"]="shavian", + ["shrd"]="sharada", + ["sidd"]="siddham", + ["sind"]="khudawadi", + ["sinh"]="sinhala", + ["sogd"]="sogdian", + ["sogo"]="old sogdian", + ["sora"]="sora sompeng", + ["soyo"]="soyombo", + ["sund"]="sundanese", + ["sylo"]="syloti nagri", + ["syrc"]="syriac", + ["tagb"]="tagbanwa", + ["takr"]="takri", + ["tale"]="tai le", + ["talu"]="tai lu", + ["taml"]="tamil", + ["tang"]="tangut", + ["tavt"]="tai viet", + ["tel2"]="telugu variant 2", + ["telu"]="telugu", + ["tfng"]="tifinagh", + ["tglg"]="tagalog", + ["thaa"]="thaana", + ["thai"]="thai", + ["tibt"]="tibetan", + ["tirh"]="tirhuta", + ["tml2"]="tamil variant 2", + ["ugar"]="ugaritic cuneiform", + ["vai" ]="vai", + ["wara"]="warang citi", + ["xpeo"]="old persian cuneiform", + ["xsux"]="sumero-akkadian cuneiform", + ["yi" ]="yi", + ["zanb"]="zanabazar square", +} +local languages=allocate { + ["aba" ]="abaza", + ["abk" ]="abkhazian", + ["ach" ]="acholi", + ["acr" ]="achi", + ["ady" ]="adyghe", + ["afk" ]="afrikaans", + ["afr" ]="afar", + ["agw" ]="agaw", + ["aio" ]="aiton", + ["aka" ]="akan", + ["als" ]="alsatian", + ["alt" ]="altai", + ["amh" ]="amharic", + ["ang" ]="anglo-saxon", + ["apph"]="phonetic transcription—americanist conventions", + ["ara" ]="arabic", + ["arg" ]="aragonese", + ["ari" ]="aari", + ["ark" ]="rakhine", + ["asm" ]="assamese", + ["ast" ]="asturian", + ["ath" ]="athapaskan", + ["avr" ]="avar", + ["awa" ]="awadhi", + ["aym" ]="aymara", + ["azb" ]="torki", + ["aze" ]="azerbaijani", + ["bad" ]="badaga", + ["bad0"]="banda", + ["bag" ]="baghelkhandi", + ["bal" ]="balkar", + ["ban" ]="balinese", + ["bar" ]="bavarian", + ["bau" ]="baulé", + ["bbc" ]="batak toba", + ["bbr" ]="berber", + ["bch" ]="bench", + ["bcr" ]="bible cree", + ["bdy" ]="bandjalang", + ["bel" ]="belarussian", + ["bem" ]="bemba", + ["ben" ]="bengali", + ["bgc" ]="haryanvi", + ["bgq" ]="bagri", + ["bgr" ]="bulgarian", + ["bhi" ]="bhili", + ["bho" ]="bhojpuri", + ["bik" ]="bikol", + ["bil" ]="bilen", + ["bis" ]="bislama", + ["bjj" ]="kanauji", + ["bkf" ]="blackfoot", + ["bli" ]="baluchi", + ["blk" ]="pa'o karen", + ["bln" ]="balante", + ["blt" ]="balti", + ["bmb" ]="bambara (bamanankan)", + ["bml" ]="bamileke", + ["bos" ]="bosnian", + ["bpy" ]="bishnupriya manipuri", + ["bre" ]="breton", + ["brh" ]="brahui", + ["bri" ]="braj bhasha", + ["brm" ]="burmese", + ["brx" ]="bodo", + ["bsh" ]="bashkir", + ["bsk" ]="burushaski", + ["bti" ]="beti", + ["bts" ]="batak simalungun", + ["bug" ]="bugis", + ["byv" ]="medumba", + ["cak" ]="kaqchikel", + ["cat" ]="catalan", + ["cbk" ]="zamboanga chavacano", + ["cchn"]="chinantec", + ["ceb" ]="cebuano", + ["cgg" ]="chiga", + ["cha" ]="chamorro", + ["che" ]="chechen", + ["chg" ]="chaha gurage", + ["chh" ]="chattisgarhi", + ["chi" ]="chichewa (chewa, nyanja)", + ["chk" ]="chukchi", + ["chk0"]="chuukese", + ["cho" ]="choctaw", + ["chp" ]="chipewyan", + ["chr" ]="cherokee", + ["chu" ]="chuvash", + ["chy" ]="cheyenne", + ["cja" ]="western cham", + ["cjm" ]="eastern cham", + ["cmr" ]="comorian", + ["cop" ]="coptic", + ["cor" ]="cornish", + ["cos" ]="corsican", + ["cpp" ]="creoles", + ["cre" ]="cree", + ["crr" ]="carrier", + ["crt" ]="crimean tatar", + ["csb" ]="kashubian", + ["csl" ]="church slavonic", + ["csy" ]="czech", + ["ctg" ]="chittagonian", + ["cuk" ]="san blas kuna", + ["dan" ]="danish", + ["dar" ]="dargwa", + ["dax" ]="dayi", + ["dcr" ]="woods cree", + ["deu" ]="german", + ["dgo" ]="dogri", + ["dgr" ]="dogri", + ["dhg" ]="dhangu", + ["dhv" ]="divehi (dhivehi, maldivian)", + ["diq" ]="dimli", + ["div" ]="divehi (dhivehi, maldivian)", + ["djr" ]="zarma", + ["djr0"]="djambarrpuyngu", + ["dng" ]="dangme", + ["dnj" ]="dan", + ["dnk" ]="dinka", + ["dri" ]="dari", + ["duj" ]="dhuwal", + ["dun" ]="dungan", + ["dzn" ]="dzongkha", + ["ebi" ]="ebira", + ["ecr" ]="eastern cree", + ["edo" ]="edo", + ["efi" ]="efik", + ["ell" ]="greek", + ["emk" ]="eastern maninkakan", + ["eng" ]="english", + ["erz" ]="erzya", + ["esp" ]="spanish", + ["esu" ]="central yupik", + ["eti" ]="estonian", + ["euq" ]="basque", + ["evk" ]="evenki", + ["evn" ]="even", + ["ewe" ]="ewe", + ["fan" ]="french antillean", + ["fan0"]=" fang", + ["far" ]="persian", + ["fat" ]="fanti", + ["fin" ]="finnish", + ["fji" ]="fijian", + ["fle" ]="dutch (flemish)", + ["fmp" ]="fe’fe’", + ["fne" ]="forest nenets", + ["fon" ]="fon", + ["fos" ]="faroese", + ["fra" ]="french", + ["frc" ]="cajun french", + ["fri" ]="frisian", + ["frl" ]="friulian", + ["frp" ]="arpitan", + ["fta" ]="futa", + ["ful" ]="fulah", + ["fuv" ]="nigerian fulfulde", + ["gad" ]="ga", + ["gae" ]="scottish gaelic (gaelic)", + ["gag" ]="gagauz", + ["gal" ]="galician", + ["gar" ]="garshuni", + ["gaw" ]="garhwali", + ["gez" ]="ge'ez", + ["gih" ]="githabul", + ["gil" ]="gilyak", + ["gil0"]="kiribati (gilbertese)", + ["gkp" ]="kpelle (guinea)", + ["glk" ]="gilaki", + ["gmz" ]="gumuz", + ["gnn" ]="gumatj", + ["gog" ]="gogo", + ["gon" ]="gondi", + ["grn" ]="greenlandic", + ["gro" ]="garo", + ["gua" ]="guarani", + ["guc" ]="wayuu", + ["guf" ]="gupapuyngu", + ["guj" ]="gujarati", + ["guz" ]="gusii", + ["hai" ]="haitian (haitian creole)", + ["hal" ]="halam", + ["har" ]="harauti", + ["hau" ]="hausa", + ["haw" ]="hawaiian", + ["hay" ]="haya", + ["haz" ]="hazaragi", + ["hbn" ]="hammer-banna", + ["her" ]="herero", + ["hil" ]="hiligaynon", + ["hin" ]="hindi", + ["hma" ]="high mari", + ["hmn" ]="hmong", + ["hmo" ]="hiri motu", + ["hnd" ]="hindko", + ["ho" ]="ho", + ["hri" ]="harari", + ["hrv" ]="croatian", + ["hun" ]="hungarian", + ["hye" ]="armenian", + ["hye0"]="armenian east", + ["iba" ]="iban", + ["ibb" ]="ibibio", + ["ibo" ]="igbo", + ["ido" ]="ido", + ["ijo" ]="ijo languages", + ["ile" ]="interlingue", + ["ilo" ]="ilokano", + ["ina" ]="interlingua", + ["ind" ]="indonesian", + ["ing" ]="ingush", + ["inu" ]="inuktitut", + ["ipk" ]="inupiat", + ["ipph"]="phonetic transcription—ipa conventions", + ["iri" ]="irish", + ["irt" ]="irish traditional", + ["isl" ]="icelandic", + ["ism" ]="inari sami", + ["ita" ]="italian", + ["iwr" ]="hebrew", + ["jam" ]="jamaican creole", + ["jan" ]="japanese", + ["jav" ]="javanese", + ["jbo" ]="lojban", + ["jct" ]="krymchak", + ["jii" ]="yiddish", + ["jud" ]="ladino", + ["jul" ]="jula", + ["kab" ]="kabardian", + ["kab0"]="kabyle", + ["kac" ]="kachchi", + ["kal" ]="kalenjin", + ["kan" ]="kannada", + ["kar" ]="karachay", + ["kat" ]="georgian", + ["kaz" ]="kazakh", + ["kde" ]="makonde", + ["kea" ]="kabuverdianu (crioulo)", + ["keb" ]="kebena", + ["kek" ]="kekchi", + ["kge" ]="khutsuri georgian", + ["kha" ]="khakass", + ["khk" ]="khanty-kazim", + ["khm" ]="khmer", + ["khs" ]="khanty-shurishkar", + ["kht" ]="khamti shan", + ["khv" ]="khanty-vakhi", + ["khw" ]="khowar", + ["kik" ]="kikuyu (gikuyu)", + ["kir" ]="kirghiz (kyrgyz)", + ["kis" ]="kisii", + ["kiu" ]="kirmanjki", + ["kjd" ]="southern kiwai", + ["kjp" ]="eastern pwo karen", + ["kjz" ]="bumthangkha", + ["kkn" ]="kokni", + ["klm" ]="kalmyk", + ["kmb" ]="kamba", + ["kmn" ]="kumaoni", + ["kmo" ]="komo", + ["kms" ]="komso", + ["kmz" ]="khorasani turkic", + ["knr" ]="kanuri", + ["kod" ]="kodagu", + ["koh" ]="korean old hangul", + ["kok" ]="konkani", + ["kom" ]="komi", + ["kon" ]="kikongo", + ["kon0"]="kongo", + ["kop" ]="komi-permyak", + ["kor" ]="korean", + ["kos" ]="kosraean", + ["koz" ]="komi-zyrian", + ["kpl" ]="kpelle", + ["kri" ]="krio", + ["krk" ]="karakalpak", + ["krl" ]="karelian", + ["krm" ]="karaim", + ["krn" ]="karen", + ["krt" ]="koorete", + ["ksh" ]="kashmiri", + ["ksh0"]="ripuarian", + ["ksi" ]="khasi", + ["ksm" ]="kildin sami", + ["ksw" ]="s’gaw karen", + ["kua" ]="kuanyama", + ["kui" ]="kui", + ["kul" ]="kulvi", + ["kum" ]="kumyk", + ["kur" ]="kurdish", + ["kuu" ]="kurukh", + ["kuy" ]="kuy", + ["kyk" ]="koryak", + ["kyu" ]="western kayah", + ["lad" ]="ladin", + ["lah" ]="lahuli", + ["lak" ]="lak", + ["lam" ]="lambani", + ["lao" ]="lao", + ["lat" ]="latin", + ["laz" ]="laz", + ["lcr" ]="l-cree", + ["ldk" ]="ladakhi", + ["lez" ]="lezgi", + ["lij" ]="ligurian", + ["lim" ]="limburgish", + ["lin" ]="lingala", + ["lis" ]="lisu", + ["ljp" ]="lampung", + ["lki" ]="laki", + ["lma" ]="low mari", + ["lmb" ]="limbu", + ["lmo" ]="lombard", + ["lmw" ]="lomwe", + ["lom" ]="loma", + ["lrc" ]="luri", + ["lsb" ]="lower sorbian", + ["lsm" ]="lule sami", + ["lth" ]="lithuanian", + ["ltz" ]="luxembourgish", + ["lua" ]="luba-lulua", + ["lub" ]="luba-katanga", + ["lug" ]="ganda", + ["luh" ]="luyia", + ["luo" ]="luo", + ["lvi" ]="latvian", + ["mad" ]="madura", + ["mag" ]="magahi", + ["mah" ]="marshallese", + ["maj" ]="majang", + ["mak" ]="makhuwa", + ["mal" ]="malayalam reformed", + ["mam" ]="mam", + ["man" ]="mansi", + ["map" ]="mapudungun", + ["mar" ]="marathi", + ["maw" ]="marwari", + ["mbn" ]="mbundu", + ["mbo" ]="mbo", + ["mch" ]="manchu", + ["mcr" ]="moose cree", + ["mde" ]="mende", + ["mdr" ]="mandar", + ["men" ]="me'en", + ["mer" ]="meru", + ["mfa" ]="pattani malay", + ["mfe" ]="morisyen", + ["min" ]="minangkabau", + ["miz" ]="mizo", + ["mkd" ]="macedonian", + ["mkr" ]="makasar", + ["mkw" ]="kituba", + ["mle" ]="male", + ["mlg" ]="malagasy", + ["mln" ]="malinke", + ["mlr" ]="malayalam reformed", + ["mly" ]="malay", + ["mnd" ]="mandinka", + ["mng" ]="mongolian", + ["mni" ]="manipuri", + ["mnk" ]="maninka", + ["mnx" ]="manx", + ["moh" ]="mohawk", + ["mok" ]="moksha", + ["mol" ]="moldavian", + ["mon" ]="mon", + ["mor" ]="moroccan", + ["mos" ]="mossi", + ["mri" ]="maori", + ["mth" ]="maithili", + ["mts" ]="maltese", + ["mun" ]="mundari", + ["mus" ]="muscogee", + ["mwl" ]="mirandese", + ["mww" ]="hmong daw", + ["myn" ]="mayan", + ["mzn" ]="mazanderani", + ["nag" ]="naga-assamese", + ["nah" ]="nahuatl", + ["nan" ]="nanai", + ["nap" ]="neapolitan", + ["nas" ]="naskapi", + ["nau" ]="nauruan", + ["nav" ]="navajo", + ["ncr" ]="n-cree", + ["ndb" ]="ndebele", + ["ndc" ]="ndau", + ["ndg" ]="ndonga", + ["nds" ]="low saxon", + ["nep" ]="nepali", + ["new" ]="newari", + ["nga" ]="ngbaka", + ["ngr" ]="nagari", + ["nhc" ]="norway house cree", + ["nis" ]="nisi", + ["niu" ]="niuean", + ["nkl" ]="nyankole", + ["nko" ]="n'ko", + ["nld" ]="dutch", + ["noe" ]="nimadi", + ["nog" ]="nogai", + ["nor" ]="norwegian", + ["nov" ]="novial", + ["nsm" ]="northern sami", + ["nso" ]="sotho, northern", + ["nta" ]="northern tai", + ["nto" ]="esperanto", + ["nym" ]="nyamwezi", + ["nyn" ]="norwegian nynorsk", + ["nza" ]="mbembe tigon", + ["oci" ]="occitan", + ["ocr" ]="oji-cree", + ["ojb" ]="ojibway", + ["ori" ]="odia", + ["oro" ]="oromo", + ["oss" ]="ossetian", + ["paa" ]="palestinian aramaic", + ["pag" ]="pangasinan", + ["pal" ]="pali", + ["pam" ]="pampangan", + ["pan" ]="punjabi", + ["pap" ]="palpa", + ["pap0"]="papiamentu", + ["pas" ]="pashto", + ["pau" ]="palauan", + ["pcc" ]="bouyei", + ["pcd" ]="picard", + ["pdc" ]="pennsylvania german", + ["pgr" ]="polytonic greek", + ["phk" ]="phake", + ["pih" ]="norfolk", + ["pil" ]="filipino", + ["plg" ]="palaung", + ["plk" ]="polish", + ["pms" ]="piemontese", + ["pnb" ]="western panjabi", + ["poh" ]="pocomchi", + ["pon" ]="pohnpeian", + ["pro" ]="provencal", + ["ptg" ]="portuguese", + ["pwo" ]="western pwo karen", + ["qin" ]="chin", + ["quc" ]="k’iche’", + ["quh" ]="quechua (bolivia)", + ["quz" ]="quechua", + ["qvi" ]="quechua (ecuador)", + ["qwh" ]="quechua (peru)", + ["raj" ]="rajasthani", + ["rar" ]="rarotongan", + ["rbu" ]="russian buriat", + ["rcr" ]="r-cree", + ["rej" ]="rejang", + ["ria" ]="riang", + ["rif" ]="tarifit", + ["rit" ]="ritarungo", + ["rkw" ]="arakwal", + ["rms" ]="romansh", + ["rmy" ]="vlax romani", + ["rom" ]="romanian", + ["roy" ]="romany", + ["rsy" ]="rusyn", + ["rtm" ]="rotuman", + ["rua" ]="kinyarwanda", + ["run" ]="rundi", + ["rup" ]="aromanian", + ["rus" ]="russian", + ["sad" ]="sadri", + ["san" ]="sanskrit", + ["sas" ]="sasak", + ["sat" ]="santali", + ["say" ]="sayisi", + ["scn" ]="sicilian", + ["sco" ]="scots", + ["scs" ]="north slavey", + ["sek" ]="sekota", + ["sel" ]="selkup", + ["sga" ]="old irish", + ["sgo" ]="sango", + ["sgs" ]="samogitian", + ["shi" ]="tachelhit", + ["shn" ]="shan", + ["sib" ]="sibe", + ["sid" ]="sidamo", + ["sig" ]="silte gurage", + ["sks" ]="skolt sami", + ["sky" ]="slovak", + ["sla" ]="slavey", + ["slv" ]="slovenian", + ["sml" ]="somali", + ["smo" ]="samoan", + ["sna" ]="sena", + ["sna0"]="shona", + ["snd" ]="sindhi", + ["snh" ]="sinhala (sinhalese)", + ["snk" ]="soninke", + ["sog" ]="sodo gurage", + ["sop" ]="songe", + ["sot" ]="sotho, southern", + ["sqi" ]="albanian", + ["srb" ]="serbian", + ["srd" ]="sardinian", + ["srk" ]="saraiki", + ["srr" ]="serer", + ["ssl" ]="south slavey", + ["ssm" ]="southern sami", + ["stq" ]="saterland frisian", + ["suk" ]="sukuma", + ["sun" ]="sundanese", + ["sur" ]="suri", + ["sva" ]="svan", + ["sve" ]="swedish", + ["swa" ]="swadaya aramaic", + ["swk" ]="swahili", + ["swz" ]="swati", + ["sxt" ]="sutu", + ["sxu" ]="upper saxon", + ["syl" ]="sylheti", + ["syr" ]="syriac", + ["syre"]="estrangela syriac", + ["syrj"]="western syriac", + ["syrn"]="eastern syriac", + ["szl" ]="silesian", + ["tab" ]="tabasaran", + ["taj" ]="tajiki", + ["tam" ]="tamil", + ["tat" ]="tatar", + ["tcr" ]="th-cree", + ["tdd" ]="dehong dai", + ["tel" ]="telugu", + ["tet" ]="tetum", + ["tgl" ]="tagalog", + ["tgn" ]="tongan", + ["tgr" ]="tigre", + ["tgy" ]="tigrinya", + ["tha" ]="thai", + ["tht" ]="tahitian", + ["tib" ]="tibetan", + ["tiv" ]="tiv", + ["tkm" ]="turkmen", + ["tmh" ]="tamashek", + ["tmn" ]="temne", + ["tna" ]="tswana", + ["tne" ]="tundra nenets", + ["tng" ]="tonga", + ["tod" ]="todo", + ["tod0"]="toma", + ["tpi" ]="tok pisin", + ["trk" ]="turkish", + ["tsg" ]="tsonga", + ["tsj" ]="tshangla", + ["tua" ]="turoyo aramaic", + ["tul" ]="tulu", + ["tum" ]="tulu", + ["tuv" ]="tuvin", + ["tvl" ]="tuvalu", + ["twi" ]="twi", + ["tyz" ]="tày", + ["tzm" ]="tamazight", + ["tzo" ]="tzotzil", + ["udm" ]="udmurt", + ["ukr" ]="ukrainian", + ["umb" ]="umbundu", + ["urd" ]="urdu", + ["usb" ]="upper sorbian", + ["uyg" ]="uyghur", + ["uzb" ]="uzbek", + ["vec" ]="venetian", + ["ven" ]="venda", + ["vit" ]="vietnamese", + ["vol" ]="volapük", + ["vro" ]="võro", + ["wa" ]="wa", + ["wag" ]="wagdi", + ["war" ]="waray-waray", + ["wcr" ]="west-cree", + ["wel" ]="welsh", + ["wlf" ]="wolof", + ["wln" ]="walloon", + ["wtm" ]="mewati", + ["xbd" ]="lü", + ["xhs" ]="xhosa", + ["xjb" ]="minjangbal", + ["xkf" ]="khengkha", + ["xog" ]="soga", + ["xpe" ]="kpelle (liberia)", + ["yak" ]="sakha", + ["yao" ]="yao", + ["yap" ]="yapese", + ["yba" ]="yoruba", + ["ycr" ]="y-cree", + ["yic" ]="yi classic", + ["yim" ]="yi modern", + ["zea" ]="zealandic", + ["zgh" ]="standard morrocan tamazigh", + ["zha" ]="zhuang", + ["zhh" ]="chinese, hong kong sar", + ["zhp" ]="chinese phonetic", + ["zhs" ]="chinese simplified", + ["zht" ]="chinese traditional", + ["znd" ]="zande", + ["zul" ]="zulu", + ["zza" ]="zazaki", +} +local features=allocate { + ["aalt"]="access all alternates", + ["abvf"]="above-base forms", + ["abvm"]="above-base mark positioning", + ["abvs"]="above-base substitutions", + ["afrc"]="alternative fractions", + ["akhn"]="akhands", + ["blwf"]="below-base forms", + ["blwm"]="below-base mark positioning", + ["blws"]="below-base substitutions", + ["c2pc"]="petite capitals from capitals", + ["c2sc"]="small capitals from capitals", + ["calt"]="contextual alternates", + ["case"]="case-sensitive forms", + ["ccmp"]="glyph composition/decomposition", + ["cfar"]="conjunct form after ro", + ["cjct"]="conjunct forms", + ["clig"]="contextual ligatures", + ["cpct"]="centered cjk punctuation", + ["cpsp"]="capital spacing", + ["cswh"]="contextual swash", + ["curs"]="cursive positioning", + ["dflt"]="default processing", + ["dist"]="distances", + ["dlig"]="discretionary ligatures", + ["dnom"]="denominators", + ["dtls"]="dotless forms", + ["expt"]="expert forms", + ["falt"]="final glyph alternates", + ["fin2"]="terminal forms #2", + ["fin3"]="terminal forms #3", + ["fina"]="terminal forms", + ["flac"]="flattened accents over capitals", + ["frac"]="fractions", + ["fwid"]="full width", + ["half"]="half forms", + ["haln"]="halant forms", + ["halt"]="alternate half width", + ["hist"]="historical forms", + ["hkna"]="horizontal kana alternates", + ["hlig"]="historical ligatures", + ["hngl"]="hangul", + ["hojo"]="hojo kanji forms", + ["hwid"]="half width", + ["init"]="initial forms", + ["isol"]="isolated forms", + ["ital"]="italics", + ["jalt"]="justification alternatives", + ["jp04"]="jis2004 forms", + ["jp78"]="jis78 forms", + ["jp83"]="jis83 forms", + ["jp90"]="jis90 forms", + ["kern"]="kerning", + ["lfbd"]="left bounds", + ["liga"]="standard ligatures", + ["ljmo"]="leading jamo forms", + ["lnum"]="lining figures", + ["locl"]="localized forms", + ["ltra"]="left-to-right alternates", + ["ltrm"]="left-to-right mirrored forms", + ["mark"]="mark positioning", + ["med2"]="medial forms #2", + ["medi"]="medial forms", + ["mgrk"]="mathematical greek", + ["mkmk"]="mark to mark positioning", + ["mset"]="mark positioning via substitution", + ["nalt"]="alternate annotation forms", + ["nlck"]="nlc kanji forms", + ["nukt"]="nukta forms", + ["numr"]="numerators", + ["onum"]="old style figures", + ["opbd"]="optical bounds", + ["ordn"]="ordinals", + ["ornm"]="ornaments", + ["palt"]="proportional alternate width", + ["pcap"]="petite capitals", + ["pkna"]="proportional kana", + ["pnum"]="proportional figures", + ["pref"]="pre-base forms", + ["pres"]="pre-base substitutions", + ["pstf"]="post-base forms", + ["psts"]="post-base substitutions", + ["pwid"]="proportional widths", + ["qwid"]="quarter widths", + ["rand"]="randomize", + ["rclt"]="required contextual alternates", + ["rkrf"]="rakar forms", + ["rlig"]="required ligatures", + ["rphf"]="reph form", + ["rtbd"]="right bounds", + ["rtla"]="right-to-left alternates", + ["rtlm"]="right to left mirrored forms", + ["rvrn"]="required variation alternates", + ["ruby"]="ruby notation forms", + ["salt"]="stylistic alternates", + ["sinf"]="scientific inferiors", + ["size"]="optical size", + ["smcp"]="small capitals", + ["smpl"]="simplified forms", + ["ssty"]="script style", + ["stch"]="stretching glyph decomposition", + ["subs"]="subscript", + ["sups"]="superscript", + ["swsh"]="swash", + ["titl"]="titling", + ["tjmo"]="trailing jamo forms", + ["tnam"]="traditional name forms", + ["tnum"]="tabular figures", + ["trad"]="traditional forms", + ["twid"]="third widths", + ["unic"]="unicase", + ["valt"]="alternate vertical metrics", + ["vatu"]="vattu variants", + ["vert"]="vertical writing", + ["vhal"]="alternate vertical half metrics", + ["vjmo"]="vowel jamo forms", + ["vkna"]="vertical kana alternates", + ["vkrn"]="vertical kerning", + ["vpal"]="proportional alternate vertical metrics", + ["vrtr"]="vertical alternates for rotation", + ["vrt2"]="vertical rotation", + ["zero"]="slashed zero", + ["trep"]="traditional tex replacements", + ["tlig"]="traditional tex ligatures", + ["ss.."]="stylistic set ..", + ["cv.."]="character variant ..", + ["js.."]="justification ..", + ["dv.."]="devanagari ..", + ["ml.."]="malayalam ..", +} +local baselines=allocate { + ["hang"]="hanging baseline", + ["icfb"]="ideographic character face bottom edge baseline", + ["icft"]="ideographic character face tope edige baseline", + ["ideo"]="ideographic em-box bottom edge baseline", + ["idtp"]="ideographic em-box top edge baseline", + ["math"]="mathematical centered baseline", + ["romn"]="roman baseline" +} +tables.scripts=scripts +tables.languages=languages +tables.features=features +tables.baselines=baselines +local acceptscripts=true directives.register("otf.acceptscripts",function(v) acceptscripts=v end) +local acceptlanguages=true directives.register("otf.acceptlanguages",function(v) acceptlanguages=v end) +local report_checks=logs.reporter("fonts","checks") +if otffeatures.features then + for k,v in next,otffeatures.features do + features[k]=v + end + otffeatures.features=features +end +local function swapped(h) + local r={} + for k,v in next,h do + r[gsub(v,"[^a-z0-9]","")]=k + end + return r +end +local verbosescripts=allocate(swapped(scripts )) +local verboselanguages=allocate(swapped(languages)) +local verbosefeatures=allocate(swapped(features )) +local verbosebaselines=allocate(swapped(baselines)) +local function resolve(t,k) + if k then + k=gsub(lower(k),"[^a-z0-9]","") + local v=rawget(t,k) + if v then + return v + end + end +end +setmetatableindex(verbosescripts,resolve) +setmetatableindex(verboselanguages,resolve) +setmetatableindex(verbosefeatures,resolve) +setmetatableindex(verbosebaselines,resolve) +setmetatableindex(scripts,function(t,k) + if k then + k=lower(k) + if k=="dflt" then + return k + end + local v=rawget(t,k) + if v then + return v + end + k=gsub(k," ","") + v=rawget(t,v) + if v then + return v + elseif acceptscripts then + report_checks("registering extra script %a",k) + rawset(t,k,k) + return k + end + end + return "dflt" +end) +setmetatableindex(languages,function(t,k) + if k then + k=lower(k) + if k=="dflt" then + return k + end + local v=rawget(t,k) + if v then + return v + end + k=gsub(k," ","") + v=rawget(t,v) + if v then + return v + elseif acceptlanguages then + report_checks("registering extra language %a",k) + rawset(t,k,k) + return k + end + end + return "dflt" +end) +if setmetatablenewindex then + setmetatablenewindex(languages,"ignore") + setmetatablenewindex(scripts,"ignore") + setmetatablenewindex(baselines,"ignore") +end +local function resolve(t,k) + if k then + k=lower(k) + local v=rawget(t,k) + if v then + return v + end + k=gsub(k," ","") + local v=rawget(t,k) + if v then + return v + end + local tag,dd=match(k,"(..)(%d+)") + if tag and dd then + local v=rawget(t,tag) + if v then + return v + else + local v=rawget(t,tag.."..") + if v then + return (gsub(v,"%.%.",tonumber(dd))) + end + end + end + end + return k +end +setmetatableindex(features,resolve) +local function assign(t,k,v) + if k and v then + v=lower(v) + rawset(t,k,v) + end +end +if setmetatablenewindex then + setmetatablenewindex(features,assign) +end +local checkers={ + rand=function(v) + return v==true and "random" or v + end +} +if not storage then + return +end +local usedfeatures=statistics.usedfeatures or {} +statistics.usedfeatures=usedfeatures +table.setmetatableindex(usedfeatures,function(t,k) if k then local v={} t[k]=v return v end end) +storage.register("fonts/otf/usedfeatures",usedfeatures,"fonts.handlers.otf.statistics.usedfeatures" ) +local normalizedaxis=otf.readers.helpers.normalizedaxis or function(s) return s end +function otffeatures.normalize(features,wrap) + if features then + local h={} + for key,value in next,features do + local k=lower(key) + if k=="language" then + local v=gsub(lower(value),"[^a-z0-9]","") + h.language=rawget(verboselanguages,v) or (languages[v] and v) or "dflt" + elseif k=="script" then + local v=gsub(lower(value),"[^a-z0-9]","") + h.script=rawget(verbosescripts,v) or (scripts[v] and v) or "dflt" + elseif k=="axis" then + h[k]=normalizedaxis(value) + else + local uk=usedfeatures[key] + local uv=uk[value] + if uv then + else + uv=tonumber(value) + if uv then + elseif type(value)=="string" then + local b=is_boolean(value) + if type(b)=="nil" then + if wrap and find(value,",") then + uv="{"..lower(value).."}" + else + uv=lower(value) + end + else + uv=b + end + elseif type(value)=="table" then + uv=sequenced(t,",") + else + uv=value + end + if not rawget(features,k) then + k=rawget(verbosefeatures,k) or k + end + local c=checkers[k] + if c then + uv=c(uv) or vc + end + uk[value]=uv + end + h[k]=uv + end + end + return h + end +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-ott”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-cff” 2b677fad52d9999d0685e8525271a8cc] --- + +if not modules then modules={} end modules ['font-cff']={ + version=1.001, + optimize=true, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next,type,tonumber,rawget=next,type,tonumber,rawget +local byte,char,gmatch,sub=string.byte,string.char,string.gmatch,string.sub +local concat,remove,unpack=table.concat,table.remove,table.unpack +local floor,abs,round,ceil,min,max=math.floor,math.abs,math.round,math.ceil,math.min,math.max +local P,C,R,S,C,Cs,Ct=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Ct +local lpegmatch=lpeg.match +local formatters=string.formatters +local bytetable=string.bytetable +local idiv=number.idiv +local rshift,band,extract=bit32.rshift,bit32.band,bit32.extract +local readers=fonts.handlers.otf.readers +local streamreader=readers.streamreader +local readstring=streamreader.readstring +local readbyte=streamreader.readcardinal1 +local readushort=streamreader.readcardinal2 +local readuint=streamreader.readcardinal3 +local readulong=streamreader.readcardinal4 +local setposition=streamreader.setposition +local getposition=streamreader.getposition +local readbytetable=streamreader.readbytetable +directives.register("fonts.streamreader",function() + streamreader=utilities.streams + readstring=streamreader.readstring + readbyte=streamreader.readcardinal1 + readushort=streamreader.readcardinal2 + readuint=streamreader.readcardinal3 + readulong=streamreader.readcardinal4 + setposition=streamreader.setposition + getposition=streamreader.getposition + readbytetable=streamreader.readbytetable +end) +local setmetatableindex=table.setmetatableindex +local trace_charstrings=false trackers.register("fonts.cff.charstrings",function(v) trace_charstrings=v end) +local report=logs.reporter("otf reader","cff") +local parsedictionaries +local parsecharstring +local parsecharstrings +local resetcharstrings +local parseprivates +local startparsing +local stopparsing +local defaultstrings={ [0]= + ".notdef","space","exclam","quotedbl","numbersign","dollar","percent", + "ampersand","quoteright","parenleft","parenright","asterisk","plus", + "comma","hyphen","period","slash","zero","one","two","three","four", + "five","six","seven","eight","nine","colon","semicolon","less", + "equal","greater","question","at","A","B","C","D","E","F","G","H", + "I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W", + "X","Y","Z","bracketleft","backslash","bracketright","asciicircum", + "underscore","quoteleft","a","b","c","d","e","f","g","h","i","j", + "k","l","m","n","o","p","q","r","s","t","u","v","w","x","y", + "z","braceleft","bar","braceright","asciitilde","exclamdown","cent", + "sterling","fraction","yen","florin","section","currency", + "quotesingle","quotedblleft","guillemotleft","guilsinglleft", + "guilsinglright","fi","fl","endash","dagger","daggerdbl", + "periodcentered","paragraph","bullet","quotesinglbase","quotedblbase", + "quotedblright","guillemotright","ellipsis","perthousand","questiondown", + "grave","acute","circumflex","tilde","macron","breve","dotaccent", + "dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash", + "AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae", + "dotlessi","lslash","oslash","oe","germandbls","onesuperior", + "logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn", + "onequarter","divide","brokenbar","degree","thorn","threequarters", + "twosuperior","registered","minus","eth","multiply","threesuperior", + "copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring", + "Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave", + "Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute", + "Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute", + "Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron", + "aacute","acircumflex","adieresis","agrave","aring","atilde", + "ccedilla","eacute","ecircumflex","edieresis","egrave","iacute", + "icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex", + "odieresis","ograve","otilde","scaron","uacute","ucircumflex", + "udieresis","ugrave","yacute","ydieresis","zcaron","exclamsmall", + "Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall", + "Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader", + "onedotenleader","zerooldstyle","oneoldstyle","twooldstyle", + "threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle", + "sevenoldstyle","eightoldstyle","nineoldstyle","commasuperior", + "threequartersemdash","periodsuperior","questionsmall","asuperior", + "bsuperior","centsuperior","dsuperior","esuperior","isuperior", + "lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior", + "tsuperior","ff","ffi","ffl","parenleftinferior","parenrightinferior", + "Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall", + "Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall", + "Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall", + "Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall", + "Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah", + "Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall", + "Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall", + "Dotaccentsmall","Macronsmall","figuredash","hypheninferior", + "Ogoneksmall","Ringsmall","Cedillasmall","questiondownsmall","oneeighth", + "threeeighths","fiveeighths","seveneighths","onethird","twothirds", + "zerosuperior","foursuperior","fivesuperior","sixsuperior", + "sevensuperior","eightsuperior","ninesuperior","zeroinferior", + "oneinferior","twoinferior","threeinferior","fourinferior", + "fiveinferior","sixinferior","seveninferior","eightinferior", + "nineinferior","centinferior","dollarinferior","periodinferior", + "commainferior","Agravesmall","Aacutesmall","Acircumflexsmall", + "Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall", + "Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall", + "Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall", + "Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall", + "Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall", + "Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall", + "Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003", + "Black","Bold","Book","Light","Medium","Regular","Roman","Semibold", +} +local standardnames={ [0]= + false,false,false,false,false,false,false,false,false,false,false, + false,false,false,false,false,false,false,false,false,false,false, + false,false,false,false,false,false,false,false,false,false, + "space","exclam","quotedbl","numbersign","dollar","percent", + "ampersand","quoteright","parenleft","parenright","asterisk","plus", + "comma","hyphen","period","slash","zero","one","two","three","four", + "five","six","seven","eight","nine","colon","semicolon","less", + "equal","greater","question","at","A","B","C","D","E","F","G","H", + "I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W", + "X","Y","Z","bracketleft","backslash","bracketright","asciicircum", + "underscore","quoteleft","a","b","c","d","e","f","g","h","i","j", + "k","l","m","n","o","p","q","r","s","t","u","v","w","x","y", + "z","braceleft","bar","braceright","asciitilde",false,false,false, + false,false,false,false,false,false,false,false,false,false,false, + false,false,false,false,false,false,false,false,false,false,false, + false,false,false,false,false,false,false,false,false,"exclamdown", + "cent","sterling","fraction","yen","florin","section","currency", + "quotesingle","quotedblleft","guillemotleft","guilsinglleft", + "guilsinglright","fi","fl",false,"endash","dagger","daggerdbl", + "periodcentered",false,"paragraph","bullet","quotesinglbase", + "quotedblbase","quotedblright","guillemotright","ellipsis","perthousand", + false,"questiondown",false,"grave","acute","circumflex","tilde", + "macron","breve","dotaccent","dieresis",false,"ring","cedilla",false, + "hungarumlaut","ogonek","caron","emdash",false,false,false,false, + false,false,false,false,false,false,false,false,false,false,false, + false,"AE",false,"ordfeminine",false,false,false,false,"Lslash", + "Oslash","OE","ordmasculine",false,false,false,false,false,"ae", + false,false,false,"dotlessi",false,false,"lslash","oslash","oe", + "germandbls",false,false,false,false +} +local cffreaders={ + readbyte, + readushort, + readuint, + readulong, +} +directives.register("fonts.streamreader",function() + cffreaders={ + readbyte, + readushort, + readuint, + readulong, + } +end) +local function readheader(f) + local offset=getposition(f) + local major=readbyte(f) + local header={ + offset=offset, + major=major, + minor=readbyte(f), + size=readbyte(f), + } + if major==1 then + header.dsize=readbyte(f) + elseif major==2 then + header.dsize=readushort(f) + else + end + setposition(f,offset+header.size) + return header +end +local function readlengths(f,longcount) + local count=longcount and readulong(f) or readushort(f) + if count==0 then + return {} + end + local osize=readbyte(f) + local read=cffreaders[osize] + if not read then + report("bad offset size: %i",osize) + return {} + end + local lengths={} + local previous=read(f) + for i=1,count do + local offset=read(f) + local length=offset-previous + if length<0 then + report("bad offset: %i",length) + length=0 + end + lengths[i]=length + previous=offset + end + return lengths +end +local function readfontnames(f) + local names=readlengths(f) + for i=1,#names do + names[i]=readstring(f,names[i]) + end + return names +end +local function readtopdictionaries(f) + local dictionaries=readlengths(f) + for i=1,#dictionaries do + dictionaries[i]=readstring(f,dictionaries[i]) + end + return dictionaries +end +local function readstrings(f) + local lengths=readlengths(f) + local strings=setmetatableindex({},defaultstrings) + local index=#defaultstrings + for i=1,#lengths do + index=index+1 + strings[index]=readstring(f,lengths[i]) + end + return strings +end +do + local stack={} + local top=0 + local result={} + local strings={} + local p_single=P("\00")/function() + result.version=strings[stack[top]] or "unset" + top=0 + end+P("\01")/function() + result.notice=strings[stack[top]] or "unset" + top=0 + end+P("\02")/function() + result.fullname=strings[stack[top]] or "unset" + top=0 + end+P("\03")/function() + result.familyname=strings[stack[top]] or "unset" + top=0 + end+P("\04")/function() + result.weight=strings[stack[top]] or "unset" + top=0 + end+P("\05")/function() + result.fontbbox={ unpack(stack,1,4) } + top=0 + end+P("\06")/function() + result.bluevalues={ unpack(stack,1,top) } + top=0 + end+P("\07")/function() + result.otherblues={ unpack(stack,1,top) } + top=0 + end+P("\08")/function() + result.familyblues={ unpack(stack,1,top) } + top=0 + end+P("\09")/function() + result.familyotherblues={ unpack(stack,1,top) } + top=0 + end+P("\10")/function() + result.strhw=stack[top] + top=0 + end+P("\11")/function() + result.strvw=stack[top] + top=0 + end+P("\13")/function() + result.uniqueid=stack[top] + top=0 + end+P("\14")/function() + result.xuid=concat(stack,"",1,top) + top=0 + end+P("\15")/function() + result.charset=stack[top] + top=0 + end+P("\16")/function() + result.encoding=stack[top] + top=0 + end+P("\17")/function() + result.charstrings=stack[top] + top=0 + end+P("\18")/function() + result.private={ + size=stack[top-1], + offset=stack[top], + } + top=0 + end+P("\19")/function() + result.subroutines=stack[top] + top=0 + end+P("\20")/function() + result.defaultwidthx=stack[top] + top=0 + end+P("\21")/function() + result.nominalwidthx=stack[top] + top=0 + end ++P("\24")/function() + result.vstore=stack[top] + top=0 + end+P("\25")/function() + result.maxstack=stack[top] + top=0 + end + local p_double=P("\12")*( + P("\00")/function() + result.copyright=stack[top] + top=0 + end+P("\01")/function() + result.monospaced=stack[top]==1 and true or false + top=0 + end+P("\02")/function() + result.italicangle=stack[top] + top=0 + end+P("\03")/function() + result.underlineposition=stack[top] + top=0 + end+P("\04")/function() + result.underlinethickness=stack[top] + top=0 + end+P("\05")/function() + result.painttype=stack[top] + top=0 + end+P("\06")/function() + result.charstringtype=stack[top] + top=0 + end+P("\07")/function() + result.fontmatrix={ unpack(stack,1,6) } + top=0 + end+P("\08")/function() + result.strokewidth=stack[top] + top=0 + end+P("\09")/function() + result.bluescale=stack[top] + top=0 + end+P("\10")/function() + result.bluesnap=stack[top] + top=0 + end+P("\11")/function() + result.bluefuzz=stack[top] + top=0 + end+P("\12")/function() + result.stemsnaph={ unpack(stack,1,top) } + top=0 + end+P("\13")/function() + result.stemsnapv={ unpack(stack,1,top) } + top=0 + end+P("\20")/function() + result.syntheticbase=stack[top] + top=0 + end+P("\21")/function() + result.postscript=strings[stack[top]] or "unset" + top=0 + end+P("\22")/function() + result.basefontname=strings[stack[top]] or "unset" + top=0 + end+P("\21")/function() + result.basefontblend=stack[top] + top=0 + end+P("\30")/function() + result.cid.registry=strings[stack[top-2]] or "unset" + result.cid.ordering=strings[stack[top-1]] or "unset" + result.cid.supplement=stack[top] + top=0 + end+P("\31")/function() + result.cid.fontversion=stack[top] + top=0 + end+P("\32")/function() + result.cid.fontrevision=stack[top] + top=0 + end+P("\33")/function() + result.cid.fonttype=stack[top] + top=0 + end+P("\34")/function() + result.cid.count=stack[top] + top=0 + end+P("\35")/function() + result.cid.uidbase=stack[top] + top=0 + end+P("\36")/function() + result.cid.fdarray=stack[top] + top=0 + end+P("\37")/function() + result.cid.fdselect=stack[top] + top=0 + end+P("\38")/function() + result.cid.fontname=strings[stack[top]] or "unset" + top=0 + end + ) + local remap={ + ["\x00"]="00",["\x01"]="01",["\x02"]="02",["\x03"]="03",["\x04"]="04",["\x05"]="05",["\x06"]="06",["\x07"]="07",["\x08"]="08",["\x09"]="09",["\x0A"]="0.",["\x0B"]="0E",["\x0C"]="0E-",["\x0D"]="0",["\x0E"]="0-",["\x0F"]="0", + ["\x10"]="10",["\x11"]="11",["\x12"]="12",["\x13"]="13",["\x14"]="14",["\x15"]="15",["\x16"]="16",["\x17"]="17",["\x18"]="18",["\x19"]="19",["\x1A"]="1.",["\x1B"]="1E",["\x1C"]="1E-",["\x1D"]="1",["\x1E"]="1-",["\x1F"]="1", + ["\x20"]="20",["\x21"]="21",["\x22"]="22",["\x23"]="23",["\x24"]="24",["\x25"]="25",["\x26"]="26",["\x27"]="27",["\x28"]="28",["\x29"]="29",["\x2A"]="2.",["\x2B"]="2E",["\x2C"]="2E-",["\x2D"]="2",["\x2E"]="2-",["\x2F"]="2", + ["\x30"]="30",["\x31"]="31",["\x32"]="32",["\x33"]="33",["\x34"]="34",["\x35"]="35",["\x36"]="36",["\x37"]="37",["\x38"]="38",["\x39"]="39",["\x3A"]="3.",["\x3B"]="3E",["\x3C"]="3E-",["\x3D"]="3",["\x3E"]="3-",["\x3F"]="3", + ["\x40"]="40",["\x41"]="41",["\x42"]="42",["\x43"]="43",["\x44"]="44",["\x45"]="45",["\x46"]="46",["\x47"]="47",["\x48"]="48",["\x49"]="49",["\x4A"]="4.",["\x4B"]="4E",["\x4C"]="4E-",["\x4D"]="4",["\x4E"]="4-",["\x4F"]="4", + ["\x50"]="50",["\x51"]="51",["\x52"]="52",["\x53"]="53",["\x54"]="54",["\x55"]="55",["\x56"]="56",["\x57"]="57",["\x58"]="58",["\x59"]="59",["\x5A"]="5.",["\x5B"]="5E",["\x5C"]="5E-",["\x5D"]="5",["\x5E"]="5-",["\x5F"]="5", + ["\x60"]="60",["\x61"]="61",["\x62"]="62",["\x63"]="63",["\x64"]="64",["\x65"]="65",["\x66"]="66",["\x67"]="67",["\x68"]="68",["\x69"]="69",["\x6A"]="6.",["\x6B"]="6E",["\x6C"]="6E-",["\x6D"]="6",["\x6E"]="6-",["\x6F"]="6", + ["\x70"]="70",["\x71"]="71",["\x72"]="72",["\x73"]="73",["\x74"]="74",["\x75"]="75",["\x76"]="76",["\x77"]="77",["\x78"]="78",["\x79"]="79",["\x7A"]="7.",["\x7B"]="7E",["\x7C"]="7E-",["\x7D"]="7",["\x7E"]="7-",["\x7F"]="7", + ["\x80"]="80",["\x81"]="81",["\x82"]="82",["\x83"]="83",["\x84"]="84",["\x85"]="85",["\x86"]="86",["\x87"]="87",["\x88"]="88",["\x89"]="89",["\x8A"]="8.",["\x8B"]="8E",["\x8C"]="8E-",["\x8D"]="8",["\x8E"]="8-",["\x8F"]="8", + ["\x90"]="90",["\x91"]="91",["\x92"]="92",["\x93"]="93",["\x94"]="94",["\x95"]="95",["\x96"]="96",["\x97"]="97",["\x98"]="98",["\x99"]="99",["\x9A"]="9.",["\x9B"]="9E",["\x9C"]="9E-",["\x9D"]="9",["\x9E"]="9-",["\x9F"]="9", + ["\xA0"]=".0",["\xA1"]=".1",["\xA2"]=".2",["\xA3"]=".3",["\xA4"]=".4",["\xA5"]=".5",["\xA6"]=".6",["\xA7"]=".7",["\xA8"]=".8",["\xA9"]=".9",["\xAA"]="..",["\xAB"]=".E",["\xAC"]=".E-",["\xAD"]=".",["\xAE"]=".-",["\xAF"]=".", + ["\xB0"]="E0",["\xB1"]="E1",["\xB2"]="E2",["\xB3"]="E3",["\xB4"]="E4",["\xB5"]="E5",["\xB6"]="E6",["\xB7"]="E7",["\xB8"]="E8",["\xB9"]="E9",["\xBA"]="E.",["\xBB"]="EE",["\xBC"]="EE-",["\xBD"]="E",["\xBE"]="E-",["\xBF"]="E", + ["\xC0"]="E-0",["\xC1"]="E-1",["\xC2"]="E-2",["\xC3"]="E-3",["\xC4"]="E-4",["\xC5"]="E-5",["\xC6"]="E-6",["\xC7"]="E-7",["\xC8"]="E-8",["\xC9"]="E-9",["\xCA"]="E-.",["\xCB"]="E-E",["\xCC"]="E-E-",["\xCD"]="E-",["\xCE"]="E--",["\xCF"]="E-", + ["\xD0"]="-0",["\xD1"]="-1",["\xD2"]="-2",["\xD3"]="-3",["\xD4"]="-4",["\xD5"]="-5",["\xD6"]="-6",["\xD7"]="-7",["\xD8"]="-8",["\xD9"]="-9",["\xDA"]="-.",["\xDB"]="-E",["\xDC"]="-E-",["\xDD"]="-",["\xDE"]="--",["\xDF"]="-", + } + local p_last=S("\x0F\x1F\x2F\x3F\x4F\x5F\x6F\x7F\x8F\x9F\xAF\xBF")+R("\xF0\xFF") + local p_nibbles=P("\30")*Cs(((1-p_last)/remap)^0*(P(1)/remap))/function(n) + top=top+1 + stack[top]=tonumber(n) or 0 + end + local p_byte=C(R("\32\246"))/function(b0) + top=top+1 + stack[top]=byte(b0)-139 + end + local p_positive=C(R("\247\250"))*C(1)/function(b0,b1) + top=top+1 + stack[top]=(byte(b0)-247)*256+byte(b1)+108 + end + local p_negative=C(R("\251\254"))*C(1)/function(b0,b1) + top=top+1 + stack[top]=-(byte(b0)-251)*256-byte(b1)-108 + end + local p_short=P("\28")*C(1)*C(1)/function(b1,b2) + top=top+1 + local n=0x100*byte(b1)+byte(b2) + if n>=0x8000 then + stack[top]=n-0xFFFF-1 + else + stack[top]=n + end + end + local p_long=P("\29")*C(1)*C(1)*C(1)*C(1)/function(b1,b2,b3,b4) + top=top+1 + local n=0x1000000*byte(b1)+0x10000*byte(b2)+0x100*byte(b3)+byte(b4) + if n>=0x8000000 then + stack[top]=n-0xFFFFFFFF-1 + else + stack[top]=n + end + end + local p_unsupported=P(1)/function(detail) + top=0 + end + local p_dictionary=( + p_byte+p_positive+p_negative+p_short+p_long+p_nibbles+p_single+p_double+p_unsupported + )^1 + parsedictionaries=function(data,dictionaries,version) + stack={} + strings=data.strings + if trace_charstrings then + report("charstring format %a",version) + end + for i=1,#dictionaries do + top=0 + result=version=="cff" and { + monospaced=false, + italicangle=0, + underlineposition=-100, + underlinethickness=50, + painttype=0, + charstringtype=2, + fontmatrix={ 0.001,0,0,0.001,0,0 }, + fontbbox={ 0,0,0,0 }, + strokewidth=0, + charset=0, + encoding=0, + cid={ + fontversion=0, + fontrevision=0, + fonttype=0, + count=8720, + } + } or { + charstringtype=2, + charset=0, + vstore=0, + cid={ + }, + } + lpegmatch(p_dictionary,dictionaries[i]) + dictionaries[i]=result + end + result={} + top=0 + stack={} + end + parseprivates=function(data,dictionaries) + stack={} + strings=data.strings + for i=1,#dictionaries do + local private=dictionaries[i].private + if private and private.data then + top=0 + result={ + forcebold=false, + languagegroup=0, + expansionfactor=0.06, + initialrandomseed=0, + subroutines=0, + defaultwidthx=0, + nominalwidthx=0, + cid={ + }, + } + lpegmatch(p_dictionary,private.data) + private.data=result + end + end + result={} + top=0 + stack={} + end + local x=0 + local y=0 + local width=false + local lsb=0 + local r=0 + local stems=0 + local globalbias=0 + local localbias=0 + local nominalwidth=0 + local defaultwidth=0 + local charset=false + local globals=false + local locals=false + local depth=1 + local xmin=0 + local xmax=0 + local ymin=0 + local ymax=0 + local checked=false + local keepcurve=false + local version=2 + local regions=false + local nofregions=0 + local region=false + local factors=false + local axis=false + local vsindex=0 + local justpass=false + local seacs={} + local procidx=nil + local function showstate(where) + report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top) + end + local function showvalue(where,value,showstack) + if showstack then + report("%w%-10s : %s : [%s] n=%i",depth*2,where,tostring(value),concat(stack," ",1,top),top) + else + report("%w%-10s : %s",depth*2,where,tostring(value)) + end + end + local function xymoveto() + if keepcurve then + r=r+1 + result[r]={ x,y,"m" } + end + if checked then + if x>xmax then xmax=x elseif xymax then ymax=y elseif yxmax then + xmax=x + elseif xymax then + ymax=y + elseif yxmax then xmax=x elseif xymax then ymax=y elseif yxmax then + xmax=x + elseif xymax then + ymax=y + elseif yxmax then xmax=x1 elseif x1ymax then ymax=y1 elseif y1xmax then xmax=x2 elseif x2ymax then ymax=y2 elseif y2xmax then xmax=x3 elseif x3ymax then ymax=y3 elseif y32 then + width=stack[1] + if trace_charstrings then + showvalue("backtrack width",width) + end + else + width=true + end + end + if trace_charstrings then + showstate("rmoveto") + end + x=x+stack[top-1] + y=y+stack[top] + top=0 + xymoveto() + end + local function hmoveto() + if not width then + if top>1 then + width=stack[1] + if trace_charstrings then + showvalue("backtrack width",width) + end + else + width=true + end + end + if trace_charstrings then + showstate("hmoveto") + end + x=x+stack[top] + top=0 + xmoveto() + end + local function vmoveto() + if not width then + if top>1 then + width=stack[1] + if trace_charstrings then + showvalue("backtrack width",width) + end + else + width=true + end + end + if trace_charstrings then + showstate("vmoveto") + end + y=y+stack[top] + top=0 + ymoveto() + end + local function rlineto() + if trace_charstrings then + showstate("rlineto") + end + for i=1,top,2 do + x=x+stack[i] + y=y+stack[i+1] + xylineto() + end + top=0 + end + local function hlineto() + if trace_charstrings then + showstate("hlineto") + end + if top==1 then + x=x+stack[1] + xlineto() + else + local swap=true + for i=1,top do + if swap then + x=x+stack[i] + xlineto() + swap=false + else + y=y+stack[i] + ylineto() + swap=true + end + end + end + top=0 + end + local function vlineto() + if trace_charstrings then + showstate("vlineto") + end + if top==1 then + y=y+stack[1] + ylineto() + else + local swap=false + for i=1,top do + if swap then + x=x+stack[i] + xlineto() + swap=false + else + y=y+stack[i] + ylineto() + swap=true + end + end + end + top=0 + end + local function rrcurveto() + if trace_charstrings then + showstate("rrcurveto") + end + for i=1,top,6 do + local ax=x+stack[i] + local ay=y+stack[i+1] + local bx=ax+stack[i+2] + local by=ay+stack[i+3] + x=bx+stack[i+4] + y=by+stack[i+5] + xycurveto(ax,ay,bx,by,x,y) + end + top=0 + end + local function hhcurveto() + if trace_charstrings then + showstate("hhcurveto") + end + local s=1 + if top%2~=0 then + y=y+stack[1] + s=2 + end + for i=s,top,4 do + local ax=x+stack[i] + local ay=y + local bx=ax+stack[i+1] + local by=ay+stack[i+2] + x=bx+stack[i+3] + y=by + xycurveto(ax,ay,bx,by,x,y) + end + top=0 + end + local function vvcurveto() + if trace_charstrings then + showstate("vvcurveto") + end + local s=1 + local d=0 + if top%2~=0 then + d=stack[1] + s=2 + end + for i=s,top,4 do + local ax=x+d + local ay=y+stack[i] + local bx=ax+stack[i+1] + local by=ay+stack[i+2] + x=bx + y=by+stack[i+3] + xycurveto(ax,ay,bx,by,x,y) + d=0 + end + top=0 + end + local function xxcurveto(swap) + local last=top%4~=0 and stack[top] + if last then + top=top-1 + end + for i=1,top,4 do + local ax,ay,bx,by + if swap then + ax=x+stack[i] + ay=y + bx=ax+stack[i+1] + by=ay+stack[i+2] + y=by+stack[i+3] + if last and i+3==top then + x=bx+last + else + x=bx + end + swap=false + else + ax=x + ay=y+stack[i] + bx=ax+stack[i+1] + by=ay+stack[i+2] + x=bx+stack[i+3] + if last and i+3==top then + y=by+last + else + y=by + end + swap=true + end + xycurveto(ax,ay,bx,by,x,y) + end + top=0 + end + local function hvcurveto() + if trace_charstrings then + showstate("hvcurveto") + end + xxcurveto(true) + end + local function vhcurveto() + if trace_charstrings then + showstate("vhcurveto") + end + xxcurveto(false) + end + local function rcurveline() + if trace_charstrings then + showstate("rcurveline") + end + for i=1,top-2,6 do + local ax=x+stack[i] + local ay=y+stack[i+1] + local bx=ax+stack[i+2] + local by=ay+stack[i+3] + x=bx+stack[i+4] + y=by+stack[i+5] + xycurveto(ax,ay,bx,by,x,y) + end + x=x+stack[top-1] + y=y+stack[top] + xylineto() + top=0 + end + local function rlinecurve() + if trace_charstrings then + showstate("rlinecurve") + end + if top>6 then + for i=1,top-6,2 do + x=x+stack[i] + y=y+stack[i+1] + xylineto() + end + end + local ax=x+stack[top-5] + local ay=y+stack[top-4] + local bx=ax+stack[top-3] + local by=ay+stack[top-2] + x=bx+stack[top-1] + y=by+stack[top] + xycurveto(ax,ay,bx,by,x,y) + top=0 + end + local function flex() + if trace_charstrings then + showstate("flex") + end + local ax=x+stack[1] + local ay=y+stack[2] + local bx=ax+stack[3] + local by=ay+stack[4] + local cx=bx+stack[5] + local cy=by+stack[6] + xycurveto(ax,ay,bx,by,cx,cy) + local dx=cx+stack[7] + local dy=cy+stack[8] + local ex=dx+stack[9] + local ey=dy+stack[10] + x=ex+stack[11] + y=ey+stack[12] + xycurveto(dx,dy,ex,ey,x,y) + top=0 + end + local function hflex() + if trace_charstrings then + showstate("hflex") + end + local ax=x+stack[1] + local ay=y + local bx=ax+stack[2] + local by=ay+stack[3] + local cx=bx+stack[4] + local cy=by + xycurveto(ax,ay,bx,by,cx,cy) + local dx=cx+stack[5] + local dy=by + local ex=dx+stack[6] + local ey=y + x=ex+stack[7] + xycurveto(dx,dy,ex,ey,x,y) + top=0 + end + local function hflex1() + if trace_charstrings then + showstate("hflex1") + end + local ax=x+stack[1] + local ay=y+stack[2] + local bx=ax+stack[3] + local by=ay+stack[4] + local cx=bx+stack[5] + local cy=by + xycurveto(ax,ay,bx,by,cx,cy) + local dx=cx+stack[6] + local dy=by + local ex=dx+stack[7] + local ey=dy+stack[8] + x=ex+stack[9] + xycurveto(dx,dy,ex,ey,x,y) + top=0 + end + local function flex1() + if trace_charstrings then + showstate("flex1") + end + local ax=x+stack[1] + local ay=y+stack[2] + local bx=ax+stack[3] + local by=ay+stack[4] + local cx=bx+stack[5] + local cy=by+stack[6] + xycurveto(ax,ay,bx,by,cx,cy) + local dx=cx+stack[7] + local dy=cy+stack[8] + local ex=dx+stack[9] + local ey=dy+stack[10] + if abs(ex-x)>abs(ey-y) then + x=ex+stack[11] + else + y=ey+stack[11] + end + xycurveto(dx,dy,ex,ey,x,y) + top=0 + end + local function getstem() + if top==0 then + elseif top%2~=0 then + if width then + remove(stack,1) + else + width=remove(stack,1) + if trace_charstrings then + showvalue("width",width) + end + end + top=top-1 + end + if trace_charstrings then + showstate("stem") + end + stems=stems+idiv(top,2) + top=0 + end + local function getmask() + if top==0 then + elseif top%2~=0 then + if width then + remove(stack,1) + else + width=remove(stack,1) + if trace_charstrings then + showvalue("width",width) + end + end + top=top-1 + end + if trace_charstrings then + showstate(operator==19 and "hintmark" or "cntrmask") + end + stems=stems+idiv(top,2) + top=0 + if stems==0 then + elseif stems<=8 then + return 1 + else + return idiv(stems+7,8) + end + end + local function unsupported(t) + if trace_charstrings then + showstate("unsupported "..t) + end + top=0 + end + local function unsupportedsub(t) + if trace_charstrings then + showstate("unsupported sub "..t) + end + top=0 + end + local function getstem3() + if trace_charstrings then + showstate("stem3") + end + top=0 + end + local function divide() + if version=="cff" then + local d=stack[top] + top=top-1 + stack[top]=stack[top]/d + end + end + local function closepath() + if version=="cff" then + if trace_charstrings then + showstate("closepath") + end + end + top=0 + end + local function hsbw() + if version=="cff" then + if trace_charstrings then + showstate("hsbw") + end + lsb=stack[top-1] or 0 + width=stack[top] + end + top=0 + end + local function sbw() + if version=="cff" then + if trace_charstrings then + showstate("sbw") + end + lsb=stack[top-3] + width=stack[top-1] + end + top=0 + end + local function seac() + if version=="cff" then + if trace_charstrings then + showstate("seac") + end + end + top=0 + end + local popped=3 + local hints=3 + local function callothersubr() + if version=="cff" then + if trace_charstrings then + showstate("callothersubr") + end + if stack[top]==hints then + popped=stack[top-2] + else + popped=3 + end + local t=stack[top-1] + if t then + top=top-(t+2) + if top<0 then + top=0 + end + else + top=0 + end + else + top=0 + end + end + local function pop() + if version=="cff" then + if trace_charstrings then + showstate("pop") + end + top=top+1 + stack[top]=popped + else + top=0 + end + end + local function setcurrentpoint() + if version=="cff" then + if trace_charstrings then + showstate("setcurrentpoint (unsupported)") + end + x=x+stack[top-1] + y=y+stack[top] + end + top=0 + end + local reginit=false + local function updateregions(n) + if regions then + local current=regions[n+1] or regions[1] + nofregions=#current + if axis and n~=reginit then + factors={} + for i=1,nofregions do + local region=current[i] + local s=1 + for j=1,#axis do + local f=axis[j] + local r=region[j] + local start=r.start + local peak=r.peak + local stop=r.stop + if start>peak or peak>stop then + elseif start<0 and stop>0 and peak~=0 then + elseif peak==0 then + elseif fstop then + s=0 + break + elseif fpeak then + s=s*(stop-f)/(stop-peak) + else + end + end + factors[i]=s + end + end + end + reginit=n + end + local function setvsindex() + local vsindex=stack[top] + if trace_charstrings then + showstate(formatters["vsindex %i"](vsindex)) + end + updateregions(vsindex) + top=top-1 + end + local function blend() + local n=stack[top] + top=top-1 + if axis then + if trace_charstrings then + local t=top-nofregions*n + local m=t-n + for i=1,n do + local k=m+i + local d=m+n+(i-1)*nofregions + local old=stack[k] + local new=old + for r=1,nofregions do + new=new+stack[d+r]*factors[r] + end + stack[k]=new + showstate(formatters["blend %i of %i: %s -> %s"](i,n,old,new)) + end + top=t + elseif n==1 then + top=top-nofregions + local v=stack[top] + for r=1,nofregions do + v=v+stack[top+r]*factors[r] + end + stack[top]=v + else + top=top-nofregions*n + local d=top + local k=top-n + for i=1,n do + k=k+1 + local v=stack[k] + for r=1,nofregions do + v=v+stack[d+r]*factors[r] + end + stack[k]=v + d=d+nofregions + end + end + else + top=top-nofregions*n + end + end + local actions={ [0]=unsupported, + getstem, + unsupported, + getstem, + vmoveto, + rlineto, + hlineto, + vlineto, + rrcurveto, + unsupported, + unsupported, + unsupported, + unsupported, + hsbw, + unsupported, + setvsindex, + blend, + unsupported, + getstem, + getmask, + getmask, + rmoveto, + hmoveto, + getstem, + rcurveline, + rlinecurve, + vvcurveto, + hhcurveto, + unsupported, + unsupported, + vhcurveto, + hvcurveto, + } + local reverse={ [0]="unsupported", + "getstem", + "unsupported", + "getstem", + "vmoveto", + "rlineto", + "hlineto", + "vlineto", + "rrcurveto", + "unsupported", + "unsupported", + "unsupported", + "unsupported", + "hsbw", + "unsupported", + "setvsindex", + "blend", + "unsupported", + "getstem", + "getmask", + "getmask", + "rmoveto", + "hmoveto", + "getstem", + "rcurveline", + "rlinecurve", + "vvcurveto", + "hhcurveto", + "unsupported", + "unsupported", + "vhcurveto", + "hvcurveto", + } + local subactions={ + [000]=dotsection, + [001]=getstem3, + [002]=getstem3, + [006]=seac, + [007]=sbw, + [012]=divide, + [016]=callothersubr, + [017]=pop, + [033]=setcurrentpoint, + [034]=hflex, + [035]=flex, + [036]=hflex1, + [037]=flex1, + } + local chars=setmetatableindex(function (t,k) + local v=char(k) + t[k]=v + return v + end) + local c_endchar=chars[14] + local encode={} + setmetatableindex(encode,function(t,i) + for i=-2048,-1130 do + t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF)) + end + for i=-1131,-108 do + local v=0xFB00-i-108 + t[i]=char(band(rshift(v,8),0xFF),band(v,0xFF)) + end + for i=-107,107 do + t[i]=chars[i+139] + end + for i=108,1131 do + local v=0xF700+i-108 + t[i]=char(extract(v,8,8),extract(v,0,8)) + end + for i=1132,2048 do + t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF)) + end + setmetatableindex(encode,function(t,k) + local r=round(k) + local v=rawget(t,r) + if v then + return v + end + local v1=floor(k) + local v2=floor((k-v1)*0x10000) + return char(255,extract(v1,8,8),extract(v1,0,8),extract(v2,8,8),extract(v2,0,8)) + end) + return t[i] + end) + readers.cffencoder=encode + local function p_setvsindex() + local vsindex=stack[top] + updateregions(vsindex) + top=top-1 + end + local function p_blend() + local n=stack[top] + top=top-1 + if not axis then + elseif n==1 then + top=top-nofregions + local v=stack[top] + for r=1,nofregions do + v=v+stack[top+r]*factors[r] + end + stack[top]=round(v) + else + top=top-nofregions*n + local d=top + local k=top-n + for i=1,n do + k=k+1 + local v=stack[k] + for r=1,nofregions do + v=v+stack[d+r]*factors[r] + end + stack[k]=round(v) + d=d+nofregions + end + end + end + local function p_getstem() + local n=0 + if top%2~=0 then + n=1 + end + if top>n then + stems=stems+idiv(top-n,2) + end + end + local function p_getmask() + local n=0 + if top%2~=0 then + n=1 + end + if top>n then + stems=stems+idiv(top-n,2) + end + if stems==0 then + return 0 + elseif stems<=8 then + return 1 + else + return idiv(stems+7,8) + end + end + local process + local function call(scope,list,bias) + depth=depth+1 + if top==0 then + showstate(formatters["unknown %s call %s, case %s"](scope,"?",1)) + top=0 + else + local index=stack[top]+bias + top=top-1 + if trace_charstrings then + showvalue(scope,index,true) + end + local tab=list[index] + if tab then + process(tab) + else + showstate(formatters["unknown %s call %s, case %s"](scope,index,2)) + top=0 + end + end + depth=depth-1 + end + process=function(tab) + local i=1 + local n=#tab + while i<=n do + local t=tab[i] + if t>=32 then + top=top+1 + if t<=246 then + stack[top]=t-139 + i=i+1 + elseif t<=250 then + stack[top]=t*256-63124+tab[i+1] + i=i+2 + elseif t<=254 then + stack[top]=-t*256+64148-tab[i+1] + i=i+2 + else + local n=0x100*tab[i+1]+tab[i+2] + if n>=0x8000 then + stack[top]=n-0x10000+(0x100*tab[i+3]+tab[i+4])/0xFFFF + else + stack[top]=n+(0x100*tab[i+3]+tab[i+4])/0xFFFF + end + i=i+5 + end + elseif t==28 then + top=top+1 + local n=0x100*tab[i+1]+tab[i+2] + if n>=0x8000 then + stack[top]=n-0x10000 + else + stack[top]=n + end + i=i+3 + elseif t==11 then + if trace_charstrings then + showstate("return") + end + return + elseif t==10 then + call("local",locals,localbias) + i=i+1 + elseif t==14 then + if width then + elseif top>0 then + width=stack[1] + if trace_charstrings then + showvalue("width",width) + end + else + width=true + end + if trace_charstrings then + showstate("endchar") + end + return + elseif t==29 then + call("global",globals,globalbias) + i=i+1 + elseif t==12 then + i=i+1 + local t=tab[i] + if justpass then + if t>=34 and t<=37 then + for i=1,top do + r=r+1;result[r]=encode[stack[i]] + end + r=r+1;result[r]=chars[12] + r=r+1;result[r]=chars[t] + top=0 + elseif t==6 then + seacs[procidx]={ + asb=stack[1], + adx=stack[2], + ady=stack[3], + base=stack[4], + accent=stack[5], + width=width, + lsb=lsb, + } + top=0 + else + local a=subactions[t] + if a then + a(t) + else + top=0 + end + end + else + local a=subactions[t] + if a then + a(t) + else + if trace_charstrings then + showvalue("",t) + end + top=0 + end + end + i=i+1 + elseif justpass then + if t==15 then + p_setvsindex() + i=i+1 + elseif t==16 then + local s=p_blend() or 0 + i=i+s+1 + elseif t==1 or t==3 or t==18 or operation==23 then + p_getstem() + if true then + if top>0 then + for i=1,top do + r=r+1;result[r]=encode[stack[i]] + end + top=0 + end + r=r+1;result[r]=chars[t] + else + top=0 + end + i=i+1 + elseif t==19 or t==20 then + local s=p_getmask() or 0 + if true then + if top>0 then + for i=1,top do + r=r+1;result[r]=encode[stack[i]] + end + top=0 + end + r=r+1;result[r]=chars[t] + for j=1,s do + i=i+1 + r=r+1;result[r]=chars[tab[i]] + end + else + i=i+s + top=0 + end + i=i+1 + elseif t==9 then + top=0 + i=i+1 + elseif t==13 then + hsbw() + if version=="cff" then + r=r+1;result[r]=encode[lsb] + r=r+1;result[r]=chars[22] + else + end + i=i+1 + else + if trace_charstrings then + showstate(reverse[t] or "") + end + if top>0 then + for i=1,top do + r=r+1;result[r]=encode[stack[i]] + end + top=0 + end + r=r+1;result[r]=chars[t] + i=i+1 + end + else + local a=actions[t] + if a then + local s=a(t) + if s then + i=i+s+1 + else + i=i+1 + end + else + if trace_charstrings then + showstate(reverse[t] or "") + end + top=0 + i=i+1 + end + end + end + end + local function setbias(globals,locals,nobias) + if nobias then + return 0,0 + else + local g=#globals + local l=#locals + return + ((g<1240 and 107) or (g<33900 and 1131) or 32768)+1, + ((l<1240 and 107) or (l<33900 and 1131) or 32768)+1 + end + end + local function processshape(tab,index,hack) + if not tab then + glyphs[index]={ + boundingbox={ 0,0,0,0 }, + width=0, + name=charset and charset[index] or nil, + } + return + end + tab=bytetable(tab) + x=0 + y=0 + width=false + lsb=0 + r=0 + top=0 + stems=0 + result={} + popped=3 + procidx=index + xmin=0 + xmax=0 + ymin=0 + ymax=0 + checked=false + if trace_charstrings then + report("glyph: %i",index) + report("data : % t",tab) + end + if regions then + updateregions(vsindex) + end + process(tab) + if hack then + return x,y + end + local boundingbox={ + round(xmin), + round(ymin), + round(xmax), + round(ymax), + } + if width==true or width==false then + width=defaultwidth + else + width=nominalwidth+width + end + local glyph=glyphs[index] + if justpass then + r=r+1 + result[r]=c_endchar + local stream=concat(result) + if glyph then + glyph.stream=stream + else + glyphs[index]={ stream=stream } + end + elseif glyph then + glyph.segments=keepcurve~=false and result or nil + glyph.boundingbox=boundingbox + if not glyph.width then + glyph.width=width + end + if charset and not glyph.name then + glyph.name=charset[index] + end + elseif keepcurve then + glyphs[index]={ + segments=result, + boundingbox=boundingbox, + width=width, + name=charset and charset[index] or nil, + } + else + glyphs[index]={ + boundingbox=boundingbox, + width=width, + name=charset and charset[index] or nil, + } + end + if trace_charstrings then + report("width : %s",tostring(width)) + report("boundingbox: % t",boundingbox) + end + end + startparsing=function(fontdata,data,streams) + reginit=false + axis=false + regions=data.regions + justpass=streams==true + popped=3 + seacs={} + if regions then + regions={} + local deltas=data.deltas + for i=1,#deltas do + regions[i]=deltas[i].regions + end + axis=data.factors or false + end + end + stopparsing=function(fontdata,data) + stack={} + glyphs=false + result={} + top=0 + locals=false + globals=false + strings=false + popped=3 + seacs={} + end + local function setwidths(private) + if not private then + return 0,0 + end + local privatedata=private.data + if not privatedata then + return 0,0 + end + return privatedata.nominalwidthx or 0,privatedata.defaultwidthx or 0 + end + parsecharstrings=function(fontdata,data,glphs,doshapes,tversion,streams,nobias) + local dictionary=data.dictionaries[1] + local charstrings=dictionary.charstrings + keepcurve=doshapes + version=tversion + strings=data.strings + globals=data.routines or {} + locals=dictionary.subroutines or {} + charset=dictionary.charset + vsindex=dictionary.vsindex or 0 + glyphs=glphs or {} + globalbias,localbias=setbias(globals,locals,nobias) + nominalwidth,defaultwidth=setwidths(dictionary.private) + if charstrings then + startparsing(fontdata,data,streams) + for index=1,#charstrings do + processshape(charstrings[index],index-1) + end + if justpass and next(seacs) then + local charset=data.dictionaries[1].charset + if charset then + local lookup=table.swapped(charset) + for index,v in next,seacs do + local bindex=lookup[standardnames[v.base]] + local aindex=lookup[standardnames[v.accent]] + local bglyph=bindex and glyphs[bindex] + local aglyph=aindex and glyphs[aindex] + if bglyph and aglyph then + local jp=justpass + justpass=false + local x,y=processshape(charstrings[bindex+1],bindex,true) + justpass=jp + local base=bglyph.stream + local accent=aglyph.stream + local moveto=encode[-x-v.asb+v.adx]..chars[22]..encode[-y+v.ady]..chars[ 4] + base=sub(base,1,#base-1) + glyphs[index].stream=base..moveto..accent + end + end + end + end + stopparsing(fontdata,data) + else + report("no charstrings") + end + return glyphs + end + parsecharstring=function(fontdata,data,dictionary,tab,glphs,index,doshapes,tversion,streams) + keepcurve=doshapes + version=tversion + strings=data.strings + globals=data.routines or {} + locals=dictionary.subroutines or {} + charset=false + vsindex=dictionary.vsindex or 0 + glyphs=glphs or {} + justpass=streams==true + seacs={} + globalbias,localbias=setbias(globals,locals,nobias) + nominalwidth,defaultwidth=setwidths(dictionary.private) + processshape(tab,index-1) + end +end +local function readglobals(f,data,version) + local routines=readlengths(f,version=="cff2") + for i=1,#routines do + routines[i]=readbytetable(f,routines[i]) + end + data.routines=routines +end +local function readencodings(f,data) + data.encodings={} +end +local function readcharsets(f,data,dictionary) + local header=data.header + local strings=data.strings + local nofglyphs=data.nofglyphs + local charsetoffset=dictionary.charset + if charsetoffset and charsetoffset~=0 then + setposition(f,header.offset+charsetoffset) + local format=readbyte(f) + local charset={ [0]=".notdef" } + dictionary.charset=charset + if format==0 then + for i=1,nofglyphs do + charset[i]=strings[readushort(f)] + end + elseif format==1 or format==2 then + local readcount=format==1 and readbyte or readushort + local i=1 + while i<=nofglyphs do + local sid=readushort(f) + local n=readcount(f) + for s=sid,sid+n do + charset[i]=strings[s] + i=i+1 + if i>nofglyphs then + break + end + end + end + else + report("cff parser: unsupported charset format %a",format) + end + else + dictionary.nocharset=true + dictionary.charset=nil + end +end +local function readprivates(f,data) + local header=data.header + local dictionaries=data.dictionaries + local private=dictionaries[1].private + if private then + setposition(f,header.offset+private.offset) + private.data=readstring(f,private.size) + end +end +local function readlocals(f,data,dictionary,version) + local header=data.header + local private=dictionary.private + if private then + local subroutineoffset=private.data.subroutines + if subroutineoffset~=0 then + setposition(f,header.offset+private.offset+subroutineoffset) + local subroutines=readlengths(f,version=="cff2") + for i=1,#subroutines do + subroutines[i]=readbytetable(f,subroutines[i]) + end + dictionary.subroutines=subroutines + private.data.subroutines=nil + else + dictionary.subroutines={} + end + else + dictionary.subroutines={} + end +end +local function readcharstrings(f,data,version) + local header=data.header + local dictionaries=data.dictionaries + local dictionary=dictionaries[1] + local stringtype=dictionary.charstringtype + local offset=dictionary.charstrings + if type(offset)~="number" then + elseif stringtype==2 then + setposition(f,header.offset+offset) + local charstrings=readlengths(f,version=="cff2") + local nofglyphs=#charstrings + for i=1,nofglyphs do + charstrings[i]=readstring(f,charstrings[i]) + end + data.nofglyphs=nofglyphs + dictionary.charstrings=charstrings + else + report("unsupported charstr type %i",stringtype) + data.nofglyphs=0 + dictionary.charstrings={} + end +end +local function readcidprivates(f,data) + local header=data.header + local dictionaries=data.dictionaries[1].cid.dictionaries + for i=1,#dictionaries do + local dictionary=dictionaries[i] + local private=dictionary.private + if private then + setposition(f,header.offset+private.offset) + private.data=readstring(f,private.size) + end + end + parseprivates(data,dictionaries) +end +readers.parsecharstrings=parsecharstrings +local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams) + local dictionaries=data.dictionaries + local dictionary=dictionaries[1] + local cid=not dictionary.private and dictionary.cid + readglobals(f,data,version) + readcharstrings(f,data,version) + if version=="cff2" then + dictionary.charset=nil + else + readencodings(f,data) + readcharsets(f,data,dictionary) + end + if cid then + local fdarray=cid.fdarray + if fdarray then + setposition(f,data.header.offset+fdarray) + local dictionaries=readlengths(f,version=="cff2") + local nofdictionaries=#dictionaries + if nofdictionaries>0 then + for i=1,nofdictionaries do + dictionaries[i]=readstring(f,dictionaries[i]) + end + parsedictionaries(data,dictionaries) + dictionary.private=dictionaries[1].private + if nofdictionaries>1 then + report("ignoring dictionaries > 1 in cid font") + end + end + end + end + readprivates(f,data) + parseprivates(data,data.dictionaries) + readlocals(f,data,dictionary,version) + startparsing(fontdata,data,streams) + parsecharstrings(fontdata,data,glyphs,doshapes,version,streams) + stopparsing(fontdata,data) +end +local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams) + local header=data.header + local dictionaries=data.dictionaries + local dictionary=dictionaries[1] + local cid=dictionary.cid + local cidselect=cid and cid.fdselect + readglobals(f,data,version) + readcharstrings(f,data,version) + if version~="cff2" then + readencodings(f,data) + end + local charstrings=dictionary.charstrings + local fdindex={} + local nofglyphs=data.nofglyphs + local maxindex=-1 + setposition(f,header.offset+cidselect) + local format=readbyte(f) + if format==1 then + for i=0,nofglyphs do + local index=readbyte(f) + fdindex[i]=index + if index>maxindex then + maxindex=index + end + end + elseif format==3 then + local nofranges=readushort(f) + local first=readushort(f) + local index=readbyte(f) + while true do + local last=readushort(f) + if index>maxindex then + maxindex=index + end + for i=first,last do + fdindex[i]=index + end + if last>=nofglyphs then + break + else + first=last+1 + index=readbyte(f) + end + end + else + end + if maxindex>=0 then + local cidarray=cid.fdarray + if cidarray then + setposition(f,header.offset+cidarray) + local dictionaries=readlengths(f,version=="cff2") + for i=1,#dictionaries do + dictionaries[i]=readstring(f,dictionaries[i]) + end + parsedictionaries(data,dictionaries) + cid.dictionaries=dictionaries + readcidprivates(f,data) + for i=1,#dictionaries do + readlocals(f,data,dictionaries[i],version) + end + startparsing(fontdata,data,streams) + for i=1,#charstrings do + parsecharstring(fontdata,data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version,streams) + end + stopparsing(fontdata,data) + else + report("no cid array") + end + end +end +local gotodatatable=readers.helpers.gotodatatable +local function cleanup(data,dictionaries) +end +function readers.cff(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"cff",specification.details or specification.glyphs) + if tableoffset then + local header=readheader(f) + if header.major~=1 then + report("only version %s is supported for table %a",1,"cff") + return + end + local glyphs=fontdata.glyphs + local names=readfontnames(f) + local dictionaries=readtopdictionaries(f) + local strings=readstrings(f) + local data={ + header=header, + names=names, + dictionaries=dictionaries, + strings=strings, + nofglyphs=fontdata.nofglyphs, + } + parsedictionaries(data,dictionaries,"cff") + local dic=dictionaries[1] + local cid=dic.cid + local cffinfo={ + familyname=dic.familyname, + fullname=dic.fullname, + boundingbox=dic.boundingbox, + weight=dic.weight, + italicangle=dic.italicangle, + underlineposition=dic.underlineposition, + underlinethickness=dic.underlinethickness, + defaultwidth=dic.defaultwidthx, + nominalwidth=dic.nominalwidthx, + monospaced=dic.monospaced, + } + fontdata.cidinfo=cid and { + registry=cid.registry, + ordering=cid.ordering, + supplement=cid.supplement, + } + fontdata.cffinfo=cffinfo + local all=specification.shapes or specification.streams or false + if specification.glyphs or all then + if cid and cid.fdselect then + readfdselect(f,fontdata,data,glyphs,all,"cff",specification.streams) + else + readnoselect(f,fontdata,data,glyphs,all,"cff",specification.streams) + end + end + local private=dic.private + if private then + local data=private.data + if type(data)=="table" then + cffinfo.defaultwidth=data.defaultwidthx or cffinfo.defaultwidth + cffinfo.nominalwidth=data.nominalwidthx or cffinfo.nominalwidth + cffinfo.bluevalues=data.bluevalues + cffinfo.otherblues=data.otherblues + cffinfo.familyblues=data.familyblues + cffinfo.familyotherblues=data.familyotherblues + cffinfo.bluescale=data.bluescale + cffinfo.blueshift=data.blueshift + cffinfo.bluefuzz=data.bluefuzz + cffinfo.stdhw=data.stdhw + cffinfo.stdvw=data.stdvw + end + end + cleanup(data,dictionaries) + end +end +function readers.cff2(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"cff2",specification.glyphs) + if tableoffset then + local header=readheader(f) + if header.major~=2 then + report("only version %s is supported for table %a",2,"cff2") + return + end + local glyphs=fontdata.glyphs + local dictionaries={ readstring(f,header.dsize) } + local data={ + header=header, + dictionaries=dictionaries, + nofglyphs=fontdata.nofglyphs, + } + parsedictionaries(data,dictionaries,"cff2") + local offset=dictionaries[1].vstore + if offset>0 then + local storeoffset=dictionaries[1].vstore+data.header.offset+2 + local regions,deltas=readers.helpers.readvariationdata(f,storeoffset,factors) + data.regions=regions + data.deltas=deltas + else + data.regions={} + data.deltas={} + end + data.factors=specification.factors + local cid=data.dictionaries[1].cid + local all=specification.shapes or specification.streams or false + if cid and cid.fdselect then + readfdselect(f,fontdata,data,glyphs,all,"cff2",specification.streams) + else + readnoselect(f,fontdata,data,glyphs,all,"cff2",specification.streams) + end + cleanup(data,dictionaries) + end +end +function readers.cffcheck(filename) + local f=io.open(filename,"rb") + if f then + local fontdata={ + glyphs={}, + } + local header=readheader(f) + if header.major~=1 then + report("only version %s is supported for table %a",1,"cff") + return + end + local names=readfontnames(f) + local dictionaries=readtopdictionaries(f) + local strings=readstrings(f) + local glyphs={} + local data={ + header=header, + names=names, + dictionaries=dictionaries, + strings=strings, + glyphs=glyphs, + nofglyphs=0, + } + parsedictionaries(data,dictionaries,"cff") + local cid=data.dictionaries[1].cid + if cid and cid.fdselect then + readfdselect(f,fontdata,data,glyphs,false) + else + readnoselect(f,fontdata,data,glyphs,false) + end + return data + end +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-cff”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-ttf” ffffc827e1bcddc33a2b615340ecff7f] --- + +if not modules then modules={} end modules ['font-ttf']={ + version=1.001, + optimize=true, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next,type,unpack=next,type,unpack +local band,rshift=bit32.band,bit32.rshift +local sqrt,round=math.sqrt,math.round +local char,rep=string.char,string.rep +local concat=table.concat +local idiv=number.idiv +local setmetatableindex=table.setmetatableindex +local report=logs.reporter("otf reader","ttf") +local trace_deltas=false +local readers=fonts.handlers.otf.readers +local streamreader=readers.streamreader +local setposition=streamreader.setposition +local getposition=streamreader.getposition +local skipbytes=streamreader.skip +local readbyte=streamreader.readcardinal1 +local readushort=streamreader.readcardinal2 +local readulong=streamreader.readcardinal4 +local readchar=streamreader.readinteger1 +local readshort=streamreader.readinteger2 +local read2dot14=streamreader.read2dot14 +local readinteger=streamreader.readinteger1 +local readcardinaltable=streamreader.readcardinaltable +local readintegertable=streamreader.readintegertable +directives.register("fonts.streamreader",function() + streamreader=utilities.streams + setposition=streamreader.setposition + getposition=streamreader.getposition + skipbytes=streamreader.skip + readbyte=streamreader.readcardinal1 + readushort=streamreader.readcardinal2 + readulong=streamreader.readcardinal4 + readchar=streamreader.readinteger1 + readshort=streamreader.readinteger2 + read2dot14=streamreader.read2dot14 + readinteger=streamreader.readinteger1 + readcardinaltable=streamreader.readcardinaltable + readintegertable=streamreader.readintegertable +end) +local short=2 +local ushort=2 +local ulong=4 +local helpers=readers.helpers +local gotodatatable=helpers.gotodatatable +local function mergecomposites(glyphs,shapes) + local function merge(index,shape,components) + local contours={} + local points={} + local nofcontours=0 + local nofpoints=0 + local offset=0 + local deltas=shape.deltas + for i=1,#components do + local component=components[i] + local subindex=component.index + local subshape=shapes[subindex] + local subcontours=subshape.contours + local subpoints=subshape.points + if not subcontours then + local subcomponents=subshape.components + if subcomponents then + subcontours,subpoints=merge(subindex,subshape,subcomponents) + end + end + if subpoints then + local matrix=component.matrix + local xscale=matrix[1] + local xrotate=matrix[2] + local yrotate=matrix[3] + local yscale=matrix[4] + local xoffset=matrix[5] + local yoffset=matrix[6] + local count=#subpoints + if xscale==1 and yscale==1 and xrotate==0 and yrotate==0 then + for i=1,count do + local p=subpoints[i] + nofpoints=nofpoints+1 + points[nofpoints]={ + p[1]+xoffset, + p[2]+yoffset, + p[3] + } + end + else + for i=1,count do + local p=subpoints[i] + local x=p[1] + local y=p[2] + nofpoints=nofpoints+1 + points[nofpoints]={ + xscale*x+xrotate*y+xoffset, + yscale*y+yrotate*x+yoffset, + p[3] + } + end + end + local subcount=#subcontours + if subcount==1 then + nofcontours=nofcontours+1 + contours[nofcontours]=offset+subcontours[1] + else + for i=1,#subcontours do + nofcontours=nofcontours+1 + contours[nofcontours]=offset+subcontours[i] + end + end + offset=offset+count + else + report("missing contours composite %s, component %s of %s, glyph %s",index,i,#components,subindex) + end + end + shape.points=points + shape.contours=contours + shape.components=nil + return contours,points + end + for index=0,#glyphs do + local shape=shapes[index] + if shape then + local components=shape.components + if components then + merge(index,shape,components) + end + end + end +end +local function readnothing(f) + return { + type="nothing", + } +end +local function curveto(m_x,m_y,l_x,l_y,r_x,r_y) + return + l_x+2/3*(m_x-l_x),l_y+2/3*(m_y-l_y), + r_x+2/3*(m_x-r_x),r_y+2/3*(m_y-r_y), + r_x,r_y,"c" +end +local function applyaxis(glyph,shape,deltas,dowidth) + local points=shape.points + if points then + local nofpoints=#points + local h=nofpoints+2 + local l=nofpoints+1 + local dw=0 + local dl=0 + for i=1,#deltas do + local deltaset=deltas[i] + local xvalues=deltaset.xvalues + local yvalues=deltaset.yvalues + local dpoints=deltaset.points + local factor=deltaset.factor + if dpoints then + local nofdpoints=#dpoints + for i=1,nofdpoints do + local d=dpoints[i] + local p=points[d] + if p then + if xvalues then + local x=xvalues[i] + if x and x~=0 then + p[1]=p[1]+factor*x + end + end + if yvalues then + local y=yvalues[i] + if y and y~=0 then + p[2]=p[2]+factor*y + end + end + elseif dowidth then + if d==h then + local x=xvalues[i] + if x then + dw=dw+factor*x + end + elseif d==l then + local x=xvalues[i] + if x then + dl=dl+factor*x + end + end + end + end + else + for i=1,nofpoints do + local p=points[i] + if xvalues then + local x=xvalues[i] + if x and x~=0 then + p[1]=p[1]+factor*x + end + end + if yvalues then + local y=yvalues[i] + if y and y~=0 then + p[2]=p[2]+factor*y + end + end + end + if dowidth then + local x=xvalues[h] + if x then + dw=dw+factor*x + end + local x=xvalues[l] + if x then + dl=dl+factor*x + end + end + end + end + if dowidth then + local width=glyph.width or 0 + glyph.width=width+dw-dl + end + else + report("no points for glyph %a",glyph.name) + end +end +local quadratic=false +local function contours2outlines_normal(glyphs,shapes) + for index=0,#glyphs-1 do + local shape=shapes[index] + if shape then + local glyph=glyphs[index] + local contours=shape.contours + local points=shape.points + if contours then + local nofcontours=#contours + local segments={} + local nofsegments=0 + glyph.segments=segments + if nofcontours>0 then + local px=0 + local py=0 + local first=1 + for i=1,nofcontours do + local last=contours[i] + if last>=first then + local first_pt=points[first] + local first_on=first_pt[3] + if first==last then + first_pt[3]="m" + nofsegments=nofsegments+1 + segments[nofsegments]=first_pt + else + local first_on=first_pt[3] + local last_pt=points[last] + local last_on=last_pt[3] + local start=1 + local control_pt=false + if first_on then + start=2 + else + if last_on then + first_pt=last_pt + else + first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false } + end + control_pt=first_pt + end + local x=first_pt[1] + local y=first_pt[2] + if not done then + xmin=x + ymin=y + xmax=x + ymax=y + done=true + end + nofsegments=nofsegments+1 + segments[nofsegments]={ x,y,"m" } + if not quadratic then + px=x + py=y + end + local previous_pt=first_pt + for i=first,last do + local current_pt=points[i] + local current_on=current_pt[3] + local previous_on=previous_pt[3] + if previous_on then + if current_on then + local x,y=current_pt[1],current_pt[2] + nofsegments=nofsegments+1 + segments[nofsegments]={ x,y,"l" } + if not quadratic then + px,py=x,y + end + else + control_pt=current_pt + end + elseif current_on then + local x1=control_pt[1] + local y1=control_pt[2] + local x2=current_pt[1] + local y2=current_pt[2] + nofsegments=nofsegments+1 + if quadratic then + segments[nofsegments]={ x1,y1,x2,y2,"q" } + else + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + control_pt=false + else + local x2=(previous_pt[1]+current_pt[1])/2 + local y2=(previous_pt[2]+current_pt[2])/2 + local x1=control_pt[1] + local y1=control_pt[2] + nofsegments=nofsegments+1 + if quadratic then + segments[nofsegments]={ x1,y1,x2,y2,"q" } + else + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + control_pt=current_pt + end + previous_pt=current_pt + end + if first_pt==last_pt then + else + nofsegments=nofsegments+1 + local x2=first_pt[1] + local y2=first_pt[2] + if not control_pt then + segments[nofsegments]={ x2,y2,"l" } + elseif quadratic then + local x1=control_pt[1] + local y1=control_pt[2] + segments[nofsegments]={ x1,y1,x2,y2,"q" } + else + local x1=control_pt[1] + local y1=control_pt[2] + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + end + end + end + first=last+1 + end + end + end + end + end +end +local function contours2outlines_shaped(glyphs,shapes,keepcurve) + for index=0,#glyphs-1 do + local shape=shapes[index] + if shape then + local glyph=glyphs[index] + local contours=shape.contours + local points=shape.points + if contours then + local nofcontours=#contours + local segments=keepcurve and {} or nil + local nofsegments=0 + if keepcurve then + glyph.segments=segments + end + if nofcontours>0 then + local xmin,ymin,xmax,ymax,done=0,0,0,0,false + local px,py=0,0 + local first=1 + for i=1,nofcontours do + local last=contours[i] + if last>=first then + local first_pt=points[first] + local first_on=first_pt[3] + if first==last then + if keepcurve then + first_pt[3]="m" + nofsegments=nofsegments+1 + segments[nofsegments]=first_pt + end + else + local first_on=first_pt[3] + local last_pt=points[last] + local last_on=last_pt[3] + local start=1 + local control_pt=false + if first_on then + start=2 + else + if last_on then + first_pt=last_pt + else + first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false } + end + control_pt=first_pt + end + local x=first_pt[1] + local y=first_pt[2] + if not done then + xmin,ymin,xmax,ymax=x,y,x,y + done=true + else + if xxmax then xmax=x end + if yymax then ymax=y end + end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x,y,"m" } + end + if not quadratic then + px=x + py=y + end + local previous_pt=first_pt + for i=first,last do + local current_pt=points[i] + local current_on=current_pt[3] + local previous_on=previous_pt[3] + if previous_on then + if current_on then + local x=current_pt[1] + local y=current_pt[2] + if xxmax then xmax=x end + if yymax then ymax=y end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x,y,"l" } + end + if not quadratic then + px=x + py=y + end + else + control_pt=current_pt + end + elseif current_on then + local x1=control_pt[1] + local y1=control_pt[2] + local x2=current_pt[1] + local y2=current_pt[2] + if quadratic then + if x1xmax then xmax=x1 end + if y1ymax then ymax=y1 end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,"q" } + end + else + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + if x1xmax then xmax=x1 end + if y1ymax then ymax=y1 end + if x2xmax then xmax=x2 end + if y2ymax then ymax=y2 end + if pxxmax then xmax=px end + if pyymax then ymax=py end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + end + control_pt=false + else + local x2=(previous_pt[1]+current_pt[1])/2 + local y2=(previous_pt[2]+current_pt[2])/2 + local x1=control_pt[1] + local y1=control_pt[2] + if quadratic then + if x1xmax then xmax=x1 end + if y1ymax then ymax=y1 end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,"q" } + end + else + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + if x1xmax then xmax=x1 end + if y1ymax then ymax=y1 end + if x2xmax then xmax=x2 end + if y2ymax then ymax=y2 end + if pxxmax then xmax=px end + if pyymax then ymax=py end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + end + control_pt=current_pt + end + previous_pt=current_pt + end + if first_pt==last_pt then + elseif not control_pt then + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ first_pt[1],first_pt[2],"l" } + end + else + local x1=control_pt[1] + local y1=control_pt[2] + local x2=first_pt[1] + local y2=first_pt[2] + if x1xmax then xmax=x1 end + if y1ymax then ymax=y1 end + if quadratic then + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,"q" } + end + else + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + if x2xmax then xmax=x2 end + if y2ymax then ymax=y2 end + if pxxmax then xmax=px end + if pyymax then ymax=py end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + end + end + end + end + first=last+1 + end + glyph.boundingbox={ round(xmin),round(ymin),round(xmax),round(ymax) } + end + end + end + end +end +local c_zero=char(0) +local s_zero=char(0,0) +local function toushort(n) + return char(band(rshift(n,8),0xFF),band(n,0xFF)) +end +local function toshort(n) + if n<0 then + n=n+0x10000 + end + return char(band(rshift(n,8),0xFF),band(n,0xFF)) +end +local chars=setmetatableindex(function(t,k) + for i=0,255 do local v=char(i) t[i]=v end return t[k] +end) +local function repackpoints(glyphs,shapes) + local noboundingbox={ 0,0,0,0 } + local result={} + local xpoints={} + local ypoints={} + for index=0,#glyphs do + local shape=shapes[index] + if shape then + local r=0 + local glyph=glyphs[index] + local contours=shape.contours + local nofcontours=contours and #contours or 0 + local boundingbox=glyph.boundingbox or noboundingbox + r=r+1 result[r]=toshort(nofcontours) + r=r+1 result[r]=toshort(boundingbox[1]) + r=r+1 result[r]=toshort(boundingbox[2]) + r=r+1 result[r]=toshort(boundingbox[3]) + r=r+1 result[r]=toshort(boundingbox[4]) + if nofcontours>0 then + for i=1,nofcontours do + r=r+1 result[r]=toshort(contours[i]-1) + end + r=r+1 result[r]=s_zero + local points=shape.points + local currentx=0 + local currenty=0 + local x=0 + local y=0 + local lastflag=nil + local nofflags=0 + for i=1,#points do + local pt=points[i] + local px=pt[1] + local py=pt[2] + local fl=pt[3] and 0x01 or 0x00 + if px==currentx then + fl=fl+0x10 + else + local dx=round(px-currentx) + x=x+1 + if dx<-255 or dx>255 then + xpoints[x]=toshort(dx) + elseif dx<0 then + fl=fl+0x02 + xpoints[x]=chars[-dx] + elseif dx>0 then + fl=fl+0x12 + xpoints[x]=chars[dx] + else + fl=fl+0x02 + xpoints[x]=c_zero + end + end + if py==currenty then + fl=fl+0x20 + else + local dy=round(py-currenty) + y=y+1 + if dy<-255 or dy>255 then + ypoints[y]=toshort(dy) + elseif dy<0 then + fl=fl+0x04 + ypoints[y]=chars[-dy] + elseif dy>0 then + fl=fl+0x24 + ypoints[y]=chars[dy] + else + fl=fl+0x04 + ypoints[y]=c_zero + end + end + currentx=px + currenty=py + if lastflag==fl then + if nofflags==255 then + lastflag=lastflag+0x08 + r=r+1 result[r]=char(lastflag,nofflags-1) + nofflags=1 + lastflag=fl + else + nofflags=nofflags+1 + end + else + if nofflags==1 then + r=r+1 result[r]=chars[lastflag] + elseif nofflags==2 then + r=r+1 result[r]=char(lastflag,lastflag) + elseif nofflags>2 then + lastflag=lastflag+0x08 + r=r+1 result[r]=char(lastflag,nofflags-1) + end + nofflags=1 + lastflag=fl + end + end + if nofflags==1 then + r=r+1 result[r]=chars[lastflag] + elseif nofflags==2 then + r=r+1 result[r]=char(lastflag,lastflag) + elseif nofflags>2 then + lastflag=lastflag+0x08 + r=r+1 result[r]=char(lastflag,nofflags-1) + end + r=r+1 result[r]=concat(xpoints,"",1,x) + r=r+1 result[r]=concat(ypoints,"",1,y) + end + local stream=concat(result,"",1,r) + local length=#stream + local padding=idiv(length+3,4)*4-length + if padding>0 then + if padding==1 then + padding="\0" + elseif padding==2 then + padding="\0\0" + else + padding="\0\0\0" + end + padding=stream..padding + end + glyph.stream=stream + end + end +end +local flags={} +local function readglyph(f,nofcontours) + local points={} + local contours={} + for i=1,nofcontours do + contours[i]=readshort(f)+1 + end + local nofpoints=contours[nofcontours] + local nofinstructions=readushort(f) + skipbytes(f,nofinstructions) + local i=1 + while i<=nofpoints do + local flag=readbyte(f) + flags[i]=flag + if band(flag,0x08)~=0 then + local n=readbyte(f) + if n==1 then + i=i+1 + flags[i]=flag + else + for j=1,n do + i=i+1 + flags[i]=flag + end + end + end + i=i+1 + end + local x=0 + for i=1,nofpoints do + local flag=flags[i] + if band(flag,0x02)~=0 then + if band(flag,0x10)~=0 then + x=x+readbyte(f) + else + x=x-readbyte(f) + end + elseif band(flag,0x10)~=0 then + else + x=x+readshort(f) + end + points[i]={ x,0,band(flag,0x01)~=0 } + end + local y=0 + for i=1,nofpoints do + local flag=flags[i] + if band(flag,0x04)~=0 then + if band(flag,0x20)~=0 then + y=y+readbyte(f) + else + y=y-readbyte(f) + end + elseif band(flag,0x20)~=0 then + else + y=y+readshort(f) + end + points[i][2]=y + end + return { + type="glyph", + points=points, + contours=contours, + nofpoints=nofpoints, + } +end +local function readcomposite(f) + local components={} + local nofcomponents=0 + local instructions=false + while true do + local flags=readushort(f) + local index=readushort(f) + local f_xyarg=band(flags,0x0002)~=0 + local f_offset=band(flags,0x0800)~=0 + local xscale=1 + local xrotate=0 + local yrotate=0 + local yscale=1 + local xoffset=0 + local yoffset=0 + local base=false + local reference=false + if f_xyarg then + if band(flags,0x0001)~=0 then + xoffset=readshort(f) + yoffset=readshort(f) + else + xoffset=readchar(f) + yoffset=readchar(f) + end + else + if band(flags,0x0001)~=0 then + base=readshort(f) + reference=readshort(f) + else + base=readchar(f) + reference=readchar(f) + end + end + if band(flags,0x0008)~=0 then + xscale=read2dot14(f) + yscale=xscale + if f_xyarg and f_offset then + xoffset=xoffset*xscale + yoffset=yoffset*yscale + end + elseif band(flags,0x0040)~=0 then + xscale=read2dot14(f) + yscale=read2dot14(f) + if f_xyarg and f_offset then + xoffset=xoffset*xscale + yoffset=yoffset*yscale + end + elseif band(flags,0x0080)~=0 then + xscale=read2dot14(f) + xrotate=read2dot14(f) + yrotate=read2dot14(f) + yscale=read2dot14(f) + if f_xyarg and f_offset then + xoffset=xoffset*sqrt(xscale^2+xrotate^2) + yoffset=yoffset*sqrt(yrotate^2+yscale^2) + end + end + nofcomponents=nofcomponents+1 + components[nofcomponents]={ + index=index, + usemine=band(flags,0x0200)~=0, + round=band(flags,0x0006)~=0, + base=base, + reference=reference, + matrix={ xscale,xrotate,yrotate,yscale,xoffset,yoffset }, + } + if band(flags,0x0100)~=0 then + instructions=true + end + if band(flags,0x0020)==0 then + break + end + end + return { + type="composite", + components=components, + } +end +function readers.loca(f,fontdata,specification) + if specification.glyphs then + local datatable=fontdata.tables.loca + if datatable then + local offset=fontdata.tables.glyf.offset + local format=fontdata.fontheader.indextolocformat + local profile=fontdata.maximumprofile + local nofglyphs=profile and profile.nofglyphs + local locations={} + setposition(f,datatable.offset) + if format==1 then + if not nofglyphs then + nofglyphs=idiv(datatable.length,4)-1 + end + for i=0,nofglyphs do + locations[i]=offset+readulong(f) + end + fontdata.nofglyphs=nofglyphs + else + if not nofglyphs then + nofglyphs=idiv(datatable.length,2)-1 + end + for i=0,nofglyphs do + locations[i]=offset+readushort(f)*2 + end + end + fontdata.nofglyphs=nofglyphs + fontdata.locations=locations + end + end +end +function readers.glyf(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"glyf",specification.glyphs) + if tableoffset then + local locations=fontdata.locations + if locations then + local glyphs=fontdata.glyphs + local nofglyphs=fontdata.nofglyphs + local filesize=fontdata.filesize + local nothing={ 0,0,0,0 } + local shapes={} + local loadshapes=specification.shapes or specification.instance or specification.streams + for index=0,nofglyphs-1 do + local location=locations[index] + local length=locations[index+1]-location + if location>=filesize then + report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1) + fontdata.nofglyphs=index-1 + fontdata.badfont=true + break + elseif length>0 then + setposition(f,location) + local nofcontours=readshort(f) + glyphs[index].boundingbox={ + readshort(f), + readshort(f), + readshort(f), + readshort(f), + } + if not loadshapes then + elseif nofcontours==0 then + shapes[index]=readnothing(f) + elseif nofcontours>0 then + shapes[index]=readglyph(f,nofcontours) + else + shapes[index]=readcomposite(f,nofcontours) + end + else + if loadshapes then + shapes[index]=readnothing(f) + end + glyphs[index].boundingbox=nothing + end + end + if loadshapes then + if readers.gvar then + readers.gvar(f,fontdata,specification,glyphs,shapes) + end + mergecomposites(glyphs,shapes) + if specification.instance then + if specification.streams then + repackpoints(glyphs,shapes) + else + contours2outlines_shaped(glyphs,shapes,specification.shapes) + end + elseif specification.shapes then + if specification.streams then + repackpoints(glyphs,shapes) + else + contours2outlines_normal(glyphs,shapes) + end + elseif specification.streams then + repackpoints(glyphs,shapes) + end + end + end + end +end +local function readtuplerecord(f,nofaxis) + local record={} + for i=1,nofaxis do + record[i]=read2dot14(f) + end + return record +end +local function readpoints(f) + local count=readbyte(f) + if count==0 then + return nil,0 + else + if count<128 then + elseif band(count,0x80)~=0 then + count=band(count,0x7F)*256+readbyte(f) + else + end + local points={} + local p=0 + local n=1 + while p0 do + local control=readbyte(f) +if not control then + break +end + local allzero=band(control,0x80)~=0 + local runlength=band(control,0x3F)+1 + if allzero then + z=z+runlength + else + local runreader=band(control,0x40)~=0 and readshort or readinteger + if z>0 then + for i=1,z do + p=p+1 + deltas[p]=0 + end + z=0 + end + for i=1,runlength do + p=p+1 + deltas[p]=runreader(f) + end + end + nofpoints=nofpoints-runlength + end + if p>0 then + return deltas + else + end +end +local function readdeltas(f,nofpoints) + local deltas={} + local p=0 + while nofpoints>0 do + local control=readbyte(f) + if control then + local allzero=band(control,0x80)~=0 + local runlength=band(control,0x3F)+1 + if allzero then + for i=1,runlength do + p=p+1 + deltas[p]=0 + end + else + local runreader=band(control,0x40)~=0 and readshort or readinteger + for i=1,runlength do + p=p+1 + deltas[p]=runreader(f) + end + end + nofpoints=nofpoints-runlength + else + break + end + end + if p>0 then + return deltas + else + end +end +function readers.gvar(f,fontdata,specification,glyphdata,shapedata) + local instance=specification.instance + if not instance then + return + end + local factors=specification.factors + if not factors then + return + end + local tableoffset=gotodatatable(f,fontdata,"gvar",specification.variable or specification.shapes) + if tableoffset then + local version=readulong(f) + local nofaxis=readushort(f) + local noftuples=readushort(f) + local tupleoffset=tableoffset+readulong(f) + local nofglyphs=readushort(f) + local flags=readushort(f) + local dataoffset=tableoffset+readulong(f) + local data={} + local tuples={} + local glyphdata=fontdata.glyphs + local dowidth=not fontdata.variabledata.hvarwidths + if band(flags,0x0001)~=0 then + for i=1,nofglyphs+1 do + data[i]=dataoffset+readulong(f) + end + else + for i=1,nofglyphs+1 do + data[i]=dataoffset+2*readushort(f) + end + end + if noftuples>0 then + setposition(f,tupleoffset) + for i=1,noftuples do + tuples[i]=readtuplerecord(f,nofaxis) + end + end + local nextoffset=false + local startoffset=data[1] + for i=1,nofglyphs do + nextoffset=data[i+1] + local glyph=glyphdata[i-1] + local name=trace_deltas and glyph.name + if startoffset==nextoffset then + if name then + report("no deltas for glyph %a",name) + end + else + local shape=shapedata[i-1] + if not shape then + if name then + report("no shape for glyph %a",name) + end + else + lastoffset=startoffset + setposition(f,startoffset) + local flags=readushort(f) + local count=band(flags,0x0FFF) + local offset=startoffset+readushort(f) + local deltas={} + local allpoints=(shape.nofpoints or 0) + local shared=false + local nofshared=0 + if band(flags,0x8000)~=0 then + local current=getposition(f) + setposition(f,offset) + shared,nofshared=readpoints(f) + offset=getposition(f) + setposition(f,current) + end + for j=1,count do + local size=readushort(f) + local flags=readushort(f) + local index=band(flags,0x0FFF) + local haspeak=band(flags,0x8000)~=0 + local intermediate=band(flags,0x4000)~=0 + local private=band(flags,0x2000)~=0 + local peak=nil + local start=nil + local stop=nil + local xvalues=nil + local yvalues=nil + local points=shared + local nofpoints=nofshared + if haspeak then + peak=readtuplerecord(f,nofaxis) + else + if index+1>#tuples then + report("error, bad tuple index",index) + end + peak=tuples[index+1] + end + if intermediate then + start=readtuplerecord(f,nofaxis) + stop=readtuplerecord(f,nofaxis) + end + if size>0 then + local current=getposition(f) + setposition(f,offset) + if private then + points,nofpoints=readpoints(f) + end + if nofpoints==0 then + nofpoints=allpoints+4 + end + if nofpoints>0 then + xvalues=readdeltas(f,nofpoints) + yvalues=readdeltas(f,nofpoints) + end + offset=offset+size + setposition(f,current) + end + if not xvalues and not yvalues then + points=nil + end + local s=1 + for i=1,nofaxis do + local f=factors[i] + local peak=peak and peak [i] or 0 + local start=start and start[i] or (peak<0 and peak or 0) + local stop=stop and stop [i] or (peak>0 and peak or 0) + if start>peak or peak>stop then + elseif start<0 and stop>0 and peak~=0 then + elseif peak==0 then + elseif fstop then + s=0 + break + elseif fpeak then + s=s*(stop-f)/(stop-peak) + else + end + end + if s==0 then + if name then + report("no deltas applied for glyph %a",name) + end + else + deltas[#deltas+1]={ + factor=s, + points=points, + xvalues=xvalues, + yvalues=yvalues, + } + end + end + if shape.type=="glyph" then + applyaxis(glyph,shape,deltas,dowidth) + else + shape.deltas=deltas + end + end + end + startoffset=nextoffset + end + end +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-ttf”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-dsp” 174ce11f3ba0bddf270f48d8d2addd56] --- + +if not modules then modules={} end modules ['font-dsp']={ + version=1.001, + optimize=true, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next,type,tonumber=next,type,tonumber +local band=bit32.band +local extract=bit32.extract +local bor=bit32.bor +local lshift=bit32.lshift +local rshift=bit32.rshift +local gsub=string.gsub +local lower=string.lower +local sub=string.sub +local strip=string.strip +local tohash=table.tohash +local concat=table.concat +local copy=table.copy +local reversed=table.reversed +local sort=table.sort +local insert=table.insert +local round=math.round +local settings_to_hash=utilities.parsers.settings_to_hash_colon_too +local setmetatableindex=table.setmetatableindex +local formatters=string.formatters +local sortedkeys=table.sortedkeys +local sortedhash=table.sortedhash +local sequenced=table.sequenced +local report=logs.reporter("otf reader") +local readers=fonts.handlers.otf.readers +local streamreader=readers.streamreader +local setposition=streamreader.setposition +local getposition=streamreader.getposition +local readuinteger=streamreader.readcardinal1 +local readushort=streamreader.readcardinal2 +local readulong=streamreader.readcardinal4 +local readinteger=streamreader.readinteger1 +local readshort=streamreader.readinteger2 +local readstring=streamreader.readstring +local readtag=streamreader.readtag +local readbytes=streamreader.readbytes +local readfixed=streamreader.readfixed4 +local read2dot14=streamreader.read2dot14 +local skipshort=streamreader.skipshort +local skipbytes=streamreader.skip +local readbytetable=streamreader.readbytetable +local readbyte=streamreader.readbyte +local readcardinaltable=streamreader.readcardinaltable +local readintegertable=streamreader.readintegertable +local readfword=readshort +local short=2 +local ushort=2 +local ulong=4 +directives.register("fonts.streamreader",function() + streamreader=utilities.streams + setposition=streamreader.setposition + getposition=streamreader.getposition + readuinteger=streamreader.readcardinal1 + readushort=streamreader.readcardinal2 + readulong=streamreader.readcardinal4 + readinteger=streamreader.readinteger1 + readshort=streamreader.readinteger2 + readstring=streamreader.readstring + readtag=streamreader.readtag + readbytes=streamreader.readbytes + readfixed=streamreader.readfixed4 + read2dot14=streamreader.read2dot14 + skipshort=streamreader.skipshort + skipbytes=streamreader.skip + readbytetable=streamreader.readbytetable + readbyte=streamreader.readbyte + readcardinaltable=streamreader.readcardinaltable + readintegertable=streamreader.readintegertable + readfword=readshort +end) +local gsubhandlers={} +local gposhandlers={} +readers.gsubhandlers=gsubhandlers +readers.gposhandlers=gposhandlers +local helpers=readers.helpers +local gotodatatable=helpers.gotodatatable +local setvariabledata=helpers.setvariabledata +local lookupidoffset=-1 +local classes={ + "base", + "ligature", + "mark", + "component", +} +local gsubtypes={ + "single", + "multiple", + "alternate", + "ligature", + "context", + "chainedcontext", + "extension", + "reversechainedcontextsingle", +} +local gpostypes={ + "single", + "pair", + "cursive", + "marktobase", + "marktoligature", + "marktomark", + "context", + "chainedcontext", + "extension", +} +local chaindirections={ + context=0, + chainedcontext=1, + reversechainedcontextsingle=-1, +} +local function setmetrics(data,where,tag,d) + local w=data[where] + if w then + local v=w[tag] + if v then + w[tag]=v+d + end + end +end +local variabletags={ + hasc=function(data,d) setmetrics(data,"windowsmetrics","typoascender",d) end, + hdsc=function(data,d) setmetrics(data,"windowsmetrics","typodescender",d) end, + hlgp=function(data,d) setmetrics(data,"windowsmetrics","typolinegap",d) end, + hcla=function(data,d) setmetrics(data,"windowsmetrics","winascent",d) end, + hcld=function(data,d) setmetrics(data,"windowsmetrics","windescent",d) end, + vasc=function(data,d) setmetrics(data,"vhea not done","ascent",d) end, + vdsc=function(data,d) setmetrics(data,"vhea not done","descent",d) end, + vlgp=function(data,d) setmetrics(data,"vhea not done","linegap",d) end, + xhgt=function(data,d) setmetrics(data,"windowsmetrics","xheight",d) end, + cpht=function(data,d) setmetrics(data,"windowsmetrics","capheight",d) end, + sbxs=function(data,d) setmetrics(data,"windowsmetrics","subscriptxsize",d) end, + sbys=function(data,d) setmetrics(data,"windowsmetrics","subscriptysize",d) end, + sbxo=function(data,d) setmetrics(data,"windowsmetrics","subscriptxoffset",d) end, + sbyo=function(data,d) setmetrics(data,"windowsmetrics","subscriptyoffset",d) end, + spxs=function(data,d) setmetrics(data,"windowsmetrics","superscriptxsize",d) end, + spys=function(data,d) setmetrics(data,"windowsmetrics","superscriptysize",d) end, + spxo=function(data,d) setmetrics(data,"windowsmetrics","superscriptxoffset",d) end, + spyo=function(data,d) setmetrics(data,"windowsmetrics","superscriptyoffset",d) end, + strs=function(data,d) setmetrics(data,"windowsmetrics","strikeoutsize",d) end, + stro=function(data,d) setmetrics(data,"windowsmetrics","strikeoutpos",d) end, + unds=function(data,d) setmetrics(data,"postscript","underlineposition",d) end, + undo=function(data,d) setmetrics(data,"postscript","underlinethickness",d) end, +} +local read_cardinal={ + streamreader.readcardinal1, + streamreader.readcardinal2, + streamreader.readcardinal3, + streamreader.readcardinal4, +} +local read_integer={ + streamreader.readinteger1, + streamreader.readinteger2, + streamreader.readinteger3, + streamreader.readinteger4, +} +local lookupnames={ + gsub={ + single="gsub_single", + multiple="gsub_multiple", + alternate="gsub_alternate", + ligature="gsub_ligature", + context="gsub_context", + chainedcontext="gsub_contextchain", + reversechainedcontextsingle="gsub_reversecontextchain", + }, + gpos={ + single="gpos_single", + pair="gpos_pair", + cursive="gpos_cursive", + marktobase="gpos_mark2base", + marktoligature="gpos_mark2ligature", + marktomark="gpos_mark2mark", + context="gpos_context", + chainedcontext="gpos_contextchain", + } +} +local lookupflags=setmetatableindex(function(t,k) + local v={ + band(k,0x0008)~=0 and true or false, + band(k,0x0004)~=0 and true or false, + band(k,0x0002)~=0 and true or false, + band(k,0x0001)~=0 and true or false, + } + t[k]=v + return v +end) +local function axistofactors(str) + local t=settings_to_hash(str) + for k,v in next,t do + t[k]=tonumber(v) or v + end + return t +end +local hash=table.setmetatableindex(function(t,k) + local v=sequenced(axistofactors(k),",") + t[k]=v + return v +end) +helpers.normalizedaxishash=hash +local cleanname=fonts.names and fonts.names.cleanname or function(name) + return name and (gsub(lower(name),"[^%a%d]","")) or nil +end +helpers.cleanname=cleanname +function helpers.normalizedaxis(str) + return hash[str] or str +end +local function getaxisscale(segments,minimum,default,maximum,user) + if not minimum or not default or not maximum then + return false + end + if usermaximum then + user=maximum + end + if userdefault then + default=(user-default)/(maximum-default) + else + default=0 + end + if not segments then + return default + end + local e + for i=1,#segments do + local s=segments[i] + if type(s)~="number" then + report("using default axis scale") + return default + elseif s[1]>=default then + if s[2]==default then + return default + else + e=i + break + end + end + end + if e then + local b=segments[e-1] + local e=segments[e] + return b[2]+(e[2]-b[2])*(default-b[1])/(e[1]-b[1]) + else + return false + end +end +local function getfactors(data,instancespec) + if instancespec==true then + elseif type(instancespec)~="string" or instancespec=="" then + return + end + local variabledata=data.variabledata + if not variabledata then + return + end + local instances=variabledata.instances + local axis=variabledata.axis + local segments=variabledata.segments + if instances and axis then + local values + if instancespec==true then + values={} + for i=1,#axis do + values[i]={ + value=axis[i].default, + } + end + else + for i=1,#instances do + local instance=instances[i] + if cleanname(instance.subfamily)==instancespec then + values=instance.values + break + end + end + end + if values then + local factors={} + for i=1,#axis do + local a=axis[i] + factors[i]=getaxisscale(segments,a.minimum,a.default,a.maximum,values[i].value) + end + return factors + end + local values=axistofactors(hash[instancespec] or instancespec) + if values then + local factors={} + for i=1,#axis do + local a=axis[i] + local d=a.default + factors[i]=getaxisscale(segments,a.minimum,d,a.maximum,values[a.name or a.tag] or d) + end + return factors + end + end +end +local function getscales(regions,factors) + local scales={} + for i=1,#regions do + local region=regions[i] + local s=1 + for j=1,#region do + local axis=region[j] + local f=factors[j] + local start=axis.start + local peak=axis.peak + local stop=axis.stop + if start>peak or peak>stop then + elseif start<0 and stop>0 and peak~=0 then + elseif peak==0 then + elseif fstop then + s=0 + break + elseif fpeak then + s=s*(stop-f)/(stop-peak) + else + end + end + scales[i]=s + end + return scales +end +helpers.getaxisscale=getaxisscale +helpers.getfactors=getfactors +helpers.getscales=getscales +helpers.axistofactors=axistofactors +local function readvariationdata(f,storeoffset,factors) + local position=getposition(f) + setposition(f,storeoffset) + local format=readushort(f) + local regionoffset=storeoffset+readulong(f) + local nofdeltadata=readushort(f) + local deltadata=readcardinaltable(f,nofdeltadata,ulong) + setposition(f,regionoffset) + local nofaxis=readushort(f) + local nofregions=readushort(f) + local regions={} + for i=1,nofregions do + local t={} + for i=1,nofaxis do + t[i]={ + start=read2dot14(f), + peak=read2dot14(f), + stop=read2dot14(f), + } + end + regions[i]=t + end + for i=1,nofdeltadata do + setposition(f,storeoffset+deltadata[i]) + local nofdeltasets=readushort(f) + local nofshorts=readushort(f) + local nofregions=readushort(f) + local usedregions={} + local deltas={} + for i=1,nofregions do + usedregions[i]=regions[readushort(f)+1] + end + for i=1,nofdeltasets do + local t=readintegertable(f,nofshorts,short) + for i=nofshorts+1,nofregions do + t[i]=readinteger(f) + end + deltas[i]=t + end + deltadata[i]={ + regions=usedregions, + deltas=deltas, + scales=factors and getscales(usedregions,factors) or nil, + } + end + setposition(f,position) + return regions,deltadata +end +helpers.readvariationdata=readvariationdata +local function readcoverage(f,offset,simple) + setposition(f,offset) + local coverageformat=readushort(f) + if coverageformat==1 then + local nofcoverage=readushort(f) + if simple then + if nofcoverage==1 then + return { readushort(f) } + elseif nofcoverage==2 then + return { readushort(f),readushort(f) } + else + return readcardinaltable(f,nofcoverage,ushort) + end + elseif nofcoverage==1 then + return { [readushort(f)]=0 } + elseif nofcoverage==2 then + return { [readushort(f)]=0,[readushort(f)]=1 } + else + local coverage={} + for i=0,nofcoverage-1 do + coverage[readushort(f)]=i + end + return coverage + end + elseif coverageformat==2 then + local nofranges=readushort(f) + local coverage={} + local n=simple and 1 or 0 + for i=1,nofranges do + local firstindex=readushort(f) + local lastindex=readushort(f) + local coverindex=readushort(f) + if simple then + for i=firstindex,lastindex do + coverage[n]=i + n=n+1 + end + else + for i=firstindex,lastindex do + coverage[i]=n + n=n+1 + end + end + end + return coverage + else + report("unknown coverage format %a ",coverageformat) + return {} + end +end +local function readclassdef(f,offset,preset) + setposition(f,offset) + local classdefformat=readushort(f) + local classdef={} + if type(preset)=="number" then + for k=0,preset-1 do + classdef[k]=1 + end + end + if classdefformat==1 then + local index=readushort(f) + local nofclassdef=readushort(f) + for i=1,nofclassdef do + classdef[index]=readushort(f)+1 + index=index+1 + end + elseif classdefformat==2 then + local nofranges=readushort(f) + local n=0 + for i=1,nofranges do + local firstindex=readushort(f) + local lastindex=readushort(f) + local class=readushort(f)+1 + for i=firstindex,lastindex do + classdef[i]=class + end + end + else + report("unknown classdef format %a ",classdefformat) + end + if type(preset)=="table" then + for k in next,preset do + if not classdef[k] then + classdef[k]=1 + end + end + end + return classdef +end +local function classtocoverage(defs) + if defs then + local list={} + for index,class in next,defs do + local c=list[class] + if c then + c[#c+1]=index + else + list[class]={ index } + end + end + return list + end +end +local skips={ [0]=0, + 1, + 1, + 2, + 1, + 2, + 2, + 3, + 2, + 2, + 3, + 2, + 3, + 3, + 4, +} +local function readvariation(f,offset) + local p=getposition(f) + setposition(f,offset) + local outer=readushort(f) + local inner=readushort(f) + local format=readushort(f) + setposition(f,p) + if format==0x8000 then + return outer,inner + end +end +local function readposition(f,format,mainoffset,getdelta) + if format==0 then + return false + end + if format==0x04 then + local h=readshort(f) + if h==0 then + return true + else + return { 0,0,h,0 } + end + end + if format==0x05 then + local x=readshort(f) + local h=readshort(f) + if x==0 and h==0 then + return true + else + return { x,0,h,0 } + end + end + if format==0x44 then + local h=readshort(f) + if getdelta then + local d=readshort(f) + if d>0 then + local outer,inner=readvariation(f,mainoffset+d) + if outer then + h=h+getdelta(outer,inner) + end + end + else + skipshort(f,1) + end + if h==0 then + return true + else + return { 0,0,h,0 } + end + end + local x=band(format,0x1)~=0 and readshort(f) or 0 + local y=band(format,0x2)~=0 and readshort(f) or 0 + local h=band(format,0x4)~=0 and readshort(f) or 0 + local v=band(format,0x8)~=0 and readshort(f) or 0 + if format>=0x10 then + local X=band(format,0x10)~=0 and skipshort(f) or 0 + local Y=band(format,0x20)~=0 and skipshort(f) or 0 + local H=band(format,0x40)~=0 and skipshort(f) or 0 + local V=band(format,0x80)~=0 and skipshort(f) or 0 + local s=skips[extract(format,4,4)] + if s>0 then + skipshort(f,s) + end + if getdelta then + if X>0 then + local outer,inner=readvariation(f,mainoffset+X) + if outer then + x=x+getdelta(outer,inner) + end + end + if Y>0 then + local outer,inner=readvariation(f,mainoffset+Y) + if outer then + y=y+getdelta(outer,inner) + end + end + if H>0 then + local outer,inner=readvariation(f,mainoffset+H) + if outer then + h=h+getdelta(outer,inner) + end + end + if V>0 then + local outer,inner=readvariation(f,mainoffset+V) + if outer then + v=v+getdelta(outer,inner) + end + end + end + return { x,y,h,v } + elseif x==0 and y==0 and h==0 and v==0 then + return true + else + return { x,y,h,v } + end +end +local function readanchor(f,offset,getdelta) + if not offset or offset==0 then + return nil + end + setposition(f,offset) + local format=readshort(f) + local x=readshort(f) + local y=readshort(f) + if format==3 then + if getdelta then + local X=readshort(f) + local Y=readshort(f) + if X>0 then + local outer,inner=readvariation(f,offset+X) + if outer then + x=x+getdelta(outer,inner) + end + end + if Y>0 then + local outer,inner=readvariation(f,offset+Y) + if outer then + y=y+getdelta(outer,inner) + end + end + else + skipshort(f,2) + end + return { x,y } + else + return { x,y } + end +end +local function readfirst(f,offset) + if offset then + setposition(f,offset) + end + return { readushort(f) } +end +local function readarray(f,offset) + if offset then + setposition(f,offset) + end + local n=readushort(f) + if n==1 then + return { readushort(f) },1 + elseif n>0 then + return readcardinaltable(f,n,ushort),n + end +end +local function readcoveragearray(f,offset,t,simple) + if not t then + return nil + end + local n=#t + if n==0 then + return nil + end + for i=1,n do + t[i]=readcoverage(f,offset+t[i],simple) + end + return t +end +local function covered(subset,all) + local used,u + for i=1,#subset do + local s=subset[i] + if all[s] then + if used then + u=u+1 + used[u]=s + else + u=1 + used={ s } + end + end + end + return used +end +local function readlookuparray(f,noflookups,nofcurrent) + local lookups={} + if noflookups>0 then + local length=0 + for i=1,noflookups do + local index=readushort(f)+1 + if index>length then + length=index + end + local lookup=readushort(f)+1 + local list=lookups[index] + if list then + list[#list+1]=lookup + else + lookups[index]={ lookup } + end + end + for index=1,length do + if not lookups[index] then + lookups[index]=false + end + end + end + return lookups +end +local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local coverage=readushort(f) + local subclasssets=readarray(f) + local rules={} + if subclasssets then + coverage=readcoverage(f,tableoffset+coverage,true) + for i=1,#subclasssets do + local offset=subclasssets[i] + if offset>0 then + local firstcoverage=coverage[i] + local rulesoffset=tableoffset+offset + local subclassrules=readarray(f,rulesoffset) + for rule=1,#subclassrules do + setposition(f,rulesoffset+subclassrules[rule]) + local nofcurrent=readushort(f) + local noflookups=readushort(f) + local current={ { firstcoverage } } + for i=2,nofcurrent do + current[i]={ readushort(f) } + end + local lookups=readlookuparray(f,noflookups,nofcurrent) + rules[#rules+1]={ + current=current, + lookups=lookups + } + end + end + end + else + report("empty subclassset in %a subtype %i","unchainedcontext",subtype) + end + return { + format="glyphs", + rules=rules, + } + elseif subtype==2 then + local coverage=readushort(f) + local currentclassdef=readushort(f) + local subclasssets=readarray(f) + local rules={} + if subclasssets then + coverage=readcoverage(f,tableoffset+coverage) + currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage) + local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs) + for class=1,#subclasssets do + local offset=subclasssets[class] + if offset>0 then + local firstcoverage=currentclasses[class] + if firstcoverage then + firstcoverage=covered(firstcoverage,coverage) + if firstcoverage then + local rulesoffset=tableoffset+offset + local subclassrules=readarray(f,rulesoffset) + for rule=1,#subclassrules do + setposition(f,rulesoffset+subclassrules[rule]) + local nofcurrent=readushort(f) + local noflookups=readushort(f) + local current={ firstcoverage } + for i=2,nofcurrent do + current[i]=currentclasses[readushort(f)+1] + end + local lookups=readlookuparray(f,noflookups,nofcurrent) + rules[#rules+1]={ + current=current, + lookups=lookups + } + end + else + report("no coverage") + end + else + report("no coverage class") + end + end + end + else + report("empty subclassset in %a subtype %i","unchainedcontext",subtype) + end + return { + format="class", + rules=rules, + } + elseif subtype==3 then + local nofglyphs=readushort(f) + local noflookups=readushort(f) + local current=readcardinaltable(f,nofglyphs,ushort) + local lookups=readlookuparray(f,noflookups,#current) + current=readcoveragearray(f,tableoffset,current,true) + return { + format="coverage", + rules={ + { + current=current, + lookups=lookups, + } + } + } + else + report("unsupported subtype %a in %a %s",subtype,"unchainedcontext",what) + end +end +local function chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local coverage=readushort(f) + local subclasssets=readarray(f) + local rules={} + if subclasssets then + coverage=readcoverage(f,tableoffset+coverage,true) + for i=1,#subclasssets do + local offset=subclasssets[i] + if offset>0 then + local firstcoverage=coverage[i] + local rulesoffset=tableoffset+offset + local subclassrules=readarray(f,rulesoffset) + for rule=1,#subclassrules do + setposition(f,rulesoffset+subclassrules[rule]) + local nofbefore=readushort(f) + local before + if nofbefore>0 then + before={} + for i=1,nofbefore do + before[i]={ readushort(f) } + end + end + local nofcurrent=readushort(f) + local current={ { firstcoverage } } + for i=2,nofcurrent do + current[i]={ readushort(f) } + end + local nofafter=readushort(f) + local after + if nofafter>0 then + after={} + for i=1,nofafter do + after[i]={ readushort(f) } + end + end + local noflookups=readushort(f) + local lookups=readlookuparray(f,noflookups,nofcurrent) + rules[#rules+1]={ + before=before, + current=current, + after=after, + lookups=lookups, + } + end + end + end + else + report("empty subclassset in %a subtype %i","chainedcontext",subtype) + end + return { + format="glyphs", + rules=rules, + } + elseif subtype==2 then + local coverage=readushort(f) + local beforeclassdef=readushort(f) + local currentclassdef=readushort(f) + local afterclassdef=readushort(f) + local subclasssets=readarray(f) + local rules={} + if subclasssets then + local coverage=readcoverage(f,tableoffset+coverage) + local beforeclassdef=readclassdef(f,tableoffset+beforeclassdef,nofglyphs) + local currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage) + local afterclassdef=readclassdef(f,tableoffset+afterclassdef,nofglyphs) + local beforeclasses=classtocoverage(beforeclassdef,fontdata.glyphs) + local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs) + local afterclasses=classtocoverage(afterclassdef,fontdata.glyphs) + for class=1,#subclasssets do + local offset=subclasssets[class] + if offset>0 then + local firstcoverage=currentclasses[class] + if firstcoverage then + firstcoverage=covered(firstcoverage,coverage) + if firstcoverage then + local rulesoffset=tableoffset+offset + local subclassrules=readarray(f,rulesoffset) + for rule=1,#subclassrules do + setposition(f,rulesoffset+subclassrules[rule]) + local nofbefore=readushort(f) + local before + if nofbefore>0 then + before={} + for i=1,nofbefore do + before[i]=beforeclasses[readushort(f)+1] + end + end + local nofcurrent=readushort(f) + local current={ firstcoverage } + for i=2,nofcurrent do + current[i]=currentclasses[readushort(f)+1] + end + local nofafter=readushort(f) + local after + if nofafter>0 then + after={} + for i=1,nofafter do + after[i]=afterclasses[readushort(f)+1] + end + end + local noflookups=readushort(f) + local lookups=readlookuparray(f,noflookups,nofcurrent) + rules[#rules+1]={ + before=before, + current=current, + after=after, + lookups=lookups, + } + end + else + report("no coverage") + end + else + report("class is not covered") + end + end + end + else + report("empty subclassset in %a subtype %i","chainedcontext",subtype) + end + return { + format="class", + rules=rules, + } + elseif subtype==3 then + local before=readarray(f) + local current=readarray(f) + local after=readarray(f) + local noflookups=readushort(f) + local lookups=readlookuparray(f,noflookups,#current) + before=readcoveragearray(f,tableoffset,before,true) + current=readcoveragearray(f,tableoffset,current,true) + after=readcoveragearray(f,tableoffset,after,true) + return { + format="coverage", + rules={ + { + before=before, + current=current, + after=after, + lookups=lookups, + } + } + } + else + report("unsupported subtype %a in %a %s",subtype,"chainedcontext",what) + end +end +local function extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,types,handlers,what) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local lookuptype=types[readushort(f)] + local faroffset=readulong(f) + local handler=handlers[lookuptype] + if handler then + return handler(f,fontdata,lookupid,tableoffset+faroffset,0,glyphs,nofglyphs),lookuptype + else + report("no handler for lookuptype %a subtype %a in %s %s",lookuptype,subtype,what,"extension") + end + else + report("unsupported subtype %a in %s %s",subtype,what,"extension") + end +end +function gsubhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local coverage=readushort(f) + local delta=readshort(f) + local coverage=readcoverage(f,tableoffset+coverage) + for index in next,coverage do + local newindex=(index+delta)%65536 + if index>nofglyphs or newindex>nofglyphs then + report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs) + coverage[index]=nil + else + coverage[index]=newindex + end + end + return { + coverage=coverage + } + elseif subtype==2 then + local coverage=readushort(f) + local nofreplacements=readushort(f) + local replacements=readcardinaltable(f,nofreplacements,ushort) + local coverage=readcoverage(f,tableoffset+coverage) + for index,newindex in next,coverage do + newindex=newindex+1 + if index>nofglyphs or newindex>nofglyphs then + report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs) + coverage[index]=nil + else + coverage[index]=replacements[newindex] + end + end + return { + coverage=coverage + } + else + report("unsupported subtype %a in %a substitution",subtype,"single") + end +end +local function sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local coverage=readushort(f) + local nofsequence=readushort(f) + local sequences=readcardinaltable(f,nofsequence,ushort) + for i=1,nofsequence do + setposition(f,tableoffset+sequences[i]) + sequences[i]=readcardinaltable(f,readushort(f),ushort) + end + local coverage=readcoverage(f,tableoffset+coverage) + for index,newindex in next,coverage do + newindex=newindex+1 + if index>nofglyphs or newindex>nofglyphs then + report("invalid index in %s format %i: %i -> %i (max %i)",what,subtype,index,newindex,nofglyphs) + coverage[index]=nil + else + coverage[index]=sequences[newindex] + end + end + return { + coverage=coverage + } + else + report("unsupported subtype %a in %a substitution",subtype,what) + end +end +function gsubhandlers.multiple(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"multiple") +end +function gsubhandlers.alternate(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"alternate") +end +function gsubhandlers.ligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local coverage=readushort(f) + local nofsets=readushort(f) + local ligatures=readcardinaltable(f,nofsets,ushort) + for i=1,nofsets do + local offset=lookupoffset+offset+ligatures[i] + setposition(f,offset) + local n=readushort(f) + if n==1 then + ligatures[i]={ offset+readushort(f) } + else + local l={} + for i=1,n do + l[i]=offset+readushort(f) + end + ligatures[i]=l + end + end + local coverage=readcoverage(f,tableoffset+coverage) + for index,newindex in next,coverage do + local hash={} + local ligatures=ligatures[newindex+1] + for i=1,#ligatures do + local offset=ligatures[i] + setposition(f,offset) + local lig=readushort(f) + local cnt=readushort(f) + local hsh=hash + for i=2,cnt do + local c=readushort(f) + local h=hsh[c] + if not h then + h={} + hsh[c]=h + end + hsh=h + end + hsh.ligature=lig + end + coverage[index]=hash + end + return { + coverage=coverage + } + else + report("unsupported subtype %a in %a substitution",subtype,"ligature") + end +end +function gsubhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"context" +end +function gsubhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"chainedcontext" +end +function gsubhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gsubtypes,gsubhandlers,"substitution") +end +function gsubhandlers.reversechainedcontextsingle(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local current=readfirst(f) + local before=readarray(f) + local after=readarray(f) + local replacements=readarray(f) + current=readcoveragearray(f,tableoffset,current,true) + before=readcoveragearray(f,tableoffset,before,true) + after=readcoveragearray(f,tableoffset,after,true) + return { + format="reversecoverage", + rules={ + { + before=before, + current=current, + after=after, + replacements=replacements, + } + } + },"reversechainedcontextsingle" + else + report("unsupported subtype %a in %a substitution",subtype,"reversechainedcontextsingle") + end +end +local function readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta) + local done={} + for i=1,#sets do + local offset=sets[i] + local reused=done[offset] + if not reused then + offset=tableoffset+offset + setposition(f,offset) + local n=readushort(f) + reused={} + for i=1,n do + reused[i]={ + readushort(f), + readposition(f,format1,offset,getdelta), + readposition(f,format2,offset,getdelta), + } + end + done[offset]=reused + end + sets[i]=reused + end + return sets +end +local function readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,mainoffset,getdelta) + local classlist1={} + for i=1,nofclasses1 do + local classlist2={} + classlist1[i]=classlist2 + for j=1,nofclasses2 do + local one=readposition(f,format1,mainoffset,getdelta) + local two=readposition(f,format2,mainoffset,getdelta) + if one or two then + classlist2[j]={ one,two } + else + classlist2[j]=false + end + end + end + return classlist1 +end +function gposhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + local getdelta=fontdata.temporary.getdelta + if subtype==1 then + local coverage=readushort(f) + local format=readushort(f) + local value=readposition(f,format,tableoffset,getdelta) + local coverage=readcoverage(f,tableoffset+coverage) + for index,newindex in next,coverage do + coverage[index]=value + end + return { + format="single", + coverage=coverage, + } + elseif subtype==2 then + local coverage=readushort(f) + local format=readushort(f) + local nofvalues=readushort(f) + local values={} + for i=1,nofvalues do + values[i]=readposition(f,format,tableoffset,getdelta) + end + local coverage=readcoverage(f,tableoffset+coverage) + for index,newindex in next,coverage do + coverage[index]=values[newindex+1] + end + return { + format="single", + coverage=coverage, + } + else + report("unsupported subtype %a in %a positioning",subtype,"single") + end +end +function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + local getdelta=fontdata.temporary.getdelta + if subtype==1 then + local coverage=readushort(f) + local format1=readushort(f) + local format2=readushort(f) + local sets=readarray(f) + sets=readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta) + coverage=readcoverage(f,tableoffset+coverage) + local shared={} + for index,newindex in next,coverage do + local set=sets[newindex+1] + local hash={} + for i=1,#set do + local value=set[i] + if value then + local other=value[1] + local share=shared[value] + if share==nil then + local first=value[2] + local second=value[3] + if first or second then + share={ first,second or nil } + else + share=false + end + shared[value]=share + end + hash[other]=share or nil + end + end + coverage[index]=hash + end + return { + shared=shared and true or nil, + format="pair", + coverage=coverage, + } + elseif subtype==2 then + local coverage=readushort(f) + local format1=readushort(f) + local format2=readushort(f) + local classdef1=readushort(f) + local classdef2=readushort(f) + local nofclasses1=readushort(f) + local nofclasses2=readushort(f) + local classlist=readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,tableoffset,getdelta) + coverage=readcoverage(f,tableoffset+coverage) + classdef1=readclassdef(f,tableoffset+classdef1,coverage) + classdef2=readclassdef(f,tableoffset+classdef2,nofglyphs) + local usedcoverage={} + local shared={} + for g1,c1 in next,classdef1 do + if coverage[g1] then + local l1=classlist[c1] + if l1 then + local hash={} + for paired,class in next,classdef2 do + local offsets=l1[class] + if offsets then + local first=offsets[1] + local second=offsets[2] + if first or second then + local s1=shared[first] + if s1==nil then + s1={} + shared[first]=s1 + end + local s2=s1[second] + if s2==nil then + s2={ first,second or nil } + s1[second]=s2 + end + hash[paired]=s2 + end + end + end + usedcoverage[g1]=hash + end + end + end + return { + shared=shared and true or nil, + format="pair", + coverage=usedcoverage, + } + elseif subtype==3 then + report("yet unsupported subtype %a in %a positioning",subtype,"pair") + else + report("unsupported subtype %a in %a positioning",subtype,"pair") + end +end +function gposhandlers.cursive(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + local getdelta=fontdata.temporary.getdelta + if subtype==1 then + local coverage=tableoffset+readushort(f) + local nofrecords=readushort(f) + local records={} + for i=1,nofrecords do + local entry=readushort(f) + local exit=readushort(f) + records[i]={ + entry~=0 and (tableoffset+entry) or false, + exit~=0 and (tableoffset+exit ) or nil, + } + end + local cc=(fontdata.temporary.cursivecount or 0)+1 + fontdata.temporary.cursivecount=cc + cc="cc-"..cc + coverage=readcoverage(f,coverage) + for i=1,nofrecords do + local r=records[i] + records[i]={ + cc, + readanchor(f,r[1],getdelta) or false, + readanchor(f,r[2],getdelta) or nil, + } + end + for index,newindex in next,coverage do + coverage[index]=records[newindex+1] + end + return { + coverage=coverage, + } + else + report("unsupported subtype %a in %a positioning",subtype,"cursive") + end +end +local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,ligature) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + local getdelta=fontdata.temporary.getdelta + if subtype==1 then + local markcoverage=tableoffset+readushort(f) + local basecoverage=tableoffset+readushort(f) + local nofclasses=readushort(f) + local markoffset=tableoffset+readushort(f) + local baseoffset=tableoffset+readushort(f) + local markcoverage=readcoverage(f,markcoverage) + local basecoverage=readcoverage(f,basecoverage,true) + setposition(f,markoffset) + local markclasses={} + local nofmarkclasses=readushort(f) + local lastanchor=fontdata.lastanchor or 0 + local usedanchors={} + for i=1,nofmarkclasses do + local class=readushort(f)+1 + local offset=readushort(f) + if offset==0 then + markclasses[i]=false + else + markclasses[i]={ class,markoffset+offset } + end + usedanchors[class]=true + end + for i=1,nofmarkclasses do + local mc=markclasses[i] + if mc then + mc[2]=readanchor(f,mc[2],getdelta) + end + end + setposition(f,baseoffset) + local nofbaserecords=readushort(f) + local baserecords={} + if ligature then + for i=1,nofbaserecords do + local offset=readushort(f) + if offset==0 then + baserecords[i]=false + else + baserecords[i]=baseoffset+offset + end + end + for i=1,nofbaserecords do + local recordoffset=baserecords[i] + if recordoffset then + setposition(f,recordoffset) + local nofcomponents=readushort(f) + local components={} + for i=1,nofcomponents do + local classes={} + for i=1,nofclasses do + local offset=readushort(f) + if offset~=0 then + classes[i]=recordoffset+offset + else + classes[i]=false + end + end + components[i]=classes + end + baserecords[i]=components + end + end + local baseclasses={} + for i=1,nofclasses do + baseclasses[i]={} + end + for i=1,nofbaserecords do + local components=baserecords[i] + if components then + local b=basecoverage[i] + for c=1,#components do + local classes=components[c] + if classes then + for i=1,nofclasses do + local anchor=readanchor(f,classes[i],getdelta) + local bclass=baseclasses[i] + local bentry=bclass[b] + if bentry then + bentry[c]=anchor + else + bclass[b]={ [c]=anchor } + end + end + end + end + end + end + for index,newindex in next,markcoverage do + markcoverage[index]=markclasses[newindex+1] or nil + end + return { + format="ligature", + baseclasses=baseclasses, + coverage=markcoverage, + } + else + for i=1,nofbaserecords do + local r={} + for j=1,nofclasses do + local offset=readushort(f) + if offset==0 then + r[j]=false + else + r[j]=baseoffset+offset + end + end + baserecords[i]=r + end + local baseclasses={} + for i=1,nofclasses do + baseclasses[i]={} + end + for i=1,nofbaserecords do + local r=baserecords[i] + local b=basecoverage[i] + for j=1,nofclasses do + baseclasses[j][b]=readanchor(f,r[j],getdelta) + end + end + for index,newindex in next,markcoverage do + markcoverage[index]=markclasses[newindex+1] or nil + end + return { + format="base", + baseclasses=baseclasses, + coverage=markcoverage, + } + end + else + report("unsupported subtype %a in",subtype) + end +end +function gposhandlers.marktobase(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) +end +function gposhandlers.marktoligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,true) +end +function gposhandlers.marktomark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) +end +function gposhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"context" +end +function gposhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"chainedcontext" +end +function gposhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gpostypes,gposhandlers,"positioning") +end +do + local plugins={} + function plugins.size(f,fontdata,tableoffset,feature) + if fontdata.designsize then + else + local function check(offset) + setposition(f,offset) + local designsize=readushort(f) + if designsize>0 then + local fontstyleid=readushort(f) + local guimenuid=readushort(f) + local minsize=readushort(f) + local maxsize=readushort(f) + if minsize==0 and maxsize==0 and fontstyleid==0 and guimenuid==0 then + minsize=designsize + maxsize=designsize + end + if designsize>=minsize and designsize<=maxsize then + return minsize,maxsize,designsize + end + end + end + local minsize,maxsize,designsize=check(tableoffset+feature.offset+feature.parameters) + if not designsize then + minsize,maxsize,designsize=check(tableoffset+feature.parameters) + if designsize then + report("bad size feature in %a, falling back to wrong offset",fontdata.filename or "?") + else + report("bad size feature in %a,",fontdata.filename or "?") + end + end + if designsize then + fontdata.minsize=minsize + fontdata.maxsize=maxsize + fontdata.designsize=designsize + end + end + end + local function reorderfeatures(fontdata,scripts,features) + local scriptlangs={} + local featurehash={} + local featureorder={} + for script,languages in next,scripts do + for language,record in next,languages do + local hash={} + local list=record.featureindices + for k=1,#list do + local index=list[k] + local feature=features[index] + local lookups=feature.lookups + local tag=feature.tag + if tag then + hash[tag]=true + end + if lookups then + for i=1,#lookups do + local lookup=lookups[i] + local o=featureorder[lookup] + if o then + local okay=true + for i=1,#o do + if o[i]==tag then + okay=false + break + end + end + if okay then + o[#o+1]=tag + end + else + featureorder[lookup]={ tag } + end + local f=featurehash[lookup] + if f then + local h=f[tag] + if h then + local s=h[script] + if s then + s[language]=true + else + h[script]={ [language]=true } + end + else + f[tag]={ [script]={ [language]=true } } + end + else + featurehash[lookup]={ [tag]={ [script]={ [language]=true } } } + end + local h=scriptlangs[tag] + if h then + local s=h[script] + if s then + s[language]=true + else + h[script]={ [language]=true } + end + else + scriptlangs[tag]={ [script]={ [language]=true } } + end + end + end + end + end + end + return scriptlangs,featurehash,featureorder + end + local function readscriplan(f,fontdata,scriptoffset) + setposition(f,scriptoffset) + local nofscripts=readushort(f) + local scripts={} + for i=1,nofscripts do + scripts[readtag(f)]=scriptoffset+readushort(f) + end + local languagesystems=setmetatableindex("table") + for script,offset in next,scripts do + setposition(f,offset) + local defaultoffset=readushort(f) + local noflanguages=readushort(f) + local languages={} + if defaultoffset>0 then + languages.dflt=languagesystems[offset+defaultoffset] + end + for i=1,noflanguages do + local language=readtag(f) + local offset=offset+readushort(f) + languages[language]=languagesystems[offset] + end + scripts[script]=languages + end + for offset,usedfeatures in next,languagesystems do + if offset>0 then + setposition(f,offset) + local featureindices={} + usedfeatures.featureindices=featureindices + usedfeatures.lookuporder=readushort(f) + usedfeatures.requiredindex=readushort(f) + local noffeatures=readushort(f) + for i=1,noffeatures do + featureindices[i]=readushort(f)+1 + end + end + end + return scripts + end + local function readfeatures(f,fontdata,featureoffset) + setposition(f,featureoffset) + local features={} + local noffeatures=readushort(f) + for i=1,noffeatures do + features[i]={ + tag=readtag(f), + offset=readushort(f) + } + end + for i=1,noffeatures do + local feature=features[i] + local offset=featureoffset+feature.offset + setposition(f,offset) + local parameters=readushort(f) + local noflookups=readushort(f) + if noflookups>0 then + local lookups=readcardinaltable(f,noflookups,ushort) + feature.lookups=lookups + for j=1,noflookups do + lookups[j]=lookups[j]+1 + end + end + if parameters>0 then + feature.parameters=parameters + local plugin=plugins[feature.tag] + if plugin then + plugin(f,fontdata,featureoffset,feature) + end + end + end + return features + end + local function readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder) + setposition(f,lookupoffset) + local noflookups=readushort(f) + local lookups=readcardinaltable(f,noflookups,ushort) + for lookupid=1,noflookups do + local offset=lookups[lookupid] + setposition(f,lookupoffset+offset) + local subtables={} + local typebits=readushort(f) + local flagbits=readushort(f) + local lookuptype=lookuptypes[typebits] + local lookupflags=lookupflags[flagbits] + local nofsubtables=readushort(f) + for j=1,nofsubtables do + subtables[j]=offset+readushort(f) + end + local markclass=band(flagbits,0x0010)~=0 + if markclass then + markclass=readushort(f) + end + local markset=rshift(flagbits,8) + if markset>0 then + markclass=markset + end + lookups[lookupid]={ + type=lookuptype, + flags=lookupflags, + name=lookupid, + subtables=subtables, + markclass=markclass, + features=featurehash[lookupid], + order=featureorder[lookupid], + } + end + return lookups + end + local f_lookupname=formatters["%s_%s_%s"] + local function resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset) + local sequences=fontdata.sequences or {} + local sublookuplist=fontdata.sublookups or {} + fontdata.sequences=sequences + fontdata.sublookups=sublookuplist + local nofsublookups=#sublookuplist + local nofsequences=#sequences + local lastsublookup=nofsublookups + local lastsequence=nofsequences + local lookupnames=lookupnames[what] + local sublookuphash={} + local sublookupcheck={} + local glyphs=fontdata.glyphs + local nofglyphs=fontdata.nofglyphs or #glyphs + local noflookups=#lookups + local lookupprefix=sub(what,2,2) + local usedlookups=false + for lookupid=1,noflookups do + local lookup=lookups[lookupid] + local lookuptype=lookup.type + local subtables=lookup.subtables + local features=lookup.features + local handler=lookuphandlers[lookuptype] + if handler then + local nofsubtables=#subtables + local order=lookup.order + local flags=lookup.flags + if flags[1] then flags[1]="mark" end + if flags[2] then flags[2]="ligature" end + if flags[3] then flags[3]="base" end + local markclass=lookup.markclass + if nofsubtables>0 then + local steps={} + local nofsteps=0 + local oldtype=nil + for s=1,nofsubtables do + local step,lt=handler(f,fontdata,lookupid,lookupoffset,subtables[s],glyphs,nofglyphs) + if lt then + lookuptype=lt + if oldtype and lt~=oldtype then + report("messy %s lookup type %a and %a",what,lookuptype,oldtype) + end + oldtype=lookuptype + end + if not step then + report("unsupported %s lookup type %a",what,lookuptype) + else + nofsteps=nofsteps+1 + steps[nofsteps]=step + local rules=step.rules + if rules then + for i=1,#rules do + local rule=rules[i] + local before=rule.before + local current=rule.current + local after=rule.after + local replacements=rule.replacements + if before then + for i=1,#before do + before[i]=tohash(before[i]) + end + rule.before=reversed(before) + end + if current then + if replacements then + local first=current[1] + local hash={} + local repl={} + for i=1,#first do + local c=first[i] + hash[c]=true + repl[c]=replacements[i] + end + rule.current={ hash } + rule.replacements=repl + else + for i=1,#current do + current[i]=tohash(current[i]) + end + end + else + end + if after then + for i=1,#after do + after[i]=tohash(after[i]) + end + end + if usedlookups then + local lookups=rule.lookups + if lookups then + for k,v in next,lookups do + if v then + for k,v in next,v do + usedlookups[v]=usedlookups[v]+1 + end + end + end + end + end + end + end + end + end + if nofsteps~=nofsubtables then + report("bogus subtables removed in %s lookup type %a",what,lookuptype) + end + lookuptype=lookupnames[lookuptype] or lookuptype + if features then + nofsequences=nofsequences+1 + local l={ + index=nofsequences, + name=f_lookupname(lookupprefix,"s",lookupid+lookupidoffset), + steps=steps, + nofsteps=nofsteps, + type=lookuptype, + markclass=markclass or nil, + flags=flags, + order=order, + features=features, + } + sequences[nofsequences]=l + lookup.done=l + else + nofsublookups=nofsublookups+1 + local l={ + index=nofsublookups, + name=f_lookupname(lookupprefix,"l",lookupid+lookupidoffset), + steps=steps, + nofsteps=nofsteps, + type=lookuptype, + markclass=markclass or nil, + flags=flags, + } + sublookuplist[nofsublookups]=l + sublookuphash[lookupid]=nofsublookups + sublookupcheck[lookupid]=0 + lookup.done=l + end + else + report("no subtables for lookup %a",lookupid) + end + else + report("no handler for lookup %a with type %a",lookupid,lookuptype) + end + end + if usedlookups then + report("used %s lookups: % t",what,sortedkeys(usedlookups)) + end + local reported={} + local function report_issue(i,what,sequence,kind) + local name=sequence.name + if not reported[name] then + report("rule %i in %s lookup %a has %s lookups",i,what,name,kind) + reported[name]=true + end + end + for i=lastsequence+1,nofsequences do + local sequence=sequences[i] + local steps=sequence.steps + for i=1,#steps do + local step=steps[i] + local rules=step.rules + if rules then + for i=1,#rules do + local rule=rules[i] + local rlookups=rule.lookups + if not rlookups then + report_issue(i,what,sequence,"no") + elseif not next(rlookups) then + rule.lookups=nil + else + local length=#rlookups + for index=1,length do + local lookuplist=rlookups[index] + if lookuplist then + local length=#lookuplist + local found={} + local noffound=0 + for index=1,length do + local lookupid=lookuplist[index] + if lookupid then + local h=sublookuphash[lookupid] + if not h then + local lookup=lookups[lookupid] + if lookup then + local d=lookup.done + if d then + nofsublookups=nofsublookups+1 + local l={ + index=nofsublookups, + name=f_lookupname(lookupprefix,"d",lookupid+lookupidoffset), + derived=true, + steps=d.steps, + nofsteps=d.nofsteps, + type=d.lookuptype or "gsub_single", + markclass=d.markclass or nil, + flags=d.flags, + } + sublookuplist[nofsublookups]=copy(l) + sublookuphash[lookupid]=nofsublookups + sublookupcheck[lookupid]=1 + h=nofsublookups + else + report_issue(i,what,sequence,"missing") + rule.lookups=nil + break + end + else + report_issue(i,what,sequence,"bad") + rule.lookups=nil + break + end + else + sublookupcheck[lookupid]=sublookupcheck[lookupid]+1 + end + if h then + noffound=noffound+1 + found[noffound]=h + end + end + end + rlookups[index]=noffound>0 and found or false + else + rlookups[index]=false + end + end + end + end + end + end + end + for i,n in sortedhash(sublookupcheck) do + local l=lookups[i] + local t=l.type + if n==0 and t~="extension" then + local d=l.done + report("%s lookup %s of type %a is not used",what,d and d.name or l.name,t) + end + end + end + local function loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder) + setposition(f,variationsoffset) + local version=readulong(f) + local nofrecords=readulong(f) + local records={} + for i=1,nofrecords do + records[i]={ + conditions=readulong(f), + substitutions=readulong(f), + } + end + for i=1,nofrecords do + local record=records[i] + local offset=record.conditions + if offset==0 then + record.condition=nil + record.matchtype="always" + else + local offset=variationsoffset+offset + setposition(f,offset) + local nofconditions=readushort(f) + local conditions={} + for i=1,nofconditions do + conditions[i]=offset+readulong(f) + end + record.conditions=conditions + record.matchtype="condition" + end + end + for i=1,nofrecords do + local record=records[i] + if record.matchtype=="condition" then + local conditions=record.conditions + for i=1,#conditions do + setposition(f,conditions[i]) + conditions[i]={ + format=readushort(f), + axis=readushort(f), + minvalue=read2dot14(f), + maxvalue=read2dot14(f), + } + end + end + end + for i=1,nofrecords do + local record=records[i] + local offset=record.substitutions + if offset==0 then + record.substitutions={} + else + setposition(f,variationsoffset+offset) + local version=readulong(f) + local nofsubstitutions=readushort(f) + local substitutions={} + for i=1,nofsubstitutions do + substitutions[readushort(f)]=readulong(f) + end + for index,alternates in sortedhash(substitutions) do + if index==0 then + record.substitutions=false + else + local tableoffset=variationsoffset+offset+alternates + setposition(f,tableoffset) + local parameters=readulong(f) + local noflookups=readushort(f) + local lookups=readcardinaltable(f,noflookups,ushort) + record.substitutions=lookups + end + end + end + end + setvariabledata(fontdata,"features",records) + end + local function readscripts(f,fontdata,what,lookuptypes,lookuphandlers,lookupstoo) + local tableoffset=gotodatatable(f,fontdata,what,true) + if tableoffset then + local version=readulong(f) + local scriptoffset=tableoffset+readushort(f) + local featureoffset=tableoffset+readushort(f) + local lookupoffset=tableoffset+readushort(f) + local variationsoffset=version>0x00010000 and (tableoffset+readulong(f)) or 0 + if not scriptoffset then + return + end + local scripts=readscriplan(f,fontdata,scriptoffset) + local features=readfeatures(f,fontdata,featureoffset) + local scriptlangs,featurehash,featureorder=reorderfeatures(fontdata,scripts,features) + if fontdata.features then + fontdata.features[what]=scriptlangs + else + fontdata.features={ [what]=scriptlangs } + end + if not lookupstoo then + return + end + local lookups=readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder) + if lookups then + resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset) + end + if variationsoffset>0 then + loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder) + end + end + end + local function checkkerns(f,fontdata,specification) + local datatable=fontdata.tables.kern + if not datatable then + return + end + local features=fontdata.features + local gposfeatures=features and features.gpos + local name + if not gposfeatures or not gposfeatures.kern then + name="kern" + elseif specification.globalkerns then + name="globalkern" + else + report("ignoring global kern table, using gpos kern feature") + return + end + setposition(f,datatable.offset) + local version=readushort(f) + local noftables=readushort(f) + if noftables>1 then + report("adding global kern table as gpos feature %a",name) + local kerns=setmetatableindex("table") + for i=1,noftables do + local version=readushort(f) + local length=readushort(f) + local coverage=readushort(f) + local format=rshift(coverage,8) + if format==0 then + local nofpairs=readushort(f) + local searchrange=readushort(f) + local entryselector=readushort(f) + local rangeshift=readushort(f) + for i=1,nofpairs do + kerns[readushort(f)][readushort(f)]=readfword(f) + end + elseif format==2 then + else + end + end + local feature={ dflt={ dflt=true } } + if not features then + fontdata.features={ gpos={ [name]=feature } } + elseif not gposfeatures then + fontdata.features.gpos={ [name]=feature } + else + gposfeatures[name]=feature + end + local sequences=fontdata.sequences + if not sequences then + sequences={} + fontdata.sequences=sequences + end + local nofsequences=#sequences+1 + sequences[nofsequences]={ + index=nofsequences, + name=name, + steps={ + { + coverage=kerns, + format="kern", + }, + }, + nofsteps=1, + type="gpos_pair", + flags={ false,false,false,false }, + order={ name }, + features={ [name]=feature }, + } + else + report("ignoring empty kern table of feature %a",name) + end + end + function readers.gsub(f,fontdata,specification) + if specification.details then + readscripts(f,fontdata,"gsub",gsubtypes,gsubhandlers,specification.lookups) + end + end + function readers.gpos(f,fontdata,specification) + if specification.details then + readscripts(f,fontdata,"gpos",gpostypes,gposhandlers,specification.lookups) + if specification.lookups then + checkkerns(f,fontdata,specification) + end + end + end +end +function readers.gdef(f,fontdata,specification) + if not specification.glyphs then + return + end + local datatable=fontdata.tables.gdef + if datatable then + local tableoffset=datatable.offset + setposition(f,tableoffset) + local version=readulong(f) + local classoffset=readushort(f) + local attachmentoffset=readushort(f) + local ligaturecarets=readushort(f) + local markclassoffset=readushort(f) + local marksetsoffset=version>=0x00010002 and readushort(f) or 0 + local varsetsoffset=version>=0x00010003 and readulong(f) or 0 + local glyphs=fontdata.glyphs + local marks={} + local markclasses=setmetatableindex("table") + local marksets=setmetatableindex("table") + fontdata.marks=marks + fontdata.markclasses=markclasses + fontdata.marksets=marksets + if classoffset~=0 then + setposition(f,tableoffset+classoffset) + local classformat=readushort(f) + if classformat==1 then + local firstindex=readushort(f) + local lastindex=firstindex+readushort(f)-1 + for index=firstindex,lastindex do + local class=classes[readushort(f)] + if class=="mark" then + marks[index]=true + end + glyphs[index].class=class + end + elseif classformat==2 then + local nofranges=readushort(f) + for i=1,nofranges do + local firstindex=readushort(f) + local lastindex=readushort(f) + local class=classes[readushort(f)] + if class then + for index=firstindex,lastindex do + glyphs[index].class=class + if class=="mark" then + marks[index]=true + end + end + end + end + end + end + if markclassoffset~=0 then + setposition(f,tableoffset+markclassoffset) + local classformat=readushort(f) + if classformat==1 then + local firstindex=readushort(f) + local lastindex=firstindex+readushort(f)-1 + for index=firstindex,lastindex do + markclasses[readushort(f)][index]=true + end + elseif classformat==2 then + local nofranges=readushort(f) + for i=1,nofranges do + local firstindex=readushort(f) + local lastindex=readushort(f) + local class=markclasses[readushort(f)] + for index=firstindex,lastindex do + class[index]=true + end + end + end + end + if marksetsoffset~=0 then + marksetsoffset=tableoffset+marksetsoffset + setposition(f,marksetsoffset) + local format=readushort(f) + if format==1 then + local nofsets=readushort(f) + local sets=readcardinaltable(f,nofsets,ulong) + for i=1,nofsets do + local offset=sets[i] + if offset~=0 then + marksets[i]=readcoverage(f,marksetsoffset+offset) + end + end + end + end + local factors=specification.factors + if (specification.variable or factors) and varsetsoffset~=0 then + local regions,deltas=readvariationdata(f,tableoffset+varsetsoffset,factors) + if factors then + fontdata.temporary.getdelta=function(outer,inner) + local delta=deltas[outer+1] + if delta then + local d=delta.deltas[inner+1] + if d then + local scales=delta.scales + local dd=0 + for i=1,#scales do + local di=d[i] + if di then + dd=dd+scales[i]*di + else + break + end + end + return round(dd) + end + end + return 0 + end + end + end + end +end +local function readmathvalue(f) + local v=readshort(f) + skipshort(f,1) + return v +end +local function readmathconstants(f,fontdata,offset) + setposition(f,offset) + fontdata.mathconstants={ + ScriptPercentScaleDown=readshort(f), + ScriptScriptPercentScaleDown=readshort(f), + DelimitedSubFormulaMinHeight=readushort(f), + DisplayOperatorMinHeight=readushort(f), + MathLeading=readmathvalue(f), + AxisHeight=readmathvalue(f), + AccentBaseHeight=readmathvalue(f), + FlattenedAccentBaseHeight=readmathvalue(f), + SubscriptShiftDown=readmathvalue(f), + SubscriptTopMax=readmathvalue(f), + SubscriptBaselineDropMin=readmathvalue(f), + SuperscriptShiftUp=readmathvalue(f), + SuperscriptShiftUpCramped=readmathvalue(f), + SuperscriptBottomMin=readmathvalue(f), + SuperscriptBaselineDropMax=readmathvalue(f), + SubSuperscriptGapMin=readmathvalue(f), + SuperscriptBottomMaxWithSubscript=readmathvalue(f), + SpaceAfterScript=readmathvalue(f), + UpperLimitGapMin=readmathvalue(f), + UpperLimitBaselineRiseMin=readmathvalue(f), + LowerLimitGapMin=readmathvalue(f), + LowerLimitBaselineDropMin=readmathvalue(f), + StackTopShiftUp=readmathvalue(f), + StackTopDisplayStyleShiftUp=readmathvalue(f), + StackBottomShiftDown=readmathvalue(f), + StackBottomDisplayStyleShiftDown=readmathvalue(f), + StackGapMin=readmathvalue(f), + StackDisplayStyleGapMin=readmathvalue(f), + StretchStackTopShiftUp=readmathvalue(f), + StretchStackBottomShiftDown=readmathvalue(f), + StretchStackGapAboveMin=readmathvalue(f), + StretchStackGapBelowMin=readmathvalue(f), + FractionNumeratorShiftUp=readmathvalue(f), + FractionNumeratorDisplayStyleShiftUp=readmathvalue(f), + FractionDenominatorShiftDown=readmathvalue(f), + FractionDenominatorDisplayStyleShiftDown=readmathvalue(f), + FractionNumeratorGapMin=readmathvalue(f), + FractionNumeratorDisplayStyleGapMin=readmathvalue(f), + FractionRuleThickness=readmathvalue(f), + FractionDenominatorGapMin=readmathvalue(f), + FractionDenominatorDisplayStyleGapMin=readmathvalue(f), + SkewedFractionHorizontalGap=readmathvalue(f), + SkewedFractionVerticalGap=readmathvalue(f), + OverbarVerticalGap=readmathvalue(f), + OverbarRuleThickness=readmathvalue(f), + OverbarExtraAscender=readmathvalue(f), + UnderbarVerticalGap=readmathvalue(f), + UnderbarRuleThickness=readmathvalue(f), + UnderbarExtraDescender=readmathvalue(f), + RadicalVerticalGap=readmathvalue(f), + RadicalDisplayStyleVerticalGap=readmathvalue(f), + RadicalRuleThickness=readmathvalue(f), + RadicalExtraAscender=readmathvalue(f), + RadicalKernBeforeDegree=readmathvalue(f), + RadicalKernAfterDegree=readmathvalue(f), + RadicalDegreeBottomRaisePercent=readshort(f), + } +end +local function readmathglyphinfo(f,fontdata,offset) + setposition(f,offset) + local italics=readushort(f) + local accents=readushort(f) + local extensions=readushort(f) + local kerns=readushort(f) + local glyphs=fontdata.glyphs + if italics~=0 then + setposition(f,offset+italics) + local coverage=readushort(f) + local nofglyphs=readushort(f) + coverage=readcoverage(f,offset+italics+coverage,true) + setposition(f,offset+italics+4) + for i=1,nofglyphs do + local italic=readmathvalue(f) + if italic~=0 then + local glyph=glyphs[coverage[i]] + local math=glyph.math + if not math then + glyph.math={ italic=italic } + else + math.italic=italic + end + end + end + fontdata.hasitalics=true + end + if accents~=0 then + setposition(f,offset+accents) + local coverage=readushort(f) + local nofglyphs=readushort(f) + coverage=readcoverage(f,offset+accents+coverage,true) + setposition(f,offset+accents+4) + for i=1,nofglyphs do + local accent=readmathvalue(f) + if accent~=0 then + local glyph=glyphs[coverage[i]] + local math=glyph.math + if not math then + glyph.math={ accent=accent } + else + math.accent=accent + end + end + end + end + if extensions~=0 then + setposition(f,offset+extensions) + end + if kerns~=0 then + local kernoffset=offset+kerns + setposition(f,kernoffset) + local coverage=readushort(f) + local nofglyphs=readushort(f) + if nofglyphs>0 then + local function get(offset) + setposition(f,kernoffset+offset) + local n=readushort(f) + if n==0 then + local k=readmathvalue(f) + if k==0 then + else + return { { kern=k } } + end + else + local l={} + for i=1,n do + l[i]={ height=readmathvalue(f) } + end + for i=1,n do + l[i].kern=readmathvalue(f) + end + l[n+1]={ kern=readmathvalue(f) } + return l + end + end + local kernsets={} + for i=1,nofglyphs do + local topright=readushort(f) + local topleft=readushort(f) + local bottomright=readushort(f) + local bottomleft=readushort(f) + kernsets[i]={ + topright=topright~=0 and topright or nil, + topleft=topleft~=0 and topleft or nil, + bottomright=bottomright~=0 and bottomright or nil, + bottomleft=bottomleft~=0 and bottomleft or nil, + } + end + coverage=readcoverage(f,kernoffset+coverage,true) + for i=1,nofglyphs do + local kernset=kernsets[i] + if next(kernset) then + local k=kernset.topright if k then kernset.topright=get(k) end + local k=kernset.topleft if k then kernset.topleft=get(k) end + local k=kernset.bottomright if k then kernset.bottomright=get(k) end + local k=kernset.bottomleft if k then kernset.bottomleft=get(k) end + if next(kernset) then + local glyph=glyphs[coverage[i]] + local math=glyph.math + if math then + math.kerns=kernset + else + glyph.math={ kerns=kernset } + end + end + end + end + end + end +end +local function readmathvariants(f,fontdata,offset) + setposition(f,offset) + local glyphs=fontdata.glyphs + local minoverlap=readushort(f) + local vcoverage=readushort(f) + local hcoverage=readushort(f) + local vnofglyphs=readushort(f) + local hnofglyphs=readushort(f) + local vconstruction=readcardinaltable(f,vnofglyphs,ushort) + local hconstruction=readcardinaltable(f,hnofglyphs,ushort) + fontdata.mathconstants.MinConnectorOverlap=minoverlap + local function get(offset,coverage,nofglyphs,construction,kvariants,kparts,kitalic) + if coverage~=0 and nofglyphs>0 then + local coverage=readcoverage(f,offset+coverage,true) + for i=1,nofglyphs do + local c=construction[i] + if c~=0 then + local index=coverage[i] + local glyph=glyphs[index] + local math=glyph.math + setposition(f,offset+c) + local assembly=readushort(f) + local nofvariants=readushort(f) + if nofvariants>0 then + local variants,v=nil,0 + for i=1,nofvariants do + local variant=readushort(f) + if variant==index then + elseif variants then + v=v+1 + variants[v]=variant + else + v=1 + variants={ variant } + end + skipshort(f) + end + if not variants then + elseif not math then + math={ [kvariants]=variants } + glyph.math=math + else + math[kvariants]=variants + end + end + if assembly~=0 then + setposition(f,offset+c+assembly) + local italic=readmathvalue(f) + local nofparts=readushort(f) + local parts={} + for i=1,nofparts do + local p={ + glyph=readushort(f), + start=readushort(f), + ["end"]=readushort(f), + advance=readushort(f), + } + local flags=readushort(f) + if band(flags,0x0001)~=0 then + p.extender=1 + end + parts[i]=p + end + if not math then + math={ + [kparts]=parts + } + glyph.math=math + else + math[kparts]=parts + end + if italic and italic~=0 then + math[kitalic]=italic + end + end + end + end + end + end + get(offset,vcoverage,vnofglyphs,vconstruction,"vvariants","vparts","vitalic") + get(offset,hcoverage,hnofglyphs,hconstruction,"hvariants","hparts","hitalic") +end +function readers.math(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"math",specification.glyphs) + if tableoffset then + local version=readulong(f) + local constants=readushort(f) + local glyphinfo=readushort(f) + local variants=readushort(f) + if constants==0 then + report("the math table of %a has no constants",fontdata.filename) + else + readmathconstants(f,fontdata,tableoffset+constants) + end + if glyphinfo~=0 then + readmathglyphinfo(f,fontdata,tableoffset+glyphinfo) + end + if variants~=0 then + readmathvariants(f,fontdata,tableoffset+variants) + end + end +end +function readers.colr(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"colr",specification.glyphs) + if tableoffset then + local version=readushort(f) + if version~=0 then + report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"colr",fontdata.filename) + return + end + if not fontdata.tables.cpal then + report("color table %a in font %a has no mandate %a table","colr",fontdata.filename,"cpal") + fontdata.colorpalettes={} + end + local glyphs=fontdata.glyphs + local nofglyphs=readushort(f) + local baseoffset=readulong(f) + local layeroffset=readulong(f) + local noflayers=readushort(f) + local layerrecords={} + local maxclass=0 + setposition(f,tableoffset+layeroffset) + for i=1,noflayers do + local slot=readushort(f) + local class=readushort(f) + if class<0xFFFF then + class=class+1 + if class>maxclass then + maxclass=class + end + end + layerrecords[i]={ + slot=slot, + class=class, + } + end + fontdata.maxcolorclass=maxclass + setposition(f,tableoffset+baseoffset) + for i=0,nofglyphs-1 do + local glyphindex=readushort(f) + local firstlayer=readushort(f) + local noflayers=readushort(f) + local t={} + for i=1,noflayers do + t[i]=layerrecords[firstlayer+i] + end + glyphs[glyphindex].colors=t + end + end + fontdata.hascolor=true +end +function readers.cpal(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"cpal",specification.glyphs) + if tableoffset then + local version=readushort(f) + local nofpaletteentries=readushort(f) + local nofpalettes=readushort(f) + local nofcolorrecords=readushort(f) + local firstcoloroffset=readulong(f) + local colorrecords={} + local palettes=readcardinaltable(f,nofpalettes,ushort) + if version==1 then + local palettettypesoffset=readulong(f) + local palettelabelsoffset=readulong(f) + local paletteentryoffset=readulong(f) + end + setposition(f,tableoffset+firstcoloroffset) + for i=1,nofcolorrecords do + local b,g,r,a=readbytes(f,4) + colorrecords[i]={ + r,g,b,a~=255 and a or nil, + } + end + for i=1,nofpalettes do + local p={} + local o=palettes[i] + for j=1,nofpaletteentries do + p[j]=colorrecords[o+j] + end + palettes[i]=p + end + fontdata.colorpalettes=palettes + end +end +local compress=gzip and gzip.compress +local compressed=compress and gzip.compressed +function readers.svg(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"svg",specification.glyphs) + if tableoffset then + local version=readushort(f) + local glyphs=fontdata.glyphs + local indexoffset=tableoffset+readulong(f) + local reserved=readulong(f) + setposition(f,indexoffset) + local nofentries=readushort(f) + local entries={} + for i=1,nofentries do + entries[i]={ + first=readushort(f), + last=readushort(f), + offset=indexoffset+readulong(f), + length=readulong(f), + } + end + for i=1,nofentries do + local entry=entries[i] + setposition(f,entry.offset) + local data=readstring(f,entry.length) + if compressed and not compressed(data) then + data=compress(data) + end + entries[i]={ + first=entry.first, + last=entry.last, + data=data + } + end + fontdata.svgshapes=entries + end + fontdata.hascolor=true +end +function readers.sbix(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"sbix",specification.glyphs) + if tableoffset then + local version=readushort(f) + local flags=readushort(f) + local nofstrikes=readulong(f) + local strikes={} + local nofglyphs=fontdata.nofglyphs + for i=1,nofstrikes do + strikes[i]=readulong(f) + end + local shapes={} + local done=0 + for i=1,nofstrikes do + local strikeoffset=strikes[i]+tableoffset + setposition(f,strikeoffset) + strikes[i]={ + ppem=readushort(f), + ppi=readushort(f), + offset=strikeoffset + } + end + sort(strikes,function(a,b) + if b.ppem==a.ppem then + return b.ppi0 or fonts.handlers.typethree + for i=1,nofstrikes do + local strike=strikes[i] + local strikeppem=strike.ppem + local strikeppi=strike.ppi + local strikeoffset=strike.offset + setposition(f,strikeoffset) + for i=0,nofglyphs do + glyphs[i]=readulong(f) + end + local glyphoffset=glyphs[0] + for i=0,nofglyphs-1 do + local nextoffset=glyphs[i+1] + if not shapes[i] then + local datasize=nextoffset-glyphoffset + if datasize>0 then + setposition(f,strikeoffset+glyphoffset) + local x=readshort(f) + local y=readshort(f) + local tag=readtag(f) + local size=datasize-8 + local data=nil + local offset=nil + if delayed then + offset=getposition(f) + data=nil + else + data=readstring(f,size) + size=nil + end + shapes[i]={ + x=x, + y=y, + o=offset, + s=size, + data=data, + } + done=done+1 + if done==nofglyphs then + break + end + end + end + glyphoffset=nextoffset + end + end + fontdata.pngshapes=shapes + end +end +do + local function getmetrics(f) + return { + ascender=readinteger(f), + descender=readinteger(f), + widthmax=readuinteger(f), + caretslopedumerator=readinteger(f), + caretslopedenominator=readinteger(f), + caretoffset=readinteger(f), + minorigin=readinteger(f), + minadvance=readinteger(f), + maxbefore=readinteger(f), + minafter=readinteger(f), + pad1=readinteger(f), + pad2=readinteger(f), + } + end + local function getbigmetrics(f) + return { + height=readuinteger(f), + width=readuinteger(f), + horiBearingX=readinteger(f), + horiBearingY=readinteger(f), + horiAdvance=readuinteger(f), + vertBearingX=readinteger(f), + vertBearingY=readinteger(f), + vertAdvance=readuinteger(f), + } + end + local function getsmallmetrics(f) + return { + height=readuinteger(f), + width=readuinteger(f), + bearingX=readinteger(f), + bearingY=readinteger(f), + advance=readuinteger(f), + } + end + function readers.cblc(f,fontdata,specification) + local ctdttableoffset=gotodatatable(f,fontdata,"cbdt",specification.glyphs) + if not ctdttableoffset then + return + end + local cblctableoffset=gotodatatable(f,fontdata,"cblc",specification.glyphs) + if cblctableoffset then + local majorversion=readushort(f) + local minorversion=readushort(f) + local nofsizetables=readulong(f) + local sizetables={} + local shapes={} + local subtables={} + for i=1,nofsizetables do + sizetables[i]={ + subtables=readulong(f), + indexsize=readulong(f), + nofsubtables=readulong(f), + colorref=readulong(f), + hormetrics=getmetrics(f), + vermetrics=getmetrics(f), + firstindex=readushort(f), + lastindex=readushort(f), + ppemx=readbyte(f), + ppemy=readbyte(f), + bitdepth=readbyte(f), + flags=readbyte(f), + } + end + sort(sizetables,function(a,b) + if b.ppemx==a.ppemx then + return b.bitdepth0 or fonts.handlers.typethree + for index,subtable in sortedhash(shapes) do + if type(subtable)=="table" then + local data=nil + local size=nil + local metrics=default + local format=subtable.format + local offset=subtable.offsets[index] + setposition(f,offset) + if format==17 then + metrics=getsmallmetrics(f) + size=true + elseif format==18 then + metrics=getbigmetrics(f) + size=true + elseif format==19 then + metrics=subtable.metrics + size=true + else + end + if size then + size=readulong(f) + if delayed then + offset=getposition(f) + data=nil + else + offset=nil + data=readstring(f,size) + size=nil + end + else + offset=nil + end + local x=metrics.width + local y=metrics.height + shapes[index]={ + x=x, + y=y, + o=offset, + s=size, + data=data, + } + local glyph=glyphs[index] + if not glyph.boundingbox then + local width=glyph.width + local height=width*y/x + glyph.boundingbox={ 0,0,width,height } + end + else + shapes[index]={ + x=0, + y=0, + data="", + } + end + end + fontdata.pngshapes=shapes + end + end + function readers.cbdt(f,fontdata,specification) + end +end +function readers.stat(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"stat",true) + if tableoffset then + local extras=fontdata.extras + local version=readulong(f) + local axissize=readushort(f) + local nofaxis=readushort(f) + local axisoffset=readulong(f) + local nofvalues=readushort(f) + local valuesoffset=readulong(f) + local fallbackname=extras[readushort(f)] + local axis={} + local values={} + setposition(f,tableoffset+axisoffset) + for i=1,nofaxis do + local tag=readtag(f) + axis[i]={ + tag=tag, + name=lower(extras[readushort(f)] or tag), + ordering=readushort(f), + variants={} + } + end + setposition(f,tableoffset+valuesoffset) + for i=1,nofvalues do + values[i]=readushort(f) + end + for i=1,nofvalues do + setposition(f,tableoffset+valuesoffset+values[i]) + local format=readushort(f) + local index=readushort(f)+1 + local flags=readushort(f) + local name=lower(extras[readushort(f)] or "no name") + local value=readfixed(f) + local variant + if format==1 then + variant={ + flags=flags, + name=name, + value=value, + } + elseif format==2 then + variant={ + flags=flags, + name=name, + value=value, + minimum=readfixed(f), + maximum=readfixed(f), + } + elseif format==3 then + variant={ + flags=flags, + name=name, + value=value, + link=readfixed(f), + } + end + insert(axis[index].variants,variant) + end + sort(axis,function(a,b) + return a.ordering=lastto then + else + values[#values+1]={ from,to } + lastfrom,lastto=from,to + end + end + nofvalues=#values + if nofvalues>2 then + local some=values[1] + if some[1]==-1 and some[2]==-1 then + some=values[nofvalues] + if some[1]==1 and some[2]==1 then + for i=2,nofvalues-1 do + some=values[i] + if some[1]==0 and some[2]==0 then + return values + end + end + end + end + end + return false + end + local version=readulong(f) + local reserved=readushort(f) + local nofaxis=readushort(f) + local segments={} + for i=1,nofaxis do + segments[i]=collect() + end + setvariabledata(fontdata,"segments",segments) + end +end +function readers.fvar(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"fvar",true) + if tableoffset then + local version=readulong(f) + local offsettoaxis=tableoffset+readushort(f) + local reserved=skipshort(f) + local nofaxis=readushort(f) + local sizeofaxis=readushort(f) + local nofinstances=readushort(f) + local sizeofinstances=readushort(f) + local extras=fontdata.extras + local axis={} + local instances={} + setposition(f,offsettoaxis) + for i=1,nofaxis do + axis[i]={ + tag=readtag(f), + minimum=readfixed(f), + default=readfixed(f), + maximum=readfixed(f), + flags=readushort(f), + name=lower(extras[readushort(f)] or "bad name"), + } + local n=sizeofaxis-20 + if n>0 then + skipbytes(f,n) + elseif n<0 then + end + end + local nofbytes=2+2+2+nofaxis*4 + local readpsname=nofbytes<=sizeofinstances + local skippable=sizeofinstances-nofbytes + for i=1,nofinstances do + local subfamid=readushort(f) + local flags=readushort(f) + local values={} + for i=1,nofaxis do + values[i]={ + axis=axis[i].tag, + value=readfixed(f), + } + end + local psnameid=readpsname and readushort(f) or 0xFFFF + if subfamid==2 or subfamid==17 then + elseif subfamid==0xFFFF then + subfamid=nil + elseif subfamid<=256 or subfamid>=32768 then + subfamid=nil + end + if psnameid==6 then + elseif psnameid==0xFFFF then + psnameid=nil + elseif psnameid<=256 or psnameid>=32768 then + psnameid=nil + end + instances[i]={ + subfamily=extras[subfamid], + psname=psnameid and extras[psnameid] or nil, + values=values, + } + if skippable>0 then + skipbytes(f,skippable) + end + end + setvariabledata(fontdata,"axis",axis) + setvariabledata(fontdata,"instances",instances) + end +end +function readers.hvar(f,fontdata,specification) + local factors=specification.factors + if not factors then + return + end + local tableoffset=gotodatatable(f,fontdata,"hvar",specification.variable) + if not tableoffset then + return + end + local version=readulong(f) + local variationoffset=tableoffset+readulong(f) + local advanceoffset=tableoffset+readulong(f) + local lsboffset=tableoffset+readulong(f) + local rsboffset=tableoffset+readulong(f) + local regions={} + local variations={} + local innerindex={} + local outerindex={} + if variationoffset>0 then + regions,deltas=readvariationdata(f,variationoffset,factors) + end + if not regions then + return + end + if advanceoffset>0 then + setposition(f,advanceoffset) + local format=readushort(f) + local mapcount=readushort(f) + local entrysize=rshift(band(format,0x0030),4)+1 + local nofinnerbits=band(format,0x000F)+1 + local innermask=lshift(1,nofinnerbits)-1 + local readcardinal=read_cardinal[entrysize] + for i=0,mapcount-1 do + local mapdata=readcardinal(f) + outerindex[i]=rshift(mapdata,nofinnerbits) + innerindex[i]=band(mapdata,innermask) + end + setvariabledata(fontdata,"hvarwidths",true) + local glyphs=fontdata.glyphs + for i=0,fontdata.nofglyphs-1 do + local glyph=glyphs[i] + local width=glyph.width + if width then + local outer=outerindex[i] or 0 + local inner=innerindex[i] or i + if outer and inner then + local delta=deltas[outer+1] + if delta then + local d=delta.deltas[inner+1] + if d then + local scales=delta.scales + local deltaw=0 + for i=1,#scales do + local di=d[i] + if di then + deltaw=deltaw+scales[i]*di + else + break + end + end + glyph.width=width+round(deltaw) + end + end + end + end + end + end +end +function readers.vvar(f,fontdata,specification) + if not specification.variable then + return + end +end +function readers.mvar(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"mvar",specification.variable) + if tableoffset then + local version=readulong(f) + local reserved=skipshort(f,1) + local recordsize=readushort(f) + local nofrecords=readushort(f) + local offsettostore=tableoffset+readushort(f) + local dimensions={} + local factors=specification.factors + if factors then + local regions,deltas=readvariationdata(f,offsettostore,factors) + for i=1,nofrecords do + local tag=readtag(f) + local var=variabletags[tag] + if var then + local outer=readushort(f) + local inner=readushort(f) + local delta=deltas[outer+1] + if delta then + local d=delta.deltas[inner+1] + if d then + local scales=delta.scales + local dd=0 + for i=1,#scales do + dd=dd+scales[i]*d[i] + end + var(fontdata,round(dd)) + end + end + else + skipshort(f,2) + end + if recordsize>8 then + skipbytes(recordsize-8) + end + end + end + end +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-dsp”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-oup” 6f46aa00ae1c20c43f8ffaf329dc8695] --- + +if not modules then modules={} end modules ['font-oup']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next,type=next,type +local P,R,S=lpeg.P,lpeg.R,lpeg.S +local lpegmatch=lpeg.match +local insert,remove,copy,unpack=table.insert,table.remove,table.copy,table.unpack +local formatters=string.formatters +local sortedkeys=table.sortedkeys +local sortedhash=table.sortedhash +local tohash=table.tohash +local setmetatableindex=table.setmetatableindex +local report_error=logs.reporter("otf reader","error") +local report_markwidth=logs.reporter("otf reader","markwidth") +local report_cleanup=logs.reporter("otf reader","cleanup") +local report_optimizations=logs.reporter("otf reader","merges") +local report_unicodes=logs.reporter("otf reader","unicodes") +local trace_markwidth=false trackers.register("otf.markwidth",function(v) trace_markwidth=v end) +local trace_cleanup=false trackers.register("otf.cleanups",function(v) trace_cleanups=v end) +local trace_optimizations=false trackers.register("otf.optimizations",function(v) trace_optimizations=v end) +local trace_unicodes=false trackers.register("otf.unicodes",function(v) trace_unicodes=v end) +local readers=fonts.handlers.otf.readers +local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 +local f_private=formatters["P%05X"] +local f_unicode=formatters["U%05X"] +local f_index=formatters["I%05X"] +local f_character_y=formatters["%C"] +local f_character_n=formatters["[ %C ]"] +local check_duplicates=true +local check_soft_hyphen=true +directives.register("otf.checksofthyphen",function(v) + check_soft_hyphen=v +end) +local function replaced(list,index,replacement) + if type(list)=="number" then + return replacement + elseif type(replacement)=="table" then + local t={} + local n=index-1 + for i=1,n do + t[i]=list[i] + end + for i=1,#replacement do + n=n+1 + t[n]=replacement[i] + end + for i=index+1,#list do + n=n+1 + t[n]=list[i] + end + else + list[index]=replacement + return list + end +end +local function unifyresources(fontdata,indices) + local descriptions=fontdata.descriptions + local resources=fontdata.resources + if not descriptions or not resources then + return + end + local nofindices=#indices + local variants=fontdata.resources.variants + if variants then + for selector,unicodes in next,variants do + for unicode,index in next,unicodes do + unicodes[unicode]=indices[index] + end + end + end + local function remark(marks) + if marks then + local newmarks={} + for k,v in next,marks do + local u=indices[k] + if u then + newmarks[u]=v + elseif trace_optimizations then + report_optimizations("discarding mark %i",k) + end + end + return newmarks + end + end + local marks=resources.marks + if marks then + resources.marks=remark(marks) + end + local markclasses=resources.markclasses + if markclasses then + for class,marks in next,markclasses do + markclasses[class]=remark(marks) + end + end + local marksets=resources.marksets + if marksets then + for class,marks in next,marksets do + marksets[class]=remark(marks) + end + end + local done={} + local duplicates=check_duplicates and resources.duplicates + if duplicates and not next(duplicates) then + duplicates=false + end + local function recover(cover) + for i=1,#cover do + local c=cover[i] + if not done[c] then + local t={} + for k,v in next,c do + local ug=indices[k] + if ug then + t[ug]=v + else + report_error("case %i, bad index in unifying %s: %s of %s",1,"coverage",k,nofindices) + end + end + cover[i]=t + done[c]=d + end + end + end + local function recursed(c,kind) + local t={} + for g,d in next,c do + if type(d)=="table" then + local ug=indices[g] + if ug then + t[ug]=recursed(d,kind) + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g,nofindices) + end + else + t[g]=indices[d] + end + end + return t + end + local function unifythem(sequences) + if not sequences then + return + end + for i=1,#sequences do + local sequence=sequences[i] + local kind=sequence.type + local steps=sequence.steps + local features=sequence.features + if steps then + for i=1,#steps do + local step=steps[i] + if kind=="gsub_single" then + local c=step.coverage + if c then + local t1=done[c] + if not t1 then + t1={} + if duplicates then + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + local ud1=indices[d1] + if ud1 then + t1[ug1]=ud1 + local dg1=duplicates[ug1] + if dg1 then + for u in next,dg1 do + t1[u]=ud1 + end + end + else + report_error("case %i, bad index in unifying %s: %s of %s",3,kind,d1,nofindices) + end + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) + end + end + else + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + t1[ug1]=indices[d1] + else + report_error("fuzzy case %i in unifying %s: %i",2,kind,g1) + end + end + end + done[c]=t1 + end + step.coverage=t1 + end + elseif kind=="gpos_pair" then + local c=step.coverage + if c then + local t1=done[c] + if not t1 then + t1={} + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + local t2=done[d1] + if not t2 then + t2={} + for g2,d2 in next,d1 do + local ug2=indices[g2] + if ug2 then + t2[ug2]=d2 + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g2,nofindices,nofindices) + end + end + done[d1]=t2 + end + t1[ug1]=t2 + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) + end + end + done[c]=t1 + end + step.coverage=t1 + end + elseif kind=="gsub_ligature" then + local c=step.coverage + if c then + step.coverage=recursed(c,kind) + end + elseif kind=="gsub_alternate" or kind=="gsub_multiple" then + local c=step.coverage + if c then + local t1=done[c] + if not t1 then + t1={} + if duplicates then + for g1,d1 in next,c do + for i=1,#d1 do + local d1i=d1[i] + local d1u=indices[d1i] + if d1u then + d1[i]=d1u + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,i,d1i,nofindices) + end + end + local ug1=indices[g1] + if ug1 then + t1[ug1]=d1 + local dg1=duplicates[ug1] + if dg1 then + for u in next,dg1 do + t1[u]=copy(d1) + end + end + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) + end + end + else + for g1,d1 in next,c do + for i=1,#d1 do + local d1i=d1[i] + local d1u=indices[d1i] + if d1u then + d1[i]=d1u + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,d1i,nofindices) + end + end + t1[indices[g1]]=d1 + end + end + done[c]=t1 + end + step.coverage=t1 + end + elseif kind=="gpos_single" then + local c=step.coverage + if c then + local t1=done[c] + if not t1 then + t1={} + if duplicates then + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + t1[ug1]=d1 + local dg1=duplicates[ug1] + if dg1 then + for u in next,dg1 do + t1[u]=d1 + end + end + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) + end + end + else + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + t1[ug1]=d1 + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) + end + end + end + done[c]=t1 + end + step.coverage=t1 + end + elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" or kind=="gpos_mark2ligature" then + local c=step.coverage + if c then + local t1=done[c] + if not t1 then + t1={} + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + t1[ug1]=d1 + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) + end + end + done[c]=t1 + end + step.coverage=t1 + end + local c=step.baseclasses + if c then + local t1=done[c] + if not t1 then + for g1,d1 in next,c do + local t2=done[d1] + if not t2 then + t2={} + for g2,d2 in next,d1 do + local ug2=indices[g2] + if ug2 then + t2[ug2]=d2 + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g2,nofindices) + end + end + done[d1]=t2 + end + c[g1]=t2 + end + done[c]=c + end + end + elseif kind=="gpos_cursive" then + local c=step.coverage + if c then + local t1=done[c] + if not t1 then + t1={} + if duplicates then + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + t1[ug1]=d1 + local dg1=duplicates[ug1] + if dg1 then + for u in next,dg1 do + t1[u]=copy(d1) + end + end + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) + end + end + else + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + t1[ug1]=d1 + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) + end + end + end + done[c]=t1 + end + step.coverage=t1 + end + end + local rules=step.rules + if rules then + for i=1,#rules do + local rule=rules[i] + local before=rule.before if before then recover(before) end + local after=rule.after if after then recover(after) end + local current=rule.current if current then recover(current) end + local replacements=rule.replacements + if replacements then + if not done[replacements] then + local r={} + for k,v in next,replacements do + r[indices[k]]=indices[v] + end + rule.replacements=r + done[replacements]=r + end + end + end + end + end + end + end + end + unifythem(resources.sequences) + unifythem(resources.sublookups) +end +local function copyduplicates(fontdata) + if check_duplicates then + local descriptions=fontdata.descriptions + local resources=fontdata.resources + local duplicates=resources.duplicates + if check_soft_hyphen then + local ds=descriptions[0xAD] + if not ds or ds.width==0 then + if ds then + descriptions[0xAD]=nil + if trace_unicodes then + report_unicodes("patching soft hyphen") + end + else + if trace_unicodes then + report_unicodes("adding soft hyphen") + end + end + if not duplicates then + duplicates={} + resources.duplicates=duplicates + end + local dh=duplicates[0x2D] + if dh then + dh[#dh+1]={ [0xAD]=true } + else + duplicates[0x2D]={ [0xAD]=true } + end + end + end + if duplicates then + for u,d in next,duplicates do + local du=descriptions[u] + if du then + local t={ f_character_y(u),"@",f_index(du.index),"->" } + local n=0 + local m=25 + for u in next,d do + if descriptions[u] then + if n0 then + t={} + n=0 + local loops=0 + while true do + loops=loops+1 + local old=nofmissing + for i=1,#ligatures do + recursed(ligatures[i]) + end + if nofmissing<=0 then + if trace_unicodes then + report_unicodes("all missings done in %s loops",loops) + end + return + elseif old==nofmissing then + break + end + end + t=nil + n=0 + end + if trace_unicodes and nofmissing>0 then + local done={} + for i,r in next,missing do + if r then + local data=descriptions[i] + local name=data and data.name or f_index(i) + if not ignore[name] then + done[name]=true + end + end + end + if next(done) then + report_unicodes("not unicoded: % t",sortedkeys(done)) + end + end +end +local firstprivate=fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000 +local puafirst=0xE000 +local pualast=0xF8FF +local function unifymissing(fontdata) + if not fonts.mappings then + require("font-map") + require("font-agl") + end + local unicodes={} + local resources=fontdata.resources + resources.unicodes=unicodes + for unicode,d in next,fontdata.descriptions do + if unicode=puafirst and unicode<=pualast then + else + local name=d.name + if name then + unicodes[name]=unicode + end + end + else + end + end + fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups) + resources.unicodes=nil +end +local function unifyglyphs(fontdata,usenames) + local private=fontdata.private or privateoffset + local glyphs=fontdata.glyphs + local indices={} + local descriptions={} + local names=usenames and {} + local resources=fontdata.resources + local zero=glyphs[0] + local zerocode=zero.unicode + if not zerocode then + zerocode=private + zero.unicode=zerocode + private=private+1 + end + descriptions[zerocode]=zero + if names then + local name=glyphs[0].name or f_private(zerocode) + indices[0]=name + names[name]=zerocode + else + indices[0]=zerocode + end + if names then + for index=1,#glyphs do + local glyph=glyphs[index] + local unicode=glyph.unicode + if not unicode then + unicode=private + local name=glyph.name or f_private(unicode) + indices[index]=name + names[name]=unicode + private=private+1 + elseif unicode>=firstprivate then + unicode=private + local name=glyph.name or f_private(unicode) + indices[index]=name + names[name]=unicode + private=private+1 + elseif unicode>=puafirst and unicode<=pualast then + local name=glyph.name or f_private(unicode) + indices[index]=name + names[name]=unicode + elseif descriptions[unicode] then + unicode=private + local name=glyph.name or f_private(unicode) + indices[index]=name + names[name]=unicode + private=private+1 + else + local name=glyph.name or f_unicode(unicode) + indices[index]=name + names[name]=unicode + end + descriptions[unicode]=glyph + end + elseif trace_unicodes then + for index=1,#glyphs do + local glyph=glyphs[index] + local unicode=glyph.unicode + if not unicode then + unicode=private + indices[index]=unicode + private=private+1 + elseif unicode>=firstprivate then + local name=glyph.name + if name then + report_unicodes("moving glyph %a indexed %05X from private %U to %U ",name,index,unicode,private) + else + report_unicodes("moving glyph indexed %05X from private %U to %U ",index,unicode,private) + end + unicode=private + indices[index]=unicode + private=private+1 + elseif unicode>=puafirst and unicode<=pualast then + local name=glyph.name + if name then + report_unicodes("keeping private unicode %U for glyph %a indexed %05X",unicode,name,index) + else + report_unicodes("keeping private unicode %U for glyph indexed %05X",unicode,index) + end + indices[index]=unicode + elseif descriptions[unicode] then + local name=glyph.name + if name then + report_unicodes("assigning duplicate unicode %U to %U for glyph %a indexed %05X ",unicode,private,name,index) + else + report_unicodes("assigning duplicate unicode %U to %U for glyph indexed %05X ",unicode,private,index) + end + unicode=private + indices[index]=unicode + private=private+1 + else + indices[index]=unicode + end + descriptions[unicode]=glyph + end + else + for index=1,#glyphs do + local glyph=glyphs[index] + local unicode=glyph.unicode + if not unicode then + unicode=private + indices[index]=unicode + private=private+1 + elseif unicode>=firstprivate then + local name=glyph.name + unicode=private + indices[index]=unicode + private=private+1 + elseif unicode>=puafirst and unicode<=pualast then + local name=glyph.name + indices[index]=unicode + elseif descriptions[unicode] then + local name=glyph.name + unicode=private + indices[index]=unicode + private=private+1 + else + indices[index]=unicode + end + descriptions[unicode]=glyph + end + end + for index=1,#glyphs do + local math=glyphs[index].math + if math then + local list=math.vparts + if list then + for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end + end + local list=math.hparts + if list then + for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end + end + local list=math.vvariants + if list then + for i=1,#list do list[i]=indices[list[i]] end + end + local list=math.hvariants + if list then + for i=1,#list do list[i]=indices[list[i]] end + end + end + end + local colorpalettes=resources.colorpalettes + if colorpalettes then + for index=1,#glyphs do + local colors=glyphs[index].colors + if colors then + for i=1,#colors do + local c=colors[i] + c.slot=indices[c.slot] + end + end + end + end + fontdata.private=private + fontdata.glyphs=nil + fontdata.names=names + fontdata.descriptions=descriptions + fontdata.hashmethod=hashmethod + return indices,names +end +local p_crappyname do + local p_hex=R("af","AF","09") + local p_digit=R("09") + local p_done=S("._-")^0+P(-1) + local p_alpha=R("az","AZ") + local p_ALPHA=R("AZ") + p_crappyname=( + lpeg.utfchartabletopattern({ "uni","u" },true)*S("Xx_")^0*p_hex^1 ++lpeg.utfchartabletopattern({ "identity","glyph","jamo" },true)*p_hex^1 ++lpeg.utfchartabletopattern({ "index","afii" },true)*p_digit^1 ++p_digit*p_hex^3+p_alpha*p_digit^1 ++P("aj")*p_digit^1+P("eh_")*(p_digit^1+p_ALPHA*p_digit^1)+(1-P("_"))^1*P("_uni")*p_hex^1+P("_")*P(1)^1 + )*p_done +end +local forcekeep=false +directives.register("otf.keepnames",function(v) + report_cleanup("keeping weird glyph names, expect larger files and more memory usage") + forcekeep=v +end) +local function stripredundant(fontdata) + local descriptions=fontdata.descriptions + if descriptions then + local n=0 + local c=0 + if (not context and fonts.privateoffsets.keepnames) or forcekeep then + for unicode,d in next,descriptions do + if d.class=="base" then + d.class=nil + c=c+1 + end + end + else + for unicode,d in next,descriptions do + local name=d.name + if name and lpegmatch(p_crappyname,name) then + d.name=nil + n=n+1 + end + if d.class=="base" then + d.class=nil + c=c+1 + end + end + end + if trace_cleanup then + if n>0 then + report_cleanup("%s bogus names removed (verbose unicode)",n) + end + if c>0 then + report_cleanup("%s base class tags removed (default is base)",c) + end + end + end +end +readers.stripredundant=stripredundant +function readers.getcomponents(fontdata) + local resources=fontdata.resources + if resources then + local sequences=resources.sequences + if sequences then + local collected={} + for i=1,#sequences do + local sequence=sequences[i] + if sequence.type=="gsub_ligature" then + local steps=sequence.steps + if steps then + local l={} + local function traverse(p,k,v) + if k=="ligature" then + collected[v]={ unpack(l) } + else + insert(l,k) + for k,vv in next,v do + traverse(p,k,vv) + end + remove(l) + end + end + for i=1,#steps do + local c=steps[i].coverage + if c then + for k,v in next,c do + traverse(k,k,v) + end + end + end + end + end + end + if next(collected) then + while true do + local done=false + for k,v in next,collected do + for i=1,#v do + local vi=v[i] + if vi==k then + collected[k]=nil + break + else + local c=collected[vi] + if c then + done=true + local t={} + local n=i-1 + for j=1,n do + t[j]=v[j] + end + for j=1,#c do + n=n+1 + t[n]=c[j] + end + for j=i+1,#v do + n=n+1 + t[n]=v[j] + end + collected[k]=t + break + end + end + end + end + if not done then + break + end + end + return collected + end + end + end +end +readers.unifymissing=unifymissing +function readers.rehash(fontdata,hashmethod) + if not (fontdata and fontdata.glyphs) then + return + end + if hashmethod=="indices" then + fontdata.hashmethod="indices" + elseif hashmethod=="names" then + fontdata.hashmethod="names" + local indices=unifyglyphs(fontdata,true) + unifyresources(fontdata,indices) + copyduplicates(fontdata) + unifymissing(fontdata) + else + fontdata.hashmethod="unicodes" + local indices=unifyglyphs(fontdata) + unifyresources(fontdata,indices) + copyduplicates(fontdata) + unifymissing(fontdata) + stripredundant(fontdata) + end +end +function readers.checkhash(fontdata) + local hashmethod=fontdata.hashmethod + if hashmethod=="unicodes" then + fontdata.names=nil + elseif hashmethod=="names" and fontdata.names then + unifyresources(fontdata,fontdata.names) + copyduplicates(fontdata) + fontdata.hashmethod="unicodes" + fontdata.names=nil + else + readers.rehash(fontdata,"unicodes") + end +end +function readers.addunicodetable(fontdata) + local resources=fontdata.resources + local unicodes=resources.unicodes + if not unicodes then + local descriptions=fontdata.descriptions + if descriptions then + unicodes={} + resources.unicodes=unicodes + for u,d in next,descriptions do + local n=d.name + if n then + unicodes[n]=u + end + end + end + end +end +local concat,sort=table.concat,table.sort +local next,type,tostring=next,type,tostring +local criterium=1 +local threshold=0 +local trace_packing=false trackers.register("otf.packing",function(v) trace_packing=v end) +local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) +local report_otf=logs.reporter("fonts","otf loading") +local function tabstr_normal(t) + local s={} + local n=0 + for k,v in next,t do + n=n+1 + if type(v)=="table" then + s[n]=k..">"..tabstr_normal(v) + elseif v==true then + s[n]=k.."+" + elseif v then + s[n]=k.."="..v + else + s[n]=k.."-" + end + end + if n==0 then + return "" + elseif n==1 then + return s[1] + else + sort(s) + return concat(s,",") + end +end +local function tabstr_flat(t) + local s={} + local n=0 + for k,v in next,t do + n=n+1 + s[n]=k.."="..v + end + if n==0 then + return "" + elseif n==1 then + return s[1] + else + sort(s) + return concat(s,",") + end +end +local function tabstr_mixed(t) + local s={} + local n=#t + if n==0 then + return "" + elseif n==1 then + local k=t[1] + if k==true then + return "++" + elseif k==false then + return "--" + else + return tostring(k) + end + else + for i=1,n do + local k=t[i] + if k==true then + s[i]="++" + elseif k==false then + s[i]="--" + else + s[i]=k + end + end + return concat(s,",") + end +end +local function tabstr_boolean(t) + local s={} + local n=0 + for k,v in next,t do + n=n+1 + if v then + s[n]=k.."+" + else + s[n]=k.."-" + end + end + if n==0 then + return "" + elseif n==1 then + return s[1] + else + sort(s) + return concat(s,",") + end +end +function readers.pack(data) + if data then + local h,t,c={},{},{} + local hh,tt,cc={},{},{} + local nt,ntt=0,0 + local function pack_normal(v) + local tag=tabstr_normal(v) + local ht=h[tag] + if ht then + c[ht]=c[ht]+1 + return ht + else + nt=nt+1 + t[nt]=v + h[tag]=nt + c[nt]=1 + return nt + end + end + local function pack_normal_cc(v) + local tag=tabstr_normal(v) + local ht=h[tag] + if ht then + c[ht]=c[ht]+1 + return ht + else + v[1]=0 + nt=nt+1 + t[nt]=v + h[tag]=nt + c[nt]=1 + return nt + end + end + local function pack_flat(v) + local tag=tabstr_flat(v) + local ht=h[tag] + if ht then + c[ht]=c[ht]+1 + return ht + else + nt=nt+1 + t[nt]=v + h[tag]=nt + c[nt]=1 + return nt + end + end + local function pack_indexed(v) + local tag=concat(v," ") + local ht=h[tag] + if ht then + c[ht]=c[ht]+1 + return ht + else + nt=nt+1 + t[nt]=v + h[tag]=nt + c[nt]=1 + return nt + end + end + local function pack_mixed(v) + local tag=tabstr_mixed(v) + local ht=h[tag] + if ht then + c[ht]=c[ht]+1 + return ht + else + nt=nt+1 + t[nt]=v + h[tag]=nt + c[nt]=1 + return nt + end + end + local function pack_boolean(v) + local tag=tabstr_boolean(v) + local ht=h[tag] + if ht then + c[ht]=c[ht]+1 + return ht + else + nt=nt+1 + t[nt]=v + h[tag]=nt + c[nt]=1 + return nt + end + end + local function pack_final(v) + if c[v]<=criterium then + return t[v] + else + local hv=hh[v] + if hv then + return hv + else + ntt=ntt+1 + tt[ntt]=t[v] + hh[v]=ntt + cc[ntt]=c[v] + return ntt + end + end + end + local function pack_final_cc(v) + if c[v]<=criterium then + return t[v] + else + local hv=hh[v] + if hv then + return hv + else + ntt=ntt+1 + tt[ntt]=t[v] + hh[v]=ntt + cc[ntt]=c[v] + return ntt + end + end + end + local function success(stage,pass) + if nt==0 then + if trace_loading or trace_packing then + report_otf("pack quality: nothing to pack") + end + return false + elseif nt>=threshold then + local one=0 + local two=0 + local rest=0 + if pass==1 then + for k,v in next,c do + if v==1 then + one=one+1 + elseif v==2 then + two=two+1 + else + rest=rest+1 + end + end + else + for k,v in next,cc do + if v>20 then + rest=rest+1 + elseif v>10 then + two=two+1 + else + one=one+1 + end + end + data.tables=tt + end + if trace_loading or trace_packing then + report_otf("pack quality: stage %s, pass %s, %s packed, 1-10:%s, 11-20:%s, rest:%s (criterium: %s)", + stage,pass,one+two+rest,one,two,rest,criterium) + end + return true + else + if trace_loading or trace_packing then + report_otf("pack quality: stage %s, pass %s, %s packed, aborting pack (threshold: %s)", + stage,pass,nt,threshold) + end + return false + end + end + local function packers(pass) + if pass==1 then + return pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc + else + return pack_final,pack_final,pack_final,pack_final,pack_final,pack_final_cc + end + end + local resources=data.resources + local sequences=resources.sequences + local sublookups=resources.sublookups + local features=resources.features + local palettes=resources.colorpalettes + local variable=resources.variabledata + local chardata=characters and characters.data + local descriptions=data.descriptions or data.glyphs + if not descriptions then + return + end + for pass=1,2 do + if trace_packing then + report_otf("start packing: stage 1, pass %s",pass) + end + local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass) + for unicode,description in next,descriptions do + local boundingbox=description.boundingbox + if boundingbox then + description.boundingbox=pack_indexed(boundingbox) + end + local math=description.math + if math then + local kerns=math.kerns + if kerns then + for tag,kern in next,kerns do + kerns[tag]=pack_normal(kern) + end + end + end + end + local function packthem(sequences) + for i=1,#sequences do + local sequence=sequences[i] + local kind=sequence.type + local steps=sequence.steps + local order=sequence.order + local features=sequence.features + local flags=sequence.flags + if steps then + for i=1,#steps do + local step=steps[i] + if kind=="gpos_pair" then + local c=step.coverage + if c then + if step.format~="pair" then + for g1,d1 in next,c do + c[g1]=pack_normal(d1) + end + elseif step.shared then + local shared={} + for g1,d1 in next,c do + for g2,d2 in next,d1 do + if not shared[d2] then + local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end + local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end + shared[d2]=true + end + end + end + if pass==2 then + step.shared=nil + end + else + for g1,d1 in next,c do + for g2,d2 in next,d1 do + local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end + local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end + end + end + end + end + elseif kind=="gpos_single" then + local c=step.coverage + if c then + if step.format=="single" then + for g1,d1 in next,c do + if d1 and d1~=true then + c[g1]=pack_indexed(d1) + end + end + else + step.coverage=pack_normal(c) + end + end + elseif kind=="gpos_cursive" then + local c=step.coverage + if c then + for g1,d1 in next,c do + local f=d1[2] if f then d1[2]=pack_indexed(f) end + local s=d1[3] if s then d1[3]=pack_indexed(s) end + end + end + elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then + local c=step.baseclasses + if c then + for g1,d1 in next,c do + for g2,d2 in next,d1 do + d1[g2]=pack_indexed(d2) + end + end + end + local c=step.coverage + if c then + for g1,d1 in next,c do + d1[2]=pack_indexed(d1[2]) + end + end + elseif kind=="gpos_mark2ligature" then + local c=step.baseclasses + if c then + for g1,d1 in next,c do + for g2,d2 in next,d1 do + for g3,d3 in next,d2 do + d2[g3]=pack_indexed(d3) + end + end + end + end + local c=step.coverage + if c then + for g1,d1 in next,c do + d1[2]=pack_indexed(d1[2]) + end + end + end + local rules=step.rules + if rules then + for i=1,#rules do + local rule=rules[i] + local r=rule.before if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end + local r=rule.after if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end + local r=rule.current if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end + local r=rule.replacements if r then rule.replacements=pack_flat (r) end + end + end + end + end + if order then + sequence.order=pack_indexed(order) + end + if features then + for script,feature in next,features do + features[script]=pack_normal(feature) + end + end + if flags then + sequence.flags=pack_normal(flags) + end + end + end + if sequences then + packthem(sequences) + end + if sublookups then + packthem(sublookups) + end + if features then + for k,list in next,features do + for feature,spec in next,list do + list[feature]=pack_normal(spec) + end + end + end + if palettes then + for i=1,#palettes do + local p=palettes[i] + for j=1,#p do + p[j]=pack_indexed(p[j]) + end + end + end + if variable then + local instances=variable.instances + if instances then + for i=1,#instances do + local v=instances[i].values + for j=1,#v do + v[j]=pack_normal(v[j]) + end + end + end + local function packdeltas(main) + if main then + local deltas=main.deltas + if deltas then + for i=1,#deltas do + local di=deltas[i] + local d=di.deltas + for j=1,#d do + d[j]=pack_indexed(d[j]) + end + di.regions=pack_indexed(di.regions) + end + end + local regions=main.regions + if regions then + for i=1,#regions do + local r=regions[i] + for j=1,#r do + r[j]=pack_normal(r[j]) + end + end + end + end + end + packdeltas(variable.global) + packdeltas(variable.horizontal) + packdeltas(variable.vertical) + packdeltas(variable.metrics) + end + if not success(1,pass) then + return + end + end + if nt>0 then + for pass=1,2 do + if trace_packing then + report_otf("start packing: stage 2, pass %s",pass) + end + local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass) + for unicode,description in next,descriptions do + local math=description.math + if math then + local kerns=math.kerns + if kerns then + math.kerns=pack_normal(kerns) + end + end + end + local function packthem(sequences) + for i=1,#sequences do + local sequence=sequences[i] + local kind=sequence.type + local steps=sequence.steps + local features=sequence.features + if steps then + for i=1,#steps do + local step=steps[i] + if kind=="gpos_pair" then + local c=step.coverage + if c then + if step.format=="pair" then + for g1,d1 in next,c do + for g2,d2 in next,d1 do + d1[g2]=pack_normal(d2) + end + end + end + end + elseif kind=="gpos_mark2ligature" then + local c=step.baseclasses + if c then + for g1,d1 in next,c do + for g2,d2 in next,d1 do + d1[g2]=pack_normal(d2) + end + end + end + end + local rules=step.rules + if rules then + for i=1,#rules do + local rule=rules[i] + local r=rule.before if r then rule.before=pack_normal(r) end + local r=rule.after if r then rule.after=pack_normal(r) end + local r=rule.current if r then rule.current=pack_normal(r) end + end + end + end + end + if features then + sequence.features=pack_normal(features) + end + end + end + if sequences then + packthem(sequences) + end + if sublookups then + packthem(sublookups) + end + if variable then + local function unpackdeltas(main) + if main then + local regions=main.regions + if regions then + main.regions=pack_normal(regions) + end + end + end + unpackdeltas(variable.global) + unpackdeltas(variable.horizontal) + unpackdeltas(variable.vertical) + unpackdeltas(variable.metrics) + end + end + for pass=1,2 do + if trace_packing then + report_otf("start packing: stage 3, pass %s",pass) + end + local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass) + local function packthem(sequences) + for i=1,#sequences do + local sequence=sequences[i] + local kind=sequence.type + local steps=sequence.steps + local features=sequence.features + if steps then + for i=1,#steps do + local step=steps[i] + if kind=="gpos_pair" then + local c=step.coverage + if c then + if step.format=="pair" then + for g1,d1 in next,c do + c[g1]=pack_normal(d1) + end + end + end + elseif kind=="gpos_cursive" then + local c=step.coverage + if c then + for g1,d1 in next,c do + c[g1]=pack_normal_cc(d1) + end + end + end + end + end + end + end + if sequences then + packthem(sequences) + end + if sublookups then + packthem(sublookups) + end + end + end + end +end +local unpacked_mt={ + __index=function(t,k) + t[k]=false + return k + end +} +function readers.unpack(data) + if data then + local tables=data.tables + if tables then + local resources=data.resources + local descriptions=data.descriptions or data.glyphs + local sequences=resources.sequences + local sublookups=resources.sublookups + local features=resources.features + local palettes=resources.colorpalettes + local variable=resources.variabledata + local unpacked={} + setmetatable(unpacked,unpacked_mt) + for unicode,description in next,descriptions do + local tv=tables[description.boundingbox] + if tv then + description.boundingbox=tv + end + local math=description.math + if math then + local kerns=math.kerns + if kerns then + local tm=tables[kerns] + if tm then + math.kerns=tm + kerns=unpacked[tm] + end + if kerns then + for k,kern in next,kerns do + local tv=tables[kern] + if tv then + kerns[k]=tv + end + end + end + end + end + end + local function unpackthem(sequences) + for i=1,#sequences do + local sequence=sequences[i] + local kind=sequence.type + local steps=sequence.steps + local order=sequence.order + local features=sequence.features + local flags=sequence.flags + local markclass=sequence.markclass + if features then + local tv=tables[features] + if tv then + sequence.features=tv + features=tv + end + for script,feature in next,features do + local tv=tables[feature] + if tv then + features[script]=tv + end + end + end + if steps then + for i=1,#steps do + local step=steps[i] + if kind=="gpos_pair" then + local c=step.coverage + if c then + if step.format=="pair" then + for g1,d1 in next,c do + local tv=tables[d1] + if tv then + c[g1]=tv + d1=tv + end + for g2,d2 in next,d1 do + local tv=tables[d2] + if tv then + d1[g2]=tv + d2=tv + end + local f=tables[d2[1]] if f then d2[1]=f end + local s=tables[d2[2]] if s then d2[2]=s end + end + end + else + for g1,d1 in next,c do + local tv=tables[d1] + if tv then + c[g1]=tv + end + end + end + end + elseif kind=="gpos_single" then + local c=step.coverage + if c then + if step.format=="single" then + for g1,d1 in next,c do + local tv=tables[d1] + if tv then + c[g1]=tv + end + end + else + local tv=tables[c] + if tv then + step.coverage=tv + end + end + end + elseif kind=="gpos_cursive" then + local c=step.coverage + if c then + for g1,d1 in next,c do + local tv=tables[d1] + if tv then + d1=tv + c[g1]=d1 + end + local f=tables[d1[2]] if f then d1[2]=f end + local s=tables[d1[3]] if s then d1[3]=s end + end + end + elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then + local c=step.baseclasses + if c then + for g1,d1 in next,c do + for g2,d2 in next,d1 do + local tv=tables[d2] + if tv then + d1[g2]=tv + end + end + end + end + local c=step.coverage + if c then + for g1,d1 in next,c do + local tv=tables[d1[2]] + if tv then + d1[2]=tv + end + end + end + elseif kind=="gpos_mark2ligature" then + local c=step.baseclasses + if c then + for g1,d1 in next,c do + for g2,d2 in next,d1 do + local tv=tables[d2] + if tv then + d2=tv + d1[g2]=d2 + end + for g3,d3 in next,d2 do + local tv=tables[d2[g3]] + if tv then + d2[g3]=tv + end + end + end + end + end + local c=step.coverage + if c then + for g1,d1 in next,c do + local tv=tables[d1[2]] + if tv then + d1[2]=tv + end + end + end + end + local rules=step.rules + if rules then + for i=1,#rules do + local rule=rules[i] + local before=rule.before + if before then + local tv=tables[before] + if tv then + rule.before=tv + before=tv + end + for i=1,#before do + local tv=tables[before[i]] + if tv then + before[i]=tv + end + end + end + local after=rule.after + if after then + local tv=tables[after] + if tv then + rule.after=tv + after=tv + end + for i=1,#after do + local tv=tables[after[i]] + if tv then + after[i]=tv + end + end + end + local current=rule.current + if current then + local tv=tables[current] + if tv then + rule.current=tv + current=tv + end + for i=1,#current do + local tv=tables[current[i]] + if tv then + current[i]=tv + end + end + end + local replacements=rule.replacements + if replacements then + local tv=tables[replacements] + if tv then + rule.replacements=tv + end + end + end + end + end + end + if order then + local tv=tables[order] + if tv then + sequence.order=tv + end + end + if flags then + local tv=tables[flags] + if tv then + sequence.flags=tv + end + end + end + end + if sequences then + unpackthem(sequences) + end + if sublookups then + unpackthem(sublookups) + end + if features then + for k,list in next,features do + for feature,spec in next,list do + local tv=tables[spec] + if tv then + list[feature]=tv + end + end + end + end + if palettes then + for i=1,#palettes do + local p=palettes[i] + for j=1,#p do + local tv=tables[p[j]] + if tv then + p[j]=tv + end + end + end + end + if variable then + local instances=variable.instances + if instances then + for i=1,#instances do + local v=instances[i].values + for j=1,#v do + local tv=tables[v[j]] + if tv then + v[j]=tv + end + end + end + end + local function unpackdeltas(main) + if main then + local deltas=main.deltas + if deltas then + for i=1,#deltas do + local di=deltas[i] + local d=di.deltas + local r=di.regions + for j=1,#d do + local tv=tables[d[j]] + if tv then + d[j]=tv + end + end + local tv=di.regions + if tv then + di.regions=tv + end + end + end + local regions=main.regions + if regions then + local tv=tables[regions] + if tv then + main.regions=tv + regions=tv + end + for i=1,#regions do + local r=regions[i] + for j=1,#r do + local tv=tables[r[j]] + if tv then + r[j]=tv + end + end + end + end + end + end + unpackdeltas(variable.global) + unpackdeltas(variable.horizontal) + unpackdeltas(variable.vertical) + unpackdeltas(variable.metrics) + end + data.tables=nil + end + end +end +local mt={ + __index=function(t,k) + if k=="height" then + local ht=t.boundingbox[4] + return ht<0 and 0 or ht + elseif k=="depth" then + local dp=-t.boundingbox[2] + return dp<0 and 0 or dp + elseif k=="width" then + return 0 + elseif k=="name" then + return forcenotdef and ".notdef" + end + end +} +local function sameformat(sequence,steps,first,nofsteps,kind) + return true +end +local function mergesteps_1(lookup,strict) + local steps=lookup.steps + local nofsteps=lookup.nofsteps + local first=steps[1] + if strict then + local f=first.format + for i=2,nofsteps do + if steps[i].format~=f then + if trace_optimizations then + report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name) + end + return 0 + end + end + end + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end + local target=first.coverage + for i=2,nofsteps do + local c=steps[i].coverage + if c then + for k,v in next,c do + if not target[k] then + target[k]=v + end + end + end + end + lookup.nofsteps=1 + lookup.merged=true + lookup.steps={ first } + return nofsteps-1 +end +local function mergesteps_2(lookup) + local steps=lookup.steps + local nofsteps=lookup.nofsteps + local first=steps[1] + if strict then + local f=first.format + for i=2,nofsteps do + if steps[i].format~=f then + if trace_optimizations then + report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name) + end + return 0 + end + end + end + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end + local target=first.coverage + for i=2,nofsteps do + local c=steps[i].coverage + if c then + for k,v in next,c do + local tk=target[k] + if tk then + for kk,vv in next,v do + if tk[kk]==nil then + tk[kk]=vv + end + end + else + target[k]=v + end + end + end + end + lookup.nofsteps=1 + lookup.merged=true + lookup.steps={ first } + return nofsteps-1 +end +local function mergesteps_3(lookup,strict) + local steps=lookup.steps + local nofsteps=lookup.nofsteps + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end + local coverage={} + for i=1,nofsteps do + local c=steps[i].coverage + if c then + for k,v in next,c do + local tk=coverage[k] + if tk then + if trace_optimizations then + report_optimizations("quitting merge due to multiple checks") + end + return nofsteps + else + coverage[k]=v + end + end + end + end + local first=steps[1] + local baseclasses={} + for i=1,nofsteps do + local offset=i*10 + local step=steps[i] + for k,v in sortedhash(step.baseclasses) do + baseclasses[offset+k]=v + end + for k,v in next,step.coverage do + v[1]=offset+v[1] + end + end + first.baseclasses=baseclasses + first.coverage=coverage + lookup.nofsteps=1 + lookup.merged=true + lookup.steps={ first } + return nofsteps-1 +end +local function nested(old,new) + for k,v in next,old do + if k=="ligature" then + if not new.ligature then + new.ligature=v + end + else + local n=new[k] + if n then + nested(v,n) + else + new[k]=v + end + end + end +end +local function mergesteps_4(lookup) + local steps=lookup.steps + local nofsteps=lookup.nofsteps + local first=steps[1] + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end + local target=first.coverage + for i=2,nofsteps do + local c=steps[i].coverage + if c then + for k,v in next,c do + local tk=target[k] + if tk then + nested(v,tk) + else + target[k]=v + end + end + end + end + lookup.nofsteps=1 + lookup.steps={ first } + return nofsteps-1 +end +local function mergesteps_5(lookup) + local steps=lookup.steps + local nofsteps=lookup.nofsteps + local first=steps[1] + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end + local target=first.coverage + local hash=nil + for k,v in next,target do + hash=v[1] + break + end + for i=2,nofsteps do + local c=steps[i].coverage + if c then + for k,v in next,c do + local tk=target[k] + if tk then + if not tk[2] then + tk[2]=v[2] + end + if not tk[3] then + tk[3]=v[3] + end + else + target[k]=v + v[1]=hash + end + end + end + end + lookup.nofsteps=1 + lookup.merged=true + lookup.steps={ first } + return nofsteps-1 +end +local function checkkerns(lookup) + local steps=lookup.steps + local nofsteps=lookup.nofsteps + local kerned=0 + for i=1,nofsteps do + local step=steps[i] + if step.format=="pair" then + local coverage=step.coverage + local kerns=true + for g1,d1 in next,coverage do + if d1==true then + elseif not d1 then + elseif d1[1]~=0 or d1[2]~=0 or d1[4]~=0 then + kerns=false + break + end + end + if kerns then + if trace_optimizations then + report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) + end + local c={} + for g1,d1 in next,coverage do + if d1 and d1~=true then + c[g1]=d1[3] + end + end + step.coverage=c + step.format="move" + kerned=kerned+1 + end + end + end + return kerned +end +local function checkpairs(lookup) + local steps=lookup.steps + local nofsteps=lookup.nofsteps + local kerned=0 + local function onlykerns(step) + local coverage=step.coverage + for g1,d1 in next,coverage do + for g2,d2 in next,d1 do + if d2[2] then + return false + else + local v=d2[1] + if v==true then + elseif v and (v[1]~=0 or v[2]~=0 or v[4]~=0) then + return false + end + end + end + end + return coverage + end + for i=1,nofsteps do + local step=steps[i] + if step.format=="pair" then + local coverage=onlykerns(step) + if coverage then + if trace_optimizations then + report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) + end + for g1,d1 in next,coverage do + local d={} + for g2,d2 in next,d1 do + local v=d2[1] + if v==true then + elseif v then + d[g2]=v[3] + end + end + coverage[g1]=d + end + step.format="move" + kerned=kerned+1 + end + end + end + return kerned +end +local compact_pairs=true +local compact_singles=true +local merge_pairs=true +local merge_singles=true +local merge_substitutions=true +local merge_alternates=true +local merge_multiples=true +local merge_ligatures=true +local merge_cursives=true +local merge_marks=true +directives.register("otf.compact.pairs",function(v) compact_pairs=v end) +directives.register("otf.compact.singles",function(v) compact_singles=v end) +directives.register("otf.merge.pairs",function(v) merge_pairs=v end) +directives.register("otf.merge.singles",function(v) merge_singles=v end) +directives.register("otf.merge.substitutions",function(v) merge_substitutions=v end) +directives.register("otf.merge.alternates",function(v) merge_alternates=v end) +directives.register("otf.merge.multiples",function(v) merge_multiples=v end) +directives.register("otf.merge.ligatures",function(v) merge_ligatures=v end) +directives.register("otf.merge.cursives",function(v) merge_cursives=v end) +directives.register("otf.merge.marks",function(v) merge_marks=v end) +function readers.compact(data) + if not data or data.compacted then + return + else + data.compacted=true + end + local resources=data.resources + local merged=0 + local kerned=0 + local allsteps=0 + local function compact(what) + local lookups=resources[what] + if lookups then + for i=1,#lookups do + local lookup=lookups[i] + local nofsteps=lookup.nofsteps + local kind=lookup.type + allsteps=allsteps+nofsteps + if nofsteps>1 then + local merg=merged + if kind=="gsub_single" then + if merge_substitutions then + merged=merged+mergesteps_1(lookup) + end + elseif kind=="gsub_alternate" then + if merge_alternates then + merged=merged+mergesteps_1(lookup) + end + elseif kind=="gsub_multiple" then + if merge_multiples then + merged=merged+mergesteps_1(lookup) + end + elseif kind=="gsub_ligature" then + if merge_ligatures then + merged=merged+mergesteps_4(lookup) + end + elseif kind=="gpos_single" then + if merge_singles then + merged=merged+mergesteps_1(lookup,true) + end + if compact_singles then + kerned=kerned+checkkerns(lookup) + end + elseif kind=="gpos_pair" then + if merge_pairs then + merged=merged+mergesteps_2(lookup) + end + if compact_pairs then + kerned=kerned+checkpairs(lookup) + end + elseif kind=="gpos_cursive" then + if merge_cursives then + merged=merged+mergesteps_5(lookup) + end + elseif kind=="gpos_mark2mark" or kind=="gpos_mark2base" or kind=="gpos_mark2ligature" then + if merge_marks then + merged=merged+mergesteps_3(lookup) + end + end + if merg~=merged then + lookup.merged=true + end + elseif nofsteps==1 then + local kern=kerned + if kind=="gpos_single" then + if compact_singles then + kerned=kerned+checkkerns(lookup) + end + elseif kind=="gpos_pair" then + if compact_pairs then + kerned=kerned+checkpairs(lookup) + end + end + if kern~=kerned then + end + end + end + elseif trace_optimizations then + report_optimizations("no lookups in %a",what) + end + end + compact("sequences") + compact("sublookups") + if trace_optimizations then + if merged>0 then + report_optimizations("%i steps of %i removed due to merging",merged,allsteps) + end + if kerned>0 then + report_optimizations("%i steps of %i steps turned from pairs into kerns",kerned,allsteps) + end + end +end +local function mergesteps(t,k) + if k=="merged" then + local merged={} + for i=1,#t do + local step=t[i] + local coverage=step.coverage + for k in next,coverage do + local m=merged[k] + if m then + m[2]=i + else + merged[k]={ i,i } + end + end + end + t.merged=merged + return merged + end +end +local function checkmerge(sequence) + local steps=sequence.steps + if steps then + setmetatableindex(steps,mergesteps) + end +end +local function checkflags(sequence,resources) + if not sequence.skiphash then + local flags=sequence.flags + if flags then + local skipmark=flags[1] + local skipligature=flags[2] + local skipbase=flags[3] + local markclass=sequence.markclass + local skipsome=skipmark or skipligature or skipbase or markclass or false + if skipsome then + sequence.skiphash=setmetatableindex(function(t,k) + local c=resources.classes[k] + local v=c==skipmark + or (markclass and c=="mark" and not markclass[k]) + or c==skipligature + or c==skipbase + or false + t[k]=v + return v + end) + else + sequence.skiphash=false + end + else + sequence.skiphash=false + end + end +end +local function checksteps(sequence) + local steps=sequence.steps + if steps then + for i=1,#steps do + steps[i].index=i + end + end +end +if fonts.helpers then + fonts.helpers.checkmerge=checkmerge + fonts.helpers.checkflags=checkflags + fonts.helpers.checksteps=checksteps +end +function readers.expand(data) + if not data or data.expanded then + return + else + data.expanded=true + end + local resources=data.resources + local sublookups=resources.sublookups + local sequences=resources.sequences + local markclasses=resources.markclasses + local descriptions=data.descriptions + if descriptions then + local defaultwidth=resources.defaultwidth or 0 + local defaultheight=resources.defaultheight or 0 + local defaultdepth=resources.defaultdepth or 0 + local basename=trace_markwidth and file.basename(resources.filename) + for u,d in next,descriptions do + local bb=d.boundingbox + local wd=d.width + if not wd then + d.width=defaultwidth + elseif trace_markwidth and wd~=0 and d.class=="mark" then + report_markwidth("mark %a with width %b found in %a",d.name or "",wd,basename) + end + if bb then + local ht=bb[4] + local dp=-bb[2] + if ht==0 or ht<0 then + else + d.height=ht + end + if dp==0 or dp<0 then + else + d.depth=dp + end + end + end + end + local function expandlookups(sequences) + if sequences then + for i=1,#sequences do + local sequence=sequences[i] + local steps=sequence.steps + if steps then + local nofsteps=sequence.nofsteps + local kind=sequence.type + local markclass=sequence.markclass + if markclass then + if not markclasses then + report_warning("missing markclasses") + sequence.markclass=false + else + sequence.markclass=markclasses[markclass] + end + end + for i=1,nofsteps do + local step=steps[i] + local baseclasses=step.baseclasses + if baseclasses then + local coverage=step.coverage + for k,v in next,coverage do + v[1]=baseclasses[v[1]] + end + elseif kind=="gpos_cursive" then + local coverage=step.coverage + for k,v in next,coverage do + v[1]=coverage + end + end + local rules=step.rules + if rules then + local rulehash={ n=0 } + local rulesize=0 + local coverage={} + local lookuptype=sequence.type + local nofrules=#rules + step.coverage=coverage + for currentrule=1,nofrules do + local rule=rules[currentrule] + local current=rule.current + local before=rule.before + local after=rule.after + local replacements=rule.replacements or false + local sequence={} + local nofsequences=0 + if before then + for n=1,#before do + nofsequences=nofsequences+1 + sequence[nofsequences]=before[n] + end + end + local start=nofsequences+1 + for n=1,#current do + nofsequences=nofsequences+1 + sequence[nofsequences]=current[n] + end + local stop=nofsequences + if after then + for n=1,#after do + nofsequences=nofsequences+1 + sequence[nofsequences]=after[n] + end + end + local lookups=rule.lookups or false + local subtype=nil + if lookups then + for i=1,#lookups do + local lookups=lookups[i] + if lookups then + for k,v in next,lookups do + local lookup=sublookups[v] + if lookup then + lookups[k]=lookup + if not subtype then + subtype=lookup.type + end + else + end + end + end + end + end + if sequence[1] then + sequence.n=#sequence + local ruledata={ + currentrule, + lookuptype, + sequence, + start, + stop, + lookups, + replacements, + subtype, + } + rulesize=rulesize+1 + rulehash[rulesize]=ruledata + rulehash.n=rulesize + if true then + for unic in next,sequence[start] do + local cu=coverage[unic] + if cu then + local n=#cu+1 + cu[n]=ruledata + cu.n=n + else + coverage[unic]={ ruledata,n=1 } + end + end + else + for unic in next,sequence[start] do + local cu=coverage[unic] + if cu then + else + coverage[unic]=rulehash + end + end + end + end + end + end + end + checkmerge(sequence) + checkflags(sequence,resources) + checksteps(sequence) + end + end + end + end + expandlookups(sequences) + expandlookups(sublookups) +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-oup”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-otl” f4e6652a191003493389de230b14cfb3] --- + +if not modules then modules={} end modules ['font-otl']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files", +} +local lower=string.lower +local type,next,tonumber,tostring,unpack=type,next,tonumber,tostring,unpack +local abs=math.abs +local derivetable=table.derive +local formatters=string.formatters +local setmetatableindex=table.setmetatableindex +local allocate=utilities.storage.allocate +local registertracker=trackers.register +local registerdirective=directives.register +local starttiming=statistics.starttiming +local stoptiming=statistics.stoptiming +local elapsedtime=statistics.elapsedtime +local findbinfile=resolvers.findbinfile +local trace_loading=false registertracker("otf.loading",function(v) trace_loading=v end) +local trace_features=false registertracker("otf.features",function(v) trace_features=v end) +local trace_defining=false registertracker("fonts.defining",function(v) trace_defining=v end) +local report_otf=logs.reporter("fonts","otf loading") +local fonts=fonts +local otf=fonts.handlers.otf +otf.version=3.113 +otf.cache=containers.define("fonts","otl",otf.version,true) +otf.svgcache=containers.define("fonts","svg",otf.version,true) +otf.pngcache=containers.define("fonts","png",otf.version,true) +otf.pdfcache=containers.define("fonts","pdf",otf.version,true) +otf.mpscache=containers.define("fonts","mps",otf.version,true) +otf.svgenabled=false +otf.pngenabled=false +local otfreaders=otf.readers +local hashes=fonts.hashes +local definers=fonts.definers +local readers=fonts.readers +local constructors=fonts.constructors +local otffeatures=constructors.features.otf +local registerotffeature=otffeatures.register +local otfenhancers=constructors.enhancers.otf +local registerotfenhancer=otfenhancers.register +local forceload=false +local cleanup=0 +local syncspace=true +local forcenotdef=false +local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 +local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes +local wildcard="*" +local default="dflt" +local formats=fonts.formats +formats.otf="opentype" +formats.ttf="truetype" +formats.ttc="truetype" +registerdirective("fonts.otf.loader.cleanup",function(v) cleanup=tonumber(v) or (v and 1) or 0 end) +registerdirective("fonts.otf.loader.force",function(v) forceload=v end) +registerdirective("fonts.otf.loader.syncspace",function(v) syncspace=v end) +registerdirective("fonts.otf.loader.forcenotdef",function(v) forcenotdef=v end) +registerotfenhancer("check extra features",function() end) +local checkmemory=utilities.lua and utilities.lua.checkmemory +local threshold=100 +local tracememory=false +registertracker("fonts.otf.loader.memory",function(v) tracememory=v end) +if not checkmemory then + local collectgarbage=collectgarbage + checkmemory=function(previous,threshold) + local current=collectgarbage("count") + if previous then + local checked=(threshold or 64)*1024 + if current-previous>checked then + collectgarbage("collect") + current=collectgarbage("count") + end + end + return current + end +end +function otf.load(filename,sub,instance) + local base=file.basename(file.removesuffix(filename)) + local name=file.removesuffix(base) + local attr=lfs.attributes(filename) + local size=attr and attr.size or 0 + local time=attr and attr.modification or 0 + if sub=="" then + sub=false + end + local hash=name + if sub then + hash=hash.."-"..sub + end + if instance then + hash=hash.."-"..instance + end + hash=containers.cleanname(hash) + local data=containers.read(otf.cache,hash) + local reload=not data or data.size~=size or data.time~=time or data.tableversion~=otfreaders.tableversion + if forceload then + report_otf("forced reload of %a due to hard coded flag",filename) + reload=true + end + if reload then + report_otf("loading %a, hash %a",filename,hash) + starttiming(otfreaders,true) + data=otfreaders.loadfont(filename,sub or 1,instance) + if data then + local used=checkmemory() + local resources=data.resources + local svgshapes=resources.svgshapes + local pngshapes=resources.pngshapes + if cleanup==0 then + checkmemory(used,threshold,tracememory) + end + if svgshapes then + resources.svgshapes=nil + if otf.svgenabled then + local timestamp=os.date() + containers.write(otf.svgcache,hash,{ + svgshapes=svgshapes, + timestamp=timestamp, + }) + data.properties.svg={ + hash=hash, + timestamp=timestamp, + } + end + if cleanup>1 then + collectgarbage("collect") + else + checkmemory(used,threshold,tracememory) + end + end + if pngshapes then + resources.pngshapes=nil + if otf.pngenabled then + local timestamp=os.date() + containers.write(otf.pngcache,hash,{ + pngshapes=pngshapes, + timestamp=timestamp, + }) + data.properties.png={ + hash=hash, + timestamp=timestamp, + } + end + if cleanup>1 then + collectgarbage("collect") + else + checkmemory(used,threshold,tracememory) + end + end + otfreaders.compact(data) + if cleanup==0 then + checkmemory(used,threshold,tracememory) + end + otfreaders.rehash(data,"unicodes") + otfreaders.addunicodetable(data) + otfreaders.extend(data) + if cleanup==0 then + checkmemory(used,threshold,tracememory) + end + otfreaders.pack(data) + report_otf("loading done") + report_otf("saving %a in cache",filename) + data=containers.write(otf.cache,hash,data) + if cleanup>1 then + collectgarbage("collect") + else + checkmemory(used,threshold,tracememory) + end + stoptiming(otfreaders) + if elapsedtime then + report_otf("loading, optimizing, packing and caching time %s",elapsedtime(otfreaders)) + end + if cleanup>3 then + collectgarbage("collect") + else + checkmemory(used,threshold,tracememory) + end + data=containers.read(otf.cache,hash) + if cleanup>2 then + collectgarbage("collect") + else + checkmemory(used,threshold,tracememory) + end + else + stoptiming(otfreaders) + data=nil + report_otf("loading failed due to read error") + end + end + if data then + if trace_defining then + report_otf("loading from cache using hash %a",hash) + end + otfreaders.unpack(data) + otfreaders.expand(data) + otfreaders.addunicodetable(data) + otfenhancers.apply(data,filename,data) + if applyruntimefixes then + applyruntimefixes(filename,data) + end + data.metadata.math=data.resources.mathconstants + local classes=data.resources.classes + if not classes then + local descriptions=data.descriptions + classes=setmetatableindex(function(t,k) + local d=descriptions[k] + local v=(d and d.class or "base") or false + t[k]=v + return v + end) + data.resources.classes=classes + end + end + return data +end +function otf.setfeatures(tfmdata,features) + local okay=constructors.initializefeatures("otf",tfmdata,features,trace_features,report_otf) + if okay then + return constructors.collectprocessors("otf",tfmdata,features,trace_features,report_otf) + else + return {} + end +end +local function copytotfm(data,cache_id) + if data then + local metadata=data.metadata + local properties=derivetable(data.properties) + local descriptions=derivetable(data.descriptions) + local goodies=derivetable(data.goodies) + local characters={} + local parameters={} + local mathparameters={} + local resources=data.resources + local unicodes=resources.unicodes + local spaceunits=500 + local spacer="space" + local designsize=metadata.designsize or 100 + local minsize=metadata.minsize or designsize + local maxsize=metadata.maxsize or designsize + local mathspecs=metadata.math + if designsize==0 then + designsize=100 + minsize=100 + maxsize=100 + end + if mathspecs then + for name,value in next,mathspecs do + mathparameters[name]=value + end + end + for unicode in next,data.descriptions do + characters[unicode]={} + end + if mathspecs then + for unicode,character in next,characters do + local d=descriptions[unicode] + local m=d.math + if m then + local italic=m.italic + local vitalic=m.vitalic + local variants=m.hvariants + local parts=m.hparts + if variants then + local c=character + for i=1,#variants do + local un=variants[i] + c.next=un + c=characters[un] + end + c.horiz_variants=parts + elseif parts then + character.horiz_variants=parts + italic=m.hitalic + end + local variants=m.vvariants + local parts=m.vparts + if variants then + local c=character + for i=1,#variants do + local un=variants[i] + c.next=un + c=characters[un] + end + c.vert_variants=parts + elseif parts then + character.vert_variants=parts + end + if italic and italic~=0 then + character.italic=italic + end + if vitalic and vitalic~=0 then + character.vert_italic=vitalic + end + local accent=m.accent + if accent then + character.accent=accent + end + local kerns=m.kerns + if kerns then + character.mathkerns=kerns + end + end + end + end + local filename=constructors.checkedfilename(resources) + local fontname=metadata.fontname + local fullname=metadata.fullname or fontname + local psname=fontname or fullname + local subfont=metadata.subfontindex + local units=metadata.units or 1000 + if units==0 then + units=1000 + metadata.units=1000 + report_otf("changing %a units to %a",0,units) + end + local monospaced=metadata.monospaced + local charwidth=metadata.averagewidth + local charxheight=metadata.xheight + local italicangle=metadata.italicangle + local hasitalics=metadata.hasitalics + properties.monospaced=monospaced + properties.hasitalics=hasitalics + parameters.italicangle=italicangle + parameters.charwidth=charwidth + parameters.charxheight=charxheight + local space=0x0020 + local emdash=0x2014 + if monospaced then + if descriptions[space] then + spaceunits,spacer=descriptions[space].width,"space" + end + if not spaceunits and descriptions[emdash] then + spaceunits,spacer=descriptions[emdash].width,"emdash" + end + if not spaceunits and charwidth then + spaceunits,spacer=charwidth,"charwidth" + end + else + if descriptions[space] then + spaceunits,spacer=descriptions[space].width,"space" + end + if not spaceunits and descriptions[emdash] then + spaceunits,spacer=descriptions[emdash].width/2,"emdash/2" + end + if not spaceunits and charwidth then + spaceunits,spacer=charwidth,"charwidth" + end + end + spaceunits=tonumber(spaceunits) or units/2 + parameters.slant=0 + parameters.space=spaceunits + parameters.space_stretch=1*units/2 + parameters.space_shrink=1*units/3 + parameters.x_height=2*units/5 + parameters.quad=units + if spaceunits<2*units/5 then + end + if italicangle and italicangle~=0 then + parameters.italicangle=italicangle + parameters.italicfactor=math.cos(math.rad(90+italicangle)) + parameters.slant=- math.tan(italicangle*math.pi/180) + end + if monospaced then + parameters.space_stretch=0 + parameters.space_shrink=0 + elseif syncspace then + parameters.space_stretch=spaceunits/2 + parameters.space_shrink=spaceunits/3 + end + parameters.extra_space=parameters.space_shrink + if charxheight then + parameters.x_height=charxheight + else + local x=0x0078 + if x then + local x=descriptions[x] + if x then + parameters.x_height=x.height + end + end + end + parameters.designsize=(designsize/10)*65536 + parameters.minsize=(minsize/10)*65536 + parameters.maxsize=(maxsize/10)*65536 + parameters.ascender=abs(metadata.ascender or 0) + parameters.descender=abs(metadata.descender or 0) + parameters.units=units + parameters.vheight=metadata.defaultvheight + properties.space=spacer + properties.format=data.format or formats.otf + properties.filename=filename + properties.fontname=fontname + properties.fullname=fullname + properties.psname=psname + properties.name=filename or fullname + properties.subfont=subfont +if not CONTEXTLMTXMODE or CONTEXTLMTXMODE==0 then + properties.encodingbytes=2 +end + properties.private=properties.private or data.private or privateoffset + return { + characters=characters, + descriptions=descriptions, + parameters=parameters, + mathparameters=mathparameters, + resources=resources, + properties=properties, + goodies=goodies, + } + end +end +local converters={ + woff={ + cachename="webfonts", + action=otf.readers.woff2otf, + } +} +local function checkconversion(specification) + local filename=specification.filename + local converter=converters[lower(file.suffix(filename))] + if converter then + local base=file.basename(filename) + local name=file.removesuffix(base) + local attr=lfs.attributes(filename) + local size=attr and attr.size or 0 + local time=attr and attr.modification or 0 + if size>0 then + local cleanname=containers.cleanname(name) + local cachename=caches.setfirstwritablefile(cleanname,converter.cachename) + if not io.exists(cachename) or (time~=lfs.attributes(cachename).modification) then + report_otf("caching font %a in %a",filename,cachename) + converter.action(filename,cachename) + lfs.touch(cachename,time,time) + end + specification.filename=cachename + end + end +end +local function otftotfm(specification) + local cache_id=specification.hash + local tfmdata=containers.read(constructors.cache,cache_id) + if not tfmdata then + checkconversion(specification) + local name=specification.name + local sub=specification.sub + local subindex=specification.subindex + local filename=specification.filename + local features=specification.features.normal + local instance=specification.instance or (features and features.axis) + local rawdata=otf.load(filename,sub,instance) + if rawdata and next(rawdata) then + local descriptions=rawdata.descriptions + rawdata.lookuphash={} + tfmdata=copytotfm(rawdata,cache_id) + if tfmdata and next(tfmdata) then + local features=constructors.checkedfeatures("otf",features) + local shared=tfmdata.shared + if not shared then + shared={} + tfmdata.shared=shared + end + shared.rawdata=rawdata + shared.dynamics={} + tfmdata.changed={} + shared.features=features + shared.processes=otf.setfeatures(tfmdata,features) + end + end + containers.write(constructors.cache,cache_id,tfmdata) + end + return tfmdata +end +local function read_from_otf(specification) + local tfmdata=otftotfm(specification) + if tfmdata then + tfmdata.properties.name=specification.name + tfmdata.properties.sub=specification.sub + tfmdata=constructors.scale(tfmdata,specification) + local allfeatures=tfmdata.shared.features or specification.features.normal + constructors.applymanipulators("otf",tfmdata,allfeatures,trace_features,report_otf) + constructors.setname(tfmdata,specification) + fonts.loggers.register(tfmdata,file.suffix(specification.filename),specification) + end + return tfmdata +end +local function checkmathsize(tfmdata,mathsize) + local mathdata=tfmdata.shared.rawdata.metadata.math + local mathsize=tonumber(mathsize) + if mathdata then + local parameters=tfmdata.parameters + parameters.scriptpercentage=mathdata.ScriptPercentScaleDown + parameters.scriptscriptpercentage=mathdata.ScriptScriptPercentScaleDown + parameters.mathsize=mathsize + end +end +registerotffeature { + name="mathsize", + description="apply mathsize specified in the font", + initializers={ + base=checkmathsize, + node=checkmathsize, + } +} +function otf.collectlookups(rawdata,kind,script,language) + if not kind then + return + end + if not script then + script=default + end + if not language then + language=default + end + local lookupcache=rawdata.lookupcache + if not lookupcache then + lookupcache={} + rawdata.lookupcache=lookupcache + end + local kindlookup=lookupcache[kind] + if not kindlookup then + kindlookup={} + lookupcache[kind]=kindlookup + end + local scriptlookup=kindlookup[script] + if not scriptlookup then + scriptlookup={} + kindlookup[script]=scriptlookup + end + local languagelookup=scriptlookup[language] + if not languagelookup then + local sequences=rawdata.resources.sequences + local featuremap={} + local featurelist={} + if sequences then + for s=1,#sequences do + local sequence=sequences[s] + local features=sequence.features + if features then + features=features[kind] + if features then + features=features[script] or features[wildcard] + if features then + features=features[language] or features[wildcard] + if features then + if not featuremap[sequence] then + featuremap[sequence]=true + featurelist[#featurelist+1]=sequence + end + end + end + end + end + end + if #featurelist==0 then + featuremap,featurelist=false,false + end + else + featuremap,featurelist=false,false + end + languagelookup={ featuremap,featurelist } + scriptlookup[language]=languagelookup + end + return unpack(languagelookup) +end +local function getgsub(tfmdata,k,kind,value) + local shared=tfmdata.shared + local rawdata=shared and shared.rawdata + if rawdata then + local sequences=rawdata.resources.sequences + if sequences then + local properties=tfmdata.properties + local validlookups,lookuplist=otf.collectlookups(rawdata,kind,properties.script,properties.language) + if validlookups then + for i=1,#lookuplist do + local lookup=lookuplist[i] + local steps=lookup.steps + local nofsteps=lookup.nofsteps + for i=1,nofsteps do + local coverage=steps[i].coverage + if coverage then + local found=coverage[k] + if found then + return found,lookup.type + end + end + end + end + end + end + end +end +otf.getgsub=getgsub +function otf.getsubstitution(tfmdata,k,kind,value) + local found,kind=getgsub(tfmdata,k,kind,value) + if not found then + elseif kind=="gsub_single" then + return found + elseif kind=="gsub_alternate" then + local choice=tonumber(value) or 1 + return found[choice] or found[1] or k + end + return k +end +otf.getalternate=otf.getsubstitution +function otf.getmultiple(tfmdata,k,kind) + local found,kind=getgsub(tfmdata,k,kind) + if found and kind=="gsub_multiple" then + return found + end + return { k } +end +function otf.getkern(tfmdata,left,right,kind) + local kerns=getgsub(tfmdata,left,kind or "kern",true) + if kerns then + local found=kerns[right] + local kind=type(found) + if kind=="table" then + found=found[1][3] + elseif kind~="number" then + found=false + end + if found then + return found*tfmdata.parameters.factor + end + end + return 0 +end +local function check_otf(forced,specification,suffix) + local name=specification.name + if forced then + name=specification.forcedname + end + local fullname=findbinfile(name,suffix) or "" + if fullname=="" then + fullname=fonts.names.getfilename(name,suffix) or "" + end + if fullname~="" and not fonts.names.ignoredfile(fullname) then + specification.filename=fullname + return read_from_otf(specification) + end +end +local function opentypereader(specification,suffix) + local forced=specification.forced or "" + if formats[forced] then + return check_otf(true,specification,forced) + else + return check_otf(false,specification,suffix) + end +end +readers.opentype=opentypereader +function readers.otf(specification) return opentypereader(specification,"otf") end +function readers.ttf(specification) return opentypereader(specification,"ttf") end +function readers.ttc(specification) return opentypereader(specification,"ttf") end +function readers.woff(specification) + checkconversion(specification) + opentypereader(specification,"") +end +function otf.scriptandlanguage(tfmdata,attr) + local properties=tfmdata.properties + return properties.script or "dflt",properties.language or "dflt" +end +local function justset(coverage,unicode,replacement) + coverage[unicode]=replacement +end +otf.coverup={ + stepkey="steps", + actions={ + chainsubstitution=justset, + chainposition=justset, + substitution=justset, + alternate=justset, + multiple=justset, + kern=justset, + pair=justset, + single=justset, + ligature=function(coverage,unicode,ligature) + local first=ligature[1] + local tree=coverage[first] + if not tree then + tree={} + coverage[first]=tree + end + for i=2,#ligature do + local l=ligature[i] + local t=tree[l] + if not t then + t={} + tree[l]=t + end + tree=t + end + tree.ligature=unicode + end, + }, + register=function(coverage,featuretype,format) + return { + format=format, + coverage=coverage, + } + end +} + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-otl”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-oto” 2b1d6bc63b2ebf8f2655a15e1cda6541] --- + +if not modules then modules={} end modules ['font-oto']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local concat,unpack=table.concat,table.unpack +local insert,remove=table.insert,table.remove +local format,gmatch,gsub,find,match,lower,strip=string.format,string.gmatch,string.gsub,string.find,string.match,string.lower,string.strip +local type,next,tonumber,tostring=type,next,tonumber,tostring +local trace_baseinit=false trackers.register("otf.baseinit",function(v) trace_baseinit=v end) +local trace_singles=false trackers.register("otf.singles",function(v) trace_singles=v end) +local trace_multiples=false trackers.register("otf.multiples",function(v) trace_multiples=v end) +local trace_alternatives=false trackers.register("otf.alternatives",function(v) trace_alternatives=v end) +local trace_ligatures=false trackers.register("otf.ligatures",function(v) trace_ligatures=v end) +local trace_kerns=false trackers.register("otf.kerns",function(v) trace_kerns=v end) +local trace_preparing=false trackers.register("otf.preparing",function(v) trace_preparing=v end) +local report_prepare=logs.reporter("fonts","otf prepare") +local fonts=fonts +local otf=fonts.handlers.otf +local otffeatures=otf.features +local registerotffeature=otffeatures.register +otf.defaultbasealternate="none" +local getprivate=fonts.constructors.getprivate +local wildcard="*" +local default="dflt" +local formatters=string.formatters +local f_unicode=formatters["%U"] +local f_uniname=formatters["%U (%s)"] +local f_unilist=formatters["% t (% t)"] +local function gref(descriptions,n) + if type(n)=="number" then + local name=descriptions[n].name + if name then + return f_uniname(n,name) + else + return f_unicode(n) + end + elseif n then + local num={} + local nam={} + local j=0 + for i=1,#n do + local ni=n[i] + if tonumber(ni) then + j=j+1 + local di=descriptions[ni] + num[j]=f_unicode(ni) + nam[j]=di and di.name or "-" + end + end + return f_unilist(num,nam) + else + return "" + end +end +local function cref(feature,sequence) + return formatters["feature %a, type %a, chain lookup %a"](feature,sequence.type,sequence.name) +end +local function report_substitution(feature,sequence,descriptions,unicode,substitution) + if unicode==substitution then + report_prepare("%s: base substitution %s maps onto itself", + cref(feature,sequence), + gref(descriptions,unicode)) + else + report_prepare("%s: base substitution %s => %S", + cref(feature,sequence), + gref(descriptions,unicode), + gref(descriptions,substitution)) + end +end +local function report_alternate(feature,sequence,descriptions,unicode,replacement,value,comment) + if unicode==replacement then + report_prepare("%s: base alternate %s maps onto itself", + cref(feature,sequence), + gref(descriptions,unicode)) + else + report_prepare("%s: base alternate %s => %s (%S => %S)", + cref(feature,sequence), + gref(descriptions,unicode), + replacement and gref(descriptions,replacement), + value, + comment) + end +end +local function report_ligature(feature,sequence,descriptions,unicode,ligature) + report_prepare("%s: base ligature %s => %S", + cref(feature,sequence), + gref(descriptions,ligature), + gref(descriptions,unicode)) +end +local function report_kern(feature,sequence,descriptions,unicode,otherunicode,value) + report_prepare("%s: base kern %s + %s => %S", + cref(feature,sequence), + gref(descriptions,unicode), + gref(descriptions,otherunicode), + value) +end +local basehash,basehashes,applied={},1,{} +local function registerbasehash(tfmdata) + local properties=tfmdata.properties + local hash=concat(applied," ") + local base=basehash[hash] + if not base then + basehashes=basehashes+1 + base=basehashes + basehash[hash]=base + end + properties.basehash=base + properties.fullname=(properties.fullname or properties.name).."-"..base + applied={} +end +local function registerbasefeature(feature,value) + applied[#applied+1]=feature.."="..tostring(value) +end +local function makefake(tfmdata,name,present) + local private=getprivate(tfmdata) + local character={ intermediate=true,ligatures={} } + resources.unicodes[name]=private + tfmdata.characters[private]=character + tfmdata.descriptions[private]={ name=name } + present[name]=private + return character +end +local function make_1(present,tree,name) + for k,v in next,tree do + if k=="ligature" then + present[name]=v + else + make_1(present,v,name.."_"..k) + end + end +end +local function make_2(present,tfmdata,characters,tree,name,preceding,unicode,done) + for k,v in next,tree do + if k=="ligature" then + local character=characters[preceding] + if not character then + if trace_baseinit then + report_prepare("weird ligature in lookup %a, current %C, preceding %C",sequence.name,v,preceding) + end + character=makefake(tfmdata,name,present) + end + local ligatures=character.ligatures + if ligatures then + ligatures[unicode]={ char=v } + else + character.ligatures={ [unicode]={ char=v } } + end + if done then + local d=done[name] + if not d then + done[name]={ "dummy",v } + else + d[#d+1]=v + end + end + else + local code=present[name] or unicode + local name=name.."_"..k + make_2(present,tfmdata,characters,v,name,code,k,done) + end + end +end +local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist) + local characters=tfmdata.characters + local descriptions=tfmdata.descriptions + local resources=tfmdata.resources + local changed=tfmdata.changed + local ligatures={} + local alternate=tonumber(value) or true and 1 + local defaultalt=otf.defaultbasealternate + local trace_singles=trace_baseinit and trace_singles + local trace_alternatives=trace_baseinit and trace_alternatives + local trace_ligatures=trace_baseinit and trace_ligatures + if not changed then + changed={} + tfmdata.changed=changed + end + for i=1,#lookuplist do + local sequence=lookuplist[i] + local steps=sequence.steps + local kind=sequence.type + if kind=="gsub_single" then + for i=1,#steps do + for unicode,data in next,steps[i].coverage do + if unicode~=data then + changed[unicode]=data + end + if trace_singles then + report_substitution(feature,sequence,descriptions,unicode,data) + end + end + end + elseif kind=="gsub_alternate" then + for i=1,#steps do + for unicode,data in next,steps[i].coverage do + local replacement=data[alternate] + if replacement then + if unicode~=replacement then + changed[unicode]=replacement + end + if trace_alternatives then + report_alternate(feature,sequence,descriptions,unicode,replacement,value,"normal") + end + elseif defaultalt=="first" then + replacement=data[1] + if unicode~=replacement then + changed[unicode]=replacement + end + if trace_alternatives then + report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt) + end + elseif defaultalt=="last" then + replacement=data[#data] + if unicode~=replacement then + changed[unicode]=replacement + end + if trace_alternatives then + report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt) + end + else + if trace_alternatives then + report_alternate(feature,sequence,descriptions,unicode,replacement,value,"unknown") + end + end + end + end + elseif kind=="gsub_ligature" then + for i=1,#steps do + for unicode,data in next,steps[i].coverage do + ligatures[#ligatures+1]={ unicode,data,"" } + if trace_ligatures then + report_ligature(feature,sequence,descriptions,unicode,data) + end + end + end + end + end + local nofligatures=#ligatures + if nofligatures>0 then + local characters=tfmdata.characters + local present={} + local done=trace_baseinit and trace_ligatures and {} + for i=1,nofligatures do + local ligature=ligatures[i] + local unicode=ligature[1] + local tree=ligature[2] + make_1(present,tree,"ctx_"..unicode) + end + for i=1,nofligatures do + local ligature=ligatures[i] + local unicode=ligature[1] + local tree=ligature[2] + local lookupname=ligature[3] + make_2(present,tfmdata,characters,tree,"ctx_"..unicode,unicode,unicode,done,sequence) + end + end +end +local function preparepositionings(tfmdata,feature,value,validlookups,lookuplist) + local characters=tfmdata.characters + local descriptions=tfmdata.descriptions + local resources=tfmdata.resources + local properties=tfmdata.properties + local traceindeed=trace_baseinit and trace_kerns + for i=1,#lookuplist do + local sequence=lookuplist[i] + local steps=sequence.steps + local kind=sequence.type + local format=sequence.format + if kind=="gpos_pair" then + for i=1,#steps do + local step=steps[i] + local format=step.format + if format=="kern" or format=="move" then + for unicode,data in next,steps[i].coverage do + local character=characters[unicode] + local kerns=character.kerns + if not kerns then + kerns={} + character.kerns=kerns + end + if traceindeed then + for otherunicode,kern in next,data do + if not kerns[otherunicode] and kern~=0 then + kerns[otherunicode]=kern + report_kern(feature,sequence,descriptions,unicode,otherunicode,kern) + end + end + else + for otherunicode,kern in next,data do + if not kerns[otherunicode] and kern~=0 then + kerns[otherunicode]=kern + end + end + end + end + else + for unicode,data in next,steps[i].coverage do + local character=characters[unicode] + local kerns=character.kerns + for otherunicode,kern in next,data do + local other=kern[2] + if other==true or (not other and not (kerns and kerns[otherunicode])) then + local kern=kern[1] + if kern==true then + elseif kern[1]~=0 or kern[2]~=0 or kern[4]~=0 then + else + kern=kern[3] + if kern~=0 then + if kerns then + kerns[otherunicode]=kern + else + kerns={ [otherunicode]=kern } + character.kerns=kerns + end + if traceindeed then + report_kern(feature,sequence,descriptions,unicode,otherunicode,kern) + end + end + end + end + end + end + end + end + end + end +end +local function initializehashes(tfmdata) +end +local function checkmathreplacements(tfmdata,fullname,fixitalics) + if tfmdata.mathparameters then + local characters=tfmdata.characters + local changed=tfmdata.changed + if next(changed) then + if trace_preparing or trace_baseinit then + report_prepare("checking math replacements for %a",fullname) + end + for unicode,replacement in next,changed do + local u=characters[unicode] + local r=characters[replacement] + if u and r then + local n=u.next + local v=u.vert_variants + local h=u.horiz_variants + if fixitalics then + local ui=u.italic + if ui and not r.italic then + if trace_preparing then + report_prepare("using %i units of italic correction from %C for %U",ui,unicode,replacement) + end + r.italic=ui + end + end + if n and not r.next then + if trace_preparing then + report_prepare("forcing %s for %C substituted by %U","incremental step",unicode,replacement) + end + r.next=n + end + if v and not r.vert_variants then + if trace_preparing then + report_prepare("forcing %s for %C substituted by %U","vertical variants",unicode,replacement) + end + r.vert_variants=v + end + if h and not r.horiz_variants then + if trace_preparing then + report_prepare("forcing %s for %C substituted by %U","horizontal variants",unicode,replacement) + end + r.horiz_variants=h + end + else + if trace_preparing then + report_prepare("error replacing %C by %U",unicode,replacement) + end + end + end + end + end +end +local function featuresinitializer(tfmdata,value) + if true then + local starttime=trace_preparing and os.clock() + local features=tfmdata.shared.features + local fullname=tfmdata.properties.fullname or "?" + if features then + initializehashes(tfmdata) + local collectlookups=otf.collectlookups + local rawdata=tfmdata.shared.rawdata + local properties=tfmdata.properties + local script=properties.script + local language=properties.language + local rawresources=rawdata.resources + local rawfeatures=rawresources and rawresources.features + local basesubstitutions=rawfeatures and rawfeatures.gsub + local basepositionings=rawfeatures and rawfeatures.gpos + local substitutionsdone=false + local positioningsdone=false + if basesubstitutions or basepositionings then + local sequences=tfmdata.resources.sequences + for s=1,#sequences do + local sequence=sequences[s] + local sfeatures=sequence.features + if sfeatures then + local order=sequence.order + if order then + for i=1,#order do + local feature=order[i] + local value=features[feature] + if value then + local validlookups,lookuplist=collectlookups(rawdata,feature,script,language) + if not validlookups then + elseif basesubstitutions and basesubstitutions[feature] then + if trace_preparing then + report_prepare("filtering base %s feature %a for %a with value %a","sub",feature,fullname,value) + end + preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist) + registerbasefeature(feature,value) + substitutionsdone=true + elseif basepositionings and basepositionings[feature] then + if trace_preparing then + report_prepare("filtering base %a feature %a for %a with value %a","pos",feature,fullname,value) + end + preparepositionings(tfmdata,feature,value,validlookups,lookuplist) + registerbasefeature(feature,value) + positioningsdone=true + end + end + end + end + end + end + end + if substitutionsdone then + checkmathreplacements(tfmdata,fullname,features.fixitalics) + end + registerbasehash(tfmdata) + end + if trace_preparing then + report_prepare("preparation time is %0.3f seconds for %a",os.clock()-starttime,fullname) + end + end +end +registerotffeature { + name="features", + description="features", + default=true, + initializers={ + base=featuresinitializer, + } +} +otf.basemodeinitializer=featuresinitializer + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-oto”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-otj” 8de59cb9b043e5f73c6b9f7cc8f6978e] --- + +if not modules then modules={} end modules ['font-otj']={ + version=1.001, + optimize=true, + comment="companion to font-lib.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files", +} +if not nodes.properties then return end +local next,rawget,tonumber=next,rawget,tonumber +local fastcopy=table.fastcopy +local registertracker=trackers.register +local registerdirective=directives.register +local trace_injections=false registertracker("fonts.injections",function(v) trace_injections=v end) +local trace_marks=false registertracker("fonts.injections.marks",function(v) trace_marks=v end) +local trace_cursive=false registertracker("fonts.injections.cursive",function(v) trace_cursive=v end) +local trace_spaces=false registertracker("fonts.injections.spaces",function(v) trace_spaces=v end) +local report_injections=logs.reporter("fonts","injections") +local report_spaces=logs.reporter("fonts","spaces") +local attributes,nodes,node=attributes,nodes,node +fonts=fonts +local hashes=fonts.hashes +local fontdata=hashes.identifiers +local fontmarks=hashes.marks +nodes.injections=nodes.injections or {} +local injections=nodes.injections +local tracers=nodes.tracers +local setcolor=tracers and tracers.colors.set +local resetcolor=tracers and tracers.colors.reset +local nodecodes=nodes.nodecodes +local glyph_code=nodecodes.glyph +local disc_code=nodecodes.disc +local kern_code=nodecodes.kern +local glue_code=nodecodes.glue +local nuts=nodes.nuts +local nodepool=nuts.pool +local tonode=nuts.tonode +local tonut=nuts.tonut +local setfield=nuts.setfield +local getnext=nuts.getnext +local getprev=nuts.getprev +local getid=nuts.getid +local getfont=nuts.getfont +local getchar=nuts.getchar +local getoffsets=nuts.getoffsets +local getboth=nuts.getboth +local getdisc=nuts.getdisc +local setdisc=nuts.setdisc +local setoffsets=nuts.setoffsets +local ischar=nuts.ischar +local getkern=nuts.getkern +local setkern=nuts.setkern +local setlink=nuts.setlink +local setwidth=nuts.setwidth +local getwidth=nuts.getwidth +local nextchar=nuts.traversers.char +local nextglue=nuts.traversers.glue +local insert_node_before=nuts.insert_before +local insert_node_after=nuts.insert_after +local properties=nodes.properties.data +local fontkern=nuts.pool and nuts.pool.fontkern +local italickern=nuts.pool and nuts.pool.italickern +local useitalickerns=false +directives.register("fonts.injections.useitalics",function(v) + if v then + report_injections("using italics for space kerns (tracing only)") + end + useitalickerns=v +end) +if not fontkern then + local thekern=nuts.new("kern",0) + local setkern=nuts.setkern + local copy_node=nuts.copy_node + fontkern=function(k) + local n=copy_node(thekern) + setkern(n,k) + return n + end +end +if not italickern then + local thekern=nuts.new("kern",3) + local setkern=nuts.setkern + local copy_node=nuts.copy_node + italickern=function(k) + local n=copy_node(thekern) + setkern(n,k) + return n + end +end +function injections.installnewkern() end +local nofregisteredkerns=0 +local nofregisteredpositions=0 +local nofregisteredmarks=0 +local nofregisteredcursives=0 +local keepregisteredcounts=false +function injections.keepcounts() + keepregisteredcounts=true +end +function injections.resetcounts() + nofregisteredkerns=0 + nofregisteredpositions=0 + nofregisteredmarks=0 + nofregisteredcursives=0 + keepregisteredcounts=false +end +function injections.reset(n) + local p=rawget(properties,n) + if p then + p.injections=false + else + properties[n]=false + end +end +function injections.copy(target,source) + local sp=rawget(properties,source) + if sp then + local tp=rawget(properties,target) + local si=sp.injections + if si then + si=fastcopy(si) + if tp then + tp.injections=si + else + properties[target]={ + injections=si, + } + end + elseif tp then + tp.injections=false + else + properties[target]={ injections={} } + end + else + local tp=rawget(properties,target) + if tp then + tp.injections=false + else + properties[target]=false + end + end +end +function injections.setligaindex(n,index) + local p=rawget(properties,n) + if p then + local i=p.injections + if i then + i.ligaindex=index + else + p.injections={ + ligaindex=index + } + end + else + properties[n]={ + injections={ + ligaindex=index + } + } + end +end +function injections.getligaindex(n,default) + local p=rawget(properties,n) + if p then + local i=p.injections + if i then + return i.ligaindex or default + end + end + return default +end +function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext,r2lflag) + local dx=factor*(exit[1]-entry[1]) + local dy=-factor*(exit[2]-entry[2]) + local ws=tfmstart.width + local wn=tfmnext.width + nofregisteredcursives=nofregisteredcursives+1 + if rlmode<0 then + dx=-(dx+wn) + else + dx=dx-ws + end + if dx==0 then + dx=0 + end + local p=rawget(properties,start) + if p then + local i=p.injections + if i then + i.cursiveanchor=true + else + p.injections={ + cursiveanchor=true, + } + end + else + properties[start]={ + injections={ + cursiveanchor=true, + }, + } + end + local p=rawget(properties,nxt) + if p then + local i=p.injections + if i then + i.cursivex=dx + i.cursivey=dy + else + p.injections={ + cursivex=dx, + cursivey=dy, + } + end + else + properties[nxt]={ + injections={ + cursivex=dx, + cursivey=dy, + }, + } + end + return dx,dy,nofregisteredcursives +end +function injections.setposition(kind,current,factor,rlmode,spec,injection) + local x=factor*(spec[1] or 0) + local y=factor*(spec[2] or 0) + local w=factor*(spec[3] or 0) + local h=factor*(spec[4] or 0) + if x~=0 or w~=0 or y~=0 or h~=0 then + local yoffset=y-h + local leftkern=x + local rightkern=w-x + if leftkern~=0 or rightkern~=0 or yoffset~=0 then + nofregisteredpositions=nofregisteredpositions+1 + if rlmode and rlmode<0 then + leftkern,rightkern=rightkern,leftkern + end + if not injection then + injection="injections" + end + local p=rawget(properties,current) + if p then + local i=p[injection] + if i then + if leftkern~=0 then + i.leftkern=(i.leftkern or 0)+leftkern + end + if rightkern~=0 then + i.rightkern=(i.rightkern or 0)+rightkern + end + if yoffset~=0 then + i.yoffset=(i.yoffset or 0)+yoffset + end + elseif leftkern~=0 or rightkern~=0 then + p[injection]={ + leftkern=leftkern, + rightkern=rightkern, + yoffset=yoffset, + } + else + p[injection]={ + yoffset=yoffset, + } + end + elseif leftkern~=0 or rightkern~=0 then + properties[current]={ + [injection]={ + leftkern=leftkern, + rightkern=rightkern, + yoffset=yoffset, + }, + } + else + properties[current]={ + [injection]={ + yoffset=yoffset, + }, + } + end + return x,y,w,h,nofregisteredpositions + end + end + return x,y,w,h +end +function injections.setkern(current,factor,rlmode,x,injection) + local dx=factor*x + if dx~=0 then + nofregisteredkerns=nofregisteredkerns+1 + local p=rawget(properties,current) + if not injection then + injection="injections" + end + if p then + local i=p[injection] + if i then + i.leftkern=dx+(i.leftkern or 0) + else + p[injection]={ + leftkern=dx, + } + end + else + properties[current]={ + [injection]={ + leftkern=dx, + }, + } + end + return dx,nofregisteredkerns + else + return 0,0 + end +end +function injections.setmove(current,factor,rlmode,x,injection) + local dx=factor*x + if dx~=0 then + nofregisteredkerns=nofregisteredkerns+1 + local p=rawget(properties,current) + if not injection then + injection="injections" + end + if rlmode and rlmode<0 then + if p then + local i=p[injection] + if i then + i.rightkern=dx+(i.rightkern or 0) + else + p[injection]={ + rightkern=dx, + } + end + else + properties[current]={ + [injection]={ + rightkern=dx, + }, + } + end + else + if p then + local i=p[injection] + if i then + i.leftkern=dx+(i.leftkern or 0) + else + p[injection]={ + leftkern=dx, + } + end + else + properties[current]={ + [injection]={ + leftkern=dx, + }, + } + end + end + return dx,nofregisteredkerns + else + return 0,0 + end +end +function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmark) + local dx=factor*(ba[1]-ma[1]) + local dy=factor*(ba[2]-ma[2]) + nofregisteredmarks=nofregisteredmarks+1 + if rlmode>=0 then + dx=tfmbase.width-dx + end + local p=rawget(properties,start) + if p then + local i=p.injections + if i then + if i.markmark then + else + i.markx=dx + i.marky=dy + i.markdir=rlmode or 0 + i.markbase=nofregisteredmarks + i.markbasenode=base + i.markmark=mkmk + i.checkmark=checkmark + end + else + p.injections={ + markx=dx, + marky=dy, + markdir=rlmode or 0, + markbase=nofregisteredmarks, + markbasenode=base, + markmark=mkmk, + checkmark=checkmark, + } + end + else + properties[start]={ + injections={ + markx=dx, + marky=dy, + markdir=rlmode or 0, + markbase=nofregisteredmarks, + markbasenode=base, + markmark=mkmk, + checkmark=checkmark, + }, + } + end + return dx,dy,nofregisteredmarks +end +local function dir(n) + return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or "unset" +end +local function showchar(n,nested) + local char=getchar(n) + report_injections("%wfont %s, char %U, glyph %c",nested and 2 or 0,getfont(n),char,char) +end +local function show(n,what,nested,symbol) + if n then + local p=rawget(properties,n) + if p then + local i=p[what] + if i then + local leftkern=i.leftkern or 0 + local rightkern=i.rightkern or 0 + local yoffset=i.yoffset or 0 + local markx=i.markx or 0 + local marky=i.marky or 0 + local markdir=i.markdir or 0 + local markbase=i.markbase or 0 + local cursivex=i.cursivex or 0 + local cursivey=i.cursivey or 0 + local ligaindex=i.ligaindex or 0 + local cursbase=i.cursiveanchor + local margin=nested and 4 or 2 + if rightkern~=0 or yoffset~=0 then + report_injections("%w%s pair: lx %p, rx %p, dy %p",margin,symbol,leftkern,rightkern,yoffset) + elseif leftkern~=0 then + report_injections("%w%s kern: dx %p",margin,symbol,leftkern) + end + if markx~=0 or marky~=0 or markbase~=0 then + report_injections("%w%s mark: dx %p, dy %p, dir %s, base %s",margin,symbol,markx,marky,markdir,markbase~=0 and "yes" or "no") + end + if cursivex~=0 or cursivey~=0 then + if cursbase then + report_injections("%w%s curs: base dx %p, dy %p",margin,symbol,cursivex,cursivey) + else + report_injections("%w%s curs: dx %p, dy %p",margin,symbol,cursivex,cursivey) + end + elseif cursbase then + report_injections("%w%s curs: base",margin,symbol) + end + if ligaindex~=0 then + report_injections("%w%s liga: index %i",margin,symbol,ligaindex) + end + end + end + end +end +local function showsub(n,what,where) + report_injections("begin subrun: %s",where) + for n in nextchar,n do + showchar(n,where) + show(n,what,where," ") + end + report_injections("end subrun") +end +local function trace(head,where) + report_injections() + report_injections("begin run %s: %s kerns, %s positions, %s marks and %s cursives registered", + where or "",nofregisteredkerns,nofregisteredpositions,nofregisteredmarks,nofregisteredcursives) + local n=head + while n do + local id=getid(n) + if id==glyph_code then + showchar(n) + show(n,"injections",false," ") + show(n,"preinjections",false,"<") + show(n,"postinjections",false,">") + show(n,"replaceinjections",false,"=") + show(n,"emptyinjections",false,"*") + elseif id==disc_code then + local pre,post,replace=getdisc(n) + if pre then + showsub(pre,"preinjections","pre") + end + if post then + showsub(post,"postinjections","post") + end + if replace then + showsub(replace,"replaceinjections","replace") + end + show(n,"emptyinjections",false,"*") + end + n=getnext(n) + end + report_injections("end run") +end +local function show_result(head) + local current=head + local skipping=false + while current do + local id=getid(current) + if id==glyph_code then + local w=getwidth(current) + local x,y=getoffsets(current) + report_injections("char: %C, width %p, xoffset %p, yoffset %p",getchar(current),w,x,y) + skipping=false + elseif id==kern_code then + report_injections("kern: %p",getkern(current)) + skipping=false + elseif not skipping then + report_injections() + skipping=true + end + current=getnext(current) + end + report_injections() +end +local function inject_kerns_only(head,where) + if trace_injections then + trace(head,"kerns") + end + local current=head + local prev=nil + local next=nil + local prevdisc=nil + local pre=nil + local post=nil + local replace=nil + local pretail=nil + local posttail=nil + local replacetail=nil + while current do + local next=getnext(current) + local char,id=ischar(current) + if char then + local p=rawget(properties,current) + if p then + local i=p.injections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + if prev and getid(prev)==glue_code then + if useitalickerns then + head=insert_node_before(head,current,italickern(leftkern)) + else + setwidth(prev,getwidth(prev)+leftkern) + end + else + head=insert_node_before(head,current,fontkern(leftkern)) + end + end + end + if prevdisc then + local done=false + if post then + local i=p.postinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(posttail,fontkern(leftkern)) + done=true + end + end + end + if replace then + local i=p.replaceinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(replacetail,fontkern(leftkern)) + done=true + end + end + else + local i=p.emptyinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + replace=fontkern(leftkern) + done=true + end + end + end + if done then + setdisc(prevdisc,pre,post,replace) + end + end + end + prevdisc=nil + elseif char==false then + prevdisc=nil + elseif id==disc_code then + pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) + local done=false + if pre then + for n in nextchar,pre do + local p=rawget(properties,n) + if p then + local i=p.injections or p.preinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + pre=insert_node_before(pre,n,fontkern(leftkern)) + done=true + end + end + end + end + end + if post then + for n in nextchar,post do + local p=rawget(properties,n) + if p then + local i=p.injections or p.postinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + post=insert_node_before(post,n,fontkern(leftkern)) + done=true + end + end + end + end + end + if replace then + for n in nextchar,replace do + local p=rawget(properties,n) + if p then + local i=p.injections or p.replaceinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + replace=insert_node_before(replace,n,fontkern(leftkern)) + done=true + end + end + end + end + end + if done then + setdisc(current,pre,post,replace) + end + prevdisc=current + else + prevdisc=nil + end + prev=current + current=next + end + if keepregisteredcounts then + keepregisteredcounts=false + else + nofregisteredkerns=0 + end + if trace_injections then + show_result(head) + end + return head +end +local function inject_positions_only(head,where) + if trace_injections then + trace(head,"positions") + end + local current=head + local prev=nil + local next=nil + local prevdisc=nil + local prevglyph=nil + local pre=nil + local post=nil + local replace=nil + local pretail=nil + local posttail=nil + local replacetail=nil + while current do + local next=getnext(current) + local char,id=ischar(current) + if char then + local p=rawget(properties,current) + if p then + local i=p.injections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(current,false,yoffset) + end + local leftkern=i.leftkern + local rightkern=i.rightkern + if leftkern and leftkern~=0 then + if rightkern and leftkern==-rightkern then + setoffsets(current,leftkern,false) + rightkern=0 + elseif prev and getid(prev)==glue_code then + if useitalickerns then + head=insert_node_before(head,current,italickern(leftkern)) + else + setwidth(prev,getwidth(prev)+leftkern) + end + else + head=insert_node_before(head,current,fontkern(leftkern)) + end + end + if rightkern and rightkern~=0 then + if next and getid(next)==glue_code then + if useitalickerns then + insert_node_after(head,current,italickern(rightkern)) + else + setwidth(next,getwidth(next)+rightkern) + end + else + insert_node_after(head,current,fontkern(rightkern)) + end + end + else + local i=p.emptyinjections + if i then + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + if next and getid(next)==disc_code then + if replace then + else + replace=fontkern(rightkern) + done=true + end + end + end + end + end + if prevdisc then + local done=false + if post then + local i=p.postinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(posttail,fontkern(leftkern)) + done=true + end + end + end + if replace then + local i=p.replaceinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(replacetail,fontkern(leftkern)) + done=true + end + end + else + local i=p.emptyinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + replace=fontkern(leftkern) + done=true + end + end + end + if done then + setdisc(prevdisc,pre,post,replace) + end + end + end + prevdisc=nil + prevglyph=current + elseif char==false then + prevdisc=nil + prevglyph=current + elseif id==disc_code then + pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) + local done=false + if pre then + for n in nextchar,pre do + local p=rawget(properties,n) + if p then + local i=p.injections or p.preinjections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(n,false,yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + pre=insert_node_before(pre,n,fontkern(leftkern)) + done=true + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(pre,n,fontkern(rightkern)) + done=true + end + end + end + end + end + if post then + for n in nextchar,post do + local p=rawget(properties,n) + if p then + local i=p.injections or p.postinjections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(n,false,yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + post=insert_node_before(post,n,fontkern(leftkern)) + done=true + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(post,n,fontkern(rightkern)) + done=true + end + end + end + end + end + if replace then + for n in nextchar,replace do + local p=rawget(properties,n) + if p then + local i=p.injections or p.replaceinjections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(n,false,yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + replace=insert_node_before(replace,n,fontkern(leftkern)) + done=true + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(replace,n,fontkern(rightkern)) + done=true + end + end + end + end + end + if prevglyph then + if pre then + local p=rawget(properties,prevglyph) + if p then + local i=p.preinjections + if i then + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + pre=insert_node_before(pre,pre,fontkern(rightkern)) + done=true + end + end + end + end + if replace then + local p=rawget(properties,prevglyph) + if p then + local i=p.replaceinjections + if i then + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + replace=insert_node_before(replace,replace,fontkern(rightkern)) + done=true + end + end + end + end + end + if done then + setdisc(current,pre,post,replace) + end + prevglyph=nil + prevdisc=current + else + prevglyph=nil + prevdisc=nil + end + prev=current + current=next + end + if keepregisteredcounts then + keepregisteredcounts=false + else + nofregisteredpositions=0 + end + if trace_injections then + show_result(head) + end + return head +end +local function showoffset(n,flag) + local x,y=getoffsets(n) + if x~=0 or y~=0 then + setcolor(n,"darkgray") + end +end +local function inject_everything(head,where) + if trace_injections then + trace(head,"everything") + end + local hascursives=nofregisteredcursives>0 + local hasmarks=nofregisteredmarks>0 + local current=head + local last=nil + local prev=nil + local next=nil + local prevdisc=nil + local prevglyph=nil + local pre=nil + local post=nil + local replace=nil + local pretail=nil + local posttail=nil + local replacetail=nil + local cursiveanchor=nil + local minc=0 + local maxc=0 + local glyphs={} + local marks={} + local nofmarks=0 + local function processmark(p,n,pn) + local px,py=getoffsets(p) + local nx,ny=getoffsets(n) + local ox=0 + local rightkern=nil + local pp=rawget(properties,p) + if pp then + pp=pp.injections + if pp then + rightkern=pp.rightkern + end + end + local markdir=pn.markdir + if rightkern then + ox=px-(pn.markx or 0)-rightkern + if markdir and markdir<0 then + if not pn.markmark then + ox=ox+(pn.leftkern or 0) + end + else + if false then + local leftkern=pp.leftkern + if leftkern then + ox=ox-leftkern + end + end + end + else + ox=px-(pn.markx or 0) + if markdir and markdir<0 then + if not pn.markmark then + local leftkern=pn.leftkern + if leftkern then + ox=ox+leftkern + end + end + end + if pn.checkmark then + local wn=getwidth(n) + if wn and wn~=0 then + wn=wn/2 + if trace_injections then + report_injections("correcting non zero width mark %C",getchar(n)) + end + insert_node_before(n,n,fontkern(-wn)) + insert_node_after(n,n,fontkern(-wn)) + end + end + end + local oy=ny+py+(pn.marky or 0) + if not pn.markmark then + local yoffset=pn.yoffset + if yoffset then + oy=oy+yoffset + end + end + setoffsets(n,ox,oy) + if trace_marks then + showoffset(n,true) + end + end + while current do + local next=getnext(current) + local char,id=ischar(current) + if char then + local p=rawget(properties,current) + if p then + local i=p.injections + if i then + local pm=i.markbasenode + if pm then + nofmarks=nofmarks+1 + marks[nofmarks]=current + else + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(current,false,yoffset) + end + if hascursives then + local cursivex=i.cursivex + if cursivex then + if cursiveanchor then + if cursivex~=0 then + i.leftkern=(i.leftkern or 0)+cursivex + end + if maxc==0 then + minc=1 + maxc=1 + glyphs[1]=cursiveanchor + else + maxc=maxc+1 + glyphs[maxc]=cursiveanchor + end + properties[cursiveanchor].cursivedy=i.cursivey + last=current + else + maxc=0 + end + elseif maxc>0 then + local nx,ny=getoffsets(current) + for i=maxc,minc,-1 do + local ti=glyphs[i] + ny=ny+properties[ti].cursivedy + setoffsets(ti,false,ny) + if trace_cursive then + showoffset(ti) + end + end + maxc=0 + cursiveanchor=nil + end + if i.cursiveanchor then + cursiveanchor=current + else + if maxc>0 then + local nx,ny=getoffsets(current) + for i=maxc,minc,-1 do + local ti=glyphs[i] + ny=ny+properties[ti].cursivedy + setoffsets(ti,false,ny) + if trace_cursive then + showoffset(ti) + end + end + maxc=0 + end + cursiveanchor=nil + end + end + local leftkern=i.leftkern + local rightkern=i.rightkern + if leftkern and leftkern~=0 then + if rightkern and leftkern==-rightkern then + setoffsets(current,leftkern,false) + rightkern=0 + elseif prev and getid(prev)==glue_code then + if useitalickerns then + head=insert_node_before(head,current,italickern(leftkern)) + else + setwidth(prev,getwidth(prev)+leftkern) + end + else + head=insert_node_before(head,current,fontkern(leftkern)) + end + end + if rightkern and rightkern~=0 then + if next and getid(next)==glue_code then + if useitalickerns then + insert_node_after(head,current,italickern(rightkern)) + else + setwidth(next,getwidth(next)+rightkern) + end + else + insert_node_after(head,current,fontkern(rightkern)) + end + end + end + else + local i=p.emptyinjections + if i then + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + if next and getid(next)==disc_code then + if replace then + else + replace=fontkern(rightkern) + done=true + end + end + end + end + end + if prevdisc then + if p then + local done=false + if post then + local i=p.postinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(posttail,fontkern(leftkern)) + done=true + end + end + end + if replace then + local i=p.replaceinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(replacetail,fontkern(leftkern)) + done=true + end + end + else + local i=p.emptyinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + replace=fontkern(leftkern) + done=true + end + end + end + if done then + setdisc(prevdisc,pre,post,replace) + end + end + end + else + if hascursives and maxc>0 then + local nx,ny=getoffsets(current) + for i=maxc,minc,-1 do + local ti=glyphs[i] + ny=ny+properties[ti].cursivedy + local xi,yi=getoffsets(ti) + setoffsets(ti,xi,yi+ny) + end + maxc=0 + cursiveanchor=nil + end + end + prevdisc=nil + prevglyph=current + elseif char==false then + prevdisc=nil + prevglyph=current + elseif id==disc_code then + pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) + local done=false + if pre then + for n in nextchar,pre do + local p=rawget(properties,n) + if p then + local i=p.injections or p.preinjections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(n,false,yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + pre=insert_node_before(pre,n,fontkern(leftkern)) + done=true + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(pre,n,fontkern(rightkern)) + done=true + end + if hasmarks then + local pm=i.markbasenode + if pm then + processmark(pm,n,i) + end + end + end + end + end + end + if post then + for n in nextchar,post do + local p=rawget(properties,n) + if p then + local i=p.injections or p.postinjections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(n,false,yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + post=insert_node_before(post,n,fontkern(leftkern)) + done=true + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(post,n,fontkern(rightkern)) + done=true + end + if hasmarks then + local pm=i.markbasenode + if pm then + processmark(pm,n,i) + end + end + end + end + end + end + if replace then + for n in nextchar,replace do + local p=rawget(properties,n) + if p then + local i=p.injections or p.replaceinjections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(n,false,yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + replace=insert_node_before(replace,n,fontkern(leftkern)) + done=true + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(replace,n,fontkern(rightkern)) + done=true + end + if hasmarks then + local pm=i.markbasenode + if pm then + processmark(pm,n,i) + end + end + end + end + end + end + if prevglyph then + if pre then + local p=rawget(properties,prevglyph) + if p then + local i=p.preinjections + if i then + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + pre=insert_node_before(pre,pre,fontkern(rightkern)) + done=true + end + end + end + end + if replace then + local p=rawget(properties,prevglyph) + if p then + local i=p.replaceinjections + if i then + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + replace=insert_node_before(replace,replace,fontkern(rightkern)) + done=true + end + end + end + end + end + if done then + setdisc(current,pre,post,replace) + end + prevglyph=nil + prevdisc=current + else + prevglyph=nil + prevdisc=nil + end + prev=current + current=next + end + if hascursives and maxc>0 then + local nx,ny=getoffsets(last) + for i=maxc,minc,-1 do + local ti=glyphs[i] + ny=ny+properties[ti].cursivedy + setoffsets(ti,false,ny) + if trace_cursive then + showoffset(ti) + end + end + end + if nofmarks>0 then + for i=1,nofmarks do + local m=marks[i] + local p=rawget(properties,m) + local i=p.injections + local b=i.markbasenode + processmark(b,m,i) + end + elseif hasmarks then + end + if keepregisteredcounts then + keepregisteredcounts=false + else + nofregisteredkerns=0 + nofregisteredpositions=0 + nofregisteredmarks=0 + nofregisteredcursives=0 + end + if trace_injections then + show_result(head) + end + return head +end +local triggers=false +function nodes.injections.setspacekerns(font,sequence) + if triggers then + triggers[font]=sequence + else + triggers={ [font]=sequence } + end +end +local getthreshold +if context then + local threshold=1 + local parameters=fonts.hashes.parameters + directives.register("otf.threshold",function(v) threshold=tonumber(v) or 1 end) + getthreshold=function(font) + local p=parameters[font] + local f=p.factor + local s=p.spacing + local t=threshold*(s and s.width or p.space or 0)-2 + return t>0 and t or 0,f + end +else + injections.threshold=0 + getthreshold=function(font) + local p=fontdata[font].parameters + local f=p.factor + local s=p.spacing + local t=injections.threshold*(s and s.width or p.space or 0)-2 + return t>0 and t or 0,f + end +end +injections.getthreshold=getthreshold +function injections.isspace(n,threshold,id) + if (id or getid(n))==glue_code then + local w=getwidth(n) + if threshold and w>threshold then + return 32 + end + end +end +local getspaceboth=getboth +function injections.installgetspaceboth(gb) + getspaceboth=gb or getboth +end +local function injectspaces(head) + if not triggers then + return head + end + local lastfont=nil + local spacekerns=nil + local leftkerns=nil + local rightkerns=nil + local factor=0 + local threshold=0 + local leftkern=false + local rightkern=false + local function updatefont(font,trig) + leftkerns=trig.left + rightkerns=trig.right + lastfont=font + threshold, + factor=getthreshold(font) + end + for n in nextglue,head do + local prev,next=getspaceboth(n) + local prevchar=prev and ischar(prev) + local nextchar=next and ischar(next) + if nextchar then + local font=getfont(next) + local trig=triggers[font] + if trig then + if lastfont~=font then + updatefont(font,trig) + end + if rightkerns then + rightkern=rightkerns[nextchar] + end + end + end + if prevchar then + local font=getfont(prev) + local trig=triggers[font] + if trig then + if lastfont~=font then + updatefont(font,trig) + end + if leftkerns then + leftkern=leftkerns[prevchar] + end + end + end + if leftkern then + local old=getwidth(n) + if old>threshold then + if rightkern then + if useitalickerns then + local lnew=leftkern*factor + local rnew=rightkern*factor + if trace_spaces then + report_spaces("%C [%p + %p + %p] %C",prevchar,lnew,old,rnew,nextchar) + end + head=insert_node_before(head,n,italickern(lnew)) + insert_node_after(head,n,italickern(rnew)) + else + local new=old+(leftkern+rightkern)*factor + if trace_spaces then + report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar) + end + setwidth(n,new) + end + rightkern=false + else + if useitalickerns then + local new=leftkern*factor + if trace_spaces then + report_spaces("%C [%p + %p]",prevchar,old,new) + end + insert_node_after(head,n,italickern(new)) + else + local new=old+leftkern*factor + if trace_spaces then + report_spaces("%C [%p -> %p]",prevchar,old,new) + end + setwidth(n,new) + end + end + end + leftkern=false + elseif rightkern then + local old=getwidth(n) + if old>threshold then + if useitalickerns then + local new=rightkern*factor + if trace_spaces then + report_spaces("[%p + %p] %C",old,new,nextchar) + end + insert_node_after(head,n,italickern(new)) + else + local new=old+rightkern*factor + if trace_spaces then + report_spaces("[%p -> %p] %C",old,new,nextchar) + end + setwidth(n,new) + end + else + end + rightkern=false + end + end + triggers=false + return head +end +function injections.handler(head,where) + if triggers then + head=injectspaces(head) + end + if nofregisteredmarks>0 or nofregisteredcursives>0 then + if trace_injections then + report_injections("injection variant %a","everything") + end + return inject_everything(head,where) + elseif nofregisteredpositions>0 then + if trace_injections then + report_injections("injection variant %a","positions") + end + return inject_positions_only(head,where) + elseif nofregisteredkerns>0 then + if trace_injections then + report_injections("injection variant %a","kerns") + end + return inject_kerns_only(head,where) + else + return head + end +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-otj”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-ota” ad1d5de06400f88829509e1f3ff2b473] --- + +if not modules then modules={} end modules ['font-ota']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local type=type +local setmetatableindex=table.setmetatableindex +if not trackers then trackers={ register=function() end } end +local fonts,nodes,node=fonts,nodes,node +local allocate=utilities.storage.allocate +local otf=fonts.handlers.otf +local analyzers=fonts.analyzers +local initializers=allocate() +local methods=allocate() +analyzers.initializers=initializers +analyzers.methods=methods +local nuts=nodes.nuts +local tonut=nuts.tonut +local getnext=nuts.getnext +local getprev=nuts.getprev +local getprev=nuts.getprev +local getprop=nuts.getprop +local setprop=nuts.setprop +local getsubtype=nuts.getsubtype +local getchar=nuts.getchar +local ischar=nuts.ischar +local end_of_math=nuts.end_of_math +local nodecodes=nodes.nodecodes +local disc_code=nodecodes.disc +local math_code=nodecodes.math +local fontdata=fonts.hashes.identifiers +local categories=characters and characters.categories or {} +local chardata=characters and characters.data +local otffeatures=fonts.constructors.features.otf +local registerotffeature=otffeatures.register +local setstate=nuts.setstate +local getstate=nuts.getstate +if not setstate or not getstate then + setstate=function(n,v) + setprop(n,"state",v) + end + getstate=function(n,v) + local s=getprop(n,"state") + if v then + return s==v + else + return s + end + end + nuts.setstate=setstate + nuts.getstate=getstate +end +local s_init=1 local s_rphf=7 +local s_medi=2 local s_half=8 +local s_fina=3 local s_pref=9 +local s_isol=4 local s_blwf=10 +local s_mark=5 local s_pstf=11 +local s_rest=6 +local states=allocate { + init=s_init, + medi=s_medi, + med2=s_medi, + fina=s_fina, + fin2=s_fina, + fin3=s_fina, + isol=s_isol, + mark=s_mark, + rest=s_rest, + rphf=s_rphf, + half=s_half, + pref=s_pref, + blwf=s_blwf, + pstf=s_pstf, +} +local features=allocate { + init=s_init, + medi=s_medi, + med2=s_medi, + fina=s_fina, + fin2=s_fina, + fin3=s_fina, + isol=s_isol, + rphf=s_rphf, + half=s_half, + pref=s_pref, + blwf=s_blwf, + pstf=s_pstf, +} +analyzers.states=states +analyzers.features=features +analyzers.useunicodemarks=false +function analyzers.setstate(head,font) + local useunicodemarks=analyzers.useunicodemarks + local tfmdata=fontdata[font] + local descriptions=tfmdata.descriptions + local first,last,current,n,done=nil,nil,head,0,false + current=tonut(current) + while current do + local char,id=ischar(current,font) + if char and not getstate(current) then + done=true + local d=descriptions[char] + if d then + if d.class=="mark" then + done=true + setstate(current,s_mark) + elseif useunicodemarks and categories[char]=="mn" then + done=true + setstate(current,s_mark) + elseif n==0 then + first,last,n=current,current,1 + setstate(current,s_init) + else + last,n=current,n+1 + setstate(current,s_medi) + end + else + if first and first==last then + setstate(last,s_isol) + elseif last then + setstate(last,s_fina) + end + first,last,n=nil,nil,0 + end + elseif char==false then + if first and first==last then + setstate(last,s_isol) + elseif last then + setstate(last,s_fina) + end + first,last,n=nil,nil,0 + if id==math_code then + current=end_of_math(current) + end + elseif id==disc_code then + setstate(current,s_medi) + last=current + else + if first and first==last then + setstate(last,s_isol) + elseif last then + setstate(last,s_fina) + end + first,last,n=nil,nil,0 + if id==math_code then + current=end_of_math(current) + end + end + current=getnext(current) + end + if first and first==last then + setstate(last,s_isol) + elseif last then + setstate(last,s_fina) + end + return head,done +end +local function analyzeinitializer(tfmdata,value) + local script,language=otf.scriptandlanguage(tfmdata) + local action=initializers[script] + if not action then + elseif type(action)=="function" then + return action(tfmdata,value) + else + local action=action[language] + if action then + return action(tfmdata,value) + end + end +end +local function analyzeprocessor(head,font,attr) + local tfmdata=fontdata[font] + local script,language=otf.scriptandlanguage(tfmdata,attr) + local action=methods[script] + if not action then + elseif type(action)=="function" then + return action(head,font,attr) + else + action=action[language] + if action then + return action(head,font,attr) + end + end + return head,false +end +registerotffeature { + name="analyze", + description="analysis of character classes", + default=true, + initializers={ + node=analyzeinitializer, + }, + processors={ + position=1, + node=analyzeprocessor, + } +} +methods.latn=analyzers.setstate +local arab_warned={} +local function warning(current,what) + local char=getchar(current) + if not arab_warned[char] then + log.report("analyze","arab: character %C has no %a class",char,what) + arab_warned[char]=true + end +end +local mappers=allocate { + l=s_init, + d=s_medi, + c=s_medi, + r=s_fina, + u=s_isol, +} +local classifiers=characters.classifiers +if not classifiers then + local f_arabic,l_arabic=characters.blockrange("arabic") + local f_syriac,l_syriac=characters.blockrange("syriac") + local f_mandiac,l_mandiac=characters.blockrange("mandiac") + local f_nko,l_nko=characters.blockrange("nko") + local f_ext_a,l_ext_a=characters.blockrange("arabicextendeda") + classifiers=setmetatableindex(function(t,k) + if type(k)=="number" then + local c=chardata[k] + local v=false + if c then + local arabic=c.arabic + if arabic then + v=mappers[arabic] + if not v then + log.report("analyze","error in mapping arabic %C",k) + v=false + end + elseif (k>=f_arabic and k<=l_arabic) or + (k>=f_syriac and k<=l_syriac) or + (k>=f_mandiac and k<=l_mandiac) or + (k>=f_nko and k<=l_nko) or + (k>=f_ext_a and k<=l_ext_a) then + if categories[k]=="mn" then + v=s_mark + else + v=s_rest + end + end + end + t[k]=v + return v + end + end) + characters.classifiers=classifiers +end +function methods.arab(head,font,attr) + local first,last,c_first,c_last + local current=head + local done=false + current=tonut(current) + while current do + local char,id=ischar(current,font) + if char and not getstate(current) then + done=true + local classifier=classifiers[char] + if not classifier then + if last then + if c_last==s_medi or c_last==s_fina then + setstate(last,s_fina) + else + warning(last,"fina") + setstate(last,s_error) + end + first,last=nil,nil + elseif first then + if c_first==s_medi or c_first==s_fina then + setstate(first,s_isol) + else + warning(first,"isol") + setstate(first,s_error) + end + first=nil + end + elseif classifier==s_mark then + setstate(current,s_mark) + elseif classifier==s_isol then + if last then + if c_last==s_medi or c_last==s_fina then + setstate(last,s_fina) + else + warning(last,"fina") + setstate(last,s_error) + end + first,last=nil,nil + elseif first then + if c_first==s_medi or c_first==s_fina then + setstate(first,s_isol) + else + warning(first,"isol") + setstate(first,s_error) + end + first=nil + end + setstate(current,s_isol) + elseif classifier==s_medi then + if first then + last=current + c_last=classifier + setstate(current,s_medi) + else + setstate(current,s_init) + first=current + c_first=classifier + end + elseif classifier==s_fina then + if last then + if getstate(last)~=s_init then + setstate(last,s_medi) + end + setstate(current,s_fina) + first,last=nil,nil + elseif first then + setstate(current,s_fina) + first=nil + else + setstate(current,s_isol) + end + else + setstate(current,s_rest) + if last then + if c_last==s_medi or c_last==s_fina then + setstate(last,s_fina) + else + warning(last,"fina") + setstate(last,s_error) + end + first,last=nil,nil + elseif first then + if c_first==s_medi or c_first==s_fina then + setstate(first,s_isol) + else + warning(first,"isol") + setstate(first,s_error) + end + first=nil + end + end + else + if last then + if c_last==s_medi or c_last==s_fina then + setstate(last,s_fina) + else + warning(last,"fina") + setstate(last,s_error) + end + first,last=nil,nil + elseif first then + if c_first==s_medi or c_first==s_fina then + setstate(first,s_isol) + else + warning(first,"isol") + setstate(first,s_error) + end + first=nil + end + if id==math_code then + current=end_of_math(current) + end + end + current=getnext(current) + end + if last then + if c_last==s_medi or c_last==s_fina then + setstate(last,s_fina) + else + warning(last,"fina") + setstate(last,s_error) + end + elseif first then + if c_first==s_medi or c_first==s_fina then + setstate(first,s_isol) + else + warning(first,"isol") + setstate(first,s_error) + end + end + return head,done +end +methods.syrc=methods.arab +methods.mand=methods.arab +methods.nko=methods.arab +do + local joining=setmetatableindex(function(t,k) + if type(k)=="number" then + local c=chardata[k] + local v=false + if c then + local mongolian=c.mongolian + v=mongolian + end + t[k]=v + return v + end + end) + function methods.mong(head,font,attr) + local first,last + local current=head + local done=false + local prevjoin=nil + local prestate=nil + current=tonut(current) + local function wrapup() + if last then + if last~=first then + local s=getstate(last) + if s==s_medi then + setstate(last,s_fina) + elseif s==s_init then + setstate(last,s_isol) + end + end + last=nil + first=nil + prevjoin=nil + prestate=nil + end + end + while current do + local char,id=ischar(current,font) + if char and not getstate(current) then + local currjoin=joining[char] + done=true + if not last then + setstate(current,s_isol) + prevjoin=currjoin + first=current + last=current + prevstate=s_isol + elseif currjoin=="t" then + last=current + elseif prevjoin=="d" or prevjoin=="jc" or prevjoin=="l" then + if currjoin=="d" or prevjoin=="jc" or prevjoin=="r" then + local s=getstate(last) + if s==s_isol then + setstate(last,s_init) + elseif s==s_fina then + setstate(last,s_medi) + end + setstate(current,s_fina) + prevstate=s_fina + elseif prevjoin=="nj" or prevjoin=="l" then + local s=getstate(last) + if s==s_medi then + setstate(last,s_fina) + elseif s==s_init then + setstate(last,s_isol) + end + setstate(current,s_isol) + prevstate=s_isol + end + prevjoin=currjoin + last=current + elseif prevjoin=="nj" or prevjoin=="r" then + if s==s_medi then + setstate(last,s_fina) + elseif s==s_init then + setstate(last,s_isol) + end + setstate(current,s_isol) + prevjoin=currjoin + prevstate=s_isol + last=current + elseif last then + wrapup() + end + else + if last then + wrapup() + end + if id==math_code then + current=end_of_math(current) + end + end + current=getnext(current) + end + if last then + wrapup() + end + return head,done + end +end +directives.register("otf.analyze.useunicodemarks",function(v) + analyzers.useunicodemarks=v +end) + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-ota”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-ots” c780a471147527f4ddc139e017927ffe] --- + +if not modules then modules={} end modules ['font-ots']={ + version=1.001, + optimize=true, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files", +} +local type,next,tonumber=type,next,tonumber +local random=math.random +local formatters=string.formatters +local insert=table.insert +local registertracker=trackers.register +local logs=logs +local trackers=trackers +local nodes=nodes +local attributes=attributes +local fonts=fonts +local otf=fonts.handlers.otf +local tracers=nodes.tracers +local trace_singles=false registertracker("otf.singles",function(v) trace_singles=v end) +local trace_multiples=false registertracker("otf.multiples",function(v) trace_multiples=v end) +local trace_alternatives=false registertracker("otf.alternatives",function(v) trace_alternatives=v end) +local trace_ligatures=false registertracker("otf.ligatures",function(v) trace_ligatures=v end) +local trace_contexts=false registertracker("otf.contexts",function(v) trace_contexts=v end) +local trace_marks=false registertracker("otf.marks",function(v) trace_marks=v end) +local trace_kerns=false registertracker("otf.kerns",function(v) trace_kerns=v end) +local trace_cursive=false registertracker("otf.cursive",function(v) trace_cursive=v end) +local trace_preparing=false registertracker("otf.preparing",function(v) trace_preparing=v end) +local trace_bugs=false registertracker("otf.bugs",function(v) trace_bugs=v end) +local trace_details=false registertracker("otf.details",function(v) trace_details=v end) +local trace_steps=false registertracker("otf.steps",function(v) trace_steps=v end) +local trace_skips=false registertracker("otf.skips",function(v) trace_skips=v end) +local trace_plugins=false registertracker("otf.plugins",function(v) trace_plugins=v end) +local trace_chains=false registertracker("otf.chains",function(v) trace_chains=v end) +local trace_kernruns=false registertracker("otf.kernruns",function(v) trace_kernruns=v end) +local trace_compruns=false registertracker("otf.compruns",function(v) trace_compruns=v end) +local trace_testruns=false registertracker("otf.testruns",function(v) trace_testruns=v end) +local forcediscretionaries=false +local forcepairadvance=false +directives.register("otf.forcediscretionaries",function(v) + forcediscretionaries=v +end) +directives.register("otf.forcepairadvance",function(v) + forcepairadvance=v +end) +local report_direct=logs.reporter("fonts","otf direct") +local report_subchain=logs.reporter("fonts","otf subchain") +local report_chain=logs.reporter("fonts","otf chain") +local report_process=logs.reporter("fonts","otf process") +local report_warning=logs.reporter("fonts","otf warning") +local report_run=logs.reporter("fonts","otf run") +registertracker("otf.substitutions","otf.singles","otf.multiples","otf.alternatives","otf.ligatures") +registertracker("otf.positions","otf.marks","otf.kerns","otf.cursive") +registertracker("otf.actions","otf.substitutions","otf.positions") +registertracker("otf.sample","otf.steps","otf.substitutions","otf.positions","otf.analyzing") +registertracker("otf.sample.silent","otf.steps=silent","otf.substitutions","otf.positions","otf.analyzing") +local nuts=nodes.nuts +local getnext=nuts.getnext +local setnext=nuts.setnext +local getprev=nuts.getprev +local setprev=nuts.setprev +local getboth=nuts.getboth +local setboth=nuts.setboth +local getid=nuts.getid +local getstate=nuts.getstate +local getsubtype=nuts.getsubtype +local setsubtype=nuts.setsubtype +local getchar=nuts.getchar +local setchar=nuts.setchar +local getdisc=nuts.getdisc +local setdisc=nuts.setdisc +local getreplace=nuts.getreplace +local setlink=nuts.setlink +local getwidth=nuts.getwidth +local getattr=nuts.getattr +local getglyphdata=nuts.getglyphdata +local copy_no_components=nuts.copy_no_components +local copy_only_glyphs=nuts.copy_only_glyphs +local count_components=nuts.count_components +local set_components=nuts.set_components +local get_components=nuts.get_components +local flush_components=nuts.flush_components +local ischar=nuts.ischar +local usesfont=nuts.uses_font +local insert_node_after=nuts.insert_after +local copy_node=nuts.copy +local copy_node_list=nuts.copy_list +local remove_node=nuts.remove +local find_node_tail=nuts.tail +local flush_node_list=nuts.flush_list +local flush_node=nuts.flush_node +local end_of_math=nuts.end_of_math +local start_of_par=nuts.start_of_par +local setmetatable=setmetatable +local setmetatableindex=table.setmetatableindex +local nextnode=nuts.traversers.node +local nodecodes=nodes.nodecodes +local glyphcodes=nodes.glyphcodes +local disccodes=nodes.disccodes +local glyph_code=nodecodes.glyph +local glue_code=nodecodes.glue +local disc_code=nodecodes.disc +local math_code=nodecodes.math +local dir_code=nodecodes.dir +local par_code=nodecodes.par +local lefttoright_code=nodes.dirvalues.lefttoright +local righttoleft_code=nodes.dirvalues.righttoleft +local discretionarydisc_code=disccodes.discretionary +local ligatureglyph_code=glyphcodes.ligature +local a_noligature=attributes.private("noligature") +local injections=nodes.injections +local setmark=injections.setmark +local setcursive=injections.setcursive +local setkern=injections.setkern +local setmove=injections.setmove +local setposition=injections.setposition +local resetinjection=injections.reset +local copyinjection=injections.copy +local setligaindex=injections.setligaindex +local getligaindex=injections.getligaindex +local fontdata=fonts.hashes.identifiers +local fontfeatures=fonts.hashes.features +local otffeatures=fonts.constructors.features.otf +local registerotffeature=otffeatures.register +local onetimemessage=fonts.loggers.onetimemessage or function() end +local getrandom=utilities and utilities.randomizer and utilities.randomizer.get +otf.defaultnodealternate="none" +local tfmdata=false +local characters=false +local descriptions=false +local marks=false +local classes=false +local currentfont=false +local factor=0 +local threshold=0 +local checkmarks=false +local discs=false +local spaces=false +local sweepnode=nil +local sweephead={} +local notmatchpre={} +local notmatchpost={} +local notmatchreplace={} +local handlers={} +local isspace=injections.isspace +local getthreshold=injections.getthreshold +local checkstep=(tracers and tracers.steppers.check) or function() end +local registerstep=(tracers and tracers.steppers.register) or function() end +local registermessage=(tracers and tracers.steppers.message) or function() end +local function logprocess(...) + if trace_steps then + registermessage(...) + if trace_steps=="silent" then + return + end + end + report_direct(...) +end +local function logwarning(...) + report_direct(...) +end +local gref do + local f_unicode=formatters["U+%X"] + local f_uniname=formatters["U+%X (%s)"] + local f_unilist=formatters["% t"] + gref=function(n) + if type(n)=="number" then + local description=descriptions[n] + local name=description and description.name + if name then + return f_uniname(n,name) + else + return f_unicode(n) + end + elseif n then + local t={} + for i=1,#n do + local ni=n[i] + if tonumber(ni) then + local di=descriptions[ni] + local nn=di and di.name + if nn then + t[#t+1]=f_uniname(ni,nn) + else + t[#t+1]=f_unicode(ni) + end + end + end + return f_unilist(t) + else + return "" + end + end +end +local function cref(dataset,sequence,index) + if not dataset then + return "no valid dataset" + end + local merged=sequence.merged and "merged " or "" + if index then + return formatters["feature %a, type %a, %schain lookup %a, index %a"]( + dataset[4],sequence.type,merged,sequence.name,index) + else + return formatters["feature %a, type %a, %schain lookup %a"]( + dataset[4],sequence.type,merged,sequence.name) + end +end +local function pref(dataset,sequence) + return formatters["feature %a, type %a, %slookup %a"]( + dataset[4],sequence.type,sequence.merged and "merged " or "",sequence.name) +end +local function mref(rlmode) + if not rlmode or rlmode>=0 then + return "l2r" + else + return "r2l" + end +end +local function flattendisk(head,disc) + local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) + local prev,next=getboth(disc) + local ishead=head==disc + setdisc(disc) + flush_node(disc) + if pre then + flush_node_list(pre) + end + if post then + flush_node_list(post) + end + if ishead then + if replace then + if next then + setlink(replacetail,next) + end + return replace,replace + elseif next then + return next,next + else + end + else + if replace then + if next then + setlink(replacetail,next) + end + setlink(prev,replace) + return head,replace + else + setlink(prev,next) + return head,next + end + end +end +local function appenddisc(disc,list) + local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) + local posthead=list + local replacehead=copy_node_list(list) + if post then + setlink(posttail,posthead) + else + post=posthead + end + if replace then + setlink(replacetail,replacehead) + else + replace=replacehead + end + setdisc(disc,pre,post,replace) +end +local function markstoligature(head,start,stop,char) + if start==stop and getchar(start)==char then + return head,start + else + local prev=getprev(start) + local next=getnext(stop) + setprev(start) + setnext(stop) + local base=copy_no_components(start,copyinjection) + if head==start then + head=base + end + resetinjection(base) + setchar(base,char) + setsubtype(base,ligatureglyph_code) + set_components(base,start) + setlink(prev,base,next) + flush_components(start) + return head,base + end +end +local no_left_ligature_code=1 +local no_right_ligature_code=2 +local no_left_kern_code=4 +local no_right_kern_code=8 +local has_glyph_option=node.direct.has_glyph_option or function(n,c) + if c==no_left_ligature_code or c==no_right_ligature_code then + return getattr(n,a_noligature)==1 + else + return false + end +end +local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks) + if has_glyph_option(start,no_right_ligature_code) then + return head,start + end + if start==stop and getchar(start)==char then + resetinjection(start) + setchar(start,char) + return head,start + end + local prev=getprev(start) + local next=getnext(stop) + local comp=start + setprev(start) + setnext(stop) + local base=copy_no_components(start,copyinjection) + if start==head then + head=base + end + resetinjection(base) + setchar(base,char) + setsubtype(base,ligatureglyph_code) + set_components(base,comp) + setlink(prev,base,next) + if not discfound then + local deletemarks=not skiphash or hasmarks + local components=start + local baseindex=0 + local componentindex=0 + local head=base + local current=base + while start do + local char=getchar(start) + if not marks[char] then + baseindex=baseindex+componentindex + componentindex=count_components(start,marks) + elseif not deletemarks then + setligaindex(start,baseindex+getligaindex(start,componentindex)) + if trace_marks then + logwarning("%s: keep ligature mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start)) + end + local n=copy_node(start) + copyinjection(n,start) + head,current=insert_node_after(head,current,n) + elseif trace_marks then + logwarning("%s: delete ligature mark %s",pref(dataset,sequence),gref(char)) + end + start=getnext(start) + end + local start=getnext(current) + while start do + local char=ischar(start) + if char then + if marks[char] then + setligaindex(start,baseindex+getligaindex(start,componentindex)) + if trace_marks then + logwarning("%s: set ligature mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start)) + end + start=getnext(start) + else + break + end + else + break + end + end + flush_components(components) + else + local discprev,discnext=getboth(discfound) + if discprev and discnext then + local pre,post,replace,pretail,posttail,replacetail=getdisc(discfound,true) + if not replace then + local prev=getprev(base) + local copied=copy_only_glyphs(comp) + if pre then + setlink(discprev,pre) + else + setnext(discprev) + end + pre=comp + if post then + setlink(posttail,discnext) + setprev(post) + else + post=discnext + setprev(discnext) + end + setlink(prev,discfound,next) + setboth(base) + set_components(base,copied) + replace=base + if forcediscretionaries then + setdisc(discfound,pre,post,replace,discretionarydisc_code) + else + setdisc(discfound,pre,post,replace) + end + base=prev + end + end + end + return head,base +end +local function multiple_glyphs(head,start,multiple,skiphash,what,stop) + local nofmultiples=#multiple + if nofmultiples>0 then + resetinjection(start) + setchar(start,multiple[1]) + if nofmultiples>1 then + local sn=getnext(start) + for k=2,nofmultiples do + local n=copy_node(start) + resetinjection(n) + setchar(n,multiple[k]) + insert_node_after(head,start,n) + start=n + end + if what==true then + elseif what>1 then + local m=multiple[nofmultiples] + for i=2,what do + local n=copy_node(start) + resetinjection(n) + setchar(n,m) + insert_node_after(head,start,n) + start=n + end + end + end + return head,start,true + else + if trace_multiples then + logprocess("no multiple for %s",gref(getchar(start))) + end + return head,start,false + end +end +local function get_alternative_glyph(start,alternatives,value) + local n=#alternatives + if n==1 then + return alternatives[1],trace_alternatives and "1 (only one present)" + elseif value=="random" then + local r=getrandom and getrandom("glyph",1,n) or random(1,n) + return alternatives[r],trace_alternatives and formatters["value %a, taking %a"](value,r) + elseif value=="first" then + return alternatives[1],trace_alternatives and formatters["value %a, taking %a"](value,1) + elseif value=="last" then + return alternatives[n],trace_alternatives and formatters["value %a, taking %a"](value,n) + end + value=value==true and 1 or tonumber(value) + if type(value)~="number" then + return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,1) + end + if value>n then + local defaultalt=otf.defaultnodealternate + if defaultalt=="first" then + return alternatives[n],trace_alternatives and formatters["invalid value %s, taking %a"](value,1) + elseif defaultalt=="last" then + return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,n) + else + return false,trace_alternatives and formatters["invalid value %a, %s"](value,"out of range") + end + elseif value==0 then + return getchar(start),trace_alternatives and formatters["invalid value %a, %s"](value,"no change") + elseif value<1 then + return alternatives[1],trace_alternatives and formatters["invalid value %a, taking %a"](value,1) + else + return alternatives[value],trace_alternatives and formatters["value %a, taking %a"](value,value) + end +end +function handlers.gsub_single(head,start,dataset,sequence,replacement) + if trace_singles then + logprocess("%s: replacing %s by single %s",pref(dataset,sequence),gref(getchar(start)),gref(replacement)) + end + resetinjection(start) + setchar(start,replacement) + return head,start,true +end +function handlers.gsub_alternate(head,start,dataset,sequence,alternative) + local kind=dataset[4] + local what=dataset[1] + local value=what==true and tfmdata.shared.features[kind] or what + local choice,comment=get_alternative_glyph(start,alternative,value) + if choice then + if trace_alternatives then + logprocess("%s: replacing %s by alternative %a to %s, %s",pref(dataset,sequence),gref(getchar(start)),gref(choice),comment) + end + resetinjection(start) + setchar(start,choice) + else + if trace_alternatives then + logwarning("%s: no variant %a for %s, %s",pref(dataset,sequence),value,gref(getchar(start)),comment) + end + end + return head,start,true +end +function handlers.gsub_multiple(head,start,dataset,sequence,multiple,rlmode,skiphash) + if trace_multiples then + logprocess("%s: replacing %s by multiple %s",pref(dataset,sequence),gref(getchar(start)),gref(multiple)) + end + return multiple_glyphs(head,start,multiple,skiphash,dataset[1]) +end +function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skiphash) + local current=getnext(start) + if not current then + return head,start,false,nil + end + local stop=nil + local startchar=getchar(start) + if skiphash and skiphash[startchar] then + while current do + local char=ischar(current,currentfont) + if char then + local lg=ligature[char] + if lg then + stop=current + ligature=lg + current=getnext(current) + else + break + end + else + break + end + end + if stop then + local lig=ligature.ligature + if lig then + if trace_ligatures then + local stopchar=getchar(stop) + head,start=markstoligature(head,start,stop,lig) + logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(getchar(start))) + else + head,start=markstoligature(head,start,stop,lig) + end + return head,start,true,false + else + end + end + else + local discfound=false + local hasmarks=marks[startchar] + while current do + local char,id=ischar(current,currentfont) + if char then + if skiphash and skiphash[char] then + current=getnext(current) + else + local lg=ligature[char] + if lg then + if marks[char] then + hasmarks=true + end + stop=current + ligature=lg + current=getnext(current) + else + break + end + end + elseif char==false then + break + elseif id==disc_code then + discfound=current + break + else + break + end + end + if discfound then + local pre,post,replace=getdisc(discfound) + local match + if replace then + local char=ischar(replace,currentfont) + if char and ligature[char] then + match=true + end + end + if not match and pre then + local char=ischar(pre,currentfont) + if char and ligature[char] then + match=true + end + end + if not match and not pre or not replace then + local n=getnext(discfound) + local char=ischar(n,currentfont) + if char and ligature[char] then + match=true + end + end + if match then + local ishead=head==start + local prev=getprev(start) + if stop then + setnext(stop) + local copy=copy_node_list(start) + local tail=stop + local liat=find_node_tail(copy) + if pre then + setlink(liat,pre) + end + if replace then + setlink(tail,replace) + end + pre=copy + replace=start + else + setnext(start) + local copy=copy_node(start) + if pre then + setlink(copy,pre) + end + if replace then + setlink(start,replace) + end + pre=copy + replace=start + end + setdisc(discfound,pre,post,replace) + if prev then + setlink(prev,discfound) + else + setprev(discfound) + head=discfound + end + start=discfound + return head,start,true,true + end + end + local lig=ligature.ligature + if lig then + if stop then + if trace_ligatures then + local stopchar=getchar(stop) + head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks) + logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig)) + else + head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks) + end + else + resetinjection(start) + setchar(start,lig) + if trace_ligatures then + logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(lig)) + end + end + return head,start,true,false + else + end + end + return head,start,false,false +end +function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) + if has_glyph_option(start,no_right_kern_code) then + return head,start,false + else + local startchar=getchar(start) + local format=step.format + if format=="single" or type(kerns)=="table" then + local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h) + end + else + local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k) + end + end + return head,start,true + end +end +function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) + if has_glyph_option(start,no_right_kern_code) then + return head,start,false + else + local snext=getnext(start) + if not snext then + return head,start,false + else + local prev=start + while snext do + local nextchar=ischar(snext,currentfont) + if nextchar then + if skiphash and skiphash[nextchar] then + prev=snext + snext=getnext(snext) + else + local krn=kerns[nextchar] + if not krn then + break + end + local format=step.format + if format=="pair" then + local a=krn[1] + local b=krn[2] + if a==true then + elseif a then + local x,y,w,h=setposition(1,start,factor,rlmode,a,injection) + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + end + end + if b==true then + start=snext + elseif b then + local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection) + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + end + start=snext + elseif forcepairadvance then + start=snext + end + return head,start,true + elseif krn~=0 then + local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection) + if trace_kerns then + logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections") + end + return head,start,true + else + break + end + end + else + break + end + end + return head,start,false + end + end +end +function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode,skiphash) + local markchar=getchar(start) + if marks[markchar] then + local base=getprev(start) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if marks[basechar] then + while base do + base=getprev(base) + if base then + basechar=ischar(base,currentfont) + if basechar then + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) + end + return head,start,false + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) + end + return head,start,false + end + end + end + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) + if trace_marks then + logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)", + pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) + end + return head,start,true + elseif trace_bugs then + logwarning("%s: mark %s is not anchored to %s",pref(dataset,sequence),gref(markchar),gref(basechar)) + end + elseif trace_bugs then + logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),1) + end + elseif trace_bugs then + logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),2) + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar)) + end + return head,start,false +end +function handlers.gpos_mark2ligature(head,start,dataset,sequence,markanchors,rlmode,skiphash) + local markchar=getchar(start) + if marks[markchar] then + local base=getprev(start) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if marks[basechar] then + while base do + base=getprev(base) + if base then + basechar=ischar(base,currentfont) + if basechar then + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) + end + return head,start,false + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) + end + return head,start,false + end + end + end + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + if ma then + local index=getligaindex(start) + ba=ba[index] + if ba then + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) + if trace_marks then + logprocess("%s, index %s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)", + pref(dataset,sequence),index,bound,gref(markchar),gref(basechar),index,dx,dy) + end + return head,start,true + else + if trace_bugs then + logwarning("%s: no matching anchors for mark %s and baselig %s with index %a",pref(dataset,sequence),gref(markchar),gref(basechar),index) + end + end + end + elseif trace_bugs then + onetimemessage(currentfont,basechar,"no base anchors",report_fonts) + end + elseif trace_bugs then + logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),1) + end + elseif trace_bugs then + logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),2) + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar)) + end + return head,start,false +end +function handlers.gpos_mark2mark(head,start,dataset,sequence,markanchors,rlmode,skiphash) + local markchar=getchar(start) + if marks[markchar] then + local base=getprev(start) + local slc=getligaindex(start) + if slc then + while base do + local blc=getligaindex(base) + if blc and blc~=slc then + base=getprev(base) + else + break + end + end + end + if base then + local basechar=ischar(base,currentfont) + if basechar then + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) + if trace_marks then + logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)", + pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) + end + return head,start,true + end + end + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar)) + end + return head,start,false +end +function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,skiphash,step) + local startchar=getchar(start) + if marks[startchar] then + if trace_cursive then + logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar)) + end + else + local nxt=getnext(start) + while nxt do + local nextchar=ischar(nxt,currentfont) + if not nextchar then + break + elseif marks[nextchar] then + nxt=getnext(nxt) + else + local exit=exitanchors[3] + if exit then + local entry=exitanchors[1][nextchar] + if entry then + entry=entry[2] + if entry then + local r2lflag=sequence.flags[4] + local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag) + if trace_cursive then + logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode)) + end + return head,start,true + end + end + end + break + end + end + end + return head,start,false +end +local chainprocs={} +local function logprocess(...) + if trace_steps then + registermessage(...) + if trace_steps=="silent" then + return + end + end + report_subchain(...) +end +local logwarning=report_subchain +local function logprocess(...) + if trace_steps then + registermessage(...) + if trace_steps=="silent" then + return + end + end + report_chain(...) +end +local logwarning=report_chain +local function reversesub(head,start,stop,dataset,sequence,replacements,rlmode,skiphash) + local char=getchar(start) + local replacement=replacements[char] + if replacement then + if trace_singles then + logprocess("%s: single reverse replacement of %s by %s",cref(dataset,sequence),gref(char),gref(replacement)) + end + resetinjection(start) + setchar(start,replacement) + return head,start,true + else + return head,start,false + end +end +chainprocs.reversesub=reversesub +local function reportzerosteps(dataset,sequence) + logwarning("%s: no steps",cref(dataset,sequence)) +end +local function reportmoresteps(dataset,sequence) + logwarning("%s: more than 1 step",cref(dataset,sequence)) +end +local function getmapping(dataset,sequence,currentlookup) + local steps=currentlookup.steps + local nofsteps=currentlookup.nofsteps + if nofsteps==0 then + reportzerosteps(dataset,sequence) + currentlookup.mapping=false + return false + else + if nofsteps>1 then + reportmoresteps(dataset,sequence) + end + local mapping=steps[1].coverage + currentlookup.mapping=mapping + currentlookup.format=steps[1].format + return mapping + end +end +function chainprocs.gsub_remove(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + if trace_chains then + logprocess("%s: removing character %s",cref(dataset,sequence,chainindex),gref(getchar(start))) + end + head,start=remove_node(head,start,true) + return head,getprev(start),true +end +function chainprocs.gsub_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local current=start + while current do + local currentchar=ischar(current) + if currentchar then + local replacement=mapping[currentchar] + if not replacement or replacement=="" then + if trace_bugs then + logwarning("%s: no single for %s",cref(dataset,sequence,chainindex),gref(currentchar)) + end + else + if trace_singles then + logprocess("%s: replacing single %s by %s",cref(dataset,sequence,chainindex),gref(currentchar),gref(replacement)) + end + resetinjection(current) + setchar(current,replacement) + end + return head,start,true + elseif currentchar==false then + break + elseif current==stop then + break + else + current=getnext(current) + end + end + end + return head,start,false +end +function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local kind=dataset[4] + local what=dataset[1] + local value=what==true and tfmdata.shared.features[kind] or what + local current=start + while current do + local currentchar=ischar(current) + if currentchar then + local alternatives=mapping[currentchar] + if alternatives then + local choice,comment=get_alternative_glyph(current,alternatives,value) + if choice then + if trace_alternatives then + logprocess("%s: replacing %s by alternative %a to %s, %s",cref(dataset,sequence),gref(currentchar),choice,gref(choice),comment) + end + resetinjection(start) + setchar(start,choice) + else + if trace_alternatives then + logwarning("%s: no variant %a for %s, %s",cref(dataset,sequence),value,gref(currentchar),comment) + end + end + end + return head,start,true + elseif currentchar==false then + break + elseif current==stop then + break + else + current=getnext(current) + end + end + end + return head,start,false +end +function chainprocs.gsub_multiple(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local startchar=getchar(start) + local replacement=mapping[startchar] + if not replacement or replacement=="" then + if trace_bugs then + logwarning("%s: no multiple for %s",cref(dataset,sequence),gref(startchar)) + end + else + if trace_multiples then + logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement)) + end + return multiple_glyphs(head,start,replacement,skiphash,dataset[1],stop) + end + end + return head,start,false +end +function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local startchar=getchar(start) + local ligatures=mapping[startchar] + if not ligatures then + if trace_bugs then + logwarning("%s: no ligatures starting with %s",cref(dataset,sequence,chainindex),gref(startchar)) + end + else + local hasmarks=marks[startchar] + local current=getnext(start) + local discfound=false + local last=stop + local nofreplacements=1 + while current do + local id=getid(current) + if id==disc_code then + if not discfound then + discfound=current + end + if current==stop then + break + else + current=getnext(current) + end + else + local schar=getchar(current) + if skiphash and skiphash[schar] then + current=getnext(current) + else + local lg=ligatures[schar] + if lg then + ligatures=lg + last=current + nofreplacements=nofreplacements+1 + if marks[char] then + hasmarks=true + end + if current==stop then + break + else + current=getnext(current) + end + else + break + end + end + end + end + local ligature=ligatures.ligature + if ligature then + if chainindex then + stop=last + end + if trace_ligatures then + if start==stop then + logprocess("%s: replacing character %s by ligature %s case 3",cref(dataset,sequence,chainindex),gref(startchar),gref(ligature)) + else + logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)),gref(ligature)) + end + end + head,start=toligature(head,start,stop,ligature,dataset,sequence,skiphash,discfound,hasmarks) + return head,start,true,nofreplacements,discfound + elseif trace_bugs then + if start==stop then + logwarning("%s: replacing character %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar)) + else + logwarning("%s: replacing character %s upto %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop))) + end + end + end + end + return head,start,false,0,false +end +function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + if not has_glyph_option(start,no_right_kern_code) then + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local startchar=getchar(start) + local kerns=mapping[startchar] + if kerns then + local format=currentlookup.format + if format=="single" then + local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns) + if trace_kerns then + logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h) + end + else + local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k) + end + end + return head,start,true + end + end + end + return head,start,false +end +function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + if not has_glyph_option(start,no_right_kern_code) then + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local snext=getnext(start) + if snext then + local startchar=getchar(start) + local kerns=mapping[startchar] + if kerns then + local prev=start + while snext do + local nextchar=ischar(snext,currentfont) + if not nextchar then + break + end + if skiphash and skiphash[nextchar] then + prev=snext + snext=getnext(snext) + else + local krn=kerns[nextchar] + if not krn then + break + end + local format=currentlookup.format + if format=="pair" then + local a=krn[1] + local b=krn[2] + if a==true then + elseif a then + local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections") + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + end + end + if b==true then + start=snext + elseif b then + local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections") + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + end + start=snext + elseif forcepairadvance then + start=snext + end + return head,start,true + elseif krn~=0 then + local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn) + if trace_kerns then + logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar)) + end + return head,start,true + else + break + end + end + end + end + end + end + end + return head,start,false +end +function chainprocs.gpos_mark2base(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local markchar=getchar(start) + if marks[markchar] then + local markanchors=mapping[markchar] + if markanchors then + local base=getprev(start) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if marks[basechar] then + while base do + base=getprev(base) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) + end + return head,start,false + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) + end + return head,start,false + end + end + end + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + if ma then + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) + if trace_marks then + logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)", + cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) + end + return head,start,true + end + end + elseif trace_bugs then + logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),1) + end + elseif trace_bugs then + logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),2) + end + elseif trace_bugs then + logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) + end + end + return head,start,false +end +function chainprocs.gpos_mark2ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local markchar=getchar(start) + if marks[markchar] then + local markanchors=mapping[markchar] + if markanchors then + local base=getprev(start) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if marks[basechar] then + while base do + base=getprev(base) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,1) + end + return head,start,false + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,2) + end + return head,start,false + end + end + end + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + if ma then + local index=getligaindex(start) + ba=ba[index] + if ba then + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) + if trace_marks then + logprocess("%s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)", + cref(dataset,sequence),a or bound,gref(markchar),gref(basechar),index,dx,dy) + end + return head,start,true + end + end + end + elseif trace_bugs then + logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),1) + end + elseif trace_bugs then + logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),2) + end + elseif trace_bugs then + logwarning("%s, mark %s has no anchors",cref(dataset,sequence),gref(markchar)) + end + elseif trace_bugs then + logwarning("%s, mark %s is no mark",cref(dataset,sequence),gref(markchar)) + end + end + return head,start,false +end +function chainprocs.gpos_mark2mark(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local markchar=getchar(start) + if marks[markchar] then + local markanchors=mapping[markchar] + if markanchors then + local base=getprev(start) + local slc=getligaindex(start) + if slc then + while base do + local blc=getligaindex(base) + if blc and blc~=slc then + base=getprev(base) + else + break + end + end + end + if base then + local basechar=ischar(base,currentfont) + if basechar then + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + if ma then + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) + if trace_marks then + logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)", + cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) + end + return head,start,true + end + end + elseif trace_bugs then + logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),1) + end + elseif trace_bugs then + logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),2) + end + elseif trace_bugs then + logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) + end + end + return head,start,false +end +function chainprocs.gpos_cursive(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local startchar=getchar(start) + local exitanchors=mapping[startchar] + if exitanchors then + if marks[startchar] then + if trace_cursive then + logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar)) + end + else + local nxt=getnext(start) + while nxt do + local nextchar=ischar(nxt,currentfont) + if not nextchar then + break + elseif marks[nextchar] then + nxt=getnext(nxt) + else + local exit=exitanchors[3] + if exit then + local entry=exitanchors[1][nextchar] + if entry then + entry=entry[2] + if entry then + local r2lflag=sequence.flags[4] + local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag) + if trace_cursive then + logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode)) + end + return head,start,true + end + end + elseif trace_bugs then + onetimemessage(currentfont,startchar,"no entry anchors",report_fonts) + end + break + end + end + end + elseif trace_cursive and trace_details then + logprocess("%s, cursive %s is already done",pref(dataset,sequence),gref(getchar(start)),alreadydone) + end + end + return head,start,false +end +local function show_skip(dataset,sequence,char,ck,class) + logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(dataset,sequence),gref(char),class,ck[1],ck[8] or ck[2]) +end +local userkern=nuts.pool and nuts.pool.newkern +do if not userkern then + local thekern=nuts.new("kern",1) + local setkern=nuts.setkern + userkern=function(k) + local n=copy_node(thekern) + setkern(n,k) + return n + end +end end +local function checked(head) + local current=head + while current do + if getid(current)==glue_code then + local kern=userkern(getwidth(current)) + if head==current then + local next=getnext(current) + if next then + setlink(kern,next) + end + flush_node(current) + head=kern + current=next + else + local prev,next=getboth(current) + setlink(prev,kern,next) + flush_node(current) + current=next + end + else + current=getnext(current) + end + end + return head +end +local function setdiscchecked(d,pre,post,replace) + if pre then pre=checked(pre) end + if post then post=checked(post) end + if replace then replace=checked(replace) end + setdisc(d,pre,post,replace) +end +local noflags={ false,false,false,false } +local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck) + local size=ck[5]-ck[4]+1 + local chainlookups=ck[6] + local done=false + if chainlookups then + if size==1 then + local chainlookup=chainlookups[1] + for j=1,#chainlookup do + local chainstep=chainlookup[j] + local chainkind=chainstep.type + local chainproc=chainprocs[chainkind] + if chainproc then + local ok + head,start,ok=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash) + if ok then + done=true + end + else + logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind) + end + end + else + local i=1 + local laststart=start + local nofchainlookups=#chainlookups + while start do + if skiphash then + while start do + local char=ischar(start,currentfont) + if char then + if skiphash and skiphash[char] then + start=getnext(start) + else + break + end + else + break + end + end + end + local chainlookup=chainlookups[i] + if chainlookup then + for j=1,#chainlookup do + local chainstep=chainlookup[j] + local chainkind=chainstep.type + local chainproc=chainprocs[chainkind] + if chainproc then + local ok,n + head,start,ok,n=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash,i) + if ok then + done=true + if n and n>1 and i+n>nofchainlookups then + i=size + break + end + end + else + logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind) + end + end + else + end + i=i+1 + if i>size or not start then + break + elseif start then + laststart=start + start=getnext(start) + end + end + if not start then + start=laststart + end + end + else + local replacements=ck[7] + if replacements then + head,start,done=reversesub(head,start,last,dataset,sequence,replacements,rlmode,skiphash) + else + done=true + if trace_contexts then + logprocess("%s: skipping match",cref(dataset,sequence)) + end + end + end + return head,start,done +end +local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) + if not start then + return head,start,false + end + local startishead=start==head + local seq=ck[3] + local f=ck[4] + local l=ck[5] + local s=#seq + local done=false + local sweepnode=sweepnode + local sweeptype=sweeptype + local sweepoverflow=false + local checkdisc=getprev(head) + local keepdisc=not sweepnode + local lookaheaddisc=nil + local backtrackdisc=nil + local current=start + local last=start + local prev=getprev(start) + local hasglue=false + local i=f + while i<=l do + local id=getid(current) + if id==glyph_code then + i=i+1 + last=current + current=getnext(current) + elseif id==glue_code then + i=i+1 + last=current + current=getnext(current) + hasglue=true + elseif id==disc_code then + if keepdisc then + keepdisc=false + lookaheaddisc=current + local replace=getreplace(current) + if not replace then + sweepoverflow=true + sweepnode=current + current=getnext(current) + else + while replace and i<=l do + if getid(replace)==glyph_code then + i=i+1 + end + replace=getnext(replace) + end + current=getnext(replace) + end + last=current + else + head,current=flattendisk(head,current) + end + else + last=current + current=getnext(current) + end + if current then + elseif sweepoverflow then + break + elseif sweeptype=="post" or sweeptype=="replace" then + current=getnext(sweepnode) + if current then + sweeptype=nil + sweepoverflow=true + else + break + end + else + break + end + end + if sweepoverflow then + local prev=current and getprev(current) + if not current or prev~=sweepnode then + local head=getnext(sweepnode) + local tail=nil + if prev then + tail=prev + setprev(current,sweepnode) + else + tail=find_node_tail(head) + end + setnext(sweepnode,current) + setprev(head) + setnext(tail) + appenddisc(sweepnode,head) + end + end + if l1 then + local current=prev + local i=f + local t=sweeptype=="pre" or sweeptype=="replace" + if not current and t and current==checkdisc then + current=getprev(sweepnode) + end + while current and i>1 do + local id=getid(current) + if id==glyph_code then + i=i-1 + elseif id==glue_code then + i=i-1 + hasglue=true + elseif id==disc_code then + if keepdisc then + keepdisc=false + if notmatchpost[current]~=notmatchreplace[current] then + backtrackdisc=current + end + local replace=getreplace(current) + while replace and i>1 do + if getid(replace)==glyph_code then + i=i-1 + end + replace=getnext(replace) + end + elseif notmatchpost[current]~=notmatchreplace[current] then + head,current=flattendisk(head,current) + end + end + current=getprev(current) + if t and current==checkdisc then + current=getprev(sweepnode) + end + end + end + local done=false + if lookaheaddisc then + local cf=start + local cl=getprev(lookaheaddisc) + local cprev=getprev(start) + local insertedmarks=0 + while cprev do + local char=ischar(cf,currentfont) + if char and marks[char] then + insertedmarks=insertedmarks+1 + cf=cprev + startishead=cf==head + cprev=getprev(cprev) + else + break + end + end + setlink(cprev,lookaheaddisc) + setprev(cf) + setnext(cl) + if startishead then + head=lookaheaddisc + end + local pre,post,replace=getdisc(lookaheaddisc) + local new=copy_node_list(cf) + local cnew=new + if pre then + setlink(find_node_tail(cf),pre) + end + if replace then + local tail=find_node_tail(new) + setlink(tail,replace) + end + for i=1,insertedmarks do + cnew=getnext(cnew) + end + cl=start + local clast=cnew + for i=f,l do + cl=getnext(cl) + clast=getnext(clast) + end + if not notmatchpre[lookaheaddisc] then + local ok=false + cf,start,ok=chainrun(cf,start,cl,dataset,sequence,rlmode,skiphash,ck) + if ok then + done=true + end + end + if not notmatchreplace[lookaheaddisc] then + local ok=false + new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck) + if ok then + done=true + end + end + if hasglue then + setdiscchecked(lookaheaddisc,cf,post,new) + else + setdisc(lookaheaddisc,cf,post,new) + end + start=getprev(lookaheaddisc) + sweephead[cf]=getnext(clast) or false + sweephead[new]=getnext(cl) or false + elseif backtrackdisc then + local cf=getnext(backtrackdisc) + local cl=start + local cnext=getnext(start) + local insertedmarks=0 + while cnext do + local char=ischar(cnext,currentfont) + if char and marks[char] then + insertedmarks=insertedmarks+1 + cl=cnext + cnext=getnext(cnext) + else + break + end + end + setlink(backtrackdisc,cnext) + setprev(cf) + setnext(cl) + local pre,post,replace,pretail,posttail,replacetail=getdisc(backtrackdisc,true) + local new=copy_node_list(cf) + local cnew=find_node_tail(new) + for i=1,insertedmarks do + cnew=getprev(cnew) + end + local clast=cnew + for i=f,l do + clast=getnext(clast) + end + if not notmatchpost[backtrackdisc] then + local ok=false + cf,start,ok=chainrun(cf,start,last,dataset,sequence,rlmode,skiphash,ck) + if ok then + done=true + end + end + if not notmatchreplace[backtrackdisc] then + local ok=false + new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck) + if ok then + done=true + end + end + if post then + setlink(posttail,cf) + else + post=cf + end + if replace then + setlink(replacetail,new) + else + replace=new + end + if hasglue then + setdiscchecked(backtrackdisc,pre,post,replace) + else + setdisc(backtrackdisc,pre,post,replace) + end + start=getprev(backtrackdisc) + sweephead[post]=getnext(clast) or false + sweephead[replace]=getnext(last) or false + else + local ok=false + head,start,ok=chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck) + if ok then + done=true + end + end + return head,start,done +end +local function chaintrac(head,start,dataset,sequence,rlmode,skiphash,ck,match,discseen,sweepnode) + local rule=ck[1] + local lookuptype=ck[8] or ck[2] + local nofseq=#ck[3] + local first=ck[4] + local last=ck[5] + local char=getchar(start) + logwarning("%s: rule %s %s at char %s for (%s,%s,%s) chars, lookuptype %a, %sdisc seen, %ssweeping", + cref(dataset,sequence),rule,match and "matches" or "nomatch", + gref(char),first-1,last-first+1,nofseq-last,lookuptype, + discseen and "" or "no ",sweepnode and "" or "not ") +end +local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,skiphash) + local sweepnode=sweepnode + local sweeptype=sweeptype + local postreplace + local prereplace + local checkdisc + local discseen + if sweeptype then + if sweeptype=="replace" then + postreplace=true + prereplace=true + else + postreplace=sweeptype=="post" + prereplace=sweeptype=="pre" + end + checkdisc=getprev(head) + end + local currentfont=currentfont + local skipped + local startprev, + startnext=getboth(start) + local done + local nofcontexts=contexts.n + local startchar=nofcontext==1 or ischar(start,currentfont) + for k=1,nofcontexts do + local ck=contexts[k] + local seq=ck[3] + local f=ck[4] + if not startchar or not seq[f][startchar] then + goto next + end + local s=seq.n + local l=ck[5] + local current=start + local last=start + if s==1 then + goto next + end + if l>f then + local discfound + local n=f+1 + last=startnext + while n<=l do + if postreplace and not last then + last=getnext(sweepnode) + sweeptype=nil + end + if last then + local char,id=ischar(last,currentfont) + if char then + if skiphash and skiphash[char] then + skipped=true + if trace_skips then + show_skip(dataset,sequence,char,ck,classes[char]) + end + last=getnext(last) + elseif seq[n][char] then + if nl then + break + end + pre=getnext(pre) + else + notmatchpre[last]=true + break + end + end + if n<=l then + notmatchpre[last]=true + end + else + notmatchpre[last]=true + end + if replace then + while replace do + if seq[n][getchar(replace)] then + n=n+1 + if n>l then + break + end + replace=getnext(replace) + else + notmatchreplace[last]=true + if notmatchpre[last] then + goto next + else + break + end + end + end + if notmatchpre[last] then + goto next + end + end + last=getnext(last) + else + goto next + end + else + goto next + end + end + end + if f>1 then + if startprev then + local prev=startprev + if prereplace and prev==checkdisc then + prev=getprev(sweepnode) + end + if prev then + local discfound + local n=f-1 + while n>=1 do + if prev then + local char,id=ischar(prev,currentfont) + if char then + if skiphash and skiphash[char] then + skipped=true + if trace_skips then + show_skip(dataset,sequence,char,ck,classes[char]) + end + prev=getprev(prev) + elseif seq[n][char] then + if n>1 then + prev=getprev(prev) + end + n=n-1 + elseif discfound then + notmatchreplace[discfound]=true + if notmatchpost[discfound] then + goto next + else + break + end + else + goto next + end + elseif char==false then + if discfound then + notmatchreplace[discfound]=true + if notmatchpost[discfound] then + goto next + end + else + goto next + end + break + elseif id==disc_code then + discseen=true + discfound=prev + notmatchpre[prev]=true + notmatchpost[prev]=nil + notmatchreplace[prev]=nil + local pre,post,replace,pretail,posttail,replacetail=getdisc(prev,true) + if pre~=start and post~=start and replace~=start then + if post then + local n=n + while posttail do + if seq[n][getchar(posttail)] then + n=n-1 + if posttail==post or n<1 then + break + else + posttail=getprev(posttail) + end + else + notmatchpost[prev]=true + break + end + end + if n>=1 then + notmatchpost[prev]=true + end + else + notmatchpost[prev]=true + end + if replace then + while replacetail do + if seq[n][getchar(replacetail)] then + n=n-1 + if replacetail==replace or n<1 then + break + else + replacetail=getprev(replacetail) + end + else + notmatchreplace[prev]=true + if notmatchpost[prev] then + goto next + else + break + end + end + end + else + end + end + prev=getprev(prev) + elseif id==glue_code then + local sn=seq[n] + if (sn[32] and spaces[prev]) or sn[0xFFFC] then + n=n-1 + prev=getprev(prev) + else + goto next + end + elseif seq[n][0xFFFC] then + n=n-1 + prev=getprev(prev) + else + goto next + end + else + goto next + end + end + else + goto next + end + else + goto next + end + end + if s>l then + local current=last and getnext(last) + if not current and postreplace then + current=getnext(sweepnode) + end + if current then + local discfound + local n=l+1 + while n<=s do + if current then + local char,id=ischar(current,currentfont) + if char then + if skiphash and skiphash[char] then + skipped=true + if trace_skips then + show_skip(dataset,sequence,char,ck,classes[char]) + end + current=getnext(current) + elseif seq[n][char] then + if ns then + break + else + pre=getnext(pre) + end + else + notmatchpre[current]=true + break + end + end + if n<=s then + notmatchpre[current]=true + end + else + notmatchpre[current]=true + end + if replace then + while replace do + if seq[n][getchar(replace)] then + n=n+1 + if n>s then + break + else + replace=getnext(replace) + end + else + notmatchreplace[current]=true + if notmatchpre[current] then + goto next + else + break + end + end + end + else + end + current=getnext(current) + elseif id==glue_code then + local sn=seq[n] + if (sn[32] and spaces[current]) or sn[0xFFFC] then + n=n+1 + current=getnext(current) + else + goto next + end + elseif seq[n][0xFFFC] then + n=n+1 + current=getnext(current) + else + goto next + end + else + goto next + end + end + else + goto next + end + end + if trace_contexts then + chaintrac(head,start,dataset,sequence,rlmode,skipped and skiphash,ck,true,discseen,sweepnode) + end + if discseen or sweepnode then + head,start,done=chaindisk(head,start,dataset,sequence,rlmode,skipped and skiphash,ck) + else + head,start,done=chainrun(head,start,last,dataset,sequence,rlmode,skipped and skiphash,ck) + end + if done then + break + end + ::next:: + end + if discseen then + notmatchpre={} + notmatchpost={} + notmatchreplace={} + end + return head,start,done +end +handlers.gsub_context=handle_contextchain +handlers.gsub_contextchain=handle_contextchain +handlers.gsub_reversecontextchain=handle_contextchain +handlers.gpos_contextchain=handle_contextchain +handlers.gpos_context=handle_contextchain +local function chained_contextchain(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash) + local steps=currentlookup.steps + local nofsteps=currentlookup.nofsteps + if nofsteps>1 then + reportmoresteps(dataset,sequence) + end + local l=steps[1].coverage[getchar(start)] + if l then + return handle_contextchain(head,start,dataset,sequence,l,rlmode,skiphash) + else + return head,start,false + end +end +chainprocs.gsub_context=chained_contextchain +chainprocs.gsub_contextchain=chained_contextchain +chainprocs.gsub_reversecontextchain=chained_contextchain +chainprocs.gpos_contextchain=chained_contextchain +chainprocs.gpos_context=chained_contextchain +local missing=setmetatableindex("table") +local logwarning=report_process +local resolved={} +local function logprocess(...) + if trace_steps then + registermessage(...) + if trace_steps=="silent" then + return + end + end + report_process(...) +end +local sequencelists=setmetatableindex(function(t,font) + local sequences=fontdata[font].resources.sequences + if not sequences or not next(sequences) then + sequences=false + end + t[font]=sequences + return sequences +end) +do + local autofeatures=fonts.analyzers.features + local featuretypes=otf.tables.featuretypes + local defaultscript=otf.features.checkeddefaultscript + local defaultlanguage=otf.features.checkeddefaultlanguage + local wildcard="*" + local default="dflt" + local function initialize(sequence,script,language,enabled,autoscript,autolanguage) + local features=sequence.features + if features then + local order=sequence.order + if order then + local featuretype=featuretypes[sequence.type or "unknown"] + for i=1,#order do + local kind=order[i] + local valid=enabled[kind] + if valid then + local scripts=features[kind] + local languages=scripts and ( + scripts[script] or + scripts[wildcard] or + (autoscript and defaultscript(featuretype,autoscript,scripts)) + ) + local enabled=languages and ( + languages[language] or + languages[wildcard] or + (autolanguage and defaultlanguage(featuretype,autolanguage,languages)) + ) + if enabled then + return { valid,autofeatures[kind] or false,sequence,kind } + end + end + end + else + end + end + return false + end + function otf.dataset(tfmdata,font) + local shared=tfmdata.shared + local properties=tfmdata.properties + local language=properties.language or "dflt" + local script=properties.script or "dflt" + local enabled=shared.features + local autoscript=enabled and enabled.autoscript + local autolanguage=enabled and enabled.autolanguage + local res=resolved[font] + if not res then + res={} + resolved[font]=res + end + local rs=res[script] + if not rs then + rs={} + res[script]=rs + end + local rl=rs[language] + if not rl then + rl={ + } + rs[language]=rl + local sequences=tfmdata.resources.sequences + if sequences then + for s=1,#sequences do + local v=enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage) + if v then + rl[#rl+1]=v + end + end + end + end + return rl + end +end +local function report_disc(what,n) + report_run("%s: %s > %s",what,n,languages.serializediscretionary(n)) +end +local function kernrun(disc,k_run,font,attr,...) + if trace_kernruns then + report_disc("kern",disc) + end + local prev,next=getboth(disc) + local nextstart=next + local done=false + local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) + local prevmarks=prev + while prevmarks do + local char=ischar(prevmarks,font) + if char and marks[char] then + prevmarks=getprev(prevmarks) + else + break + end + end + if prev and not ischar(prev,font) then + prev=false + end + if next and not ischar(next,font) then + next=false + end + if pre then + if k_run(pre,"injections",nil,font,attr,...) then + done=true + end + if prev then + setlink(prev,pre) + if k_run(prevmarks,"preinjections",pre,font,attr,...) then + done=true + end + setprev(pre) + setlink(prev,disc) + end + end + if post then + if k_run(post,"injections",nil,font,attr,...) then + done=true + end + if next then + setlink(posttail,next) + if k_run(posttail,"postinjections",next,font,attr,...) then + done=true + end + setnext(posttail) + setlink(disc,next) + end + end + if replace then + if k_run(replace,"injections",nil,font,attr,...) then + done=true + end + if prev then + setlink(prev,replace) + if k_run(prevmarks,"replaceinjections",replace,font,attr,...) then + done=true + end + setprev(replace) + setlink(prev,disc) + end + if next then + setlink(replacetail,next) + if k_run(replacetail,"replaceinjections",next,font,attr,...) then + done=true + end + setnext(replacetail) + setlink(disc,next) + end + elseif prev and next then + setlink(prev,next) + if k_run(prevmarks,"emptyinjections",next,font,attr,...) then + done=true + end + setlink(prev,disc,next) + end + if done and trace_testruns then + report_disc("done",disc) + end + return nextstart,done +end +local function comprun(disc,c_run,...) + if trace_compruns then + report_disc("comp",disc) + end + local pre,post,replace=getdisc(disc) + local renewed=false + if pre then + sweepnode=disc + sweeptype="pre" + local new,done=c_run(pre,...) + if done then + pre=new + renewed=true + end + end + if post then + sweepnode=disc + sweeptype="post" + local new,done=c_run(post,...) + if done then + post=new + renewed=true + end + end + if replace then + sweepnode=disc + sweeptype="replace" + local new,done=c_run(replace,...) + if done then + replace=new + renewed=true + end + end + sweepnode=nil + sweeptype=nil + if renewed then + if trace_testruns then + report_disc("done",disc) + end + setdisc(disc,pre,post,replace) + end + return getnext(disc),renewed +end +local function testrun(disc,t_run,c_run,...) + if trace_testruns then + report_disc("test",disc) + end + local prev,next=getboth(disc) + if not next then + return + end + local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) + local renewed=false + if post or replace then + if post then + setlink(posttail,next) + else + post=next + end + if replace then + setlink(replacetail,next) + else + replace=next + end + local d_post=t_run(post,next,...) + local d_replace=t_run(replace,next,...) + if d_post>0 or d_replace>0 then + local d=d_replace>d_post and d_replace or d_post + local head=getnext(disc) + local tail=head + for i=2,d do + local nx=getnext(tail) + local id=getid(nx) + if id==disc_code then + head,tail=flattendisk(head,nx) + elseif id==glyph_code then + tail=nx + else + break + end + end + next=getnext(tail) + setnext(tail) + setprev(head) + local new=copy_node_list(head) + if posttail then + setlink(posttail,head) + else + post=head + end + if replacetail then + setlink(replacetail,new) + else + replace=new + end + else + if posttail then + setnext(posttail) + else + post=nil + end + if replacetail then + setnext(replacetail) + else + replace=nil + end + end + setlink(disc,next) + end + if trace_testruns then + report_disc("more",disc) + end + if pre then + sweepnode=disc + sweeptype="pre" + local new,ok=c_run(pre,...) + if ok then + pre=new + renewed=true + end + end + if post then + sweepnode=disc + sweeptype="post" + local new,ok=c_run(post,...) + if ok then + post=new + renewed=true + end + end + if replace then + sweepnode=disc + sweeptype="replace" + local new,ok=c_run(replace,...) + if ok then + replace=new + renewed=true + end + end + sweepnode=nil + sweeptype=nil + if renewed then + setdisc(disc,pre,post,replace) + if trace_testruns then + report_disc("done",disc) + end + end + return getnext(disc),renewed +end +local nesting=0 +local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) + local done=false + local sweep=sweephead[head] + local start + if sweep then + start=sweep + sweephead[head]=false + else + start=head + end + while start do + local char,id=ischar(start,font) + if char then + local a + if attr then + a=getglyphdata(start) + end + if not a or (a==attr) then + local lookupmatch=lookupcache[char] + if lookupmatch then + local ok + head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if ok then + done=true + end + end + if start then + start=getnext(start) + end + else + start=getnext(start) + end + elseif char==false then + return head,done + elseif sweep then + return head,done + else + start=getnext(start) + end + end + return head,done +end +local function t_run_single(start,stop,font,attr,lookupcache) + local lastd=nil + while start~=stop do + local char=ischar(start,font) + if char then + local a + if attr then + a=getglyphdata(start) + end + local startnext=getnext(start) + if not a or (a==attr) then + local lookupmatch=lookupcache[char] + if lookupmatch then + local s=startnext + local ss=nil + local sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getreplace(s) + if not s then + s=ss + ss=nil + end + end + local l=nil + local d=0 + while s do + local char=ischar(s,font) + if char then + local lg=lookupmatch[char] + if lg then + if sstop then + d=1 + elseif d>0 then + d=d+1 + end + l=lg + s=getnext(s) + sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getreplace(s) + if not s then + s=ss + ss=nil + end + end + lookupmatch=lg + else + break + end + else + break + end + end + if l and l.ligature then + lastd=d + end + else + end + else + end + if lastd then + return lastd + end + start=startnext + else + break + end + end + return 0 +end +local function k_run_single(sub,injection,last,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) + local a + if attr then + a=getglyphdata(sub) + end + if not a or (a==attr) then + for n in nextnode,sub do + if n==last then + break + end + local char=ischar(n,font) + if char then + local lookupmatch=lookupcache[char] + if lookupmatch then + local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection) + if ok then + return true + end + end + end + end + end +end +local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) + local done=false + local sweep=sweephead[head] + local start + if sweep then + start=sweep + sweephead[head]=false + else + start=head + end + while start do + local char=ischar(start,font) + if char then + local a + if attr then + a=getglyphdata(start) + end + if not a or (a==attr) then + for i=1,nofsteps do + local step=steps[i] + local lookupcache=step.coverage + local lookupmatch=lookupcache[char] + if lookupmatch then + local ok + head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if ok then + done=true + break + elseif not start then + break + end + end + end + if start then + start=getnext(start) + end + else + start=getnext(start) + end + elseif char==false then + return head,done + elseif sweep then + return head,done + else + start=getnext(start) + end + end + return head,done +end +local function t_run_multiple(start,stop,font,attr,steps,nofsteps) + local lastd=nil + while start~=stop do + local char=ischar(start,font) + if char then + local a + if attr then + a=getglyphdata(start) + end + local startnext=getnext(start) + if not a or (a==attr) then + for i=1,nofsteps do + local step=steps[i] + local lookupcache=step.coverage + local lookupmatch=lookupcache[char] + if lookupmatch then + local s=startnext + local ss=nil + local sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getreplace(s) + if not s then + s=ss + ss=nil + end + end + local l=nil + local d=0 + while s do + local char=ischar(s) + if char then + local lg=lookupmatch[char] + if lg then + if sstop then + d=1 + elseif d>0 then + d=d+1 + end + l=lg + s=getnext(s) + sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getreplace(s) + if not s then + s=ss + ss=nil + end + end + lookupmatch=lg + else + break + end + else + break + end + end + if l and l.ligature then + lastd=d + end + end + end + else + end + if lastd then + return lastd + end + start=startnext + else + break + end + end + return 0 +end +local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) + local a + if attr then + a=getglyphdata(sub) + end + if not a or (a==attr) then + for n in nextnode,sub do + if n==last then + break + end + local char=ischar(n) + if char then + for i=1,nofsteps do + local step=steps[i] + local lookupcache=step.coverage + local lookupmatch=lookupcache[char] + if lookupmatch then + local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection) + if ok then + return true + end + end + end + end + end + end +end +local txtdirstate,pardirstate do + local getdirection=nuts.getdirection + txtdirstate=function(start,stack,top,rlparmode) + local dir,pop=getdirection(start) + if pop then + if top==1 then + return 0,rlparmode + else + top=top-1 + if stack[top]==righttoleft_code then + return top,-1 + else + return top,1 + end + end + elseif dir==lefttoright_code then + top=top+1 + stack[top]=lefttoright_code + return top,1 + elseif dir==righttoleft_code then + top=top+1 + stack[top]=righttoleft_code + return top,-1 + else + return top,rlparmode + end + end + pardirstate=function(start) + local dir=getdirection(start) + if dir==lefttoright_code then + return 1,1 + elseif dir==righttoleft_code then + return -1,-1 + else + return 0,0 + end + end +end +otf.helpers=otf.helpers or {} +otf.helpers.txtdirstate=txtdirstate +otf.helpers.pardirstate=pardirstate +do + local fastdisc=true + local testdics=false + directives.register("otf.fastdisc",function(v) fastdisc=v end) + local otfdataset=nil + local getfastdisc={ __index=function(t,k) + local v=usesfont(k,currentfont) + t[k]=v + return v + end } + local getfastspace={ __index=function(t,k) + local v=isspace(k,threshold) or false + t[k]=v + return v + end } + function otf.featuresprocessor(head,font,attr,direction,n) + local sequences=sequencelists[font] + nesting=nesting+1 + if nesting==1 then + currentfont=font + tfmdata=fontdata[font] + descriptions=tfmdata.descriptions + characters=tfmdata.characters + local resources=tfmdata.resources + marks=resources.marks + classes=resources.classes + threshold, + factor=getthreshold(font) + checkmarks=tfmdata.properties.checkmarks + if not otfdataset then + otfdataset=otf.dataset + end + discs=fastdisc and n and n>1 and setmetatable({},getfastdisc) + spaces=setmetatable({},getfastspace) + elseif currentfont~=font then + report_warning("nested call with a different font, level %s, quitting",nesting) + nesting=nesting-1 + return head,false + end + if trace_steps then + checkstep(head) + end + local initialrl=0 + if getid(head)==par_code and start_of_par(head) then + initialrl=pardirstate(head) + elseif direction==righttoleft_code then + initialrl=-1 + end + local datasets=otfdataset(tfmdata,font,attr) + local dirstack={ nil } + sweephead={} + for s=1,#datasets do + local dataset=datasets[s] + local attribute=dataset[2] + local sequence=dataset[3] + local rlparmode=initialrl + local topstack=0 + local typ=sequence.type + local gpossing=typ=="gpos_single" or typ=="gpos_pair" + local forcetestrun=typ=="gsub_ligature" + local handler=handlers[typ] + local steps=sequence.steps + local nofsteps=sequence.nofsteps + local skiphash=sequence.skiphash + if not steps then + local h,ok=handler(head,dataset,sequence,initialrl,font,attr) + if h and h~=head then + head=h + end + elseif typ=="gsub_reversecontextchain" then + local start=find_node_tail(head) + local rlmode=0 + local merged=steps.merged + while start do + local char=ischar(start,font) + if char then + local m=merged[char] + if m then + local a + if attr then + a=getglyphdata(start) + end + if not a or (a==attr) then + for i=m[1],m[2] do + local step=steps[i] + local lookupcache=step.coverage + local lookupmatch=lookupcache[char] + if lookupmatch then + local ok + head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if ok then + break + end + end + end + if start then + start=getprev(start) + end + else + start=getprev(start) + end + else + start=getprev(start) + end + else + start=getprev(start) + end + end + else + local start=head + local rlmode=initialrl + if nofsteps==1 then + local step=steps[1] + local lookupcache=step.coverage + while start do + local char,id=ischar(start,font) + if char then + if skiphash and skiphash[char] then + start=getnext(start) + else + local lookupmatch=lookupcache[char] + if lookupmatch then + local a + if attr then + if getglyphdata(start)==attr and (not attribute or getstate(start,attribute)) then + a=true + end + elseif not attribute or getstate(start,attribute) then + a=true + end + if a then + local ok,df + head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if df then + elseif start then + start=getnext(start) + end + else + start=getnext(start) + end + else + start=getnext(start) + end + end + elseif char==false or id==glue_code then + start=getnext(start) + elseif id==disc_code then + if not discs or discs[start]==true then + local ok + if gpossing then + start,ok=kernrun(start,k_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) + elseif forcetestrun then + start,ok=testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) + else + start,ok=comprun(start,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) + end + else + start=getnext(start) + end + elseif id==math_code then + start=getnext(end_of_math(start)) + elseif id==dir_code then + topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode) + start=getnext(start) + else + start=getnext(start) + end + end + else + local merged=steps.merged + while start do + local char,id=ischar(start,font) + if char then + if skiphash and skiphash[char] then + start=getnext(start) + else + local m=merged[char] + if m then + local a + if attr then + if getglyphdata(start)==attr and (not attribute or getstate(start,attribute)) then + a=true + end + elseif not attribute or getstate(start,attribute) then + a=true + end + if a then + local ok,df + for i=m[1],m[2] do + local step=steps[i] + local lookupcache=step.coverage + local lookupmatch=lookupcache[char] + if lookupmatch then + head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if df then + break + elseif ok then + break + elseif not start then + break + end + end + end + if df then + elseif start then + start=getnext(start) + end + else + start=getnext(start) + end + else + start=getnext(start) + end + end + elseif char==false or id==glue_code then + start=getnext(start) + elseif id==disc_code then + if not discs or discs[start]==true then + local ok + if gpossing then + start,ok=kernrun(start,k_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) + elseif forcetestrun then + start,ok=testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) + else + start,ok=comprun(start,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) + end + else + start=getnext(start) + end + elseif id==math_code then + start=getnext(end_of_math(start)) + elseif id==dir_code then + topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode) + start=getnext(start) + else + start=getnext(start) + end + end + end + end + if trace_steps then + registerstep(head) + end + end + nesting=nesting-1 + return head + end + function otf.datasetpositionprocessor(head,font,direction,dataset) + currentfont=font + tfmdata=fontdata[font] + descriptions=tfmdata.descriptions + characters=tfmdata.characters + local resources=tfmdata.resources + marks=resources.marks + classes=resources.classes + threshold, + factor=getthreshold(font) + checkmarks=tfmdata.properties.checkmarks + if type(dataset)=="number" then + dataset=otfdataset(tfmdata,font,0)[dataset] + end + local sequence=dataset[3] + local typ=sequence.type + local handler=handlers[typ] + local steps=sequence.steps + local nofsteps=sequence.nofsteps + local done=false + local dirstack={ nil } + local start=head + local initialrl=(direction==righttoleft_code) and -1 or 0 + local rlmode=initialrl + local rlparmode=initialrl + local topstack=0 + local merged=steps.merged + local position=0 + while start do + local char,id=ischar(start,font) + if char then + position=position+1 + local m=merged[char] + if m then + if skiphash and skiphash[char] then + start=getnext(start) + else + for i=m[1],m[2] do + local step=steps[i] + local lookupcache=step.coverage + local lookupmatch=lookupcache[char] + if lookupmatch then + local ok + head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if ok then + break + elseif not start then + break + end + end + end + if start then + start=getnext(start) + end + end + else + start=getnext(start) + end + elseif char==false or id==glue_code then + start=getnext(start) + elseif id==math_code then + start=getnext(end_of_math(start)) + elseif id==dir_code then + topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode) + start=getnext(start) + else + start=getnext(start) + end + end + return head + end +end +local plugins={} +otf.plugins=plugins +local report=logs.reporter("fonts") +function otf.registerplugin(name,f) + if type(name)=="string" and type(f)=="function" then + plugins[name]={ name,f } + report() + report("plugin %a has been loaded, please be aware of possible side effects",name) + report() + if logs.pushtarget then + logs.pushtarget("log") + end + report("Plugins are not officially supported unless stated otherwise. This is because") + report("they bypass the regular font handling and therefore some features in ConTeXt") + report("(especially those related to fonts) might not work as expected or might not work") + report("at all. Some plugins are for testing and development only and might change") + report("whenever we feel the need for it.") + report() + if logs.poptarget then + logs.poptarget() + end + end +end +function otf.plugininitializer(tfmdata,value) + if type(value)=="string" then + tfmdata.shared.plugin=plugins[value] + end +end +function otf.pluginprocessor(head,font,attr,direction) + local s=fontdata[font].shared + local p=s and s.plugin + if p then + if trace_plugins then + report_process("applying plugin %a",p[1]) + end + return p[2](head,font,attr,direction) + else + return head,false + end +end +function otf.featuresinitializer(tfmdata,value) +end +registerotffeature { + name="features", + description="features", + default=true, + initializers={ + position=1, + node=otf.featuresinitializer, + plug=otf.plugininitializer, + }, + processors={ + node=otf.featuresprocessor, + plug=otf.pluginprocessor, + } +} +local function markinitializer(tfmdata,value) + local properties=tfmdata.properties + properties.checkmarks=value +end +registerotffeature { + name="checkmarks", + description="check mark widths", + default=true, + initializers={ + node=markinitializer, + }, +} +otf.handlers=handlers +if context then + return +else +end +local setspacekerns=nodes.injections.setspacekerns if not setspacekerns then os.exit() end +local tag="kern" + function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr) + local shared=fontdata[font].shared + local features=shared and shared.features + local enabled=features and features.spacekern and features[tag] + if enabled then + setspacekerns(font,sequence) + end + return head,enabled + end +local function hasspacekerns(data) + local resources=data.resources + local sequences=resources.sequences + local validgpos=resources.features.gpos + if validgpos and sequences then + for i=1,#sequences do + local sequence=sequences[i] + local steps=sequence.steps + if steps and sequence.features[tag] then + local kind=sequence.type + if kind=="gpos_pair" or kind=="gpos_single" then + for i=1,#steps do + local step=steps[i] + local coverage=step.coverage + local rules=step.rules + if rules then + elseif not coverage then + elseif kind=="gpos_single" then + elseif kind=="gpos_pair" then + local format=step.format + if format=="move" or format=="kern" then + local kerns=coverage[32] + if kerns then + return true + end + for k,v in next,coverage do + if v[32] then + return true + end + end + elseif format=="pair" then + local kerns=coverage[32] + if kerns then + for k,v in next,kerns do + local one=v[1] + if one and one~=true then + return true + end + end + end + for k,v in next,coverage do + local kern=v[32] + if kern then + local one=kern[1] + if one and one~=true then + return true + end + end + end + end + end + end + end + end + end + end + return false +end +otf.readers.registerextender { + name="spacekerns", + action=function(data) + data.properties.hasspacekerns=hasspacekerns(data) + end +} +local function spaceinitializer(tfmdata,value) + local resources=tfmdata.resources + local spacekerns=resources and resources.spacekerns + if value and spacekerns==nil then + local rawdata=tfmdata.shared and tfmdata.shared.rawdata + local properties=rawdata.properties + if properties and properties.hasspacekerns then + local sequences=resources.sequences + local validgpos=resources.features.gpos + if validgpos and sequences then + local left={} + local right={} + local last=0 + local feat=nil + for i=1,#sequences do + local sequence=sequences[i] + local steps=sequence.steps + if steps then + local kern=sequence.features[tag] + if kern then + local kind=sequence.type + if kind=="gpos_pair" or kind=="gpos_single" then + if feat then + for script,languages in next,kern do + local f=feat[script] + if f then + for l in next,languages do + f[l]=true + end + else + feat[script]=languages + end + end + else + feat=kern + end + for i=1,#steps do + local step=steps[i] + local coverage=step.coverage + local rules=step.rules + if rules then + elseif not coverage then + elseif kind=="gpos_single" then + elseif kind=="gpos_pair" then + local format=step.format + if format=="move" or format=="kern" then + local kerns=coverage[32] + if kerns then + for k,v in next,kerns do + right[k]=v + end + end + for k,v in next,coverage do + local kern=v[32] + if kern then + left[k]=kern + end + end + elseif format=="pair" then + local kerns=coverage[32] + if kerns then + for k,v in next,kerns do + local one=v[1] + if one and one~=true then + right[k]=one[3] + end + end + end + for k,v in next,coverage do + local kern=v[32] + if kern then + local one=kern[1] + if one and one~=true then + left[k]=one[3] + end + end + end + end + end + end + last=i + end + else + end + end + end + left=next(left) and left or false + right=next(right) and right or false + if left or right then + spacekerns={ + left=left, + right=right, + } + if last>0 then + local triggersequence={ + features={ [tag]=feat or { dflt={ dflt=true,} } }, + flags=noflags, + name="trigger_space_kerns", + order={ tag }, + type="trigger_space_kerns", + left=left, + right=right, + } + insert(sequences,last,triggersequence) + end + end + end + end + resources.spacekerns=spacekerns + end + return spacekerns +end +registerotffeature { + name="spacekern", + description="space kern injection", + default=true, + initializers={ + node=spaceinitializer, + }, +} + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-ots”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-osd” 73c9531c79df5ada320cb20777f7ed49] --- + +if not modules then modules={} end modules ['font-osd']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Kai Eigner, TAT Zetwerk / Hans Hagen, PRAGMA ADE", + copyright="TAT Zetwerk / PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local insert,imerge,copy,tohash=table.insert,table.imerge,table.copy,table.tohash +local next,type=next,type +local report=logs.reporter("otf","devanagari") +fonts=fonts or {} +fonts.analyzers=fonts.analyzers or {} +fonts.analyzers.methods=fonts.analyzers.methods or { node={ otf={} } } +local otf=fonts.handlers.otf +local handlers=otf.handlers +local methods=fonts.analyzers.methods +local otffeatures=fonts.constructors.features.otf +local registerotffeature=otffeatures.register +local nuts=nodes.nuts +local getnext=nuts.getnext +local getprev=nuts.getprev +local getboth=nuts.getboth +local getid=nuts.getid +local getchar=nuts.getchar +local getfont=nuts.getfont +local getsubtype=nuts.getsubtype +local setlink=nuts.setlink +local setnext=nuts.setnext +local setprev=nuts.setprev +local setchar=nuts.setchar +local getprop=nuts.getprop +local setprop=nuts.setprop +local getstate=nuts.getstate +local setstate=nuts.setstate +local ischar=nuts.ischar +local insert_node_after=nuts.insert_after +local copy_node=nuts.copy +local remove_node=nuts.remove +local flush_list=nuts.flush_list +local flush_node=nuts.flush_node +local copyinjection=nodes.injections.copy +local unsetvalue=attributes.unsetvalue +local fontdata=fonts.hashes.identifiers +local a_syllabe=attributes.private('syllabe') +local dotted_circle=0x25CC +local c_nbsp=0x00A0 +local c_zwnj=0x200C +local c_zwj=0x200D +local states=fonts.analyzers.states +local s_rphf=states.rphf +local s_half=states.half +local s_pref=states.pref +local s_blwf=states.blwf +local s_pstf=states.pstf +local s_init=states.init +local replace_all_nbsp=nil +replace_all_nbsp=function(head) + replace_all_nbsp=typesetters and typesetters.characters and typesetters.characters.replacenbspaces or function(head) + return head + end + return replace_all_nbsp(head) +end +local processcharacters=nil +if context then + local fontprocesses=fonts.hashes.processes + function processcharacters(head,font) + local processors=fontprocesses[font] + for i=1,#processors do + head=processors[i](head,font,0) + end + return head + end +else + function processcharacters(head,font) + local processors=fontdata[font].shared.processes + for i=1,#processors do + head=processors[i](head,font,0) + end + return head + end +end +local indicgroups=characters and characters.indicgroups +if not indicgroups and characters then + local indic={ + c={}, + i={}, + d={}, + m={}, + s={}, + o={}, + } + local indicmarks={ + l={}, + t={}, + b={}, + r={}, + s={}, + } + local indicclasses={ + nukta={}, + halant={}, + ra={}, + anudatta={}, + } + local indicorders={ + bp={}, + ap={}, + bs={}, + as={}, + bh={}, + ah={}, + bm={}, + am={}, + } + for k,v in next,characters.data do + local i=v.indic + if i then + indic[i][k]=true + i=v.indicmark + if i then + if i=="s" then + local s=v.specials + indicmarks[i][k]={ s[2],s[3] } + else + indicmarks[i][k]=true + end + end + i=v.indicclass + if i then + indicclasses[i][k]=true + end + i=v.indicorder + if i then + indicorders[i][k]=true + end + end + end + indicgroups={ + consonant=indic.c, + independent_vowel=indic.i, + dependent_vowel=indic.d, + vowel_modifier=indic.m, + stress_tone_mark=indic.s, + pre_mark=indicmarks.l, + above_mark=indicmarks.t, + below_mark=indicmarks.b, + post_mark=indicmarks.r, + twopart_mark=indicmarks.s, + nukta=indicclasses.nukta, + halant=indicclasses.halant, + ra=indicclasses.ra, + anudatta=indicclasses.anudatta, + before_postscript=indicorders.bp, + after_postscript=indicorders.ap, + before_half=indicorders.bh, + after_half=indicorders.ah, + before_subscript=indicorders.bs, + after_subscript=indicorders.as, + before_main=indicorders.bm, + after_main=indicorders.am, + } + indic=nil + indicmarks=nil + indicclasses=nil + indicorders=nil + characters.indicgroups=indicgroups +end +local consonant=indicgroups.consonant +local independent_vowel=indicgroups.independent_vowel +local dependent_vowel=indicgroups.dependent_vowel +local vowel_modifier=indicgroups.vowel_modifier +local stress_tone_mark=indicgroups.stress_tone_mark +local pre_mark=indicgroups.pre_mark +local above_mark=indicgroups.above_mark +local below_mark=indicgroups.below_mark +local post_mark=indicgroups.post_mark +local twopart_mark=indicgroups.twopart_mark +local nukta=indicgroups.nukta +local halant=indicgroups.halant +local ra=indicgroups.ra +local anudatta=indicgroups.anudatta +local before_postscript=indicgroups.before_postscript +local after_postscript=indicgroups.after_postscript +local before_half=indicgroups.before_half +local after_half=indicgroups.after_half +local before_subscript=indicgroups.before_subscript +local after_subscript=indicgroups.after_subscript +local before_main=indicgroups.before_main +local after_main=indicgroups.after_main +local mark_four=table.merged ( + pre_mark, + above_mark, + below_mark, + post_mark +) +local mark_above_below_post=table.merged ( + above_mark, + below_mark, + post_mark +) +local zw_char={ + [c_zwnj]=true, + [c_zwj ]=true, +} +local dflt_true={ + dflt=true, +} +local two_defaults={} +local one_defaults={} +local false_flags={ false,false,false,false } +local sequence_reorder_matras={ + features={ dv01=two_defaults }, + flags=false_flags, + name="dv01_reorder_matras", + order={ "dv01" }, + type="devanagari_reorder_matras", + nofsteps=1, + steps={ + { + coverage=pre_mark, + } + } +} +local sequence_reorder_reph={ + features={ dv02=two_defaults }, + flags=false_flags, + name="dv02_reorder_reph", + order={ "dv02" }, + type="devanagari_reorder_reph", + nofsteps=1, + steps={ + { + coverage={}, + } + } +} +local sequence_reorder_pre_base_reordering_consonants={ + features={ dv03=one_defaults }, + flags=false_flags, + name="dv03_reorder_pre_base_reordering_consonants", + order={ "dv03" }, + type="devanagari_reorder_pre_base_reordering_consonants", + nofsteps=1, + steps={ + { + coverage={}, + } + } +} +local sequence_remove_joiners={ + features={ dv04=one_defaults }, + flags=false_flags, + name="dv04_remove_joiners", + order={ "dv04" }, + type="devanagari_remove_joiners", + nofsteps=1, + steps={ + { + coverage=zw_char, + }, + } +} +local basic_shaping_forms={ + akhn=true, + blwf=true, + cjct=true, + half=true, + nukt=true, + pref=true, + pstf=true, + rkrf=true, + rphf=true, + vatu=true, + locl=true, +} +local valid={ + abvs=true, + akhn=true, + blwf=true, + calt=true, + cjct=true, + half=true, + haln=true, + nukt=true, + pref=true, + pres=true, + pstf=true, + psts=true, + rkrf=true, + rphf=true, + vatu=true, + pres=true, + abvs=true, + blws=true, + psts=true, + haln=true, + calt=true, + locl=true, +} +local scripts={} +local scripts_one={ "deva","mlym","beng","gujr","guru","knda","orya","taml","telu" } +local scripts_two={ "dev2","mlm2","bng2","gjr2","gur2","knd2","ory2","tml2","tel2" } +local nofscripts=#scripts_one +for i=1,nofscripts do + local one=scripts_one[i] + local two=scripts_two[i] + scripts[one]=true + scripts[two]=true + two_defaults[two]=dflt_true + one_defaults[one]=dflt_true + one_defaults[two]=dflt_true +end +local function valid_one(s) for i=1,nofscripts do if s[scripts_one[i]] then return true end end end +local function valid_two(s) for i=1,nofscripts do if s[scripts_two[i]] then return true end end end +local function initializedevanagi(tfmdata) + local script,language=otf.scriptandlanguage(tfmdata,attr) + if scripts[script] then + local resources=tfmdata.resources + local devanagari=resources.devanagari + if not devanagari then + report("adding devanagari features to font") + local gsubfeatures=resources.features.gsub + local sequences=resources.sequences + local sharedfeatures=tfmdata.shared.features + gsubfeatures["dv01"]=two_defaults + gsubfeatures["dv02"]=two_defaults + gsubfeatures["dv03"]=one_defaults + gsubfeatures["dv04"]=one_defaults + local reorder_pre_base_reordering_consonants=copy(sequence_reorder_pre_base_reordering_consonants) + local reorder_reph=copy(sequence_reorder_reph) + local reorder_matras=copy(sequence_reorder_matras) + local remove_joiners=copy(sequence_remove_joiners) + local lastmatch=0 + for s=1,#sequences do + local features=sequences[s].features + if features then + for k,v in next,features do + if k=="locl" then + local steps=sequences[s].steps + local nofsteps=sequences[s].nofsteps + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + for k,v in next,pre_mark do + local locl=coverage[k] + if locl then + if #locl>0 then + for j=1,#locl do + local ck=locl[j] + local f=ck[4] + local chainlookups=ck[6] + if chainlookups then + local chainlookup=chainlookups[f] + for j=1,#chainlookup do + local chainstep=chainlookup[j] + local steps=chainstep.steps + local nofsteps=chainstep.nofsteps + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + locl=coverage[k] + end + end + end + end + end + end + if locl then + reorder_matras.steps[1].coverage[locl]=true + end + end + end + end + end + end + if basic_shaping_forms[k] then + lastmatch=lastmatch+1 + if s~=lastmatch then + table.insert(sequences,lastmatch,table.remove(sequences,s)) + end + end + end + end + end + local insertindex=lastmatch+1 + if tfmdata.properties.language then + dflt_true[tfmdata.properties.language]=true + end + insert(sequences,insertindex,reorder_pre_base_reordering_consonants) + insert(sequences,insertindex,reorder_reph) + insert(sequences,insertindex,reorder_matras) + insert(sequences,insertindex,remove_joiners) + local blwfcache={} + local vatucache={} + local pstfcache={} + local seqsubset={} + local rephstep={ + coverage={} + } + local devanagari={ + reph=false, + vattu=false, + blwfcache=blwfcache, + vatucache=vatucache, + pstfcache=pstfcache, + seqsubset=seqsubset, + reorderreph=rephstep, + } + reorder_reph.steps={ rephstep } + local pre_base_reordering_consonants={} + reorder_pre_base_reordering_consonants.steps[1].coverage=pre_base_reordering_consonants + resources.devanagari=devanagari + for s=1,#sequences do + local sequence=sequences[s] + local steps=sequence.steps + local nofsteps=sequence.nofsteps + local features=sequence.features + local has_rphf=features.rphf + local has_blwf=features.blwf + local has_vatu=features.vatu + local has_pstf=features.pstf + if has_rphf and has_rphf[script] then + devanagari.reph=true + elseif (has_blwf and has_blwf[script] ) or (has_vatu and has_vatu[script] ) then + devanagari.vattu=true + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + for k,v in next,coverage do + for h,w in next,halant do + if v[h] then + if not blwfcache[k] then + blwfcache[k]=v + end + end + if has_vatu and has_vatu[script] and not vatucache[k] then + vatucache[k]=v + end + end + end + end + end + elseif has_pstf and has_pstf[script] then + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + for k,v in next,coverage do + if not pstfcache[k] then + pstfcache[k]=v + end + end + for k,v in next,ra do + local r=coverage[k] + if r then + local found=false + if #r>0 then + for j=1,#r do + local ck=r[j] + local f=ck[4] + local chainlookups=ck[6] + if chainlookups and chainlookups[f] then + local chainlookup=chainlookups[f] + for j=1,#chainlookup do + local chainstep=chainlookup[j] + local steps=chainstep.steps + local nofsteps=chainstep.nofsteps + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + local h=coverage[k] + if h then + for k,v in next,h do + found=v and v.ligature + if found then + pre_base_reordering_consonants[found]=true + break + end + end + if found then + break + end + end + end + end + end + end + end + else + for k,v in next,r do + found=v and v.ligature + if found then + pre_base_reordering_consonants[found]=true + break + end + end + end + if found then + break + end + end + end + end + end + end + for kind,spec in next,features do + if valid[kind] and valid_two(spec)then + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + local reph,rephbase=false,false + if kind=="rphf" then + for k,v in next,ra do + local r=coverage[k] + if r then + rephbase=k + local h=false + if #r>0 then + for j=1,#r do + local ck=r[j] + local f=ck[4] + local chainlookups=ck[6] + if chainlookups then + local chainlookup=chainlookups[f] + for j=1,#chainlookup do + local chainstep=chainlookup[j] + local steps=chainstep.steps + local nofsteps=chainstep.nofsteps + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + local r=coverage[k] + if r then + for k,v in next,halant do + local h=r[k] + if h then + reph=h.ligature or false + break + end + end + if h then + break + end + end + end + end + end + end + end + else + for k,v in next,halant do + local h=r[k] + if h then + reph=h.ligature or false + break + end + end + end + if reph then + break + end + end + end + end + seqsubset[#seqsubset+1]={ kind,coverage,reph,rephbase } + end + end + end + if kind=="pref" then + local steps=sequence.steps + local nofsteps=sequence.nofsteps + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + for k,v in next,halant do + local h=coverage[k] + if h then + local found=false + if #h>0 then + for j=1,#h do + local ck=h[j] + local f=ck[4] + local chainlookups=ck[6] + if chainlookups then + local chainlookup=chainlookups[f] + for j=1,#chainlookup do + local chainstep=chainlookup[j] + local steps=chainstep.steps + local nofsteps=chainstep.nofsteps + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + local h=coverage[k] + if h then + for k,v in next,h do + found=v and v.ligature + if found then + pre_base_reordering_consonants[found]=true + break + end + end + if found then + break + end + end + end + end + end + end + end + else + for k,v in next,h do + found=v and v.ligature + if found then + pre_base_reordering_consonants[found]=true + break + end + end + end + if found then + break + end + end + end + end + end + end + end + end + if two_defaults[script] then + sharedfeatures["dv01"]=true + sharedfeatures["dv02"]=true + sharedfeatures["dv03"]=true + sharedfeatures["dv04"]=true + elseif one_defaults[script] then + sharedfeatures["dv03"]=true + sharedfeatures["dv04"]=true + end + if script=="mlym" or script=="taml" then + devanagari.left_matra_before_base=true + end + end + end +end +registerotffeature { + name="devanagari", + description="inject additional features", + default=true, + initializers={ + node=initializedevanagi, + }, +} +local show_syntax_errors=false +local function inject_syntax_error(head,current,char) + local signal=copy_node(current) + copyinjection(signal,current) + if pre_mark[char] then + setchar(signal,dotted_circle) + else + setchar(current,dotted_circle) + end + return insert_node_after(head,current,signal) +end +local function initialize_one(font,attr) + local tfmdata=fontdata[font] + local datasets=otf.dataset(tfmdata,font,attr) + local devanagaridata=datasets.devanagari + if not devanagaridata then + devanagaridata={ + reph=false, + vattu=false, + blwfcache={}, + vatucache={}, + pstfcache={}, + } + datasets.devanagari=devanagaridata + local resources=tfmdata.resources + local devanagari=resources.devanagari + for s=1,#datasets do + local dataset=datasets[s] + if dataset and dataset[1] then + local kind=dataset[4] + if kind=="rphf" then + devanagaridata.reph=true + elseif kind=="blwf" or kind=="vatu" then + devanagaridata.vattu=true + devanagaridata.blwfcache=devanagari.blwfcache + devanagaridata.vatucache=devanagari.vatucache + devanagaridata.pstfcache=devanagari.pstfcache + end + end + end + end + return devanagaridata.reph,devanagaridata.vattu,devanagaridata.blwfcache,devanagaridata.vatucache,devanagaridata.pstfcache +end +local function contextchain(contexts,n) + local char=getchar(n) + for k=1,#contexts do + local ck=contexts[k] + local seq=ck[3] + local f=ck[4] + local l=ck[5] + if (l-f)==1 and seq[f+1][char] then + local ok=true + local c=n + for i=l+1,#seq do + c=getnext(c) + if not c or not seq[i][ischar(c)] then + ok=false + break + end + end + if ok then + c=getprev(n) + for i=1,f-1 do + c=getprev(c) + if not c or not seq[f-i][ischar(c)] then + ok=false + end + end + end + if ok then + return true + end + end + end + return false +end +local function order_matras(c) + local cn=getnext(c) + local char=getchar(cn) + while dependent_vowel[char] do + local next=getnext(cn) + local cc=c + local cchar=getchar(cc) + while cc~=cn do + if (above_mark[char] and (below_mark[cchar] or post_mark[cchar])) or (below_mark[char] and (post_mark[cchar])) then + local prev,next=getboth(cn) + if next then + setprev(next,prev) + end + setnext(prev,next) + setnext(getprev(cc),cn) + setprev(cn,getprev(cc)) + setnext(cn,cc) + setprev(cc,cn) + break + end + cc=getnext(cc) + cchar=getchar(cc) + end + cn=next + char=getchar(cn) + end +end +local function reorder_one(head,start,stop,font,attr,nbspaces) + local reph,vattu,blwfcache,vatucache,pstfcache=initialize_one(font,attr) + local devanagari=fontdata[font].resources.devanagari + local current=start + local n=getnext(start) + local base=nil + local firstcons=nil + local lastcons=nil + local basefound=false + if reph and ra[getchar(start)] and halant[getchar(n)] then + if n==stop then + return head,stop,nbspaces + end + if getchar(getnext(n))==c_zwj then + current=start + else + current=getnext(n) + setstate(start,s_rphf) + end + end + if getchar(current)==c_nbsp then + if current==stop then + stop=getprev(stop) + head=remove_node(head,current) + flush_node(current) + return head,stop,nbspaces + else + nbspaces=nbspaces+1 + base=current + firstcons=current + lastcons=current + current=getnext(current) + if current~=stop then + local char=getchar(current) + if nukta[char] then + current=getnext(current) + char=getchar(current) + end + if char==c_zwj and current~=stop then + local next=getnext(current) + if next~=stop and halant[getchar(next)] then + current=next + next=getnext(current) + local tmp=next and getnext(next) or nil + local changestop=next==stop + local tempcurrent=copy_node(next) + copyinjection(tempcurrent,next) + local nextcurrent=copy_node(current) + copyinjection(nextcurrent,current) + setlink(tempcurrent,nextcurrent) + setstate(tempcurrent,s_blwf) + tempcurrent=processcharacters(tempcurrent,font) + setstate(tempcurrent,unsetvalue) + if getchar(next)==getchar(tempcurrent) then + flush_list(tempcurrent) + if show_syntax_errors then + head,current=inject_syntax_error(head,current,char) + end + else + setchar(current,getchar(tempcurrent)) + local freenode=getnext(current) + setlink(current,tmp) + flush_node(freenode) + flush_list(tempcurrent) + if changestop then + stop=current + end + end + end + end + end + end + end + while not basefound do + local char=getchar(current) + if consonant[char] then + setstate(current,s_half) + if not firstcons then + firstcons=current + end + lastcons=current + if not base then + base=current + elseif blwfcache[char] then + setstate(current,s_blwf) + elseif pstfcache[char] then + setstate(current,s_pstf) + else + base=current + end + end + basefound=current==stop + current=getnext(current) + end + if base~=lastcons then + local np=base + local n=getnext(base) + local ch=getchar(n) + if nukta[ch] then + np=n + n=getnext(n) + ch=getchar(n) + end + if halant[ch] then + if lastcons~=stop then + local ln=getnext(lastcons) + if nukta[getchar(ln)] then + lastcons=ln + end + end + local nn=getnext(n) + local ln=getnext(lastcons) + setlink(np,nn) + setnext(lastcons,n) + if ln then + setprev(ln,n) + end + setnext(n,ln) + setprev(n,lastcons) + if lastcons==stop then + stop=n + end + end + end + n=getnext(start) + if n~=stop and ra[getchar(start)] and halant[getchar(n)] and not zw_char[getchar(getnext(n))] then + local matra=base + if base~=stop then + local next=getnext(base) + if dependent_vowel[getchar(next)] then + matra=next + end + end + local sp=getprev(start) + local nn=getnext(n) + local mn=getnext(matra) + setlink(sp,nn) + setlink(matra,start) + setlink(n,mn) + if head==start then + head=nn + end + start=nn + if matra==stop then + stop=n + end + end + local current=start + while current~=stop do + local next=getnext(current) + if next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwnj then + setstate(current,unsetvalue) + end + current=next + end + if base~=stop and getstate(base) then + local next=getnext(base) + if halant[getchar(next)] and not (next~=stop and getchar(getnext(next))==c_zwj) then + setstate(base,unsetvalue) + end + end + local current,allreordered,moved=start,false,{ [base]=true } + local a,b,p,bn=base,base,base,getnext(base) + if base~=stop and nukta[getchar(bn)] then + a,b,p=bn,bn,bn + end + while not allreordered do + local c=current + local n=getnext(current) + local l=nil + if c~=stop then + local ch=getchar(n) + if nukta[ch] then + c=n + n=getnext(n) + ch=getchar(n) + end + if c~=stop then + if halant[ch] then + c=n + n=getnext(n) + ch=getchar(n) + end + local tpm=twopart_mark[ch] + while tpm do + local extra=copy_node(n) + copyinjection(extra,n) + ch=tpm[1] + setchar(n,ch) + setchar(extra,tpm[2]) + head=insert_node_after(head,current,extra) + tpm=twopart_mark[ch] + end + while c~=stop and dependent_vowel[ch] do + c=n + n=getnext(n) + ch=getchar(n) + end + if c~=stop then + if vowel_modifier[ch] then + c=n + n=getnext(n) + ch=getchar(n) + end + if c~=stop and stress_tone_mark[ch] then + c=n + n=getnext(n) + end + end + end + end + local bp=getprev(firstcons) + local cn=getnext(current) + local last=getnext(c) + while cn~=last do + if pre_mark[getchar(cn)] then + if devanagari.left_matra_before_base then + local prev,next=getboth(cn) + setlink(prev,next) + if cn==stop then + stop=getprev(cn) + end + if base==start then + if head==start then + head=cn + end + start=cn + end + setlink(getprev(base),cn) + setlink(cn,base) + cn=next + else + if bp then + setnext(bp,cn) + end + local prev,next=getboth(cn) + if next then + setprev(next,prev) + end + setnext(prev,next) + if cn==stop then + stop=prev + end + setprev(cn,bp) + setlink(cn,firstcons) + if firstcons==start then + if head==start then + head=cn + end + start=cn + end + cn=next + end + elseif current~=base and dependent_vowel[getchar(cn)] then + local prev,next=getboth(cn) + if next then + setprev(next,prev) + end + setnext(prev,next) + if cn==stop then + stop=prev + end + setlink(b,cn,getnext(b)) + order_matras(cn) + cn=next + elseif current==base and dependent_vowel[getchar(cn)] then + local cnn=getnext(cn) + order_matras(cn) + cn=cnn + while cn~=last and dependent_vowel[getchar(cn)] do + cn=getnext(cn) + end + else + cn=getnext(cn) + end + end + allreordered=c==stop + current=getnext(c) + end + if reph or vattu then + local current,cns=start,nil + while current~=stop do + local c=current + local n=getnext(current) + if ra[getchar(current)] and halant[getchar(n)] then + c=n + n=getnext(n) + local b,bn=base,base + while bn~=stop do + local next=getnext(bn) + if dependent_vowel[getchar(next)] then + b=next + end + bn=next + end + if getstate(current,s_rphf) then + if b~=current then + if current==start then + if head==start then + head=n + end + start=n + end + if b==stop then + stop=c + end + local prev=getprev(current) + setlink(prev,n) + local next=getnext(b) + setlink(c,next) + setlink(b,current) + end + elseif cns and getnext(cns)~=current then + local cp=getprev(current) + local cnsn=getnext(cns) + setlink(cp,n) + setlink(cns,current) + setlink(c,cnsn) + if c==stop then + stop=cp + break + end + current=getprev(n) + end + else + local char=getchar(current) + if consonant[char] then + cns=current + local next=getnext(cns) + if halant[getchar(next)] then + cns=next + end + if not vatucache[char] then + next=getnext(cns) + while dependent_vowel[getchar(next)] do + cns=next + next=getnext(cns) + end + end + elseif char==c_nbsp then + nbspaces=nbspaces+1 + cns=current + local next=getnext(cns) + if halant[getchar(next)] then + cns=next + end + if not vatucache[char] then + next=getnext(cns) + while dependent_vowel[getchar(next)] do + cns=next + next=getnext(cns) + end + end + end + end + current=getnext(current) + end + end + if getchar(base)==c_nbsp then + nbspaces=nbspaces-1 + if base==stop then + stop=getprev(stop) + end + head=remove_node(head,base) + flush_node(base) + end + return head,stop,nbspaces +end +function handlers.devanagari_reorder_matras(head,start) + local current=start + local startfont=getfont(start) + local startattr=getprop(start,a_syllabe) + while current do + local char=ischar(current,startfont) + local next=getnext(current) + if char and getprop(current,a_syllabe)==startattr then + if halant[char] then + if next then + local char=ischar(next,startfont) + if char and zw_char[char] and getprop(next,a_syllabe)==startattr then + current=next + next=getnext(current) + end + end + local startnext=getnext(start) + head=remove_node(head,start) + setlink(start,next) + setlink(current,start) + start=startnext + break + end + else + break + end + current=next + end + return head,start,true +end +local rephbase={} +function handlers.devanagari_reorder_reph(head,start) + local current=getnext(start) + local startnext=nil + local startprev=nil + local startfont=getfont(start) + local startattr=getprop(start,a_syllabe) + ::step_1:: + local char=ischar(start,startfont) + local rephbase=rephbase[startfont][char] + if char and after_subscript[rephbase] then + goto step_5 + end + ::step_2:: + if char and not after_postscript[rephbase] then + while current do + local char=ischar(current,startfont) + if char and getprop(current,a_syllabe)==startattr then + if halant[char] then + local next=getnext(current) + if next then + local nextchar=ischar(next,startfont) + if nextchar and zw_char[nextchar] and getprop(next,a_syllabe)==startattr then + current=next + next=getnext(current) + end + end + startnext=getnext(start) + head=remove_node(head,start) + setlink(start,next) + setlink(current,start) + start=startnext + startattr=getprop(start,a_syllabe) + break + end + current=getnext(current) + else + break + end + end + end + ::step_3:: + if not startnext then + if char and after_main[rephbase] then + current=getnext(start) + while current do + local char=ischar(current,startfont) + if char and getprop(current,a_syllabe)==startattr then + if consonant[char] and not getstate(current,s_pref) then + startnext=getnext(start) + head=remove_node(head,start) + setlink(current,start) + setlink(start,getnext(current)) + start=startnext + startattr=getprop(start,a_syllabe) + break + end + current=getnext(current) + else + break + end + end + end + end + ::step_4:: + if not startnext then + if char and before_postscript[rephbase] then + current=getnext(start) + local c=nil + while current do + local char=ischar(current,startfont) + if char and getprop(current,a_syllabe)==startattr then + if getstate(current,s_pstf) then + startnext=getnext(start) + head=remove_node(head,start) + setlink(getprev(current),start) + setlink(start,current) + start=startnext + startattr=getprop(start,a_syllabe) + break + elseif not c and (vowel_modifier[char] or stress_tone_mark[char] ) then + c=current + end + current=getnext(current) + else + if c then + startnext=getnext(start) + head=remove_node(head,start) + setlink(getprev(c),start) + setlink(start,c) + start=startnext + startattr=getprop(start,a_syllabe) + end + break + end + end + end + end + ::step_5:: + if not startnext then + current=getnext(start) + local c=nil + while current do + local char=ischar(current,startfont) + if char and getprop(current,a_syllabe)==startattr then + local state=getstate(current) + if before_subscript[rephbase] and (state==s_blwf or state==s_pstf) then + c=current + elseif after_subscript[rephbase] and (state==s_pstf) then + c=current + end + current=getnext(current) + else + break + end + end + if c then + startnext=getnext(start) + head=remove_node(head,start) + setlink(getprev(c),start) + setlink(start,c) + start=startnext + startattr=getprop(start,a_syllabe) + end + end + ::step_6:: + if not startnext then + current=start + local next=getnext(current) + while next do + local nextchar=ischar(next,startfont) + if nextchar and getprop(next,a_syllabe)==startattr then + current=next + next=getnext(current) + else + break + end + end + if start~=current then + startnext=getnext(start) + head=remove_node(head,start) + setlink(start,getnext(current)) + setlink(current,start) + start=startnext + end + end + return head,start,true +end +local reordered_pre_base_reordering_consonants={} +function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start) + if reordered_pre_base_reordering_consonants[start] then + return head,start,true + end + local current=start + local startfont=getfont(start) + local startattr=getprop(start,a_syllabe) + while current do + local char=ischar(current,startfont) + local next=getnext(current) + if char and getprop(current,a_syllabe)==startattr then + if halant[char] then + if next then + local char=ischar(next,startfont) + if char and zw_char[char] and getprop(next,a_syllabe)==startattr then + current=next + next=getnext(current) + end + end + local startnext=getnext(start) + head=remove_node(head,start) + setlink(start,next) + setlink(current,start) + reordered_pre_base_reordering_consonants[start]=true + start=startnext + return head,start,true + end + else + break + end + current=next + end + local startattr=getprop(start,a_syllabe) + local current=getprev(start) + while current and getprop(current,a_syllabe)==startattr do + local char=ischar(current) + if (not dependent_vowel[char] and (not getstate(current) or getstate(current,s_init))) then + startnext=getnext(start) + head=remove_node(head,start) + if current==head then + setlink(start,current) + head=start + else + setlink(getprev(current),start) + setlink(start,current) + end + reordered_pre_base_reordering_consonants[start]=true + start=startnext + break + end + current=getprev(current) + end + return head,start,true +end +function handlers.devanagari_remove_joiners(head,start,kind,lookupname,replacement) + local stop=getnext(start) + local font=getfont(start) + local last=start + while stop do + local char=ischar(stop,font) + if char and (char==c_zwnj or char==c_zwj) then + last=stop + stop=getnext(stop) + else + break + end + end + local prev=getprev(start) + if stop then + setnext(last) + setlink(prev,stop) + elseif prev then + setnext(prev) + end + if head==start then + head=stop + end + flush_list(start) + return head,stop,true +end +local function initialize_two(font,attr) + local devanagari=fontdata[font].resources.devanagari + if devanagari then + return devanagari.seqsubset or {},devanagari.reorderreph or {} + else + return {},{} + end +end +local function reorder_two(head,start,stop,font,attr,nbspaces) + local seqsubset,reorderreph=initialize_two(font,attr) + local halfpos=nil + local basepos=nil + local subpos=nil + local postpos=nil + reorderreph.coverage={} + rephbase[font]={} + for i=1,#seqsubset do + local subset=seqsubset[i] + local kind=subset[1] + local lookupcache=subset[2] + if kind=="rphf" then + reorderreph.coverage[subset[3]]=true + rephbase[font][subset[3]]=subset[4] + local current=start + local last=getnext(stop) + while current~=last do + if current~=stop then + local c=getchar(current) + local found=lookupcache[c] + if found then + local next=getnext(current) + if found[getchar(next)] or contextchain(found,next) then + local afternext=next~=stop and getnext(next) + if afternext and zw_char[getchar(afternext)] then + current=afternext + elseif current==start then + setstate(current,s_rphf) + current=next + else + current=next + end + end + end + end + current=getnext(current) + end + elseif kind=="pref" then + local current=start + local last=getnext(stop) + while current~=last do + if current~=stop then + local c=getchar(current) + local found=lookupcache[c] + if found then + local next=getnext(current) + if found[getchar(next)] or contextchain(found,next) then + if (not getstate(current) and not getstate(next)) then + setstate(current,s_pref) + setstate(next,s_pref) + current=next + end + end + end + end + current=getnext(current) + end + elseif kind=="half" then + local current=start + local last=getnext(stop) + while current~=last do + if current~=stop then + local c=getchar(current) + local found=lookupcache[c] + if found then + local next=getnext(current) + if found[getchar(next)] or contextchain(found,next) then + if next~=stop and getchar(getnext(next))==c_zwnj then + current=next + elseif (not getstate(current)) then + setstate(current,s_half) + if not halfpos then + halfpos=current + end + end + current=getnext(current) + end + end + end + current=getnext(current) + end + elseif kind=="blwf" or kind=="vatu" then + local current=start + local last=getnext(stop) + while current~=last do + if current~=stop then + local c=getchar(current) + local found=lookupcache[c] + if found then + local next=getnext(current) + if found[getchar(next)] or contextchain(found,next) then + if (not getstate(current) and not getstate(next)) then + setstate(current,s_blwf) + setstate(next,s_blwf) + current=next + subpos=current + end + end + end + end + current=getnext(current) + end + elseif kind=="pstf" then + local current=start + local last=getnext(stop) + while current~=last do + if current~=stop then + local c=getchar(current) + local found=lookupcache[c] + if found then + local next=getnext(current) + if found[getchar(next)] or contextchain(found,next) then + if (not getstate(current) and not getstate(next)) then + setstate(current,s_pstf) + setstate(next,s_pstf) + current=next + postpos=current + end + end + end + end + current=getnext(current) + end + end + end + local current,base,firstcons=start,nil,nil + if getstate(start,s_rphf) then + current=getnext(getnext(start)) + end + if current~=getnext(stop) and getchar(current)==c_nbsp then + if current==stop then + stop=getprev(stop) + head=remove_node(head,current) + flush_node(current) + return head,stop,nbspaces + else + nbspaces=nbspaces+1 + base=current + current=getnext(current) + if current~=stop then + local char=getchar(current) + if nukta[char] then + current=getnext(current) + char=getchar(current) + end + if char==c_zwj then + local next=getnext(current) + if current~=stop and next~=stop and halant[getchar(next)] then + current=next + next=getnext(current) + local tmp=getnext(next) + local changestop=next==stop + setnext(next) + setstate(current,s_pref) + current=processcharacters(current,font) + setstate(current,s_blwf) + current=processcharacters(current,font) + setstate(current,s_pstf) + current=processcharacters(current,font) + setstate(current,unsetvalue) + if halant[getchar(current)] then + setnext(getnext(current),tmp) + if show_syntax_errors then + head,current=inject_syntax_error(head,current,char) + end + else + setnext(current,tmp) + if changestop then + stop=current + end + end + end + end + end + end + else + local last=getnext(stop) + while current~=last do + local next=getnext(current) + if consonant[getchar(current)] then + if not (current~=stop and next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwj) then + if not firstcons then + firstcons=current + end + local a=getstate(current) + if not (a==s_blwf or a==s_pstf or (a~=s_rphf and a~=s_blwf and ra[getchar(current)])) then + base=current + end + end + end + current=next + end + if not base then + base=firstcons + end + end + if not base then + if getstate(start,s_rphf) then + setstate(start,unsetvalue) + end + return head,stop,nbspaces + else + if getstate(base) then + setstate(base,unsetvalue) + end + basepos=base + end + if not halfpos then + halfpos=base + end + if not subpos then + subpos=base + end + if not postpos then + postpos=subpos or base + end + local moved={} + local current=start + local last=getnext(stop) + while current~=last do + local char=getchar(current) + local target=nil + local cn=getnext(current) + local tpm=twopart_mark[char] + while tpm do + local extra=copy_node(current) + copyinjection(extra,current) + char=tpm[1] + setchar(current,char) + setchar(extra,tpm[2]) + head=insert_node_after(head,current,extra) + tpm=twopart_mark[char] + end + if not moved[current] and dependent_vowel[char] then + if pre_mark[char] then + moved[current]=true + local prev,next=getboth(current) + setlink(prev,next) + if current==stop then + stop=getprev(current) + end + local pos + if before_main[char] then + pos=basepos + else + pos=halfpos + end + local ppos=getprev(pos) + while ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) do + if getstate(ppos,s_pref) then + pos=ppos + end + ppos=getprev(ppos) + end + local ppos=getprev(pos) + while ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) and halant[ischar(ppos)] do + ppos=getprev(ppos) + if ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) and consonant[ischar(ppos)] then + pos=ppos + ppos=getprev(ppos) + else + break + end + end + if pos==start then + if head==start then + head=current + end + start=current + end + setlink(getprev(pos),current) + setlink(current,pos) + elseif above_mark[char] then + target=basepos + if subpos==basepos then + subpos=current + end + if postpos==basepos then + postpos=current + end + basepos=current + elseif below_mark[char] then + target=subpos + if postpos==subpos then + postpos=current + end + subpos=current + elseif post_mark[char] then + local n=getnext(postpos) + while n do + local v=ischar(n,font) + if nukta[v] or stress_tone_mark[v] or vowel_modifier[v] then + postpos=n + else + break + end + n=getnext(n) + end + target=postpos + postpos=current + end + if mark_above_below_post[char] then + local prev=getprev(current) + if prev~=target then + local next=getnext(current) + setlink(prev,next) + if current==stop then + stop=prev + end + setlink(current,getnext(target)) + setlink(target,current) + end + end + end + current=cn + end + local current=getnext(start) + local last=getnext(stop) + while current~=last do + local char=getchar(current) + local cn=getnext(current) + if halant[char] and ra[ischar(cn)] and (not getstate(cn,s_rphf)) and (not getstate(cn,s_blwf)) then + if after_main[ischar(cn)] then + local prev=getprev(current) + local next=getnext(cn) + local bpn=getnext(basepos) + while bpn and dependent_vowel[ischar(bpn)] do + basepos=bpn + bpn=getnext(bpn) + end + if basepos~=prev then + setlink(prev,next) + setlink(cn,getnext(basepos)) + setlink(basepos,current) + if cn==stop then + stop=prev + end + cn=next + end + end + end + current=cn + end + local current=start + local c=nil + while current~=stop do + local char=getchar(current) + if halant[char] or stress_tone_mark[char] then + if not c then + c=current + end + else + c=nil + end + local next=getnext(current) + if c and nukta[getchar(next)] then + if head==c then + head=next + end + if stop==next then + stop=current + end + setlink(getprev(c),next) + local nextnext=getnext(next) + setnext(current,nextnext) + local nextnextnext=getnext(nextnext) + if nextnextnext then + setprev(nextnextnext,current) + end + setlink(nextnext,c) + end + if stop==current then break end + current=getnext(current) + end + if getchar(base)==c_nbsp then + if base==stop then + stop=getprev(stop) + end + nbspaces=nbspaces-1 + head=remove_node(head,base) + flush_node(base) + end + return head,stop,nbspaces +end +local separator={} +imerge(separator,consonant) +imerge(separator,independent_vowel) +imerge(separator,dependent_vowel) +imerge(separator,vowel_modifier) +imerge(separator,stress_tone_mark) +for k,v in next,nukta do separator[k]=true end +for k,v in next,halant do separator[k]=true end +local function analyze_next_chars_one(c,font,variant) + local n=getnext(c) + if not n then + return c + end + if variant==1 then + local v=ischar(n,font) + if v and nukta[v] then + n=getnext(n) + if n then + v=ischar(n,font) + end + end + if n and v then + local nn=getnext(n) + if nn then + local vv=ischar(nn,font) + if vv then + local nnn=getnext(nn) + if nnn then + local vvv=ischar(nnn,font) + if vvv then + if vv==c_zwj and consonant[vvv] then + c=nnn + elseif (vv==c_zwnj or vv==c_zwj) and halant[vvv] then + local nnnn=getnext(nnn) + if nnnn then + local vvvv=ischar(nnnn,font) + if vvvv and consonant[vvvv] then + c=nnnn + end + end + end + end + end + end + end + end + elseif variant==2 then + local v=ischar(n,font) + if v and nukta[v] then + c=n + end + n=getnext(c) + if n then + v=ischar(n,font) + if v then + local nn=getnext(n) + if nn then + local vv=ischar(nn,font) + if vv and zw_char[v] then + n=nn + v=vv + nn=getnext(nn) + vv=nn and ischar(nn,font) + end + if vv and halant[v] and consonant[vv] then + c=nn + end + end + end + end + end + local n=getnext(c) + if not n then + return c + end + local v=ischar(n,font) + if not v then + return c + end + local already_pre_mark + local already_above_mark + local already_below_mark + local already_post_mark + while dependent_vowel[v] do + local vowels=twopart_mark[v] or { v } + for k,v in next,vowels do + if pre_mark[v] and not already_pre_mark then + already_pre_mark=true + elseif above_mark[v] and not already_above_mark then + already_above_mark=true + elseif below_mark[v] and not already_below_mark then + already_below_mark=true + elseif post_mark[v] and not already_post_mark then + already_post_mark=true + else + return c + end + end + c=getnext(c) + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if nukta[v] then + c=getnext(c) + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if halant[v] then + c=getnext(c) + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if vowel_modifier[v] then + c=getnext(c) + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if stress_tone_mark[v] then + c=getnext(c) + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if stress_tone_mark[v] then + return n + else + return c + end +end +local function analyze_next_chars_two(c,font) + local n=getnext(c) + if not n then + return c + end + local v=ischar(n,font) + if v and nukta[v] then + c=n + end + n=c + while true do + local nn=getnext(n) + if nn then + local vv=ischar(nn,font) + if vv then + if halant[vv] then + n=nn + local nnn=getnext(nn) + if nnn then + local vvv=ischar(nnn,font) + if vvv and zw_char[vvv] then + n=nnn + end + end + elseif vv==c_zwnj or vv==c_zwj then + local nnn=getnext(nn) + if nnn then + local vvv=ischar(nnn,font) + if vvv and halant[vvv] then + n=nnn + end + end + else + break + end + local nn=getnext(n) + if nn then + local vv=ischar(nn,font) + if vv and consonant[vv] then + n=nn + local nnn=getnext(nn) + if nnn then + local vvv=ischar(nnn,font) + if vvv and nukta[vvv] then + n=nnn + end + end + c=n + else + break + end + else + break + end + else + break + end + else + break + end + end + if not c then + return + end + local n=getnext(c) + if not n then + return c + end + local v=ischar(n,font) + if not v then + return c + end + if anudatta[v] then + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if halant[v] then + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + if v==c_zwnj or v==c_zwj then + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + else + local already_pre_mark + local already_above_mark + local already_below_mark + local already_post_mark + while dependent_vowel[v] do + local vowels=twopart_mark[v] or { v } + for k,v in next,vowels do + if pre_mark[v] and not already_pre_mark then + already_pre_mark=true + elseif above_mark[v] and not already_above_mark then + already_above_mark=true + elseif below_mark[v] and not already_below_mark then + already_below_mark=true + elseif post_mark[v] and not already_post_mark then + already_post_mark=true + else + return c + end + end + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if nukta[v] then + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if halant[v] then + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + end + if vowel_modifier[v] then + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if stress_tone_mark[v] then + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if stress_tone_mark[v] then + return n + else + return c + end +end +local function method_one(head,font,attr) + local current=head + local start=true + local done=false + local nbspaces=0 + local syllabe=0 + while current do + local char=ischar(current,font) + if char then + done=true + local syllablestart=current + local syllableend=nil + local c=current + local n=getnext(c) + local first=char + if n and ra[first] then + local second=ischar(n,font) + if second and halant[second] then + local n=getnext(n) + if n then + local third=ischar(n,font) + if third then + c=n + first=third + end + end + end + end + local standalone=first==c_nbsp + if standalone then + local prev=getprev(current) + if prev then + local prevchar=ischar(prev,font) + if not prevchar then + elseif not separator[prevchar] then + else + standalone=false + end + else + end + end + if standalone then + local syllableend=analyze_next_chars_one(c,font,2) + current=getnext(syllableend) + if syllablestart~=syllableend then + head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces) + current=getnext(current) + end + else + if consonant[char] then + local prevc=true + while prevc do + prevc=false + local n=getnext(current) + if not n then + break + end + local v=ischar(n,font) + if not v then + break + end + if nukta[v] then + n=getnext(n) + if not n then + break + end + v=ischar(n,font) + if not v then + break + end + end + if halant[v] then + n=getnext(n) + if not n then + break + end + v=ischar(n,font) + if not v then + break + end + if v==c_zwnj or v==c_zwj then + n=getnext(n) + if not n then + break + end + v=ischar(n,font) + if not v then + break + end + end + if consonant[v] then + prevc=true + current=n + end + end + end + local n=getnext(current) + if n then + local v=ischar(n,font) + if v and nukta[v] then + current=n + n=getnext(current) + end + end + syllableend=current + current=n + if current then + local v=ischar(current,font) + if not v then + elseif halant[v] then + local n=getnext(current) + if n then + local v=ischar(n,font) + if v and zw_char[v] then + syllableend=n + current=getnext(n) + else + syllableend=current + current=n + end + else + syllableend=current + current=n + end + else + if dependent_vowel[v] then + syllableend=current + current=getnext(current) + v=ischar(current,font) + end + if v and vowel_modifier[v] then + syllableend=current + current=getnext(current) + v=ischar(current,font) + end + if v and stress_tone_mark[v] then + syllableend=current + current=getnext(current) + end + end + end + if syllablestart~=syllableend then + if syllableend then + syllabe=syllabe+1 + local c=syllablestart + local n=getnext(syllableend) + while c~=n do + setprop(c,a_syllabe,syllabe) + c=getnext(c) + end + end + head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces) + current=getnext(current) + end + elseif independent_vowel[char] then + syllableend=current + current=getnext(current) + if current then + local v=ischar(current,font) + if v then + if vowel_modifier[v] then + syllableend=current + current=getnext(current) + v=ischar(current,font) + end + if v and stress_tone_mark[v] then + syllableend=current + current=getnext(current) + end + end + end + else + if show_syntax_errors then + local mark=mark_four[char] + if mark then + head,current=inject_syntax_error(head,current,char) + end + end + current=getnext(current) + end + end + else + current=getnext(current) + end + start=false + end + if nbspaces>0 then + head=replace_all_nbsp(head) + end + current=head + local n=0 + while current do + local char=ischar(current,font) + if char then + if n==0 and not getstate(current) then + setstate(current,s_init) + end + n=n+1 + else + n=0 + end + current=getnext(current) + end + return head,done +end +local function method_two(head,font,attr) + local current=head + local start=true + local done=false + local syllabe=0 + local nbspaces=0 + while current do + local syllablestart=nil + local syllableend=nil + local char=ischar(current,font) + if char then + done=true + syllablestart=current + local c=current + local n=getnext(current) + if n and ra[char] then + local nextchar=ischar(n,font) + if nextchar and halant[nextchar] then + local n=getnext(n) + if n then + local nextnextchar=ischar(n,font) + if nextnextchar then + c=n + char=nextnextchar + end + end + end + end + if independent_vowel[char] then + current=analyze_next_chars_one(c,font,1) + syllableend=current + else + local standalone=char==c_nbsp + if standalone then + nbspaces=nbspaces+1 + local p=getprev(current) + if not p then + elseif ischar(p,font) then + elseif not separator[getchar(p)] then + else + standalone=false + end + end + if standalone then + current=analyze_next_chars_one(c,font,2) + syllableend=current + elseif consonant[getchar(current)] then + current=analyze_next_chars_two(current,font) + syllableend=current + end + end + end + if syllableend then + syllabe=syllabe+1 + local c=syllablestart + local n=getnext(syllableend) + while c~=n do + setprop(c,a_syllabe,syllabe) + c=getnext(c) + end + end + if syllableend and syllablestart~=syllableend then + head,current,nbspaces=reorder_two(head,syllablestart,syllableend,font,attr,nbspaces) + end + if not syllableend and show_syntax_errors then + local char=ischar(current,font) + if char and not getstate(current) then + local mark=mark_four[char] + if mark then + head,current=inject_syntax_error(head,current,char) + end + end + end + start=false + current=getnext(current) + end + if nbspaces>0 then + head=replace_all_nbsp(head) + end + current=head + local n=0 + while current do + local char=ischar(current,font) + if char then + if n==0 and not getstate(current) then + setstate(current,s_init) + end + n=n+1 + else + n=0 + end + current=getnext(current) + end + return head,done +end +for i=1,nofscripts do + methods[scripts_one[i]]=method_one + methods[scripts_two[i]]=method_two +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-osd”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-ocl” 797b5c71bf819c5f4fb314a4d646e9a7] --- + +if not modules then modules={} end modules ['font-ocl']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local tostring,tonumber,next=tostring,tonumber,next +local round,max=math.round,math.round +local gsub,find=string.gsub,string.find +local sortedkeys,sortedhash,concat=table.sortedkeys,table.sortedhash,table.concat +local setmetatableindex=table.setmetatableindex +local formatters=string.formatters +local tounicode=fonts.mappings.tounicode +local helpers=fonts.helpers +local charcommand=helpers.commands.char +local rightcommand=helpers.commands.right +local leftcommand=helpers.commands.left +local downcommand=helpers.commands.down +local otf=fonts.handlers.otf +local otfregister=otf.features.register +local f_color=formatters["%.3f %.3f %.3f rg"] +local f_gray=formatters["%.3f g"] +if context then + local startactualtext=nil + local stopactualtext=nil + function otf.getactualtext(s) + if not startactualtext then + startactualtext=backends.codeinjections.startunicodetoactualtextdirect + stopactualtext=backends.codeinjections.stopunicodetoactualtextdirect + end + return startactualtext(s),stopactualtext() + end +else + local tounicode=fonts.mappings.tounicode16 + function otf.getactualtext(s) + return + "/Span << /ActualText >> BDC", + "EMC" + end +end +local sharedpalettes={} +local hash=setmetatableindex(function(t,k) + local v={ "pdf","direct",k } + t[k]=v + return v +end) +if context then + local colors=attributes.list[attributes.private('color')] or {} + local transparencies=attributes.list[attributes.private('transparency')] or {} + function otf.registerpalette(name,values) + sharedpalettes[name]=values + local color=lpdf.color + local transparency=lpdf.transparency + local register=colors.register + for i=1,#values do + local v=values[i] + if v=="textcolor" then + values[i]=false + else + local c=nil + local t=nil + if type(v)=="table" then + c=register(name,"rgb", + max(round((v.r or 0)*255),255)/255, + max(round((v.g or 0)*255),255)/255, + max(round((v.b or 0)*255),255)/255 + ) + else + c=colors[v] + t=transparencies[v] + end + if c and t then + values[i]=hash[color(1,c).." "..transparency(t)] + elseif c then + values[i]=hash[color(1,c)] + elseif t then + values[i]=hash[color(1,t)] + end + end + end + end +else + function otf.registerpalette(name,values) + sharedpalettes[name]=values + for i=1,#values do + local v=values[i] + if v then + values[i]=hash[f_color( + max(round((v.r or 0)*255),255)/255, + max(round((v.g or 0)*255),255)/255, + max(round((v.b or 0)*255),255)/255 + )] + end + end + end +end +local function convert(t,k) + local v={} + for i=1,#k do + local p=k[i] + local r,g,b=p[1],p[2],p[3] + if r==g and g==b then + v[i]=hash[f_gray(r/255)] + else + v[i]=hash[f_color(r/255,g/255,b/255)] + end + end + t[k]=v + return v +end +local mode={ "pdf","mode","font" } +local push={ "pdf","page","q" } +local pop={ "pdf","page","Q" } +local function initializeoverlay(tfmdata,kind,value) + if value then + local resources=tfmdata.resources + local palettes=resources.colorpalettes + if palettes then + local converted=resources.converted + if not converted then + converted=setmetatableindex(convert) + resources.converted=converted + end + local colorvalues=sharedpalettes[value] + local default=false + if colorvalues then + default=colorvalues[#colorvalues] + else + colorvalues=converted[palettes[tonumber(value) or 1] or palettes[1]] or {} + end + local classes=#colorvalues + if classes==0 then + return + end + local characters=tfmdata.characters + local descriptions=tfmdata.descriptions + local properties=tfmdata.properties + properties.virtualized=true + tfmdata.fonts={ + { id=0 } + } + local getactualtext=otf.getactualtext + local b,e=getactualtext(tounicode(0xFFFD)) + local actualb={ "pdf","page",b } + local actuale={ "pdf","page",e } + for unicode,character in next,characters do + local description=descriptions[unicode] + if description then + local colorlist=description.colors + if colorlist then + local u=description.unicode or characters[unicode].unicode + local w=character.width or 0 + local s=#colorlist + local goback=w~=0 and leftcommand[w] or nil + local t={ + mode, + not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) }, + push, + } + local n=3 + local l=nil + for i=1,s do + local entry=colorlist[i] + local v=colorvalues[entry.class] or default + if v and l~=v then + n=n+1 t[n]=v + l=v + end + n=n+1 t[n]=charcommand[entry.slot] + if s>1 and i temp-otf-svg-shape.log","w") + end + end + local new=nil + local function inkscapeformat(suffix) + if new==nil then + new=os.resultof("inkscape --version") or "" + new=new=="" or not find(new,"Inkscape%s*0") + end + return new and "filename" or suffix + end + function otfsvg.topdf(svgshapes,tfmdata) + local pdfshapes={} + local inkscape=runner() + if inkscape then + local descriptions=tfmdata.descriptions + local nofshapes=#svgshapes + local f_svgfile=formatters["temp-otf-svg-shape-%i.svg"] + local f_pdffile=formatters["temp-otf-svg-shape-%i.pdf"] + local f_convert=formatters["%s --export-%s=%s\n"] + local filterglyph=otfsvg.filterglyph + local nofdone=0 + local processed={} + report_svg("processing %i svg containers",nofshapes) + statistics.starttiming() + for i=1,nofshapes do + local entry=svgshapes[i] + for index=entry.first,entry.last do + local data=filterglyph(entry,index) + if data and data~="" then + local svgfile=f_svgfile(index) + local pdffile=f_pdffile(index) + savedata(svgfile,data) + inkscape:write(f_convert(svgfile,inkscapeformat("pdf"),pdffile)) + processed[index]=true + nofdone=nofdone+1 + if nofdone%25==0 then + report_svg("%i shapes submitted",nofdone) + end + end + end + end + if nofdone%25~=0 then + report_svg("%i shapes submitted",nofdone) + end + report_svg("processing can be going on for a while") + inkscape:write("quit\n") + inkscape:close() + report_svg("processing %i pdf results",nofshapes) + for index in next,processed do + local svgfile=f_svgfile(index) + local pdffile=f_pdffile(index) + local pdfdata=loaddata(pdffile) + if pdfdata and pdfdata~="" then + pdfshapes[index]={ + data=pdfdata, + } + end + remove(svgfile) + remove(pdffile) + end + local characters=tfmdata.characters + for k,v in next,characters do + local d=descriptions[k] + local i=d.index + if i then + local p=pdfshapes[i] + if p then + local w=d.width + local l=d.boundingbox[1] + local r=d.boundingbox[3] + p.scale=(r-l)/w + p.x=l + end + end + end + if not next(pdfshapes) then + report_svg("there are no converted shapes, fix your setup") + end + statistics.stoptiming() + if statistics.elapsedseconds then + report_svg("svg conversion time %s",statistics.elapsedseconds() or "-") + end + end + return pdfshapes + end +end +local function initializesvg(tfmdata,kind,value) + if value and otf.svgenabled then + local svg=tfmdata.properties.svg + local hash=svg and svg.hash + local timestamp=svg and svg.timestamp + if not hash then + return + end + local pdffile=containers.read(otf.pdfcache,hash) + local pdfshapes=pdffile and pdffile.pdfshapes + if not pdfshapes or pdffile.timestamp~=timestamp or not next(pdfshapes) then + local svgfile=containers.read(otf.svgcache,hash) + local svgshapes=svgfile and svgfile.svgshapes + pdfshapes=svgshapes and otfsvg.topdf(svgshapes,tfmdata,otf.pdfcache.writable,hash) or {} + containers.write(otf.pdfcache,hash,{ + pdfshapes=pdfshapes, + timestamp=timestamp, + }) + end + pdftovirtual(tfmdata,pdfshapes,"svg") + return true + end +end +otfregister { + name="svg", + description="svg glyphs", + manipulators={ + base=initializesvg, + node=initializesvg, + } +} +local otfpng=otf.png or {} +otf.png=otfpng +otf.pngenabled=true +do + local report_png=logs.reporter("fonts","png conversion") + local loaddata=io.loaddata + local savedata=io.savedata + local remove=os.remove + local runner=sandbox and sandbox.registerrunner { + name="otfpng", + program="gm", + template="convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log", + } + if not runner then + runner=function() + return os.execute("gm convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log") + end + end + function otfpng.topdf(pngshapes) + local pdfshapes={} + local pngfile="temp-otf-png-shape.png" + local pdffile="temp-otf-png-shape.pdf" + local nofdone=0 + local indices=sortedkeys(pngshapes) + local nofindices=#indices + report_png("processing %i png containers",nofindices) + statistics.starttiming() + for i=1,nofindices do + local index=indices[i] + local entry=pngshapes[index] + local data=entry.data + local x=entry.x + local y=entry.y + savedata(pngfile,data) + runner() + pdfshapes[index]={ + x=x~=0 and x or nil, + y=y~=0 and y or nil, + data=loaddata(pdffile), + } + nofdone=nofdone+1 + if nofdone%100==0 then + report_png("%i shapes processed",nofdone) + end + end + report_png("processing %i pdf results",nofindices) + remove(pngfile) + remove(pdffile) + statistics.stoptiming() + if statistics.elapsedseconds then + report_png("png conversion time %s",statistics.elapsedseconds() or "-") + end + return pdfshapes + end +end +local function initializepng(tfmdata,kind,value) + if value and otf.pngenabled then + local png=tfmdata.properties.png + local hash=png and png.hash + local timestamp=png and png.timestamp + if not hash then + return + end + local pdffile=containers.read(otf.pdfcache,hash) + local pdfshapes=pdffile and pdffile.pdfshapes + if not pdfshapes or pdffile.timestamp~=timestamp then + local pngfile=containers.read(otf.pngcache,hash) + local pngshapes=pngfile and pngfile.pngshapes + pdfshapes=pngshapes and otfpng.topdf(pngshapes) or {} + containers.write(otf.pdfcache,hash,{ + pdfshapes=pdfshapes, + timestamp=timestamp, + }) + end + pdftovirtual(tfmdata,pdfshapes,"png") + return true + end +end +otfregister { + name="sbix", + description="sbix glyphs", + manipulators={ + base=initializepng, + node=initializepng, + } +} +otfregister { + name="cblc", + description="cblc glyphs", + manipulators={ + base=initializepng, + node=initializepng, + } +} +if context then + local function initializecolor(tfmdata,kind,value) + if value=="auto" then + return + initializeoverlay(tfmdata,kind,value) or + initializesvg(tfmdata,kind,value) or + initializepng(tfmdata,kind,value) + elseif value=="overlay" then + return initializeoverlay(tfmdata,kind,value) + elseif value=="svg" then + return initializesvg(tfmdata,kind,value) + elseif value=="png" or value=="bitmap" then + return initializepng(tfmdata,kind,value) + else + end + end + otfregister { + name="color", + description="color glyphs", + manipulators={ + base=initializecolor, + node=initializecolor, + } + } +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-ocl”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-otc” 0f12230ea07b5151f75d52726977e91f] --- + +if not modules then modules={} end modules ['font-otc']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local insert,sortedkeys,sortedhash,tohash=table.insert,table.sortedkeys,table.sortedhash,table.tohash +local type,next,tonumber=type,next,tonumber +local lpegmatch=lpeg.match +local utfbyte,utflen=utf.byte,utf.len +local sortedhash=table.sortedhash +local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) +local report_otf=logs.reporter("fonts","otf loading") +local fonts=fonts +local otf=fonts.handlers.otf +local registerotffeature=otf.features.register +local setmetatableindex=table.setmetatableindex +local fonthelpers=fonts.helpers +local checkmerge=fonthelpers.checkmerge +local checkflags=fonthelpers.checkflags +local checksteps=fonthelpers.checksteps +local normalized={ + substitution="substitution", + single="substitution", + ligature="ligature", + alternate="alternate", + multiple="multiple", + kern="kern", + pair="pair", + single="single", + chainsubstitution="chainsubstitution", + chainposition="chainposition", +} +local types={ + substitution="gsub_single", + ligature="gsub_ligature", + alternate="gsub_alternate", + multiple="gsub_multiple", + kern="gpos_pair", + pair="gpos_pair", + single="gpos_single", + chainsubstitution="gsub_contextchain", + chainposition="gpos_contextchain", +} +local names={ + gsub_single="gsub", + gsub_multiple="gsub", + gsub_alternate="gsub", + gsub_ligature="gsub", + gsub_context="gsub", + gsub_contextchain="gsub", + gsub_reversecontextchain="gsub", + gpos_single="gpos", + gpos_pair="gpos", + gpos_cursive="gpos", + gpos_mark2base="gpos", + gpos_mark2ligature="gpos", + gpos_mark2mark="gpos", + gpos_context="gpos", + gpos_contextchain="gpos", +} +setmetatableindex(types,function(t,k) t[k]=k return k end) +local everywhere={ ["*"]={ ["*"]=true } } +local noflags={ false,false,false,false } +local function getrange(sequences,category) + local count=#sequences + local first=nil + local last=nil + for i=1,count do + local t=sequences[i].type + if t and names[t]==category then + if not first then + first=i + end + last=i + end + end + return first or 1,last or count +end +local function validspecification(specification,name) + local dataset=specification.dataset + if dataset then + elseif specification[1] then + dataset=specification + specification={ dataset=dataset } + else + dataset={ { data=specification.data } } + specification.data=nil + specification.dataset=dataset + end + local first=dataset[1] + if first then + first=first.data + end + if not first then + report_otf("invalid feature specification, no dataset") + return + end + if type(name)~="string" then + name=specification.name or first.name + end + if type(name)~="string" then + report_otf("invalid feature specification, no name") + return + end + local n=#dataset + if n>0 then + for i=1,n do + setmetatableindex(dataset[i],specification) + end + return specification,name + end +end +local function addfeature(data,feature,specifications) + if not specifications then + report_otf("missing specification") + return + end + local descriptions=data.descriptions + local resources=data.resources + local features=resources.features + local sequences=resources.sequences + if not features or not sequences then + report_otf("missing specification") + return + end + local alreadydone=resources.alreadydone + if not alreadydone then + alreadydone={} + resources.alreadydone=alreadydone + end + if alreadydone[specifications] then + return + else + alreadydone[specifications]=true + end + local fontfeatures=resources.features or everywhere + local unicodes=resources.unicodes + local splitter=lpeg.splitter(" ",unicodes) + local done=0 + local skip=0 + local aglunicodes=false + local privateslot=fonthelpers.privateslot + local specifications=validspecification(specifications,feature) + if not specifications then + return + end + local p=lpeg.P("P")*(lpeg.patterns.hexdigit^1/function(s) return tonumber(s,16) end)*lpeg.P(-1) + local function tounicode(code) + if not code then + return + end + if type(code)=="number" then + return code + end + local u=unicodes[code] + if u then + return u + end + if utflen(code)==1 then + u=utfbyte(code) + if u then + return u + end + end + if privateslot then + u=privateslot(code) + if u then + return u + end + end + local u=lpegmatch(p,code) + if u then + return u + end + if not aglunicodes then + aglunicodes=fonts.encodings.agl.unicodes + end + local u=aglunicodes[code] + if u then + return u + end + end + local coverup=otf.coverup + local coveractions=coverup.actions + local stepkey=coverup.stepkey + local register=coverup.register + local function prepare_substitution(list,featuretype,nocheck) + local coverage={} + local cover=coveractions[featuretype] + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if not nocheck and not description then + skip=skip+1 + else + if type(replacement)=="table" then + replacement=replacement[1] + end + replacement=tounicode(replacement) + if replacement and (nocheck or descriptions[replacement]) then + cover(coverage,unicode,replacement) + done=done+1 + else + skip=skip+1 + end + end + end + return coverage + end + local function prepare_alternate(list,featuretype,nocheck) + local coverage={} + local cover=coveractions[featuretype] + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if not nocheck and not description then + skip=skip+1 + elseif type(replacement)=="table" then + local r={} + for i=1,#replacement do + local u=tounicode(replacement[i]) + r[i]=(nocheck or descriptions[u]) and u or unicode + end + cover(coverage,unicode,r) + done=done+1 + else + local u=tounicode(replacement) + if u then + cover(coverage,unicode,{ u }) + done=done+1 + else + skip=skip+1 + end + end + end + return coverage + end + local function prepare_multiple(list,featuretype,nocheck) + local coverage={} + local cover=coveractions[featuretype] + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if not nocheck and not description then + skip=skip+1 + elseif type(replacement)=="table" then + local r={} + local n=0 + for i=1,#replacement do + local u=tounicode(replacement[i]) + if nocheck or descriptions[u] then + n=n+1 + r[n]=u + end + end + if n>0 then + cover(coverage,unicode,r) + done=done+1 + else + skip=skip+1 + end + else + local u=tounicode(replacement) + if u then + cover(coverage,unicode,{ u }) + done=done+1 + else + skip=skip+1 + end + end + end + return coverage + end + local function prepare_ligature(list,featuretype,nocheck) + local coverage={} + local cover=coveractions[featuretype] + for code,ligature in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if not nocheck and not description then + skip=skip+1 + else + if type(ligature)=="string" then + ligature={ lpegmatch(splitter,ligature) } + end + local present=true + for i=1,#ligature do + local l=ligature[i] + local u=tounicode(l) + if nocheck or descriptions[u] then + ligature[i]=u + else + present=false + break + end + end + if present then + cover(coverage,unicode,ligature) + done=done+1 + else + skip=skip+1 + end + end + end + return coverage + end + local function resetspacekerns() + data.properties.hasspacekerns=true + data.resources .spacekerns=nil + end + local function prepare_kern(list,featuretype) + local coverage={} + local cover=coveractions[featuretype] + local isspace=false + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if description and type(replacement)=="table" then + local r={} + for k,v in next,replacement do + local u=tounicode(k) + if u then + r[u]=v + if u==32 then + isspace=true + end + end + end + if next(r) then + cover(coverage,unicode,r) + done=done+1 + if unicode==32 then + isspace=true + end + else + skip=skip+1 + end + else + skip=skip+1 + end + end + if isspace then + resetspacekerns() + end + return coverage + end + local function prepare_pair(list,featuretype) + local coverage={} + local cover=coveractions[featuretype] + if cover then + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if description and type(replacement)=="table" then + local r={} + for k,v in next,replacement do + local u=tounicode(k) + if u then + r[u]=v + if u==32 then + isspace=true + end + end + end + if next(r) then + cover(coverage,unicode,r) + done=done+1 + if unicode==32 then + isspace=true + end + else + skip=skip+1 + end + else + skip=skip+1 + end + end + if isspace then + resetspacekerns() + end + else + report_otf("unknown cover type %a",featuretype) + end + return coverage + end + local prepare_single=prepare_pair + local function prepare_chain(list,featuretype,sublookups) + local rules=list.rules + local coverage={} + if rules then + local rulehash={} + local rulesize=0 + local lookuptype=types[featuretype] + for nofrules=1,#rules do + local rule=rules[nofrules] + local current=rule.current + local before=rule.before + local after=rule.after + local replacements=rule.replacements or false + local sequence={} + local nofsequences=0 + if before then + for n=1,#before do + nofsequences=nofsequences+1 + sequence[nofsequences]=before[n] + end + end + local start=nofsequences+1 + for n=1,#current do + nofsequences=nofsequences+1 + sequence[nofsequences]=current[n] + end + local stop=nofsequences + if after then + for n=1,#after do + nofsequences=nofsequences+1 + sequence[nofsequences]=after[n] + end + end + local lookups=rule.lookups or false + local subtype=nil + if lookups and sublookups then + for k,v in sortedhash(lookups) do + local t=type(v) + if t=="table" then + for i=1,#v do + local vi=v[i] + if type(vi)~="table" then + v[i]={ vi } + end + end + elseif t=="number" then + local lookup=sublookups[v] + if lookup then + lookups[k]={ lookup } + if not subtype then + subtype=lookup.type + end + elseif v==0 then + lookups[k]={ { type="gsub_remove" } } + else + lookups[k]=false + end + else + lookups[k]=false + end + end + end + if nofsequences>0 then + local hashed={} + for i=1,nofsequences do + local t={} + local s=sequence[i] + for i=1,#s do + local u=tounicode(s[i]) + if u then + t[u]=true + end + end + hashed[i]=t + end + sequence=hashed + rulesize=rulesize+1 + rulehash[rulesize]={ + nofrules, + lookuptype, + sequence, + start, + stop, + lookups, + replacements, + subtype, + } + for unic in sortedhash(sequence[start]) do + local cu=coverage[unic] + if not cu then + coverage[unic]=rulehash + end + end + sequence.n=nofsequences + end + end + rulehash.n=rulesize + end + return coverage + end + local dataset=specifications.dataset + local function report(name,category,position,first,last,sequences) + report_otf("injecting name %a of category %a at position %i in [%i,%i] of [%i,%i]", + name,category,position,first,last,1,#sequences) + end + local function inject(specification,sequences,sequence,first,last,category,name) + local position=specification.position or false + if not position then + position=specification.prepend + if position==true then + if trace_loading then + report(name,category,first,first,last,sequences) + end + insert(sequences,first,sequence) + return + end + end + if not position then + position=specification.append + if position==true then + if trace_loading then + report(name,category,last+1,first,last,sequences) + end + insert(sequences,last+1,sequence) + return + end + end + local kind=type(position) + if kind=="string" then + local index=false + for i=first,last do + local s=sequences[i] + local f=s.features + if f then + for k in sortedhash(f) do + if k==position then + index=i + break + end + end + if index then + break + end + end + end + if index then + position=index + else + position=last+1 + end + elseif kind=="number" then + if position<0 then + position=last-position+1 + end + if position>last then + position=last+1 + elseif position0 then + for k,v in next,askedfeatures do + if v[1] then + askedfeatures[k]=tohash(v) + end + end + if featureflags[1] then featureflags[1]="mark" end + if featureflags[2] then featureflags[2]="ligature" end + if featureflags[3] then featureflags[3]="base" end + local steptype=types[featuretype] + local sequence={ + chain=featurechain, + features={ [feature]=askedfeatures }, + flags=featureflags, + name=feature, + order=featureorder, + [stepkey]=steps, + nofsteps=nofsteps, + type=steptype, + } + checkflags(sequence,resources) + checkmerge(sequence) + checksteps(sequence) + local first,last=getrange(sequences,category) + inject(specification,sequences,sequence,first,last,category,feature) + local features=fontfeatures[category] + if not features then + features={} + fontfeatures[category]=features + end + local k=features[feature] + if not k then + k={} + features[feature]=k + end + for script,languages in next,askedfeatures do + local kk=k[script] + if not kk then + kk={} + k[script]=kk + end + for language,value in next,languages do + kk[language]=value + end + end + end + end + end + if trace_loading then + report_otf("registering feature %a, affected glyphs %a, skipped glyphs %a",feature,done,skip) + end +end +otf.enhancers.addfeature=addfeature +local extrafeatures={} +local knownfeatures={} +function otf.addfeature(name,specification) + if type(name)=="table" then + specification=name + end + if type(specification)~="table" then + report_otf("invalid feature specification, no valid table") + return + end + specification,name=validspecification(specification,name) + if name and specification then + local slot=knownfeatures[name] + if not slot then + slot=#extrafeatures+1 + knownfeatures[name]=slot + elseif specification.overload==false then + slot=#extrafeatures+1 + knownfeatures[name]=slot + else + end + specification.name=name + extrafeatures[slot]=specification + end +end +local function enhance(data,filename,raw) + for slot=1,#extrafeatures do + local specification=extrafeatures[slot] + addfeature(data,specification.name,specification) + end +end +otf.enhancers.enhance=enhance +otf.enhancers.register("check extra features",enhance) + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-otc”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-onr” 6d161533f3437435e12a0ad64866df44] --- + +if not modules then modules={} end modules ['font-onr']={ + version=1.001, + optimize=true, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local fonts,logs,trackers,resolvers=fonts,logs,trackers,resolvers +local next,type,tonumber,rawset=next,type,tonumber,rawset +local match,lower,gsub,strip,find=string.match,string.lower,string.gsub,string.strip,string.find +local char,byte,sub=string.char,string.byte,string.sub +local abs=math.abs +local bxor,rshift=bit32.bxor,bit32.rshift +local P,S,R,V,Cmt,C,Ct,Cs,Carg,Cf,Cg,Cc=lpeg.P,lpeg.S,lpeg.R,lpeg.V,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cf,lpeg.Cg,lpeg.Cc +local lpegmatch,patterns=lpeg.match,lpeg.patterns +local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end) +local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end) +local report_afm=logs.reporter("fonts","afm loading") +local report_pfb=logs.reporter("fonts","pfb loading") +local handlers=fonts.handlers +local afm=handlers.afm or {} +handlers.afm=afm +local readers=afm.readers or {} +afm.readers=readers +afm.version=1.513 +local get_indexes,get_shapes +do + local decrypt + do + local r,c1,c2,n=0,0,0,0 + local function step(c) + local cipher=byte(c) + local plain=bxor(cipher,rshift(r,8)) + r=((cipher+r)*c1+c2)%65536 + return char(plain) + end + decrypt=function(binary,initial,seed) + r,c1,c2,n=initial,52845,22719,seed + binary=gsub(binary,".",step) + return sub(binary,n+1) + end + end + local charstrings=P("/CharStrings") + local subroutines=P("/Subrs") + local encoding=P("/Encoding") + local dup=P("dup") + local put=P("put") + local array=P("array") + local name=P("/")*C((R("az","AZ","09")+S("-_."))^1) + local digits=R("09")^1 + local cardinal=digits/tonumber + local spaces=P(" ")^1 + local spacing=patterns.whitespace^0 + local routines,vector,chars,n,m + local initialize=function(str,position,size) + n=0 + m=size + return position+1 + end + local setroutine=function(str,position,index,size,filename) + if routines[index] then + return false + end + local forward=position+size + local stream=decrypt(sub(str,position+1,forward),4330,4) + routines[index]={ byte(stream,1,#stream) } + n=n+1 + if n>=m then + return #str + end + return forward+1 + end + local setvector=function(str,position,name,size,filename) + local forward=position+tonumber(size) + if n>=m then + return #str + elseif forward<#str then + if n==0 and name~=".notdef" then + report_pfb("reserving .notdef at index 0 in %a",filename) + n=n+1 + end + vector[n]=name + n=n+1 + return forward + else + return #str + end + end + local setshapes=function(str,position,name,size,filename) + local forward=position+tonumber(size) + local stream=sub(str,position+1,forward) + if n>m then + return #str + elseif forward<#str then + if n==0 and name~=".notdef" then + report_pfb("reserving .notdef at index 0 in %a",filename) + n=n+1 + end + vector[n]=name + n=n+1 + chars [n]=decrypt(stream,4330,4) + return forward + else + return #str + end + end + local p_rd=spacing*(P("RD")+P("-|")) + local p_np=spacing*(P("NP")+P("|")) + local p_nd=spacing*(P("ND")+P("|")) + local p_filterroutines= + (1-subroutines)^0*subroutines*spaces*Cmt(cardinal,initialize)*(Cmt(cardinal*spaces*cardinal*p_rd*Carg(1),setroutine)*p_np+(1-p_nd))^1 + local p_filtershapes= + (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*p_rd*Carg(1),setshapes)*p_nd+P(1))^1 + local p_filternames=Ct ( + (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*Carg(1),setvector)+P(1))^1 + ) + local p_filterencoding=(1-encoding)^0*encoding*spaces*digits*spaces*array*(1-dup)^0*Cf( + Ct("")*Cg(spacing*dup*spaces*cardinal*spaces*name*spaces*put)^1 +,rawset) + local key=spacing*P("/")*R("az","AZ") + local str=spacing*Cs { (P("(")/"")*((1-P("\\(")-P("\\)")-S("()"))+V(1))^0*(P(")")/"") } + local num=spacing*(R("09")+S("+-."))^1/tonumber + local arr=spacing*Ct (S("[{")*(num)^0*spacing*S("]}")) + local boo=spacing*(P("true")*Cc(true)+P("false")*Cc(false)) + local nam=spacing*P("/")*Cs(R("az","AZ")^1) + local p_filtermetadata=( + P("/")*Carg(1)*(( + C("version")*str+C("Copyright")*str+C("Notice")*str+C("FullName")*str+C("FamilyName")*str+C("Weight")*str+C("ItalicAngle")*num+C("isFixedPitch")*boo+C("UnderlinePosition")*num+C("UnderlineThickness")*num+C("FontName")*nam+C("FontMatrix")*arr+C("FontBBox")*arr + ) )/function(t,k,v) t[lower(k)]=v end+P(1) + )^0*Carg(1) + local function loadpfbvector(filename,shapestoo,streams) + local data=io.loaddata(resolvers.findfile(filename)) + if not data then + report_pfb("no data in %a",filename) + return + end + if not (find(data,"!PS-AdobeFont-",1,true) or find(data,"%!FontType1",1,true)) then + report_pfb("no font in %a",filename) + return + end + local ascii,binary=match(data,"(.*)eexec%s+......(.*)") + if not binary then + report_pfb("no binary data in %a",filename) + return + end + binary=decrypt(binary,55665,4) + local names={} + local encoding=lpegmatch(p_filterencoding,ascii) + local metadata=lpegmatch(p_filtermetadata,ascii,1,{}) + local glyphs={} + routines,vector,chars={},{},{} + if shapestoo or streams then + lpegmatch(p_filterroutines,binary,1,filename) + lpegmatch(p_filtershapes,binary,1,filename) + local data={ + dictionaries={ + { + charstrings=chars, + charset=vector, + subroutines=routines, + } + }, + } + fonts.handlers.otf.readers.parsecharstrings(false,data,glyphs,true,"cff",streams,true) + else + lpegmatch(p_filternames,binary,1,filename) + end + names=vector + routines,vector,chars=nil,nil,nil + return names,encoding,glyphs,metadata + end + local pfb=handlers.pfb or {} + handlers.pfb=pfb + pfb.loadvector=loadpfbvector + get_indexes=function(data,pfbname) + local vector=loadpfbvector(pfbname) + if vector then + local characters=data.characters + if trace_loading then + report_afm("getting index data from %a",pfbname) + end + for index=0,#vector do + local name=vector[index] + local char=characters[name] + if char then + if trace_indexing then + report_afm("glyph %a has index %a",name,index) + end + char.index=index + else + if trace_indexing then + report_afm("glyph %a has index %a but no data",name,index) + end + end + end + end + end + get_shapes=function(pfbname) + local vector,encoding,glyphs=loadpfbvector(pfbname,true) + return glyphs + end +end +local spacer=patterns.spacer +local whitespace=patterns.whitespace +local lineend=patterns.newline +local spacing=spacer^0 +local number=spacing*S("+-")^-1*(R("09")+S("."))^1/tonumber +local name=spacing*C((1-whitespace)^1) +local words=spacing*((1-lineend)^1/strip) +local rest=(1-lineend)^0 +local fontdata=Carg(1) +local semicolon=spacing*P(";") +local plus=spacing*P("plus")*number +local minus=spacing*P("minus")*number +local function addkernpair(data,one,two,value) + local chr=data.characters[one] + if chr then + local kerns=chr.kerns + if kerns then + kerns[two]=tonumber(value) + else + chr.kerns={ [two]=tonumber(value) } + end + end +end +local p_kernpair=(fontdata*P("KPX")*name*name*number)/addkernpair +local chr=false +local ind=0 +local function start(data,version) + data.metadata.afmversion=version + ind=0 + chr={} +end +local function stop() + ind=0 + chr=false +end +local function setindex(i) + if i<0 then + ind=ind+1 + else + ind=i + end + chr={ + index=ind + } +end +local function setwidth(width) + chr.width=width +end +local function setname(data,name) + data.characters[name]=chr +end +local function setboundingbox(boundingbox) + chr.boundingbox=boundingbox +end +local function setligature(plus,becomes) + local ligatures=chr.ligatures + if ligatures then + ligatures[plus]=becomes + else + chr.ligatures={ [plus]=becomes } + end +end +local p_charmetric=(( + P("C")*number/setindex+P("WX")*number/setwidth+P("N")*fontdata*name/setname+P("B")*Ct((number)^4)/setboundingbox+P("L")*(name)^2/setligature + )*semicolon )^1 +local p_charmetrics=P("StartCharMetrics")*number*(p_charmetric+(1-P("EndCharMetrics")))^0*P("EndCharMetrics") +local p_kernpairs=P("StartKernPairs")*number*(p_kernpair+(1-P("EndKernPairs" )))^0*P("EndKernPairs" ) +local function set_1(data,key,a) data.metadata[lower(key)]=a end +local function set_2(data,key,a,b) data.metadata[lower(key)]={ a,b } end +local function set_3(data,key,a,b,c) data.metadata[lower(key)]={ a,b,c } end +local p_parameters=P(false)+fontdata*((P("FontName")+P("FullName")+P("FamilyName"))/lower)*words/function(data,key,value) + data.metadata[key]=value + end+fontdata*((P("Weight")+P("Version"))/lower)*name/function(data,key,value) + data.metadata[key]=value + end+fontdata*P("IsFixedPitch")*name/function(data,pitch) + data.metadata.monospaced=toboolean(pitch,true) + end+fontdata*P("FontBBox")*Ct(number^4)/function(data,boundingbox) + data.metadata.boundingbox=boundingbox + end+fontdata*((P("CharWidth")+P("CapHeight")+P("XHeight")+P("Descender")+P("Ascender")+P("ItalicAngle"))/lower)*number/function(data,key,value) + data.metadata[key]=value + end+P("Comment")*spacing*(P(false)+(fontdata*C("DESIGNSIZE")*number*rest)/set_1 ++(fontdata*C("TFM designsize")*number*rest)/set_1+(fontdata*C("DesignSize")*number*rest)/set_1+(fontdata*C("CODINGSCHEME")*words*rest)/set_1 ++(fontdata*C("CHECKSUM")*number*words*rest)/set_1 ++(fontdata*C("SPACE")*number*plus*minus*rest)/set_3 ++(fontdata*C("QUAD")*number*rest)/set_1 ++(fontdata*C("EXTRASPACE")*number*rest)/set_1 ++(fontdata*C("NUM")*number*number*number*rest)/set_3 ++(fontdata*C("DENOM")*number*number*rest)/set_2 ++(fontdata*C("SUP")*number*number*number*rest)/set_3 ++(fontdata*C("SUB")*number*number*rest)/set_2 ++(fontdata*C("SUPDROP")*number*rest)/set_1 ++(fontdata*C("SUBDROP")*number*rest)/set_1 ++(fontdata*C("DELIM")*number*number*rest)/set_2 ++(fontdata*C("AXISHEIGHT")*number*rest)/set_1 + ) +local fullparser=(P("StartFontMetrics")*fontdata*name/start )*(p_charmetrics+p_kernpairs+p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop ) +local infoparser=(P("StartFontMetrics")*fontdata*name/start )*(p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop ) +local function read(filename,parser) + local afmblob=io.loaddata(filename) + if afmblob then + local data={ + resources={ + filename=resolvers.unresolve(filename), + version=afm.version, + creator="context mkiv", + }, + properties={ + hasitalics=false, + }, + goodies={}, + metadata={ + filename=file.removesuffix(file.basename(filename)) + }, + characters={ + }, + descriptions={ + }, + } + if trace_loading then + report_afm("parsing afm file %a",filename) + end + lpegmatch(parser,afmblob,1,data) + return data + else + if trace_loading then + report_afm("no valid afm file %a",filename) + end + return nil + end +end +function readers.loadfont(afmname,pfbname) + local data=read(resolvers.findfile(afmname),fullparser) + if data then + if not pfbname or pfbname=="" then + pfbname=resolvers.findfile(file.replacesuffix(file.nameonly(afmname),"pfb")) + end + if pfbname and pfbname~="" then + data.resources.filename=resolvers.unresolve(pfbname) + get_indexes(data,pfbname) + return data + else + report_afm("no pfb file for %a",afmname) + end + end +end +function readers.loadshapes(filename) + local fullname=resolvers.findfile(filename) or "" + if fullname=="" then + return { + filename="not found: "..filename, + glyphs={} + } + else + return { + filename=fullname, + format="opentype", + glyphs=get_shapes(fullname) or {}, + units=1000, + } + end +end +function readers.getinfo(filename) + local data=read(resolvers.findfile(filename),infoparser) + if data then + return data.metadata + end +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-onr”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-one” 53cd565030e919da984b50471cc3be37] --- + +if not modules then modules={} end modules ['font-one']={ + version=1.001, + optimize=true, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local fonts,logs,trackers,containers,resolvers=fonts,logs,trackers,containers,resolvers +local next,type,tonumber,rawget=next,type,tonumber,rawget +local match,gsub=string.match,string.gsub +local abs=math.abs +local P,S,R,Cmt,C,Ct,Cs,Carg=lpeg.P,lpeg.S,lpeg.R,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg +local lpegmatch,patterns=lpeg.match,lpeg.patterns +local sortedhash=table.sortedhash +local trace_features=false trackers.register("afm.features",function(v) trace_features=v end) +local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end) +local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end) +local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) +local report_afm=logs.reporter("fonts","afm loading") +local setmetatableindex=table.setmetatableindex +local derivetable=table.derive +local findbinfile=resolvers.findbinfile +local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 +local definers=fonts.definers +local readers=fonts.readers +local constructors=fonts.constructors +local afm=constructors.handlers.afm +local pfb=constructors.handlers.pfb +local otf=fonts.handlers.otf +local otfreaders=otf.readers +local otfenhancers=otf.enhancers +local afmfeatures=constructors.features.afm +local registerafmfeature=afmfeatures.register +local afmenhancers=constructors.enhancers.afm +local registerafmenhancer=afmenhancers.register +afm.version=1.513 +afm.cache=containers.define("fonts","one",afm.version,true) +afm.autoprefixed=true +afm.helpdata={} +afm.syncspace=true +local overloads=fonts.mappings.overloads +local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes +function afm.load(filename) + filename=resolvers.findfile(filename,'afm') or "" + if filename~="" and not fonts.names.ignoredfile(filename) then + local name=file.removesuffix(file.basename(filename)) + local data=containers.read(afm.cache,name) + local attr=lfs.attributes(filename) + local size=attr and attr.size or 0 + local time=attr and attr.modification or 0 + local pfbfile=file.replacesuffix(name,"pfb") + local pfbname=resolvers.findfile(pfbfile,"pfb") or "" + if pfbname=="" then + pfbname=resolvers.findfile(file.basename(pfbfile),"pfb") or "" + end + local pfbsize=0 + local pfbtime=0 + if pfbname~="" then + local attr=lfs.attributes(pfbname) + pfbsize=attr.size or 0 + pfbtime=attr.modification or 0 + end + if not data or data.size~=size or data.time~=time or data.pfbsize~=pfbsize or data.pfbtime~=pfbtime then + report_afm("reading %a",filename) + data=afm.readers.loadfont(filename,pfbname) + if data then + afmenhancers.apply(data,filename) + fonts.mappings.addtounicode(data,filename) + otfreaders.stripredundant(data) + otfreaders.pack(data) + data.size=size + data.time=time + data.pfbsize=pfbsize + data.pfbtime=pfbtime + report_afm("saving %a in cache",name) + data=containers.write(afm.cache,name,data) + data=containers.read(afm.cache,name) + end + end + if data then + otfreaders.unpack(data) + otfreaders.expand(data) + otfreaders.addunicodetable(data) + otfenhancers.apply(data,filename,data) + if applyruntimefixes then + applyruntimefixes(filename,data) + end + end + return data + end +end +local uparser=fonts.mappings.makenameparser() +local function enhance_unify_names(data,filename) + local unicodevector=fonts.encodings.agl.unicodes + local unicodes={} + local names={} + local private=data.private or privateoffset + local descriptions=data.descriptions + for name,blob in sortedhash(data.characters) do + local code=unicodevector[name] + if not code then + code=lpegmatch(uparser,name) + if type(code)~="number" then + code=private + private=private+1 + report_afm("assigning private slot %U for unknown glyph name %a",code,name) + end + end + local index=blob.index + unicodes[name]=code + names[name]=index + blob.name=name + descriptions[code]={ + boundingbox=blob.boundingbox, + width=blob.width, + kerns=blob.kerns, + index=index, + name=name, + } + end + for unicode,description in next,descriptions do + local kerns=description.kerns + if kerns then + local krn={} + for name,kern in next,kerns do + local unicode=unicodes[name] + if unicode then + krn[unicode]=kern + else + end + end + description.kerns=krn + end + end + data.characters=nil + data.private=private + local resources=data.resources + local filename=resources.filename or file.removesuffix(file.basename(filename)) + resources.filename=resolvers.unresolve(filename) + resources.unicodes=unicodes + resources.marks={} +end +local everywhere={ ["*"]={ ["*"]=true } } +local noflags={ false,false,false,false } +local function enhance_normalize_features(data) + local ligatures=setmetatableindex("table") + local kerns=setmetatableindex("table") + local extrakerns=setmetatableindex("table") + for u,c in next,data.descriptions do + local l=c.ligatures + local k=c.kerns + local e=c.extrakerns + if l then + ligatures[u]=l + for u,v in next,l do + l[u]={ ligature=v } + end + c.ligatures=nil + end + if k then + kerns[u]=k + for u,v in next,k do + k[u]=v + end + c.kerns=nil + end + if e then + extrakerns[u]=e + for u,v in next,e do + e[u]=v + end + c.extrakerns=nil + end + end + local features={ + gpos={}, + gsub={}, + } + local sequences={ + } + if next(ligatures) then + features.gsub.liga=everywhere + data.properties.hasligatures=true + sequences[#sequences+1]={ + features={ + liga=everywhere, + }, + flags=noflags, + name="s_s_0", + nofsteps=1, + order={ "liga" }, + type="gsub_ligature", + steps={ + { + coverage=ligatures, + }, + }, + } + end + if next(kerns) then + features.gpos.kern=everywhere + data.properties.haskerns=true + sequences[#sequences+1]={ + features={ + kern=everywhere, + }, + flags=noflags, + name="p_s_0", + nofsteps=1, + order={ "kern" }, + type="gpos_pair", + steps={ + { + format="kern", + coverage=kerns, + }, + }, + } + end + if next(extrakerns) then + features.gpos.extrakerns=everywhere + data.properties.haskerns=true + sequences[#sequences+1]={ + features={ + extrakerns=everywhere, + }, + flags=noflags, + name="p_s_1", + nofsteps=1, + order={ "extrakerns" }, + type="gpos_pair", + steps={ + { + format="kern", + coverage=extrakerns, + }, + }, + } + end + data.resources.features=features + data.resources.sequences=sequences +end +local function enhance_fix_names(data) + for k,v in next,data.descriptions do + local n=v.name + local r=overloads[n] + if r then + local name=r.name + if trace_indexing then + report_afm("renaming characters %a to %a",n,name) + end + v.name=name + v.unicode=r.unicode + end + end +end +local addthem=function(rawdata,ligatures) + if ligatures then + local descriptions=rawdata.descriptions + local resources=rawdata.resources + local unicodes=resources.unicodes + for ligname,ligdata in next,ligatures do + local one=descriptions[unicodes[ligname]] + if one then + for _,pair in next,ligdata do + local two=unicodes[pair[1]] + local three=unicodes[pair[2]] + if two and three then + local ol=one.ligatures + if ol then + if not ol[two] then + ol[two]=three + end + else + one.ligatures={ [two]=three } + end + end + end + end + end + end +end +local function enhance_add_ligatures(rawdata) + addthem(rawdata,afm.helpdata.ligatures) +end +local function enhance_add_extra_kerns(rawdata) + local descriptions=rawdata.descriptions + local resources=rawdata.resources + local unicodes=resources.unicodes + local function do_it_left(what) + if what then + for unicode,description in next,descriptions do + local kerns=description.kerns + if kerns then + local extrakerns + for complex,simple in next,what do + complex=unicodes[complex] + simple=unicodes[simple] + if complex and simple then + local ks=kerns[simple] + if ks and not kerns[complex] then + if extrakerns then + extrakerns[complex]=ks + else + extrakerns={ [complex]=ks } + end + end + end + end + if extrakerns then + description.extrakerns=extrakerns + end + end + end + end + end + local function do_it_copy(what) + if what then + for complex,simple in next,what do + complex=unicodes[complex] + simple=unicodes[simple] + if complex and simple then + local complexdescription=descriptions[complex] + if complexdescription then + local simpledescription=descriptions[complex] + if simpledescription then + local extrakerns + local kerns=simpledescription.kerns + if kerns then + for unicode,kern in next,kerns do + if extrakerns then + extrakerns[unicode]=kern + else + extrakerns={ [unicode]=kern } + end + end + end + local extrakerns=simpledescription.extrakerns + if extrakerns then + for unicode,kern in next,extrakerns do + if extrakerns then + extrakerns[unicode]=kern + else + extrakerns={ [unicode]=kern } + end + end + end + if extrakerns then + complexdescription.extrakerns=extrakerns + end + end + end + end + end + end + end + do_it_left(afm.helpdata.leftkerned) + do_it_left(afm.helpdata.bothkerned) + do_it_copy(afm.helpdata.bothkerned) + do_it_copy(afm.helpdata.rightkerned) +end +local function adddimensions(data) + if data then + for unicode,description in next,data.descriptions do + local bb=description.boundingbox + if bb then + local ht=bb[4] + local dp=-bb[2] + if ht==0 or ht<0 then + else + description.height=ht + end + if dp==0 or dp<0 then + else + description.depth=dp + end + end + end + end +end +local function copytotfm(data) + if data and data.descriptions then + local metadata=data.metadata + local resources=data.resources + local properties=derivetable(data.properties) + local descriptions=derivetable(data.descriptions) + local goodies=derivetable(data.goodies) + local characters={} + local parameters={} + local unicodes=resources.unicodes + for unicode,description in next,data.descriptions do + characters[unicode]={} + end + local filename=constructors.checkedfilename(resources) + local fontname=metadata.fontname or metadata.fullname + local fullname=metadata.fullname or metadata.fontname + local endash=0x2013 + local emdash=0x2014 + local space=0x0020 + local spacer="space" + local spaceunits=500 + local monospaced=metadata.monospaced + local charwidth=metadata.charwidth + local italicangle=metadata.italicangle + local charxheight=metadata.xheight and metadata.xheight>0 and metadata.xheight + properties.monospaced=monospaced + parameters.italicangle=italicangle + parameters.charwidth=charwidth + parameters.charxheight=charxheight + local d_endash=descriptions[endash] + local d_emdash=descriptions[emdash] + local d_space=descriptions[space] + if not d_space or d_space==0 then + d_space=d_endash + end + if d_space then + spaceunits,spacer=d_space.width or 0,"space" + end + if properties.monospaced then + if spaceunits==0 and d_emdash then + spaceunits,spacer=d_emdash.width or 0,"emdash" + end + else + if spaceunits==0 and d_endash then + spaceunits,spacer=d_emdash.width or 0,"endash" + end + end + if spaceunits==0 and charwidth then + spaceunits,spacer=charwidth or 0,"charwidth" + end + if spaceunits==0 then + spaceunits=tonumber(spaceunits) or 500 + end + if spaceunits==0 then + spaceunits=500 + end + parameters.slant=0 + parameters.space=spaceunits + parameters.space_stretch=500 + parameters.space_shrink=333 + parameters.x_height=400 + parameters.quad=1000 + if italicangle and italicangle~=0 then + parameters.italicangle=italicangle + parameters.italicfactor=math.cos(math.rad(90+italicangle)) + parameters.slant=- math.tan(italicangle*math.pi/180) + end + if monospaced then + parameters.space_stretch=0 + parameters.space_shrink=0 + elseif afm.syncspace then + parameters.space_stretch=spaceunits/2 + parameters.space_shrink=spaceunits/3 + end + parameters.extra_space=parameters.space_shrink + if charxheight then + parameters.x_height=charxheight + else + local x=0x0078 + if x then + local x=descriptions[x] + if x then + parameters.x_height=x.height + end + end + end + if metadata.sup then + local dummy={ 0,0,0 } + parameters[ 1]=metadata.designsize or 0 + parameters[ 2]=metadata.checksum or 0 + parameters[ 3], + parameters[ 4], + parameters[ 5]=unpack(metadata.space or dummy) + parameters[ 6]=metadata.quad or 0 + parameters[ 7]=metadata.extraspace or 0 + parameters[ 8], + parameters[ 9], + parameters[10]=unpack(metadata.num or dummy) + parameters[11], + parameters[12]=unpack(metadata.denom or dummy) + parameters[13], + parameters[14], + parameters[15]=unpack(metadata.sup or dummy) + parameters[16], + parameters[17]=unpack(metadata.sub or dummy) + parameters[18]=metadata.supdrop or 0 + parameters[19]=metadata.subdrop or 0 + parameters[20], + parameters[21]=unpack(metadata.delim or dummy) + parameters[22]=metadata.axisheight or 0 + end + parameters.designsize=(metadata.designsize or 10)*65536 + parameters.ascender=abs(metadata.ascender or 0) + parameters.descender=abs(metadata.descender or 0) + parameters.units=1000 + properties.spacer=spacer + properties.format=fonts.formats[filename] or "type1" + properties.filename=filename + properties.fontname=fontname + properties.fullname=fullname + properties.psname=fullname + properties.name=filename or fullname or fontname + properties.private=properties.private or data.private or privateoffset +if not CONTEXTLMTXMODE or CONTEXTLMTXMODE==0 then + properties.encodingbytes=2 +end + if next(characters) then + return { + characters=characters, + descriptions=descriptions, + parameters=parameters, + resources=resources, + properties=properties, + goodies=goodies, + } + end + end + return nil +end +function afm.setfeatures(tfmdata,features) + local okay=constructors.initializefeatures("afm",tfmdata,features,trace_features,report_afm) + if okay then + return constructors.collectprocessors("afm",tfmdata,features,trace_features,report_afm) + else + return {} + end +end +local function addtables(data) + local resources=data.resources + local lookuptags=resources.lookuptags + local unicodes=resources.unicodes + if not lookuptags then + lookuptags={} + resources.lookuptags=lookuptags + end + setmetatableindex(lookuptags,function(t,k) + local v=type(k)=="number" and ("lookup "..k) or k + t[k]=v + return v + end) + if not unicodes then + unicodes={} + resources.unicodes=unicodes + setmetatableindex(unicodes,function(t,k) + setmetatableindex(unicodes,nil) + for u,d in next,data.descriptions do + local n=d.name + if n then + t[n]=u + end + end + return rawget(t,k) + end) + end + constructors.addcoreunicodes(unicodes) +end +local function afmtotfm(specification) + local afmname=specification.filename or specification.name + if specification.forced=="afm" or specification.format=="afm" then + if trace_loading then + report_afm("forcing afm format for %a",afmname) + end + else + local tfmname=findbinfile(afmname,"ofm") or "" + if tfmname~="" then + if trace_loading then + report_afm("fallback from afm to tfm for %a",afmname) + end + return + end + end + if afmname~="" then + local features=constructors.checkedfeatures("afm",specification.features.normal) + specification.features.normal=features + constructors.hashinstance(specification,true) + specification=definers.resolve(specification) + local cache_id=specification.hash + local tfmdata=containers.read(constructors.cache,cache_id) + if not tfmdata then + local rawdata=afm.load(afmname) + if rawdata and next(rawdata) then + addtables(rawdata) + adddimensions(rawdata) + tfmdata=copytotfm(rawdata) + if tfmdata and next(tfmdata) then + local shared=tfmdata.shared + if not shared then + shared={} + tfmdata.shared=shared + end + shared.rawdata=rawdata + shared.dynamics={} + tfmdata.changed={} + shared.features=features + shared.processes=afm.setfeatures(tfmdata,features) + end + elseif trace_loading then + report_afm("no (valid) afm file found with name %a",afmname) + end + tfmdata=containers.write(constructors.cache,cache_id,tfmdata) + end + return tfmdata + end +end +local function read_from_afm(specification) + local tfmdata=afmtotfm(specification) + if tfmdata then + tfmdata.properties.name=specification.name + tfmdata=constructors.scale(tfmdata,specification) + local allfeatures=tfmdata.shared.features or specification.features.normal + constructors.applymanipulators("afm",tfmdata,allfeatures,trace_features,report_afm) + fonts.loggers.register(tfmdata,'afm',specification) + end + return tfmdata +end +registerafmfeature { + name="mode", + description="mode", + initializers={ + base=otf.modeinitializer, + node=otf.modeinitializer, + } +} +registerafmfeature { + name="features", + description="features", + default=true, + initializers={ + node=otf.nodemodeinitializer, + base=otf.basemodeinitializer, + }, + processors={ + node=otf.featuresprocessor, + } +} +fonts.formats.afm="type1" +fonts.formats.pfb="type1" +local function check_afm(specification,fullname) + local foundname=findbinfile(fullname,'afm') or "" + if foundname=="" then + foundname=fonts.names.getfilename(fullname,"afm") or "" + end + if fullname and foundname=="" and afm.autoprefixed then + local encoding,shortname=match(fullname,"^(.-)%-(.*)$") + if encoding and shortname and fonts.encodings.known[encoding] then + shortname=findbinfile(shortname,'afm') or "" + if shortname~="" then + foundname=shortname + if trace_defining then + report_afm("stripping encoding prefix from filename %a",afmname) + end + end + end + end + if foundname~="" then + specification.filename=foundname + specification.format="afm" + return read_from_afm(specification) + end +end +function readers.afm(specification,method) + local fullname=specification.filename or "" + local tfmdata=nil + if fullname=="" then + local forced=specification.forced or "" + if forced~="" then + tfmdata=check_afm(specification,specification.name.."."..forced) + end + if not tfmdata then + local check_tfm=readers.check_tfm + method=(check_tfm and (method or definers.method or "afm or tfm")) or "afm" + if method=="tfm" then + tfmdata=check_tfm(specification,specification.name) + elseif method=="afm" then + tfmdata=check_afm(specification,specification.name) + elseif method=="tfm or afm" then + tfmdata=check_tfm(specification,specification.name) or check_afm(specification,specification.name) + else + tfmdata=check_afm(specification,specification.name) or check_tfm(specification,specification.name) + end + end + else + tfmdata=check_afm(specification,fullname) + end + return tfmdata +end +function readers.pfb(specification,method) + local original=specification.specification + if trace_defining then + report_afm("using afm reader for %a",original) + end + specification.forced="afm" + local function swap(name) + local value=specification[swap] + if value then + specification[swap]=gsub("%.pfb",".afm",1) + end + end + swap("filename") + swap("fullname") + swap("forcedname") + swap("specification") + return readers.afm(specification,method) +end +registerafmenhancer("unify names",enhance_unify_names) +registerafmenhancer("add ligatures",enhance_add_ligatures) +registerafmenhancer("add extra kerns",enhance_add_extra_kerns) +registerafmenhancer("normalize features",enhance_normalize_features) +registerafmenhancer("check extra features",otfenhancers.enhance) +registerafmenhancer("fix names",enhance_fix_names) + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-one”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-afk” 9da14e0fb22129c053acc599d1312544] --- + +if not modules then modules={} end modules ['font-afk']={ + version=1.001, + comment="companion to font-lib.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files", + dataonly=true, +} +local allocate=utilities.storage.allocate +fonts.handlers.afm.helpdata={ + ligatures=allocate { + ['f']={ + { 'f','ff' }, + { 'i','fi' }, + { 'l','fl' }, + }, + ['ff']={ + { 'i','ffi' } + }, + ['fi']={ + { 'i','fii' } + }, + ['fl']={ + { 'i','fli' } + }, + ['s']={ + { 't','st' } + }, + ['i']={ + { 'j','ij' } + }, + }, + texligatures=allocate { + ['quoteleft']={ + { 'quoteleft','quotedblleft' } + }, + ['quoteright']={ + { 'quoteright','quotedblright' } + }, + ['hyphen']={ + { 'hyphen','endash' } + }, + ['endash']={ + { 'hyphen','emdash' } + } + }, + leftkerned=allocate { + AEligature="A",aeligature="a", + OEligature="O",oeligature="o", + IJligature="I",ijligature="i", + AE="A",ae="a", + OE="O",oe="o", + IJ="I",ij="i", + Ssharp="S",ssharp="s", + }, + rightkerned=allocate { + AEligature="E",aeligature="e", + OEligature="E",oeligature="e", + IJligature="J",ijligature="j", + AE="E",ae="e", + OE="E",oe="e", + IJ="J",ij="j", + Ssharp="S",ssharp="s", + }, + bothkerned=allocate { + Acircumflex="A",acircumflex="a", + Ccircumflex="C",ccircumflex="c", + Ecircumflex="E",ecircumflex="e", + Gcircumflex="G",gcircumflex="g", + Hcircumflex="H",hcircumflex="h", + Icircumflex="I",icircumflex="i", + Jcircumflex="J",jcircumflex="j", + Ocircumflex="O",ocircumflex="o", + Scircumflex="S",scircumflex="s", + Ucircumflex="U",ucircumflex="u", + Wcircumflex="W",wcircumflex="w", + Ycircumflex="Y",ycircumflex="y", + Agrave="A",agrave="a", + Egrave="E",egrave="e", + Igrave="I",igrave="i", + Ograve="O",ograve="o", + Ugrave="U",ugrave="u", + Ygrave="Y",ygrave="y", + Atilde="A",atilde="a", + Itilde="I",itilde="i", + Otilde="O",otilde="o", + Utilde="U",utilde="u", + Ntilde="N",ntilde="n", + Adiaeresis="A",adiaeresis="a",Adieresis="A",adieresis="a", + Ediaeresis="E",ediaeresis="e",Edieresis="E",edieresis="e", + Idiaeresis="I",idiaeresis="i",Idieresis="I",idieresis="i", + Odiaeresis="O",odiaeresis="o",Odieresis="O",odieresis="o", + Udiaeresis="U",udiaeresis="u",Udieresis="U",udieresis="u", + Ydiaeresis="Y",ydiaeresis="y",Ydieresis="Y",ydieresis="y", + Aacute="A",aacute="a", + Cacute="C",cacute="c", + Eacute="E",eacute="e", + Iacute="I",iacute="i", + Lacute="L",lacute="l", + Nacute="N",nacute="n", + Oacute="O",oacute="o", + Racute="R",racute="r", + Sacute="S",sacute="s", + Uacute="U",uacute="u", + Yacute="Y",yacute="y", + Zacute="Z",zacute="z", + Dstroke="D",dstroke="d", + Hstroke="H",hstroke="h", + Tstroke="T",tstroke="t", + Cdotaccent="C",cdotaccent="c", + Edotaccent="E",edotaccent="e", + Gdotaccent="G",gdotaccent="g", + Idotaccent="I",idotaccent="i", + Zdotaccent="Z",zdotaccent="z", + Amacron="A",amacron="a", + Emacron="E",emacron="e", + Imacron="I",imacron="i", + Omacron="O",omacron="o", + Umacron="U",umacron="u", + Ccedilla="C",ccedilla="c", + Kcedilla="K",kcedilla="k", + Lcedilla="L",lcedilla="l", + Ncedilla="N",ncedilla="n", + Rcedilla="R",rcedilla="r", + Scedilla="S",scedilla="s", + Tcedilla="T",tcedilla="t", + Ohungarumlaut="O",ohungarumlaut="o", + Uhungarumlaut="U",uhungarumlaut="u", + Aogonek="A",aogonek="a", + Eogonek="E",eogonek="e", + Iogonek="I",iogonek="i", + Uogonek="U",uogonek="u", + Aring="A",aring="a", + Uring="U",uring="u", + Abreve="A",abreve="a", + Ebreve="E",ebreve="e", + Gbreve="G",gbreve="g", + Ibreve="I",ibreve="i", + Obreve="O",obreve="o", + Ubreve="U",ubreve="u", + Ccaron="C",ccaron="c", + Dcaron="D",dcaron="d", + Ecaron="E",ecaron="e", + Lcaron="L",lcaron="l", + Ncaron="N",ncaron="n", + Rcaron="R",rcaron="r", + Scaron="S",scaron="s", + Tcaron="T",tcaron="t", + Zcaron="Z",zcaron="z", + dotlessI="I",dotlessi="i", + dotlessJ="J",dotlessj="j", + AEligature="AE",aeligature="ae",AE="AE",ae="ae", + OEligature="OE",oeligature="oe",OE="OE",oe="oe", + IJligature="IJ",ijligature="ij",IJ="IJ",ij="ij", + Lstroke="L",lstroke="l",Lslash="L",lslash="l", + Ostroke="O",ostroke="o",Oslash="O",oslash="o", + Ssharp="SS",ssharp="ss", + Aumlaut="A",aumlaut="a", + Eumlaut="E",eumlaut="e", + Iumlaut="I",iumlaut="i", + Oumlaut="O",oumlaut="o", + Uumlaut="U",uumlaut="u", + } +} + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-afk”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “fonts-tfm” f0eb5e2a8068b17ad401bb7efdba1630] --- + +if not modules then modules={} end modules ['luatex-fonts-tfm']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next,type=next,type +local match,format=string.match,string.format +local concat,sortedhash=table.concat,table.sortedhash +local idiv=number.idiv +local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) +local trace_features=false trackers.register("tfm.features",function(v) trace_features=v end) +local report_defining=logs.reporter("fonts","defining") +local report_tfm=logs.reporter("fonts","tfm loading") +local findbinfile=resolvers.findbinfile +local setmetatableindex=table.setmetatableindex +local fonts=fonts +local handlers=fonts.handlers +local helpers=fonts.helpers +local readers=fonts.readers +local constructors=fonts.constructors +local encodings=fonts.encodings +local tfm=constructors.handlers.tfm +tfm.version=1.000 +tfm.maxnestingdepth=5 +tfm.maxnestingsize=65536*1024 +local otf=fonts.handlers.otf +local otfenhancers=otf.enhancers +local tfmfeatures=constructors.features.tfm +local registertfmfeature=tfmfeatures.register +local tfmenhancers=constructors.enhancers.tfm +local registertfmenhancer=tfmenhancers.register +local charcommand=helpers.commands.char +constructors.resolvevirtualtoo=false +fonts.formats.tfm="type1" +fonts.formats.ofm="type1" +function tfm.setfeatures(tfmdata,features) + local okay=constructors.initializefeatures("tfm",tfmdata,features,trace_features,report_tfm) + if okay then + return constructors.collectprocessors("tfm",tfmdata,features,trace_features,report_tfm) + else + return {} + end +end +local depth={} +local loadtfm=font.read_tfm +local loadvf=font.read_vf +local function read_from_tfm(specification) + local filename=specification.filename + local size=specification.size + depth[filename]=(depth[filename] or 0)+1 + if trace_defining then + report_defining("loading tfm file %a at size %s",filename,size) + end + local tfmdata=loadtfm(filename,size) + if tfmdata then + local features=specification.features and specification.features.normal or {} + local features=constructors.checkedfeatures("tfm",features) + specification.features.normal=features + local newtfmdata=(depth[filename]==1) and tfm.reencode(tfmdata,specification) + if newtfmdata then + tfmdata=newtfmdata + end + local resources=tfmdata.resources or {} + local properties=tfmdata.properties or {} + local parameters=tfmdata.parameters or {} + local shared=tfmdata.shared or {} + shared.features=features + shared.resources=resources + properties.name=tfmdata.name + properties.fontname=tfmdata.fontname + properties.psname=tfmdata.psname + properties.fullname=tfmdata.fullname + properties.filename=specification.filename + properties.format=tfmdata.format or fonts.formats.tfm + properties.usedbitmap=tfmdata.usedbitmap + tfmdata.properties=properties + tfmdata.resources=resources + tfmdata.parameters=parameters + tfmdata.shared=shared + shared.rawdata={ resources=resources } + shared.features=features + if newtfmdata then + if not resources.marks then + resources.marks={} + end + if not resources.sequences then + resources.sequences={} + end + if not resources.features then + resources.features={ + gsub={}, + gpos={}, + } + end + if not tfmdata.changed then + tfmdata.changed={} + end + if not tfmdata.descriptions then + tfmdata.descriptions=tfmdata.characters + end + otf.readers.addunicodetable(tfmdata) + tfmenhancers.apply(tfmdata,filename) + constructors.applymanipulators("tfm",tfmdata,features,trace_features,report_tfm) + otf.readers.unifymissing(tfmdata) + fonts.mappings.addtounicode(tfmdata,filename) + tfmdata.tounicode=1 + local tounicode=fonts.mappings.tounicode + for unicode,v in next,tfmdata.characters do + local u=v.unicode + if u then + v.tounicode=tounicode(u) + end + end + if tfmdata.usedbitmap then + tfm.addtounicode(tfmdata) + end + end + shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil + if size<0 then + size=idiv(65536*-size,100) + end + parameters.factor=1 + parameters.units=1000 + parameters.size=size + parameters.slant=parameters.slant or parameters[1] or 0 + parameters.space=parameters.space or parameters[2] or 0 + parameters.space_stretch=parameters.space_stretch or parameters[3] or 0 + parameters.space_shrink=parameters.space_shrink or parameters[4] or 0 + parameters.x_height=parameters.x_height or parameters[5] or 0 + parameters.quad=parameters.quad or parameters[6] or 0 + parameters.extra_space=parameters.extra_space or parameters[7] or 0 + constructors.enhanceparameters(parameters) + properties.private=properties.private or tfmdata.private or privateoffset + if newtfmdata then + elseif constructors.resolvevirtualtoo then + fonts.loggers.register(tfmdata,file.suffix(filename),specification) + local vfname=findbinfile(specification.name,'ovf') + if vfname and vfname~="" then + local vfdata=loadvf(vfname,size) + if vfdata then + local chars=tfmdata.characters + for k,v in next,vfdata.characters do + chars[k].commands=v.commands + end + properties.virtualized=true + tfmdata.fonts=vfdata.fonts + tfmdata.type="virtual" + local fontlist=vfdata.fonts + local name=file.nameonly(filename) + for i=1,#fontlist do + local n=fontlist[i].name + local s=fontlist[i].size + local d=depth[filename] + s=constructors.scaled(s,vfdata.designsize) + if d>tfm.maxnestingdepth then + report_defining("too deeply nested virtual font %a with size %a, max nesting depth %s",n,s,tfm.maxnestingdepth) + fontlist[i]={ id=0 } + elseif (d>1) and (s>tfm.maxnestingsize) then + report_defining("virtual font %a exceeds size %s",n,s) + fontlist[i]={ id=0 } + else + local t,id=constructors.readanddefine(n,s) + fontlist[i]={ id=id } + end + end + end + end + end + properties.haskerns=true + properties.hasligatures=true + properties.hasitalics=true + resources.unicodes={} + resources.lookuptags={} + depth[filename]=depth[filename]-1 + return tfmdata + else + depth[filename]=depth[filename]-1 + end +end +local function check_tfm(specification,fullname) + local foundname=findbinfile(fullname,'tfm') or "" + if foundname=="" then + foundname=findbinfile(fullname,'ofm') or "" + end + if foundname=="" then + foundname=fonts.names.getfilename(fullname,"tfm") or "" + end + if foundname~="" then + specification.filename=foundname + specification.format="ofm" + return read_from_tfm(specification) + elseif trace_defining then + report_defining("loading tfm with name %a fails",specification.name) + end +end +readers.check_tfm=check_tfm +function readers.tfm(specification) + local fullname=specification.filename or "" + if fullname=="" then + local forced=specification.forced or "" + if forced~="" then + fullname=specification.name.."."..forced + else + fullname=specification.name + end + end + return check_tfm(specification,fullname) +end +readers.ofm=readers.tfm +do + local outfiles={} + local tfmcache=table.setmetatableindex(function(t,tfmdata) + local id=font.define(tfmdata) + t[tfmdata]=id + return id + end) + local encdone=table.setmetatableindex("table") + function tfm.reencode(tfmdata,specification) + local features=specification.features + if not features then + return + end + local features=features.normal + if not features then + return + end + local tfmfile=file.basename(tfmdata.name) + local encfile=features.reencode + local pfbfile=features.pfbfile + local bitmap=features.bitmap + if not encfile then + return + end + local pfbfile=outfiles[tfmfile] + if pfbfile==nil then + if bitmap then + pfbfile=false + elseif type(pfbfile)~="string" then + pfbfile=tfmfile + end + if type(pfbfile)=="string" then + pfbfile=file.addsuffix(pfbfile,"pfb") + report_tfm("using type1 shapes from %a for %a",pfbfile,tfmfile) + else + report_tfm("using bitmap shapes for %a",tfmfile) + pfbfile=false + end + outfiles[tfmfile]=pfbfile + end + local encoding=false + local vector=false + if type(pfbfile)=="string" then + local pfb=constructors.handlers.pfb + if pfb and pfb.loadvector then + local v,e=pfb.loadvector(pfbfile) + if v then + vector=v + end + if e then + encoding=e + end + end + end + if type(encfile)=="string" and encfile~="auto" then + encoding=fonts.encodings.load(file.addsuffix(encfile,"enc")) + if encoding then + encoding=encoding.vector + end + end + if not encoding then + report_tfm("bad encoding for %a, quitting",tfmfile) + return + end + local unicoding=fonts.encodings.agl and fonts.encodings.agl.unicodes + local virtualid=tfmcache[tfmdata] + local tfmdata=table.copy(tfmdata) + local characters={} + local originals=tfmdata.characters + local indices={} + local parentfont={ "font",1 } + local private=tfmdata.privateoffset or constructors.privateoffset + local reported=encdone[tfmfile][encfile] + local backmap=vector and table.swapped(vector) + local done={} + for index,name in sortedhash(encoding) do + local unicode=unicoding[name] + local original=originals[index] + if original then + if unicode then + original.unicode=unicode + else + unicode=private + private=private+1 + if not reported then + report_tfm("glyph %a in font %a with encoding %a gets unicode %U",name,tfmfile,encfile,unicode) + end + end + characters[unicode]=original + indices[index]=unicode + original.name=name + if backmap then + original.index=backmap[name] + else + original.commands={ parentfont,charcommand[index] } + original.oindex=index + end + done[name]=true + elseif not done[name] then + report_tfm("bad index %a in font %a with name %a",index,tfmfile,name) + end + end + encdone[tfmfile][encfile]=true + for k,v in next,characters do + local kerns=v.kerns + if kerns then + local t={} + for k,v in next,kerns do + local i=indices[k] + if i then + t[i]=v + end + end + v.kerns=next(t) and t or nil + end + local ligatures=v.ligatures + if ligatures then + local t={} + for k,v in next,ligatures do + local i=indices[k] + if i then + t[i]=v + v.char=indices[v.char] + end + end + v.ligatures=next(t) and t or nil + end + end + tfmdata.fonts={ { id=virtualid } } + tfmdata.characters=characters + tfmdata.fullname=tfmdata.fullname or tfmdata.name + tfmdata.psname=file.nameonly(pfbfile or tfmdata.name) + tfmdata.filename=pfbfile + tfmdata.encodingbytes=2 + tfmdata.format="type1" + tfmdata.tounicode=1 + tfmdata.embedding="subset" + tfmdata.usedbitmap=bitmap and virtualid + tfmdata.private=private + return tfmdata + end +end +do + local template=[[ +/CIDInit /ProcSet findresource begin + 12 dict begin + begincmap + /CIDSystemInfo << /Registry (TeX) /Ordering (bitmap-%s) /Supplement 0 >> def + /CMapName /TeX-bitmap-%s def + /CMapType 2 def + 1 begincodespacerange + <00> + endcodespacerange + %s beginbfchar +%s + endbfchar + endcmap +CMapName currentdict /CMap defineresource pop end +end +end +]] + local flushstreamobject=lpdf and lpdf.flushstreamobject + local setfontattributes=lpdf and lpdf.setfontattributes + if not flushstreamobject then + flushstreamobject=function(data) + return pdf.obj { immediate=true,type="stream",string=data } + end + end + if not setfontattributes then + setfontattributes=function(id,data) + return pdf.setfontattributes(id,data) + end + end + function tfm.addtounicode(tfmdata) + local id=tfmdata.usedbitmap + local map={} + local char={} + for k,v in next,tfmdata.characters do + local index=v.oindex + local tounicode=v.tounicode + if index and tounicode then + map[index]=tounicode + end + end + for k,v in sortedhash(map) do + char[#char+1]=format("<%02X> <%s>",k,v) + end + char=concat(char,"\n") + local stream=format(template,id,id,#char,char) + local reference=flushstreamobject(stream,nil,true) + setfontattributes(id,format("/ToUnicode %i 0 R",reference)) + end +end +do + local everywhere={ ["*"]={ ["*"]=true } } + local noflags={ false,false,false,false } + local function enhance_normalize_features(data) + local ligatures=setmetatableindex("table") + local kerns=setmetatableindex("table") + local characters=data.characters + for u,c in next,characters do + local l=c.ligatures + local k=c.kerns + if l then + ligatures[u]=l + for u,v in next,l do + l[u]={ ligature=v.char } + end + c.ligatures=nil + end + if k then + kerns[u]=k + for u,v in next,k do + k[u]=v + end + c.kerns=nil + end + end + for u,l in next,ligatures do + for k,v in next,l do + local vl=v.ligature + local dl=ligatures[vl] + if dl then + for kk,vv in next,dl do + v[kk]=vv + end + end + end + end + local features={ + gpos={}, + gsub={}, + } + local sequences={ + } + if next(ligatures) then + features.gsub.liga=everywhere + data.properties.hasligatures=true + sequences[#sequences+1]={ + features={ + liga=everywhere, + }, + flags=noflags, + name="s_s_0", + nofsteps=1, + order={ "liga" }, + type="gsub_ligature", + steps={ + { + coverage=ligatures, + }, + }, + } + end + if next(kerns) then + features.gpos.kern=everywhere + data.properties.haskerns=true + sequences[#sequences+1]={ + features={ + kern=everywhere, + }, + flags=noflags, + name="p_s_0", + nofsteps=1, + order={ "kern" }, + type="gpos_pair", + steps={ + { + format="kern", + coverage=kerns, + }, + }, + } + end + data.resources.features=features + data.resources.sequences=sequences + data.shared.resources=data.shared.resources or resources + end + registertfmenhancer("normalize features",enhance_normalize_features) + registertfmenhancer("check extra features",otfenhancers.enhance) +end +registertfmfeature { + name="mode", + description="mode", + initializers={ + base=otf.modeinitializer, + node=otf.modeinitializer, + } +} +registertfmfeature { + name="features", + description="features", + default=true, + initializers={ + base=otf.basemodeinitializer, + node=otf.nodemodeinitializer, + }, + processors={ + node=otf.featuresprocessor, + } +} + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “fonts-tfm”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-lua” 1fbfdf7b689b2bdfd0e3bb9bf74ce136] --- + +if not modules then modules={} end modules ['font-lua']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) +local report_lua=logs.reporter("fonts","lua loading") +local fonts=fonts +local readers=fonts.readers +fonts.formats.lua="lua" +local function check_lua(specification,fullname) + local fullname=resolvers.findfile(fullname) or "" + if fullname~="" then + local loader=loadfile(fullname) + loader=loader and loader() + return loader and loader(specification) + end +end +readers.check_lua=check_lua +function readers.lua(specification) + local original=specification.specification + if trace_defining then + report_lua("using lua reader for %a",original) + end + local fullname=specification.filename or "" + if fullname=="" then + local forced=specification.forced or "" + if forced~="" then + fullname=specification.name.."."..forced + else + fullname=specification.name + end + end + return check_lua(specification,fullname) +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-lua”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-def” b9d908c2338b7dc443ce9d1e9fcb7139] --- + +if not modules then modules={} end modules ['font-def']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local lower,gsub=string.lower,string.gsub +local tostring,next=tostring,next +local lpegmatch=lpeg.match +local suffixonly,removesuffix,basename=file.suffix,file.removesuffix,file.basename +local formatters=string.formatters +local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys +local allocate=utilities.storage.allocate +local trace_defining=false trackers .register("fonts.defining",function(v) trace_defining=v end) +local directive_embedall=false directives.register("fonts.embedall",function(v) directive_embedall=v end) +trackers.register("fonts.loading","fonts.defining","otf.loading","afm.loading","tfm.loading") +local report_defining=logs.reporter("fonts","defining") +local fonts=fonts +local fontdata=fonts.hashes.identifiers +local readers=fonts.readers +local definers=fonts.definers +local specifiers=fonts.specifiers +local constructors=fonts.constructors +local fontgoodies=fonts.goodies +readers.sequence=allocate { 'otf','ttf','afm','tfm','lua' } +local variants=allocate() +specifiers.variants=variants +definers.methods=definers.methods or {} +local internalized=allocate() +local loadedfonts=constructors.loadedfonts +local designsizes=constructors.designsizes +local resolvefile=fontgoodies and fontgoodies.filenames and fontgoodies.filenames.resolve or function(s) return s end +local function makespecification(specification,lookup,name,sub,method,detail,size) + size=size or 655360 + if not lookup or lookup=="" then + lookup=definers.defaultlookup + end + if trace_defining then + report_defining("specification %a, lookup %a, name %a, sub %a, method %a, detail %a", + specification,lookup,name,sub,method,detail) + end + local t={ + lookup=lookup, + specification=specification, + size=size, + name=name, + sub=sub, + method=method, + detail=detail, + resolved="", + forced="", + features={}, + } + return t +end +definers.makespecification=makespecification +if context then + local splitter,splitspecifiers=nil,"" + local P,C,S,Cc,Cs=lpeg.P,lpeg.C,lpeg.S,lpeg.Cc,lpeg.Cs + local left=P("(") + local right=P(")") + local colon=P(":") + local space=P(" ") + local lbrace=P("{") + local rbrace=P("}") + definers.defaultlookup="file" + local prefixpattern=P(false) + local function addspecifier(symbol) + splitspecifiers=splitspecifiers..symbol + local method=S(splitspecifiers) + local lookup=C(prefixpattern)*colon + local sub=left*C(P(1-left-right-method)^1)*right + local specification=C(method)*C(P(1)^1) + local name=Cs((lbrace/"")*(1-rbrace)^1*(rbrace/"")+(1-sub-specification)^1) + splitter=P((lookup+Cc(""))*name*(sub+Cc(""))*(specification+Cc(""))) + end + local function addlookup(str) + prefixpattern=prefixpattern+P(str) + end + definers.addlookup=addlookup + addlookup("file") + addlookup("name") + addlookup("spec") + local function getspecification(str) + return lpegmatch(splitter,str or "") + end + definers.getspecification=getspecification + function definers.registersplit(symbol,action,verbosename) + addspecifier(symbol) + variants[symbol]=action + if verbosename then + variants[verbosename]=action + end + end + function definers.analyze(specification,size) + local lookup,name,sub,method,detail=getspecification(specification or "") + return makespecification(specification,lookup,name,sub,method,detail,size) + end +end +definers.resolvers=definers.resolvers or {} +local resolvers=definers.resolvers +function resolvers.file(specification) + local name=resolvefile(specification.name) + local suffix=lower(suffixonly(name)) + if fonts.formats[suffix] then + specification.forced=suffix + specification.forcedname=name + specification.name=removesuffix(name) + else + specification.name=name + end +end +function resolvers.name(specification) + local resolve=fonts.names.resolve + if resolve then + local resolved,sub,subindex,instance=resolve(specification.name,specification.sub,specification) + if resolved then + specification.resolved=resolved + specification.sub=sub + specification.subindex=subindex + if instance then + specification.instance=instance + local features=specification.features + if not features then + features={} + specification.features=features + end + local normal=features.normal + if not normal then + normal={} + features.normal=normal + end + normal.instance=instance + end + local suffix=lower(suffixonly(resolved)) + if fonts.formats[suffix] then + specification.forced=suffix + specification.forcedname=resolved + specification.name=removesuffix(resolved) + else + specification.name=resolved + end + end + else + resolvers.file(specification) + end +end +function resolvers.spec(specification) + local resolvespec=fonts.names.resolvespec + if resolvespec then + local resolved,sub,subindex=resolvespec(specification.name,specification.sub,specification) + if resolved then + specification.resolved=resolved + specification.sub=sub + specification.subindex=subindex + specification.forced=lower(suffixonly(resolved)) + specification.forcedname=resolved + specification.name=removesuffix(resolved) + end + else + resolvers.name(specification) + end +end +function definers.resolve(specification) + if not specification.resolved or specification.resolved=="" then + local r=resolvers[specification.lookup] + if r then + r(specification) + end + end + if specification.forced=="" then + specification.forced=nil + specification.forcedname=nil + end + specification.hash=lower(specification.name..' @ '..constructors.hashfeatures(specification)) + if specification.sub and specification.sub~="" then + specification.hash=specification.sub..' @ '..specification.hash + end + return specification +end +function definers.applypostprocessors(tfmdata) + local postprocessors=tfmdata.postprocessors + if postprocessors then + local properties=tfmdata.properties + for i=1,#postprocessors do + local extrahash=postprocessors[i](tfmdata) + if type(extrahash)=="string" and extrahash~="" then + extrahash=gsub(lower(extrahash),"[^a-z]","-") + properties.fullname=formatters["%s-%s"](properties.fullname,extrahash) + end + end + end + return tfmdata +end +local function checkembedding(tfmdata) + local properties=tfmdata.properties + local embedding + if directive_embedall then + embedding="full" + elseif properties and properties.filename and constructors.dontembed[properties.filename] then + embedding="no" + else + embedding="subset" + end + if properties then + properties.embedding=embedding + else + tfmdata.properties={ embedding=embedding } + end + tfmdata.embedding=embedding +end +local function checkfeatures(tfmdata) + local resources=tfmdata.resources + local shared=tfmdata.shared + if resources and shared then + local features=resources.features + local usedfeatures=shared.features + if features and usedfeatures then + local usedlanguage=usedfeatures.language or "dflt" + local usedscript=usedfeatures.script or "dflt" + local function check(what) + if what then + local foundlanguages={} + for feature,scripts in next,what do + if usedscript=="auto" or scripts["*"] then + elseif not scripts[usedscript] then + else + for script,languages in next,scripts do + if languages["*"] then + elseif context and not languages[usedlanguage] then + report_defining("font %!font:name!, feature %a, script %a, no language %a", + tfmdata,feature,script,usedlanguage) + end + end + end + for script,languages in next,scripts do + for language in next,languages do + foundlanguages[language]=true + end + end + end + if false then + foundlanguages["*"]=nil + foundlanguages=sortedkeys(foundlanguages) + for feature,scripts in sortedhash(what) do + for script,languages in next,scripts do + if not languages["*"] then + for i=1,#foundlanguages do + local language=foundlanguages[i] + if context and not languages[language] then + report_defining("font %!font:name!, feature %a, script %a, no language %a", + tfmdata,feature,script,language) + end + end + end + end + end + end + end + end + check(features.gsub) + check(features.gpos) + end + end +end +function definers.loadfont(specification) + local hash=constructors.hashinstance(specification) + local tfmdata=loadedfonts[hash] + if not tfmdata then + local forced=specification.forced or "" + if forced~="" then + local reader=readers[lower(forced)] + tfmdata=reader and reader(specification) + if not tfmdata then + report_defining("forced type %a of %a not found",forced,specification.name) + end + else + local sequence=readers.sequence + for s=1,#sequence do + local reader=sequence[s] + if readers[reader] then + if trace_defining then + report_defining("trying (reader sequence driven) type %a for %a with file %a",reader,specification.name,specification.filename) + end + tfmdata=readers[reader](specification) + if tfmdata then + break + else + specification.filename=nil + end + end + end + end + if tfmdata then + tfmdata=definers.applypostprocessors(tfmdata) + checkembedding(tfmdata) + loadedfonts[hash]=tfmdata + designsizes[specification.hash]=tfmdata.parameters.designsize + checkfeatures(tfmdata) + end + end + if not tfmdata then + report_defining("font with asked name %a is not found using lookup %a",specification.name,specification.lookup) + end + return tfmdata +end +function constructors.readanddefine(name,size) + local specification=definers.analyze(name,size) + local method=specification.method + if method and variants[method] then + specification=variants[method](specification) + end + specification=definers.resolve(specification) + local hash=constructors.hashinstance(specification) + local id=definers.registered(hash) + if not id then + local tfmdata=definers.loadfont(specification) + if tfmdata then + tfmdata.properties.hash=hash + id=font.define(tfmdata) + definers.register(tfmdata,id) + else + id=0 + end + end + return fontdata[id],id +end +function definers.registered(hash) + local id=internalized[hash] + return id,id and fontdata[id] +end +function definers.register(tfmdata,id) + if tfmdata and id then + local hash=tfmdata.properties.hash + if not hash then + report_defining("registering font, id %a, name %a, invalid hash",id,tfmdata.properties.filename or "?") + elseif not internalized[hash] then + internalized[hash]=id + if trace_defining then + report_defining("registering font, id %s, hash %a",id,hash) + end + fontdata[id]=tfmdata + end + end +end +function definers.read(specification,size,id) + statistics.starttiming(fonts) + if type(specification)=="string" then + specification=definers.analyze(specification,size) + end + local method=specification.method + if method and variants[method] then + specification=variants[method](specification) + end + specification=definers.resolve(specification) + local hash=constructors.hashinstance(specification) + local tfmdata=definers.registered(hash) + if tfmdata then + if trace_defining then + report_defining("already hashed: %s",hash) + end + else + tfmdata=definers.loadfont(specification) + if tfmdata then + tfmdata.original=specification.specification + if trace_defining then + report_defining("loaded and hashed: %s",hash) + end + tfmdata.properties.hash=hash + if id then + definers.register(tfmdata,id) + end + else + if trace_defining then + report_defining("not loaded and hashed: %s",hash) + end + end + end + if not tfmdata then + report_defining("unknown font %a, loading aborted",specification.name) + elseif trace_defining and type(tfmdata)=="table" then + local properties=tfmdata.properties or {} + local parameters=tfmdata.parameters or {} + report_defining("using %a font with id %a, name %a, size %a, bytes %a, encoding %a, fullname %a, filename %a", + properties.format or "unknown",id or "-",properties.name,parameters.size,properties.encodingbytes, + properties.encodingname,properties.fullname,basename(properties.filename)) + end + statistics.stoptiming(fonts) + return tfmdata +end +function font.getfont(id) + return fontdata[id] +end +if not context then + callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)") +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-def”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-shp” 5ff497c993112d4fef4c148348d964eb] --- + +if not modules then modules={} end modules ['font-shp']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local tonumber,next=tonumber,next +local concat=table.concat +local formatters,lower=string.formatters,string.lower +local otf=fonts.handlers.otf +local afm=fonts.handlers.afm +local pfb=fonts.handlers.pfb +local hashes=fonts.hashes +local identifiers=hashes.identifiers +local version=0.009 +local shapescache=containers.define("fonts","shapes",version,true) +local streamscache=containers.define("fonts","streams",version,true) +local compact_streams=false +directives.register("fonts.streams.compact",function(v) compact_streams=v end) +local function packoutlines(data,makesequence) + local subfonts=data.subfonts + if subfonts then + for i=1,#subfonts do + packoutlines(subfonts[i],makesequence) + end + return + end + local common=data.segments + if common then + return + end + local glyphs=data.glyphs + if not glyphs then + return + end + if makesequence then + for index=0,#glyphs do + local glyph=glyphs[index] + if glyph then + local segments=glyph.segments + if segments then + local sequence={} + local nofsequence=0 + for i=1,#segments do + local segment=segments[i] + local nofsegment=#segment + nofsequence=nofsequence+1 + sequence[nofsequence]=segment[nofsegment] + for i=1,nofsegment-1 do + nofsequence=nofsequence+1 + sequence[nofsequence]=segment[i] + end + end + glyph.sequence=sequence + glyph.segments=nil + end + end + end + else + local hash={} + local common={} + local reverse={} + local last=0 + for index=0,#glyphs do + local glyph=glyphs[index] + if glyph then + local segments=glyph.segments + if segments then + for i=1,#segments do + local h=concat(segments[i]," ") + hash[h]=(hash[h] or 0)+1 + end + end + end + end + for index=0,#glyphs do + local glyph=glyphs[index] + if glyph then + local segments=glyph.segments + if segments then + for i=1,#segments do + local segment=segments[i] + local h=concat(segment," ") + if hash[h]>1 then + local idx=reverse[h] + if not idx then + last=last+1 + reverse[h]=last + common[last]=segment + idx=last + end + segments[i]=idx + end + end + end + end + end + if last>0 then + data.segments=common + end + end +end +local function unpackoutlines(data) + local subfonts=data.subfonts + if subfonts then + for i=1,#subfonts do + unpackoutlines(subfonts[i]) + end + return + end + local common=data.segments + if not common then + return + end + local glyphs=data.glyphs + if not glyphs then + return + end + for index=0,#glyphs do + local glyph=glyphs[index] + if glyph then + local segments=glyph.segments + if segments then + for i=1,#segments do + local c=common[segments[i]] + if c then + segments[i]=c + end + end + end + end + end + data.segments=nil +end +local readers=otf.readers +local cleanname=otf.readers.helpers.cleanname +local function makehash(filename,sub,instance) + local name=cleanname(file.basename(filename)) + if instance then + return formatters["%s-%s-%s"](name,sub or 0,cleanname(instance)) + else + return formatters["%s-%s"] (name,sub or 0) + end +end +local function loadoutlines(cache,filename,sub,instance) + local base=file.basename(filename) + local name=file.removesuffix(base) + local kind=file.suffix(filename) + local attr=lfs.attributes(filename) + local size=attr and attr.size or 0 + local time=attr and attr.modification or 0 + local sub=tonumber(sub) + if size>0 and (kind=="otf" or kind=="ttf" or kind=="tcc") then + local hash=makehash(filename,sub,instance) + data=containers.read(cache,hash) + if not data or data.time~=time or data.size~=size then + data=otf.readers.loadshapes(filename,sub,instance) + if data then + data.size=size + data.format=data.format or (kind=="otf" and "opentype") or "truetype" + data.time=time + packoutlines(data) + containers.write(cache,hash,data) + data=containers.read(cache,hash) + end + end + unpackoutlines(data) + elseif size>0 and (kind=="pfb") then + local hash=containers.cleanname(base) + data=containers.read(cache,hash) + if not data or data.time~=time or data.size~=size then + data=afm.readers.loadshapes(filename) + if data then + data.size=size + data.format="type1" + data.time=time + packoutlines(data) + containers.write(cache,hash,data) + data=containers.read(cache,hash) + end + end + unpackoutlines(data) + else + data={ + filename=filename, + size=0, + time=time, + format="unknown", + units=1000, + glyphs={} + } + end + return data +end +local function cachethem(cache,hash,data) + containers.write(cache,hash,data,compact_streams) + return containers.read(cache,hash) +end +local function loadstreams(cache,filename,sub,instance) + local base=file.basename(filename) + local name=file.removesuffix(base) + local kind=lower(file.suffix(filename)) + local attr=lfs.attributes(filename) + local size=attr and attr.size or 0 + local time=attr and attr.modification or 0 + local sub=tonumber(sub) + if size>0 and (kind=="otf" or kind=="ttf" or kind=="ttc") then + local hash=makehash(filename,sub,instance) + data=containers.read(cache,hash) + if not data or data.time~=time or data.size~=size then + data=otf.readers.loadshapes(filename,sub,instance,true) + if data then + local glyphs=data.glyphs + local streams={} + if glyphs then + for i=0,#glyphs do + local glyph=glyphs[i] + if glyph then + streams[i]=glyph.stream or "" + else + streams[i]="" + end + end + end + data.streams=streams + data.glyphs=nil + data.size=size + data.format=data.format or (kind=="otf" and "opentype") or "truetype" + data.time=time + data=cachethem(cache,hash,data) + end + end + elseif size>0 and (kind=="pfb") then + local hash=makehash(filename,sub,instance) + data=containers.read(cache,hash) + if not data or data.time~=time or data.size~=size then + local names,encoding,streams,metadata=pfb.loadvector(filename,false,true) + if streams then + local fontbbox=metadata.fontbbox or { 0,0,0,0 } + for i=0,#streams do + streams[i]=streams[i].stream or "\14" + end + data={ + filename=filename, + size=size, + time=time, + format="type1", + streams=streams, + fontheader={ + fontversion=metadata.version, + units=1000, + xmin=fontbbox[1], + ymin=fontbbox[2], + xmax=fontbbox[3], + ymax=fontbbox[4], + }, + horizontalheader={ + ascender=0, + descender=0, + }, + maximumprofile={ + nofglyphs=#streams+1, + }, + names={ + copyright=metadata.copyright, + family=metadata.familyname, + fullname=metadata.fullname, + fontname=metadata.fontname, + subfamily=metadata.subfamilyname, + trademark=metadata.trademark, + notice=metadata.notice, + version=metadata.version, + }, + cffinfo={ + familyname=metadata.familyname, + fullname=metadata.fullname, + italicangle=metadata.italicangle, + monospaced=metadata.isfixedpitch and true or false, + underlineposition=metadata.underlineposition, + underlinethickness=metadata.underlinethickness, + weight=metadata.weight, + }, + } + data=cachethem(cache,hash,data) + end + end + else + data={ + filename=filename, + size=0, + time=time, + format="unknown", + streams={} + } + end + return data +end +local loadedshapes={} +local loadedstreams={} +local function loadoutlinedata(fontdata,streams) + local properties=fontdata.properties + local filename=properties.filename + local subindex=fontdata.subindex + local instance=properties.instance + local hash=makehash(filename,subindex,instance) + local loaded=loadedshapes[hash] + if not loaded then + loaded=loadoutlines(shapescache,filename,subindex,instance) + loadedshapes[hash]=loaded + end + return loaded +end +hashes.shapes=table.setmetatableindex(function(t,k) + local f=identifiers[k] + if f then + return loadoutlinedata(f) + end +end) +local function getstreamhash(fontid) + local fontdata=identifiers[fontid] + if fontdata then + local properties=fontdata.properties + return makehash(properties.filename,properties.subfont,properties.instance) + end +end +local function loadstreamdata(fontdata) + local properties=fontdata.properties + local shared=fontdata.shared + local rawdata=shared and shared.rawdata + local metadata=rawdata and rawdata.metadata + local filename=properties.filename + local subindex=metadata and metadata.subfontindex + local instance=properties.instance + local hash=makehash(filename,subindex,instance) + local loaded=loadedstreams[hash] + if not loaded then + loaded=loadstreams(streamscache,filename,subindex,instance) + loadedstreams[hash]=loaded + end + return loaded +end +hashes.streams=table.setmetatableindex(function(t,k) + local f=identifiers[k] + if f then + return loadstreamdata(f) + end +end) +otf.loadoutlinedata=loadoutlinedata +otf.loadstreamdata=loadstreamdata +otf.loadshapes=loadshapes +otf.getstreamhash=getstreamhash +local streams=fonts.hashes.streams +callback.register("glyph_stream_provider",function(id,index,mode) + if id>0 then + local streams=streams[id].streams + if streams then + return streams[index] or "" + end + end + return "" +end) + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-shp”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “fonts-def” f435e0875f203f343157baeff876ec9c] --- + +if not modules then modules={} end modules ['luatex-fonts-def']={ + version=1.001, + comment="companion to luatex-*.tex", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +if context then + os.exit() +end +local fonts=fonts +fonts.constructors.namemode="specification" +function fonts.definers.getspecification(str) + return "",str,"",":",str +end +local list={} +local function issome () list.lookup='name' end +local function isfile () list.lookup='file' end +local function isname () list.lookup='name' end +local function thename(s) list.name=s end +local function issub (v) list.sub=v end +local function iscrap (s) list.crap=string.lower(s) end +local function iskey (k,v) list[k]=v end +local function istrue (s) list[s]=true end +local function isfalse(s) list[s]=false end +local P,S,R,C,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs +local spaces=P(" ")^0 +local namespec=Cs((P("{")/"")*(1-S("}"))^0*(P("}")/"")+(1-S("/:("))^0) +local crapspec=spaces*P("/")*(((1-P(":"))^0)/iscrap)*spaces +local filename_1=P("file:")/isfile*(namespec/thename) +local filename_2=P("[")*P(true)/isfile*(((1-P("]"))^0)/thename)*P("]") +local fontname_1=P("name:")/isname*(namespec/thename) +local fontname_2=P(true)/issome*(namespec/thename) +local sometext=R("az","AZ","09")^1 +local somekey=R("az","AZ","09")^1 +local somevalue=(P("{")/"")*(1-P("}"))^0*(P("}")/"")+(1-S(";"))^1 +local truevalue=P("+")*spaces*(sometext/istrue) +local falsevalue=P("-")*spaces*(sometext/isfalse) +local keyvalue=(C(somekey)*spaces*P("=")*spaces*C(somevalue))/iskey +local somevalue=sometext/istrue +local subvalue=P("(")*(C(P(1-S("()"))^1)/issub)*P(")") +local option=spaces*(keyvalue+falsevalue+truevalue+somevalue)*spaces +local options=P(":")*spaces*(P(";")^0*option)^0 +local pattern=(filename_1+filename_2+fontname_1+fontname_2)*subvalue^0*crapspec^0*options^0 +function fonts.definers.analyze(str,size) + local specification=fonts.definers.makespecification(str,nil,nil,nil,":",nil,size) + list={} + lpeg.match(pattern,str) + list.crap=nil + if list.name then + specification.name=list.name + list.name=nil + end + if list.lookup then + specification.lookup=list.lookup + list.lookup=nil + end + if list.sub then + specification.sub=list.sub + list.sub=nil + end + specification.features.normal=fonts.handlers.otf.features.normalize(list) + list=nil + return specification +end +function fonts.definers.applypostprocessors(tfmdata) + local postprocessors=tfmdata.postprocessors + if postprocessors then + for i=1,#postprocessors do + local extrahash=postprocessors[i](tfmdata) + if type(extrahash)=="string" and extrahash~="" then + extrahash=string.gsub(lower(extrahash),"[^a-z]","-") + tfmdata.properties.fullname=format("%s-%s",tfmdata.properties.fullname,extrahash) + end + end + end + return tfmdata +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “fonts-def”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “fonts-ext” 32013cbc5d5d336be8b1d1e5879d86c4] --- + +if not modules then modules={} end modules ['luatex-fonts-ext']={ + version=1.001, + comment="companion to luatex-*.tex", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +if context then + os.exit() +end +local byte=string.byte +local fonts=fonts +local handlers=fonts.handlers +local otf=handlers.otf +local afm=handlers.afm +local registerotffeature=otf.features.register +local registerafmfeature=afm.features.register +function fonts.loggers.onetimemessage() end +fonts.protrusions=fonts.protrusions or {} +fonts.protrusions.setups=fonts.protrusions.setups or {} +local setups=fonts.protrusions.setups +setups['default']={ + factor=1, + left=1, + right=1, + [0x002C]={ 0,1 }, + [0x002E]={ 0,1 }, + [0x003A]={ 0,1 }, + [0x003B]={ 0,1 }, + [0x002D]={ 0,1 }, + [0x2013]={ 0,0.50 }, + [0x2014]={ 0,0.33 }, + [0x3001]={ 0,1 }, + [0x3002]={ 0,1 }, + [0x060C]={ 0,1 }, + [0x061B]={ 0,1 }, + [0x06D4]={ 0,1 }, +} +local function initializeprotrusion(tfmdata,value) + if value then + local setup=setups[value] + if setup then + local factor,left,right=setup.factor or 1,setup.left or 1,setup.right or 1 + local emwidth=tfmdata.parameters.quad + tfmdata.parameters.protrusion={ + auto=true, + } + for i,chr in next,tfmdata.characters do + local v,pl,pr=setup[i],nil,nil + if v then + pl,pr=v[1],v[2] + end + if pl and pl~=0 then chr.left_protruding=left*pl*factor end + if pr and pr~=0 then chr.right_protruding=right*pr*factor end + end + end + end +end +local specification={ + name="protrusion", + description="shift characters into the left and or right margin", + initializers={ + base=initializeprotrusion, + node=initializeprotrusion, + } +} +registerotffeature(specification) +registerafmfeature(specification) +fonts.expansions=fonts.expansions or {} +fonts.expansions.setups=fonts.expansions.setups or {} +local setups=fonts.expansions.setups +setups['default']={ + stretch=2, + shrink=2, + step=.5, + factor=1, + [byte('A')]=0.5,[byte('B')]=0.7,[byte('C')]=0.7,[byte('D')]=0.5,[byte('E')]=0.7, + [byte('F')]=0.7,[byte('G')]=0.5,[byte('H')]=0.7,[byte('K')]=0.7,[byte('M')]=0.7, + [byte('N')]=0.7,[byte('O')]=0.5,[byte('P')]=0.7,[byte('Q')]=0.5,[byte('R')]=0.7, + [byte('S')]=0.7,[byte('U')]=0.7,[byte('W')]=0.7,[byte('Z')]=0.7, + [byte('a')]=0.7,[byte('b')]=0.7,[byte('c')]=0.7,[byte('d')]=0.7,[byte('e')]=0.7, + [byte('g')]=0.7,[byte('h')]=0.7,[byte('k')]=0.7,[byte('m')]=0.7,[byte('n')]=0.7, + [byte('o')]=0.7,[byte('p')]=0.7,[byte('q')]=0.7,[byte('s')]=0.7,[byte('u')]=0.7, + [byte('w')]=0.7,[byte('z')]=0.7, + [byte('2')]=0.7,[byte('3')]=0.7,[byte('6')]=0.7,[byte('8')]=0.7,[byte('9')]=0.7, +} +local function initializeexpansion(tfmdata,value) + if value then + local setup=setups[value] + if setup then + local factor=setup.factor or 1 + tfmdata.parameters.expansion={ + stretch=10*(setup.stretch or 0), + shrink=10*(setup.shrink or 0), + step=10*(setup.step or 0), + auto=true, + } + for i,chr in next,tfmdata.characters do + local v=setup[i] + if v and v~=0 then + chr.expansion_factor=v*factor + else + chr.expansion_factor=factor + end + end + end + end +end +local specification={ + name="expansion", + description="apply hz optimization", + initializers={ + base=initializeexpansion, + node=initializeexpansion, + } +} +registerotffeature(specification) +registerafmfeature(specification) +if not otf.features.normalize then + otf.features.normalize=function(t) + if t.rand then + t.rand="random" + end + return t + end +end +function fonts.helpers.nametoslot(name) + local t=type(name) + if t=="string" then + local tfmdata=fonts.hashes.identifiers[currentfont()] + local shared=tfmdata and tfmdata.shared + local fntdata=shared and shared.rawdata + return fntdata and fntdata.resources.unicodes[name] + elseif t=="number" then + return n + end +end +fonts.encodings=fonts.encodings or {} +local reencodings={} +fonts.encodings.reencodings=reencodings +local function specialreencode(tfmdata,value) + local encoding=value and reencodings[value] + if encoding then + local temp={} + local char=tfmdata.characters + for k,v in next,encoding do + temp[k]=char[v] + end + for k,v in next,temp do + char[k]=temp[k] + end + return string.format("reencoded:%s",value) + end +end +local function initialize(tfmdata,value) + tfmdata.postprocessors=tfmdata.postprocessors or {} + table.insert(tfmdata.postprocessors, + function(tfmdata) + return specialreencode(tfmdata,value) + end + ) +end +registerotffeature { + name="reencode", + description="reencode characters", + manipulators={ + base=initialize, + node=initialize, + } +} +local function initialize(tfmdata,key,value) + if value then + tfmdata.mathparameters=nil + end +end +registerotffeature { + name="ignoremathconstants", + description="ignore math constants table", + initializers={ + base=initialize, + node=initialize, + } +} + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “fonts-ext”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-imp-tex” ceb087ef6fa2f89aed7179f60ddf8f35] --- + +if not modules then modules={} end modules ['font-imp-tex']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next=next +local fonts=fonts +local otf=fonts.handlers.otf +local registerotffeature=otf.features.register +local addotffeature=otf.addfeature +local specification={ + type="ligature", + order={ "tlig" }, + prepend=true, + data={ + [0x2013]={ 0x002D,0x002D }, + [0x2014]={ 0x002D,0x002D,0x002D }, + }, +} +addotffeature("tlig",specification) +registerotffeature { + name="tlig", + description="tex ligatures", +} +local specification={ + type="substitution", + order={ "trep" }, + prepend=true, + data={ + [0x0027]=0x2019, + }, +} +addotffeature("trep",specification) +registerotffeature { + name="trep", + description="tex replacements", +} +local anum_arabic={ + [0x0030]=0x0660, + [0x0031]=0x0661, + [0x0032]=0x0662, + [0x0033]=0x0663, + [0x0034]=0x0664, + [0x0035]=0x0665, + [0x0036]=0x0666, + [0x0037]=0x0667, + [0x0038]=0x0668, + [0x0039]=0x0669, +} +local anum_persian={ + [0x0030]=0x06F0, + [0x0031]=0x06F1, + [0x0032]=0x06F2, + [0x0033]=0x06F3, + [0x0034]=0x06F4, + [0x0035]=0x06F5, + [0x0036]=0x06F6, + [0x0037]=0x06F7, + [0x0038]=0x06F8, + [0x0039]=0x06F9, +} +local function valid(data) + local features=data.resources.features + if features then + for k,v in next,features do + for k,v in next,v do + if v.arab then + return true + end + end + end + end +end +local specification={ + { + type="substitution", + features={ arab={ urd=true,dflt=true } }, + order={ "anum" }, + data=anum_arabic, + valid=valid, + }, + { + type="substitution", + features={ arab={ urd=true } }, + order={ "anum" }, + data=anum_persian, + valid=valid, + }, +} +addotffeature("anum",specification) +registerotffeature { + name="anum", + description="arabic digits", +} + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-imp-tex”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-imp-ligatures” 26ffcf089391445f7af59536c8814364] --- + +if not modules then modules={} end modules ['font-imp-ligatures']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local lpegmatch=lpeg.match +local utfsplit=utf.split +local settings_to_array=utilities.parsers.settings_to_array +local fonts=fonts +local otf=fonts.handlers.otf +local registerotffeature=otf.features.register +local addotffeature=otf.addfeature +local lookups={} +local protect={} +local revert={} +local zwjchar=0x200C +local zwj={ zwjchar } +addotffeature { + name="blockligatures", + type="chainsubstitution", + nocheck=true, + prepend=true, + future=true, + lookups={ + { + type="multiple", + data=lookups, + }, + }, + data={ + rules=protect, + } +} +addotffeature { + name="blockligatures", + type="chainsubstitution", + nocheck=true, + append=true, + overload=false, + lookups={ + { + type="ligature", + data=lookups, + }, + }, + data={ + rules=revert, + } +} +registerotffeature { + name='blockligatures', + description='block certain ligatures', +} +local splitter=lpeg.splitat(":") +local function blockligatures(str) + local t=settings_to_array(str) + for i=1,#t do + local ti=t[i] + local before,current,after=lpegmatch(splitter,ti) + if current and after then + if before then + before=utfsplit(before) + for i=1,#before do + before[i]={ before[i] } + end + end + if current then + current=utfsplit(current) + end + if after then + after=utfsplit(after) + for i=1,#after do + after[i]={ after[i] } + end + end + else + before=nil + current=utfsplit(ti) + after=nil + end + if #current>1 then + local one=current[1] + local two=current[2] + lookups[one]={ one,zwjchar } + local one={ one } + local two={ two } + local new=#protect+1 + protect[new]={ + before=before, + current={ one,two }, + after=after, + lookups={ 1 }, + } + revert[new]={ + current={ one,zwj }, + after={ two }, + lookups={ 1 }, + } + end + end +end +otf.helpers.blockligatures=blockligatures +if context then + interfaces.implement { + name="blockligatures", + arguments="string", + actions=blockligatures, + } +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-imp-ligatures”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-imp-italics” defcb415bc1e0a0999b27773902adc18] --- + +if not modules then modules={} end modules ['font-imp-italics']={ + version=1.001, + comment="companion to font-ini.mkiv and hand-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next=next +local fonts=fonts +local handlers=fonts.handlers +local registerotffeature=handlers.otf.features.register +local registerafmfeature=handlers.afm.features.register +local function initialize(tfmdata,key,value) + for unicode,character in next,tfmdata.characters do + local olditalic=character.italic + if olditalic and olditalic~=0 then + character.width=character.width+olditalic + character.italic=0 + end + end +end +local specification={ + name="italicwidths", + description="add italic to width", + manipulators={ + base=initialize, + node=initialize, + } +} +registerotffeature(specification) +registerafmfeature(specification) +local function initialize(tfmdata,value) + if value then + local parameters=tfmdata.parameters + local italicangle=parameters.italicangle + if italicangle and italicangle~=0 then + local properties=tfmdata.properties + local factor=tonumber(value) or 1 + properties.hasitalics=true + properties.autoitalicamount=factor*(parameters.uwidth or 40)/2 + end + end +end +local specification={ + name="itlc", + description="italic correction", + initializers={ + base=initialize, + node=initialize, + } +} +registerotffeature(specification) +registerafmfeature(specification) +if context then + local function initialize(tfmdata,value) + tfmdata.properties.textitalics=toboolean(value) + end + local specification={ + name="textitalics", + description="use alternative text italic correction", + initializers={ + base=initialize, + node=initialize, + } + } + registerotffeature(specification) + registerafmfeature(specification) + local letter=characters.is_letter + local always=true + local function collapseitalics(tfmdata,key,value) + local threshold=value==true and 100 or tonumber(value) + if threshold and threshold>0 then + if threshold>100 then + threshold=100 + end + for unicode,data in next,tfmdata.characters do + if always or letter[unicode] or letter[data.unicode] then + local italic=data.italic + if italic and italic~=0 then + local width=data.width + if width and width~=0 then + local delta=threshold*italic/100 + data.width=width+delta + data.italic=italic-delta + end + end + end + end + end + end + local dimensions_specification={ + name="collapseitalics", + description="collapse italics", + manipulators={ + base=collapseitalics, + node=collapseitalics, + } + } + registerotffeature(dimensions_specification) + registerafmfeature(dimensions_specification) +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-imp-italics”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “font-imp-effects” a2dde5e071fcb3fc7b90f2bcd5aa4f22] --- + +if not modules then modules={} end modules ['font-imp-effects']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next,type,tonumber=next,type,tonumber +local is_boolean=string.is_boolean +local fonts=fonts +local handlers=fonts.handlers +local registerotffeature=handlers.otf.features.register +local registerafmfeature=handlers.afm.features.register +local settings_to_hash=utilities.parsers.settings_to_hash_colon_too +local helpers=fonts.helpers +local prependcommands=helpers.prependcommands +local charcommand=helpers.commands.char +local leftcommand=helpers.commands.left +local rightcommand=helpers.commands.right +local upcommand=helpers.commands.up +local downcommand=helpers.commands.down +local dummycommand=helpers.commands.dummy +local report_effect=logs.reporter("fonts","effect") +local report_slant=logs.reporter("fonts","slant") +local report_extend=logs.reporter("fonts","extend") +local report_squeeze=logs.reporter("fonts","squeeze") +local trace=false +trackers.register("fonts.effect",function(v) trace=v end) +trackers.register("fonts.slant",function(v) trace=v end) +trackers.register("fonts.extend",function(v) trace=v end) +trackers.register("fonts.squeeze",function(v) trace=v end) +local function initializeslant(tfmdata,value) + value=tonumber(value) + if not value then + value=0 + elseif value>1 then + value=1 + elseif value<-1 then + value=-1 + end + if trace then + report_slant("applying %0.3f",value) + end + tfmdata.parameters.slantfactor=value +end +local specification={ + name="slant", + description="slant glyphs", + initializers={ + base=initializeslant, + node=initializeslant, + } +} +registerotffeature(specification) +registerafmfeature(specification) +local function initializeextend(tfmdata,value) + value=tonumber(value) + if not value then + value=0 + elseif value>10 then + value=10 + elseif value<-10 then + value=-10 + end + if trace then + report_extend("applying %0.3f",value) + end + tfmdata.parameters.extendfactor=value +end +local specification={ + name="extend", + description="scale glyphs horizontally", + initializers={ + base=initializeextend, + node=initializeextend, + } +} +registerotffeature(specification) +registerafmfeature(specification) +local function initializesqueeze(tfmdata,value) + value=tonumber(value) + if not value then + value=0 + elseif value>10 then + value=10 + elseif value<-10 then + value=-10 + end + if trace then + report_squeeze("applying %0.3f",value) + end + tfmdata.parameters.squeezefactor=value +end +local specification={ + name="squeeze", + description="scale glyphs vertically", + initializers={ + base=initializesqueeze, + node=initializesqueeze, + } +} +registerotffeature(specification) +registerafmfeature(specification) +local effects={ + inner=0, + normal=0, + outer=1, + outline=1, + both=2, + hidden=3, +} +local function initializeeffect(tfmdata,value) + local spec + if type(value)=="number" then + spec={ width=value } + else + spec=settings_to_hash(value) + end + local effect=spec.effect or "both" + local width=tonumber(spec.width) or 0 + local mode=effects[effect] + if not mode then + report_effect("invalid effect %a",effect) + elseif width==0 and mode==0 then + report_effect("invalid width %a for effect %a",width,effect) + else + local parameters=tfmdata.parameters + local properties=tfmdata.properties + parameters.mode=mode + parameters.width=width*1000 + if is_boolean(spec.auto)==true then + local squeeze=1-width/20 + local average=(1-squeeze)*width*100 + spec.squeeze=squeeze + spec.extend=1+width/2 + spec.wdelta=average + spec.hdelta=average/2 + spec.ddelta=average/2 + spec.vshift=average/2 + end + local factor=tonumber(spec.factor) or 0 + local hfactor=tonumber(spec.hfactor) or factor + local vfactor=tonumber(spec.vfactor) or factor + local delta=tonumber(spec.delta) or 1 + local wdelta=tonumber(spec.wdelta) or delta + local hdelta=tonumber(spec.hdelta) or delta + local ddelta=tonumber(spec.ddelta) or hdelta + local vshift=tonumber(spec.vshift) or 0 + local slant=spec.slant + local extend=spec.extend + local squeeze=spec.squeeze + if slant then + initializeslant(tfmdata,slant) + end + if extend then + initializeextend(tfmdata,extend) + end + if squeeze then + initializesqueeze(tfmdata,squeeze) + end + properties.effect={ + effect=effect, + width=width, + factor=factor, + hfactor=hfactor, + vfactor=vfactor, + wdelta=wdelta, + hdelta=hdelta, + ddelta=ddelta, + vshift=vshift, + slant=tfmdata.parameters.slantfactor, + extend=tfmdata.parameters.extendfactor, + squeeze=tfmdata.parameters.squeezefactor, + } + end +end +local rules={ + "RadicalRuleThickness", + "OverbarRuleThickness", + "FractionRuleThickness", + "UnderbarRuleThickness", +} +local setmathparameters +local setmathcharacters +if CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 then + setmathparameters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) + if delta~=0 then + for i=1,#rules do + local name=rules[i] + local value=mathparameters[name] + if value then + mathparameters[name]=(squeeze or 1)*(value+dy) + end + end + end + end + setmathcharacters=function() + end +else + setmathparameters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) + if delta~=0 then + for i=1,#rules do + local name=rules[i] + local value=mathparameters[name] + if value then + mathparameters[name]=(squeeze or 1)*(value+dy) + end + end + end + end + setmathcharacters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) + local function wdpatch(char) + if wsnap~=0 then + char.width=char.width+wdelta/2 + end + end + local function htpatch(char) + if hsnap~=0 then + local height=char.height + if height then + char.height=char.height+2*dy + end + end + end + local character=characters[0x221A] + if character and character.next then + local char=character + local next=character.next + wdpatch(char) + htpatch(char) + while next do + char=characters[next] + wdpatch(char) + htpatch(char) + next=char.next + end + if char then + local v=char.vert_variants + if v then + local top=v[#v] + if top then + local char=characters[top.glyph] + htpatch(char) + end + end + end + end + end +end +local shiftmode=CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 +local function manipulateeffect(tfmdata) + local effect=tfmdata.properties.effect + if effect then + local characters=tfmdata.characters + local parameters=tfmdata.parameters + local mathparameters=tfmdata.mathparameters + local multiplier=effect.width*100 + local factor=parameters.factor + local hfactor=parameters.hfactor + local vfactor=parameters.vfactor + local wdelta=effect.wdelta*hfactor*multiplier + local hdelta=effect.hdelta*vfactor*multiplier + local ddelta=effect.ddelta*vfactor*multiplier + local vshift=effect.vshift*vfactor*multiplier + local squeeze=effect.squeeze + local hshift=wdelta/2 + local dx=multiplier*vfactor + local dy=vshift + local factor=(1+effect.factor)*factor + local hfactor=(1+effect.hfactor)*hfactor + local vfactor=(1+effect.vfactor)*vfactor + if shiftmode then + parameters.hshift=hshift + parameters.vshift=vshift + else + vshift=vshift~=0 and upcommand[vshift] or false + hshift=rightcommand[hshift] + end + for unicode,character in next,characters do + local oldwidth=character.width + local oldheight=character.height + local olddepth=character.depth + if oldwidth and oldwidth>0 then + character.width=oldwidth+wdelta + if not shiftmode then + local commands=character.commands + if vshift then + if commands then + prependcommands (commands, + hshift, + vshift + ) + else + character.commands={ + hshift, + vshift, + charcommand[unicode] + } + end + else + if commands then + prependcommands (commands, + hshift + ) + else + character.commands={ + hshift, + charcommand[unicode] + } + end + end + end + end + if oldheight and oldheight>0 then + character.height=oldheight+hdelta + end + if olddepth and olddepth>0 then + character.depth=olddepth+ddelta + end + end + if mathparameters then + setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) + setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) + end + parameters.factor=factor + parameters.hfactor=hfactor + parameters.vfactor=vfactor + if trace then + report_effect("applying") + report_effect(" effect : %s",effect.effect) + report_effect(" width : %s => %s",effect.width,multiplier) + report_effect(" factor : %s => %s",effect.factor,factor ) + report_effect(" hfactor : %s => %s",effect.hfactor,hfactor) + report_effect(" vfactor : %s => %s",effect.vfactor,vfactor) + report_effect(" wdelta : %s => %s",effect.wdelta,wdelta) + report_effect(" hdelta : %s => %s",effect.hdelta,hdelta) + report_effect(" ddelta : %s => %s",effect.ddelta,ddelta) + end + end +end +local specification={ + name="effect", + description="apply effects to glyphs", + initializers={ + base=initializeeffect, + node=initializeeffect, + }, + manipulators={ + base=manipulateeffect, + node=manipulateeffect, + }, +} +registerotffeature(specification) +registerafmfeature(specification) +local function initializeoutline(tfmdata,value) + value=tonumber(value) + if not value then + value=0 + else + value=tonumber(value) or 0 + end + local parameters=tfmdata.parameters + local properties=tfmdata.properties + parameters.mode=effects.outline + parameters.width=value*1000 + properties.effect={ + effect=effect, + width=width, + } +end +local specification={ + name="outline", + description="outline glyphs", + initializers={ + base=initializeoutline, + node=initializeoutline, + } +} +registerotffeature(specification) +registerafmfeature(specification) + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “font-imp-effects”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “fonts-lig” fbd251eea3810a43a8d5542319361d68] --- + + +fonts.handlers.otf.addfeature { + ["dataset"]={ + { + ["data"]={ + ["À"]={ "A","̀" }, + ["Á"]={ "A","́" }, + ["Â"]={ "A","̂" }, + ["Ã"]={ "A","̃" }, + ["Ä"]={ "A","̈" }, + ["Å"]={ "A","̊" }, + ["Ç"]={ "C","̧" }, + ["È"]={ "E","̀" }, + ["É"]={ "E","́" }, + ["Ê"]={ "E","̂" }, + ["Ë"]={ "E","̈" }, + ["Ì"]={ "I","̀" }, + ["Í"]={ "I","́" }, + ["Î"]={ "I","̂" }, + ["Ï"]={ "I","̈" }, + ["Ñ"]={ "N","̃" }, + ["Ò"]={ "O","̀" }, + ["Ó"]={ "O","́" }, + ["Ô"]={ "O","̂" }, + ["Õ"]={ "O","̃" }, + ["Ö"]={ "O","̈" }, + ["Ù"]={ "U","̀" }, + ["Ú"]={ "U","́" }, + ["Û"]={ "U","̂" }, + ["Ü"]={ "U","̈" }, + ["Ý"]={ "Y","́" }, + ["à"]={ "a","̀" }, + ["á"]={ "a","́" }, + ["â"]={ "a","̂" }, + ["ã"]={ "a","̃" }, + ["ä"]={ "a","̈" }, + ["å"]={ "a","̊" }, + ["ç"]={ "c","̧" }, + ["è"]={ "e","̀" }, + ["é"]={ "e","́" }, + ["ê"]={ "e","̂" }, + ["ë"]={ "e","̈" }, + ["ì"]={ "i","̀" }, + ["í"]={ "i","́" }, + ["î"]={ "i","̂" }, + ["ï"]={ "i","̈" }, + ["ñ"]={ "n","̃" }, + ["ò"]={ "o","̀" }, + ["ó"]={ "o","́" }, + ["ô"]={ "o","̂" }, + ["õ"]={ "o","̃" }, + ["ö"]={ "o","̈" }, + ["ù"]={ "u","̀" }, + ["ú"]={ "u","́" }, + ["û"]={ "u","̂" }, + ["ü"]={ "u","̈" }, + ["ý"]={ "y","́" }, + ["ÿ"]={ "y","̈" }, + ["Ā"]={ "A","̄" }, + ["ā"]={ "a","̄" }, + ["Ă"]={ "A","̆" }, + ["ă"]={ "a","̆" }, + ["Ą"]={ "A","̨" }, + ["ą"]={ "a","̨" }, + ["Ć"]={ "C","́" }, + ["ć"]={ "c","́" }, + ["Ĉ"]={ "C","̂" }, + ["ĉ"]={ "c","̂" }, + ["Ċ"]={ "C","̇" }, + ["ċ"]={ "c","̇" }, + ["Č"]={ "C","̌" }, + ["č"]={ "c","̌" }, + ["Ď"]={ "D","̌" }, + ["ď"]={ "d","̌" }, + ["Ē"]={ "E","̄" }, + ["ē"]={ "e","̄" }, + ["Ĕ"]={ "E","̆" }, + ["ĕ"]={ "e","̆" }, + ["Ė"]={ "E","̇" }, + ["ė"]={ "e","̇" }, + ["Ę"]={ "E","̨" }, + ["ę"]={ "e","̨" }, + ["Ě"]={ "E","̌" }, + ["ě"]={ "e","̌" }, + ["Ĝ"]={ "G","̂" }, + ["ĝ"]={ "g","̂" }, + ["Ğ"]={ "G","̆" }, + ["ğ"]={ "g","̆" }, + ["Ġ"]={ "G","̇" }, + ["ġ"]={ "g","̇" }, + ["Ģ"]={ "G","̧" }, + ["ģ"]={ "g","̧" }, + ["Ĥ"]={ "H","̂" }, + ["ĥ"]={ "h","̂" }, + ["Ĩ"]={ "I","̃" }, + ["ĩ"]={ "i","̃" }, + ["Ī"]={ "I","̄" }, + ["ī"]={ "i","̄" }, + ["Ĭ"]={ "I","̆" }, + ["ĭ"]={ "i","̆" }, + ["Į"]={ "I","̨" }, + ["į"]={ "i","̨" }, + ["İ"]={ "I","̇" }, + ["Ĵ"]={ "J","̂" }, + ["ĵ"]={ "j","̂" }, + ["Ķ"]={ "K","̧" }, + ["ķ"]={ "k","̧" }, + ["Ĺ"]={ "L","́" }, + ["ĺ"]={ "l","́" }, + ["Ļ"]={ "L","̧" }, + ["ļ"]={ "l","̧" }, + ["Ľ"]={ "L","̌" }, + ["ľ"]={ "l","̌" }, + ["Ń"]={ "N","́" }, + ["ń"]={ "n","́" }, + ["Ņ"]={ "N","̧" }, + ["ņ"]={ "n","̧" }, + ["Ň"]={ "N","̌" }, + ["ň"]={ "n","̌" }, + ["Ō"]={ "O","̄" }, + ["ō"]={ "o","̄" }, + ["Ŏ"]={ "O","̆" }, + ["ŏ"]={ "o","̆" }, + ["Ő"]={ "O","̋" }, + ["ő"]={ "o","̋" }, + ["Ŕ"]={ "R","́" }, + ["ŕ"]={ "r","́" }, + ["Ŗ"]={ "R","̧" }, + ["ŗ"]={ "r","̧" }, + ["Ř"]={ "R","̌" }, + ["ř"]={ "r","̌" }, + ["Ś"]={ "S","́" }, + ["ś"]={ "s","́" }, + ["Ŝ"]={ "S","̂" }, + ["ŝ"]={ "s","̂" }, + ["Ş"]={ "S","̧" }, + ["ş"]={ "s","̧" }, + ["Š"]={ "S","̌" }, + ["š"]={ "s","̌" }, + ["Ţ"]={ "T","̧" }, + ["ţ"]={ "t","̧" }, + ["Ť"]={ "T","̌" }, + ["ť"]={ "t","̌" }, + ["Ũ"]={ "U","̃" }, + ["ũ"]={ "u","̃" }, + ["Ū"]={ "U","̄" }, + ["ū"]={ "u","̄" }, + ["Ŭ"]={ "U","̆" }, + ["ŭ"]={ "u","̆" }, + ["Ů"]={ "U","̊" }, + ["ů"]={ "u","̊" }, + ["Ű"]={ "U","̋" }, + ["ű"]={ "u","̋" }, + ["Ų"]={ "U","̨" }, + ["ų"]={ "u","̨" }, + ["Ŵ"]={ "W","̂" }, + ["ŵ"]={ "w","̂" }, + ["Ŷ"]={ "Y","̂" }, + ["ŷ"]={ "y","̂" }, + ["Ÿ"]={ "Y","̈" }, + ["Ź"]={ "Z","́" }, + ["ź"]={ "z","́" }, + ["Ż"]={ "Z","̇" }, + ["ż"]={ "z","̇" }, + ["Ž"]={ "Z","̌" }, + ["ž"]={ "z","̌" }, + ["Ơ"]={ "O","̛" }, + ["ơ"]={ "o","̛" }, + ["Ư"]={ "U","̛" }, + ["ư"]={ "u","̛" }, + ["Ǎ"]={ "A","̌" }, + ["ǎ"]={ "a","̌" }, + ["Ǐ"]={ "I","̌" }, + ["ǐ"]={ "i","̌" }, + ["Ǒ"]={ "O","̌" }, + ["ǒ"]={ "o","̌" }, + ["Ǔ"]={ "U","̌" }, + ["ǔ"]={ "u","̌" }, + ["Ǖ"]={ "Ü","̄" }, + ["ǖ"]={ "ü","̄" }, + ["Ǘ"]={ "Ü","́" }, + ["ǘ"]={ "ü","́" }, + ["Ǚ"]={ "Ü","̌" }, + ["ǚ"]={ "ü","̌" }, + ["Ǜ"]={ "Ü","̀" }, + ["ǜ"]={ "ü","̀" }, + ["Ǟ"]={ "Ä","̄" }, + ["ǟ"]={ "ä","̄" }, + ["Ǡ"]={ "Ȧ","̄" }, + ["ǡ"]={ "ȧ","̄" }, + ["Ǣ"]={ "Æ","̄" }, + ["ǣ"]={ "æ","̄" }, + ["Ǧ"]={ "G","̌" }, + ["ǧ"]={ "g","̌" }, + ["Ǩ"]={ "K","̌" }, + ["ǩ"]={ "k","̌" }, + ["Ǫ"]={ "O","̨" }, + ["ǫ"]={ "o","̨" }, + ["Ǭ"]={ "Ǫ","̄" }, + ["ǭ"]={ "ǫ","̄" }, + ["Ǯ"]={ "Ʒ","̌" }, + ["ǯ"]={ "ʒ","̌" }, + ["ǰ"]={ "j","̌" }, + ["Ǵ"]={ "G","́" }, + ["ǵ"]={ "g","́" }, + ["Ǹ"]={ "N","̀" }, + ["ǹ"]={ "n","̀" }, + ["Ǻ"]={ "Å","́" }, + ["ǻ"]={ "å","́" }, + ["Ǽ"]={ "Æ","́" }, + ["ǽ"]={ "æ","́" }, + ["Ǿ"]={ "Ø","́" }, + ["ǿ"]={ "ø","́" }, + ["Ȁ"]={ "A","̏" }, + ["ȁ"]={ "a","̏" }, + ["Ȃ"]={ "A","̑" }, + ["ȃ"]={ "a","̑" }, + ["Ȅ"]={ "E","̏" }, + ["ȅ"]={ "e","̏" }, + ["Ȇ"]={ "E","̑" }, + ["ȇ"]={ "e","̑" }, + ["Ȉ"]={ "I","̏" }, + ["ȉ"]={ "i","̏" }, + ["Ȋ"]={ "I","̑" }, + ["ȋ"]={ "i","̑" }, + ["Ȍ"]={ "O","̏" }, + ["ȍ"]={ "o","̏" }, + ["Ȏ"]={ "O","̑" }, + ["ȏ"]={ "o","̑" }, + ["Ȑ"]={ "R","̏" }, + ["ȑ"]={ "r","̏" }, + ["Ȓ"]={ "R","̑" }, + ["ȓ"]={ "r","̑" }, + ["Ȕ"]={ "U","̏" }, + ["ȕ"]={ "u","̏" }, + ["Ȗ"]={ "U","̑" }, + ["ȗ"]={ "u","̑" }, + ["Ș"]={ "S","̦" }, + ["ș"]={ "s","̦" }, + ["Ț"]={ "T","̦" }, + ["ț"]={ "t","̦" }, + ["Ȟ"]={ "H","̌" }, + ["ȟ"]={ "h","̌" }, + ["Ȧ"]={ "A","̇" }, + ["ȧ"]={ "a","̇" }, + ["Ȩ"]={ "E","̧" }, + ["ȩ"]={ "e","̧" }, + ["Ȫ"]={ "Ö","̄" }, + ["ȫ"]={ "ö","̄" }, + ["Ȭ"]={ "Õ","̄" }, + ["ȭ"]={ "õ","̄" }, + ["Ȯ"]={ "O","̇" }, + ["ȯ"]={ "o","̇" }, + ["Ȱ"]={ "Ȯ","̄" }, + ["ȱ"]={ "ȯ","̄" }, + ["Ȳ"]={ "Y","̄" }, + ["ȳ"]={ "y","̄" }, + ["̈́"]={ "̈","́" }, + ["΅"]={ "¨","́" }, + ["Ά"]={ "Α","́" }, + ["Έ"]={ "Ε","́" }, + ["Ή"]={ "Η","́" }, + ["Ί"]={ "Ι","́" }, + ["Ό"]={ "Ο","́" }, + ["Ύ"]={ "Υ","́" }, + ["Ώ"]={ "Ω","́" }, + ["ΐ"]={ "ϊ","́" }, + ["Ϊ"]={ "Ι","̈" }, + ["Ϋ"]={ "Υ","̈" }, + ["ά"]={ "α","́" }, + ["έ"]={ "ε","́" }, + ["ή"]={ "η","́" }, + ["ί"]={ "ι","́" }, + ["ΰ"]={ "ϋ","́" }, + ["ϊ"]={ "ι","̈" }, + ["ϋ"]={ "υ","̈" }, + ["ό"]={ "ο","́" }, + ["ύ"]={ "υ","́" }, + ["ώ"]={ "ω","́" }, + ["ϓ"]={ "ϒ","́" }, + ["ϔ"]={ "ϒ","̈" }, + ["Ѐ"]={ "Е","̀" }, + ["Ё"]={ "Е","̈" }, + ["Ѓ"]={ "Г","́" }, + ["Ї"]={ "І","̈" }, + ["Ќ"]={ "К","́" }, + ["Ѝ"]={ "И","̀" }, + ["Ў"]={ "У","̆" }, + ["Й"]={ "И","̆" }, + ["й"]={ "и","̆" }, + ["ѐ"]={ "е","̀" }, + ["ё"]={ "е","̈" }, + ["ѓ"]={ "г","́" }, + ["ї"]={ "і","̈" }, + ["ќ"]={ "к","́" }, + ["ѝ"]={ "и","̀" }, + ["ў"]={ "у","̆" }, + ["Ѷ"]={ "Ѵ","̏" }, + ["ѷ"]={ "ѵ","̏" }, + ["Ӂ"]={ "Ж","̆" }, + ["ӂ"]={ "ж","̆" }, + ["Ӑ"]={ "А","̆" }, + ["ӑ"]={ "а","̆" }, + ["Ӓ"]={ "А","̈" }, + ["ӓ"]={ "а","̈" }, + ["Ӗ"]={ "Е","̆" }, + ["ӗ"]={ "е","̆" }, + ["Ӛ"]={ "Ә","̈" }, + ["ӛ"]={ "ә","̈" }, + ["Ӝ"]={ "Ж","̈" }, + ["ӝ"]={ "ж","̈" }, + ["Ӟ"]={ "З","̈" }, + ["ӟ"]={ "з","̈" }, + ["Ӣ"]={ "И","̄" }, + ["ӣ"]={ "и","̄" }, + ["Ӥ"]={ "И","̈" }, + ["ӥ"]={ "и","̈" }, + ["Ӧ"]={ "О","̈" }, + ["ӧ"]={ "о","̈" }, + ["Ӫ"]={ "Ө","̈" }, + ["ӫ"]={ "ө","̈" }, + ["Ӭ"]={ "Э","̈" }, + ["ӭ"]={ "э","̈" }, + ["Ӯ"]={ "У","̄" }, + ["ӯ"]={ "у","̄" }, + ["Ӱ"]={ "У","̈" }, + ["ӱ"]={ "у","̈" }, + ["Ӳ"]={ "У","̋" }, + ["ӳ"]={ "у","̋" }, + ["Ӵ"]={ "Ч","̈" }, + ["ӵ"]={ "ч","̈" }, + ["Ӹ"]={ "Ы","̈" }, + ["ӹ"]={ "ы","̈" }, + ["آ"]={ "ا","ٓ" }, + ["أ"]={ "ا","ٔ" }, + ["ؤ"]={ "و","ٔ" }, + ["إ"]={ "ا","ٕ" }, + ["ئ"]={ "ي","ٔ" }, + ["ۀ"]={ "ە","ٔ" }, + ["ۂ"]={ "ہ","ٔ" }, + ["ۓ"]={ "ے","ٔ" }, + ["ऩ"]={ "न","़" }, + ["ऱ"]={ "र","़" }, + ["ऴ"]={ "ळ","़" }, + ["क़"]={ "क","़" }, + ["ख़"]={ "ख","़" }, + ["ग़"]={ "ग","़" }, + ["ज़"]={ "ज","़" }, + ["ड़"]={ "ड","़" }, + ["ढ़"]={ "ढ","़" }, + ["फ़"]={ "फ","़" }, + ["य़"]={ "य","़" }, + ["ো"]={ "ে","া" }, + ["ৌ"]={ "ে","ৗ" }, + ["ড়"]={ "ড","়" }, + ["ঢ়"]={ "ঢ","়" }, + ["য়"]={ "য","়" }, + ["ਲ਼"]={ "ਲ","਼" }, + ["ਸ਼"]={ "ਸ","਼" }, + ["ਖ਼"]={ "ਖ","਼" }, + ["ਗ਼"]={ "ਗ","਼" }, + ["ਜ਼"]={ "ਜ","਼" }, + ["ਫ਼"]={ "ਫ","਼" }, + ["ୈ"]={ "େ","ୖ" }, + ["ୋ"]={ "େ","ା" }, + ["ୌ"]={ "େ","ୗ" }, + ["ଡ଼"]={ "ଡ","଼" }, + ["ଢ଼"]={ "ଢ","଼" }, + ["ஔ"]={ "ஒ","ௗ" }, + ["ொ"]={ "ெ","ா" }, + ["ோ"]={ "ே","ா" }, + ["ௌ"]={ "ெ","ௗ" }, + ["ై"]={ "ె","ౖ" }, + ["ೀ"]={ "ಿ","ೕ" }, + ["ೇ"]={ "ೆ","ೕ" }, + ["ೈ"]={ "ೆ","ೖ" }, + ["ೊ"]={ "ೆ","ೂ" }, + ["ೋ"]={ "ೊ","ೕ" }, + ["ൊ"]={ "െ","ാ" }, + ["ോ"]={ "േ","ാ" }, + ["ൌ"]={ "െ","ൗ" }, + ["ේ"]={ "ෙ","්" }, + ["ො"]={ "ෙ","ා" }, + ["ෝ"]={ "ො","්" }, + ["ෞ"]={ "ෙ","ෟ" }, + ["གྷ"]={ "ག","ྷ" }, + ["ཌྷ"]={ "ཌ","ྷ" }, + ["དྷ"]={ "ད","ྷ" }, + ["བྷ"]={ "བ","ྷ" }, + ["ཛྷ"]={ "ཛ","ྷ" }, + ["ཀྵ"]={ "ཀ","ྵ" }, + ["ཱི"]={ "ཱ","ི" }, + ["ཱུ"]={ "ཱ","ུ" }, + ["ྲྀ"]={ "ྲ","ྀ" }, + ["ླྀ"]={ "ླ","ྀ" }, + ["ཱྀ"]={ "ཱ","ྀ" }, + ["ྒྷ"]={ "ྒ","ྷ" }, + ["ྜྷ"]={ "ྜ","ྷ" }, + ["ྡྷ"]={ "ྡ","ྷ" }, + ["ྦྷ"]={ "ྦ","ྷ" }, + ["ྫྷ"]={ "ྫ","ྷ" }, + ["ྐྵ"]={ "ྐ","ྵ" }, + ["ဦ"]={ "ဥ","ီ" }, + ["ᬆ"]={ "ᬅ","ᬵ" }, + ["ᬈ"]={ "ᬇ","ᬵ" }, + ["ᬊ"]={ "ᬉ","ᬵ" }, + ["ᬌ"]={ "ᬋ","ᬵ" }, + ["ᬎ"]={ "ᬍ","ᬵ" }, + ["ᬒ"]={ "ᬑ","ᬵ" }, + ["ᬻ"]={ "ᬺ","ᬵ" }, + ["ᬽ"]={ "ᬼ","ᬵ" }, + ["ᭀ"]={ "ᬾ","ᬵ" }, + ["ᭁ"]={ "ᬿ","ᬵ" }, + ["ᭃ"]={ "ᭂ","ᬵ" }, + ["Ḁ"]={ "A","̥" }, + ["ḁ"]={ "a","̥" }, + ["Ḃ"]={ "B","̇" }, + ["ḃ"]={ "b","̇" }, + ["Ḅ"]={ "B","̣" }, + ["ḅ"]={ "b","̣" }, + ["Ḇ"]={ "B","̱" }, + ["ḇ"]={ "b","̱" }, + ["Ḉ"]={ "Ç","́" }, + ["ḉ"]={ "ç","́" }, + ["Ḋ"]={ "D","̇" }, + ["ḋ"]={ "d","̇" }, + ["Ḍ"]={ "D","̣" }, + ["ḍ"]={ "d","̣" }, + ["Ḏ"]={ "D","̱" }, + ["ḏ"]={ "d","̱" }, + ["Ḑ"]={ "D","̧" }, + ["ḑ"]={ "d","̧" }, + ["Ḓ"]={ "D","̭" }, + ["ḓ"]={ "d","̭" }, + ["Ḕ"]={ "Ē","̀" }, + ["ḕ"]={ "ē","̀" }, + ["Ḗ"]={ "Ē","́" }, + ["ḗ"]={ "ē","́" }, + ["Ḙ"]={ "E","̭" }, + ["ḙ"]={ "e","̭" }, + ["Ḛ"]={ "E","̰" }, + ["ḛ"]={ "e","̰" }, + ["Ḝ"]={ "Ȩ","̆" }, + ["ḝ"]={ "ȩ","̆" }, + ["Ḟ"]={ "F","̇" }, + ["ḟ"]={ "f","̇" }, + ["Ḡ"]={ "G","̄" }, + ["ḡ"]={ "g","̄" }, + ["Ḣ"]={ "H","̇" }, + ["ḣ"]={ "h","̇" }, + ["Ḥ"]={ "H","̣" }, + ["ḥ"]={ "h","̣" }, + ["Ḧ"]={ "H","̈" }, + ["ḧ"]={ "h","̈" }, + ["Ḩ"]={ "H","̧" }, + ["ḩ"]={ "h","̧" }, + ["Ḫ"]={ "H","̮" }, + ["ḫ"]={ "h","̮" }, + ["Ḭ"]={ "I","̰" }, + ["ḭ"]={ "i","̰" }, + ["Ḯ"]={ "Ï","́" }, + ["ḯ"]={ "ï","́" }, + ["Ḱ"]={ "K","́" }, + ["ḱ"]={ "k","́" }, + ["Ḳ"]={ "K","̣" }, + ["ḳ"]={ "k","̣" }, + ["Ḵ"]={ "K","̱" }, + ["ḵ"]={ "k","̱" }, + ["Ḷ"]={ "L","̣" }, + ["ḷ"]={ "l","̣" }, + ["Ḹ"]={ "Ḷ","̄" }, + ["ḹ"]={ "ḷ","̄" }, + ["Ḻ"]={ "L","̱" }, + ["ḻ"]={ "l","̱" }, + ["Ḽ"]={ "L","̭" }, + ["ḽ"]={ "l","̭" }, + ["Ḿ"]={ "M","́" }, + ["ḿ"]={ "m","́" }, + ["Ṁ"]={ "M","̇" }, + ["ṁ"]={ "m","̇" }, + ["Ṃ"]={ "M","̣" }, + ["ṃ"]={ "m","̣" }, + ["Ṅ"]={ "N","̇" }, + ["ṅ"]={ "n","̇" }, + ["Ṇ"]={ "N","̣" }, + ["ṇ"]={ "n","̣" }, + ["Ṉ"]={ "N","̱" }, + ["ṉ"]={ "n","̱" }, + ["Ṋ"]={ "N","̭" }, + ["ṋ"]={ "n","̭" }, + ["Ṍ"]={ "Õ","́" }, + ["ṍ"]={ "õ","́" }, + ["Ṏ"]={ "Õ","̈" }, + ["ṏ"]={ "õ","̈" }, + ["Ṑ"]={ "Ō","̀" }, + ["ṑ"]={ "ō","̀" }, + ["Ṓ"]={ "Ō","́" }, + ["ṓ"]={ "ō","́" }, + ["Ṕ"]={ "P","́" }, + ["ṕ"]={ "p","́" }, + ["Ṗ"]={ "P","̇" }, + ["ṗ"]={ "p","̇" }, + ["Ṙ"]={ "R","̇" }, + ["ṙ"]={ "r","̇" }, + ["Ṛ"]={ "R","̣" }, + ["ṛ"]={ "r","̣" }, + ["Ṝ"]={ "Ṛ","̄" }, + ["ṝ"]={ "ṛ","̄" }, + ["Ṟ"]={ "R","̱" }, + ["ṟ"]={ "r","̱" }, + ["Ṡ"]={ "S","̇" }, + ["ṡ"]={ "s","̇" }, + ["Ṣ"]={ "S","̣" }, + ["ṣ"]={ "s","̣" }, + ["Ṥ"]={ "Ś","̇" }, + ["ṥ"]={ "ś","̇" }, + ["Ṧ"]={ "Š","̇" }, + ["ṧ"]={ "š","̇" }, + ["Ṩ"]={ "Ṣ","̇" }, + ["ṩ"]={ "ṣ","̇" }, + ["Ṫ"]={ "T","̇" }, + ["ṫ"]={ "t","̇" }, + ["Ṭ"]={ "T","̣" }, + ["ṭ"]={ "t","̣" }, + ["Ṯ"]={ "T","̱" }, + ["ṯ"]={ "t","̱" }, + ["Ṱ"]={ "T","̭" }, + ["ṱ"]={ "t","̭" }, + ["Ṳ"]={ "U","̤" }, + ["ṳ"]={ "u","̤" }, + ["Ṵ"]={ "U","̰" }, + ["ṵ"]={ "u","̰" }, + ["Ṷ"]={ "U","̭" }, + ["ṷ"]={ "u","̭" }, + ["Ṹ"]={ "Ũ","́" }, + ["ṹ"]={ "ũ","́" }, + ["Ṻ"]={ "Ū","̈" }, + ["ṻ"]={ "ū","̈" }, + ["Ṽ"]={ "V","̃" }, + ["ṽ"]={ "v","̃" }, + ["Ṿ"]={ "V","̣" }, + ["ṿ"]={ "v","̣" }, + ["Ẁ"]={ "W","̀" }, + ["ẁ"]={ "w","̀" }, + ["Ẃ"]={ "W","́" }, + ["ẃ"]={ "w","́" }, + ["Ẅ"]={ "W","̈" }, + ["ẅ"]={ "w","̈" }, + ["Ẇ"]={ "W","̇" }, + ["ẇ"]={ "w","̇" }, + ["Ẉ"]={ "W","̣" }, + ["ẉ"]={ "w","̣" }, + ["Ẋ"]={ "X","̇" }, + ["ẋ"]={ "x","̇" }, + ["Ẍ"]={ "X","̈" }, + ["ẍ"]={ "x","̈" }, + ["Ẏ"]={ "Y","̇" }, + ["ẏ"]={ "y","̇" }, + ["Ẑ"]={ "Z","̂" }, + ["ẑ"]={ "z","̂" }, + ["Ẓ"]={ "Z","̣" }, + ["ẓ"]={ "z","̣" }, + ["Ẕ"]={ "Z","̱" }, + ["ẕ"]={ "z","̱" }, + ["ẖ"]={ "h","̱" }, + ["ẗ"]={ "t","̈" }, + ["ẘ"]={ "w","̊" }, + ["ẙ"]={ "y","̊" }, + ["ẛ"]={ "ſ","̇" }, + ["Ạ"]={ "A","̣" }, + ["ạ"]={ "a","̣" }, + ["Ả"]={ "A","̉" }, + ["ả"]={ "a","̉" }, + ["Ấ"]={ "Â","́" }, + ["ấ"]={ "â","́" }, + ["Ầ"]={ "Â","̀" }, + ["ầ"]={ "â","̀" }, + ["Ẩ"]={ "Â","̉" }, + ["ẩ"]={ "â","̉" }, + ["Ẫ"]={ "Â","̃" }, + ["ẫ"]={ "â","̃" }, + ["Ậ"]={ "Ạ","̂" }, + ["ậ"]={ "ạ","̂" }, + ["Ắ"]={ "Ă","́" }, + ["ắ"]={ "ă","́" }, + ["Ằ"]={ "Ă","̀" }, + ["ằ"]={ "ă","̀" }, + ["Ẳ"]={ "Ă","̉" }, + ["ẳ"]={ "ă","̉" }, + ["Ẵ"]={ "Ă","̃" }, + ["ẵ"]={ "ă","̃" }, + ["Ặ"]={ "Ạ","̆" }, + ["ặ"]={ "ạ","̆" }, + ["Ẹ"]={ "E","̣" }, + ["ẹ"]={ "e","̣" }, + ["Ẻ"]={ "E","̉" }, + ["ẻ"]={ "e","̉" }, + ["Ẽ"]={ "E","̃" }, + ["ẽ"]={ "e","̃" }, + ["Ế"]={ "Ê","́" }, + ["ế"]={ "ê","́" }, + ["Ề"]={ "Ê","̀" }, + ["ề"]={ "ê","̀" }, + ["Ể"]={ "Ê","̉" }, + ["ể"]={ "ê","̉" }, + ["Ễ"]={ "Ê","̃" }, + ["ễ"]={ "ê","̃" }, + ["Ệ"]={ "Ẹ","̂" }, + ["ệ"]={ "ẹ","̂" }, + ["Ỉ"]={ "I","̉" }, + ["ỉ"]={ "i","̉" }, + ["Ị"]={ "I","̣" }, + ["ị"]={ "i","̣" }, + ["Ọ"]={ "O","̣" }, + ["ọ"]={ "o","̣" }, + ["Ỏ"]={ "O","̉" }, + ["ỏ"]={ "o","̉" }, + ["Ố"]={ "Ô","́" }, + ["ố"]={ "ô","́" }, + ["Ồ"]={ "Ô","̀" }, + ["ồ"]={ "ô","̀" }, + ["Ổ"]={ "Ô","̉" }, + ["ổ"]={ "ô","̉" }, + ["Ỗ"]={ "Ô","̃" }, + ["ỗ"]={ "ô","̃" }, + ["Ộ"]={ "Ọ","̂" }, + ["ộ"]={ "ọ","̂" }, + ["Ớ"]={ "Ơ","́" }, + ["ớ"]={ "ơ","́" }, + ["Ờ"]={ "Ơ","̀" }, + ["ờ"]={ "ơ","̀" }, + ["Ở"]={ "Ơ","̉" }, + ["ở"]={ "ơ","̉" }, + ["Ỡ"]={ "Ơ","̃" }, + ["ỡ"]={ "ơ","̃" }, + ["Ợ"]={ "Ơ","̣" }, + ["ợ"]={ "ơ","̣" }, + ["Ụ"]={ "U","̣" }, + ["ụ"]={ "u","̣" }, + ["Ủ"]={ "U","̉" }, + ["ủ"]={ "u","̉" }, + ["Ứ"]={ "Ư","́" }, + ["ứ"]={ "ư","́" }, + ["Ừ"]={ "Ư","̀" }, + ["ừ"]={ "ư","̀" }, + ["Ử"]={ "Ư","̉" }, + ["ử"]={ "ư","̉" }, + ["Ữ"]={ "Ư","̃" }, + ["ữ"]={ "ư","̃" }, + ["Ự"]={ "Ư","̣" }, + ["ự"]={ "ư","̣" }, + ["Ỳ"]={ "Y","̀" }, + ["ỳ"]={ "y","̀" }, + ["Ỵ"]={ "Y","̣" }, + ["ỵ"]={ "y","̣" }, + ["Ỷ"]={ "Y","̉" }, + ["ỷ"]={ "y","̉" }, + ["Ỹ"]={ "Y","̃" }, + ["ỹ"]={ "y","̃" }, + ["ἀ"]={ "α","̓" }, + ["ἁ"]={ "α","̔" }, + ["ἂ"]={ "ἀ","̀" }, + ["ἃ"]={ "ἁ","̀" }, + ["ἄ"]={ "ἀ","́" }, + ["ἅ"]={ "ἁ","́" }, + ["ἆ"]={ "ἀ","͂" }, + ["ἇ"]={ "ἁ","͂" }, + ["Ἀ"]={ "Α","̓" }, + ["Ἁ"]={ "Α","̔" }, + ["Ἂ"]={ "Ἀ","̀" }, + ["Ἃ"]={ "Ἁ","̀" }, + ["Ἄ"]={ "Ἀ","́" }, + ["Ἅ"]={ "Ἁ","́" }, + ["Ἆ"]={ "Ἀ","͂" }, + ["Ἇ"]={ "Ἁ","͂" }, + ["ἐ"]={ "ε","̓" }, + ["ἑ"]={ "ε","̔" }, + ["ἒ"]={ "ἐ","̀" }, + ["ἓ"]={ "ἑ","̀" }, + ["ἔ"]={ "ἐ","́" }, + ["ἕ"]={ "ἑ","́" }, + ["Ἐ"]={ "Ε","̓" }, + ["Ἑ"]={ "Ε","̔" }, + ["Ἒ"]={ "Ἐ","̀" }, + ["Ἓ"]={ "Ἑ","̀" }, + ["Ἔ"]={ "Ἐ","́" }, + ["Ἕ"]={ "Ἑ","́" }, + ["ἠ"]={ "η","̓" }, + ["ἡ"]={ "η","̔" }, + ["ἢ"]={ "ἠ","̀" }, + ["ἣ"]={ "ἡ","̀" }, + ["ἤ"]={ "ἠ","́" }, + ["ἥ"]={ "ἡ","́" }, + ["ἦ"]={ "ἠ","͂" }, + ["ἧ"]={ "ἡ","͂" }, + ["Ἠ"]={ "Η","̓" }, + ["Ἡ"]={ "Η","̔" }, + ["Ἢ"]={ "Ἠ","̀" }, + ["Ἣ"]={ "Ἡ","̀" }, + ["Ἤ"]={ "Ἠ","́" }, + ["Ἥ"]={ "Ἡ","́" }, + ["Ἦ"]={ "Ἠ","͂" }, + ["Ἧ"]={ "Ἡ","͂" }, + ["ἰ"]={ "ι","̓" }, + ["ἱ"]={ "ι","̔" }, + ["ἲ"]={ "ἰ","̀" }, + ["ἳ"]={ "ἱ","̀" }, + ["ἴ"]={ "ἰ","́" }, + ["ἵ"]={ "ἱ","́" }, + ["ἶ"]={ "ἰ","͂" }, + ["ἷ"]={ "ἱ","͂" }, + ["Ἰ"]={ "Ι","̓" }, + ["Ἱ"]={ "Ι","̔" }, + ["Ἲ"]={ "Ἰ","̀" }, + ["Ἳ"]={ "Ἱ","̀" }, + ["Ἴ"]={ "Ἰ","́" }, + ["Ἵ"]={ "Ἱ","́" }, + ["Ἶ"]={ "Ἰ","͂" }, + ["Ἷ"]={ "Ἱ","͂" }, + ["ὀ"]={ "ο","̓" }, + ["ὁ"]={ "ο","̔" }, + ["ὂ"]={ "ὀ","̀" }, + ["ὃ"]={ "ὁ","̀" }, + ["ὄ"]={ "ὀ","́" }, + ["ὅ"]={ "ὁ","́" }, + ["Ὀ"]={ "Ο","̓" }, + ["Ὁ"]={ "Ο","̔" }, + ["Ὂ"]={ "Ὀ","̀" }, + ["Ὃ"]={ "Ὁ","̀" }, + ["Ὄ"]={ "Ὀ","́" }, + ["Ὅ"]={ "Ὁ","́" }, + ["ὐ"]={ "υ","̓" }, + ["ὑ"]={ "υ","̔" }, + ["ὒ"]={ "ὐ","̀" }, + ["ὓ"]={ "ὑ","̀" }, + ["ὔ"]={ "ὐ","́" }, + ["ὕ"]={ "ὑ","́" }, + ["ὖ"]={ "ὐ","͂" }, + ["ὗ"]={ "ὑ","͂" }, + ["Ὑ"]={ "Υ","̔" }, + ["Ὓ"]={ "Ὑ","̀" }, + ["Ὕ"]={ "Ὑ","́" }, + ["Ὗ"]={ "Ὑ","͂" }, + ["ὠ"]={ "ω","̓" }, + ["ὡ"]={ "ω","̔" }, + ["ὢ"]={ "ὠ","̀" }, + ["ὣ"]={ "ὡ","̀" }, + ["ὤ"]={ "ὠ","́" }, + ["ὥ"]={ "ὡ","́" }, + ["ὦ"]={ "ὠ","͂" }, + ["ὧ"]={ "ὡ","͂" }, + ["Ὠ"]={ "Ω","̓" }, + ["Ὡ"]={ "Ω","̔" }, + ["Ὢ"]={ "Ὠ","̀" }, + ["Ὣ"]={ "Ὡ","̀" }, + ["Ὤ"]={ "Ὠ","́" }, + ["Ὥ"]={ "Ὡ","́" }, + ["Ὦ"]={ "Ὠ","͂" }, + ["Ὧ"]={ "Ὡ","͂" }, + ["ὰ"]={ "α","̀" }, + ["ὲ"]={ "ε","̀" }, + ["ὴ"]={ "η","̀" }, + ["ὶ"]={ "ι","̀" }, + ["ὸ"]={ "ο","̀" }, + ["ὺ"]={ "υ","̀" }, + ["ὼ"]={ "ω","̀" }, + ["ᾀ"]={ "ἀ","ͅ" }, + ["ᾁ"]={ "ἁ","ͅ" }, + ["ᾂ"]={ "ἂ","ͅ" }, + ["ᾃ"]={ "ἃ","ͅ" }, + ["ᾄ"]={ "ἄ","ͅ" }, + ["ᾅ"]={ "ἅ","ͅ" }, + ["ᾆ"]={ "ἆ","ͅ" }, + ["ᾇ"]={ "ἇ","ͅ" }, + ["ᾈ"]={ "Ἀ","ͅ" }, + ["ᾉ"]={ "Ἁ","ͅ" }, + ["ᾊ"]={ "Ἂ","ͅ" }, + ["ᾋ"]={ "Ἃ","ͅ" }, + ["ᾌ"]={ "Ἄ","ͅ" }, + ["ᾍ"]={ "Ἅ","ͅ" }, + ["ᾎ"]={ "Ἆ","ͅ" }, + ["ᾏ"]={ "Ἇ","ͅ" }, + ["ᾐ"]={ "ἠ","ͅ" }, + ["ᾑ"]={ "ἡ","ͅ" }, + ["ᾒ"]={ "ἢ","ͅ" }, + ["ᾓ"]={ "ἣ","ͅ" }, + ["ᾔ"]={ "ἤ","ͅ" }, + ["ᾕ"]={ "ἥ","ͅ" }, + ["ᾖ"]={ "ἦ","ͅ" }, + ["ᾗ"]={ "ἧ","ͅ" }, + ["ᾘ"]={ "Ἠ","ͅ" }, + ["ᾙ"]={ "Ἡ","ͅ" }, + ["ᾚ"]={ "Ἢ","ͅ" }, + ["ᾛ"]={ "Ἣ","ͅ" }, + ["ᾜ"]={ "Ἤ","ͅ" }, + ["ᾝ"]={ "Ἥ","ͅ" }, + ["ᾞ"]={ "Ἦ","ͅ" }, + ["ᾟ"]={ "Ἧ","ͅ" }, + ["ᾠ"]={ "ὠ","ͅ" }, + ["ᾡ"]={ "ὡ","ͅ" }, + ["ᾢ"]={ "ὢ","ͅ" }, + ["ᾣ"]={ "ὣ","ͅ" }, + ["ᾤ"]={ "ὤ","ͅ" }, + ["ᾥ"]={ "ὥ","ͅ" }, + ["ᾦ"]={ "ὦ","ͅ" }, + ["ᾧ"]={ "ὧ","ͅ" }, + ["ᾨ"]={ "Ὠ","ͅ" }, + ["ᾩ"]={ "Ὡ","ͅ" }, + ["ᾪ"]={ "Ὢ","ͅ" }, + ["ᾫ"]={ "Ὣ","ͅ" }, + ["ᾬ"]={ "Ὤ","ͅ" }, + ["ᾭ"]={ "Ὥ","ͅ" }, + ["ᾮ"]={ "Ὦ","ͅ" }, + ["ᾯ"]={ "Ὧ","ͅ" }, + ["ᾰ"]={ "α","̆" }, + ["ᾱ"]={ "α","̄" }, + ["ᾲ"]={ "ὰ","ͅ" }, + ["ᾳ"]={ "α","ͅ" }, + ["ᾴ"]={ "ά","ͅ" }, + ["ᾶ"]={ "α","͂" }, + ["ᾷ"]={ "ᾶ","ͅ" }, + ["Ᾰ"]={ "Α","̆" }, + ["Ᾱ"]={ "Α","̄" }, + ["Ὰ"]={ "Α","̀" }, + ["ᾼ"]={ "Α","ͅ" }, + ["῁"]={ "¨","͂" }, + ["ῂ"]={ "ὴ","ͅ" }, + ["ῃ"]={ "η","ͅ" }, + ["ῄ"]={ "ή","ͅ" }, + ["ῆ"]={ "η","͂" }, + ["ῇ"]={ "ῆ","ͅ" }, + ["Ὲ"]={ "Ε","̀" }, + ["Ὴ"]={ "Η","̀" }, + ["ῌ"]={ "Η","ͅ" }, + ["῍"]={ "᾿","̀" }, + ["῎"]={ "᾿","́" }, + ["῏"]={ "᾿","͂" }, + ["ῐ"]={ "ι","̆" }, + ["ῑ"]={ "ι","̄" }, + ["ῒ"]={ "ϊ","̀" }, + ["ῖ"]={ "ι","͂" }, + ["ῗ"]={ "ϊ","͂" }, + ["Ῐ"]={ "Ι","̆" }, + ["Ῑ"]={ "Ι","̄" }, + ["Ὶ"]={ "Ι","̀" }, + ["῝"]={ "῾","̀" }, + ["῞"]={ "῾","́" }, + ["῟"]={ "῾","͂" }, + ["ῠ"]={ "υ","̆" }, + ["ῡ"]={ "υ","̄" }, + ["ῢ"]={ "ϋ","̀" }, + ["ῤ"]={ "ρ","̓" }, + ["ῥ"]={ "ρ","̔" }, + ["ῦ"]={ "υ","͂" }, + ["ῧ"]={ "ϋ","͂" }, + ["Ῠ"]={ "Υ","̆" }, + ["Ῡ"]={ "Υ","̄" }, + ["Ὺ"]={ "Υ","̀" }, + ["Ῥ"]={ "Ρ","̔" }, + ["῭"]={ "¨","̀" }, + ["ῲ"]={ "ὼ","ͅ" }, + ["ῳ"]={ "ω","ͅ" }, + ["ῴ"]={ "ώ","ͅ" }, + ["ῶ"]={ "ω","͂" }, + ["ῷ"]={ "ῶ","ͅ" }, + ["Ὸ"]={ "Ο","̀" }, + ["Ὼ"]={ "Ω","̀" }, + ["ῼ"]={ "Ω","ͅ" }, + ["↚"]={ "←","̸" }, + ["↛"]={ "→","̸" }, + ["↮"]={ "↔","̸" }, + ["⇍"]={ "⇐","̸" }, + ["⇎"]={ "⇔","̸" }, + ["⇏"]={ "⇒","̸" }, + ["∄"]={ "∃","̸" }, + ["∉"]={ "∈","̸" }, + ["∌"]={ "∋","̸" }, + ["∤"]={ "∣","̸" }, + ["∦"]={ "∥","̸" }, + ["≁"]={ "∼","̸" }, + ["≄"]={ "≃","̸" }, + ["≇"]={ "≅","̸" }, + ["≉"]={ "≈","̸" }, + ["≠"]={ "=","̸" }, + ["≢"]={ "≡","̸" }, + ["≭"]={ "≍","̸" }, + ["≮"]={ "<","̸" }, + ["≯"]={ ">","̸" }, + ["≰"]={ "≤","̸" }, + ["≱"]={ "≥","̸" }, + ["≴"]={ "≲","̸" }, + ["≵"]={ "≳","̸" }, + ["≸"]={ "≶","̸" }, + ["≹"]={ "≷","̸" }, + ["⊀"]={ "≺","̸" }, + ["⊁"]={ "≻","̸" }, + ["⊄"]={ "⊂","̸" }, + ["⊅"]={ "⊃","̸" }, + ["⊈"]={ "⊆","̸" }, + ["⊉"]={ "⊇","̸" }, + ["⊬"]={ "⊢","̸" }, + ["⊭"]={ "⊨","̸" }, + ["⊮"]={ "⊩","̸" }, + ["⊯"]={ "⊫","̸" }, + ["⋠"]={ "≼","̸" }, + ["⋡"]={ "≽","̸" }, + ["⋢"]={ "⊑","̸" }, + ["⋣"]={ "⊒","̸" }, + ["⋪"]={ "⊲","̸" }, + ["⋫"]={ "⊳","̸" }, + ["⋬"]={ "⊴","̸" }, + ["⋭"]={ "⊵","̸" }, + ["⫝̸"]={ "⫝","̸" }, + ["が"]={ "か","゙" }, + ["ぎ"]={ "き","゙" }, + ["ぐ"]={ "く","゙" }, + ["げ"]={ "け","゙" }, + ["ご"]={ "こ","゙" }, + ["ざ"]={ "さ","゙" }, + ["じ"]={ "し","゙" }, + ["ず"]={ "す","゙" }, + ["ぜ"]={ "せ","゙" }, + ["ぞ"]={ "そ","゙" }, + ["だ"]={ "た","゙" }, + ["ぢ"]={ "ち","゙" }, + ["づ"]={ "つ","゙" }, + ["で"]={ "て","゙" }, + ["ど"]={ "と","゙" }, + ["ば"]={ "は","゙" }, + ["ぱ"]={ "は","゚" }, + ["び"]={ "ひ","゙" }, + ["ぴ"]={ "ひ","゚" }, + ["ぶ"]={ "ふ","゙" }, + ["ぷ"]={ "ふ","゚" }, + ["べ"]={ "へ","゙" }, + ["ぺ"]={ "へ","゚" }, + ["ぼ"]={ "ほ","゙" }, + ["ぽ"]={ "ほ","゚" }, + ["ゔ"]={ "う","゙" }, + ["ゞ"]={ "ゝ","゙" }, + ["ガ"]={ "カ","゙" }, + ["ギ"]={ "キ","゙" }, + ["グ"]={ "ク","゙" }, + ["ゲ"]={ "ケ","゙" }, + ["ゴ"]={ "コ","゙" }, + ["ザ"]={ "サ","゙" }, + ["ジ"]={ "シ","゙" }, + ["ズ"]={ "ス","゙" }, + ["ゼ"]={ "セ","゙" }, + ["ゾ"]={ "ソ","゙" }, + ["ダ"]={ "タ","゙" }, + ["ヂ"]={ "チ","゙" }, + ["ヅ"]={ "ツ","゙" }, + ["デ"]={ "テ","゙" }, + ["ド"]={ "ト","゙" }, + ["バ"]={ "ハ","゙" }, + ["パ"]={ "ハ","゚" }, + ["ビ"]={ "ヒ","゙" }, + ["ピ"]={ "ヒ","゚" }, + ["ブ"]={ "フ","゙" }, + ["プ"]={ "フ","゚" }, + ["ベ"]={ "ヘ","゙" }, + ["ペ"]={ "ヘ","゚" }, + ["ボ"]={ "ホ","゙" }, + ["ポ"]={ "ホ","゚" }, + ["ヴ"]={ "ウ","゙" }, + ["ヷ"]={ "ワ","゙" }, + ["ヸ"]={ "ヰ","゙" }, + ["ヹ"]={ "ヱ","゙" }, + ["ヺ"]={ "ヲ","゙" }, + ["ヾ"]={ "ヽ","゙" }, + ["יִ"]={ "י","ִ" }, + ["ײַ"]={ "ײ","ַ" }, + ["שׁ"]={ "ש","ׁ" }, + ["שׂ"]={ "ש","ׂ" }, + ["שּׁ"]={ "שּ","ׁ" }, + ["שּׂ"]={ "שּ","ׂ" }, + ["אַ"]={ "א","ַ" }, + ["אָ"]={ "א","ָ" }, + ["אּ"]={ "א","ּ" }, + ["בּ"]={ "ב","ּ" }, + ["גּ"]={ "ג","ּ" }, + ["דּ"]={ "ד","ּ" }, + ["הּ"]={ "ה","ּ" }, + ["וּ"]={ "ו","ּ" }, + ["זּ"]={ "ז","ּ" }, + ["טּ"]={ "ט","ּ" }, + ["יּ"]={ "י","ּ" }, + ["ךּ"]={ "ך","ּ" }, + ["כּ"]={ "כ","ּ" }, + ["לּ"]={ "ל","ּ" }, + ["מּ"]={ "מ","ּ" }, + ["נּ"]={ "נ","ּ" }, + ["סּ"]={ "ס","ּ" }, + ["ףּ"]={ "ף","ּ" }, + ["פּ"]={ "פ","ּ" }, + ["צּ"]={ "צ","ּ" }, + ["קּ"]={ "ק","ּ" }, + ["רּ"]={ "ר","ּ" }, + ["שּ"]={ "ש","ּ" }, + ["תּ"]={ "ת","ּ" }, + ["וֹ"]={ "ו","ֹ" }, + ["בֿ"]={ "ב","ֿ" }, + ["כֿ"]={ "כ","ֿ" }, + ["פֿ"]={ "פ","ֿ" }, + ["𑂚"]={ "𑂙","𑂺" }, + ["𑂜"]={ "𑂛","𑂺" }, + ["𑂫"]={ "𑂥","𑂺" }, + ["𑄮"]={ "𑄱","𑄧" }, + ["𑄯"]={ "𑄲","𑄧" }, + ["𑍋"]={ "𑍇","𑌾" }, + ["𑍌"]={ "𑍇","𑍗" }, + ["𑒻"]={ "𑒹","𑒺" }, + ["𑒼"]={ "𑒹","𑒰" }, + ["𑒾"]={ "𑒹","𑒽" }, + ["𑖺"]={ "𑖸","𑖯" }, + ["𑖻"]={ "𑖹","𑖯" }, + ["𝅗𝅥"]={ "𝅗","𝅥" }, + ["𝅘𝅥"]={ "𝅘","𝅥" }, + ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" }, + ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" }, + ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" }, + ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" }, + ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" }, + ["𝆹𝅥"]={ "𝆹","𝅥" }, + ["𝆺𝅥"]={ "𝆺","𝅥" }, + ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" }, + ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" }, + ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" }, + ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" }, + }, + }, + { + ["data"]={ + ["À"]={ "A","̀" }, + ["Á"]={ "A","́" }, + ["Â"]={ "A","̂" }, + ["Ã"]={ "A","̃" }, + ["Ä"]={ "A","̈" }, + ["Å"]={ "A","̊" }, + ["Ç"]={ "C","̧" }, + ["È"]={ "E","̀" }, + ["É"]={ "E","́" }, + ["Ê"]={ "E","̂" }, + ["Ë"]={ "E","̈" }, + ["Ì"]={ "I","̀" }, + ["Í"]={ "I","́" }, + ["Î"]={ "I","̂" }, + ["Ï"]={ "I","̈" }, + ["Ñ"]={ "N","̃" }, + ["Ò"]={ "O","̀" }, + ["Ó"]={ "O","́" }, + ["Ô"]={ "O","̂" }, + ["Õ"]={ "O","̃" }, + ["Ö"]={ "O","̈" }, + ["Ù"]={ "U","̀" }, + ["Ú"]={ "U","́" }, + ["Û"]={ "U","̂" }, + ["Ü"]={ "U","̈" }, + ["Ý"]={ "Y","́" }, + ["à"]={ "a","̀" }, + ["á"]={ "a","́" }, + ["â"]={ "a","̂" }, + ["ã"]={ "a","̃" }, + ["ä"]={ "a","̈" }, + ["å"]={ "a","̊" }, + ["ç"]={ "c","̧" }, + ["è"]={ "e","̀" }, + ["é"]={ "e","́" }, + ["ê"]={ "e","̂" }, + ["ë"]={ "e","̈" }, + ["ì"]={ "i","̀" }, + ["í"]={ "i","́" }, + ["î"]={ "i","̂" }, + ["ï"]={ "i","̈" }, + ["ñ"]={ "n","̃" }, + ["ò"]={ "o","̀" }, + ["ó"]={ "o","́" }, + ["ô"]={ "o","̂" }, + ["õ"]={ "o","̃" }, + ["ö"]={ "o","̈" }, + ["ù"]={ "u","̀" }, + ["ú"]={ "u","́" }, + ["û"]={ "u","̂" }, + ["ü"]={ "u","̈" }, + ["ý"]={ "y","́" }, + ["ÿ"]={ "y","̈" }, + ["Ā"]={ "A","̄" }, + ["ā"]={ "a","̄" }, + ["Ă"]={ "A","̆" }, + ["ă"]={ "a","̆" }, + ["Ą"]={ "A","̨" }, + ["ą"]={ "a","̨" }, + ["Ć"]={ "C","́" }, + ["ć"]={ "c","́" }, + ["Ĉ"]={ "C","̂" }, + ["ĉ"]={ "c","̂" }, + ["Ċ"]={ "C","̇" }, + ["ċ"]={ "c","̇" }, + ["Č"]={ "C","̌" }, + ["č"]={ "c","̌" }, + ["Ď"]={ "D","̌" }, + ["ď"]={ "d","̌" }, + ["Ē"]={ "E","̄" }, + ["ē"]={ "e","̄" }, + ["Ĕ"]={ "E","̆" }, + ["ĕ"]={ "e","̆" }, + ["Ė"]={ "E","̇" }, + ["ė"]={ "e","̇" }, + ["Ę"]={ "E","̨" }, + ["ę"]={ "e","̨" }, + ["Ě"]={ "E","̌" }, + ["ě"]={ "e","̌" }, + ["Ĝ"]={ "G","̂" }, + ["ĝ"]={ "g","̂" }, + ["Ğ"]={ "G","̆" }, + ["ğ"]={ "g","̆" }, + ["Ġ"]={ "G","̇" }, + ["ġ"]={ "g","̇" }, + ["Ģ"]={ "G","̧" }, + ["ģ"]={ "g","̧" }, + ["Ĥ"]={ "H","̂" }, + ["ĥ"]={ "h","̂" }, + ["Ĩ"]={ "I","̃" }, + ["ĩ"]={ "i","̃" }, + ["Ī"]={ "I","̄" }, + ["ī"]={ "i","̄" }, + ["Ĭ"]={ "I","̆" }, + ["ĭ"]={ "i","̆" }, + ["Į"]={ "I","̨" }, + ["į"]={ "i","̨" }, + ["İ"]={ "I","̇" }, + ["Ĵ"]={ "J","̂" }, + ["ĵ"]={ "j","̂" }, + ["Ķ"]={ "K","̧" }, + ["ķ"]={ "k","̧" }, + ["Ĺ"]={ "L","́" }, + ["ĺ"]={ "l","́" }, + ["Ļ"]={ "L","̧" }, + ["ļ"]={ "l","̧" }, + ["Ľ"]={ "L","̌" }, + ["ľ"]={ "l","̌" }, + ["Ń"]={ "N","́" }, + ["ń"]={ "n","́" }, + ["Ņ"]={ "N","̧" }, + ["ņ"]={ "n","̧" }, + ["Ň"]={ "N","̌" }, + ["ň"]={ "n","̌" }, + ["Ō"]={ "O","̄" }, + ["ō"]={ "o","̄" }, + ["Ŏ"]={ "O","̆" }, + ["ŏ"]={ "o","̆" }, + ["Ő"]={ "O","̋" }, + ["ő"]={ "o","̋" }, + ["Ŕ"]={ "R","́" }, + ["ŕ"]={ "r","́" }, + ["Ŗ"]={ "R","̧" }, + ["ŗ"]={ "r","̧" }, + ["Ř"]={ "R","̌" }, + ["ř"]={ "r","̌" }, + ["Ś"]={ "S","́" }, + ["ś"]={ "s","́" }, + ["Ŝ"]={ "S","̂" }, + ["ŝ"]={ "s","̂" }, + ["Ş"]={ "S","̧" }, + ["ş"]={ "s","̧" }, + ["Š"]={ "S","̌" }, + ["š"]={ "s","̌" }, + ["Ţ"]={ "T","̧" }, + ["ţ"]={ "t","̧" }, + ["Ť"]={ "T","̌" }, + ["ť"]={ "t","̌" }, + ["Ũ"]={ "U","̃" }, + ["ũ"]={ "u","̃" }, + ["Ū"]={ "U","̄" }, + ["ū"]={ "u","̄" }, + ["Ŭ"]={ "U","̆" }, + ["ŭ"]={ "u","̆" }, + ["Ů"]={ "U","̊" }, + ["ů"]={ "u","̊" }, + ["Ű"]={ "U","̋" }, + ["ű"]={ "u","̋" }, + ["Ų"]={ "U","̨" }, + ["ų"]={ "u","̨" }, + ["Ŵ"]={ "W","̂" }, + ["ŵ"]={ "w","̂" }, + ["Ŷ"]={ "Y","̂" }, + ["ŷ"]={ "y","̂" }, + ["Ÿ"]={ "Y","̈" }, + ["Ź"]={ "Z","́" }, + ["ź"]={ "z","́" }, + ["Ż"]={ "Z","̇" }, + ["ż"]={ "z","̇" }, + ["Ž"]={ "Z","̌" }, + ["ž"]={ "z","̌" }, + ["Ơ"]={ "O","̛" }, + ["ơ"]={ "o","̛" }, + ["Ư"]={ "U","̛" }, + ["ư"]={ "u","̛" }, + ["Ǎ"]={ "A","̌" }, + ["ǎ"]={ "a","̌" }, + ["Ǐ"]={ "I","̌" }, + ["ǐ"]={ "i","̌" }, + ["Ǒ"]={ "O","̌" }, + ["ǒ"]={ "o","̌" }, + ["Ǔ"]={ "U","̌" }, + ["ǔ"]={ "u","̌" }, + ["Ǖ"]={ "Ü","̄" }, + ["ǖ"]={ "ü","̄" }, + ["Ǘ"]={ "Ü","́" }, + ["ǘ"]={ "ü","́" }, + ["Ǚ"]={ "Ü","̌" }, + ["ǚ"]={ "ü","̌" }, + ["Ǜ"]={ "Ü","̀" }, + ["ǜ"]={ "ü","̀" }, + ["Ǟ"]={ "Ä","̄" }, + ["ǟ"]={ "ä","̄" }, + ["Ǡ"]={ "Ȧ","̄" }, + ["ǡ"]={ "ȧ","̄" }, + ["Ǣ"]={ "Æ","̄" }, + ["ǣ"]={ "æ","̄" }, + ["Ǧ"]={ "G","̌" }, + ["ǧ"]={ "g","̌" }, + ["Ǩ"]={ "K","̌" }, + ["ǩ"]={ "k","̌" }, + ["Ǫ"]={ "O","̨" }, + ["ǫ"]={ "o","̨" }, + ["Ǭ"]={ "Ǫ","̄" }, + ["ǭ"]={ "ǫ","̄" }, + ["Ǯ"]={ "Ʒ","̌" }, + ["ǯ"]={ "ʒ","̌" }, + ["ǰ"]={ "j","̌" }, + ["Ǵ"]={ "G","́" }, + ["ǵ"]={ "g","́" }, + ["Ǹ"]={ "N","̀" }, + ["ǹ"]={ "n","̀" }, + ["Ǻ"]={ "Å","́" }, + ["ǻ"]={ "å","́" }, + ["Ǽ"]={ "Æ","́" }, + ["ǽ"]={ "æ","́" }, + ["Ǿ"]={ "Ø","́" }, + ["ǿ"]={ "ø","́" }, + ["Ȁ"]={ "A","̏" }, + ["ȁ"]={ "a","̏" }, + ["Ȃ"]={ "A","̑" }, + ["ȃ"]={ "a","̑" }, + ["Ȅ"]={ "E","̏" }, + ["ȅ"]={ "e","̏" }, + ["Ȇ"]={ "E","̑" }, + ["ȇ"]={ "e","̑" }, + ["Ȉ"]={ "I","̏" }, + ["ȉ"]={ "i","̏" }, + ["Ȋ"]={ "I","̑" }, + ["ȋ"]={ "i","̑" }, + ["Ȍ"]={ "O","̏" }, + ["ȍ"]={ "o","̏" }, + ["Ȏ"]={ "O","̑" }, + ["ȏ"]={ "o","̑" }, + ["Ȑ"]={ "R","̏" }, + ["ȑ"]={ "r","̏" }, + ["Ȓ"]={ "R","̑" }, + ["ȓ"]={ "r","̑" }, + ["Ȕ"]={ "U","̏" }, + ["ȕ"]={ "u","̏" }, + ["Ȗ"]={ "U","̑" }, + ["ȗ"]={ "u","̑" }, + ["Ș"]={ "S","̦" }, + ["ș"]={ "s","̦" }, + ["Ț"]={ "T","̦" }, + ["ț"]={ "t","̦" }, + ["Ȟ"]={ "H","̌" }, + ["ȟ"]={ "h","̌" }, + ["Ȧ"]={ "A","̇" }, + ["ȧ"]={ "a","̇" }, + ["Ȩ"]={ "E","̧" }, + ["ȩ"]={ "e","̧" }, + ["Ȫ"]={ "Ö","̄" }, + ["ȫ"]={ "ö","̄" }, + ["Ȭ"]={ "Õ","̄" }, + ["ȭ"]={ "õ","̄" }, + ["Ȯ"]={ "O","̇" }, + ["ȯ"]={ "o","̇" }, + ["Ȱ"]={ "Ȯ","̄" }, + ["ȱ"]={ "ȯ","̄" }, + ["Ȳ"]={ "Y","̄" }, + ["ȳ"]={ "y","̄" }, + ["̈́"]={ "̈","́" }, + ["΅"]={ "¨","́" }, + ["Ά"]={ "Α","́" }, + ["Έ"]={ "Ε","́" }, + ["Ή"]={ "Η","́" }, + ["Ί"]={ "Ι","́" }, + ["Ό"]={ "Ο","́" }, + ["Ύ"]={ "Υ","́" }, + ["Ώ"]={ "Ω","́" }, + ["ΐ"]={ "ϊ","́" }, + ["Ϊ"]={ "Ι","̈" }, + ["Ϋ"]={ "Υ","̈" }, + ["ά"]={ "α","́" }, + ["έ"]={ "ε","́" }, + ["ή"]={ "η","́" }, + ["ί"]={ "ι","́" }, + ["ΰ"]={ "ϋ","́" }, + ["ϊ"]={ "ι","̈" }, + ["ϋ"]={ "υ","̈" }, + ["ό"]={ "ο","́" }, + ["ύ"]={ "υ","́" }, + ["ώ"]={ "ω","́" }, + ["ϓ"]={ "ϒ","́" }, + ["ϔ"]={ "ϒ","̈" }, + ["Ѐ"]={ "Е","̀" }, + ["Ё"]={ "Е","̈" }, + ["Ѓ"]={ "Г","́" }, + ["Ї"]={ "І","̈" }, + ["Ќ"]={ "К","́" }, + ["Ѝ"]={ "И","̀" }, + ["Ў"]={ "У","̆" }, + ["Й"]={ "И","̆" }, + ["й"]={ "и","̆" }, + ["ѐ"]={ "е","̀" }, + ["ё"]={ "е","̈" }, + ["ѓ"]={ "г","́" }, + ["ї"]={ "і","̈" }, + ["ќ"]={ "к","́" }, + ["ѝ"]={ "и","̀" }, + ["ў"]={ "у","̆" }, + ["Ѷ"]={ "Ѵ","̏" }, + ["ѷ"]={ "ѵ","̏" }, + ["Ӂ"]={ "Ж","̆" }, + ["ӂ"]={ "ж","̆" }, + ["Ӑ"]={ "А","̆" }, + ["ӑ"]={ "а","̆" }, + ["Ӓ"]={ "А","̈" }, + ["ӓ"]={ "а","̈" }, + ["Ӗ"]={ "Е","̆" }, + ["ӗ"]={ "е","̆" }, + ["Ӛ"]={ "Ә","̈" }, + ["ӛ"]={ "ә","̈" }, + ["Ӝ"]={ "Ж","̈" }, + ["ӝ"]={ "ж","̈" }, + ["Ӟ"]={ "З","̈" }, + ["ӟ"]={ "з","̈" }, + ["Ӣ"]={ "И","̄" }, + ["ӣ"]={ "и","̄" }, + ["Ӥ"]={ "И","̈" }, + ["ӥ"]={ "и","̈" }, + ["Ӧ"]={ "О","̈" }, + ["ӧ"]={ "о","̈" }, + ["Ӫ"]={ "Ө","̈" }, + ["ӫ"]={ "ө","̈" }, + ["Ӭ"]={ "Э","̈" }, + ["ӭ"]={ "э","̈" }, + ["Ӯ"]={ "У","̄" }, + ["ӯ"]={ "у","̄" }, + ["Ӱ"]={ "У","̈" }, + ["ӱ"]={ "у","̈" }, + ["Ӳ"]={ "У","̋" }, + ["ӳ"]={ "у","̋" }, + ["Ӵ"]={ "Ч","̈" }, + ["ӵ"]={ "ч","̈" }, + ["Ӹ"]={ "Ы","̈" }, + ["ӹ"]={ "ы","̈" }, + ["آ"]={ "ا","ٓ" }, + ["أ"]={ "ا","ٔ" }, + ["ؤ"]={ "و","ٔ" }, + ["إ"]={ "ا","ٕ" }, + ["ئ"]={ "ي","ٔ" }, + ["ۀ"]={ "ە","ٔ" }, + ["ۂ"]={ "ہ","ٔ" }, + ["ۓ"]={ "ے","ٔ" }, + ["ऩ"]={ "न","़" }, + ["ऱ"]={ "र","़" }, + ["ऴ"]={ "ळ","़" }, + ["क़"]={ "क","़" }, + ["ख़"]={ "ख","़" }, + ["ग़"]={ "ग","़" }, + ["ज़"]={ "ज","़" }, + ["ड़"]={ "ड","़" }, + ["ढ़"]={ "ढ","़" }, + ["फ़"]={ "फ","़" }, + ["य़"]={ "य","़" }, + ["ো"]={ "ে","া" }, + ["ৌ"]={ "ে","ৗ" }, + ["ড়"]={ "ড","়" }, + ["ঢ়"]={ "ঢ","়" }, + ["য়"]={ "য","়" }, + ["ਲ਼"]={ "ਲ","਼" }, + ["ਸ਼"]={ "ਸ","਼" }, + ["ਖ਼"]={ "ਖ","਼" }, + ["ਗ਼"]={ "ਗ","਼" }, + ["ਜ਼"]={ "ਜ","਼" }, + ["ਫ਼"]={ "ਫ","਼" }, + ["ୈ"]={ "େ","ୖ" }, + ["ୋ"]={ "େ","ା" }, + ["ୌ"]={ "େ","ୗ" }, + ["ଡ଼"]={ "ଡ","଼" }, + ["ଢ଼"]={ "ଢ","଼" }, + ["ஔ"]={ "ஒ","ௗ" }, + ["ொ"]={ "ெ","ா" }, + ["ோ"]={ "ே","ா" }, + ["ௌ"]={ "ெ","ௗ" }, + ["ై"]={ "ె","ౖ" }, + ["ೀ"]={ "ಿ","ೕ" }, + ["ೇ"]={ "ೆ","ೕ" }, + ["ೈ"]={ "ೆ","ೖ" }, + ["ೊ"]={ "ೆ","ೂ" }, + ["ೋ"]={ "ೊ","ೕ" }, + ["ൊ"]={ "െ","ാ" }, + ["ോ"]={ "േ","ാ" }, + ["ൌ"]={ "െ","ൗ" }, + ["ේ"]={ "ෙ","්" }, + ["ො"]={ "ෙ","ා" }, + ["ෝ"]={ "ො","්" }, + ["ෞ"]={ "ෙ","ෟ" }, + ["གྷ"]={ "ག","ྷ" }, + ["ཌྷ"]={ "ཌ","ྷ" }, + ["དྷ"]={ "ད","ྷ" }, + ["བྷ"]={ "བ","ྷ" }, + ["ཛྷ"]={ "ཛ","ྷ" }, + ["ཀྵ"]={ "ཀ","ྵ" }, + ["ཱི"]={ "ཱ","ི" }, + ["ཱུ"]={ "ཱ","ུ" }, + ["ྲྀ"]={ "ྲ","ྀ" }, + ["ླྀ"]={ "ླ","ྀ" }, + ["ཱྀ"]={ "ཱ","ྀ" }, + ["ྒྷ"]={ "ྒ","ྷ" }, + ["ྜྷ"]={ "ྜ","ྷ" }, + ["ྡྷ"]={ "ྡ","ྷ" }, + ["ྦྷ"]={ "ྦ","ྷ" }, + ["ྫྷ"]={ "ྫ","ྷ" }, + ["ྐྵ"]={ "ྐ","ྵ" }, + ["ဦ"]={ "ဥ","ီ" }, + ["ᬆ"]={ "ᬅ","ᬵ" }, + ["ᬈ"]={ "ᬇ","ᬵ" }, + ["ᬊ"]={ "ᬉ","ᬵ" }, + ["ᬌ"]={ "ᬋ","ᬵ" }, + ["ᬎ"]={ "ᬍ","ᬵ" }, + ["ᬒ"]={ "ᬑ","ᬵ" }, + ["ᬻ"]={ "ᬺ","ᬵ" }, + ["ᬽ"]={ "ᬼ","ᬵ" }, + ["ᭀ"]={ "ᬾ","ᬵ" }, + ["ᭁ"]={ "ᬿ","ᬵ" }, + ["ᭃ"]={ "ᭂ","ᬵ" }, + ["Ḁ"]={ "A","̥" }, + ["ḁ"]={ "a","̥" }, + ["Ḃ"]={ "B","̇" }, + ["ḃ"]={ "b","̇" }, + ["Ḅ"]={ "B","̣" }, + ["ḅ"]={ "b","̣" }, + ["Ḇ"]={ "B","̱" }, + ["ḇ"]={ "b","̱" }, + ["Ḉ"]={ "Ç","́" }, + ["ḉ"]={ "ç","́" }, + ["Ḋ"]={ "D","̇" }, + ["ḋ"]={ "d","̇" }, + ["Ḍ"]={ "D","̣" }, + ["ḍ"]={ "d","̣" }, + ["Ḏ"]={ "D","̱" }, + ["ḏ"]={ "d","̱" }, + ["Ḑ"]={ "D","̧" }, + ["ḑ"]={ "d","̧" }, + ["Ḓ"]={ "D","̭" }, + ["ḓ"]={ "d","̭" }, + ["Ḕ"]={ "Ē","̀" }, + ["ḕ"]={ "ē","̀" }, + ["Ḗ"]={ "Ē","́" }, + ["ḗ"]={ "ē","́" }, + ["Ḙ"]={ "E","̭" }, + ["ḙ"]={ "e","̭" }, + ["Ḛ"]={ "E","̰" }, + ["ḛ"]={ "e","̰" }, + ["Ḝ"]={ "Ȩ","̆" }, + ["ḝ"]={ "ȩ","̆" }, + ["Ḟ"]={ "F","̇" }, + ["ḟ"]={ "f","̇" }, + ["Ḡ"]={ "G","̄" }, + ["ḡ"]={ "g","̄" }, + ["Ḣ"]={ "H","̇" }, + ["ḣ"]={ "h","̇" }, + ["Ḥ"]={ "H","̣" }, + ["ḥ"]={ "h","̣" }, + ["Ḧ"]={ "H","̈" }, + ["ḧ"]={ "h","̈" }, + ["Ḩ"]={ "H","̧" }, + ["ḩ"]={ "h","̧" }, + ["Ḫ"]={ "H","̮" }, + ["ḫ"]={ "h","̮" }, + ["Ḭ"]={ "I","̰" }, + ["ḭ"]={ "i","̰" }, + ["Ḯ"]={ "Ï","́" }, + ["ḯ"]={ "ï","́" }, + ["Ḱ"]={ "K","́" }, + ["ḱ"]={ "k","́" }, + ["Ḳ"]={ "K","̣" }, + ["ḳ"]={ "k","̣" }, + ["Ḵ"]={ "K","̱" }, + ["ḵ"]={ "k","̱" }, + ["Ḷ"]={ "L","̣" }, + ["ḷ"]={ "l","̣" }, + ["Ḹ"]={ "Ḷ","̄" }, + ["ḹ"]={ "ḷ","̄" }, + ["Ḻ"]={ "L","̱" }, + ["ḻ"]={ "l","̱" }, + ["Ḽ"]={ "L","̭" }, + ["ḽ"]={ "l","̭" }, + ["Ḿ"]={ "M","́" }, + ["ḿ"]={ "m","́" }, + ["Ṁ"]={ "M","̇" }, + ["ṁ"]={ "m","̇" }, + ["Ṃ"]={ "M","̣" }, + ["ṃ"]={ "m","̣" }, + ["Ṅ"]={ "N","̇" }, + ["ṅ"]={ "n","̇" }, + ["Ṇ"]={ "N","̣" }, + ["ṇ"]={ "n","̣" }, + ["Ṉ"]={ "N","̱" }, + ["ṉ"]={ "n","̱" }, + ["Ṋ"]={ "N","̭" }, + ["ṋ"]={ "n","̭" }, + ["Ṍ"]={ "Õ","́" }, + ["ṍ"]={ "õ","́" }, + ["Ṏ"]={ "Õ","̈" }, + ["ṏ"]={ "õ","̈" }, + ["Ṑ"]={ "Ō","̀" }, + ["ṑ"]={ "ō","̀" }, + ["Ṓ"]={ "Ō","́" }, + ["ṓ"]={ "ō","́" }, + ["Ṕ"]={ "P","́" }, + ["ṕ"]={ "p","́" }, + ["Ṗ"]={ "P","̇" }, + ["ṗ"]={ "p","̇" }, + ["Ṙ"]={ "R","̇" }, + ["ṙ"]={ "r","̇" }, + ["Ṛ"]={ "R","̣" }, + ["ṛ"]={ "r","̣" }, + ["Ṝ"]={ "Ṛ","̄" }, + ["ṝ"]={ "ṛ","̄" }, + ["Ṟ"]={ "R","̱" }, + ["ṟ"]={ "r","̱" }, + ["Ṡ"]={ "S","̇" }, + ["ṡ"]={ "s","̇" }, + ["Ṣ"]={ "S","̣" }, + ["ṣ"]={ "s","̣" }, + ["Ṥ"]={ "Ś","̇" }, + ["ṥ"]={ "ś","̇" }, + ["Ṧ"]={ "Š","̇" }, + ["ṧ"]={ "š","̇" }, + ["Ṩ"]={ "Ṣ","̇" }, + ["ṩ"]={ "ṣ","̇" }, + ["Ṫ"]={ "T","̇" }, + ["ṫ"]={ "t","̇" }, + ["Ṭ"]={ "T","̣" }, + ["ṭ"]={ "t","̣" }, + ["Ṯ"]={ "T","̱" }, + ["ṯ"]={ "t","̱" }, + ["Ṱ"]={ "T","̭" }, + ["ṱ"]={ "t","̭" }, + ["Ṳ"]={ "U","̤" }, + ["ṳ"]={ "u","̤" }, + ["Ṵ"]={ "U","̰" }, + ["ṵ"]={ "u","̰" }, + ["Ṷ"]={ "U","̭" }, + ["ṷ"]={ "u","̭" }, + ["Ṹ"]={ "Ũ","́" }, + ["ṹ"]={ "ũ","́" }, + ["Ṻ"]={ "Ū","̈" }, + ["ṻ"]={ "ū","̈" }, + ["Ṽ"]={ "V","̃" }, + ["ṽ"]={ "v","̃" }, + ["Ṿ"]={ "V","̣" }, + ["ṿ"]={ "v","̣" }, + ["Ẁ"]={ "W","̀" }, + ["ẁ"]={ "w","̀" }, + ["Ẃ"]={ "W","́" }, + ["ẃ"]={ "w","́" }, + ["Ẅ"]={ "W","̈" }, + ["ẅ"]={ "w","̈" }, + ["Ẇ"]={ "W","̇" }, + ["ẇ"]={ "w","̇" }, + ["Ẉ"]={ "W","̣" }, + ["ẉ"]={ "w","̣" }, + ["Ẋ"]={ "X","̇" }, + ["ẋ"]={ "x","̇" }, + ["Ẍ"]={ "X","̈" }, + ["ẍ"]={ "x","̈" }, + ["Ẏ"]={ "Y","̇" }, + ["ẏ"]={ "y","̇" }, + ["Ẑ"]={ "Z","̂" }, + ["ẑ"]={ "z","̂" }, + ["Ẓ"]={ "Z","̣" }, + ["ẓ"]={ "z","̣" }, + ["Ẕ"]={ "Z","̱" }, + ["ẕ"]={ "z","̱" }, + ["ẖ"]={ "h","̱" }, + ["ẗ"]={ "t","̈" }, + ["ẘ"]={ "w","̊" }, + ["ẙ"]={ "y","̊" }, + ["ẛ"]={ "ſ","̇" }, + ["Ạ"]={ "A","̣" }, + ["ạ"]={ "a","̣" }, + ["Ả"]={ "A","̉" }, + ["ả"]={ "a","̉" }, + ["Ấ"]={ "Â","́" }, + ["ấ"]={ "â","́" }, + ["Ầ"]={ "Â","̀" }, + ["ầ"]={ "â","̀" }, + ["Ẩ"]={ "Â","̉" }, + ["ẩ"]={ "â","̉" }, + ["Ẫ"]={ "Â","̃" }, + ["ẫ"]={ "â","̃" }, + ["Ậ"]={ "Ạ","̂" }, + ["ậ"]={ "ạ","̂" }, + ["Ắ"]={ "Ă","́" }, + ["ắ"]={ "ă","́" }, + ["Ằ"]={ "Ă","̀" }, + ["ằ"]={ "ă","̀" }, + ["Ẳ"]={ "Ă","̉" }, + ["ẳ"]={ "ă","̉" }, + ["Ẵ"]={ "Ă","̃" }, + ["ẵ"]={ "ă","̃" }, + ["Ặ"]={ "Ạ","̆" }, + ["ặ"]={ "ạ","̆" }, + ["Ẹ"]={ "E","̣" }, + ["ẹ"]={ "e","̣" }, + ["Ẻ"]={ "E","̉" }, + ["ẻ"]={ "e","̉" }, + ["Ẽ"]={ "E","̃" }, + ["ẽ"]={ "e","̃" }, + ["Ế"]={ "Ê","́" }, + ["ế"]={ "ê","́" }, + ["Ề"]={ "Ê","̀" }, + ["ề"]={ "ê","̀" }, + ["Ể"]={ "Ê","̉" }, + ["ể"]={ "ê","̉" }, + ["Ễ"]={ "Ê","̃" }, + ["ễ"]={ "ê","̃" }, + ["Ệ"]={ "Ẹ","̂" }, + ["ệ"]={ "ẹ","̂" }, + ["Ỉ"]={ "I","̉" }, + ["ỉ"]={ "i","̉" }, + ["Ị"]={ "I","̣" }, + ["ị"]={ "i","̣" }, + ["Ọ"]={ "O","̣" }, + ["ọ"]={ "o","̣" }, + ["Ỏ"]={ "O","̉" }, + ["ỏ"]={ "o","̉" }, + ["Ố"]={ "Ô","́" }, + ["ố"]={ "ô","́" }, + ["Ồ"]={ "Ô","̀" }, + ["ồ"]={ "ô","̀" }, + ["Ổ"]={ "Ô","̉" }, + ["ổ"]={ "ô","̉" }, + ["Ỗ"]={ "Ô","̃" }, + ["ỗ"]={ "ô","̃" }, + ["Ộ"]={ "Ọ","̂" }, + ["ộ"]={ "ọ","̂" }, + ["Ớ"]={ "Ơ","́" }, + ["ớ"]={ "ơ","́" }, + ["Ờ"]={ "Ơ","̀" }, + ["ờ"]={ "ơ","̀" }, + ["Ở"]={ "Ơ","̉" }, + ["ở"]={ "ơ","̉" }, + ["Ỡ"]={ "Ơ","̃" }, + ["ỡ"]={ "ơ","̃" }, + ["Ợ"]={ "Ơ","̣" }, + ["ợ"]={ "ơ","̣" }, + ["Ụ"]={ "U","̣" }, + ["ụ"]={ "u","̣" }, + ["Ủ"]={ "U","̉" }, + ["ủ"]={ "u","̉" }, + ["Ứ"]={ "Ư","́" }, + ["ứ"]={ "ư","́" }, + ["Ừ"]={ "Ư","̀" }, + ["ừ"]={ "ư","̀" }, + ["Ử"]={ "Ư","̉" }, + ["ử"]={ "ư","̉" }, + ["Ữ"]={ "Ư","̃" }, + ["ữ"]={ "ư","̃" }, + ["Ự"]={ "Ư","̣" }, + ["ự"]={ "ư","̣" }, + ["Ỳ"]={ "Y","̀" }, + ["ỳ"]={ "y","̀" }, + ["Ỵ"]={ "Y","̣" }, + ["ỵ"]={ "y","̣" }, + ["Ỷ"]={ "Y","̉" }, + ["ỷ"]={ "y","̉" }, + ["Ỹ"]={ "Y","̃" }, + ["ỹ"]={ "y","̃" }, + ["ἀ"]={ "α","̓" }, + ["ἁ"]={ "α","̔" }, + ["ἂ"]={ "ἀ","̀" }, + ["ἃ"]={ "ἁ","̀" }, + ["ἄ"]={ "ἀ","́" }, + ["ἅ"]={ "ἁ","́" }, + ["ἆ"]={ "ἀ","͂" }, + ["ἇ"]={ "ἁ","͂" }, + ["Ἀ"]={ "Α","̓" }, + ["Ἁ"]={ "Α","̔" }, + ["Ἂ"]={ "Ἀ","̀" }, + ["Ἃ"]={ "Ἁ","̀" }, + ["Ἄ"]={ "Ἀ","́" }, + ["Ἅ"]={ "Ἁ","́" }, + ["Ἆ"]={ "Ἀ","͂" }, + ["Ἇ"]={ "Ἁ","͂" }, + ["ἐ"]={ "ε","̓" }, + ["ἑ"]={ "ε","̔" }, + ["ἒ"]={ "ἐ","̀" }, + ["ἓ"]={ "ἑ","̀" }, + ["ἔ"]={ "ἐ","́" }, + ["ἕ"]={ "ἑ","́" }, + ["Ἐ"]={ "Ε","̓" }, + ["Ἑ"]={ "Ε","̔" }, + ["Ἒ"]={ "Ἐ","̀" }, + ["Ἓ"]={ "Ἑ","̀" }, + ["Ἔ"]={ "Ἐ","́" }, + ["Ἕ"]={ "Ἑ","́" }, + ["ἠ"]={ "η","̓" }, + ["ἡ"]={ "η","̔" }, + ["ἢ"]={ "ἠ","̀" }, + ["ἣ"]={ "ἡ","̀" }, + ["ἤ"]={ "ἠ","́" }, + ["ἥ"]={ "ἡ","́" }, + ["ἦ"]={ "ἠ","͂" }, + ["ἧ"]={ "ἡ","͂" }, + ["Ἠ"]={ "Η","̓" }, + ["Ἡ"]={ "Η","̔" }, + ["Ἢ"]={ "Ἠ","̀" }, + ["Ἣ"]={ "Ἡ","̀" }, + ["Ἤ"]={ "Ἠ","́" }, + ["Ἥ"]={ "Ἡ","́" }, + ["Ἦ"]={ "Ἠ","͂" }, + ["Ἧ"]={ "Ἡ","͂" }, + ["ἰ"]={ "ι","̓" }, + ["ἱ"]={ "ι","̔" }, + ["ἲ"]={ "ἰ","̀" }, + ["ἳ"]={ "ἱ","̀" }, + ["ἴ"]={ "ἰ","́" }, + ["ἵ"]={ "ἱ","́" }, + ["ἶ"]={ "ἰ","͂" }, + ["ἷ"]={ "ἱ","͂" }, + ["Ἰ"]={ "Ι","̓" }, + ["Ἱ"]={ "Ι","̔" }, + ["Ἲ"]={ "Ἰ","̀" }, + ["Ἳ"]={ "Ἱ","̀" }, + ["Ἴ"]={ "Ἰ","́" }, + ["Ἵ"]={ "Ἱ","́" }, + ["Ἶ"]={ "Ἰ","͂" }, + ["Ἷ"]={ "Ἱ","͂" }, + ["ὀ"]={ "ο","̓" }, + ["ὁ"]={ "ο","̔" }, + ["ὂ"]={ "ὀ","̀" }, + ["ὃ"]={ "ὁ","̀" }, + ["ὄ"]={ "ὀ","́" }, + ["ὅ"]={ "ὁ","́" }, + ["Ὀ"]={ "Ο","̓" }, + ["Ὁ"]={ "Ο","̔" }, + ["Ὂ"]={ "Ὀ","̀" }, + ["Ὃ"]={ "Ὁ","̀" }, + ["Ὄ"]={ "Ὀ","́" }, + ["Ὅ"]={ "Ὁ","́" }, + ["ὐ"]={ "υ","̓" }, + ["ὑ"]={ "υ","̔" }, + ["ὒ"]={ "ὐ","̀" }, + ["ὓ"]={ "ὑ","̀" }, + ["ὔ"]={ "ὐ","́" }, + ["ὕ"]={ "ὑ","́" }, + ["ὖ"]={ "ὐ","͂" }, + ["ὗ"]={ "ὑ","͂" }, + ["Ὑ"]={ "Υ","̔" }, + ["Ὓ"]={ "Ὑ","̀" }, + ["Ὕ"]={ "Ὑ","́" }, + ["Ὗ"]={ "Ὑ","͂" }, + ["ὠ"]={ "ω","̓" }, + ["ὡ"]={ "ω","̔" }, + ["ὢ"]={ "ὠ","̀" }, + ["ὣ"]={ "ὡ","̀" }, + ["ὤ"]={ "ὠ","́" }, + ["ὥ"]={ "ὡ","́" }, + ["ὦ"]={ "ὠ","͂" }, + ["ὧ"]={ "ὡ","͂" }, + ["Ὠ"]={ "Ω","̓" }, + ["Ὡ"]={ "Ω","̔" }, + ["Ὢ"]={ "Ὠ","̀" }, + ["Ὣ"]={ "Ὡ","̀" }, + ["Ὤ"]={ "Ὠ","́" }, + ["Ὥ"]={ "Ὡ","́" }, + ["Ὦ"]={ "Ὠ","͂" }, + ["Ὧ"]={ "Ὡ","͂" }, + ["ὰ"]={ "α","̀" }, + ["ὲ"]={ "ε","̀" }, + ["ὴ"]={ "η","̀" }, + ["ὶ"]={ "ι","̀" }, + ["ὸ"]={ "ο","̀" }, + ["ὺ"]={ "υ","̀" }, + ["ὼ"]={ "ω","̀" }, + ["ᾀ"]={ "ἀ","ͅ" }, + ["ᾁ"]={ "ἁ","ͅ" }, + ["ᾂ"]={ "ἂ","ͅ" }, + ["ᾃ"]={ "ἃ","ͅ" }, + ["ᾄ"]={ "ἄ","ͅ" }, + ["ᾅ"]={ "ἅ","ͅ" }, + ["ᾆ"]={ "ἆ","ͅ" }, + ["ᾇ"]={ "ἇ","ͅ" }, + ["ᾈ"]={ "Ἀ","ͅ" }, + ["ᾉ"]={ "Ἁ","ͅ" }, + ["ᾊ"]={ "Ἂ","ͅ" }, + ["ᾋ"]={ "Ἃ","ͅ" }, + ["ᾌ"]={ "Ἄ","ͅ" }, + ["ᾍ"]={ "Ἅ","ͅ" }, + ["ᾎ"]={ "Ἆ","ͅ" }, + ["ᾏ"]={ "Ἇ","ͅ" }, + ["ᾐ"]={ "ἠ","ͅ" }, + ["ᾑ"]={ "ἡ","ͅ" }, + ["ᾒ"]={ "ἢ","ͅ" }, + ["ᾓ"]={ "ἣ","ͅ" }, + ["ᾔ"]={ "ἤ","ͅ" }, + ["ᾕ"]={ "ἥ","ͅ" }, + ["ᾖ"]={ "ἦ","ͅ" }, + ["ᾗ"]={ "ἧ","ͅ" }, + ["ᾘ"]={ "Ἠ","ͅ" }, + ["ᾙ"]={ "Ἡ","ͅ" }, + ["ᾚ"]={ "Ἢ","ͅ" }, + ["ᾛ"]={ "Ἣ","ͅ" }, + ["ᾜ"]={ "Ἤ","ͅ" }, + ["ᾝ"]={ "Ἥ","ͅ" }, + ["ᾞ"]={ "Ἦ","ͅ" }, + ["ᾟ"]={ "Ἧ","ͅ" }, + ["ᾠ"]={ "ὠ","ͅ" }, + ["ᾡ"]={ "ὡ","ͅ" }, + ["ᾢ"]={ "ὢ","ͅ" }, + ["ᾣ"]={ "ὣ","ͅ" }, + ["ᾤ"]={ "ὤ","ͅ" }, + ["ᾥ"]={ "ὥ","ͅ" }, + ["ᾦ"]={ "ὦ","ͅ" }, + ["ᾧ"]={ "ὧ","ͅ" }, + ["ᾨ"]={ "Ὠ","ͅ" }, + ["ᾩ"]={ "Ὡ","ͅ" }, + ["ᾪ"]={ "Ὢ","ͅ" }, + ["ᾫ"]={ "Ὣ","ͅ" }, + ["ᾬ"]={ "Ὤ","ͅ" }, + ["ᾭ"]={ "Ὥ","ͅ" }, + ["ᾮ"]={ "Ὦ","ͅ" }, + ["ᾯ"]={ "Ὧ","ͅ" }, + ["ᾰ"]={ "α","̆" }, + ["ᾱ"]={ "α","̄" }, + ["ᾲ"]={ "ὰ","ͅ" }, + ["ᾳ"]={ "α","ͅ" }, + ["ᾴ"]={ "ά","ͅ" }, + ["ᾶ"]={ "α","͂" }, + ["ᾷ"]={ "ᾶ","ͅ" }, + ["Ᾰ"]={ "Α","̆" }, + ["Ᾱ"]={ "Α","̄" }, + ["Ὰ"]={ "Α","̀" }, + ["ᾼ"]={ "Α","ͅ" }, + ["῁"]={ "¨","͂" }, + ["ῂ"]={ "ὴ","ͅ" }, + ["ῃ"]={ "η","ͅ" }, + ["ῄ"]={ "ή","ͅ" }, + ["ῆ"]={ "η","͂" }, + ["ῇ"]={ "ῆ","ͅ" }, + ["Ὲ"]={ "Ε","̀" }, + ["Ὴ"]={ "Η","̀" }, + ["ῌ"]={ "Η","ͅ" }, + ["῍"]={ "᾿","̀" }, + ["῎"]={ "᾿","́" }, + ["῏"]={ "᾿","͂" }, + ["ῐ"]={ "ι","̆" }, + ["ῑ"]={ "ι","̄" }, + ["ῒ"]={ "ϊ","̀" }, + ["ῖ"]={ "ι","͂" }, + ["ῗ"]={ "ϊ","͂" }, + ["Ῐ"]={ "Ι","̆" }, + ["Ῑ"]={ "Ι","̄" }, + ["Ὶ"]={ "Ι","̀" }, + ["῝"]={ "῾","̀" }, + ["῞"]={ "῾","́" }, + ["῟"]={ "῾","͂" }, + ["ῠ"]={ "υ","̆" }, + ["ῡ"]={ "υ","̄" }, + ["ῢ"]={ "ϋ","̀" }, + ["ῤ"]={ "ρ","̓" }, + ["ῥ"]={ "ρ","̔" }, + ["ῦ"]={ "υ","͂" }, + ["ῧ"]={ "ϋ","͂" }, + ["Ῠ"]={ "Υ","̆" }, + ["Ῡ"]={ "Υ","̄" }, + ["Ὺ"]={ "Υ","̀" }, + ["Ῥ"]={ "Ρ","̔" }, + ["῭"]={ "¨","̀" }, + ["ῲ"]={ "ὼ","ͅ" }, + ["ῳ"]={ "ω","ͅ" }, + ["ῴ"]={ "ώ","ͅ" }, + ["ῶ"]={ "ω","͂" }, + ["ῷ"]={ "ῶ","ͅ" }, + ["Ὸ"]={ "Ο","̀" }, + ["Ὼ"]={ "Ω","̀" }, + ["ῼ"]={ "Ω","ͅ" }, + ["↚"]={ "←","̸" }, + ["↛"]={ "→","̸" }, + ["↮"]={ "↔","̸" }, + ["⇍"]={ "⇐","̸" }, + ["⇎"]={ "⇔","̸" }, + ["⇏"]={ "⇒","̸" }, + ["∄"]={ "∃","̸" }, + ["∉"]={ "∈","̸" }, + ["∌"]={ "∋","̸" }, + ["∤"]={ "∣","̸" }, + ["∦"]={ "∥","̸" }, + ["≁"]={ "∼","̸" }, + ["≄"]={ "≃","̸" }, + ["≇"]={ "≅","̸" }, + ["≉"]={ "≈","̸" }, + ["≠"]={ "=","̸" }, + ["≢"]={ "≡","̸" }, + ["≭"]={ "≍","̸" }, + ["≮"]={ "<","̸" }, + ["≯"]={ ">","̸" }, + ["≰"]={ "≤","̸" }, + ["≱"]={ "≥","̸" }, + ["≴"]={ "≲","̸" }, + ["≵"]={ "≳","̸" }, + ["≸"]={ "≶","̸" }, + ["≹"]={ "≷","̸" }, + ["⊀"]={ "≺","̸" }, + ["⊁"]={ "≻","̸" }, + ["⊄"]={ "⊂","̸" }, + ["⊅"]={ "⊃","̸" }, + ["⊈"]={ "⊆","̸" }, + ["⊉"]={ "⊇","̸" }, + ["⊬"]={ "⊢","̸" }, + ["⊭"]={ "⊨","̸" }, + ["⊮"]={ "⊩","̸" }, + ["⊯"]={ "⊫","̸" }, + ["⋠"]={ "≼","̸" }, + ["⋡"]={ "≽","̸" }, + ["⋢"]={ "⊑","̸" }, + ["⋣"]={ "⊒","̸" }, + ["⋪"]={ "⊲","̸" }, + ["⋫"]={ "⊳","̸" }, + ["⋬"]={ "⊴","̸" }, + ["⋭"]={ "⊵","̸" }, + ["⫝̸"]={ "⫝","̸" }, + ["が"]={ "か","゙" }, + ["ぎ"]={ "き","゙" }, + ["ぐ"]={ "く","゙" }, + ["げ"]={ "け","゙" }, + ["ご"]={ "こ","゙" }, + ["ざ"]={ "さ","゙" }, + ["じ"]={ "し","゙" }, + ["ず"]={ "す","゙" }, + ["ぜ"]={ "せ","゙" }, + ["ぞ"]={ "そ","゙" }, + ["だ"]={ "た","゙" }, + ["ぢ"]={ "ち","゙" }, + ["づ"]={ "つ","゙" }, + ["で"]={ "て","゙" }, + ["ど"]={ "と","゙" }, + ["ば"]={ "は","゙" }, + ["ぱ"]={ "は","゚" }, + ["び"]={ "ひ","゙" }, + ["ぴ"]={ "ひ","゚" }, + ["ぶ"]={ "ふ","゙" }, + ["ぷ"]={ "ふ","゚" }, + ["べ"]={ "へ","゙" }, + ["ぺ"]={ "へ","゚" }, + ["ぼ"]={ "ほ","゙" }, + ["ぽ"]={ "ほ","゚" }, + ["ゔ"]={ "う","゙" }, + ["ゞ"]={ "ゝ","゙" }, + ["ガ"]={ "カ","゙" }, + ["ギ"]={ "キ","゙" }, + ["グ"]={ "ク","゙" }, + ["ゲ"]={ "ケ","゙" }, + ["ゴ"]={ "コ","゙" }, + ["ザ"]={ "サ","゙" }, + ["ジ"]={ "シ","゙" }, + ["ズ"]={ "ス","゙" }, + ["ゼ"]={ "セ","゙" }, + ["ゾ"]={ "ソ","゙" }, + ["ダ"]={ "タ","゙" }, + ["ヂ"]={ "チ","゙" }, + ["ヅ"]={ "ツ","゙" }, + ["デ"]={ "テ","゙" }, + ["ド"]={ "ト","゙" }, + ["バ"]={ "ハ","゙" }, + ["パ"]={ "ハ","゚" }, + ["ビ"]={ "ヒ","゙" }, + ["ピ"]={ "ヒ","゚" }, + ["ブ"]={ "フ","゙" }, + ["プ"]={ "フ","゚" }, + ["ベ"]={ "ヘ","゙" }, + ["ペ"]={ "ヘ","゚" }, + ["ボ"]={ "ホ","゙" }, + ["ポ"]={ "ホ","゚" }, + ["ヴ"]={ "ウ","゙" }, + ["ヷ"]={ "ワ","゙" }, + ["ヸ"]={ "ヰ","゙" }, + ["ヹ"]={ "ヱ","゙" }, + ["ヺ"]={ "ヲ","゙" }, + ["ヾ"]={ "ヽ","゙" }, + ["יִ"]={ "י","ִ" }, + ["ײַ"]={ "ײ","ַ" }, + ["שׁ"]={ "ש","ׁ" }, + ["שׂ"]={ "ש","ׂ" }, + ["שּׁ"]={ "שּ","ׁ" }, + ["שּׂ"]={ "שּ","ׂ" }, + ["אַ"]={ "א","ַ" }, + ["אָ"]={ "א","ָ" }, + ["אּ"]={ "א","ּ" }, + ["בּ"]={ "ב","ּ" }, + ["גּ"]={ "ג","ּ" }, + ["דּ"]={ "ד","ּ" }, + ["הּ"]={ "ה","ּ" }, + ["וּ"]={ "ו","ּ" }, + ["זּ"]={ "ז","ּ" }, + ["טּ"]={ "ט","ּ" }, + ["יּ"]={ "י","ּ" }, + ["ךּ"]={ "ך","ּ" }, + ["כּ"]={ "כ","ּ" }, + ["לּ"]={ "ל","ּ" }, + ["מּ"]={ "מ","ּ" }, + ["נּ"]={ "נ","ּ" }, + ["סּ"]={ "ס","ּ" }, + ["ףּ"]={ "ף","ּ" }, + ["פּ"]={ "פ","ּ" }, + ["צּ"]={ "צ","ּ" }, + ["קּ"]={ "ק","ּ" }, + ["רּ"]={ "ר","ּ" }, + ["שּ"]={ "ש","ּ" }, + ["תּ"]={ "ת","ּ" }, + ["וֹ"]={ "ו","ֹ" }, + ["בֿ"]={ "ב","ֿ" }, + ["כֿ"]={ "כ","ֿ" }, + ["פֿ"]={ "פ","ֿ" }, + ["𑂚"]={ "𑂙","𑂺" }, + ["𑂜"]={ "𑂛","𑂺" }, + ["𑂫"]={ "𑂥","𑂺" }, + ["𑄮"]={ "𑄱","𑄧" }, + ["𑄯"]={ "𑄲","𑄧" }, + ["𑍋"]={ "𑍇","𑌾" }, + ["𑍌"]={ "𑍇","𑍗" }, + ["𑒻"]={ "𑒹","𑒺" }, + ["𑒼"]={ "𑒹","𑒰" }, + ["𑒾"]={ "𑒹","𑒽" }, + ["𑖺"]={ "𑖸","𑖯" }, + ["𑖻"]={ "𑖹","𑖯" }, + ["𝅗𝅥"]={ "𝅗","𝅥" }, + ["𝅘𝅥"]={ "𝅘","𝅥" }, + ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" }, + ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" }, + ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" }, + ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" }, + ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" }, + ["𝆹𝅥"]={ "𝆹","𝅥" }, + ["𝆺𝅥"]={ "𝆺","𝅥" }, + ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" }, + ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" }, + ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" }, + ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" }, + }, + }, + }, + ["name"]="collapse", + ["prepend"]=true, + ["type"]="ligature", +} + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “fonts-lig”] --- + + +do --- [luaotfload, fontloader-2021-01-07.lua scope for “fonts-gbn” 10ecdf01e7c926e5128ad8a9dff4d677] --- + +if not modules then modules={} end modules ['luatex-fonts-gbn']={ + version=1.001, + comment="companion to luatex-*.tex", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +if context then + os.exit() +end +local next=next +local fonts=fonts +local nodes=nodes +local nuts=nodes.nuts +local traverse_id=nuts.traverse_id +local flush_node=nuts.flush_node +local glyph_code=nodes.nodecodes.glyph +local disc_code=nodes.nodecodes.disc +local tonode=nuts.tonode +local tonut=nuts.tonut +local getfont=nuts.getfont +local getchar=nuts.getchar +local getid=nuts.getid +local getboth=nuts.getboth +local getprev=nuts.getprev +local getnext=nuts.getnext +local getdisc=nuts.getdisc +local setchar=nuts.setchar +local setlink=nuts.setlink +local setprev=nuts.setprev +local n_ligaturing=node.ligaturing +local n_kerning=node.kerning +local d_ligaturing=nuts.ligaturing +local d_kerning=nuts.kerning +local basemodepass=true +local function l_warning() logs.report("fonts","don't call 'node.ligaturing' directly") l_warning=nil end +local function k_warning() logs.report("fonts","don't call 'node.kerning' directly") k_warning=nil end +function node.ligaturing(...) + if basemodepass and l_warning then + l_warning() + end + return n_ligaturing(...) +end +function node.kerning(...) + if basemodepass and k_warning then + k_warning() + end + return n_kerning(...) +end +function nuts.ligaturing(...) + if basemodepass and l_warning then + l_warning() + end + return d_ligaturing(...) +end +function nuts.kerning(...) + if basemodepass and k_warning then + k_warning() + end + return d_kerning(...) +end +function nodes.handlers.setbasemodepass(v) + basemodepass=v +end +local function nodepass(head,groupcode,size,packtype,direction) + local fontdata=fonts.hashes.identifiers + if fontdata then + local usedfonts={} + local basefonts={} + local prevfont=nil + local basefont=nil + local variants=nil + local redundant=nil + local nofused=0 + for n in traverse_id(glyph_code,head) do + local font=getfont(n) + if font~=prevfont then + if basefont then + basefont[2]=getprev(n) + end + prevfont=font + local used=usedfonts[font] + if not used then + local tfmdata=fontdata[font] + if tfmdata then + local shared=tfmdata.shared + if shared then + local processors=shared.processes + if processors and #processors>0 then + usedfonts[font]=processors + nofused=nofused+1 + elseif basemodepass then + basefont={ n,nil } + basefonts[#basefonts+1]=basefont + end + end + local resources=tfmdata.resources + variants=resources and resources.variants + variants=variants and next(variants) and variants or false + end + else + local tfmdata=fontdata[prevfont] + if tfmdata then + local resources=tfmdata.resources + variants=resources and resources.variants + variants=variants and next(variants) and variants or false + end + end + end + if variants then + local char=getchar(n) + if (char>=0xFE00 and char<=0xFE0F) or (char>=0xE0100 and char<=0xE01EF) then + local hash=variants[char] + if hash then + local p=getprev(n) + if p and getid(p)==glyph_code then + local variant=hash[getchar(p)] + if variant then + setchar(p,variant) + end + end + end + if not redundant then + redundant={ n } + else + redundant[#redundant+1]=n + end + end + end + end + local nofbasefonts=#basefonts + if redundant then + for i=1,#redundant do + local r=redundant[i] + local p,n=getboth(r) + if r==head then + head=n + setprev(n) + else + setlink(p,n) + end + if nofbasefonts>0 then + for i=1,nofbasefonts do + local bi=basefonts[i] + if r==bi[1] then + bi[1]=n + end + if r==bi[2] then + bi[2]=n + end + end + end + flush_node(r) + end + end + for d in traverse_id(disc_code,head) do + local _,_,r=getdisc(d) + if r then + for n in traverse_id(glyph_code,r) do + local font=getfont(n) + if font~=prevfont then + prevfont=font + local used=usedfonts[font] + if not used then + local tfmdata=fontdata[font] + if tfmdata then + local shared=tfmdata.shared + if shared then + local processors=shared.processes + if processors and #processors>0 then + usedfonts[font]=processors + nofused=nofused+1 + end + end + end + end + end + end + end + end + if next(usedfonts) then + for font,processors in next,usedfonts do + for i=1,#processors do + head=processors[i](head,font,0,direction,nofused) or head + end + end + end + if basemodepass and nofbasefonts>0 then + for i=1,nofbasefonts do + local range=basefonts[i] + local start=range[1] + local stop=range[2] + if start then + local front=head==start + local prev,next + if stop then + next=getnext(stop) + start,stop=d_ligaturing(start,stop) + start,stop=d_kerning(start,stop) + else + prev=getprev(start) + start=d_ligaturing(start) + start=d_kerning(start) + end + if prev then + setlink(prev,start) + end + if next then + setlink(stop,next) + end + if front and head~=start then + head=start + end + end + end + end + end + return head +end +local function basepass(head) + if basemodepass then + head=d_ligaturing(head) + head=d_kerning(head) + end + return head +end +local protectpass=node.direct.protect_glyphs +local injectpass=nodes.injections.handler +function nodes.handlers.nodepass(head,...) + if head then + return tonode(nodepass(tonut(head),...)) + end +end +function nodes.handlers.basepass(head) + if head then + return tonode(basepass(tonut(head))) + end +end +function nodes.handlers.injectpass(head) + if head then + return tonode(injectpass(tonut(head))) + end +end +function nodes.handlers.protectpass(head) + if head then + protectpass(tonut(head)) + return head + end +end +function nodes.simple_font_handler(head,groupcode,size,packtype,direction) + if head then + head=tonut(head) + head=nodepass(head,groupcode,size,packtype,direction) + head=injectpass(head) + if not basemodepass then + head=basepass(head) + end + protectpass(head) + head=tonode(head) + end + return head +end + +end --- [luaotfload, fontloader-2021-01-07.lua scope for “fonts-gbn”] --- + + +--- vim:ft=lua:sw=2:ts=8:et:tw=79 diff --git a/macros/luatex/generic/luaotfload/fontloader-font-cff.lua b/macros/luatex/generic/luaotfload/fontloader-font-cff.lua index b7d45392d6..4e2981011a 100644 --- a/macros/luatex/generic/luaotfload/fontloader-font-cff.lua +++ b/macros/luatex/generic/luaotfload/fontloader-font-cff.lua @@ -1425,13 +1425,15 @@ do -- to wrap my head around the rather complex variable font specification -- with regions and axis, the following approach kind of works but is more -- some trial and error trick. It's still not clear how much of the complex - -- truetype description applies to cff. + -- truetype description applies to cff. Once there are fonts out there we'll + -- get there. (Marcel and friends did some tests with recent cff2 fonts so + -- the code has been adapted accordingly.) local reginit = false local function updateregions(n) -- n + 1 if regions then - local current = regions[n] or regions[1] + local current = regions[n+1] or regions[1] nofregions = #current if axis and n ~= reginit then factors = { } @@ -2155,7 +2157,14 @@ do popped = 3 seacs = { } if regions then - regions = { regions } -- needs checking + -- this was: + -- regions = { regions } -- needs checking + -- and is now (MFC): + regions = { } + local deltas = data.deltas + for i = 1, #deltas do + regions[i] = deltas[i].regions + end axis = data.factors or false end end diff --git a/macros/luatex/generic/luaotfload/fontloader-font-con.lua b/macros/luatex/generic/luaotfload/fontloader-font-con.lua index 7162338c66..f650e5b03d 100644 --- a/macros/luatex/generic/luaotfload/fontloader-font-con.lua +++ b/macros/luatex/generic/luaotfload/fontloader-font-con.lua @@ -600,13 +600,17 @@ function constructors.scale(tfmdata,specification) -- if hasmath then constructors.assignmathparameters(target,tfmdata) -- does scaling and whatever is needed - properties.hasmath = true - target.nomath = false - target.MathConstants = target.mathparameters + properties.hasmath = true + target.nomath = false + target.MathConstants = target.mathparameters + -- + local oldmath = properties.oldmath + targetproperties.oldmath = oldmath + target.oldmath = oldmath else - properties.hasmath = false - target.nomath = true - target.mathparameters = nil -- nop + properties.hasmath = false + target.nomath = true + target.mathparameters = nil -- nop end -- -- Here we support some context specific trickery (this might move to a plugin). During the diff --git a/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua b/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua index 91ee83b19b..8d7c3d359d 100644 --- a/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua +++ b/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua @@ -503,7 +503,7 @@ local function readvariationdata(f,storeoffset,factors) -- store regions[i] = t end -- deltas - if factors then + -- if factors then for i=1,nofdeltadata do setposition(f,storeoffset+deltadata[i]) local nofdeltasets = readushort(f) @@ -528,7 +528,7 @@ local function readvariationdata(f,storeoffset,factors) -- store scales = factors and getscales(usedregions,factors) or nil, } end - end + -- end setposition(f,position) return regions, deltadata end diff --git a/macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua b/macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua index 3e172bedee..6c432d7cf4 100644 --- a/macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua +++ b/macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua @@ -79,24 +79,6 @@ if context then registerotffeature(specification) registerafmfeature(specification) - -- no longer used - - -- local function initializemathitalics(tfmdata,value) -- yes no delay - -- tfmdata.properties.mathitalics = toboolean(value) - -- end - -- - -- local specification = { - -- name = "mathitalics", - -- description = "use alternative math italic correction", - -- initializers = { - -- base = initializemathitalics, - -- node = initializemathitalics, - -- } - -- } - -- - -- registerotffeature(specification) - -- registerafmfeature(specification) - -- only used when testing local letter = characters.is_letter diff --git a/macros/luatex/generic/luaotfload/fontloader-font-otl.lua b/macros/luatex/generic/luaotfload/fontloader-font-otl.lua index b8e13f1070..19de2bb777 100644 --- a/macros/luatex/generic/luaotfload/fontloader-font-otl.lua +++ b/macros/luatex/generic/luaotfload/fontloader-font-otl.lua @@ -52,7 +52,7 @@ local report_otf = logs.reporter("fonts","otf loading") local fonts = fonts local otf = fonts.handlers.otf -otf.version = 3.112 -- beware: also sync font-mis.lua and in mtx-fonts +otf.version = 3.113 -- beware: also sync font-mis.lua and in mtx-fonts otf.cache = containers.define("fonts", "otl", otf.version, true) otf.svgcache = containers.define("fonts", "svg", otf.version, true) otf.pngcache = containers.define("fonts", "png", otf.version, true) diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ots.lua b/macros/luatex/generic/luaotfload/fontloader-font-ots.lua index 1f4806ee25..880bcb6d50 100644 --- a/macros/luatex/generic/luaotfload/fontloader-font-ots.lua +++ b/macros/luatex/generic/luaotfload/fontloader-font-ots.lua @@ -829,6 +829,9 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip -- of{f-}{}{f}e o{f-}{}{f}fe o{-}{}{ff}e (oe and ff ligature) -- we can end up here when we have a start run .. testruns start at a disc but -- so here we have the other case: char + disc + -- + -- Challenge for Kai (latinmodern): \hyphenation{fii-f-f-iif} fiiffiif + -- if discfound then -- don't assume marks in a disc and we don't run over a disc (for now) local pre, post, replace = getdisc(discfound) diff --git a/macros/luatex/generic/luaotfload/fontloader-reference.lua b/macros/luatex/generic/luaotfload/fontloader-reference.lua index 0b220327c3..dde25ac75d 100644 --- a/macros/luatex/generic/luaotfload/fontloader-reference.lua +++ b/macros/luatex/generic/luaotfload/fontloader-reference.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 2020-12-30 16:42 +-- merge date : 2021-01-07 16:56 do -- begin closure to overcome local limits and interference @@ -9268,6 +9268,9 @@ function constructors.scale(tfmdata,specification) properties.hasmath=true target.nomath=false target.MathConstants=target.mathparameters + local oldmath=properties.oldmath + targetproperties.oldmath=oldmath + target.oldmath=oldmath else properties.hasmath=false target.nomath=true @@ -14016,7 +14019,7 @@ do local reginit=false local function updateregions(n) if regions then - local current=regions[n] or regions[1] + local current=regions[n+1] or regions[1] nofregions=#current if axis and n~=reginit then factors={} @@ -14585,7 +14588,11 @@ do popped=3 seacs={} if regions then - regions={ regions } + regions={} + local deltas=data.deltas + for i=1,#deltas do + regions[i]=deltas[i].regions + end axis=data.factors or false end end @@ -16570,7 +16577,6 @@ local function readvariationdata(f,storeoffset,factors) end regions[i]=t end - if factors then for i=1,nofdeltadata do setposition(f,storeoffset+deltadata[i]) local nofdeltasets=readushort(f) @@ -16594,7 +16600,6 @@ local function readvariationdata(f,storeoffset,factors) scales=factors and getscales(usedregions,factors) or nil, } end - end setposition(f,position) return regions,deltadata end @@ -20779,7 +20784,7 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_d local report_otf=logs.reporter("fonts","otf loading") local fonts=fonts local otf=fonts.handlers.otf -otf.version=3.112 +otf.version=3.113 otf.cache=containers.define("fonts","otl",otf.version,true) otf.svgcache=containers.define("fonts","svg",otf.version,true) otf.pngcache=containers.define("fonts","png",otf.version,true) diff --git a/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua b/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua index 2d4e757bc0..fcbd644158 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua @@ -6,8 +6,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-auxiliary", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / auxiliary functions", license = "GPL v2.0" } diff --git a/macros/luatex/generic/luaotfload/luaotfload-case-el.lua b/macros/luatex/generic/luaotfload/luaotfload-case-el.lua new file mode 100644 index 0000000000..1b329c4a65 --- /dev/null +++ b/macros/luatex/generic/luaotfload/luaotfload-case-el.lua @@ -0,0 +1,294 @@ +local unicode_data = require'luaotfload-unicode' + +local has_accent = 1 +local has_combining_dialytika = 2 +local has_ypogegrammeni = 4 +local has_other_diacritic = 8 +local has_vowel = 16 +local vowels = { + [0x03B1] = true, + [0x0391] = true, + [0x03B5] = true, + [0x0395] = true, + [0x03B7] = true, + [0x0397] = true, + [0x03B9] = true, + [0x0399] = true, + [0x03BF] = true, + [0x039F] = true, + [0x03C9] = true, + [0x03A9] = true, + [0x03C5] = true, + [0x03A5] = true, + [0x03F5] = true, +} +local diacritic_data = { + [0x0300] = has_accent, + [0x0301] = has_accent, + [0x0302] = has_accent, + [0x0303] = has_accent, + [0x0311] = has_accent, + [0x0342] = has_accent, + [0x0308] = has_combining_dialytika, + [0x0344] = has_accent | has_combining_dialytika, + [0x0345] = has_ypogegrammeni, + [0x0304] = has_other_diacritic, + [0x0306] = has_other_diacritic, + [0x0313] = has_other_diacritic, + [0x0314] = has_other_diacritic, + [0x0343] = has_other_diacritic, +} + +local mapping_tables = unicode_data.casemapping +local soft_dotted = unicode_data.soft_dotted +local ccc = unicode_data.ccc + +local uppercase = mapping_tables.uppercase +local lowercase = mapping_tables.lowercase +local cased = mapping_tables.cased +local case_ignorable = mapping_tables.case_ignorable + +local otfregister = fonts.constructors.features.otf.register + +local direct = node.direct +local is_char = direct.is_char +local has_glyph = direct.has_glyph +local uses_font = direct.uses_font +local getnext = direct.getnext +local setchar = direct.setchar +local setdisc = direct.setdisc +local getdisc = direct.getdisc +local getfield = direct.getfield +local remove = direct.remove +local copy = direct.copy +local insert_after = direct.insert_after +local traverse = direct.traverse + +local disc = node.id'disc' + +local nfd = {} -- FIXME: Data + +local data do + for cp = 1, 0xFF, 1 do -- FIXME: Correct limits + local decomposed = nfd[cp] + local first = decomposed and decomposed[1] or cp + local upper = uppercase[first] + local data = vowels[first] and has_vowel or 0 + if decomposed then + for i=1, #decomposed do + data = data | (diacritic_data[decomposed[i]] or 0) + end + end + end +end + +--[[ We make some implicit assumptions about contexts in SpecialCasing.txt here which happened to be true when I wrote the code: +-- +-- * Before_Dot only appears as Not_Before_Dot +-- * No other context appears with Not_ +-- * Final_Sigma is never language dependent +-- * Other contexts are always language dependent +-- * The only languages with special mappings are Lithuanian (lt/"LTH "/lit), Turkish (tr/"TRK "/tur), and Azeri/Azerbaijani (az/"AZE "/aze) +]] + +local font_lang = setmetatable({}, {__index = function(t, fid) + local f = font.getfont(fid) + local lang = f.specification.features.normal.language + lang = lang == 'lth' and 'lt' or lang == 'trk' and 'tr' or lang == 'aze' and 'az' or false + t[fid] = lang + return lang +end}) + +local function is_Final_Sigma(font, mapping, n, after) + mapping = mapping.Final_Sigma + if not mapping then return false end + mapping = mapping._ + if not mapping then return false end + n = getnext(n) + repeat + while n do + local char, id = is_char(n, font) + if id == disc then + after = getnext(n) + n = getfield(n, 'replace') + char, id = is_char(n, font) + elseif char then + if not case_ignorable[char] then + return not cased[char] and mapping + end + n = getnext(n) + else + return mapping + end + end + n, after = after + until not n + return mapping +end + +local function is_More_Above(font, mapping, n, after) + mapping = mapping.More_Above + if not mapping then return false end + mapping = mapping._ + if not mapping then return false end + n = getnext(n) + repeat + while n do + local char, id = is_char(n, font) + if id == disc then + after = getnext(n) + n = getfield(n, 'replace') + char, id = is_char(n, font) + elseif char then + local char_ccc = ccc[char] + if not char_ccc then + return false + elseif char_ccc == 230 then + return mapping + end + n = getnext(n) + else + return false + end + end + n, after = after + until not n + return false +end + +local function is_Not_Before_Dot(font, mapping, n, after) + mapping = mapping.Not_Before_Dot + if not mapping then return false end + mapping = mapping._ + if not mapping then return false end + n = getnext(n) + repeat + while n do + local char, id = is_char(n, font) + if id == disc then + after = getnext(n) + n = getfield(n, 'replace') + char, id = is_char(n, font) + elseif char then + local char_ccc = ccc[char] + if not char_ccc then + return mapping + elseif char_ccc == 230 then + return char ~= 0x0307 and mapping + end + n = getnext(n) + else + return mapping + end + end + n, after = after + until not n + return mapping +end + +local function is_Language_Mapping(font, mapping, n, after, seen_soft_dotted, seen_I) + if not mapping then return false end + if seen_soft_dotted then + local mapping = mapping.After_Soft_Dotted + mapping = mapping and mapping._ + if mapping then + return mapping + end + end + if seen_I then + local mapping = mapping.After_I + mapping = mapping and mapping._ + if mapping then + return mapping + end + end + return is_More_Above(font, mapping, n, after) or is_Not_Before_Dot(font, mapping, n, after) or mapping._ -- Might be nil +end + +local function process(table) + local function processor(head, font, after, seen_cased, seen_soft_dotted, seen_I) + local lang = font_lang[font] + local n = head + while n do + do + local new = has_glyph(n) + if n ~= new then + seen_cased, seen_soft_dotted, seen_I = nil + end + n = new + end + if not n then break end + local char, id = is_char(n, font) + if char then + local mapping = table[char] + if mapping then + if tonumber(mapping) then + setchar(n, mapping) + else + mapping = seen_cased and is_Final_Sigma(font, mapping, n, after) + or lang and is_Language_Mapping(font, mapping[lang], n, after, seen_soft_dotted, seen_I) + or mapping._ + if #mapping == 0 then + head, n = remove(head, n) + goto continue + else + setchar(n, mapping[1]) + for i=2, #mapping do + head, n = insert_after(head, n, copy(n)) + setchar(n, mapping[i]) + end + end + end + end + if not case_ignorable[char] then + seen_cased = cased[char] or nil + end + local char_ccc = ccc[char] + if not char_ccc or char_ccc == 230 then + seen_I = char == 0x49 or nil + seen_soft_dotted = soft_dotted[char] + end + elseif id == disc and uses_font(n, font) then + local pre, post, rep = getdisc(n) + local after = getnext(n) + pre, post, rep, seen_cased, seen_soft_dotted, seen_I = + processor(pre, font, nil, seen_cased, seen_soft_dotted, seen_I), + processor(post, font, after), + processor(rep, font, after, seen_cased, seen_soft_dotted, seen_I) + setdisc(n, pre, post, rep) + else + seen_cased, seen_soft_dotted, seen_I = nil + end + n = getnext(n) + ::continue:: + end + return head, seen_cased, seen_soft_dotted, seen_I + end + return function(head, font) return (processor(head, font)) end +end + +local upper_process = process(uppercase) +otfregister { + name = 'upper', + description = 'Map to uppercase', + default = false, + processors = { + position = 1, + plug = upper_process, + node = upper_process, + base = upper_process, + }, +} + +local lower_process = process(lowercase) +otfregister { + name = 'lower', + description = 'Map to lowercase', + default = false, + processors = { + position = 1, + plug = lower_process, + node = lower_process, + base = lower_process, + }, +} diff --git a/macros/luatex/generic/luaotfload/luaotfload-colors.lua b/macros/luatex/generic/luaotfload/luaotfload-colors.lua index c1f8a63a8e..fb1cbd3487 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-colors.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-colors.lua @@ -5,8 +5,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-colors", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / color", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang, Dohyun Kim, David Carlisle", diff --git a/macros/luatex/generic/luaotfload/luaotfload-conf.pdf b/macros/luatex/generic/luaotfload/luaotfload-conf.pdf index 52137882d4..afb5a2a4f5 100644 Binary files a/macros/luatex/generic/luaotfload/luaotfload-conf.pdf and b/macros/luatex/generic/luaotfload/luaotfload-conf.pdf differ diff --git a/macros/luatex/generic/luaotfload/luaotfload-configuration.lua b/macros/luatex/generic/luaotfload/luaotfload-configuration.lua index e5e1ed24f0..07ac92096d 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-configuration.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-configuration.lua @@ -7,8 +7,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-configuration", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / config file reader", license = "GPL v2.0" } diff --git a/macros/luatex/generic/luaotfload/luaotfload-database.lua b/macros/luatex/generic/luaotfload/luaotfload-database.lua index da2d9965a3..288f4a21b2 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-database.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-database.lua @@ -5,8 +5,8 @@ do -- block to avoid to many local variables error assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-database", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / database", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger", diff --git a/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua b/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua index 366c7c98ec..67970dc4c5 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua @@ -7,8 +7,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-diagnostics", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload-tool submodule / diagnostics", license = "GPL v2.0" } diff --git a/macros/luatex/generic/luaotfload/luaotfload-dvi.lua b/macros/luatex/generic/luaotfload/luaotfload-dvi.lua index 33083045d4..12ca5d7d56 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-dvi.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-dvi.lua @@ -6,8 +6,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-dvi", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / DVI", license = "GPL v2.0", author = "Marcel Krüger", diff --git a/macros/luatex/generic/luaotfload/luaotfload-embolden.lua b/macros/luatex/generic/luaotfload/luaotfload-embolden.lua index 73993eead8..d9f68f4d4d 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-embolden.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-embolden.lua @@ -5,8 +5,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-embolden", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / embolden", license = "GPL v2.0", author = "Marcel Krüger" diff --git a/macros/luatex/generic/luaotfload/luaotfload-fakesc.lua b/macros/luatex/generic/luaotfload/luaotfload-fakesc.lua new file mode 100644 index 0000000000..421f6fd24d --- /dev/null +++ b/macros/luatex/generic/luaotfload/luaotfload-fakesc.lua @@ -0,0 +1,204 @@ +----------------------------------------------------------------------- +-- FILE: luaotfload-fakesc.lua +-- DESCRIPTION: part of luaotfload / fakesc +----------------------------------------------------------------------- + +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { + name = "luaotfload-fakesc", + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE + description = "luaotfload submodule / fakesc", + license = "GPL v2.0", + author = "Marcel Krüger" +} + +local nodenew = node.direct.new +local getfont = font.getfont +local setfont = node.direct.setfont +local getwhd = node.direct.getwhd +local insert_after = node.direct.insert_after +local traverse_char = node.direct.traverse_char +local protect_glyph = node.direct.protect_glyph +local otffeatures = fonts.constructors.newfeatures "otf" + +local sep = lpeg.P' '^0 * ';' * lpeg.P' '^0 +local codepoint = lpeg.S'0123456789ABCDEF'^4/function(c)return tonumber(c, 16)end +local codepoint_range = codepoint * ('..' * codepoint + lpeg.Cc(false)) +local function multirawset(table, key1, key2, value) + for key = key1,(key2 or key1) do + rawset(table, key, value) + end + return table +end +local script_extensions do + local entry = lpeg.Cg(codepoint_range * sep * lpeg.Ct((lpeg.C(lpeg.R'AZ' * lpeg.R'az'^1))^1 * ' ') * '#')^-1 * (1-lpeg.P'\n')^0 * '\n' + local file = lpeg.Cf( + lpeg.Ct'' + * entry^0 + , multirawset) + + local f = io.open(kpse.find_file"ScriptExtensions.txt") + script_extensions = file:match(f:read'*a') + f:close() + for cp,t in next, script_extensions do + for i=1,#t do + t[t[i]] = true + end + end +end +local script_mapping do + -- We could extract these from PropertyValueAliases.txt... + local script_aliases = { + Adlam = "Adlm", Caucasian_Albanian = "Aghb", Ahom = "Ahom", Arabic = "Arab", + Imperial_Aramaic = "Armi", Armenian = "Armn", Avestan = "Avst", + Balinese = "Bali", Bamum = "Bamu", Bassa_Vah = "Bass", Batak = "Batk", + Bengali = "Beng", Bhaiksuki = "Bhks", Bopomofo = "Bopo", Brahmi = "Brah", + Braille = "Brai", Buginese = "Bugi", Buhid = "Buhd", Chakma = "Cakm", + Canadian_Aboriginal = "Cans", Carian = "Cari", Cham = "Cham", + Cherokee = "Cher", Coptic = "Copt", Cypriot = "Cprt", Cyrillic = "Cyrl", + Devanagari = "Deva", Dogra = "Dogr", Deseret = "Dsrt", Duployan = "Dupl", + Egyptian_Hieroglyphs = "Egyp", Elbasan = "Elba", Elymaic = "Elym", + Ethiopic = "Ethi", Georgian = "Geor", Glagolitic = "Glag", + Gunjala_Gondi = "Gong", Masaram_Gondi = "Gonm", Gothic = "Goth", + Grantha = "Gran", Greek = "Grek", Gujarati = "Gujr", Gurmukhi = "Guru", + Hangul = "Hang", Han = "Hani", Hanunoo = "Hano", Hatran = "Hatr", + Hebrew = "Hebr", Hiragana = "Hira", Anatolian_Hieroglyphs = "Hluw", + Pahawh_Hmong = "Hmng", Nyiakeng_Puachue_Hmong = "Hmnp", + Katakana_Or_Hiragana = "Hrkt", Old_Hungarian = "Hung", Old_Italic = "Ital", + Javanese = "Java", Kayah_Li = "Kali", Katakana = "Kana", + Kharoshthi = "Khar", Khmer = "Khmr", Khojki = "Khoj", Kannada = "Knda", + Kaithi = "Kthi", Tai_Tham = "Lana", Lao = "Laoo", Latin = "Latn", + Lepcha = "Lepc", Limbu = "Limb", Linear_A = "Lina", Linear_B = "Linb", + Lisu = "Lisu", Lycian = "Lyci", Lydian = "Lydi", Mahajani = "Mahj", + Makasar = "Maka", Mandaic = "Mand", Manichaean = "Mani", Marchen = "Marc", + Medefaidrin = "Medf", Mende_Kikakui = "Mend", Meroitic_Cursive = "Merc", + Meroitic_Hieroglyphs = "Mero", Malayalam = "Mlym", Modi = "Modi", + Mongolian = "Mong", Mro = "Mroo", Meetei_Mayek = "Mtei", Multani = "Mult", + Myanmar = "Mymr", Nandinagari = "Nand", Old_North_Arabian = "Narb", + Nabataean = "Nbat", Newa = "Newa", Nko = "Nkoo", Nushu = "Nshu", + Ogham = "Ogam", Ol_Chiki = "Olck", Old_Turkic = "Orkh", Oriya = "Orya", + Osage = "Osge", Osmanya = "Osma", Palmyrene = "Palm", Pau_Cin_Hau = "Pauc", + Old_Permic = "Perm", Phags_Pa = "Phag", Inscriptional_Pahlavi = "Phli", + Psalter_Pahlavi = "Phlp", Phoenician = "Phnx", Miao = "Plrd", + Inscriptional_Parthian = "Prti", Rejang = "Rjng", Hanifi_Rohingya = "Rohg", + Runic = "Runr", Samaritan = "Samr", Old_South_Arabian = "Sarb", + Saurashtra = "Saur", SignWriting = "Sgnw", Shavian = "Shaw", + Sharada = "Shrd", Siddham = "Sidd", Khudawadi = "Sind", Sinhala = "Sinh", + Sogdian = "Sogd", Old_Sogdian = "Sogo", Sora_Sompeng = "Sora", + Soyombo = "Soyo", Sundanese = "Sund", Syloti_Nagri = "Sylo", + Syriac = "Syrc", Tagbanwa = "Tagb", Takri = "Takr", Tai_Le = "Tale", + New_Tai_Lue = "Talu", Tamil = "Taml", Tangut = "Tang", Tai_Viet = "Tavt", + Telugu = "Telu", Tifinagh = "Tfng", Tagalog = "Tglg", Thaana = "Thaa", + Thai = "Thai", Tibetan = "Tibt", Tirhuta = "Tirh", Ugaritic = "Ugar", + Vai = "Vaii", Warang_Citi = "Wara", Wancho = "Wcho", Old_Persian = "Xpeo", + Cuneiform = "Xsux", Yi = "Yiii", Zanabazar_Square = "Zanb", + Inherited = "Zinh", Common = "Zyyy", Unknown = "Zzzz", + } + local entry = lpeg.Cg(codepoint_range * sep * ((lpeg.R'AZ' + lpeg.R'az' + '_')^1/script_aliases))^-1 * (1-lpeg.P'\n')^0 * '\n' + -- local entry = lpeg.Cg(codepoint_range * sep * lpeg.Cc(true))^-1 * (1-lpeg.P'\n')^0 * '\n' + local file = lpeg.Cf( + lpeg.Ct'' + * entry^0 + , multirawset) + + local f = io.open(kpse.find_file"Scripts.txt") + script_mapping = file:match(f:read'*a') + f:close() +end + +local additional_scripts_tables = { } + +local additional_scripts_fonts = setmetatable({}, { + __index = function(t, fid) + local f = font.getfont(fid) + -- table.tofile('myfont2', f) + local res = f and f.additional_scripts or false + t[fid] = res + return res + end, +}) + +local function makecombifont(tfmdata, _, additional_scripts) + local basescript = tfmdata.properties.script + local scripts = {basescript = false} + additional_scripts = additional_scripts_tables[additional_scripts] + for script, fontname in pairs(additional_scripts) do + if script ~= basescript then + local f = fonts.definers.read(fontname, tfmdata.size) + local fid + if type(f) == 'table' then + fid = font.define(f) + else + error[[FIXME???]] + end + scripts[script] = { + fid = fid, + font = f, + characters = f.characters, + } + end + end + tfmdata.additional_scripts = scripts +end + +local glyph_id = node.id'glyph' +-- TODO: unset last_script, matching parentheses etc +function domultiscript(head, _, _, _, direction) + head = node.direct.todirect(head) + local last_fid, last_fonts, last_script + for cur, cid, fid in traverse_char(head) do + if fid ~= last_fid then + last_fid, last_fonts, last_script = fid, additional_scripts_fonts[fid] + end + if last_fonts then + local mapped_scr = script_mapping[cid] + if mapped_scr == "Zinh" then + mapped_scr = last_script + else + local additional_scr = script_extensions[cid] + if additional_scripts then + if additional_scripts[last_script] then + mapped_scr = last_script + elseif not last_fonts[mapped_scr] then + for i = 1, #additional_scripts do + if last_fonts[additional_scripts[i]] then + mapped_scr = additional_scripts[i] + break + end + end + end + elseif mapped_scr == "Zyyy" then + mapped_scr = last_script + end + end + last_script = mapped_scr + local mapped_font = last_fonts[mapped_scr] + if mapped_font then + setfont(cur, mapped_font.fid) + end + end + end +end + +function luaotfload.add_multiscript(name, fonts) + if fonts == nil then + fonts = name + name = #additional_scripts_fonts + 1 + end + additional_scripts_tables[name] = fonts + return name +end + +otffeatures.register { + name = "multiscript", + description = "Combine fonts for multiple scripts", + manipulators = { + node = makecombifont, + }, + -- processors = { -- processors would be nice, but they are applied + -- -- too late for our purposes + -- node = donotdef, + -- } +} + +--- vim:sw=2:ts=2:expandtab:tw=71 diff --git a/macros/luatex/generic/luaotfload/luaotfload-fallback.lua b/macros/luatex/generic/luaotfload/luaotfload-fallback.lua index 17bd7ca404..0caef93589 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-fallback.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-fallback.lua @@ -5,8 +5,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-fallback", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / fallback", license = "GPL v2.0", author = "Marcel Krüger" diff --git a/macros/luatex/generic/luaotfload/luaotfload-features.lua b/macros/luatex/generic/luaotfload/luaotfload-features.lua index 67c9f93565..adce910c4e 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-features.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-features.lua @@ -5,8 +5,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-features", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / features", license = "GPL v2.0", author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger", diff --git a/macros/luatex/generic/luaotfload/luaotfload-filelist.lua b/macros/luatex/generic/luaotfload/luaotfload-filelist.lua index 69195603ed..10421ee372 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-filelist.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-filelist.lua @@ -6,8 +6,8 @@ if luaotfload_module then luaotfload_module { name = "luaotfload-filelist", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / filelist", license = "GPL v2.0" } end diff --git a/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua b/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua index aefc8369c6..7a34f29ca1 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua @@ -1,8 +1,8 @@ if luaotfload_module then luaotfload_module { name = "luaotfload-glyphlist", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / autogenerated glyphlist", copyright = "derived from https://raw.githubusercontent.com/adobe-type-tools/agl-aglfn/master/glyphlist.txt", original = "Adobe Glyph List, version 2.0, September 20, 2002", diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua index 5be4acfa65..f470b13772 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua @@ -5,8 +5,8 @@ do -- block to avoid to many local variables error assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-harf-define", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / HarfBuzz font loading", license = "GPL v2.0", author = "Khaled Hosny, Marcel Krüger", diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua index c40aa3b72e..bf7028c54d 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua @@ -5,8 +5,8 @@ do -- block to avoid to many local variables error assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-harf-plug", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / HarfBuzz shaping", license = "GPL v2.0", author = "Khaled Hosny, Marcel Krüger", diff --git a/macros/luatex/generic/luaotfload/luaotfload-init.lua b/macros/luatex/generic/luaotfload/luaotfload-init.lua index 3b67738fe5..c0ec8cd84b 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-init.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-init.lua @@ -7,8 +7,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-init", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / initialization", license = "GPL v2.0" } diff --git a/macros/luatex/generic/luaotfload/luaotfload-latex.pdf b/macros/luatex/generic/luaotfload/luaotfload-latex.pdf index 299ff211aa..84c541dc0c 100644 Binary files a/macros/luatex/generic/luaotfload/luaotfload-latex.pdf and b/macros/luatex/generic/luaotfload/luaotfload-latex.pdf differ diff --git a/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua b/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua index c1a3d6f1b7..bbdaa729e2 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua @@ -5,8 +5,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-letterspace", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / letterspacing", license = "GPL v2.0", copyright = "PRAGMA ADE / ConTeXt Development Team", diff --git a/macros/luatex/generic/luaotfload/luaotfload-loaders.lua b/macros/luatex/generic/luaotfload/luaotfload-loaders.lua index 84c5555f5d..e58f2429fe 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-loaders.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-loaders.lua @@ -8,8 +8,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-loaders", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / callback handling", license = "GPL v2.0" } diff --git a/macros/luatex/generic/luaotfload/luaotfload-log.lua b/macros/luatex/generic/luaotfload/luaotfload-log.lua index 58fc403e62..38208241f7 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-log.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-log.lua @@ -6,8 +6,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-log", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / logging", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang", diff --git a/macros/luatex/generic/luaotfload/luaotfload-main.tex b/macros/luatex/generic/luaotfload/luaotfload-main.tex index d1f698f684..acc136fd9d 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-main.tex +++ b/macros/luatex/generic/luaotfload/luaotfload-main.tex @@ -1,4 +1,4 @@ -%% Copyright (C) 2009-2020 +%% Copyright (C) 2009-2021 %% %% by Elie Roux %% and Khaled Hosny @@ -32,7 +32,7 @@ \beginfrontmatter \setdocumenttitle {The \identifier{luaotfload} package} - \setdocumentdate {2020-12-31 v3.16} + \setdocumentdate {2021-01-08 v3.17} \setdocumentauthor {LaTeX3 Project\\ Elie Roux · Khaled Hosny · Philipp Gesang · Ulrike Fischer · Marcel Krüger\\ Home: \hyperlink {https://github.com/latex3/luaotfload}} @@ -62,6 +62,14 @@ Supported is the \identifier{luatex} versions of a current TeXLive 2019 (and a c \endsection \beginsection{Changes} +\beginsubsection {New in version 3.17 (by Ulrike Fischer/Marcel Krüger)} +\begin{itemize} + \item The experimental support for OpenType variable fonts has been extended + to more reliably support modern fonts. + \item A number of small bugfixes. + \end{itemize} +\endsubsection + \beginsubsection {New in version 3.16 (by Ulrike Fischer/Marcel Krüger)} \begin{itemize} \item The entry point is called \identifier{luaotfload.lua} instead of diff --git a/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua b/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua index a632ab4c6a..7caae3a222 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua @@ -5,8 +5,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-multiscript", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / multiscript", license = "GPL v2.0", author = "Marcel Krüger" diff --git a/macros/luatex/generic/luaotfload/luaotfload-notdef.lua b/macros/luatex/generic/luaotfload/luaotfload-notdef.lua index 7b9664fa7e..aa4ce3076e 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-notdef.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-notdef.lua @@ -5,8 +5,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-notdef", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / notdef", license = "GPL v2.0", author = "Marcel Krüger" diff --git a/macros/luatex/generic/luaotfload/luaotfload-parsers.lua b/macros/luatex/generic/luaotfload/luaotfload-parsers.lua index 7810c3a49e..40973db882 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-parsers.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-parsers.lua @@ -7,8 +7,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-parsers", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / parsers", license = "GPL v2.0" } diff --git a/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua b/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua index 2ea85de781..4aa27a513b 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua @@ -11,8 +11,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-resolvers", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / resolvers", license = "GPL v2.0" } diff --git a/macros/luatex/generic/luaotfload/luaotfload-scripts.lua b/macros/luatex/generic/luaotfload/luaotfload-scripts.lua index b6c34b9e3e..003dda6c07 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-scripts.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-scripts.lua @@ -5,8 +5,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-script", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / Script helpers", license = "CC0 1.0 Universal", author = "Marcel Krüger" diff --git a/macros/luatex/generic/luaotfload/luaotfload-status.lua b/macros/luatex/generic/luaotfload/luaotfload-status.lua index 0ad3c01ead..ef89e65010 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-status.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-status.lua @@ -1,99 +1,99 @@ return { ["hashes"]={ - { "fontloader-2020-12-30.lua", "68ad807e7fdc2161801a16d1d404e1c4" }, - { "fontloader-util-fil.lua", "a617cad49fc028e99f0f30bce8b2b623" }, - { "fontloader-util-str.lua", "a2041dad54b982ad124cbc764f5de43b" }, - { "fontloader-l-unicode.lua", "a4464b61c123f0454bea92c1cf502891" }, - { "fontloader-l-math.lua", "a373be3ed2db0d5f98588fa81abca48f" }, - { "fontloader-l-boolean.lua", "18ed6c4b2c40dd87224ea33229548d20" }, - { "fontloader-l-file.lua", "60ddd3948d9de7bde8b4a0f5c51ff9f5" }, - { "fontloader-l-io.lua", "a4042e9d6bce71c61fdd94e6e17f2bf4" }, - { "fontloader-l-table.lua", "20c03ae1b81e902217f3f76995b9d294" }, - { "fontloader-l-string.lua", "e1347bef0eeeff9f098df83b30b32df9" }, - { "fontloader-l-function.lua", "f771cc91839ebcdfc094083434fbe00f" }, - { "fontloader-l-lpeg.lua", "c3407de16bcedd73652250b000b39e98" }, - { "fontloader-l-lua.lua", "c8dbb33df962e1b945b91b906b3c15c4" }, - { "fontloader-fonts-gbn.lua", "d25472d54c4841db43a745764a63533e" }, - { "fontloader-fonts-lig.lua", "b9dbe77ce747d4c35bb2a20ffbe5aa51" }, - { "fontloader-fonts-ext.lua", "01015ab3758cdc2af29394e6d502a91a" }, - { "fontloader-fonts-def.lua", "5ad79120ebc5e60f4d322fb3ee13bffe" }, - { "fontloader-fonts-tfm.lua", "3bbba3214fd0b8c6f35ad85592fc2917" }, - { "fontloader-fonts-enc.lua", "3e71a54297e8f85a1ac438bb0f20dd79" }, - { "fontloader-fonts-mis.lua", "bc9eb43c27f63ce9d0fff67e104fe1c6" }, - { "fontloader-basics-chr.lua", "58b7ef0c486e06090b362971b9f85e27" }, - { "fontloader-basics-nod.lua", "6549c88db8cf4c6ae005a2e08f223d4b" }, - { "fontloader-font-imp-effects.lua", "231cda056b88f6dc282fab9d7643d380" }, - { "fontloader-font-imp-italics.lua", "058fb834c11c6ac30c280b29e496966e" }, - { "fontloader-font-imp-ligatures.lua", "043daa4fcccf2560868da359d71d3a4a" }, - { "fontloader-font-imp-tex.lua", "77c374b0ef00c2fb12188ec42beb4257" }, - { "fontloader-font-shp.lua", "72de6029980ac796ec6ec76fa3ec8684" }, - { "fontloader-font-def.lua", "226b4d26ede7fa7be8e45b7f0d93e781" }, - { "fontloader-font-lua.lua", "55b281fb98f7bd848fc19928f376f647" }, - { "fontloader-font-afk.lua", "54d554530e75c57c56ee76234724e26d" }, - { "fontloader-font-one.lua", "2e52d1e42764f68b779522bda9569480" }, - { "fontloader-font-onr.lua", "7a9ece7bf3e36b5f0adf295a9a2a2989" }, - { "fontloader-font-ocl.lua", "ab81576f20e2d37bc8707e1dbd3decf2" }, - { "fontloader-font-osd.lua", "61f05fcf91add1aa5dac9bc8b235adc9" }, - { "fontloader-font-otc.lua", "1204a2fdc436e644127c0aa38ab69607" }, - { "fontloader-font-ots.lua", "a83d5992a82b706c0ffdb5c2778534f1" }, - { "fontloader-font-ota.lua", "f31232af3a694ae3d50380a5a92f88d3" }, - { "fontloader-font-oup.lua", "1700a2dac4f8b105c187d4e5b84cecdf" }, - { "fontloader-font-otj.lua", "a37a1007b8a92c9e7d24064180c2a772" }, - { "fontloader-font-oto.lua", "24238a7c600d090a8ee88312321dd9b3" }, - { "fontloader-font-otl.lua", "70237f19b76c4bc75f0c6e89038fb49a" }, - { "fontloader-font-ott.lua", "1249b7018dba80e080fc478a38aa6756" }, - { "fontloader-font-oti.lua", "dbae7722baae24d917a17176553825cf" }, - { "fontloader-font-dsp.lua", "10eb256f4bcb9c5eabd48048e2da5eab" }, - { "fontloader-font-ttf.lua", "ebef049a169c04edd19902fd66ddea44" }, - { "fontloader-font-cff.lua", "aa9038651d9fedd2b76cacd1f69fd742" }, - { "fontloader-font-otr.lua", "7a2f7a9e9627b29158e1822ea3c650ab" }, - { "fontloader-font-vfc.lua", "04fa0ffad5c51198c7c19462949f54ed" }, - { "fontloader-font-map.lua", "a03653ea3c5f042b457d54ed678d6df3" }, - { "fontloader-font-cid.lua", "4d87988efa86020a14708ee03c23415f" }, - { "fontloader-font-con.lua", "cbccccc4a5016196d62332a365aa8b72" }, - { "fontloader-font-ini.lua", "4dee96e1e1474d324dd126bd5d375df8" }, - { "fontloader-data-con.lua", "de6ae0997b0e70a23bcc9afff5d8b072" }, - { "fontloader-reference.lua", "957f358a48ea6fcbc78a8701f947d7e5" }, - { "fontloader-basics-gen.lua", "7bcfb5e4f48a1a34be6ddfcee2b1e49d" }, - { "mktests", "c7cff7025962922944376acc1ffa9c47" }, - { "mkstatus", "f3b00b5999440afce64bdc448f3fda9a" }, - { "mkcharacters", "92c24bb582fc84c0365634f29eb89863" }, - { "mkglyphlist", "95bbf91338214d40b2102114285ccd3f" }, - { "mkimport", "5dacc09f3358ba9b90cf3a804f9a535c" }, - { "luaotfload-glyphlist.lua", "bb6a9912a0944b3b21a61fce247dd728" }, - { "luaotfload-characters.lua", "6a46f4749368e4f56a863da9c61b7bd6" }, - { "luaotfload-dvi.lua", "34e1550905555da63304e07797168c69" }, - { "luaotfload-tounicode.lua", "09fa475eeb7b160d3eb124e9107d4e03" }, - { "luaotfload-unicode.lua", "153f97b086fd38dcb7f4850d95a41016" }, - { "luaotfload-resolvers.lua", "2441b9624775fbcea6617e6cc72b424d" }, - { "luaotfload-parsers.lua", "623d33f43813eda562cbfef5528753de" }, - { "luaotfload-fallback.lua", "ec702c1c9407eba7bfe80b59c36f3f67" }, - { "luaotfload-szss.lua", "ee4c0c070dcacf4d3e43f52948611392" }, - { "luaotfload-scripts.lua", "14a19085cd5288592ebd5e24acf8514a" }, - { "luaotfload-multiscript.lua", "4a283df608be713b0b666515fb6b9789" }, - { "luaotfload-loaders.lua", "f0eeb293d8f448413631b1ffff554e39" }, - { "luaotfload-harf-plug.lua", "34182344e7985d1267dacde37f387433" }, - { "luaotfload-harf-define.lua", "252c36178f4f9ab066bdc15adfe809f1" }, - { "luaotfload-notdef.lua", "06278786a6f2f8ddd3749b5d75f611db" }, - { "luaotfload-embolden.lua", "8bdfebc528d078086c7fd0747815df74" }, - { "luaotfload-letterspace.lua", "57d6026196fa62f9891d7a7a7300f63f" }, - { "luaotfload-features.lua", "2219adcecef7362bbbe46da2e5ed005b" }, - { "luaotfload-database.lua", "e2bea14191641d3a18b04064752d0fd4" }, - { "luaotfload-configuration.lua", "dfa0521ef327c68573ea587ed7b989c8" }, - { "luaotfload-colors.lua", "32bf6714aa19f6c291922cd1be01b629" }, - { "luaotfload-auxiliary.lua", "4c18ffcc0d1cbef3ad4db2b6440a863e" }, - { "luaotfload-filelist.lua", "8bb0a321254e6f04a1fa776d2f67747f" }, - { "luaotfload-tool.lua", "ac7b0adfd9d0096228bed8ae61540a70" }, - { "luaotfload-diagnostics.lua", "21bca70ad0b6f7dd1d9d57c7b1513809" }, - { "luaotfload-log.lua", "d9c45eff233d71c3824f3a579694d737" }, - { "luaotfload-init.lua", "265f1bfe8789fbb0cc3bff3a780f5494" }, - { "luaotfload-main.lua", "f5f771d1cf5c8c4a2519a8d46aed1241" }, + { "fontloader-2021-01-07.lua", "ef54bfa34416e2c85fa48d3195c67fd2" }, + { "fontloader-util-fil.lua", "aae2a2add764144bb58dd8216fd59260" }, + { "fontloader-util-str.lua", "c975ff7bbd178163cf47d9e9296c8b4b" }, + { "fontloader-l-unicode.lua", "f368874f11f3c525de5864fd413e4b24" }, + { "fontloader-l-math.lua", "082add08e0bb79f39191ae9534a79849" }, + { "fontloader-l-boolean.lua", "abe28515dd33e8f6c416c09bca351cf8" }, + { "fontloader-l-file.lua", "352b42b8360ada02ceb26a41f0bd2a76" }, + { "fontloader-l-io.lua", "bbcc4824d0ded30b415d7d2d5763028a" }, + { "fontloader-l-table.lua", "0330da8b3a08d39876def70df8d9c0e5" }, + { "fontloader-l-string.lua", "9457f2af85723e0e6c46d0b5122e9000" }, + { "fontloader-l-function.lua", "a7e68a9703c35238729da41a474e951b" }, + { "fontloader-l-lpeg.lua", "10bdaef44175902917691835010ae5f5" }, + { "fontloader-l-lua.lua", "420bc442e6d81f4624728a6c56fcd175" }, + { "fontloader-fonts-gbn.lua", "10ecdf01e7c926e5128ad8a9dff4d677" }, + { "fontloader-fonts-lig.lua", "fbd251eea3810a43a8d5542319361d68" }, + { "fontloader-fonts-ext.lua", "32013cbc5d5d336be8b1d1e5879d86c4" }, + { "fontloader-fonts-def.lua", "f435e0875f203f343157baeff876ec9c" }, + { "fontloader-fonts-tfm.lua", "f0eb5e2a8068b17ad401bb7efdba1630" }, + { "fontloader-fonts-enc.lua", "5ff4ca50493d7c4ecea0e15c203099f0" }, + { "fontloader-fonts-mis.lua", "17e967c9ec4d001deefd43ddf25e98f7" }, + { "fontloader-basics-chr.lua", "64fafe4eaf55d64aead6513c1e74a024" }, + { "fontloader-basics-nod.lua", "4b5c3c63e19df1b3f37fae7f87c25bda" }, + { "fontloader-font-imp-effects.lua", "a2dde5e071fcb3fc7b90f2bcd5aa4f22" }, + { "fontloader-font-imp-italics.lua", "defcb415bc1e0a0999b27773902adc18" }, + { "fontloader-font-imp-ligatures.lua", "26ffcf089391445f7af59536c8814364" }, + { "fontloader-font-imp-tex.lua", "ceb087ef6fa2f89aed7179f60ddf8f35" }, + { "fontloader-font-shp.lua", "5ff497c993112d4fef4c148348d964eb" }, + { "fontloader-font-def.lua", "b9d908c2338b7dc443ce9d1e9fcb7139" }, + { "fontloader-font-lua.lua", "1fbfdf7b689b2bdfd0e3bb9bf74ce136" }, + { "fontloader-font-afk.lua", "9da14e0fb22129c053acc599d1312544" }, + { "fontloader-font-one.lua", "53cd565030e919da984b50471cc3be37" }, + { "fontloader-font-onr.lua", "6d161533f3437435e12a0ad64866df44" }, + { "fontloader-font-ocl.lua", "797b5c71bf819c5f4fb314a4d646e9a7" }, + { "fontloader-font-osd.lua", "73c9531c79df5ada320cb20777f7ed49" }, + { "fontloader-font-otc.lua", "0f12230ea07b5151f75d52726977e91f" }, + { "fontloader-font-ots.lua", "c780a471147527f4ddc139e017927ffe" }, + { "fontloader-font-ota.lua", "ad1d5de06400f88829509e1f3ff2b473" }, + { "fontloader-font-oup.lua", "6f46aa00ae1c20c43f8ffaf329dc8695" }, + { "fontloader-font-otj.lua", "8de59cb9b043e5f73c6b9f7cc8f6978e" }, + { "fontloader-font-oto.lua", "2b1d6bc63b2ebf8f2655a15e1cda6541" }, + { "fontloader-font-otl.lua", "f4e6652a191003493389de230b14cfb3" }, + { "fontloader-font-ott.lua", "673ed11e1d159997f535bfec5fa73808" }, + { "fontloader-font-oti.lua", "309a75f9c14b77d87e94eba827dc4e71" }, + { "fontloader-font-dsp.lua", "174ce11f3ba0bddf270f48d8d2addd56" }, + { "fontloader-font-ttf.lua", "ffffc827e1bcddc33a2b615340ecff7f" }, + { "fontloader-font-cff.lua", "2b677fad52d9999d0685e8525271a8cc" }, + { "fontloader-font-otr.lua", "64dcbbc7107538723990e1119a80a9f8" }, + { "fontloader-font-vfc.lua", "a81c29eda98cd62cbebdb6c93544b50d" }, + { "fontloader-font-map.lua", "c4a39db5ad822b348aa61bca5f4a599a" }, + { "fontloader-font-cid.lua", "22b0367742fb253deef84ef7ccf5e8de" }, + { "fontloader-font-con.lua", "724e5dd14aec2d4d189f8619898004cf" }, + { "fontloader-font-ini.lua", "5343de60613adb24cdd7a8d2ee1d153c" }, + { "fontloader-data-con.lua", "23a0f5386d46a1c157ae82a373e35fa0" }, + { "fontloader-reference.lua", "4807209e6a35420dd7528e9ec02f11da" }, + { "fontloader-basics-gen.lua", "4bc43036e9796fccb0b8869f4b05bf2e" }, + { "mktests", "918cb50be9ee8bd645ac1a27dc501e8c" }, + { "mkstatus", "d3bc6e7d0f6deb80db4edc6975e2ac5c" }, + { "mkcharacters", "bfca0e96e1e351afe7077502f9595af9" }, + { "mkglyphlist", "7a8a8fdc0eac7fac2f13ec8f4e8e7aa9" }, + { "mkimport", "7d62f1042e548f8b9368f26b9ba4be5c" }, + { "luaotfload-glyphlist.lua", "6097b4fd28b303a3ae7577e94f86610d" }, + { "luaotfload-characters.lua", "76415ca3ede312cad6e09038323489ae" }, + { "luaotfload-dvi.lua", "a0d33e699c250c0e4abd4cfa1b974b6e" }, + { "luaotfload-tounicode.lua", "e07e112222777070250fbc980b2e6b85" }, + { "luaotfload-unicode.lua", "1d7fd6ab63640cb6c8e2091ac5a57915" }, + { "luaotfload-resolvers.lua", "b387d9435738f7ce8cf1e6af86b565a6" }, + { "luaotfload-parsers.lua", "dba42cb2f6bbfa13b9a56d0e4a2b2f44" }, + { "luaotfload-fallback.lua", "a3c8c048b14a304d3352871014ef1343" }, + { "luaotfload-szss.lua", "2413a2be98181fe77f7e110369194769" }, + { "luaotfload-scripts.lua", "2b924be852e17191e651faf5a2097e12" }, + { "luaotfload-multiscript.lua", "db7b6c7791b4b909d12234620ff7973d" }, + { "luaotfload-loaders.lua", "d169564522ac7194e7410d8263cd1b31" }, + { "luaotfload-harf-plug.lua", "8fdc1ba513a6026546b883259e559c7e" }, + { "luaotfload-harf-define.lua", "1c9a663bb7bfa650b93dcf01d5450675" }, + { "luaotfload-notdef.lua", "26fed1a76150718e05c8c56b1983ebdd" }, + { "luaotfload-embolden.lua", "5506419bc583d450f252542b1105d6ce" }, + { "luaotfload-letterspace.lua", "1a518a55f6663ce13866416a5b94d6a4" }, + { "luaotfload-features.lua", "33fdd06674606d043599dc4ea9b2a56b" }, + { "luaotfload-database.lua", "4a0f9f3b500df0d8a8234a0954065e46" }, + { "luaotfload-configuration.lua", "589ca99522479a0929d6824bafa36f63" }, + { "luaotfload-colors.lua", "7c201914c79310d9e79e75dfc7ee982b" }, + { "luaotfload-auxiliary.lua", "8e427ec79ced91d9fc6fbcece159d042" }, + { "luaotfload-filelist.lua", "3cd6b9d12ba2fb48783e393593cd9afd" }, + { "luaotfload-tool.lua", "f4534033397387433601040694b70c6b" }, + { "luaotfload-diagnostics.lua", "473e1a3cd00e4b277b1f7e17b13254da" }, + { "luaotfload-log.lua", "809e4afac4e070b619512461a6fedd90" }, + { "luaotfload-init.lua", "e3b832a9efc91c977044383640835069" }, + { "luaotfload-main.lua", "b19c9cc34cf1d676c39f872cfb41aef6" }, }, ["notes"]={ - ["committer"]="Ulrike Fischer ", - ["description"]="v3.16/2020-12-31", - ["loader"]="fontloader-2020-12-30.lua", - ["revision"]="d1423b56efe2649e2881657747cee8d54cf64e12", - ["timestamp"]="2020-12-31 12:35:44 +0100", + ["committer"]="Marcel Fabian Krüger ", + ["description"]="v3.17/2021-01-08", + ["loader"]="fontloader-2021-01-07.lua", + ["revision"]="359a8a50a0d1f778e358cc1507b6f08ec17b6898", + ["timestamp"]="2021-01-08 14:15:42 +0100", }, } \ No newline at end of file diff --git a/macros/luatex/generic/luaotfload/luaotfload-suppress.lua b/macros/luatex/generic/luaotfload/luaotfload-suppress.lua index c4c0c1010e..d78428ca96 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-suppress.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-suppress.lua @@ -5,8 +5,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-suppress", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / suppress", license = "GPL v2.0", author = "Marcel Krüger" diff --git a/macros/luatex/generic/luaotfload/luaotfload-szss.lua b/macros/luatex/generic/luaotfload/luaotfload-szss.lua index 4c7de4d11b..88b02350f0 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-szss.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-szss.lua @@ -5,8 +5,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-szss", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / Special feature handling", license = "GPL v2.0", author = "Marcel Krüger" diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.1 b/macros/luatex/generic/luaotfload/luaotfload-tool.1 index 7cd4934ab0..86f70ac706 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-tool.1 +++ b/macros/luatex/generic/luaotfload/luaotfload-tool.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH LUAOTFLOAD-TOOL 1 "2020-12-31" "3.16" "text processing" +.TH LUAOTFLOAD-TOOL 1 "2021-01-08" "3.17" "text processing" .SH NAME luaotfload-tool \- generate and query the Luaotfload font names database . diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.lua b/macros/luatex/generic/luaotfload/luaotfload-tool.lua index fd66a9f79c..0c58363903 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-tool.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-tool.lua @@ -9,8 +9,8 @@ local ProvidesLuaModule = { name = "luaotfload-tool", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload-tool / database functionality", license = "GPL v2.0" } diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.pdf b/macros/luatex/generic/luaotfload/luaotfload-tool.pdf index e35752ab17..3836a25b15 100644 Binary files a/macros/luatex/generic/luaotfload/luaotfload-tool.pdf and b/macros/luatex/generic/luaotfload/luaotfload-tool.pdf differ diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.rst b/macros/luatex/generic/luaotfload/luaotfload-tool.rst index c4c15d916f..9ebc3127a1 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-tool.rst +++ b/macros/luatex/generic/luaotfload/luaotfload-tool.rst @@ -6,9 +6,9 @@ generate and query the Luaotfload font names database ----------------------------------------------------------------------- -:Date: 2020-12-31 +:Date: 2021-01-08 :Copyright: GPL v2.0 -:Version: 3.16 +:Version: 3.17 :Manual section: 1 :Manual group: text processing diff --git a/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua b/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua index f4eeec1125..5c92785066 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua @@ -5,8 +5,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-tounicode", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / tounicode", license = "GPL v2.0", author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger", diff --git a/macros/luatex/generic/luaotfload/luaotfload-unicode.lua b/macros/luatex/generic/luaotfload/luaotfload-unicode.lua index a05c660a36..5320c48ab2 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-unicode.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-unicode.lua @@ -5,8 +5,8 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-unicode", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "luaotfload submodule / Unicode helpers", license = "CC0 1.0 Universal", author = "Marcel Krüger" diff --git a/macros/luatex/generic/luaotfload/luaotfload.conf.5 b/macros/luatex/generic/luaotfload/luaotfload.conf.5 index 4620ef0f2f..efb8b5fff3 100644 --- a/macros/luatex/generic/luaotfload/luaotfload.conf.5 +++ b/macros/luatex/generic/luaotfload/luaotfload.conf.5 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH LUAOTFLOAD.CONF 5 "2020-12-31" "3.16" "text processing" +.TH LUAOTFLOAD.CONF 5 "2021-01-08" "3.17" "text processing" .SH NAME luaotfload.conf \- Luaotfload configuration file . diff --git a/macros/luatex/generic/luaotfload/luaotfload.conf.rst b/macros/luatex/generic/luaotfload/luaotfload.conf.rst index 5905eb3811..645a659d2b 100644 --- a/macros/luatex/generic/luaotfload/luaotfload.conf.rst +++ b/macros/luatex/generic/luaotfload/luaotfload.conf.rst @@ -6,9 +6,9 @@ Luaotfload configuration file ----------------------------------------------------------------------- -:Date: 2020-12-31 +:Date: 2021-01-08 :Copyright: GPL v2.0 -:Version: 3.16 +:Version: 3.17 :Manual section: 5 :Manual group: text processing diff --git a/macros/luatex/generic/luaotfload/luaotfload.lua b/macros/luatex/generic/luaotfload/luaotfload.lua index 843c84a3bf..4a3cdb78ae 100644 --- a/macros/luatex/generic/luaotfload/luaotfload.lua +++ b/macros/luatex/generic/luaotfload/luaotfload.lua @@ -20,8 +20,8 @@ local authors = "\z -- version number is used below! local ProvidesLuaModule = { name = "luaotfload", - version = "3.16", --TAGVERSION - date = "2020-12-31", --TAGDATE + version = "3.17", --TAGVERSION + date = "2021-01-08", --TAGDATE description = "Lua based OpenType font support", author = authors, copyright = authors, diff --git a/macros/luatex/generic/luaotfload/luaotfload.sty b/macros/luatex/generic/luaotfload/luaotfload.sty index d9a3397d14..915b418693 100644 --- a/macros/luatex/generic/luaotfload/luaotfload.sty +++ b/macros/luatex/generic/luaotfload/luaotfload.sty @@ -1,4 +1,4 @@ -%% Copyright (C) 2009-2020 +%% Copyright (C) 2009-2021 %% %% by Elie Roux %% and Khaled Hosny @@ -39,7 +39,7 @@ \fi \ifdefined\ProvidesPackage \ProvidesPackage{luaotfload}% - [2020/12/31 v3.16 OpenType layout system] + [2021/01/08 v3.17 OpenType layout system] \fi \directlua{ if xpcall(function ()% diff --git a/macros/luatex/generic/luaotfload/scripts-demo.pdf b/macros/luatex/generic/luaotfload/scripts-demo.pdf index 5c00e2f4a6..29d47c2695 100644 Binary files a/macros/luatex/generic/luaotfload/scripts-demo.pdf and b/macros/luatex/generic/luaotfload/scripts-demo.pdf differ diff --git a/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf b/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf index fa1bda41bb..bfb4258474 100644 Binary files a/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf and b/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf differ diff --git a/macros/luatex/generic/luaotfload/shaper-demo.pdf b/macros/luatex/generic/luaotfload/shaper-demo.pdf index b19632bbc7..056db0fac3 100644 Binary files a/macros/luatex/generic/luaotfload/shaper-demo.pdf and b/macros/luatex/generic/luaotfload/shaper-demo.pdf differ diff --git a/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl b/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl index f00f5a76a2..fa20a9722f 100644 --- a/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl +++ b/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl @@ -46,6 +46,7 @@ $mirrors = { }, 'Korea' => { 'http://ftp.kaist.ac.kr/pub/tex-archive/' => 1, + 'http://ftp.ktug.org/tex-archive/' => 1, 'https://cran.asia/tex/' => 1, 'https://ftp.harukasan.org/CTAN/' => 1, 'https://mirror.navercorp.com/CTAN/' => 1, diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb b/systems/texlive/tlnet/tlpkg/texlive.tlpdb index 017901d51e..1c6c5c1c71 100644 --- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb +++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb @@ -26,11 +26,11 @@ depend container_split_src_files/1 depend frozen/0 depend minrelease/2016 depend release/2020 -depend revision/57421 +depend revision/57434 name 00texlive.image category TLCore -revision 57420 +revision 57430 shortdesc TeX Live files only in the source repository longdesc The files here are not copied by the installer and containers longdesc are not built for them; they exist only in the source @@ -40,7 +40,7 @@ longdesc IgnorePatterns in the check_files routine in tlmgr.pl augment longdesc this list. Those are not included in the source/ tarball. For longdesc information on the 00texlive prefix see longdesc 00texlive.installation(.tlpsrc) -runfiles size=13792 +runfiles size=13793 .mkisofsrc autorun.inf texmf-dist/README @@ -2880,6 +2880,7 @@ runfiles size=13792 tlpkg/tlpsrc/numnameru.tlpsrc tlpkg/tlpsrc/numprint.tlpsrc tlpkg/tlpsrc/numspell.tlpsrc + tlpkg/tlpsrc/nunito.tlpsrc tlpkg/tlpsrc/nwejm.tlpsrc tlpkg/tlpsrc/oberdiek.tlpsrc tlpkg/tlpsrc/objectz.tlpsrc @@ -4323,7 +4324,7 @@ depend setting_available_architectures:aarch64-linux amd64-freebsd amd64-netbsd name 00texlive.installer category TLCore -revision 57406 +revision 57426 shortdesc TeX Live standalone installer package longdesc This package defines the files to go into the installer longdesc archives (install-tl-unx.tar.gz, install-tl.zip) built by the @@ -64539,7 +64540,7 @@ containerchecksum 5bd74e1a434549cf31ce31777e9a32f90baa14148e6658633945508a46dbf6 name collection-fontsextra category Collection -revision 57399 +revision 57429 shortdesc Additional fonts relocated 1 depend Asana-Math @@ -64780,6 +64781,7 @@ depend nkarta depend noto depend noto-emoji depend notomath +depend nunito depend obnov depend ocherokee depend ocr-b @@ -64868,8 +64870,8 @@ depend yfonts depend yfonts-t1 depend yinit-otf depend zlmtt -containersize 1888 -containerchecksum 7ec54a8d09c4506c41c906219b86831936b245d72df99ee979a551d24c857c7629777fb8bcf54b66a1c411aa9c8fb38804132788a6c7c8cf18bde08632503426 +containersize 1892 +containerchecksum 46045ece0dfbbda6193466434f912fee04314c1959d62f305e71ef45bb5fe453cf2088af1da7ca3ffe1dda51a816eb61c700b1c2977dc4e316a0f420a2ca2161 name collection-fontsrecommended category Collection @@ -96752,15 +96754,15 @@ catalogue-topics notes editorial name easybook category Package -revision 57418 +revision 57431 shortdesc Typeset Chinese books or notes relocated 1 longdesc Easybook is a minimalist style template based on the ctexbook longdesc book document class. -containersize 9956 -containerchecksum 534cb91eafb136bdfafa2b9a27ee60fc4c414519fb3cf9c62a2d2b3858043307440facfea20e5496cc76891b8668412eb3d997a46dfa7ac218644551b291f0df -doccontainersize 526796 -doccontainerchecksum a0d8d42e13b0114fbcbfccc6cc86307c631f0e21414c42a5bb60ab334c52c537c29bf3da862bc1bf0277e3e61fffc861be8739b2c2586376aaa858cae94ea25f +containersize 9824 +containerchecksum bda9a99244839f0b05108dd3e2402e41bc25d9694328622ac2e2dad10ff23340313e96fd1bcf80892f204718f1b61216c8e9c0eae28c0c0efa8ef72ea5e6f71c +doccontainersize 527376 +doccontainerchecksum d55c9962e2a3acd155bf9fd509b1e020dcae1bf1c8ca0a11bde2e60a3dd9857e6f6f293c9a68e53ebaf794a46c75063bd070f0dc1eb1e38976c04001e0a0b83d docfiles size=149 RELOC/doc/latex/easybook/README.md details="Readme" RELOC/doc/latex/easybook/appendix.tex @@ -96780,7 +96782,7 @@ catalogue-contact-repository https://gitee.com/texl3/easybook catalogue-ctan /macros/latex/contrib/easybook catalogue-license cc-by-4 catalogue-topics book-pub class chinese expl3 -catalogue-version 1.21d +catalogue-version 1.21e name easyfig category Package @@ -112201,7 +112203,7 @@ catalogue-version 1.0 name fcolumn category Package -revision 50937 +revision 57428 shortdesc Typesetting financial tables relocated 1 longdesc In financial reports, text and currency amounts are regularly @@ -112209,25 +112211,25 @@ longdesc put in one table, e.g., a year balance or a profit-and-loss longdesc overview. This package provides the settings for automatically longdesc typesetting such columns, including the sum line (preceded by a longdesc rule of the correct width) using the specifier "f". -containersize 3720 -containerchecksum 13128f25e12c914bf25c45c87a75bad814eab519059c8a478162cd4fc678972ed8e24800042e87866197174044eaf9f90d3cd3a8eca62f33400e3fd2294922c8 -doccontainersize 282276 -doccontainerchecksum ae0645744e26bbf1a940ba1339256b7d718f4df819ad04f5f52301a26d445cbce4a1ae4bfa2fe6d13bb81ed31e94839d87a251a7429305d396a56ea113df37bb -docfiles size=71 +containersize 4376 +containerchecksum 9bd1bff80e03a080f2d3778c89c19478691cc119361229cd66b776e24260ddadc30ba37fadd5a82c631c14b369a2045960123f5b1f169ec699d9ad627ded3256 +doccontainersize 319588 +doccontainerchecksum fac7e6eae8c6c3d1c6b05eefcca881f08334ef32a10946227f0244c74460f3a66926e6735342dfbf4da80228a0271b10aed8b42fcf66eb72ae41ff74c9f72af4 +docfiles size=80 RELOC/doc/latex/fcolumn/README details="Readme" RELOC/doc/latex/fcolumn/fcolumn.pdf details="Package documentation" RELOC/doc/latex/fcolumn/makefile -srccontainersize 18300 -srccontainerchecksum 47b78b21332aeba11b08ed6f4eaf781b182c224450b508a48a80ca7f93ffb43c4cc818739d3793ca16674b29fbfeeed320247170c63a4aa321f6054610fe782b -srcfiles size=15 +srccontainersize 21252 +srccontainerchecksum a343431efc38bb19ec033e0791c7b5712324c2dc92837b9d620b6a35d8a6fcec24faf04cb71edfaaf34d8355ad2f40c7ab51b21f4b3ebe1e4e84cef0c2af6487 +srcfiles size=18 RELOC/source/latex/fcolumn/fcolumn.dtx RELOC/source/latex/fcolumn/fcolumn.ins -runfiles size=3 +runfiles size=4 RELOC/tex/latex/fcolumn/fcolumn.sty catalogue-ctan /macros/latex/contrib/fcolumn catalogue-license lppl1.3 catalogue-topics table -catalogue-version 1.2 +catalogue-version 1.3 name fdsymbol category Package @@ -185843,28 +185845,29 @@ catalogue-topics index-multi name marathi category Package -revision 56781 +revision 57432 shortdesc Typeset Marathi language using XeLaTeX or LuaLaTeX relocated 1 longdesc luaa-laattek v jhii-laattek hyaaNcyaash mraatthiicaa sulbh -longdesc vaapr krnnyaasaatthii. ithuun puddhe laattek-vriil -longdesc mraatthiicyaa sthaanikiikrnnaace kaam hyaa aajnyaasNcaamaarpht -longdesc kele jaaiil. tuurt expex v blindtext hyaa aajnyaasNcaaNce -longdesc sthaanikiikrnn hyaa aajnyaasNcaamaarpht purvle aahe. For -longdesc conveniently typesetting Marathi language with LuaLaTeX and -longdesc XeLaTeX. This package will from now onwards host localizations -longdesc needed for the Marathi language. Currently the package -longdesc localizes package blindtext and package expex. -containersize 4492 -containerchecksum 2e76c85b62b77d6c06583bb2c32004d56e667e59b9421aea092b1a8e70557ccdd81b9bde7b6642880abf7ee0e2c9c786d64be7d47f599876c542328541ffdd7a -doccontainersize 119856 -doccontainerchecksum 578f82df4421539ac07f19bd78f521ef1b529c8cf07021519ac1faebad92dcfb61cecefad485adb7b5d2b204ef0131898030bf5c96b85a27d4b96ab272dcdebb -docfiles size=31 +longdesc vaapr krnnyaasaatthii. laattek-vriil mraatthiicyaa +longdesc sthaanikiikrnnaace kaam hyaa aajnyaasNcaamaarpht kele jaaiil. +longdesc expex v blindtext hyaa aajnyaasNcaaNce sthaanikiikrnn tuurtaas +longdesc hyaa aajnyaasNcaamaarpht purvle jaat aahe. For conveniently +longdesc typesetting Marathi language with LuaLaTeX and XeLaTeX. This +longdesc package will provide localizations needed for the Marathi +longdesc language. Currently the package localizes package blindtext and +longdesc package expex. +containersize 5240 +containerchecksum 249a5c501ae3112bdd3e005624bf09f337f5ae08c64732aa7dddb5b24b4f56c99ac8e075ae5a16af6172cddad0b0a7b56e44caec754704e7148022396b9b6870 +doccontainersize 184044 +doccontainerchecksum 5499396ceeddb7131206320de769720884020a25f4fdc06c5a3f94f6db1c3ec7ad291733a3736d51b67e15d679e377a5e27bc0c22c230ed2a69551d5ce14da18 +docfiles size=53 + RELOC/doc/latex/marathi/COPYING RELOC/doc/latex/marathi/README.txt details="Readme" RELOC/doc/latex/marathi/marathi.pdf details="Package documentation" language="mr" -srccontainersize 8584 -srccontainerchecksum bd4a298971ba46d991d84f6def53e7ba60669f2047109d3b8491e6aa956788431fd65e30479b4c2d8048059991f37f462f6728079ceeb9aaecfe64eb34a227e2 -srcfiles size=11 +srccontainersize 17536 +srccontainerchecksum 0c49488df81ae6f2995c062814ae5b0bf151197ff2acfd850208d62b7dfb8852c66b915237b05c8fab1b249450d75972a9c87279b1c28a5a0680b0203f24e164 +srcfiles size=19 RELOC/source/latex/marathi/marathi.dtx RELOC/source/latex/marathi/marathi.ins runfiles size=15 @@ -185878,9 +185881,9 @@ runfiles size=15 catalogue-contact-bugs https://gitlab.com/niranjanvikastambe/marathi/-/issues catalogue-contact-repository https://gitlab.com/niranjanvikastambe/marathi/ catalogue-ctan /language/marathi -catalogue-license lppl1.3c +catalogue-license gpl3+ other-free catalogue-topics indic marathi -catalogue-version 1.5 +catalogue-version 1.6.1 name marcellus category Package @@ -225176,6 +225179,459 @@ catalogue-license lppl1.3 catalogue-topics numbers multilingual english french german hungarian italian catalogue-version 1.4 +name nunito +category Package +revision 57429 +shortdesc The Nunito font face with support for LaTeX and pdfLaTeX +relocated 1 +longdesc This package provides LaTeX and pdfLaTeX support for the Nunito +longdesc family of fonts, designed by Vernon Adams, Cyreal. +execute addMap Nunito.map +containersize 4627580 +containerchecksum 920e074987e7e75fa6db92e3c05d76f7aad3e7d9b4f0166a8a8ca79bc5183549299b56a10f1cb6c7fdaa63f7f55aa6b9c1b2bcb4cbf03567b26e9fcb0240472e +doccontainersize 182360 +doccontainerchecksum e0de75f22da96d229a6465a4d47baa8e4c3199567f8d2e3255893e5b2a2d16ab73eabec1a103b355518c4cb98ea3146ff067af54938c21a910aa65aee3f429db +docfiles size=48 + RELOC/doc/fonts/nunito/LICENSE.TXT + RELOC/doc/fonts/nunito/README details="Readme" + RELOC/doc/fonts/nunito/nunito-samples.pdf details="Font samples" + RELOC/doc/fonts/nunito/nunito-samples.tex +runfiles size=2919 + RELOC/fonts/enc/dvips/nunito/a_2owfxx.enc + RELOC/fonts/enc/dvips/nunito/a_35ovjx.enc + RELOC/fonts/enc/dvips/nunito/a_g4f2r6.enc + RELOC/fonts/enc/dvips/nunito/a_hxzdi6.enc + RELOC/fonts/enc/dvips/nunito/a_lzhlbi.enc + RELOC/fonts/enc/dvips/nunito/a_nr4mc7.enc + RELOC/fonts/enc/dvips/nunito/a_wslvgt.enc + RELOC/fonts/enc/dvips/nunito/a_xcjjqo.enc + RELOC/fonts/enc/dvips/nunito/a_xv7ze7.enc + RELOC/fonts/enc/dvips/nunito/a_xzgqel.enc + RELOC/fonts/map/dvips/nunito/Nunito.map + RELOC/fonts/opentype/public/nunito/Nunito-Black.otf + RELOC/fonts/opentype/public/nunito/Nunito-BlackItalic.otf + RELOC/fonts/opentype/public/nunito/Nunito-Bold.otf + RELOC/fonts/opentype/public/nunito/Nunito-BoldItalic.otf + RELOC/fonts/opentype/public/nunito/Nunito-ExtraBold.otf + RELOC/fonts/opentype/public/nunito/Nunito-ExtraBoldItalic.otf + RELOC/fonts/opentype/public/nunito/Nunito-ExtraLight.otf + RELOC/fonts/opentype/public/nunito/Nunito-ExtraLightItalic.otf + RELOC/fonts/opentype/public/nunito/Nunito-Italic.otf + RELOC/fonts/opentype/public/nunito/Nunito-Light.otf + RELOC/fonts/opentype/public/nunito/Nunito-LightItalic.otf + RELOC/fonts/opentype/public/nunito/Nunito-Regular.otf + RELOC/fonts/opentype/public/nunito/Nunito-SemiBold.otf + RELOC/fonts/opentype/public/nunito/Nunito-SemiBoldItalic.otf + RELOC/fonts/tfm/public/nunito/Nunito-Black-sup-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Black-sup-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Black-sup-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Black-sup-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Black-sup-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Black-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Black-tlf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Black-tlf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Black-tlf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Black-tlf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Black-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Black-tlf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Black-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Black-tosf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Black-tosf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Black-tosf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Black-tosf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Black-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Black-tosf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BlackItalic-sup-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BlackItalic-sup-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BlackItalic-sup-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BlackItalic-sup-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BlackItalic-sup-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BlackItalic-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BlackItalic-tlf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BlackItalic-tlf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BlackItalic-tlf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BlackItalic-tlf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BlackItalic-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BlackItalic-tlf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BlackItalic-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BlackItalic-tosf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BlackItalic-tosf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BlackItalic-tosf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BlackItalic-tosf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BlackItalic-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BlackItalic-tosf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Bold-sup-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Bold-sup-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Bold-sup-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Bold-sup-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Bold-sup-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Bold-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Bold-tlf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Bold-tlf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Bold-tlf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Bold-tlf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Bold-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Bold-tlf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Bold-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Bold-tosf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Bold-tosf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Bold-tosf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Bold-tosf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Bold-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Bold-tosf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BoldItalic-sup-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BoldItalic-sup-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BoldItalic-sup-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BoldItalic-sup-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BoldItalic-sup-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BoldItalic-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BoldItalic-tlf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BoldItalic-tlf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BoldItalic-tlf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BoldItalic-tlf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BoldItalic-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BoldItalic-tlf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BoldItalic-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BoldItalic-tosf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BoldItalic-tosf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BoldItalic-tosf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BoldItalic-tosf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BoldItalic-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-BoldItalic-tosf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBold-sup-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBold-sup-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBold-sup-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBold-sup-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBold-sup-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBold-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBold-tlf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBold-tlf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBold-tlf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBold-tlf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBold-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBold-tlf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBold-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBold-tosf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBold-tosf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBold-tosf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBold-tosf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBold-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBold-tosf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBoldItalic-sup-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBoldItalic-sup-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBoldItalic-sup-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBoldItalic-sup-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBoldItalic-sup-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBoldItalic-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBoldItalic-tlf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBoldItalic-tlf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBoldItalic-tlf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBoldItalic-tlf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBoldItalic-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBoldItalic-tlf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBoldItalic-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBoldItalic-tosf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBoldItalic-tosf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBoldItalic-tosf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBoldItalic-tosf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBoldItalic-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraBoldItalic-tosf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLight-sup-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLight-sup-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLight-sup-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLight-sup-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLight-sup-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLight-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLight-tlf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLight-tlf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLight-tlf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLight-tlf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLight-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLight-tlf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLight-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLight-tosf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLight-tosf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLight-tosf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLight-tosf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLight-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLight-tosf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLightItalic-sup-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLightItalic-sup-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLightItalic-sup-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLightItalic-sup-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLightItalic-sup-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLightItalic-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLightItalic-tlf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLightItalic-tlf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLightItalic-tlf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLightItalic-tlf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLightItalic-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLightItalic-tlf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLightItalic-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLightItalic-tosf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLightItalic-tosf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLightItalic-tosf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLightItalic-tosf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLightItalic-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-ExtraLightItalic-tosf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Italic-sup-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Italic-sup-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Italic-sup-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Italic-sup-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Italic-sup-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Italic-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Italic-tlf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Italic-tlf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Italic-tlf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Italic-tlf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Italic-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Italic-tlf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Italic-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Italic-tosf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Italic-tosf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Italic-tosf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Italic-tosf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Italic-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Italic-tosf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Light-sup-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Light-sup-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Light-sup-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Light-sup-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Light-sup-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Light-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Light-tlf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Light-tlf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Light-tlf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Light-tlf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Light-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Light-tlf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Light-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Light-tosf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Light-tosf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Light-tosf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Light-tosf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Light-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Light-tosf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-LightItalic-sup-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-LightItalic-sup-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-LightItalic-sup-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-LightItalic-sup-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-LightItalic-sup-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-LightItalic-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-LightItalic-tlf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-LightItalic-tlf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-LightItalic-tlf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-LightItalic-tlf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-LightItalic-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-LightItalic-tlf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-LightItalic-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-LightItalic-tosf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-LightItalic-tosf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-LightItalic-tosf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-LightItalic-tosf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-LightItalic-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-LightItalic-tosf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Regular-sup-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Regular-sup-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Regular-sup-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Regular-sup-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Regular-sup-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Regular-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Regular-tlf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Regular-tlf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Regular-tlf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Regular-tlf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Regular-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Regular-tlf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Regular-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Regular-tosf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Regular-tosf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Regular-tosf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Regular-tosf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Regular-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-Regular-tosf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBold-sup-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBold-sup-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBold-sup-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBold-sup-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBold-sup-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBold-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBold-tlf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBold-tlf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBold-tlf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBold-tlf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBold-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBold-tlf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBold-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBold-tosf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBold-tosf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBold-tosf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBold-tosf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBold-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBold-tosf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBoldItalic-sup-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBoldItalic-sup-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBoldItalic-sup-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBoldItalic-sup-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBoldItalic-sup-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBoldItalic-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBoldItalic-tlf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBoldItalic-tlf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBoldItalic-tlf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBoldItalic-tlf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBoldItalic-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBoldItalic-tlf-ts1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBoldItalic-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBoldItalic-tosf-ly1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBoldItalic-tosf-ot1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBoldItalic-tosf-t1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBoldItalic-tosf-t1.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBoldItalic-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/nunito/Nunito-SemiBoldItalic-tosf-ts1.tfm + RELOC/fonts/type1/public/nunito/Nunito-Black.pfb + RELOC/fonts/type1/public/nunito/Nunito-BlackItalic.pfb + RELOC/fonts/type1/public/nunito/Nunito-Bold.pfb + RELOC/fonts/type1/public/nunito/Nunito-BoldItalic.pfb + RELOC/fonts/type1/public/nunito/Nunito-ExtraBold.pfb + RELOC/fonts/type1/public/nunito/Nunito-ExtraBoldItalic.pfb + RELOC/fonts/type1/public/nunito/Nunito-ExtraLight.pfb + RELOC/fonts/type1/public/nunito/Nunito-ExtraLightItalic.pfb + RELOC/fonts/type1/public/nunito/Nunito-Italic.pfb + RELOC/fonts/type1/public/nunito/Nunito-Light.pfb + RELOC/fonts/type1/public/nunito/Nunito-LightItalic.pfb + RELOC/fonts/type1/public/nunito/Nunito-Regular.pfb + RELOC/fonts/type1/public/nunito/Nunito-SemiBold.pfb + RELOC/fonts/type1/public/nunito/Nunito-SemiBoldItalic.pfb + RELOC/fonts/vf/public/nunito/Nunito-Black-sup-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-Black-sup-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-Black-tlf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-Black-tlf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-Black-tlf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-Black-tosf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-Black-tosf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-Black-tosf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-BlackItalic-sup-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-BlackItalic-sup-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-BlackItalic-tlf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-BlackItalic-tlf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-BlackItalic-tlf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-BlackItalic-tosf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-BlackItalic-tosf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-BlackItalic-tosf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-Bold-sup-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-Bold-sup-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-Bold-tlf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-Bold-tlf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-Bold-tlf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-Bold-tosf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-Bold-tosf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-Bold-tosf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-BoldItalic-sup-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-BoldItalic-sup-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-BoldItalic-tlf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-BoldItalic-tlf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-BoldItalic-tlf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-BoldItalic-tosf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-BoldItalic-tosf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-BoldItalic-tosf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraBold-sup-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraBold-sup-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraBold-tlf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraBold-tlf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraBold-tlf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraBold-tosf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraBold-tosf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraBold-tosf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraBoldItalic-sup-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraBoldItalic-sup-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraBoldItalic-tlf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraBoldItalic-tlf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraBoldItalic-tlf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraBoldItalic-tosf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraBoldItalic-tosf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraBoldItalic-tosf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraLight-sup-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraLight-sup-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraLight-tlf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraLight-tlf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraLight-tlf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraLight-tosf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraLight-tosf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraLight-tosf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraLightItalic-sup-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraLightItalic-sup-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraLightItalic-tlf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraLightItalic-tlf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraLightItalic-tlf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraLightItalic-tosf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraLightItalic-tosf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-ExtraLightItalic-tosf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-Italic-sup-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-Italic-sup-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-Italic-tlf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-Italic-tlf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-Italic-tlf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-Italic-tosf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-Italic-tosf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-Italic-tosf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-Light-sup-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-Light-sup-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-Light-tlf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-Light-tlf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-Light-tlf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-Light-tosf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-Light-tosf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-Light-tosf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-LightItalic-sup-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-LightItalic-sup-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-LightItalic-tlf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-LightItalic-tlf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-LightItalic-tlf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-LightItalic-tosf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-LightItalic-tosf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-LightItalic-tosf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-Regular-sup-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-Regular-sup-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-Regular-tlf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-Regular-tlf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-Regular-tlf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-Regular-tosf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-Regular-tosf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-Regular-tosf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-SemiBold-sup-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-SemiBold-sup-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-SemiBold-tlf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-SemiBold-tlf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-SemiBold-tlf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-SemiBold-tosf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-SemiBold-tosf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-SemiBold-tosf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-SemiBoldItalic-sup-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-SemiBoldItalic-sup-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-SemiBoldItalic-tlf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-SemiBoldItalic-tlf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-SemiBoldItalic-tlf-ts1.vf + RELOC/fonts/vf/public/nunito/Nunito-SemiBoldItalic-tosf-ly1.vf + RELOC/fonts/vf/public/nunito/Nunito-SemiBoldItalic-tosf-t1.vf + RELOC/fonts/vf/public/nunito/Nunito-SemiBoldItalic-tosf-ts1.vf + RELOC/tex/latex/nunito/LY1Nunito-Sup.fd + RELOC/tex/latex/nunito/LY1Nunito-TLF.fd + RELOC/tex/latex/nunito/LY1Nunito-TOsF.fd + RELOC/tex/latex/nunito/OT1Nunito-Sup.fd + RELOC/tex/latex/nunito/OT1Nunito-TLF.fd + RELOC/tex/latex/nunito/OT1Nunito-TOsF.fd + RELOC/tex/latex/nunito/T1Nunito-Sup.fd + RELOC/tex/latex/nunito/T1Nunito-TLF.fd + RELOC/tex/latex/nunito/T1Nunito-TOsF.fd + RELOC/tex/latex/nunito/TS1Nunito-TLF.fd + RELOC/tex/latex/nunito/TS1Nunito-TOsF.fd + RELOC/tex/latex/nunito/nunito.sty +catalogue-contact-repository https://github.com/ccebinger/CTAN_Nunito +catalogue-ctan /fonts/nunito +catalogue-license ofl lppl +catalogue-topics font font-body font-sans font-proportional font-otf font-type1 font-supp font-t1enc +catalogue-version 0.0.1 + name nwejm category Package revision 54392 @@ -247417,7 +247873,7 @@ catalogue-version 0.35 name pslatex category Package -revision 16416 +revision 57434 shortdesc Use PostScript fonts by default relocated 1 longdesc A small package that makes LaTeX default to 'standard' @@ -247435,10 +247891,10 @@ longdesc different technique for scaling Helvetica, and treats Courier longdesc as a lost cause (there are better free fixed-width available longdesc now, than there were when pslatex was designed). As a result, longdesc pslatex is widely considered obsolete. -containersize 5748 -containerchecksum 4e6c2163fe9d8573012cde55d7a9686d45276617d6368a2191b2ca5ecd9e2e88f9ea07d638c726cfb43f0fddb5d8c8b1b8ca1eb58177517b6704776f792630db -srccontainersize 1204 -srccontainerchecksum 27e8f6f5c30338cccfded6805b713b74b6139841ad81a10a4a06ff5acd5a189733e2d6fdc80c2483c5fc8beececfb91a0a9d03202bc44fea753ee6bfda9fe649 +containersize 5824 +containerchecksum 64dc0f10f3aaa78a4d611d21601e5fb3f27c7c97bcf04f5dd3192f5253660edc862481f3b1bcb8b18b6cc07a6064e78953c31470bf36bc70103f2a83374483c4 +srccontainersize 1200 +srccontainerchecksum 086805aaf0b61b8e3e561627388ea1af67ef8dba3a0b5808ef3d9719652e76abf4353345ca2096e31fb33c9c960b01b4972754f29532a25e91ad59dc6c1d6cae srcfiles size=3 RELOC/source/latex/pslatex/fontinst/pslatex.tex RELOC/source/latex/pslatex/shell/pslatex @@ -247451,9 +247907,12 @@ runfiles size=9 RELOC/fonts/vf/public/pslatex/pcrr7tn.vf RELOC/fonts/vf/public/pslatex/pcrr8tn.vf RELOC/tex/latex/pslatex/pslatex.sty +catalogue-contact-bugs https://github.com/davidcarlisle/dpctex/issues +catalogue-contact-repository https://github.com/davidcarlisle/dpctex catalogue-ctan /macros/latex/contrib/pslatex catalogue-license lppl catalogue-topics font-supp obsolete +catalogue-version 1.3 name psnfss category Package @@ -257729,17 +258188,17 @@ catalogue-version 1.11 name readablecv category Package -revision 55190 +revision 57433 shortdesc A highly readable and good looking CV and letter class relocated 1 longdesc This class provides, what I have found, to be an extremely longdesc attractive and highly readable CV which will lead to your CV longdesc being read rather than disgarded. -containersize 3636 -containerchecksum 54d42ad6b7e25cbc6f80f0ea960b230a082e30a15cd4d67ac21b6a941e16aac859195e7445a1067a16fbd83ee2a74e942ee9a8f88ec6e5202424ed793f2e005e -doccontainersize 166356 -doccontainerchecksum 01a03842ff5aa895e257beedfef8cd9d01014a122244e70c74ccc307e72c73a2727a74b570cd8b61a78889b8a31fba7b3c61614a3dd9bff5aa7b4f5faa54fed3 -docfiles size=45 +containersize 3896 +containerchecksum 2165f742cfad485942ec3ce085c3f9eeb7de1b75028020f143661e69a8694ea4f321779c79ac04895771170310e85e4f9019a86ffea0cc4cce97eab2f4ae055a +doccontainersize 207536 +doccontainerchecksum 78d4721ac35a4361141f0a1d84a5d7d7a416976a1e8445f96c02963fbd924e86555f6c0c7a7beaba1573b9488086be4a3b65ae826ae7db3e16de6e386fee2fda +docfiles size=57 RELOC/doc/latex/readablecv/README.md details="Readme" RELOC/doc/latex/readablecv/ReadableCV.pdf details="Package documentation" RELOC/doc/latex/readablecv/ReadableCV.tex @@ -257751,7 +258210,7 @@ catalogue-contact-home https://philipstone.co.uk/type.html catalogue-ctan /macros/latex/contrib/readablecv catalogue-license lppl1.3 catalogue-topics class cv -catalogue-version 2.0 +catalogue-version 3.0 name readarray category Package @@ -278966,7 +279425,7 @@ catalogue-version 1.1.3 name stix2-otf category Package -revision 54080 +revision 57427 shortdesc OpenType Unicode text and maths fonts relocated 1 longdesc The Scientific and Technical Information eXchange (STIX) fonts @@ -278977,25 +279436,29 @@ longdesc Unicode-based collection of mathematical symbols and alphabets longdesc with a set of text faces suitable for professional publishing. longdesc The fonts are available royalty-free under the SIL Open Font longdesc License. -containersize 686984 -containerchecksum c4e3a28d7865d0448c8a7dda406e2e2c1a34943b4aed1ed67732134a84e1f5c92b9f57cdcf2836b39221aa4dadf91812c2404a01ba08b658c044c381065af473 -doccontainersize 1780248 -doccontainerchecksum f94f8570c8b99f4eabab76473ae541438b5982154f4fd8c9b8de6c6024ecf817063de52259049c142d7145126c90431abedb8663d01c30593a7ccf877e040767 -docfiles size=513 +containersize 1383744 +containerchecksum 3bd27d08e0112039d35e37e3e026e1f88e0d2fb8c02955447bf68ac379767dce82d3c68415489afb606c753a5ddee5df4cdba905d178ba23f7d3bcc961f6aa20 +doccontainersize 1219820 +doccontainerchecksum 0dffc7f54f04deeca5f42e91a66e2a5c5de9d097058ce09bc7518b32efb2116cf647a4eadad18d9b56976959b3db8e1ca4d8d5542ef558e4010f91597eae972c +docfiles size=363 + RELOC/doc/fonts/stix2-otf/AUTHORS.txt + RELOC/doc/fonts/stix2-otf/CONTRIBUTORS.txt + RELOC/doc/fonts/stix2-otf/FONTLOG.txt + RELOC/doc/fonts/stix2-otf/OFL-FAQ.txt + RELOC/doc/fonts/stix2-otf/OFL.txt RELOC/doc/fonts/stix2-otf/README.md details="Readme" - RELOC/doc/fonts/stix2-otf/STIX_2.0.1_license.pdf - RELOC/doc/fonts/stix2-otf/STIX_2.0.1_release_notes.txt - RELOC/doc/fonts/stix2-otf/StixTwoBold.pdf - RELOC/doc/fonts/stix2-otf/StixTwoBoldItalic.pdf - RELOC/doc/fonts/stix2-otf/StixTwoItalic.pdf - RELOC/doc/fonts/stix2-otf/StixTwoMath.pdf details="Package documentation" - RELOC/doc/fonts/stix2-otf/StixTwoRegular.pdf -runfiles size=569 - RELOC/fonts/opentype/public/stix2-otf/STIX2Math.otf - RELOC/fonts/opentype/public/stix2-otf/STIX2Text-Bold.otf - RELOC/fonts/opentype/public/stix2-otf/STIX2Text-BoldItalic.otf - RELOC/fonts/opentype/public/stix2-otf/STIX2Text-Italic.otf - RELOC/fonts/opentype/public/stix2-otf/STIX2Text-Regular.otf + RELOC/doc/fonts/stix2-otf/STIXTwoMath-Regular.pdf details="Package documentation" + RELOC/doc/fonts/stix2-otf/STIXTwoText-Regular.pdf details="Further Package documentation" +runfiles size=814 + RELOC/fonts/opentype/public/stix2-otf/STIXTwoMath-Regular.otf + RELOC/fonts/opentype/public/stix2-otf/STIXTwoText-Bold.otf + RELOC/fonts/opentype/public/stix2-otf/STIXTwoText-BoldItalic.otf + RELOC/fonts/opentype/public/stix2-otf/STIXTwoText-Italic.otf + RELOC/fonts/opentype/public/stix2-otf/STIXTwoText-Medium.otf + RELOC/fonts/opentype/public/stix2-otf/STIXTwoText-MediumItalic.otf + RELOC/fonts/opentype/public/stix2-otf/STIXTwoText-Regular.otf + RELOC/fonts/opentype/public/stix2-otf/STIXTwoText-SemiBold.otf + RELOC/fonts/opentype/public/stix2-otf/STIXTwoText-SemiBoldItalic.otf catalogue-also stickstoo catalogue-contact-bugs https://github.com/stipub/stixfonts/issues catalogue-contact-home http://www.stixfonts.org/ @@ -279003,11 +279466,11 @@ catalogue-contact-repository https://github.com/stipub/stixfonts catalogue-ctan /fonts/stix2-otf catalogue-license ofl catalogue-topics font font-otf font-maths font-symbol font-symbol-maths font-body font-collection font-nonroman font-serif -catalogue-version 2.0.1 +catalogue-version 2.11 name stix2-type1 category Package -revision 54512 +revision 57430 shortdesc Type1 versions of the STIX Two OpenType fonts relocated 1 longdesc The stix2 package provides minimal support for using the STIX @@ -279026,141 +279489,129 @@ longdesc versions. In addition, while development of the OpenType longdesc versions is ongoing, no further updates are planned to the Type longdesc 1 versions of the fonts. execute addMap stix2.map -containersize 3171312 -containerchecksum 4a4600e3f579c5d04a2b51d2fccaad2d7134daf2e0e22d4956c52a78df3febbbce1abc0d0c74bf087b3e1ac598fac29992900481398a364ffa79d64dcb9bbcd5 -doccontainersize 1331724 -doccontainerchecksum 417df8a3cf6e9195dfa74719b5de690a5d3e464fc10f1ebea811ff7df352dda592fbbd65dd62f630a4b85fa5b817768833cad915666da353ad074d9cec314ef8 -docfiles size=328 - RELOC/doc/latex/stix2/README.md details="Readme" - RELOC/doc/latex/stix2/stix2.pdf details="Package documentation" -srccontainersize 28004 -srccontainerchecksum aac691a5e949b0a4cd74bbc8a2617bb50ca9db01c0e118101e60911037afec3b4f694dfe722edc653594cb4f4ff5452c4f55424abe3ed4a2e3b1f8cc6eb1b8b0 +containersize 3109488 +containerchecksum 9d4db9e8fa1a56f99bc63e088091773d0acda5f65d0f411855dec3d38b0d9b65e77d8932505c6336a25483f1abf669961aae122bd2f2a399510b4864fd923dc5 +doccontainersize 1393064 +doccontainerchecksum 82c1dd6e760cd18c8f6edc16528a788526914f8743f5fa3c875fb20fa90c33442775cf16943a7473da37d50e721843ac2370ac22453295f4a9a70dcad594d4ec +docfiles size=1063 + RELOC/doc/fonts/stix2-type1/README.md details="Readme" + RELOC/doc/fonts/stix2-type1/ot1-stix2text-bold.pl + RELOC/doc/fonts/stix2-type1/ot1-stix2text-bolditalic.pl + RELOC/doc/fonts/stix2-type1/ot1-stix2text-italic.pl + RELOC/doc/fonts/stix2-type1/ot1-stix2text.pl + RELOC/doc/fonts/stix2-type1/ot1-stix2textsc-bold.pl + RELOC/doc/fonts/stix2-type1/ot1-stix2textsc.pl + RELOC/doc/fonts/stix2-type1/ot2-stix2text-bold.pl + RELOC/doc/fonts/stix2-type1/ot2-stix2text-bolditalic.pl + RELOC/doc/fonts/stix2-type1/ot2-stix2text-italic.pl + RELOC/doc/fonts/stix2-type1/ot2-stix2text.pl + RELOC/doc/fonts/stix2-type1/ot2-stix2textsc-bold.pl + RELOC/doc/fonts/stix2-type1/ot2-stix2textsc.pl + RELOC/doc/fonts/stix2-type1/stix2-mathbb.pl + RELOC/doc/fonts/stix2-type1/stix2-mathbbit.pl + RELOC/doc/fonts/stix2-type1/stix2-mathcal.pl + RELOC/doc/fonts/stix2-type1/stix2-mathex.pl + RELOC/doc/fonts/stix2-type1/stix2-mathfrak-bold.pl + RELOC/doc/fonts/stix2-type1/stix2-mathfrak.pl + RELOC/doc/fonts/stix2-type1/stix2-mathit-bold.pl + RELOC/doc/fonts/stix2-type1/stix2-mathit.pl + RELOC/doc/fonts/stix2-type1/stix2-mathrm-bold.pl + RELOC/doc/fonts/stix2-type1/stix2-mathrm.pl + RELOC/doc/fonts/stix2-type1/stix2-mathscr-bold.pl + RELOC/doc/fonts/stix2-type1/stix2-mathscr.pl + RELOC/doc/fonts/stix2-type1/stix2-mathsf-bold.pl + RELOC/doc/fonts/stix2-type1/stix2-mathsf.pl + RELOC/doc/fonts/stix2-type1/stix2-mathsfit-bold.pl + RELOC/doc/fonts/stix2-type1/stix2-mathsfit.pl + RELOC/doc/fonts/stix2-type1/stix2-mathtt.pl + RELOC/doc/fonts/stix2-type1/stix2.pdf details="Package documentation" + RELOC/doc/fonts/stix2-type1/t1-stix2text-bold.pl + RELOC/doc/fonts/stix2-type1/t1-stix2text-bolditalic.pl + RELOC/doc/fonts/stix2-type1/t1-stix2text-italic.pl + RELOC/doc/fonts/stix2-type1/t1-stix2text.pl + RELOC/doc/fonts/stix2-type1/t1-stix2textsc-bold.pl + RELOC/doc/fonts/stix2-type1/t1-stix2textsc.pl + RELOC/doc/fonts/stix2-type1/ts1-stix2text-bold.pl + RELOC/doc/fonts/stix2-type1/ts1-stix2text-bolditalic.pl + RELOC/doc/fonts/stix2-type1/ts1-stix2text-italic.pl + RELOC/doc/fonts/stix2-type1/ts1-stix2text.pl +srccontainersize 28080 +srccontainerchecksum 6ecf5aff826b8a9fff867e8768486e3b112df44679399b8b6ef30eb2ac00dff0b4cf531d871a90c8a793d3300656bc3d15454c9628a907e13cb8aa71fabe7647 srcfiles size=52 - RELOC/source/latex/stix2/stix2.dtx - RELOC/source/latex/stix2/stix2.fdd -runfiles size=1665 - RELOC/fonts/enc/dvips/stix2/stix2-mathbb.enc - RELOC/fonts/enc/dvips/stix2/stix2-mathbbit.enc - RELOC/fonts/enc/dvips/stix2/stix2-mathcal.enc - RELOC/fonts/enc/dvips/stix2/stix2-mathex.enc - RELOC/fonts/enc/dvips/stix2/stix2-mathfrak-bold.enc - RELOC/fonts/enc/dvips/stix2/stix2-mathfrak.enc - RELOC/fonts/enc/dvips/stix2/stix2-mathit-bold.enc - RELOC/fonts/enc/dvips/stix2/stix2-mathit.enc - RELOC/fonts/enc/dvips/stix2/stix2-mathrm-bold.enc - RELOC/fonts/enc/dvips/stix2/stix2-mathrm.enc - RELOC/fonts/enc/dvips/stix2/stix2-mathscr-bold.enc - RELOC/fonts/enc/dvips/stix2/stix2-mathscr.enc - RELOC/fonts/enc/dvips/stix2/stix2-mathsf-bold.enc - RELOC/fonts/enc/dvips/stix2/stix2-mathsf.enc - RELOC/fonts/enc/dvips/stix2/stix2-mathsfit-bold.enc - RELOC/fonts/enc/dvips/stix2/stix2-mathsfit.enc - RELOC/fonts/enc/dvips/stix2/stix2-mathtt.enc - RELOC/fonts/enc/dvips/stix2/stix2-ot1.enc - RELOC/fonts/enc/dvips/stix2/stix2-ot1sc.enc - RELOC/fonts/enc/dvips/stix2/stix2-ot2.enc - RELOC/fonts/enc/dvips/stix2/stix2-ot2sc.enc - RELOC/fonts/enc/dvips/stix2/stix2-t1.enc - RELOC/fonts/enc/dvips/stix2/stix2-t1sc.enc - RELOC/fonts/enc/dvips/stix2/stix2-ts1.enc - RELOC/fonts/map/dvips/stix2/stix2.map - RELOC/fonts/source/public/stix2/ot1-stix2text-bold.pl - RELOC/fonts/source/public/stix2/ot1-stix2text-bolditalic.pl - RELOC/fonts/source/public/stix2/ot1-stix2text-italic.pl - RELOC/fonts/source/public/stix2/ot1-stix2text.pl - RELOC/fonts/source/public/stix2/ot1-stix2textsc-bold.pl - RELOC/fonts/source/public/stix2/ot1-stix2textsc.pl - RELOC/fonts/source/public/stix2/ot2-stix2text-bold.pl - RELOC/fonts/source/public/stix2/ot2-stix2text-bolditalic.pl - RELOC/fonts/source/public/stix2/ot2-stix2text-italic.pl - RELOC/fonts/source/public/stix2/ot2-stix2text.pl - RELOC/fonts/source/public/stix2/ot2-stix2textsc-bold.pl - RELOC/fonts/source/public/stix2/ot2-stix2textsc.pl - RELOC/fonts/source/public/stix2/stix2-mathbb.pl - RELOC/fonts/source/public/stix2/stix2-mathbbit.pl - RELOC/fonts/source/public/stix2/stix2-mathcal.pl - RELOC/fonts/source/public/stix2/stix2-mathex.pl - RELOC/fonts/source/public/stix2/stix2-mathfrak-bold.pl - RELOC/fonts/source/public/stix2/stix2-mathfrak.pl - RELOC/fonts/source/public/stix2/stix2-mathit-bold.pl - RELOC/fonts/source/public/stix2/stix2-mathit.pl - RELOC/fonts/source/public/stix2/stix2-mathrm-bold.pl - RELOC/fonts/source/public/stix2/stix2-mathrm.pl - RELOC/fonts/source/public/stix2/stix2-mathscr-bold.pl - RELOC/fonts/source/public/stix2/stix2-mathscr.pl - RELOC/fonts/source/public/stix2/stix2-mathsf-bold.pl - RELOC/fonts/source/public/stix2/stix2-mathsf.pl - RELOC/fonts/source/public/stix2/stix2-mathsfit-bold.pl - RELOC/fonts/source/public/stix2/stix2-mathsfit.pl - RELOC/fonts/source/public/stix2/stix2-mathtt.pl - RELOC/fonts/source/public/stix2/t1-stix2text-bold.pl - RELOC/fonts/source/public/stix2/t1-stix2text-bolditalic.pl - RELOC/fonts/source/public/stix2/t1-stix2text-italic.pl - RELOC/fonts/source/public/stix2/t1-stix2text.pl - RELOC/fonts/source/public/stix2/t1-stix2textsc-bold.pl - RELOC/fonts/source/public/stix2/t1-stix2textsc.pl - RELOC/fonts/source/public/stix2/ts1-stix2text-bold.pl - RELOC/fonts/source/public/stix2/ts1-stix2text-bolditalic.pl - RELOC/fonts/source/public/stix2/ts1-stix2text-italic.pl - RELOC/fonts/source/public/stix2/ts1-stix2text.pl - RELOC/fonts/tfm/public/stix2/ot1-stix2text-bold.tfm - RELOC/fonts/tfm/public/stix2/ot1-stix2text-bolditalic.tfm - RELOC/fonts/tfm/public/stix2/ot1-stix2text-italic.tfm - RELOC/fonts/tfm/public/stix2/ot1-stix2text.tfm - RELOC/fonts/tfm/public/stix2/ot1-stix2textsc-bold.tfm - RELOC/fonts/tfm/public/stix2/ot1-stix2textsc.tfm - RELOC/fonts/tfm/public/stix2/ot2-stix2text-bold.tfm - RELOC/fonts/tfm/public/stix2/ot2-stix2text-bolditalic.tfm - RELOC/fonts/tfm/public/stix2/ot2-stix2text-italic.tfm - RELOC/fonts/tfm/public/stix2/ot2-stix2text.tfm - RELOC/fonts/tfm/public/stix2/ot2-stix2textsc-bold.tfm - RELOC/fonts/tfm/public/stix2/ot2-stix2textsc.tfm - RELOC/fonts/tfm/public/stix2/stix2-mathbb.tfm - RELOC/fonts/tfm/public/stix2/stix2-mathbbit.tfm - RELOC/fonts/tfm/public/stix2/stix2-mathcal.tfm - RELOC/fonts/tfm/public/stix2/stix2-mathex.tfm - RELOC/fonts/tfm/public/stix2/stix2-mathfrak-bold.tfm - RELOC/fonts/tfm/public/stix2/stix2-mathfrak.tfm - RELOC/fonts/tfm/public/stix2/stix2-mathit-bold.tfm - RELOC/fonts/tfm/public/stix2/stix2-mathit.tfm - RELOC/fonts/tfm/public/stix2/stix2-mathrm-bold.tfm - RELOC/fonts/tfm/public/stix2/stix2-mathrm.tfm - RELOC/fonts/tfm/public/stix2/stix2-mathscr-bold.tfm - RELOC/fonts/tfm/public/stix2/stix2-mathscr.tfm - RELOC/fonts/tfm/public/stix2/stix2-mathsf-bold.tfm - RELOC/fonts/tfm/public/stix2/stix2-mathsf.tfm - RELOC/fonts/tfm/public/stix2/stix2-mathsfit-bold.tfm - RELOC/fonts/tfm/public/stix2/stix2-mathsfit.tfm - RELOC/fonts/tfm/public/stix2/stix2-mathtt.tfm - RELOC/fonts/tfm/public/stix2/t1-stix2text-bold.tfm - RELOC/fonts/tfm/public/stix2/t1-stix2text-bolditalic.tfm - RELOC/fonts/tfm/public/stix2/t1-stix2text-italic.tfm - RELOC/fonts/tfm/public/stix2/t1-stix2text.tfm - RELOC/fonts/tfm/public/stix2/t1-stix2textsc-bold.tfm - RELOC/fonts/tfm/public/stix2/t1-stix2textsc.tfm - RELOC/fonts/tfm/public/stix2/ts1-stix2text-bold.tfm - RELOC/fonts/tfm/public/stix2/ts1-stix2text-bolditalic.tfm - RELOC/fonts/tfm/public/stix2/ts1-stix2text-italic.tfm - RELOC/fonts/tfm/public/stix2/ts1-stix2text.tfm - RELOC/fonts/type1/public/stix2/STIX2Math.pfb - RELOC/fonts/type1/public/stix2/STIX2Text-Bold.pfb - RELOC/fonts/type1/public/stix2/STIX2Text-BoldItalic.pfb - RELOC/fonts/type1/public/stix2/STIX2Text-Italic.pfb - RELOC/fonts/type1/public/stix2/STIX2Text-Regular.pfb - RELOC/tex/latex/stix2/ls1stix2.fd - RELOC/tex/latex/stix2/ls1stix2bb.fd - RELOC/tex/latex/stix2/ls1stix2frak.fd - RELOC/tex/latex/stix2/ls1stix2scr.fd - RELOC/tex/latex/stix2/ls1stix2sf.fd - RELOC/tex/latex/stix2/ls2stix2.fd - RELOC/tex/latex/stix2/ls2stix2cal.fd - RELOC/tex/latex/stix2/ls2stix2ex.fd - RELOC/tex/latex/stix2/ls2stix2tt.fd - RELOC/tex/latex/stix2/ot1stix2.fd - RELOC/tex/latex/stix2/ot2stix2.fd - RELOC/tex/latex/stix2/stix2.sty - RELOC/tex/latex/stix2/t1stix2.fd - RELOC/tex/latex/stix2/ts1stix2.fd + RELOC/source/fonts/stix2-type1/stix2.dtx + RELOC/source/fonts/stix2-type1/stix2.fdd + RELOC/source/fonts/stix2-type1/stix2.ins +runfiles size=917 + RELOC/fonts/enc/dvips/stix2-type1/stix2-mathbb.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-mathbbit.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-mathcal.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-mathex.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-mathfrak-bold.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-mathfrak.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-mathit-bold.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-mathit.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-mathrm-bold.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-mathrm.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-mathscr-bold.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-mathscr.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-mathsf-bold.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-mathsf.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-mathsfit-bold.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-mathsfit.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-mathtt.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-ot1.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-ot1sc.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-ot2.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-ot2sc.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-t1.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-t1sc.enc + RELOC/fonts/enc/dvips/stix2-type1/stix2-ts1.enc + RELOC/fonts/map/dvips/stix2-type1/stix2.map + RELOC/fonts/tfm/public/stix2-type1/ot1-stix2text-bold.tfm + RELOC/fonts/tfm/public/stix2-type1/ot1-stix2text-bolditalic.tfm + RELOC/fonts/tfm/public/stix2-type1/ot1-stix2text-italic.tfm + RELOC/fonts/tfm/public/stix2-type1/ot1-stix2text.tfm + RELOC/fonts/tfm/public/stix2-type1/ot1-stix2textsc-bold.tfm + RELOC/fonts/tfm/public/stix2-type1/ot1-stix2textsc.tfm + RELOC/fonts/tfm/public/stix2-type1/ot2-stix2text-bold.tfm + RELOC/fonts/tfm/public/stix2-type1/ot2-stix2text-bolditalic.tfm + RELOC/fonts/tfm/public/stix2-type1/ot2-stix2text-italic.tfm + RELOC/fonts/tfm/public/stix2-type1/ot2-stix2text.tfm + RELOC/fonts/tfm/public/stix2-type1/ot2-stix2textsc-bold.tfm + RELOC/fonts/tfm/public/stix2-type1/ot2-stix2textsc.tfm + RELOC/fonts/tfm/public/stix2-type1/stix2-mathbb.tfm + RELOC/fonts/tfm/public/stix2-type1/stix2-mathbbit.tfm + RELOC/fonts/tfm/public/stix2-type1/stix2-mathcal.tfm + RELOC/fonts/tfm/public/stix2-type1/stix2-mathex.tfm + RELOC/fonts/tfm/public/stix2-type1/stix2-mathfrak-bold.tfm + RELOC/fonts/tfm/public/stix2-type1/stix2-mathfrak.tfm + RELOC/fonts/tfm/public/stix2-type1/stix2-mathit-bold.tfm + RELOC/fonts/tfm/public/stix2-type1/stix2-mathit.tfm + RELOC/fonts/tfm/public/stix2-type1/stix2-mathrm-bold.tfm + RELOC/fonts/tfm/public/stix2-type1/stix2-mathrm.tfm + RELOC/fonts/tfm/public/stix2-type1/stix2-mathscr-bold.tfm + RELOC/fonts/tfm/public/stix2-type1/stix2-mathscr.tfm + RELOC/fonts/tfm/public/stix2-type1/stix2-mathsf-bold.tfm + RELOC/fonts/tfm/public/stix2-type1/stix2-mathsf.tfm + RELOC/fonts/tfm/public/stix2-type1/stix2-mathsfit-bold.tfm + RELOC/fonts/tfm/public/stix2-type1/stix2-mathsfit.tfm + RELOC/fonts/tfm/public/stix2-type1/stix2-mathtt.tfm + RELOC/fonts/tfm/public/stix2-type1/t1-stix2text-bold.tfm + RELOC/fonts/tfm/public/stix2-type1/t1-stix2text-bolditalic.tfm + RELOC/fonts/tfm/public/stix2-type1/t1-stix2text-italic.tfm + RELOC/fonts/tfm/public/stix2-type1/t1-stix2text.tfm + RELOC/fonts/tfm/public/stix2-type1/t1-stix2textsc-bold.tfm + RELOC/fonts/tfm/public/stix2-type1/t1-stix2textsc.tfm + RELOC/fonts/tfm/public/stix2-type1/ts1-stix2text-bold.tfm + RELOC/fonts/tfm/public/stix2-type1/ts1-stix2text-bolditalic.tfm + RELOC/fonts/tfm/public/stix2-type1/ts1-stix2text-italic.tfm + RELOC/fonts/tfm/public/stix2-type1/ts1-stix2text.tfm + RELOC/fonts/type1/public/stix2-type1/STIX2Math.pfb + RELOC/fonts/type1/public/stix2-type1/STIX2Text-Bold.pfb + RELOC/fonts/type1/public/stix2-type1/STIX2Text-BoldItalic.pfb + RELOC/fonts/type1/public/stix2-type1/STIX2Text-Italic.pfb + RELOC/fonts/type1/public/stix2-type1/STIX2Text-Regular.pfb + RELOC/tex/latex/stix2-type1/stix2.sty catalogue-also stickstoo catalogue-contact-bugs https://github.com/stipub/stixfonts/issues catalogue-contact-development https://github.com/stipub/stixfonts @@ -279168,7 +279619,7 @@ catalogue-contact-home http://www.stixfonts.org/ catalogue-ctan /fonts/stix2-type1 catalogue-license ofl lppl1.3 catalogue-topics font font-type1 font-maths font-symbol-maths font-bbd font-body font-collection font-nonroman font-otf font-serif font-symbol font-supp font-supp-maths font-supp-symbol -catalogue-version 2.0.0a +catalogue-version 2.0.1 name stmaryrd category Package @@ -295218,7 +295669,7 @@ docfiles size=368 name texlive-scripts category TLCore -revision 57407 +revision 57423 shortdesc TeX Live infrastructure programs longdesc Includes install-tl, tl-portable, rungs, etc.; not needed for longdesc tlmgr to run but still ours. Not included in tlcritical. @@ -295226,10 +295677,10 @@ depend texlive-scripts.ARCH depend texlive.infra execute addMap mathpple.map postaction shortcut type=menu name="TeX Live command-line" cmd=TEXDIR/tlpkg/installer/tl-cmd.bat -containersize 132172 -containerchecksum c0ff227d24c0186ae348199d77dd478478d5b8b18ba2c0810496bb0715909e7f591d8dba8c7be744c4cf8793156f428a2c20cee242c31473de2c6f8103e1e277 +containersize 132192 +containerchecksum 501c2392b79fa52c1bba04c738d1690c10d2681ae2c9f2cd387b4030b0d703cb47c12e42e4b94d32fbccbc94dc13dc28340130818d9023d4b8715fef4388701e doccontainersize 218820 -doccontainerchecksum d7f2af8557930793722c637f3ba2d1d468bfe8f20b4d6ef54d5e4b68f42423f45cce95468cbb5c659b813543a53c1eef7a3b45511b4bfd6cb9df7244e90a7728 +doccontainerchecksum 6616d01dd2472d6a2866b54f7d73c49e3571dd9581363570020afe8a844b4d7c0d49dc756fe104b62a6069f49ac1edbf1b93bdaa2ff9997e3690cae5c52e9d41 docfiles size=141 texmf-dist/doc/man/man1/fmtutil-sys.1 texmf-dist/doc/man/man1/fmtutil-sys.man1.pdf @@ -306857,14 +307308,14 @@ binfiles arch=win32 size=5 name tlshell category TLCore -revision 56461 +revision 57426 shortdesc GUI frontend (tcl/tk-based) for tlmgr depend tlshell.ARCH postaction shortcut type=menu name="TeX Live Manager" cmd=TEXDIR/bin/win32/tlshell.exe -containersize 26836 -containerchecksum 8223b473aa8b02c1bc0b7552d3d023f3629aaaf807699f41c723191a5dacb3cb62165eed5562eaba6ea67a8b22baa0736b7a281c5c1a69d7577b435ef5d37fed +containersize 27380 +containerchecksum a31ce082a98760d9ce611fcd76cd44c3d60962500fd33a99cafb6422827af20ee94ebfe54d39b66099d52e09f5ecf7ed6d917517a97629770398a31b5d8e385e doccontainersize 440 -doccontainerchecksum 3a15c4464ee8d5dddcc30882573d0069e93884a52f3ef24a3b7fe8f273db256cfb7f7bc87f7b68e266ed9840127cd0eb65a98a2e2554f4da470cbaf198d4e481 +doccontainerchecksum 5a815bdd40d1bf0735895a82d1ea0836bcae5445d0060f3f3bc3dd7c2caae457b642ab99f56f4d01d60aa40c07580dbc83d12a80df063cb3bc16f85a04c05b6b docfiles size=1 texmf-dist/doc/support/tlshell/README runfiles size=27 diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 index fcbaffb0d6..8ae755a297 100644 --- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 +++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 @@ -1 +1 @@ -4fa22d7b072994bf5e8f3b8eac1894c3 texlive.tlpdb +7bbeac9f391c74941528a2d5193cca1e texlive.tlpdb diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 index aedbcd0777..bac158f088 100644 --- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 +++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 @@ -1 +1 @@ -096a5606f5e8552f220f49eca5a26c1714b99922ed2486b8facbe46a2b6c191c3549b849fe851512697ff233789322245bc53264494c055124d442b2b98d4736 texlive.tlpdb +ab6a89c07402715cc5030b0d8430d189bbbcf8fe294db3a4c7dd5f578f709780e09fff6fba7679de519fe7592afc2e961a7bf07d852e4eba48c12f2d89a62d5e texlive.tlpdb diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc index a6189c40c6..18231553db 100644 --- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc +++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc @@ -1,10 +1,10 @@ -----BEGIN PGP SIGNATURE----- -iQEcBAEBCgAGBQJgAOhzAAoJEEzhh34ZQ4xw+VkH/15D97Jwh0OjakRzOzgS8BSp -5b/503Tdjw1v2UucXWnDvpcZnzBRZHMEoOf6+bTMEHdZvCVXh1Ie+87FKlrnre1s -w+E8mxQJpcdGkCHf9b1sRf1yvkbb3jZ5Pfikq11QJVkLtNSW+NTpcxpqeBhdixz1 -+62gwSY0Yuj3ysGkk3xIOdhcHplDxsK/mZ0042If7kpNl/EHhLfQc/M70btkqEXP -zfEQ2N+ovHGDBFOmwIhDlBgmjWS7YehYweHHinkJoFxFHVXfpVz42oVyZpQ9eRVU -zjh68MZ66fEZtkxZKeHi0tDVcthkFFIvfLYIGJe2DqorEtOZi3cSR64ttQlRqW0= -=z181 +iQEcBAEBCgAGBQJgAjoxAAoJEEzhh34ZQ4xw0gwH/Ah/BFU2EtwrFIRDcpmRsMTy +Z7685r8nKxCJKdvVy/jIqS95FGkj0d0kzxleqJGlkf1J1tVEa+hYf9PmWwtQrbOG +id+Q3l+ZUMYZtmqv6PH056CDzM4wiKTMdCtPifesYcdxEOQ+LKcBePr18GTHtqyd +zg3iYLJpCPKG72/4KrNYcqKX/NLuI5iiTwLtBYgTu/VSFB/g/V4rZksOwuM2+iHR +RKHKNBWtehI6/MfHFcAGRw6m0LldcVdEs/7k72RX1pj8ulA7zyNxfnXxwakm0ed6 +US2zyYXgaHK3lW4BqAcOpi56SzpJ/jnkXf2+HnwRD0mU0268LYyVLhJ9EnO/kCU= +=hhi1 -----END PGP SIGNATURE----- diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz index 5840401430..0fc31e44b1 100644 Binary files a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz and b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz differ diff --git a/systems/texlive/tlnet/tlpkg/tltcl/tltcl.tcl b/systems/texlive/tlnet/tlpkg/tltcl/tltcl.tcl index ff5c273c05..562b148125 100644 --- a/systems/texlive/tlnet/tlpkg/tltcl/tltcl.tcl +++ b/systems/texlive/tlnet/tlpkg/tltcl/tltcl.tcl @@ -478,11 +478,11 @@ set gry [ttk::style lookup TButton -foreground disabled] # 'default' padding proc ppack {wdg args} { ; # pack command with padding - pack $wdg {*}$args -padx 3 -pady 3 + pack $wdg {*}$args -padx 3pt -pady 3pt } proc pgrid {wdg args} { ; # grid command with padding - grid $wdg {*}$args -padx 3 -pady 3 + grid $wdg {*}$args -padx 3pt -pady 3pt } # unicode symbols as fake checkboxes in ttk::treeview widgets @@ -664,7 +664,7 @@ if {$::tcl_platform(platform) eq "unix"} { wm title .browser [__ "Browse..."] # wallpaper - pack [ttk::frame .browser.bg -padding 3] -fill both -expand 1 + pack [ttk::frame .browser.bg -padding 3pt] -fill both -expand 1 # ok and cancel buttons pack [ttk::frame .browser.fr1] \ diff --git a/systems/win32/w32tex/ChangeLog b/systems/win32/w32tex/ChangeLog index ae9451a5af..4b1a5516bd 100644 --- a/systems/win32/w32tex/ChangeLog +++ b/systems/win32/w32tex/ChangeLog @@ -1,5 +1,21 @@ W32TeX (x86 & x64) ChangeLog +[2021/01/15] +(01) dvipdfm-w32.tar.xz + Update dvipdfmx.dll (20210115). +(02) ltxpkgs.tar.xz + Update fcolumn. +(03) ptex-ng-w32.tar.xz + Update libdpx. +(04) xetex-w32.tar.xz + Update dvipdfmx.dll (20210115). +(05) win64/dvipdfm-w64.tar.xz + Update dvipdfmx.dll (20210115). +(06) win64/ptex-ng-w64.tar.xz + Update libdpx. +(07) win64/xetex-w64.tar.xz + Update dvipdfmx.dll (20210115). + [2021/01/14] (01) ltxpkgs.tar.xz Update showexpl. diff --git a/timestamp b/timestamp index b55b00644d..207e8458be 100644 --- a/timestamp +++ b/timestamp @@ -2,4 +2,4 @@ # The source CTAN of this site's material: dante.ctan.org # The year-month-day-hour-minute of this site's material: -2021-01-16-02-02 +2021-01-17-02-02 -- cgit v1.2.3