diff options
Diffstat (limited to 'Master/texmf-dist')
60 files changed, 2810 insertions, 877 deletions
diff --git a/Master/texmf-dist/doc/luatex/luaotfload/NEWS b/Master/texmf-dist/doc/luatex/luaotfload/NEWS index 39bfcc4cc33..86b9dd9b2da 100644 --- a/Master/texmf-dist/doc/luatex/luaotfload/NEWS +++ b/Master/texmf-dist/doc/luatex/luaotfload/NEWS @@ -1,5 +1,12 @@ Change History -------------- +2019-11-04 luaotfload v3.1 + * added code to use the harfbuzz library of luahbtex ("mode=harf") + * fonts in ttc can now be indexed by name + * remove a number of lua tables from the global enviroment (_G) to reduce the polution. + Kept there are only the tables luaotfload, fonts and nodes. + * sync with context files from 2019-10-29 + 2019-09-13 luaotfload v3.0 * invisible option to avoid that some glyph are shown (issue #63) * correct small bug in xheight calculation diff --git a/Master/texmf-dist/doc/luatex/luaotfload/README.md b/Master/texmf-dist/doc/luatex/luaotfload/README.md index a6f24d4ab94..ca760b1bab4 100644 --- a/Master/texmf-dist/doc/luatex/luaotfload/README.md +++ b/Master/texmf-dist/doc/luatex/luaotfload/README.md @@ -1,8 +1,8 @@ # The Luaotfload Package -VERSION: 3.00 +VERSION: 3.1 -DATE: 2019-09-13 +DATE: 2019-11-04 ## Description diff --git a/Master/texmf-dist/doc/luatex/luaotfload/filegraph.pdf b/Master/texmf-dist/doc/luatex/luaotfload/filegraph.pdf Binary files differindex a14afaa1697..95b296c5997 100644 --- a/Master/texmf-dist/doc/luatex/luaotfload/filegraph.pdf +++ b/Master/texmf-dist/doc/luatex/luaotfload/filegraph.pdf diff --git a/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-conf.pdf b/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-conf.pdf Binary files differindex edea84a1d79..031fb0987aa 100644 --- a/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-conf.pdf +++ b/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-conf.pdf diff --git a/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.pdf b/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.pdf Binary files differindex 8b128aed7e7..28391b2e8ab 100644 --- a/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.pdf +++ b/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.pdf diff --git a/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-main.tex b/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-main.tex index 8fdb4048ad0..dbc8d73e7db 100644 --- a/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-main.tex +++ b/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-main.tex @@ -32,11 +32,10 @@ \beginfrontmatter \setdocumenttitle {The \identifier{luaotfload} package} - \setdocumentdate {2019-09-13 v3.00} - \setdocumentauthor {Elie Roux · Khaled Hosny · Philipp Gesang · Ulrike Fischer\\ - Home: \hyperlink {https://github.com/lualatex/luaotfload}\\ - New Home: \hyperlink {https://github.com/u-fischer/luaotfload}\\ - Support: \email {lualatex-dev@tug.org}} + \setdocumentdate {2019-11-04 v3.1} + \setdocumentauthor {LaTeX3 Project\\ + Elie Roux · Khaled Hosny · Philipp Gesang · Ulrike Fischer · Marcel Krüger\\ + Home: \hyperlink {https://github.com/latex3/luaotfload}} \typesetdocumenttitle @@ -55,34 +54,56 @@ \pdfbookmark[1]{\contentsname}{table} \typesetcontent -\beginsection {New in version 3.00 (by Ulrike Fischer/Marcel Krüger)} +\beginsection {Engine and version support} +\identifier{luaotfload} is a quite large and complex package. It imports code from context which is actively developed along with the luatex binary. It is not possible +to support a large number of engines variants or versions. + +Supported is the \identifier{luatex} versions of a current TeXLive 2019 (and a current MiKTeX). Beginning with version 3.1 of this package also \identifier{luahbtex} is supported. +\endsection + +\beginsection{Changes} +\beginsubsection {New in version 3.1 (by Ulrike Fischer/Marcel Krüger)} +\begin{itemize} +\item The package has been moved to the github of the LaTeX3 Project and is now maintained + officially by the LaTeX3 Project team. +\item Code to use the harfbuzz library of luahbtex has been added. See the description of the harf mode. +\item fonts in ttc-collections can now be indexed by name. +\item To reduce the polution of the global lua enviroment a number of lua tables have been removed. + Only the tables \identifier{luaotfload}, \identifier{fonts} and \identifier{nodes} have been kept there. +\item The fontloader has been synched with the context files from 2019-10-29. + +\end{itemize} +\endsubsection + + +\beginsubsection {New in version 3.00 (by Ulrike Fischer/Marcel Krüger)} \begin{itemize} \item Default Ignorable characters are now invisible by default (issue 63). This can be deactivated with the option \texttt{invisible}. \end{itemize} -\endsection +\endsubsection -\beginsection {New in version 2.99 (by Ulrike Fischer)} +\beginsubsection {New in version 2.99 (by Ulrike Fischer)} \begin{itemize} \item Code cleanup. \item The fontloader has been synched with the context files from 2019-08-11. \end{itemize} -\endsection -\beginsection {New in version 2.98 (by Ulrike Fischer)} +\endsubsection +\beginsubsection {New in version 2.98 (by Ulrike Fischer)} \begin{itemize} \item The\marginpar{\mbox{}\hfill \textbf{breaking change!}} handling of missing chars has been changed. In This version a missing char will insert the \inlinecode{/.notdef} char of the fonts (this is sometimes a space, sometimes a rectangle with a cross) and no longer simply ignore the glyph. This behaviour can be reverted by using \inlinecode{notdef=false} as font feature. \item The font feature \inlinecode{embolden} can now be used to fake a bold font. \item The fontloader has been synched with the context files from 2019-07-04. \end{itemize} -\endsection -\beginsection {New in version 2.97 (by Ulrike Fischer)} +\endsubsection +\beginsubsection {New in version 2.97 (by Ulrike Fischer)} \begin{itemize} \item the new generic fontloader improves the handling of large fonts (but some fonts still need a 64bit luatex version to create the font files). \item A number of small bug (also in luaotfload-tool) have been corrected, see the NEWS file for details. \end{itemize} -\endsection +\endsubsection -\beginsection {New in version 2.96 (by Ulrike Fischer)} +\beginsubsection {New in version 2.96 (by Ulrike Fischer)} \begin{itemize} \item In\marginpar{\mbox{}\hfill \textbf{Incompatible change!}} version 2.95 letterspacing was broken due to a change in the fontloader (issue 38). This has been repaired. At the same time a number of oddities and bugs in the letterspacing has been corrected. This can change existing documents. See page~\pageref{p:letterspace} for more information. @@ -90,11 +111,11 @@ version 2.95 letterspacing was broken due to a change in the fontloader (issue 3 \item A problem with the detection of bold fonts has been corrected (issue 41, pull request 42). \end{itemize} -\endsection +\endsubsection -\beginsection {New in version 2.95 (by Ulrike Fischer)} +\beginsubsection {New in version 2.95 (by Ulrike Fischer)} \begin{itemize} \item This version imports from context the generic fontloader in the version of 2019-01-28. Contrary to the last announcement, it still works with luatex 1.07. So updates will continue. @@ -106,8 +127,8 @@ This version imports from context the generic fontloader in the version of 2019- \item The resolver code has be refactorated (pull request 36). \end{itemize} -\endsection -\beginsection {New in version 2.94 (by Ulrike Fischer)} +\endsubsection +\beginsubsection {New in version 2.94 (by Ulrike Fischer)} \begin{itemize} \item This version imports from context the generic fontloader in the version of 2018-12-19. It is the last version that works with luatex 1.07 and texlive 2018. As context has moved to luatex 1.09 newer versions of the fontloader needs now this luatex version too. This means that until the texlive 2018 freeze there will be probably no update of luaotfload. @@ -116,13 +137,13 @@ This version imports from context the generic fontloader in the version of 2018- \end{itemize} -\endsection +\endsubsection -\beginsection {New in version 2.93 (by Ulrike Fischer)} +\beginsubsection {New in version 2.93 (by Ulrike Fischer)} Mainly internal clean up of the version info to allow automatic versioning. -\endsection +\endsubsection -\beginsection {New in version 2.92 (by Ulrike Fischer)} +\beginsubsection {New in version 2.92 (by Ulrike Fischer)} \begin{itemize} @@ -131,15 +152,15 @@ Mainly internal clean up of the version info to allow automatic versioning. \item The syntax \inlinecode{file:} for legacy font works again (issue \#11). \item The fontloader has been synched with the newest context version from october, 18. \end{itemize} -\endsection -\beginsection {New in version 2.91 (by Ulrike Fischer)} +\endsubsection +\beginsubsection {New in version 2.91 (by Ulrike Fischer)} This version mostly correct two bugs found in the previous fontloader: Glyphvariants weren't copied and pasted correctly. Glyphs encoded in the PUA couldn't be accessed anymore. -\endsection +\endsubsection -\beginsection {New in version 2.9 (by Ulrike Fischer)} +\beginsubsection {New in version 2.9 (by Ulrike Fischer)} On the one side there is not very much new in this version: The native components of \identifier{Luaotfload} are nearly unchanged. A few bugs have been corrected, the various files lists which loads the components of the font loader have been cleaned up. @@ -154,7 +175,7 @@ On the other side there is a lot new: \beginaltitem {Lualibs} The update of the fontloader files also required an update of the \identifier{Lualibs} package. This \identifier{Luaotfload} version needs version 2.6 of \identifier{Lualibs}. \endaltitem - \beginaltitem {Maintenance} As the current maintainer wasn't available and it was urgent to get a \identifier{Luaotfload} compatible with \LUATEX 1.08/1.09 maintenance has been transfered to Ulrike Fischer and Marcel Krüger. The package is currently maintained and developed at \hyperlink{https://github.com/u-fischer/luaotfload}. Issues should be reported there. + \beginaltitem {Maintenance} As the current maintainer wasn't available and it was urgent to get a \identifier{Luaotfload} compatible with \LUATEX 1.08/1.09 maintenance has been transfered to Ulrike Fischer and Marcel Krüger. The package was maintained and developed at \hyperlink{https://github.com/u-fischer/luaotfload}. Issues should be reported there. \endaltitem \beginaltitem {Documentation} @@ -163,6 +184,7 @@ On the other side there is a lot new: \enddescriptions +\endsubsection \endsection %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \beginsection {Introduction} @@ -181,11 +203,8 @@ These fonts can contain many more characters than \TEX fonts, as well as additional functionality like ligatures, old-style numbers, small capitals, etc., and support more complex writing systems like Arabic and Indic\footnote{% - Unfortunately, \identifier{luaotfload} doesn‘t support many Indic - scripts right now. - Assistance in implementing the prerequisites is greatly - appreciated. -} + Unfortunately, the default fontloader of \identifier{luaotfload} doesn‘t support many Indic + scripts correctly. For these scripts it is recommended to use the harf mode along with the binary \identifier{luahbtex}.} scripts. \OpenType fonts are widely deployed and available for all modern @@ -382,7 +401,7 @@ where \meta{prefix} is either \inlinecode{file:} or \inlinecode {name:}.\footnot % For a working example see the \hyperlink [test in the luaotfload - repo]{https://github.com/u-fischer/luaotfload/blob/master/testfiles/my-resolver.lvt}. + repo]{https://github.com/latex3/luaotfload/blob/master/testfiles/my-resolver.lvt}. } % It determines whether the font loader should interpret the request as @@ -563,8 +582,8 @@ non-standard directory: \identifier{TrueType} collection files (the extension is usually \inlinecode{.ttc}) contain more than a single font. In order to refer to these -subfonts, the respective index may be added in parentheses after the file -name.\footnote{% +subfonts, the respective index or the respective PostScript font name may be +added in parentheses after the file name.\footnote{% Incidentally, this syntactical detail also prevents one from loading files that end in balanced parentheses. } @@ -572,6 +591,8 @@ name.\footnote{% \beginlisting \font \cambriamain = "file:cambria.ttc(0)" at 10pt \font \cambriamath = "file:cambria.ttc(1)" at 10pt + \font \Cambriamain = "file:cambria.ttc(Cambria)" at 10pt + \font \Cambriamath = "file:cambria.ttc(CambriaMath)" at 10pt \endlisting and likewise, requesting subfont inside a TTC container by path: @@ -721,10 +742,9 @@ obviously, \inlinecode{random}. \begindescriptions \beginaltitem {mode} - Until version 2.94 - \identifier{luaotfload} had two \OpenType processing + \identifier{luaotfload} had three \OpenType processing \emphasis{modes}: - \identifier{base} and \identifier{node}. + \identifier{base}, \identifier{node} and \identifier{harf}. \identifier{base} mode works by mapping \OpenType features to traditional \TEX ligature and kerning mechanisms. @@ -744,12 +764,42 @@ obviously, \inlinecode{random}. mode, and \identifier{base} mode has to be requested where needed, e.~g. for math fonts. - Since version 2.94 it is possible to call other font renderers with the mode key. A simple example with a plain reader can be found at \hyperlink{https://github.com/u-fischer/luaotfload/pull/26\#issuecomment-437716326}. - A more useful example needs the new experimental harftex engine (windows binaries can be found at w32tex.org), and the harf renderer (\hyperlink{https://github.com/khaledhosny/harf}). With both it is possible to render a font using the harfbuzz library (used also by xetex). + \identifier{harf} mode is new in version 3.1 and needs the new \identifier{luahbtex} engine (the mode is ignored if \identifier{luahbtex} is not used). With it is possible to render a font using the harfbuzz library in-built in the new engine. \identifier{harf} mode improves greatly the rendering of indic and arabic scripts and is highly recommended for such scripts. + + When using \identifier{harf} mode it is required to set also the script correctly: + + + \beginlisting + \font\burmesefont={file:NotoSerifMyanmar-Regular.ttf:mode=harf;script=mymr;} + \font\devafont={file:NotoSansDevanagari-Regular.ttf:mode=harf;script=deva;} + \font\banglafont={name:Noto Sans Bengali:mode=harf;script=beng;} + \font\tibetanfont={name:Noto Serif Tibetan:mode=harf;script=tibt;} + \endlisting + \includegraphics{scripts-demo} + + + It is possible to call other font renderers with the mode key. A simple example with a plain reader can be found at \url{https://github.com/latex3/luaotfload/pull/26#issuecomment-437716326}. \endaltitem + \beginaltitem {shaper} \label{shaper-tag} + If \identifier{luahbtex} and \identifier{harf} mode are used it is possible to specify a shaper, like \identifier{graphite2} or \identifier{ot} (open type). + + \beginlisting + \pardir TRT\textdir TRT + \font\test={file:AwamiNastaliq-Regular.ttf:mode=harf;shaper=ot} + \endlisting + + \includegraphics{shaper-demo} + + \beginlisting + \pardir TRT\textdir TRT + \font\test={file:AwamiNastaliq-Regular.ttf:mode=harf;shaper=graphite2} + \endlisting + + \includegraphics{shaper-demo-graphite} + \endaltitem \beginaltitem {script} \label{script-tag} An \OpenType script tag;\footnote{% See \hyperlink {http://www.microsoft.com/typography/otspec/scripttags.htm} @@ -948,7 +998,7 @@ obviously, \inlinecode{random}. \font \test = LatinModernRoman:protrusion=default \endlisting \endaltitem - + \beginaltitem {invisible} Default Ignorable characters are control characters that should be invisible by default even if the font has glyphs for them. Since version 3.0 luaotfload makes them invisible, this can be switch on and off with the \texttt{invisible}. By default it is on. @@ -960,16 +1010,16 @@ obviously, \inlinecode{random}. \endlisting {\font\amiri={file:amiri-regular.ttf} at 20pt \amiri \char"200Dي\char"200D} - + \beginlisting \font\amiri={file:amiri-regular.ttf:-invisible;} at 20pt \amiri \char"200Dي\char"200D \endlisting {\font\amiri={file:amiri-regular.ttf:-invisible;} at 20pt \amiri \char"200Dي\char"200D} - - \endaltitem + + \endaltitem \enddescriptions \endsubsection diff --git a/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.pdf b/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.pdf Binary files differindex 697cfefd3c3..76c2bb6df83 100644 --- a/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.pdf +++ b/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.pdf diff --git a/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.rst b/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.rst index 5d61e04368b..1c1ec3161e3 100644 --- a/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.rst +++ b/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.rst @@ -6,9 +6,9 @@ generate and query the Luaotfload font names database ----------------------------------------------------------------------- -:Date: 2019-09-13 +:Date: 2019-11-04 :Copyright: GPL v2.0 -:Version: 3.00 +:Version: 3.1 :Manual section: 1 :Manual group: text processing diff --git a/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.conf.rst b/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.conf.rst index 7b85fd1a289..18042188b82 100644 --- a/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.conf.rst +++ b/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.conf.rst @@ -6,9 +6,9 @@ Luaotfload configuration file ----------------------------------------------------------------------- -:Date: 2019-09-13 +:Date: 2019-11-04 :Copyright: GPL v2.0 -:Version: 3.00 +:Version: 3.1 :Manual section: 5 :Manual group: text processing diff --git a/Master/texmf-dist/doc/luatex/luaotfload/scripts-demo.pdf b/Master/texmf-dist/doc/luatex/luaotfload/scripts-demo.pdf Binary files differnew file mode 100644 index 00000000000..f0f1bb00655 --- /dev/null +++ b/Master/texmf-dist/doc/luatex/luaotfload/scripts-demo.pdf diff --git a/Master/texmf-dist/doc/luatex/luaotfload/scripts-demo.tex b/Master/texmf-dist/doc/luatex/luaotfload/scripts-demo.tex new file mode 100644 index 00000000000..4bbe06064c8 --- /dev/null +++ b/Master/texmf-dist/doc/luatex/luaotfload/scripts-demo.tex @@ -0,0 +1,15 @@ +\documentclass{standalone} + +\font\burmesefont={file:NotoSerifMyanmar-Regular.ttf:mode=harf;script=mymr;} +\font\devafont={file:NotoSansDevanagari-Regular.ttf:mode=harf;script=deva;} +\font\banglafont={file:NotoSansBengali-Regular.ttf:mode=harf;script=beng;} +\font\tibetanfont={file:NotoSerifTibetan-Regular.ttf:mode=harf;script=tibt;} +\standaloneenv{tabular} +\begin{document} +\begin{tabular}{l} +\burmesefont မ္မတီခေါင်းလောင်းကြီ\\ +\devafont क्रर्कि \\ +\banglafont কণ্যা এখন কি করিবে\\ +\tibetanfont སྐྱེས་ཙམ་ཉིད་ནས་ཆེ་མཐོངས་དང༌། +\end{tabular} +\end{document}
\ No newline at end of file diff --git a/Master/texmf-dist/doc/luatex/luaotfload/shaper-demo-graphite.pdf b/Master/texmf-dist/doc/luatex/luaotfload/shaper-demo-graphite.pdf Binary files differnew file mode 100644 index 00000000000..3c97c23522c --- /dev/null +++ b/Master/texmf-dist/doc/luatex/luaotfload/shaper-demo-graphite.pdf diff --git a/Master/texmf-dist/doc/luatex/luaotfload/shaper-demo-graphite.tex b/Master/texmf-dist/doc/luatex/luaotfload/shaper-demo-graphite.tex new file mode 100644 index 00000000000..cf83fb2f701 --- /dev/null +++ b/Master/texmf-dist/doc/luatex/luaotfload/shaper-demo-graphite.tex @@ -0,0 +1,9 @@ +\documentclass[12pt]{standalone} + +\begin{document} + +\pardir TRT\textdir TRT +\font\test={file:AwamiNastaliq-Regular.ttf:mode=harf;shaper=graphite2} +\test +اُرْشَلیمئے +\end{document} diff --git a/Master/texmf-dist/doc/luatex/luaotfload/shaper-demo.pdf b/Master/texmf-dist/doc/luatex/luaotfload/shaper-demo.pdf Binary files differnew file mode 100644 index 00000000000..183b062e1f2 --- /dev/null +++ b/Master/texmf-dist/doc/luatex/luaotfload/shaper-demo.pdf diff --git a/Master/texmf-dist/doc/luatex/luaotfload/shaper-demo.tex b/Master/texmf-dist/doc/luatex/luaotfload/shaper-demo.tex new file mode 100644 index 00000000000..b4931dcfc22 --- /dev/null +++ b/Master/texmf-dist/doc/luatex/luaotfload/shaper-demo.tex @@ -0,0 +1,7 @@ +\documentclass[12pt]{standalone} +\begin{document} +\pardir TRT\textdir TRT +\font\test={file:AwamiNastaliq-Regular.ttf:mode=harf;shaper=ot} +\test +اُرْشَلیمئے +\end{document} diff --git a/Master/texmf-dist/doc/man/man1/luaotfload-tool.1 b/Master/texmf-dist/doc/man/man1/luaotfload-tool.1 index 3636d2f6e6d..c2d754baa34 100644 --- a/Master/texmf-dist/doc/man/man1/luaotfload-tool.1 +++ b/Master/texmf-dist/doc/man/man1/luaotfload-tool.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH LUAOTFLOAD-TOOL 1 "2019-09-13" "3.00" "text processing" +.TH LUAOTFLOAD-TOOL 1 "2019-11-04" "3.1" "text processing" .SH NAME luaotfload-tool \- generate and query the Luaotfload font names database . diff --git a/Master/texmf-dist/doc/man/man1/luaotfload-tool.man1.pdf b/Master/texmf-dist/doc/man/man1/luaotfload-tool.man1.pdf Binary files differindex ebd52a20009..5e58a2f3577 100644 --- a/Master/texmf-dist/doc/man/man1/luaotfload-tool.man1.pdf +++ b/Master/texmf-dist/doc/man/man1/luaotfload-tool.man1.pdf diff --git a/Master/texmf-dist/doc/man/man5/luaotfload.conf.5 b/Master/texmf-dist/doc/man/man5/luaotfload.conf.5 index 1173d9a3de1..9726ad7aaca 100644 --- a/Master/texmf-dist/doc/man/man5/luaotfload.conf.5 +++ b/Master/texmf-dist/doc/man/man5/luaotfload.conf.5 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH LUAOTFLOAD.CONF 5 "2019-09-13" "3.00" "text processing" +.TH LUAOTFLOAD.CONF 5 "2019-11-04" "3.1" "text processing" .SH NAME luaotfload.conf \- Luaotfload configuration file . diff --git a/Master/texmf-dist/doc/man/man5/luaotfload.conf.man5.pdf b/Master/texmf-dist/doc/man/man5/luaotfload.conf.man5.pdf Binary files differindex dbfe0f22629..2d6608e530f 100644 --- a/Master/texmf-dist/doc/man/man5/luaotfload.conf.man5.pdf +++ b/Master/texmf-dist/doc/man/man5/luaotfload.conf.man5.pdf diff --git a/Master/texmf-dist/scripts/luaotfload/luaotfload-tool.lua b/Master/texmf-dist/scripts/luaotfload/luaotfload-tool.lua index 06729778f45..12bf2b3a42c 100755 --- a/Master/texmf-dist/scripts/luaotfload/luaotfload-tool.lua +++ b/Master/texmf-dist/scripts/luaotfload/luaotfload-tool.lua @@ -9,8 +9,8 @@ local ProvidesLuaModule = { name = "luaotfload-tool", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload-tool / database functionality", license = "GPL v2.0" } @@ -25,6 +25,7 @@ local version = ProvidesLuaModule.version luaotfload.version = ProvidesLuaModule.version luaotfload.min_luatex_version = { 0, 95, 0 } luaotfload.self = "luaotfload-tool" +luaotfload.fontloader = _G -- We don't isolate the fontloader here --[[doc-- diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2019-08-11.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2019-10-29.lua index b4d3f3ce126..dc98bd56969 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2019-08-11.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2019-10-29.lua @@ -1,6 +1,6 @@ --[[info----------------------------------------------------------------------- Luaotfload fontloader package - build 2019-08-13 18:34:34 + build 2019-10-29 22:02:47 ------------------------------------------------------------------------------- © 2019 PRAGMA ADE / ConTeXt Development Team @@ -62,7 +62,7 @@ --info]]----------------------------------------------------------------------- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “data-con” 7ce546725b1550f655c78ac9d69419ca] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “data-con” 7ce546725b1550f655c78ac9d69419ca] --- if not modules then modules={} end modules ['data-con']={ version=1.100, @@ -174,10 +174,10 @@ function containers.cleanname(name) return (gsub(lower(name),"[^%w\128-\255]+","-")) end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “data-con”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “data-con”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “basics-nod” 65064d03c2650a1761ee13ebd9e1400a] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “basics-nod” c05f47077c709bbf12a8758852dc4e06] --- if not modules then modules={} end modules ['luatex-fonts-nod']={ version=1.001, @@ -247,6 +247,7 @@ nuts.getchar=direct.getchar nuts.getcomponents=direct.getcomponents nuts.getdirection=direct.getdirection nuts.getdisc=direct.getdisc +nuts.getreplace=direct.getreplace nuts.getfield=direct.getfield nuts.getfont=direct.getfont nuts.getid=direct.getid @@ -263,6 +264,7 @@ 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 @@ -380,11 +382,22 @@ do 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 -end --- [luaotfload, fontloader-2019-08-13.lua scope for “basics-nod”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “basics-nod”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “basics-chr” 58b7ef0c486e06090b362971b9f85e27] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “basics-chr” 58b7ef0c486e06090b362971b9f85e27] --- characters=characters or {} @@ -3994,10 +4007,10 @@ characters.indicgroups={ }, } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “basics-chr”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “basics-chr”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ini” 4299a02110bbd7c0d27e131235c5319d] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ini” 4299a02110bbd7c0d27e131235c5319d] --- if not modules then modules={} end modules ['font-ini']={ version=1.001, @@ -4035,10 +4048,10 @@ fonts.privateoffsets={ keepnames=false, } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ini”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ini”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-mis” bc9eb43c27f63ce9d0fff67e104fe1c6] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-mis” bc9eb43c27f63ce9d0fff67e104fe1c6] --- if not modules then modules={} end modules ['luatex-font-mis']={ version=1.001, @@ -4070,10 +4083,10 @@ function font.each() return table.sortedhash(fonts.hashes.identifiers) end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-mis”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-mis”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-con” ca733211a0555d9a93b1e2f7ebc937d3] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-con” 8b35e7c2203d5b57c61942e07cee2c0a] --- if not modules then modules={} end modules ['font-con']={ version=1.001, @@ -4376,7 +4389,8 @@ function constructors.scale(tfmdata,specification) 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.mode=properties.mode or "base" + targetproperties.method=properties.method local askedscaledpoints=scaledpoints local scaledpoints,delta=constructors.calculatescale(tfmdata,scaledpoints,nil,specification) local hdelta=delta @@ -5416,10 +5430,10 @@ function constructors.addcoreunicodes(unicodes) return unicodes end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-con”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-con”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-enc” 3e71a54297e8f85a1ac438bb0f20dd79] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-enc” 3e71a54297e8f85a1ac438bb0f20dd79] --- if not modules then modules={} end modules ['luatex-font-enc']={ version=1.001, @@ -5488,10 +5502,10 @@ function encodings.load(filename) return containers.write(encodings.cache,name,data) end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-enc”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-enc”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-cid” 4d87988efa86020a14708ee03c23415f] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-cid” 4d87988efa86020a14708ee03c23415f] --- if not modules then modules={} end modules ['font-cid']={ version=1.001, @@ -5642,10 +5656,10 @@ function cid.getmap(specification) return found end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-cid”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-cid”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-map” f486746e90fe972de4b73e208ac7cbb2] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-map” f486746e90fe972de4b73e208ac7cbb2] --- if not modules then modules={} end modules ['font-map']={ version=1.001, @@ -6033,10 +6047,10 @@ function mappings.addtounicode(data,filename,checklookups,forceligatures) end end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-map”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-map”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-vfc” 94937140f2c909e9c831ba021f1ab303] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-vfc” 94937140f2c909e9c831ba021f1ab303] --- if not modules then modules={} end modules ['font-vfc']={ version=1.001, @@ -6134,10 +6148,10 @@ helpers.commands=utilities.storage.allocate { dummy=dummy, } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-vfc”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-vfc”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otr” b1c03925c949027c86f781785fa7a208] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otr” b1c03925c949027c86f781785fa7a208] --- if not modules then modules={} end modules ['font-otr']={ version=1.001, @@ -7987,10 +8001,10 @@ function readers.extend(fontdata) end end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otr”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otr”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-oti” dbae7722baae24d917a17176553825cf] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-oti” dbae7722baae24d917a17176553825cf] --- if not modules then modules={} end modules ['font-oti']={ version=1.001, @@ -8133,10 +8147,10 @@ function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages) end end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-oti”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-oti”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ott” aba6d8335a5f38a5a62d3631492f3392] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ott” aba6d8335a5f38a5a62d3631492f3392] --- if not modules then modules={} end modules ["font-ott"]={ version=1.001, @@ -9255,10 +9269,10 @@ function otffeatures.normalize(features,wrap) end end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ott”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ott”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-cff” 98d5a660ea803b65cb883c009ecf3c0b] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-cff” 98d5a660ea803b65cb883c009ecf3c0b] --- if not modules then modules={} end modules ['font-cff']={ version=1.001, @@ -11282,10 +11296,10 @@ function readers.cffcheck(filename) end end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-cff”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-cff”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ttf” 44e61cef50dab9b1aaf48130f9367c34] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ttf” 44e61cef50dab9b1aaf48130f9367c34] --- if not modules then modules={} end modules ['font-ttf']={ version=1.001, @@ -12455,10 +12469,10 @@ function readers.gvar(f,fontdata,specification,glyphdata,shapedata) end end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ttf”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ttf”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-dsp” b5bf2f1c198e027a0d4ededcdf3947b4] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-dsp” 5d3db0184c903829b2c5bddcb8cdb14c] --- if not modules then modules={} end modules ['font-dsp']={ version=1.001, @@ -15092,6 +15106,8 @@ function readers.cpal(f,fontdata,specification) 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 @@ -15113,10 +15129,14 @@ function readers.svg(f,fontdata,specification) 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=readstring(f,entry.length) + data=data } end fontdata.svgshapes=entries @@ -15699,10 +15719,10 @@ function readers.mvar(f,fontdata,specification) end end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-dsp”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-dsp”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-oup” 669e479e716999edc626a1f045bd76fa] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-oup” 0cef35af01739f52fd09feb5401192ae] --- if not modules then modules={} end modules ['font-oup']={ version=1.001, @@ -16379,6 +16399,9 @@ local function checklookups(fontdata,missing,nofmissing) 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") @@ -16389,18 +16412,19 @@ local function unifymissing(fontdata) resources.unicodes=unicodes for unicode,d in next,fontdata.descriptions do if unicode<privateoffset then - local name=d.name - if name then - unicodes[name]=unicode + 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 firstprivate=fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000 -local puafirst=0xE000 -local pualast=0xF8FF local function unifyglyphs(fontdata,usenames) local private=fontdata.private or privateoffset local glyphs=fontdata.glyphs @@ -18339,10 +18363,10 @@ function readers.expand(data) expandlookups(sublookups) end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-oup”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-oup”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otl” 940f9c5ad84f4968a8488f4da2d15e2d] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otl” ec0241b7465a7713e53c246e8e9fb2a8] --- if not modules then modules={} end modules ['font-otl']={ version=1.001, @@ -18370,11 +18394,12 @@ 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.109 +otf.version=3.110 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 @@ -19045,10 +19070,10 @@ otf.coverup={ end } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otl”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otl”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-oto” 52804afd96f4be005f513a012b874668] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-oto” 52804afd96f4be005f513a012b874668] --- if not modules then modules={} end modules ['font-oto']={ version=1.001, @@ -19506,10 +19531,10 @@ registerotffeature { } otf.basemodeinitializer=featuresinitializer -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-oto”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-oto”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otj” 66c7a910d95d4a52b81061de776898e1] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otj” 66c7a910d95d4a52b81061de776898e1] --- if not modules then modules={} end modules ['font-otj']={ version=1.001, @@ -20966,10 +20991,10 @@ function injections.handler(head,where) end end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otj”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otj”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ota” d6dfb94563d6a52675e274b2e673e4a6] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ota” d6dfb94563d6a52675e274b2e673e4a6] --- if not modules then modules={} end modules ['font-ota']={ version=1.001, @@ -21346,10 +21371,10 @@ directives.register("otf.analyze.useunicodemarks",function(v) analyzers.useunicodemarks=v end) -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ota”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ota”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ots” d5504847a278385cd0d20ecf1b3d59cc] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ots” d6a0ce4b40cd4ee1895e2248dcf87d37] --- if not modules then modules={} end modules ['font-ots']={ version=1.001, @@ -21408,7 +21433,6 @@ 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 getfield=nuts.getfield local getnext=nuts.getnext local setnext=nuts.setnext local getprev=nuts.getprev @@ -21424,6 +21448,7 @@ 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 getcomponents=nuts.getcomponents local setcomponents=nuts.setcomponents @@ -23002,7 +23027,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) if keepdisc then keepdisc=false lookaheaddisc=current - local replace=getfield(current,"replace") + local replace=getreplace(current) if not replace then sweepoverflow=true sweepnode=current @@ -23074,7 +23099,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) if notmatchpre[current]~=notmatchreplace[current] then lookaheaddisc=current end - local replace=getfield(current,"replace") + local replace=getreplace(current) while replace and i<s do if getid(replace)==glyph_code then i=i+1 @@ -23118,7 +23143,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) if notmatchpost[current]~=notmatchreplace[current] then backtrackdisc=current end - local replace=getfield(current,"replace") + local replace=getreplace(current) while replace and i>1 do if getid(replace)==glyph_code then i=i-1 @@ -24082,7 +24107,7 @@ local function t_run_single(start,stop,font,attr,lookupcache) end while getid(s)==disc_code do ss=getnext(s) - s=getfield(s,"replace") + s=getreplace(s) if not s then s=ss ss=nil @@ -24109,7 +24134,7 @@ local function t_run_single(start,stop,font,attr,lookupcache) end while getid(s)==disc_code do ss=getnext(s) - s=getfield(s,"replace") + s=getreplace(s) if not s then s=ss ss=nil @@ -24236,7 +24261,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) end while getid(s)==disc_code do ss=getnext(s) - s=getfield(s,"replace") + s=getreplace(s) if not s then s=ss ss=nil @@ -24263,7 +24288,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) end while getid(s)==disc_code do ss=getnext(s) - s=getfield(s,"replace") + s=getreplace(s) if not s then s=ss ss=nil @@ -24963,10 +24988,10 @@ registerotffeature { }, } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ots”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ots”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-osd” 79eb2fc4a71364fd73c8b996a109f5df] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-osd” 39e92f6e575741646d75ea79e3be87f3] --- if not modules then modules={} end modules ['font-osd']={ version=1.001, @@ -26046,7 +26071,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces) local cp=getprev(current) local cnsn=getnext(cns) setlink(cp,n) - setlink(cns,current) + setlink(cns,current) setlink(c,cnsn) if c==stop then stop=cp @@ -27398,10 +27423,10 @@ for i=1,nofscripts do methods[scripts_two[i]]=method_two end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-osd”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-osd”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ocl” b720867fb19a23f0b50377efd2a3c54a] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ocl” ba40df1a92b9b42a5c70d20c28f44759] --- if not modules then modules={} end modules ['font-ocl']={ version=1.001, @@ -27410,9 +27435,13 @@ if not modules then modules={} end modules ['font-ocl']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } +if CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 then + return +end local tostring,tonumber,next=tostring,tonumber,next local round,max=math.round,math.round -local sortedkeys,sortedhash=table.sortedkeys,table.sortedhash +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 @@ -27422,6 +27451,7 @@ 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 @@ -27515,7 +27545,7 @@ end local start={ "pdf","mode","font" } local push={ "pdf","page","q" } local pop={ "pdf","page","Q" } -local function initialize(tfmdata,kind,value) +local function initializeoverlay(tfmdata,kind,value) if value then local resources=tfmdata.resources local palettes=resources.colorpalettes @@ -27557,52 +27587,39 @@ local function initialize(tfmdata,kind,value) local s=#colorlist local goback=w~=0 and leftcommand[w] or nil local t={ - start, - not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) } + not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) }, + push, } local n=2 local l=nil - local f=false for i=1,s do local entry=colorlist[i] local v=colorvalues[entry.class] or default if v and l~=v then - if f then - n=n+1 t[n]=pop - end - n=n+1 t[n]=push - f=true n=n+1 t[n]=v l=v - else - if f then - n=n+1 t[n]=pop - end - f=false - l=nil end n=n+1 t[n]=charcommand[entry.slot] if s>1 and i<s and goback then n=n+1 t[n]=goback end end - if f then - n=n+1 t[n]=pop - end + n=n+1 t[n]=pop n=n+1 t[n]=actuale character.commands=t end end end + return true end end end -fonts.handlers.otf.features.register { +otfregister { name="colr", description="color glyphs", manipulators={ - base=initialize, - node=initialize, + base=initializeoverlay, + node=initializeoverlay, } } do @@ -27653,14 +27670,20 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) local data=nil local dx=nil local dy=nil + local scale=1 if typ=="table" then data=pdf.data - dx=pdf.dx or 0 - dy=pdf.dy or 0 + dx=pdf.x or pdf.dx or 0 + dy=pdf.y or pdf.dy or 0 + scale=pdf.scale or 1 elseif typ=="string" then data=pdf dx=0 dy=0 + elseif typ=="number" then + data=pdf + dx=0 + dy=0 end if data then local bt=unicode and getactualtext(unicode) @@ -27669,9 +27692,9 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) local dp=character.depth or 0 character.commands={ not unicode and actualb or { "pdf","page",(getactualtext(unicode)) }, - downcommand[dp+dy*hfactor], - rightcommand[dx*hfactor], - vfimage(wd,ht,dp,data,name), + downcommand [dp+dy*hfactor], + rightcommand[ dx*hfactor], + vfimage(scale*wd,ht,dp,data,pdfshapes.filename or ""), actuale, } character[kind]=true @@ -27705,24 +27728,27 @@ do name="otfsvg", program="inkscape", method="pipeto", - template="--shell > temp-otf-svg-shape.log", + template="--export-area-drawing --shell > temp-otf-svg-shape.log", reporter=report_svg, } if not runner then runner=function() - return io.open("inkscape --shell > temp-otf-svg-shape.log","w") + return io.popen("inkscape --export-area-drawing --shell > temp-otf-svg-shape.log","w") end end - function otfsvg.topdf(svgshapes) + function otfsvg.topdf(svgshapes,tfmdata) local pdfshapes={} local inkscape=runner() if inkscape then + local indices=fonts.getindices(tfmdata) + 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-pdf=%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 @@ -27734,24 +27760,51 @@ do local pdffile=f_pdffile(index) savedata(svgfile,data) inkscape:write(f_convert(svgfile,pdffile)) - pdfshapes[index]=true + processed[index]=true nofdone=nofdone+1 - if nofdone%100==0 then - report_svg("%i shapes processed",nofdone) + 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,pdfshapes do + for index in next,processed do local svgfile=f_svgfile(index) local pdffile=f_pdffile(index) - pdfshapes[index]=loaddata(pdffile) + 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 "-") @@ -27770,19 +27823,20 @@ local function initializesvg(tfmdata,kind,value) end local pdffile=containers.read(otf.pdfcache,hash) local pdfshapes=pdffile and pdffile.pdfshapes - if not pdfshapes or pdffile.timestamp~=timestamp then + 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) or {} + 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 -fonts.handlers.otf.features.register { +otfregister { name="svg", description="svg glyphs", manipulators={ @@ -27865,9 +27919,10 @@ local function initializepng(tfmdata,kind,value) }) end pdftovirtual(tfmdata,pdfshapes,"png") + return true end end -fonts.handlers.otf.features.register { +otfregister { name="sbix", description="sbix glyphs", manipulators={ @@ -27875,7 +27930,7 @@ fonts.handlers.otf.features.register { node=initializepng, } } -fonts.handlers.otf.features.register { +otfregister { name="cblc", description="cblc glyphs", manipulators={ @@ -27883,11 +27938,36 @@ fonts.handlers.otf.features.register { 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-2019-08-13.lua scope for “font-ocl”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ocl”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otc” 95a4ff28ba4afb55a978a4aecfd688bf] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otc” 1204a2fdc436e644127c0aa38ab69607] --- if not modules then modules={} end modules ['font-otc']={ version=1.001, @@ -27907,9 +27987,10 @@ local fonts=fonts local otf=fonts.handlers.otf local registerotffeature=otf.features.register local setmetatableindex=table.setmetatableindex -local checkmerge=fonts.helpers.checkmerge -local checkflags=fonts.helpers.checkflags -local checksteps=fonts.helpers.checksteps +local fonthelpers=fonts.helpers +local checkmerge=fonthelpers.checkmerge +local checkflags=fonthelpers.checkflags +local checksteps=fonthelpers.checksteps local normalized={ substitution="substitution", single="substitution", @@ -28031,6 +28112,7 @@ local function addfeature(data,feature,specifications) local done=0 local skip=0 local aglunicodes=false + local privateslot=fonthelpers.privateslot local specifications=validspecification(specifications,feature) if not specifications then return @@ -28053,6 +28135,12 @@ local function addfeature(data,feature,specifications) 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 @@ -28082,7 +28170,7 @@ local function addfeature(data,feature,specifications) replacement=replacement[1] end replacement=tounicode(replacement) - if replacement and descriptions[replacement] then + if replacement and (nocheck or descriptions[replacement]) then cover(coverage,unicode,replacement) done=done+1 else @@ -28452,7 +28540,6 @@ local function addfeature(data,feature,specifications) local featuretype=normalized[specification.type or "substitution"] or "substitution" local featureflags=specification.flags or noflags local nocheck=specification.nocheck - local futuresteps=specification.futuresteps local featureorder=specification.order or { feature } local featurechain=(featuretype=="chainsubstitution" or featuretype=="chainposition") and 1 or 0 local nofsteps=0 @@ -28637,10 +28724,10 @@ end otf.enhancers.enhance=enhance otf.enhancers.register("check extra features",enhance) -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otc”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otc”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-onr” d4d2449b4084e6afb1837ae5835082cc] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-onr” d4d2449b4084e6afb1837ae5835082cc] --- if not modules then modules={} end modules ['font-onr']={ version=1.001, @@ -29012,10 +29099,10 @@ function readers.getinfo(filename) end end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-onr”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-onr”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-one” 987c5c5ed3754ad2feab80985067d59e] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-one” 987c5c5ed3754ad2feab80985067d59e] --- if not modules then modules={} end modules ['font-one']={ version=1.001, @@ -29726,10 +29813,10 @@ registerafmenhancer("normalize features",enhance_normalize_features) registerafmenhancer("check extra features",otfenhancers.enhance) registerafmenhancer("fix names",enhance_fix_names) -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-one”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-one”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-afk” 54d554530e75c57c56ee76234724e26d] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-afk” 54d554530e75c57c56ee76234724e26d] --- if not modules then modules={} end modules ['font-afk']={ version=1.001, @@ -29896,10 +29983,10 @@ fonts.handlers.afm.helpdata={ } } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-afk”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-afk”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-tfm” 3bbba3214fd0b8c6f35ad85592fc2917] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-tfm” 3bbba3214fd0b8c6f35ad85592fc2917] --- if not modules then modules={} end modules ['luatex-fonts-tfm']={ version=1.001, @@ -30414,10 +30501,10 @@ registertfmfeature { } } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-tfm”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-tfm”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-lua” 55b281fb98f7bd848fc19928f376f647] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-lua” 55b281fb98f7bd848fc19928f376f647] --- if not modules then modules={} end modules ['font-lua']={ version=1.001, @@ -30457,10 +30544,10 @@ function readers.lua(specification) return check_lua(specification,fullname) end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-lua”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-lua”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-def” f66c365dae4499f982d8bf16e5d37de3] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-def” f66c365dae4499f982d8bf16e5d37de3] --- if not modules then modules={} end modules ['font-def']={ version=1.001, @@ -30862,10 +30949,10 @@ function font.getfont(id) end callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)") -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-def”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-def”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-def” 5ad79120ebc5e60f4d322fb3ee13bffe] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-def” 5ad79120ebc5e60f4d322fb3ee13bffe] --- if not modules then modules={} end modules ['luatex-fonts-def']={ version=1.001, @@ -30946,10 +31033,10 @@ function fonts.definers.applypostprocessors(tfmdata) return tfmdata end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-def”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-def”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-ext” 01015ab3758cdc2af29394e6d502a91a] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-ext” 01015ab3758cdc2af29394e6d502a91a] --- if not modules then modules={} end modules ['luatex-fonts-ext']={ version=1.001, @@ -31135,10 +31222,10 @@ registerotffeature { } } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-ext”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-ext”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-tex” 77c374b0ef00c2fb12188ec42beb4257] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-tex” 77c374b0ef00c2fb12188ec42beb4257] --- if not modules then modules={} end modules ['font-imp-tex']={ version=1.001, @@ -31237,10 +31324,10 @@ registerotffeature { description="arabic digits", } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-tex”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-tex”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-ligatures” 043daa4fcccf2560868da359d71d3a4a] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-ligatures” 043daa4fcccf2560868da359d71d3a4a] --- if not modules then modules={} end modules ['font-imp-ligatures']={ version=1.001, @@ -31354,10 +31441,10 @@ if context then } end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-ligatures”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-ligatures”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-italics” fe1ca80fb5ea4a2f8d2d5c484e7ba913] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-italics” fe1ca80fb5ea4a2f8d2d5c484e7ba913] --- if not modules then modules={} end modules ['font-imp-italics']={ version=1.001, @@ -31463,10 +31550,10 @@ if context then registerafmfeature(dimensions_specification) end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-italics”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-italics”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-effects” 73a660359a0ec71e44cc2b7225a715ac] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-effects” 73a660359a0ec71e44cc2b7225a715ac] --- if not modules then modules={} end modules ['font-imp-effects']={ version=1.001, @@ -31823,10 +31910,10 @@ local specification={ registerotffeature(specification) registerafmfeature(specification) -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-effects”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-effects”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-lig” b9dbe77ce747d4c35bb2a20ffbe5aa51] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-lig” b9dbe77ce747d4c35bb2a20ffbe5aa51] --- fonts.handlers.otf.addfeature { @@ -33895,10 +33982,10 @@ fonts.handlers.otf.addfeature { ["type"]="ligature", } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-lig”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-lig”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-gbn” d25472d54c4841db43a745764a63533e] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-gbn” d25472d54c4841db43a745764a63533e] --- if not modules then modules={} end modules ['luatex-fonts-gbn']={ version=1.001, @@ -34163,7 +34250,7 @@ function nodes.simple_font_handler(head,groupcode,size,packtype,direction) return head end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-gbn”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-gbn”] --- --- vim:ft=lua:sw=2:ts=8:et:tw=79 diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua index 418b9d69d42..172fcc7f7ed 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua @@ -99,6 +99,7 @@ nuts.getchar = direct.getchar nuts.getcomponents = direct.getcomponents nuts.getdirection = direct.getdirection nuts.getdisc = direct.getdisc +nuts.getreplace = direct.getreplace nuts.getfield = direct.getfield nuts.getfont = direct.getfont nuts.getid = direct.getid @@ -115,6 +116,7 @@ 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 @@ -261,3 +263,19 @@ do } 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 diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-con.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-con.lua index 9c1e825fa2e..652794142b5 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-con.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-con.lua @@ -444,9 +444,10 @@ function constructors.scale(tfmdata,specification) -- boundarychar = 65536, -- there is now a string 'right_boundary' -- false_boundarychar = 65536, -- produces invalid tfm in luatex -- - targetproperties.language = properties.language or "dflt" -- inherited - targetproperties.script = properties.script or "dflt" -- inherited - targetproperties.mode = properties.mode or "base" -- inherited + targetproperties.language = properties.language or "dflt" -- inherited + targetproperties.script = properties.script or "dflt" -- inherited + targetproperties.mode = properties.mode or "base" -- inherited + targetproperties.method = properties.method -- local askedscaledpoints = scaledpoints local scaledpoints, delta = constructors.calculatescale(tfmdata,scaledpoints,nil,specification) -- no shortcut, dan be redefined diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-dsp.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-dsp.lua index 79749741c34..7777f9c6ad4 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-dsp.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-dsp.lua @@ -3159,6 +3159,14 @@ function readers.cpal(f,fontdata,specification) end end +local compress = gzip and gzip.compress +local compressed = compress and gzip.compressed + +-- At some point I will delay loading and only store the offsets (in context lmtx +-- only). + +-- compressed = false + function readers.svg(f,fontdata,specification) local tableoffset = gotodatatable(f,fontdata,"svg",specification.glyphs) if tableoffset then @@ -3184,10 +3192,14 @@ function readers.svg(f,fontdata,specification) 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 = readstring(f,entry.length) + data = data } end fontdata.svgshapes = entries diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua index d79ed657e02..3752203fa22 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua @@ -8,9 +8,14 @@ if not modules then modules = { } end modules ['font-ocl'] = { -- todo : user list of colors +if CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 then + return +end + local tostring, tonumber, next = tostring, tonumber, next local round, max = math.round, math.round -local sortedkeys, sortedhash = table.sortedkeys, table.sortedhash +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 @@ -24,6 +29,7 @@ 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"] @@ -150,7 +156,7 @@ local pop = { "pdf", "page", "Q" } -- -- only shows the first glyph in acrobat and nothing more. No problem with other -- -- renderers. -- --- local function initialize(tfmdata,kind,value) -- hm, always value +-- local function initializeoverlay(tfmdata,kind,value) -- hm, always value -- if value then -- local resources = tfmdata.resources -- local palettes = resources.colorpalettes @@ -193,11 +199,11 @@ local pop = { "pdf", "page", "Q" } -- local goback = w ~= 0 and leftcommand[w] or nil -- needs checking: are widths the same -- local t = { -- start, --- not u and actualb or { "pdf", "page", (getactualtext(tounicode(u))) } +-- not u and actualb or { "pdf", "page", (getactualtext(tounicode(u))) }, +-- push, -- } --- local n = 2 +-- local n = 3 -- local l = nil --- n = n + 1 t[n] = push -- for i=1,s do -- local entry = colorlist[i] -- local v = colorvalues[entry.class] or default @@ -220,11 +226,8 @@ local pop = { "pdf", "page", "Q" } -- end -- end -- end --- --- -- Here we have no color change in BT .. ET and more q Q pairs but even then acrobat --- -- fails displaying the overlays correctly. Other renderers do it right. -local function initialize(tfmdata,kind,value) +local function initializeoverlay(tfmdata,kind,value) if value then local resources = tfmdata.resources local palettes = resources.colorpalettes @@ -271,54 +274,40 @@ local function initialize(tfmdata,kind,value) local s = #colorlist local goback = w ~= 0 and leftcommand[w] or nil -- needs checking: are widths the same local t = { - start, -- really needed - not u and actualb or { "pdf", "page", (getactualtext(tounicode(u))) } + not u and actualb or { "pdf", "page", (getactualtext(tounicode(u))) }, + push, } local n = 2 local l = nil - local f = false for i=1,s do local entry = colorlist[i] local v = colorvalues[entry.class] or default if v and l ~= v then - if f then - n = n + 1 t[n] = pop - end - n = n + 1 t[n] = push - f = true n = n + 1 t[n] = v l = v - else - if f then - n = n + 1 t[n] = pop - end - f = false - l = nil end n = n + 1 t[n] = charcommand[entry.slot] if s > 1 and i < s and goback then n = n + 1 t[n] = goback end end - if f then - n = n + 1 t[n] = pop - end + n = n + 1 t[n] = pop n = n + 1 t[n] = actuale - -- n = n + 1 t[n] = stop -- not needed character.commands = t end end end + return true end end end -fonts.handlers.otf.features.register { +otfregister { name = "colr", description = "color glyphs", manipulators = { - base = initialize, - node = initialize, + base = initializeoverlay, + node = initializeoverlay, } } @@ -382,19 +371,25 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = png|svg for unicode, character in sortedhash(characters) do -- sort is nicer for svg local index = character.index if index then - local pdf = pdfshapes[index] - local typ = type(pdf) - local data = nil - local dx = nil - local dy = nil + local pdf = pdfshapes[index] + local typ = type(pdf) + local data = nil + local dx = nil + local dy = nil + local scale = 1 if typ == "table" then - data = pdf.data - dx = pdf.dx or 0 - dy = pdf.dy or 0 + data = pdf.data + dx = pdf.x or pdf.dx or 0 + dy = pdf.y or pdf.dy or 0 + scale = pdf.scale or 1 elseif typ == "string" then data = pdf dx = 0 dy = 0 + elseif typ == "number" then + data = pdf + dx = 0 + dy = 0 end if data then -- We can delay storage by a lua function in commands: but then we need to @@ -404,12 +399,20 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = png|svg local wd = character.width or 0 local ht = character.height or 0 local dp = character.depth or 0 - -- The down and right will change too (we can move that elsewhere). + -- The down and right will change too (we can move that elsewhere). We have + -- a different treatment in lmtx but the next kind of works. These images are + -- a mess anyway as in svg the bbox can be messed up absent). A png image + -- needs the x/y. I might normalize this once we moev to lmtx exlusively. character.commands = { not unicode and actualb or { "pdf", "page", (getactualtext(unicode)) }, - downcommand[dp + dy * hfactor], - rightcommand[dx * hfactor], - vfimage(wd,ht,dp,data,name), + -- lmtx (when we deal with depth in vfimage, currently disabled): + -- downcommand [dy * hfactor], + -- rightcommand[dx * hfactor], + -- vfimage(wd,ht,dp,data,name), + -- mkiv + downcommand [dp + dy * hfactor], + rightcommand[ dx * hfactor], + vfimage(scale*wd,ht,dp,data,pdfshapes.filename or ""), actuale, } character[kind] = true @@ -455,7 +458,7 @@ do name = "otfsvg", program = "inkscape", method = "pipeto", - template = "--shell > temp-otf-svg-shape.log", + template = "--export-area-drawing --shell > temp-otf-svg-shape.log", reporter = report_svg, } @@ -464,20 +467,31 @@ do -- poor mans variant for generic: -- runner = function() - return io.open("inkscape --shell > temp-otf-svg-shape.log","w") + return io.popen("inkscape --export-area-drawing --shell > temp-otf-svg-shape.log","w") end end - function otfsvg.topdf(svgshapes) + -- There are svg out there with bad viewBox specifications where shapes lay outside that area, + -- but trying to correct that didn't work out well enough so I discarded that code. BTW, we + -- decouple the inskape run and the loading run because inkscape is working in the background + -- in the files so we need to have unique files. + -- + -- Because a generic setup can be flawed we need to catch bad inkscape runs which add a bit of + -- ugly overhead. Bah. + + function otfsvg.topdf(svgshapes,tfmdata) local pdfshapes = { } local inkscape = runner() if inkscape then - 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-pdf=%s\n"] - local filterglyph = otfsvg.filterglyph - local nofdone = 0 + local indices = fonts.getindices(tfmdata) + 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-pdf=%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 @@ -489,24 +503,55 @@ do local pdffile = f_pdffile(index) savedata(svgfile,data) inkscape:write(f_convert(svgfile,pdffile)) - pdfshapes[index] = true + processed[index] = true nofdone = nofdone + 1 - if nofdone % 100 == 0 then - report_svg("%i shapes processed",nofdone) + 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, pdfshapes do + for index in next, processed do local svgfile = f_svgfile(index) local pdffile = f_pdffile(index) - pdfshapes[index] = loaddata(pdffile) + -- local fntdata = descriptions[indices[index]] + -- local bounds = fntdata and fntdata.boundingbox + local pdfdata = loaddata(pdffile) + if pdfdata and pdfdata ~= "" then + pdfshapes[index] = { + data = pdfdata, + -- x = bounds and bounds[1] or 0, + -- y = bounds and bounds[2] or 0, + } + 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 "-") @@ -527,20 +572,23 @@ local function initializesvg(tfmdata,kind,value) -- hm, always value end local pdffile = containers.read(otf.pdfcache,hash) local pdfshapes = pdffile and pdffile.pdfshapes - if not pdfshapes or pdffile.timestamp ~= timestamp then + if not pdfshapes or pdffile.timestamp ~= timestamp or not next(pdfshapes) then + -- the next test tries to catch errors in generic usage but of course can result + -- in running again and again local svgfile = containers.read(otf.svgcache,hash) local svgshapes = svgfile and svgfile.svgshapes - pdfshapes = svgshapes and otfsvg.topdf(svgshapes) or { } + 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 -fonts.handlers.otf.features.register { +otfregister { name = "svg", description = "svg glyphs", manipulators = { @@ -648,10 +696,11 @@ local function initializepng(tfmdata,kind,value) -- hm, always value end -- pdftovirtual(tfmdata,pdfshapes,"png") + return true end end -fonts.handlers.otf.features.register { +otfregister { name = "sbix", description = "sbix glyphs", manipulators = { @@ -660,7 +709,7 @@ fonts.handlers.otf.features.register { } } -fonts.handlers.otf.features.register { +otfregister { name = "cblc", description = "cblc glyphs", manipulators = { @@ -668,3 +717,36 @@ fonts.handlers.otf.features.register { node = initializepng, } } + +if context then + + -- untested in generic and might clash with other color trickery + -- anyway so let's stick to context only + + 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 + -- forget about it + end + end + + otfregister { + name = "color", + description = "color glyphs", + manipulators = { + base = initializecolor, + node = initializecolor, + } + } + +end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-osd.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-osd.lua index 203c1d79d40..b97ac9c6f57 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-osd.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-osd.lua @@ -1285,7 +1285,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces) local cp = getprev(current) local cnsn = getnext(cns) setlink(cp,n) - setlink(cns,current) + setlink(cns,current) -- cns ? setlink(c,cnsn) if c == stop then stop = cp diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otc.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otc.lua index a774a81c2c9..2643d022a57 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otc.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otc.lua @@ -22,9 +22,10 @@ local otf = fonts.handlers.otf local registerotffeature = otf.features.register local setmetatableindex = table.setmetatableindex -local checkmerge = fonts.helpers.checkmerge -local checkflags = fonts.helpers.checkflags -local checksteps = fonts.helpers.checksteps +local fonthelpers = fonts.helpers +local checkmerge = fonthelpers.checkmerge +local checkflags = fonthelpers.checkflags +local checksteps = fonthelpers.checksteps local normalized = { substitution = "substitution", @@ -167,6 +168,7 @@ local function addfeature(data,feature,specifications) local done = 0 local skip = 0 local aglunicodes = false + local privateslot = fonthelpers.privateslot local specifications = validspecification(specifications,feature) if not specifications then @@ -196,6 +198,13 @@ local function addfeature(data,feature,specifications) return u end end + if privateslot then + u = privateslot(code) -- no creation ! + if u then + -- unicodes[code] = u + return u + end + end local u = lpegmatch(p,code) if u then -- unicodes[code] = u @@ -229,7 +238,7 @@ local function addfeature(data,feature,specifications) replacement = replacement[1] end replacement = tounicode(replacement) - if replacement and descriptions[replacement] then + if replacement and (nocheck or descriptions[replacement]) then cover(coverage,unicode,replacement) done = done + 1 else @@ -620,7 +629,6 @@ local function addfeature(data,feature,specifications) local featuretype = normalized[specification.type or "substitution"] or "substitution" local featureflags = specification.flags or noflags local nocheck = specification.nocheck - local futuresteps = specification.futuresteps local featureorder = specification.order or { feature } local featurechain = (featuretype == "chainsubstitution" or featuretype == "chainposition") and 1 or 0 local nofsteps = 0 diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otl.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otl.lua index f8cd8217cd7..5d3bd4230cb 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otl.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otl.lua @@ -52,11 +52,12 @@ local report_otf = logs.reporter("fonts","otf loading") local fonts = fonts local otf = fonts.handlers.otf -otf.version = 3.109 -- beware: also sync font-mis.lua and in mtx-fonts +otf.version = 3.110 -- 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) otf.pdfcache = containers.define("fonts", "pdf", otf.version, true) +otf.mpscache = containers.define("fonts", "mps", otf.version, true) otf.svgenabled = false otf.pngenabled = false diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua index 63130220069..5091fd76570 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua @@ -177,7 +177,6 @@ registertracker("otf.sample.silent", "otf.steps=silent","otf.substitutions","otf local nuts = nodes.nuts -local getfield = nuts.getfield local getnext = nuts.getnext local setnext = nuts.setnext local getprev = nuts.getprev @@ -193,6 +192,7 @@ 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 getcomponents = nuts.getcomponents -- the original one, not yet node-aux local setcomponents = nuts.setcomponents -- the original one, not yet node-aux @@ -2090,7 +2090,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) if keepdisc then keepdisc = false lookaheaddisc = current - local replace = getfield(current,"replace") + local replace = getreplace(current) if not replace then sweepoverflow = true sweepnode = current @@ -2167,7 +2167,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) lookaheaddisc = current end -- we assume a simple text only replace (we could use nuts.count) - local replace = getfield(current,"replace") + local replace = getreplace(current) while replace and i < s do if getid(replace) == glyph_code then i = i + 1 @@ -2213,7 +2213,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) backtrackdisc = current end -- we assume a simple text only replace (we could use nuts.count) - local replace = getfield(current,"replace") + local replace = getreplace(current) while replace and i > 1 do if getid(replace) == glyph_code then i = i - 1 @@ -3386,7 +3386,7 @@ local function t_run_single(start,stop,font,attr,lookupcache) -- how about post ... we can probably merge this into the while while getid(s) == disc_code do ss = getnext(s) - s = getfield(s,"replace") + s = getreplace(s) if not s then s = ss ss = nil @@ -3413,7 +3413,7 @@ local function t_run_single(start,stop,font,attr,lookupcache) end while getid(s) == disc_code do ss = getnext(s) - s = getfield(s,"replace") + s = getreplace(s) if not s then s = ss ss = nil @@ -3556,7 +3556,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) end while getid(s) == disc_code do ss = getnext(s) - s = getfield(s,"replace") + s = getreplace(s) if not s then s = ss ss = nil @@ -3583,7 +3583,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) end while getid(s) == disc_code do ss = getnext(s) - s = getfield(s,"replace") + s = getreplace(s) if not s then s = ss ss = nil diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-oup.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-oup.lua index 51b1c248f87..0e7e25808ca 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-oup.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-oup.lua @@ -720,6 +720,10 @@ local function checklookups(fontdata,missing,nofmissing) 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") @@ -730,20 +734,22 @@ local function unifymissing(fontdata) resources.unicodes = unicodes for unicode, d in next, fontdata.descriptions do if unicode < privateoffset then - local name = d.name - if name then - unicodes[name] = unicode + if unicode >= puafirst and unicode <= pualast then + -- report_unicodes("resolving private unicode %U",unicode) + else + local name = d.name + if name then + unicodes[name] = unicode + end end + else + -- report_unicodes("resolving private unicode %U",unicode) end end fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups) resources.unicodes = nil end -local firstprivate = fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000 -local puafirst = 0xE000 -local pualast = 0xF8FF - local function unifyglyphs(fontdata,usenames) local private = fontdata.private or privateoffset local glyphs = fontdata.glyphs diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lpeg.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lpeg.lua index 51bc1d3df30..7979a40fb94 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lpeg.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lpeg.lua @@ -295,7 +295,7 @@ patterns.longtostring = Cs(whitespace^0/"" * ((patterns.quoted + nonwhitespace^ -- return P { P(pattern) + 1 * V(1) } -- end -function anywhere(pattern) -- faster +local function anywhere(pattern) -- faster return (1-P(pattern))^0 * P(pattern) end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lua.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lua.lua index 6e9606e849f..51399216ccf 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lua.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lua.lua @@ -35,6 +35,12 @@ if LUAVERSION < 5.2 and jit then LUAVERSION = 5.2 end +-- this is lmtx only: + +if lua and lua.openfile then + io.open = lua.openfile +end + -- lpeg if not lpeg then diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-table.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-table.lua index cffdcc23e20..e8282038674 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-table.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-table.lua @@ -287,6 +287,37 @@ local function sortedhash(t,cmp) return nothing end +-- local function iterate(t,i) +-- local i = i + 1 +-- if i <= t.n then +-- local k = t[i] +-- return i, k, t.t[k] +-- end +-- end +-- +-- local function indexedhash(t,cmp) +-- if t then +-- local s +-- if cmp then +-- -- it would be nice if the sort function would accept a third argument (or nicer, an optional first) +-- s = sortedhashkeys(t,function(a,b) return cmp(t,a,b) end) +-- else +-- s = sortedkeys(t) -- the robust one +-- end +-- local m = #s +-- if m == 1 then +-- return next, t +-- elseif m > 0 then +-- s.n = m +-- s.t = t +-- return iterate, s, 0 +-- end +-- end +-- return nothing +-- end +-- +-- -- for i, k, v in indexedhash(t) do print(k,v,s) end + table.sortedhash = sortedhash table.sortedpairs = sortedhash -- obsolete diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-unicode.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-unicode.lua index 13e0a3fa1c1..c57aaf33ebc 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-unicode.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-unicode.lua @@ -1081,56 +1081,62 @@ function utf.utf32_to_utf8_t(t,endian) return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t end -local function little(b) - if b < 0x10000 then - return char(b%256,rshift(b,8)) - else - b = b - 0x10000 - local b1 = rshift(b,10) + 0xD800 - local b2 = b%1024 + 0xDC00 - return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8)) +if bit32 then + + local rshift = bit32.rshift + + local function little(b) + if b < 0x10000 then + return char(b%256,rshift(b,8)) + else + b = b - 0x10000 + local b1 = rshift(b,10) + 0xD800 + local b2 = b%1024 + 0xDC00 + return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8)) + end end -end -local function big(b) - if b < 0x10000 then - return char(rshift(b,8),b%256) - else - b = b - 0x10000 - local b1 = rshift(b,10) + 0xD800 - local b2 = b%1024 + 0xDC00 - return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256) + local function big(b) + if b < 0x10000 then + return char(rshift(b,8),b%256) + else + b = b - 0x10000 + local b1 = rshift(b,10) + 0xD800 + local b2 = b%1024 + 0xDC00 + return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256) + end end -end -local l_remap = Cs((p_utf8byte/little+P(1)/"")^0) -local b_remap = Cs((p_utf8byte/big +P(1)/"")^0) + local l_remap = Cs((p_utf8byte/little+P(1)/"")^0) + local b_remap = Cs((p_utf8byte/big +P(1)/"")^0) -local function utf8_to_utf16_be(str,nobom) - if nobom then - return lpegmatch(b_remap,str) - else - return char(254,255) .. lpegmatch(b_remap,str) + local function utf8_to_utf16_be(str,nobom) + if nobom then + return lpegmatch(b_remap,str) + else + return char(254,255) .. lpegmatch(b_remap,str) + end end -end -local function utf8_to_utf16_le(str,nobom) - if nobom then - return lpegmatch(l_remap,str) - else - return char(255,254) .. lpegmatch(l_remap,str) + local function utf8_to_utf16_le(str,nobom) + if nobom then + return lpegmatch(l_remap,str) + else + return char(255,254) .. lpegmatch(l_remap,str) + end end -end -utf.utf8_to_utf16_be = utf8_to_utf16_be -utf.utf8_to_utf16_le = utf8_to_utf16_le + utf.utf8_to_utf16_be = utf8_to_utf16_be + utf.utf8_to_utf16_le = utf8_to_utf16_le -function utf.utf8_to_utf16(str,littleendian,nobom) - if littleendian then - return utf8_to_utf16_le(str,nobom) - else - return utf8_to_utf16_be(str,nobom) + function utf.utf8_to_utf16(str,littleendian,nobom) + if littleendian then + return utf8_to_utf16_le(str,nobom) + else + return utf8_to_utf16_be(str,nobom) + end end + end local pattern = Cs ( diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-reference.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-reference.lua index 3120f45135b..b8a21fc937b 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-reference.lua +++ b/Master/texmf-dist/tex/luatex/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 : 08/11/19 20:03:46 +-- merge date : 10/29/19 15:00:00 do -- begin closure to overcome local limits and interference @@ -20,6 +20,9 @@ if LUAVERSION<5.2 and jit then MINORVERSION=2 LUAVERSION=5.2 end +if lua and lua.openfile then + io.open=lua.openfile +end if not lpeg then lpeg=require("lpeg") end @@ -296,7 +299,7 @@ patterns.propername=(uppercase+lowercase+underscore)*(uppercase+lowercase+unders patterns.somecontent=(anything-newline-space)^1 patterns.beginline=#(1-newline) patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(endofstring+Cc(" ")))^0)) -function anywhere(pattern) +local function anywhere(pattern) return (1-P(pattern))^0*P(pattern) end lpeg.anywhere=anywhere @@ -3433,7 +3436,7 @@ local environment={ stripzero=patterns.stripzero, stripzeros=patterns.stripzeros, escapedquotes=string.escapedquotes, - FORMAT=string.f9, + FORMAT=string.f6, } local arguments={ "a1" } setmetatable(arguments,{ __index=function(t,k) @@ -3641,12 +3644,25 @@ local format_n=function() n=n+1 return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n) end -local format_N=function(f) - n=n+1 - if not f or f=="" then - f=".9" - end - return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n) +local format_N if environment.FORMAT then + format_N=function(f) + n=n+1 + if not f or f=="" then + return format("FORMAT(a%s,'%%.9f')",n) + elseif f==".6" then + return format("FORMAT(a%s)",n) + else + return format("FORMAT(a%s,'%%%sf')",n,f) + end + end +else + format_N=function(f) + n=n+1 + if not f or f=="" then + f=".9" + end + return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n) + end end local format_a=function(f) n=n+1 @@ -4865,6 +4881,7 @@ nuts.getchar=direct.getchar nuts.getcomponents=direct.getcomponents nuts.getdirection=direct.getdirection nuts.getdisc=direct.getdisc +nuts.getreplace=direct.getreplace nuts.getfield=direct.getfield nuts.getfont=direct.getfont nuts.getid=direct.getid @@ -4881,6 +4898,7 @@ 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 @@ -4998,6 +5016,17 @@ do 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 end -- closure @@ -8989,7 +9018,8 @@ function constructors.scale(tfmdata,specification) 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.mode=properties.mode or "base" + targetproperties.method=properties.method local askedscaledpoints=scaledpoints local scaledpoints,delta=constructors.calculatescale(tfmdata,scaledpoints,nil,specification) local hdelta=delta @@ -19773,6 +19803,8 @@ function readers.cpal(f,fontdata,specification) 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 @@ -19794,10 +19826,14 @@ function readers.svg(f,fontdata,specification) 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=readstring(f,entry.length) + data=data } end fontdata.svgshapes=entries @@ -21059,6 +21095,9 @@ local function checklookups(fontdata,missing,nofmissing) 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") @@ -21069,18 +21108,19 @@ local function unifymissing(fontdata) resources.unicodes=unicodes for unicode,d in next,fontdata.descriptions do if unicode<privateoffset then - local name=d.name - if name then - unicodes[name]=unicode + 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 firstprivate=fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000 -local puafirst=0xE000 -local pualast=0xF8FF local function unifyglyphs(fontdata,usenames) local private=fontdata.private or privateoffset local glyphs=fontdata.glyphs @@ -23049,11 +23089,12 @@ 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.109 +otf.version=3.110 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 @@ -26076,7 +26117,6 @@ 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 getfield=nuts.getfield local getnext=nuts.getnext local setnext=nuts.setnext local getprev=nuts.getprev @@ -26092,6 +26132,7 @@ 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 getcomponents=nuts.getcomponents local setcomponents=nuts.setcomponents @@ -27670,7 +27711,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) if keepdisc then keepdisc=false lookaheaddisc=current - local replace=getfield(current,"replace") + local replace=getreplace(current) if not replace then sweepoverflow=true sweepnode=current @@ -27742,7 +27783,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) if notmatchpre[current]~=notmatchreplace[current] then lookaheaddisc=current end - local replace=getfield(current,"replace") + local replace=getreplace(current) while replace and i<s do if getid(replace)==glyph_code then i=i+1 @@ -27786,7 +27827,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) if notmatchpost[current]~=notmatchreplace[current] then backtrackdisc=current end - local replace=getfield(current,"replace") + local replace=getreplace(current) while replace and i>1 do if getid(replace)==glyph_code then i=i-1 @@ -28750,7 +28791,7 @@ local function t_run_single(start,stop,font,attr,lookupcache) end while getid(s)==disc_code do ss=getnext(s) - s=getfield(s,"replace") + s=getreplace(s) if not s then s=ss ss=nil @@ -28777,7 +28818,7 @@ local function t_run_single(start,stop,font,attr,lookupcache) end while getid(s)==disc_code do ss=getnext(s) - s=getfield(s,"replace") + s=getreplace(s) if not s then s=ss ss=nil @@ -28904,7 +28945,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) end while getid(s)==disc_code do ss=getnext(s) - s=getfield(s,"replace") + s=getreplace(s) if not s then s=ss ss=nil @@ -28931,7 +28972,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) end while getid(s)==disc_code do ss=getnext(s) - s=getfield(s,"replace") + s=getreplace(s) if not s then s=ss ss=nil @@ -30708,7 +30749,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces) local cp=getprev(current) local cnsn=getnext(cns) setlink(cp,n) - setlink(cns,current) + setlink(cns,current) setlink(c,cnsn) if c==stop then stop=cp @@ -32071,9 +32112,13 @@ if not modules then modules={} end modules ['font-ocl']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } +if CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 then + return +end local tostring,tonumber,next=tostring,tonumber,next local round,max=math.round,math.round -local sortedkeys,sortedhash=table.sortedkeys,table.sortedhash +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 @@ -32083,6 +32128,7 @@ 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 @@ -32139,7 +32185,7 @@ end local start={ "pdf","mode","font" } local push={ "pdf","page","q" } local pop={ "pdf","page","Q" } -local function initialize(tfmdata,kind,value) +local function initializeoverlay(tfmdata,kind,value) if value then local resources=tfmdata.resources local palettes=resources.colorpalettes @@ -32181,52 +32227,39 @@ local function initialize(tfmdata,kind,value) local s=#colorlist local goback=w~=0 and leftcommand[w] or nil local t={ - start, - not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) } + not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) }, + push, } local n=2 local l=nil - local f=false for i=1,s do local entry=colorlist[i] local v=colorvalues[entry.class] or default if v and l~=v then - if f then - n=n+1 t[n]=pop - end - n=n+1 t[n]=push - f=true n=n+1 t[n]=v l=v - else - if f then - n=n+1 t[n]=pop - end - f=false - l=nil end n=n+1 t[n]=charcommand[entry.slot] if s>1 and i<s and goback then n=n+1 t[n]=goback end end - if f then - n=n+1 t[n]=pop - end + n=n+1 t[n]=pop n=n+1 t[n]=actuale character.commands=t end end end + return true end end end -fonts.handlers.otf.features.register { +otfregister { name="colr", description="color glyphs", manipulators={ - base=initialize, - node=initialize, + base=initializeoverlay, + node=initializeoverlay, } } do @@ -32277,14 +32310,20 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) local data=nil local dx=nil local dy=nil + local scale=1 if typ=="table" then data=pdf.data - dx=pdf.dx or 0 - dy=pdf.dy or 0 + dx=pdf.x or pdf.dx or 0 + dy=pdf.y or pdf.dy or 0 + scale=pdf.scale or 1 elseif typ=="string" then data=pdf dx=0 dy=0 + elseif typ=="number" then + data=pdf + dx=0 + dy=0 end if data then local bt=unicode and getactualtext(unicode) @@ -32293,9 +32332,9 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) local dp=character.depth or 0 character.commands={ not unicode and actualb or { "pdf","page",(getactualtext(unicode)) }, - downcommand[dp+dy*hfactor], - rightcommand[dx*hfactor], - vfimage(wd,ht,dp,data,name), + downcommand [dp+dy*hfactor], + rightcommand[ dx*hfactor], + vfimage(scale*wd,ht,dp,data,pdfshapes.filename or ""), actuale, } character[kind]=true @@ -32329,24 +32368,27 @@ do name="otfsvg", program="inkscape", method="pipeto", - template="--shell > temp-otf-svg-shape.log", + template="--export-area-drawing --shell > temp-otf-svg-shape.log", reporter=report_svg, } if not runner then runner=function() - return io.open("inkscape --shell > temp-otf-svg-shape.log","w") + return io.popen("inkscape --export-area-drawing --shell > temp-otf-svg-shape.log","w") end end - function otfsvg.topdf(svgshapes) + function otfsvg.topdf(svgshapes,tfmdata) local pdfshapes={} local inkscape=runner() if inkscape then + local indices=fonts.getindices(tfmdata) + 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-pdf=%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 @@ -32358,24 +32400,51 @@ do local pdffile=f_pdffile(index) savedata(svgfile,data) inkscape:write(f_convert(svgfile,pdffile)) - pdfshapes[index]=true + processed[index]=true nofdone=nofdone+1 - if nofdone%100==0 then - report_svg("%i shapes processed",nofdone) + 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,pdfshapes do + for index in next,processed do local svgfile=f_svgfile(index) local pdffile=f_pdffile(index) - pdfshapes[index]=loaddata(pdffile) + 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 "-") @@ -32394,19 +32463,20 @@ local function initializesvg(tfmdata,kind,value) end local pdffile=containers.read(otf.pdfcache,hash) local pdfshapes=pdffile and pdffile.pdfshapes - if not pdfshapes or pdffile.timestamp~=timestamp then + 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) or {} + 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 -fonts.handlers.otf.features.register { +otfregister { name="svg", description="svg glyphs", manipulators={ @@ -32489,9 +32559,10 @@ local function initializepng(tfmdata,kind,value) }) end pdftovirtual(tfmdata,pdfshapes,"png") + return true end end -fonts.handlers.otf.features.register { +otfregister { name="sbix", description="sbix glyphs", manipulators={ @@ -32499,7 +32570,7 @@ fonts.handlers.otf.features.register { node=initializepng, } } -fonts.handlers.otf.features.register { +otfregister { name="cblc", description="cblc glyphs", manipulators={ @@ -32507,6 +32578,11 @@ fonts.handlers.otf.features.register { node=initializepng, } } +if context then + +--removed + +end end -- closure @@ -32530,9 +32606,10 @@ local fonts=fonts local otf=fonts.handlers.otf local registerotffeature=otf.features.register local setmetatableindex=table.setmetatableindex -local checkmerge=fonts.helpers.checkmerge -local checkflags=fonts.helpers.checkflags -local checksteps=fonts.helpers.checksteps +local fonthelpers=fonts.helpers +local checkmerge=fonthelpers.checkmerge +local checkflags=fonthelpers.checkflags +local checksteps=fonthelpers.checksteps local normalized={ substitution="substitution", single="substitution", @@ -32654,6 +32731,7 @@ local function addfeature(data,feature,specifications) local done=0 local skip=0 local aglunicodes=false + local privateslot=fonthelpers.privateslot local specifications=validspecification(specifications,feature) if not specifications then return @@ -32676,6 +32754,12 @@ local function addfeature(data,feature,specifications) 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 @@ -32705,7 +32789,7 @@ local function addfeature(data,feature,specifications) replacement=replacement[1] end replacement=tounicode(replacement) - if replacement and descriptions[replacement] then + if replacement and (nocheck or descriptions[replacement]) then cover(coverage,unicode,replacement) done=done+1 else @@ -33075,7 +33159,6 @@ local function addfeature(data,feature,specifications) local featuretype=normalized[specification.type or "substitution"] or "substitution" local featureflags=specification.flags or noflags local nocheck=specification.nocheck - local futuresteps=specification.futuresteps local featureorder=specification.order or { feature } local featurechain=(featuretype=="chainsubstitution" or featuretype=="chainposition") and 1 or 0 local nofsteps=0 diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-str.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-str.lua index ad22302df0c..432b39ec5ad 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-str.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-str.lua @@ -633,7 +633,7 @@ local environment = { stripzeros = patterns.stripzeros, escapedquotes = string.escapedquotes, - FORMAT = string.f9, + FORMAT = string.f6, } -- -- -- @@ -908,7 +908,7 @@ local format_L = function() return format("(a%s and 'TRUE' or 'FALSE')",n) end -local format_n = function() -- strips leading and trailing zeros and removes .0 +local format_n = function() -- strips leading and trailing zeros and removes .0, beware: can produce e notation n = n + 1 return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n) end @@ -938,13 +938,30 @@ end -- end -- end -local format_N = function(f) -- strips leading and trailing zeros - n = n + 1 - -- stripzero (singular) as we only have a number - if not f or f == "" then - f = ".9" - end -- always a leading number ! - return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n) +local format_N if environment.FORMAT then + + format_N = function(f) + n = n + 1 + if not f or f == "" then + return format("FORMAT(a%s,'%%.9f')",n) + elseif f == ".6" then + return format("FORMAT(a%s)",n) + else + return format("FORMAT(a%s,'%%%sf')",n,f) + end + end + +else + + format_N = function(f) -- strips leading and trailing zeros + n = n + 1 + -- stripzero (singular) as we only have a number + if not f or f == "" then + f = ".9" + end -- always a leading number ! + return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n) + end + end local format_a = function(f) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua index d3b5c734183..9538a15bb01 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua @@ -6,8 +6,8 @@ local ProvidesLuaModule = { name = "luaotfload-auxiliary", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / auxiliary functions", license = "GPL v2.0" } @@ -39,6 +39,13 @@ local stringbyte = string.byte local stringfind = string.find local tablecopy = table.copy +local harf = luaotfload.harfbuzz +local GSUBtag, GPOStag +if harf then + GSUBtag = harf.Tag.new("GSUB") + GPOStag = harf.Tag.new("GPOS") +end + local aux = { } local luaotfload_callbacks = { } @@ -101,6 +108,14 @@ luaotfload_callbacks [#luaotfload_callbacks + 1] = { "patch_font", set_sscale_dimens, "set_sscale_dimens", } +-- Starting with LuaTeX 1.11.2, this is a more reliable way of selecting the +-- right font than relying on psnames +luaotfload_callbacks [#luaotfload_callbacks + 1] = { + "patch_font", function(fontdata) + fontdata.subfont = fontdata.specification.sub or 1 + end, "set_font_index", +} + local default_units = 1000 --- fontobj -> int @@ -349,15 +364,27 @@ function aux.slot_of_name(font_id, glyphname, unsafe) local tfmdata = identifiers [font_id] if not tfmdata then return raw_slot_of_name (font_id, glyphname) end - local resources = tfmdata.resources if not resources then return false end - local unicodes = resources.unicodes if not unicodes then return false end - - local unicode = unicodes [glyphname] - if unicode then - if type (unicode) == "number" then - return unicode - else - return unicode [1] --- for multiple components + local hbdata = tfmdata.hb + if hbdata then + local hbshared = hbdata.shared + local nominals = hbshared.nominals + local hbfont = hbshared.font + + local gid = hbfont:get_glyph_from_name(glyphname) + if gid ~= nil then + return nominals[gid] or gid + hbshared.gid_offset + end + else + local resources = tfmdata.resources if not resources then return false end + local unicodes = resources.unicodes if not unicodes then return false end + + local unicode = unicodes [glyphname] + if unicode then + if type (unicode) == "number" then + return unicode + else + return unicode [1] --- for multiple components + end end end return false @@ -412,6 +439,11 @@ local function get_features(tfmdata) return features end +local function get_hbface(tfmdata) + if not tfmdata.hb then return end + return tfmdata.hbshared.face +end + --[[doc-- This function, modeled after “check_script()” from fontspec, returns true if in the given font, the script “asked_script” is accounted for in at @@ -429,9 +461,22 @@ function aux.provides_script(font_id, asked_script) return false end asked_script = stringlower(asked_script) - if font_id and font_id > 0 then - local tfmdata = identifiers[font_id] - if not tfmdata then return false end + local tfmdata = identifiers[font_id] + if not tfmdata then + logreport ("log", 0, "aux", "no font with id %d", font_id) + return false + end + local hbface = get_hbface(tfmdata) + if hbface then + local script = harf.Tag.new(asked_script == "dflt" and "DFLT" + or asked_script) + for _, tag in next, { GSUBtag, GPOStag } do + if hbface:ot_layout_find_script(tag, script) then + return true + end + end + return false + else local features = get_features (tfmdata) if features == false then logreport ("log", 1, "aux", "font no %d lacks a features table", font_id) @@ -452,7 +497,6 @@ function aux.provides_script(font_id, asked_script) "font no %d (%s) defines no feature for script %s", font_id, fontname, asked_script) end - logreport ("log", 0, "aux", "no font with id %d", font_id) return false end @@ -477,8 +521,30 @@ function aux.provides_language(font_id, asked_script, asked_language) return false end asked_script = stringlower(asked_script) - asked_language = stringlower(asked_language) - if font_id and font_id > 0 then + local tfmdata = identifiers[font_id] + if not tfmdata then + logreport ("log", 0, "aux", "no font with id %d", font_id) + return false + end + local hbface = get_hbface(tfmdata) + if hbface then + asked_language = stringupper(asked_language) + if asked_language == "DFLT" then + return aux.provides_script(font_id, asked_script) + end + local script = harf.Tag.new(asked_script == "dflt" and "DFLT" + or asked_script) + local language = harf.Tag.new(asked_language == "DFLT" and "dflt" + or asked_language) + for _, tag in next, { GSUBtag, GPOStag } do + local _, script_idx = hbface:ot_layout_find_script(tag, script) + if hbface:ot_layout_find_language(tag, script_idx, language) then + return true + end + end + return false + else + asked_language = stringlower(asked_language) local tfmdata = identifiers[font_id] if not tfmdata then return false end local features = get_features (tfmdata) @@ -504,9 +570,8 @@ function aux.provides_language(font_id, asked_script, asked_language) "font no %d (%s) defines no feature " .. "for script %s with language %s", font_id, fontname, asked_script, asked_language) + return false end - logreport ("log", 0, "aux", "no font with id %d", font_id) - return false end --[[doc-- @@ -558,12 +623,32 @@ function aux.provides_feature(font_id, asked_script, return false end asked_script = stringlower(asked_script) - asked_language = stringlower(asked_language) asked_feature = lpegmatch(strip_garbage, asked_feature) - if font_id > 0 then - local tfmdata = identifiers[font_id] - if not tfmdata then return false end + local tfmdata = identifiers[font_id] + if not tfmdata then + logreport ("log", 0, "aux", "no font with id %d", font_id) + return false + end + local hbface = get_hbface(tfmdata) + if hbface then + asked_language = stringupper(asked_language) + local script = harf.Tag.new(asked_script == "dflt" and "DFLT" + or asked_script) + local language = harf.Tag.new(asked_language == "DFLT" and "dflt" + or asked_language) + local feature = harf.Tag.new(feature) + + for _, tag in next, { GSUBtag, GPOStag } do + local _, script_idx = hbface:ot_layout_find_script(tag, script) + local _, language_idx = hbface:ot_layout_find_language(tag, script_idx, language) + if hbface:ot_layout_find_feature(tag, script_idx, language_idx, feature) then + return true + end + end + return false + else + asked_language = stringlower(asked_language) local features = get_features (tfmdata) if features == false then logreport ("log", 1, "aux", "font no %d lacks a features table", font_id) @@ -588,8 +673,6 @@ function aux.provides_feature(font_id, asked_script, "font no %d (%s) does not define feature %s for script %s with language %s", font_id, fontname, asked_feature, asked_script, asked_language) end - logreport ("log", 0, "aux", "no font with id %d", font_id) - return false end ----------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua index fdae0c4450c..ae78130b4f8 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua @@ -5,8 +5,8 @@ local ProvidesLuaModule = { name = "luaotfload-colors", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / color", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang, Dohyun Kim, David Carlisle", @@ -405,6 +405,7 @@ return function () initializers = { base = setcolor, node = setcolor, + plug = setcolor, } } return true diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua index fc30cc8343a..e9b818df2d8 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua @@ -7,8 +7,8 @@ local ProvidesLuaModule = { name = "luaotfload-configuration", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / config file reader", license = "GPL v2.0" } @@ -62,7 +62,7 @@ local filejoin = file.join local filereplacesuffix = file.replacesuffix local logreport = print -- overloaded later -local getwritablepath = caches.getwritablepath +local getwritablepath = luaotfload.fontloader.caches.getwritablepath local config_parser -- set later during init @@ -382,7 +382,7 @@ local set_default_features = function () global = { }, defaults = { }, } - current_features = luaotfload.features + local current_features = luaotfload.features for var, val in next, default_features do if var == "global" then current_features.global = val diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua index 06106189056..10a0853c890 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua @@ -5,8 +5,8 @@ do -- block to avoid to many local variables error local ProvidesLuaModule = { name = "luaotfload-database", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / database", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger", @@ -148,7 +148,6 @@ local gzipload = gzip.load local gzipsave = gzip.save local iolines = io.lines local ioopen = io.open -local iopopen = io.popen local kpseexpand_path = kpse.expand_path local kpsefind_file = kpse.find_file local kpselookup = kpse.lookup @@ -168,13 +167,14 @@ local stringgmatch = string.gmatch local stringgsub = string.gsub local stringlower = string.lower local stringsub = string.sub -local stringupper = string.upper local tableconcat = table.concat local tablesort = table.sort local utf8len = utf8.len local utf8offset = utf8.offset --- these come from Lualibs/Context +local context_environment = luaotfload.fontloader +local caches = context_environment.caches local filebasename = file.basename local filecollapsepath = file.collapsepath or file.collapse_path local filedirname = file.dirname @@ -198,9 +198,9 @@ local tablecontains = table.contains local tablecopy = table.copy local tablefastcopy = table.fastcopy local tabletofile = table.tofile -local tabletohash = table.tohash local tableserialize = table.serialize local names = fonts and fonts.names or { } +local resolversfindfile = context_environment.resolvers.findfile --- some of our own local unicode = require'luaotfload-unicode' @@ -736,7 +736,7 @@ lookup_font_file = function (filename) if not found then local type = file.suffix(filename) if type ~= "" then - found = resolvers.findfile(filename, type) + found = resolversfindfile(filename, type) end end @@ -746,7 +746,7 @@ lookup_font_file = function (filename) for i=1, #type1_metrics do local format = type1_metrics[i] - if resolvers.findfile(filename, format) then + if resolversfindfile(filename, format) then return file.addsuffix(filename, format), format, true end end @@ -785,7 +785,7 @@ local get_font_file = function (index) end local basename = entry.basename if entry.location == "texmf" then - local fullname = resolvers.findfile(basename, entry.format) + local fullname = resolversfindfile(basename, entry.format) if fullname then return true, fullname, entry.subfont end @@ -809,7 +809,7 @@ local verify_font_file = function (basename) if path and lfsisfile(path) then return true end - if resolvers.findfile(basename) then + if resolversfindfile(basename) then return true end return false @@ -2125,9 +2125,8 @@ do return end - if splitcomma == nil then - splitcomma = luaotfload.parsers and luaotfload.parsers.splitcomma - end + local splitcomma = luaotfload.parsers and luaotfload.parsers.splitcomma + if stringsub (formats, 1, 1) == "+" then -- add formats = lpegmatch (splitcomma, stringsub (formats, 2)) if formats then @@ -2281,7 +2280,14 @@ local truncate_string = function (str, restrict) local tw = config.luaotfload.misc.termwidth local wd = tw - restrict local len = utf8len (str) - if wd - len < 0 then + if not len then + -- str is not valid UTF-8... We will assume a 8-bit + -- encoding and forward it verbatim to the output. + len = #str + if wd - len < 0 then + str = ".." .. stringsub(str, len - wd + 2) + end + elseif wd - len < 0 then --- combined length exceeds terminal, str = ".." .. stringsub(str, utf8offset(str, - wd + 2)) end @@ -3098,6 +3104,39 @@ end --[[doc-- + Get the subfont index corresponding to a given psname in a + font collection + +--doc]]-- + +local function lookup_subfont_index(filepath, psname) + assert(name_index) + -- if not name_index then name_index = load_names () end + local filestatus = name_index.status[filepath] + local mappings = name_index.mappings + if filestatus then + for subfont, idx in next, filestatus.index do + if mappings[idx].psname == psname then + return subfont or 1 + end + end + end + + -- If that didn't work, we do a manual search + psname = sanitize_fontname(psname) + local err, info = read_font_file (filepath) + if #info == 0 then return 1 end + for i = 1, #info do + for _, names in next, info[i].platformnames do + if psname == sanitize_fontname(names.postscriptname) then + return i + end + end + end +end + +--[[doc-- + collect_font_filenames -- Scan the three search path categories for font files. This constitutes the first pass of the update mode. @@ -3707,8 +3746,6 @@ end --- PHG: we need to investigate these, maybe they’re useful as early --- hooks -local ignoredfile = function () return false end - local reportmissingbase = function () logreport ("info", 0, "db", --> bug‽ "Font name database not found but expected by fontloader.") @@ -3737,7 +3774,7 @@ local resolve = function (name, subfont) end local api = { - ignoredfile = ignoredfile, + ignoredfile = function() return false end, reportmissingbase = reportmissingbase, reportmissingname = reportmissingname, getfilename = getfilename, @@ -3770,6 +3807,7 @@ local export = { count_font_files = count_font_files, nth_font_filename = nth_font_filename, font_slice = font_slice, + lookup_subfont_index = lookup_subfont_index, --- font cache purge_cache = purge_cache, erase_cache = erase_cache, diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua index b38c1add0d2..1dc24ba6ee7 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua @@ -7,8 +7,8 @@ local ProvidesLuaModule = { name = "luaotfload-diagnostics", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload-tool submodule / diagnostics", license = "GPL v2.0" } diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-embolden.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-embolden.lua index bd2237f0869..8d512499764 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-embolden.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-embolden.lua @@ -5,8 +5,8 @@ local ProvidesLuaModule = { name = "luaotfload-embolden", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / color", license = "GPL v2.0", author = "Marcel Krüger" diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua index 3901d940dd8..bf56c4e3d14 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua @@ -5,8 +5,8 @@ local ProvidesLuaModule = { name = "luaotfload-features", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / features", license = "GPL v2.0", author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger", @@ -26,6 +26,7 @@ local lpeg = require "lpeg" local lpegmatch = lpeg.match local P = lpeg.P local R = lpeg.R +local S = lpeg.S local C = lpeg.C local table = table @@ -338,10 +339,9 @@ end local extract_subfont do local eof = P(-1) - local digit = R"09" --- Theoretically a valid subfont address can be up to ten - --- digits long. - local sub_expr = P"(" * C(digit^1) * P")" * eof + --- digits long. Additionally we allow names + local sub_expr = P"(" * C((1 - S"()")^1) * P")" * eof local full_path = C(P(1 - sub_expr)^1) extract_subfont = full_path * sub_expr end @@ -371,7 +371,7 @@ local handle_request = function (specification) local fullpath, sub = lpegmatch(extract_subfont, specification.specification) if fullpath and sub then - specification.sub = tonumber(sub) + specification.sub = tonumber(sub) or sub specification.name = fullpath else specification.name = specification.specification @@ -428,12 +428,7 @@ local handle_request = function (specification) --- investigated it any further (luatex-fonts-ext), so it will --- just stay here. features.normal = normalize (request.features) - local subfont = tonumber (request.sub) - if subfont and subfont >= 0 then - specification.sub = subfont + 1 - else - specification.sub = false - end + specification.sub = request.sub or specification.sub or false if request.features and request.features.mode and fonts.readers[request.features.mode] then @@ -572,8 +567,8 @@ local autofeatures = { local add_auto_features = function () local nfeats = #autofeatures - logreport ("both", 5, "features", - "auto-installing %d feature definitions", nfeats) + report ("both", 5, "features", + "auto-installing %d feature definitions", nfeats) for i = 1, nfeats do local name, spec, desc = unpack (autofeatures [i]) spec.description = desc @@ -582,12 +577,10 @@ local add_auto_features = function () end return function () - logreport = luaotfload.log.report - if not fonts and fonts.handlers then - logreport ("log", 0, "features", - "OTF mechanisms missing -- did you forget to \z - load a font loader?") + report ("log", 0, "features", + "OTF mechanisms missing -- did you forget to \z + load a font loader?") return false end add_auto_features () diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua index ade50b43166..24868eb3154 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua @@ -6,8 +6,8 @@ local ProvidesLuaModule = { name = "luaotfload-filelist", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / filelist", license = "GPL v2.0" } @@ -248,11 +248,14 @@ luaotfload.filelist.data = { name = "letterspace" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, { name = "embolden" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, { name = "notdef" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, + { name = "harf-define" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, + { name = "harf-plug" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, { name = "loaders" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, { name = "multiscript" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, { name = "parsers" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, { name = "resolvers" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, { name = "unicode" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, + { name = "tounicode" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, { name = "characters" ,kind = kind_generated, ext =".lua", gitdir=gitdirgen, texdir=texdirtex, gitpref = "luaotfload-", script="mkcharacter" }, { name = "glyphlist" ,kind = kind_generated, ext =".lua", gitdir=gitdirgen, texdir=texdirtex, gitpref = "luaotfload-", script="mkglyphlist" }, diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua index 1ba46ab0d76..fe655149ada 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua @@ -1,7 +1,7 @@ local ProvidesLuaModule = { name = "luaotfload-glyphlist", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --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/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-define.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-define.lua new file mode 100644 index 00000000000..e8154cb719d --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-define.lua @@ -0,0 +1,394 @@ +----------------------------------------------------------------------- +-- FILE: luaotfload-harf-define.lua +-- DESCRIPTION: part of luaotfload / HarfBuzz / font definition +----------------------------------------------------------------------- +do -- block to avoid to many local variables error + local ProvidesLuaModule = { + name = "luaotfload-harf-define", + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE + description = "luaotfload submodule / database", + license = "GPL v2.0", + author = "Khaled Hosny, Marcel Krüger", + copyright = "Luaotfload Development Team", + } + + if luatexbase and luatexbase.provides_module then + luatexbase.provides_module (ProvidesLuaModule) + end +end + +local stringlower = string.lower +local stringupper = string.upper +local gsub = string.gsub + +local hb = luaotfload.harfbuzz + +local hbfonts = {} + +local cfftag = hb.Tag.new("CFF ") +local cff2tag = hb.Tag.new("CFF2") +local os2tag = hb.Tag.new("OS/2") +local posttag = hb.Tag.new("post") +local glyftag = hb.Tag.new("glyf") + +local containers = luaotfload.fontloader.containers +local hbcacheversion = 1.0 +local facecache = containers.define("fonts", "hb", hbcacheversion, true) + +local function loadfont(spec) + local path, sub = spec.resolved, spec.sub or 1 + + local key = string.format("%s:%d", gsub(path, "[/\\]", ":"), sub) + + local attributes = lfs.attributes(path) + local size, date = attributes.size or 0, attributes.modification or 0 + + local cached = containers.read(facecache, key) + local iscached = cached and cached.date == date and cached.size == size + + local hbface = iscached and cached.face or hb.Face.new(path, sub - 1) + local tags = hbface and hbface:get_table_tags() + -- If the face has no table tags then it isn’t a valid SFNT font that + -- HarfBuzz can handle. + if not tags then return end + local hbfont = iscached and cached.font or hb.Font.new(hbface) + + if not iscached then + local upem = hbface:get_upem() + + -- The engine seems to use the font type to tell whether there is a CFF + -- table or not, so we check for that here. + local fonttype = nil + local hasos2 = false + local haspost = false + for i = 1, #tags do + local tag = tags[i] + if tag == cfftag or tag == cff2tag then + fonttype = "opentype" + elseif tag == glyftag then + fonttype = "truetype" + elseif tag == os2tag then + hasos2 = true + elseif tag == posttag then + haspost = true + end + end + + local fontextents = hbfont:get_h_extents() + local ascender = fontextents and fontextents.ascender or upem * .8 + local descender = fontextents and fontextents.descender or upem * .2 + + local gid = hbfont:get_nominal_glyph(0x0020) + local space = gid and hbfont:get_glyph_h_advance(gid) or upem / 2 + + local slant = 0 + if haspost then + local post = hbface:get_table(posttag) + local length = post:get_length() + local data = post:get_data() + if length >= 32 and string.unpack(">i4", data) <= 0x00030000 then + local italicangle = string.unpack(">i4", data, 5) / 2^16 + if italicangle ~= 0 then + slant = -math.tan(italicangle * math.pi / 180) * 65536.0 + end + end + end + + -- Load glyph metrics for all glyphs in the font. We used to do this on + -- demand to make loading fonts faster, but hit many limitations inside + -- the engine (mainly with shared backend fonts, where the engine would + -- assume all fonts it decides to share load the same set of glyphs). + -- + -- Getting glyph advances is fast enough, but glyph extents are slower + -- especially in CFF fonts. We might want to have an option to ignore exact + -- glyph extents and use font ascender and descender if this proved to be + -- too slow. + local glyphcount = hbface:get_glyph_count() + local glyphs = {} + for gid = 0, glyphcount - 1 do + local width = hbfont:get_glyph_h_advance(gid) + local height, depth, italic = nil, nil, nil + local extents = hbfont:get_glyph_extents(gid) + if extents then + height = extents.y_bearing + depth = extents.y_bearing + extents.height + if extents.x_bearing < 0 then + italic = -extents.x_bearing + end + end + glyphs[gid] = { + width = width, + height = height or ascender, + depth = -(depth or descender), + italic = italic or 0, + } + end + + local unicodes = hbface:collect_unicodes() + local characters = {} + local nominals = {} + for _, uni in next, unicodes do + local glyph = hbfont:get_nominal_glyph(uni) + if glyph then + characters[uni] = glyph + nominals[glyph] = uni + end + end + + local xheight, capheight = 0, 0 + if hasos2 then + local os2 = hbface:get_table(os2tag) + local length = os2:get_length() + local data = os2:get_data() + if length >= 96 and string.unpack(">H", data) > 1 then + -- We don’t need much of the table, so we read from hard-coded offsets. + xheight = string.unpack(">H", data, 87) + capheight = string.unpack(">H", data, 89) + end + end + + if xheight == 0 then + local gid = characters[120] -- x + if gid then + xheight = glyphs[gid].height + else + xheight = ascender / 2 + end + end + + if capheight == 0 then + local gid = characters[88] -- X + if gid then + capheight = glyphs[gid].height + else + capheight = ascender + end + end + + cached = { + date = date, + size = size, + gid_offset = 0x120000, + upem = upem, + fonttype = fonttype, + space = space, + xheight = xheight, + capheight = capheight, + slant = slant, + glyphs = glyphs, + nominals = nominals, + unicodes = characters, + psname = hbface:get_name(hb.ot.NAME_ID_POSTSCRIPT_NAME), + fullname = hbface:get_name(hb.ot.NAME_ID_FULL_NAME), + haspng = hbface:ot_color_has_png(), + loaded = {}, -- Cached loaded glyph data. + } + + containers.write(facecache, key, cached) + end + cached.face = hbface + cached.font = hbfont + return cached +end + +-- Drop illegal characters from PS Name, per the spec +-- https://docs.microsoft.com/en-us/typography/opentype/spec/name#nid6 +local function sanitize(psname) + return psname:gsub('[][\0-\32\127-\255(){}<>/%%]', '-') +end + +-- Ligatures. The value is a character "ligature" table as described in the +-- manual. +local tlig ={ + [0x2013] = { [0x002D] = { char = 0x2014 } }, -- [---] + [0x002D] = { [0x002D] = { char = 0x2013 } }, -- [--] + [0x0060] = { [0x0060] = { char = 0x201C } }, -- [``] + [0x0027] = { [0x0027] = { char = 0x201D } }, -- [''] + [0x0021] = { [0x0060] = { char = 0x00A1 } }, -- [!`] + [0x003F] = { [0x0060] = { char = 0x00BF } }, -- [?`] + [0x002C] = { [0x002C] = { char = 0x201E } }, -- [,,] + [0x003C] = { [0x003C] = { char = 0x00AB } }, -- [<<] + [0x003E] = { [0x003E] = { char = 0x00BB } }, -- [>>] +} + +local function scalefont(data, spec) + local size = spec.size + local features = spec.features.normal + features.mode = 'plug' + features.features = 'harf' + fonts.constructors.checkedfeatures("otf", features) + local hbface = data.face + local hbfont = data.font + local upem = data.upem + local space = data.space + local gid_offset = data.gid_offset + + if size < 0 then + size = -655.36 * size + end + + -- We shape in font units (at UPEM) and then scale output with the desired + -- sfont size. + local scale = size / upem + hbfont:set_scale(upem, upem) + + -- Populate font’s characters table. + local glyphs = data.glyphs + local characters = {} + for gid, glyph in next, glyphs do + characters[gid_offset + gid] = { + index = gid, + width = glyph.width * scale, + height = glyph.height * scale, + depth = glyph.depth * scale, + italic = glyph.italic * scale, + } + end + + local unicodes = data.unicodes + for uni, gid in next, unicodes do + characters[uni] = characters[gid_offset + gid] + end + + -- Select font palette, we support `palette=index` option, and load the first + -- one otherwise. + local paletteidx = tonumber(features.palette or features.colr) or 1 + + -- Load CPAL palette from the font. + local palette = nil + if hbface:ot_color_has_palettes() and hbface:ot_color_has_layers() then + local count = hbface:ot_color_palette_get_count() + if paletteidx <= count then + palette = hbface:ot_color_palette_get_colors(paletteidx) + end + end + + local letterspace = 0 + if features.letterspace then + letterspace = tonumber(features.letterspace) / 100 * upem + elseif features.kernfactor then + letterspace = tonumber(features.kernfactor) * upem + end + space = space + letterspace + + local slantfactor = nil + if features.slant then + slantfactor = tonumber(features.slant) * 1000 + end + + local mode = nil + local width = nil + if features.embolden then + mode = 2 + -- The multiplication by 7200.0/7227 is to undo the opposite conversion + -- the engine is doing and make the final number written in the PDF file + -- match XeTeX’s. + width = (size * tonumber(features.embolden) / 6553.6) * (7200.0/7227) + end + + local hscale = upem + local extendfactor = nil + if features.extend then + extendfactor = tonumber(features.extend) * 1000 + hscale = hscale * tonumber(features.extend) + end + + local vscale = upem + local squeezefactor = nil + if features.squeeze then + squeezefactor = tonumber(features.squeeze) * 1000 + vscale = vscale * tonumber(features.squeeze) + end + + if features.tlig then + for char in next, characters do + local ligatures = tlig[char] + if ligatures then + characters[char].ligatures = ligatures + end + end + end + + local tfmdata = { + name = spec.specification, + filename = spec.resolved, + subfont = spec.sub or 1, + designsize = size, + psname = sanitize(data.psname), + fullname = data.fullname, + index = spec.index, + size = size, + units_per_em = upem, + embedding = "subset", + tounicode = 1, + nomath = true, + format = data.fonttype, + slant = slantfactor, + mode = mode, + width = width, + extend = extendfactor, + squeeze = squeezefactor, + characters = characters, + parameters = { + slant = data.slant, + space = space * scale, + space_stretch = space * scale / 2, + space_shrink = space * scale / 3, + x_height = data.xheight * scale, + quad = size, + extra_space = space * scale / 3, + [8] = data.capheight * scale, -- for XeTeX compatibility. + }, + hb = { + scale = scale, + spec = spec, + palette = palette, + shared = data, + letterspace = letterspace, + hscale = hscale, + vscale = vscale, + }, + specification = spec, + shared = {}, + properties = {}, + } + tfmdata.shared.processes = fonts.handlers.otf.setfeatures(tfmdata, features) + return tfmdata +end + +-- Register a reader for `harf` mode (`mode=harf` font option) so that we only +-- load fonts when explicitly requested. Fonts we load will be shaped by the +-- harf plugin in luaotfload-harf-plug. +fonts.readers.harf = function(spec) + if not spec.resolved then return end + local rawfeatures = spec.features.raw + local hb_features = {} + spec.hb_features = hb_features + + if rawfeatures.language then + local language = stringupper(rawfeatures.language) + spec.language = hb.Language.new(language == "DFLT" and "dflt" + or language) + end + if rawfeatures.script then + local script = stringlower(rawfeatures.script) + spec.script = hb.Script.new(script == "dflt" and "DFLT" + or script) + end + for key, val in next, rawfeatures do + if key:len() == 4 then + -- 4-letter options are likely font features, but not always, so we do + -- some checks below. Other options will be queried + -- from spec.features.normal. + if val == true or val == false then + val = (val and '+' or '-')..key + hb_features[#hb_features + 1] = hb.Feature.new(val) + elseif tonumber(val) then + val = '+'..key..'='..tonumber(val) - 1 + hb_features[#hb_features + 1] = hb.Feature.new(val) + end + end + end + return scalefont(loadfont(spec), spec) +end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-plug.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-plug.lua new file mode 100644 index 00000000000..123a1c4563e --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-plug.lua @@ -0,0 +1,983 @@ +----------------------------------------------------------------------- +-- FILE: luaotfload-harf-plug.lua +-- DESCRIPTION: part of luaotfload / HarfBuzz / fontloader plugin +----------------------------------------------------------------------- +do -- block to avoid to many local variables error + local ProvidesLuaModule = { + name = "luaotfload-harf-plug", + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE + description = "luaotfload submodule / database", + license = "GPL v2.0", + author = "Khaled Hosny, Marcel Krüger", + copyright = "Luaotfload Development Team", + } + + if luatexbase and luatexbase.provides_module then + luatexbase.provides_module (ProvidesLuaModule) + end +end + +local hb = luaotfload.harfbuzz + +local assert = assert +local next = next +local tonumber = tonumber +local type = type +local format = string.format +local open = io.open +local tableinsert = table.insert +local tableremove = table.remove +local ostmpname = os.tmpname +local osremove = os.remove + +local direct = node.direct +local tonode = direct.tonode +local todirect = direct.todirect +local traverse = direct.traverse +local insertbefore = direct.insert_before +local insertafter = direct.insert_after +local protectglyph = direct.protect_glyph +local newnode = direct.new +local freenode = direct.free +local copynode = direct.copy +local removenode = direct.remove +local copynodelist = direct.copy_list +local ischar = direct.is_char +local uses_font = direct.uses_font + +local getattrs = direct.getattributelist +local setattrs = direct.setattributelist +local getchar = direct.getchar +local setchar = direct.setchar +local getdir = direct.getdir +local setdir = direct.setdir +local getdisc = direct.getdisc +local setdisc = direct.setdisc +local getfont = direct.getfont +local getdata = direct.getdata +local setdata = direct.setdata +local getfont = direct.getfont +local setfont = direct.setfont +local getfield = direct.getfield +local setfield = direct.setfield +local getid = direct.getid +local getkern = direct.getkern +local setkern = direct.setkern +local getnext = direct.getnext +local setnext = direct.setnext +local getoffsets = direct.getoffsets +local setoffsets = direct.setoffsets +local getproperty = direct.getproperty +local setproperty = direct.setproperty +local getprev = direct.getprev +local setprev = direct.setprev +local getsubtype = direct.getsubtype +local setsubtype = direct.setsubtype +local getwidth = direct.getwidth +local setwidth = direct.setwidth +local is_char = direct.is_char +local tail = direct.tail + +local properties = direct.get_properties_table() + +local imgnode = img.node + +local disc_t = node.id("disc") +local glue_t = node.id("glue") +local glyph_t = node.id("glyph") +local dir_t = node.id("dir") +local kern_t = node.id("kern") +local localpar_t = node.id("local_par") +local whatsit_t = node.id("whatsit") +local pdfliteral_t = node.subtype("pdf_literal") + +local explicitdisc_t = 1 +local fontkern_t = 0 +local italiccorr_t = 3 +local regulardisc_t = 3 +local spaceskip_t = 13 + +local invalid_l = hb.Language.new() +local invalid_s = hb.Script.new() + +local dir_ltr = hb.Direction.new("ltr") +local dir_rtl = hb.Direction.new("rtl") +local fl_unsafe = hb.Buffer.GLYPH_FLAG_UNSAFE_TO_BREAK + +local startactual_p = "luaotfload_startactualtext" +local endactual_p = "luaotfload_endactualtext" + +-- "Copy" properties as done by LuaTeX: Make old properties metatable +local function copytable(old) + local new = {} + for k, v in next, old do + if type(v) == "table" then v = copytable(v) end + new[k] = v + end + setmetatable(new, getmetatable(old)) + return new +end + +-- Set and get properties. +local function setprop(n, prop, value) + local props = properties[n] + if not props then + props = {} + properties[n] = props + end + props[prop] = value +end + +local function inherit(t, base, properties) + local n = newnode(t) + setattrs(n, getattrs(base)) + if properties then + setproperty(n, setmetatable({}, {__index = properties})) + end + return n +end +-- New kern node of amount `v`, inheriting the properties/attributes of `n`. +local function newkern(v, n) + local kern = inherit(kern_t, n, getproperty(n)) + setkern(kern, v) + return kern +end + +local function insertkern(head, current, kern, rtl) + if rtl then + head = insertbefore(head, current, kern) + else + head, current = insertafter(head, current, kern) + end + return head, current +end + +-- Convert list of integers to UTF-16 hex string used in PDF. +local function to_utf16_hex(uni) + if uni < 0x10000 then + return format("%04X", uni) + else + uni = uni - 0x10000 + local hi = 0xD800 + (uni // 0x400) + local lo = 0xDC00 + (uni % 0x400) + return format("%04X%04X", hi, lo) + end +end + +local process + +-- Legacy TeX Input Method Disguised as Font Ligatures hack. +-- +-- Single replacements, keyed by character to replace. Handled separately +-- because TeX ligaturing mechanism does not support one-to-one replacements. +local trep = { + [0x0022] = 0x201D, -- ["] + [0x0027] = 0x2019, -- ['] + [0x0060] = 0x2018, -- [`] +} + +local function itemize(head, fontid, direction) + local fontdata = font.getfont(fontid) + local hbdata = fontdata and fontdata.hb + local spec = fontdata and fontdata.specification + local options = spec and spec.features.raw + local texlig = options and options.tlig + + local runs, codes = {}, {} + local dirstack = {} + local currdir = direction or "TLT" + local lastskip, lastdir = true + local lastrun = {} + + for n, id, subtype in direct.traverse(head) do + local code = 0xFFFC -- OBJECT REPLACEMENT CHARACTER + local skip = false + + if id == glyph_t then + if is_char(n) and getfont(n) == fontid then + code = getchar(n) + else + skip = true + end + elseif id == glue_t and subtype == spaceskip_t then + code = 0x0020 -- SPACE + skip = lastskip + elseif id == disc_t then + if uses_font(n, fontid) then + code = 0x00AD -- SOFT HYPHEN + else + skip = true + end + elseif id == dir_t then + local dir = getdir(n) + if dir:sub(1, 1) == "+" then + -- Push the current direction to the stack. + tableinsert(dirstack, currdir) + currdir = dir:sub(2) + else + assert(currdir == dir:sub(2)) + -- Pop the last direction from the stack. + currdir = tableremove(dirstack) + end + skip = lastskip + elseif id == localpar_t then + currdir = getdir(n) + skip = lastskip + end + + if not skip and texlig then + local replacement = trep[code] + if replacement then + code = replacement + end + end + + codes[#codes + 1] = code + + if lastdir ~= currdir or lastskip ~= skip then + lastrun.after = n + lastrun = { + start = #codes, + len = 1, + font = fontid, + dir = currdir == "TRT" and dir_rtl or dir_ltr, + skip = skip, + codes = codes, + } + runs[#runs + 1] = lastrun + lastdir, lastskip = currdir, skip + else + lastrun.len = lastrun.len + 1 + end + end + + return runs +end + + +-- Check if it is not safe to break before this glyph. +local function unsafetobreak(glyph) + return glyph + and glyph.flags + and glyph.flags & fl_unsafe +end + +local shape + +-- Make s a sub run, used by discretionary nodes. +local function makesub(run, codes, nodelist) + local subrun = { + start = 1, + len = #codes, + font = run.font, + dir = run.dir, + fordisc = true, + node = nodelist, + codes = codes, + } + local glyphs + if nodelist == 0 then -- FIXME: This shouldn't happen + nodelist = nil + end + nodelist, glyphs = shape(nodelist, nodelist, subrun) + return { glyphs = glyphs, run = subrun, head = nodelist } +end + +local function printnodes(label, head, after) + after = tonode(after) + for n in node.traverse(tonode(head)) do + if n == after then return end + print(label, n, n.font or '', n.char or '') + local pre, post, rep = getdisc(todirect(n)) + if pre then + printnodes(label .. '<', pre) + end + if post then + printnodes(label .. '>', post) + end + if rep then + printnodes(label .. '=', rep) + end + end +end +-- Main shaping function that calls HarfBuzz, and does some post-processing of +-- the output. +function shape(head, node, run) + local codes = run.codes + local offset = run.start + local nodeindex = offset + run.start = offset + local len = run.len + local fontid = run.font + local dir = run.dir + local fordisc = run.fordisc + local cluster = offset - 2 + + local fontdata = font.getfont(fontid) + local hbdata = fontdata.hb + local spec = hbdata.spec + local features = spec.hb_features + local options = spec.features.raw + local hbshared = hbdata.shared + local hbfont = hbshared.font + + local lang = spec.language or invalid_l + local script = spec.script or invalid_s + local shapers = options.shaper and { options.shaper } or {} + + local buf = hb.Buffer.new() + buf:set_direction(dir) + buf:set_script(script) + buf:set_language(lang) + buf:set_cluster_level(buf.CLUSTER_LEVEL_MONOTONE_CHARACTERS) + buf:add_codepoints(codes, offset - 1, len) + + local hscale = hbdata.hscale + local vscale = hbdata.vscale + hbfont:set_scale(hscale, vscale) + + if hb.shape_full(hbfont, buf, features, shapers) then + -- The engine wants the glyphs in logical order, but HarfBuzz outputs them + -- in visual order, so we reverse RTL buffers. + if dir:is_backward() then buf:reverse() end + + local glyphs = buf:get_glyphs() + + local i = 0 + while i < #glyphs do + i = i + 1 + local glyph = glyphs[i] + + -- Calculate the Unicode code points of this glyph. If cluster did not + -- change then this is a glyph inside a complex cluster and will be + -- handled with the start of its cluster. + if cluster ~= glyph.cluster then + cluster = glyph.cluster + for i = nodeindex, cluster do node = getnext(node) end + nodeindex = cluster + 1 + local hex = "" + local str = "" + local nextcluster + for j = i+1, #glyphs do + nextcluster = glyphs[j].cluster + if cluster ~= nextcluster then + glyph.nglyphs = j - i + goto NEXTCLUSTERFOUND -- break + end + end -- else -- only executed if the loop reached the end without + -- finding another cluster + nextcluster = offset + len - 1 + glyph.nglyphs = #glyphs + 1 - i + ::NEXTCLUSTERFOUND:: -- end + glyph.nextcluster = nextcluster + do + local node = node + for j = cluster,nextcluster-1 do + local id = getid(node) + if id == glyph_t or id == glue_t then + local code = codes[j + 1] + hex = hex..to_utf16_hex(code) + str = str..utf8.char(code) + end + end + glyph.tounicode = hex + glyph.string = str + end + if not fordisc then + local discindex = nil + local disc = node + for j = cluster + 1, nextcluster do + if codes[j] == 0x00AD then + discindex = j + break + end + disc = getnext(disc) + end + if discindex then + -- Discretionary found. + local startindex, stopindex = nil, nil + local startglyph, stopglyph = nil, nil + + -- Find the previous glyph that is safe to break at. + local startglyph = i + while startglyph > 1 + and codes[glyphs[startglyph - 1].cluster + 1] ~= 0x20 + and codes[glyphs[startglyph - 1].cluster + 1] ~= 0xFFFC + and unsafetobreak(glyphs[startglyph]) do + startglyph = startglyph - 1 + end + -- Get the corresponding character index. + startindex = glyphs[startglyph].cluster + 1 + + -- Find the next glyph that is safe to break at. + stopglyph = i + 1 + local lastcluster = glyphs[i].cluster + while stopglyph <= #glyphs + and codes[glyphs[stopglyph].cluster + 1] ~= 0x20 + and codes[glyphs[stopglyph].cluster + 1] ~= 0xFFFC + and (unsafetobreak(glyphs[stopglyph]) + or lastcluster == glyphs[stopglyph].cluster) do + lastcluster = glyphs[stopglyph].cluster + stopglyph = stopglyph + 1 + end + + stopindex = stopglyph <= #glyphs and glyphs[stopglyph].cluster + 1 + or offset + len + + local startnode, stopnode = node, node + for j=nodeindex - 1, startindex, -1 do + startnode = getprev(startnode) + end + for j=nodeindex + 1, stopindex do + stopnode = getnext(stopnode) + end + + glyphs[startglyph] = glyph + glyph.cluster = startindex - 1 + glyph.nextcluster = startindex + for j = stopglyph, #glyphs do + local glyph = glyphs[j] + glyph.cluster = glyph.cluster - (stopindex - startindex) + 1 + end + len = len - (stopindex - startindex) + 1 + table.move(glyphs, stopglyph, #glyphs + stopglyph - startglyph - 1, startglyph + 1) + + local subcodes, subindex = {} + do + local node = startnode + while node ~= stopnode do + if node == disc then + subindex = #subcodes + startindex = startindex + 1 + node = getnext(node) + elseif getid(node) == disc_t then + local oldnode = node + startnode, node = removenode(startnode, node) + freenode(oldnode) + tableremove(codes, startindex) + else + subcodes[#subcodes + 1] = tableremove(codes, startindex) + node = getnext(node) + end + end + end + + local pre, post, rep, lastpre, lastpost, lastrep = getdisc(disc, true) + local precodes, postcodes, repcodes = {}, {}, {} + table.move(subcodes, 1, subindex, 1, repcodes) + for n, id, subtype in traverse(rep) do + repcodes[#repcodes + 1] = getfont(n) == fontid and getchar(n) or 0xFFFC + end + table.move(subcodes, subindex + 1, #subcodes, #repcodes + 1, repcodes) + table.move(subcodes, 1, subindex, 1, precodes) + for n, id, subtype in traverse(pre) do + precodes[#precodes + 1] = getfont(n) == fontid and getchar(n) or 0xFFFC + end + for n, id, subtype in traverse(post) do + postcodes[#postcodes + 1] = getfont(n) == fontid and getchar(n) or 0xFFFC + end + table.move(subcodes, subindex + 1, #subcodes, #postcodes + 1, postcodes) + if startnode ~= disc then + local newpre = copynodelist(startnode, disc) + setnext(tail(newpre), pre) + pre = newpre + end + if post then + setnext(lastpost, copynodelist(getnext(disc), stopnode)) + else + post = copynodelist(getnext(disc), stopnode) + end + if startnode ~= disc then + local predisc = getprev(disc) + setnext(predisc, rep) + setprev(rep, predisc) + if startnode == head then + head = disc + else + local before = getprev(startnode) + setnext(before, disc) + setprev(disc, before) + end + setprev(startnode, nil) + rep = startnode + lastrep = lastrep or predisc + end + if getnext(disc) ~= stopnode then + setnext(getprev(stopnode), nil) + setprev(stopnode, disc) + setprev(getnext(disc), lastrep) + setnext(lastrep, getnext(disc)) + rep = rep or getnext(disc) + setnext(disc, stopnode) + end + glyph.replace = makesub(run, repcodes, rep) + glyph.pre = makesub(run, precodes, pre) + glyph.post = makesub(run, postcodes, post) + i = startglyph + node = disc + cluster = glyph.cluster + nodeindex = cluster + 1 + end + end + end + end + return head, glyphs, run.len - len + end + + return head, {}, 0 +end + +local function color_to_rgba(color) + local r = color.red / 255 + local g = color.green / 255 + local b = color.blue / 255 + local a = color.alpha / 255 + if a ~= 1 then + -- XXX: alpha + return format('%s %s %s rg', r, g, b) + else + return format('%s %s %s rg', r, g, b) + end +end + +-- Cache of color glyph PNG data for bookkeeping, only because I couldn’t +-- figure how to make the engine load the image from the binary data directly. +local pngcache = {} +local pngcachefiles = {} +local function cachedpng(data) + local hash = md5.sumhexa(data) + local i = pngcache[hash] + if not i then + local path = ostmpname() + pngcachefiles[#pngcachefiles + 1] = path + open(path, "wb"):write(data):close() + -- local file = open(path, "wb"):write():close() + -- file:write(data) + -- file:close() + i = img.scan{filename = path} + pngcache[hash] = i + end + return i +end + +local function get_png_glyph(gid, fontid, characters, haspng) + return gid +end + +local push_cmd = { "push" } +local pop_cmd = { "pop" } +local nop_cmd = { "nop" } +local save_cmd = { "pdf", "page", "q" } +local restore_cmd = { "pdf", "page", "Q" } + +-- Convert glyphs to nodes and collect font characters. +local function tonodes(head, node, run, glyphs) + local nodeindex = run.start + local dir = run.dir + local fontid = run.font + local fontdata = font.getfont(fontid) + local characters = fontdata.characters + local hbdata = fontdata.hb + local palette = hbdata.palette + local hbshared = hbdata.shared + local hbface = hbshared.face + local nominals = hbshared.nominals + local hbfont = hbshared.font + local fontglyphs = hbshared.glyphs + local gid_offset = hbshared.gid_offset + local rtl = dir:is_backward() + local lastprops + + local scale = hbdata.scale + local letterspace = hbdata.letterspace + + local haspng = hbshared.haspng + local fonttype = hbshared.fonttype + + local nextcluster + + for i, glyph in ipairs(glyphs) do + if glyph.cluster + 1 >= nodeindex then -- Reached a new cluster + nextcluster = glyph.nextcluster + assert(nextcluster) + for j = nodeindex, glyph.cluster do + local oldnode = node + head, node = removenode(head, node) + freenode(oldnode) + end + lastprops = getproperty(node) + nodeindex = glyph.cluster + 1 + elseif nextcluster + 1 == nodeindex then -- Oops, we went too far + nodeindex = nodeindex - 1 + local new = inherit(glyph_t, getprev(node), lastprops) + setfont(new, fontid) + head, node = insertbefore(head, node, new) + end + local gid = glyph.codepoint + local char = nominals[gid] or gid_offset + gid + local id = getid(node) + + if glyph.replace then + -- For discretionary the glyph itself is skipped and a discretionary node + -- is output in place of it. + local rep, pre, post = glyph.replace, glyph.pre, glyph.post + + setdisc(node, tonodes(pre.head, pre.head, pre.run, pre.glyphs), + tonodes(post.head, post.head, post.run, post.glyphs), + tonodes(rep.head, rep.head, rep.run, rep.glyphs)) + node = getnext(node) + nodeindex = nodeindex + 1 + elseif glyph.skip then + local oldnode = node + head, node = removenode(head, node) + freenode(oldnode) + nodeindex = nodeindex + 1 + else + if id == glyph_t then + local done + local fontglyph = fontglyphs[gid] + local character = characters[char] + + if not character.commands then + if palette then + local layers = fontglyph.layers + if layers == nil then + layers = hbface:ot_color_glyph_get_layers(gid) or false + fontglyph.layers = layers + end + if layers then + local cmds = {} -- Every layer will add 5 cmds + local prev_color = nil + for j = 1, #layers do + local layer = layers[j] + local layerchar = characters[gid_offset + layer.glyph] + if layerchar.height > character.height then + character.height = layerchar.height + end + if layerchar.depth > character.depth then + character.depth = layerchar.depth + end + -- color_index has a special value, 0x10000, that mean use text + -- color, we don’t check for it here explicitly since we will + -- get nil anyway. + local color = palette[layer.color_index] + cmds[5*j - 4] = (color and not prev_color) and save_cmd or nop_cmd + cmds[5*j - 3] = prev_color == color and nop_cmd or (color and {"pdf", "page", color_to_rgba(color)} or restore_cmd) + cmds[5*j - 2] = push_cmd + cmds[5*j - 1] = {"char", layer.glyph + gid_offset} + cmds[5*j] = pop_cmd + fontglyphs[layer.glyph].used = true + prev_color = color + end + cmds[#cmds + 1] = prev_color and restore_cmd + if not character.colored then + local coloredcharacter = {} + for k,v in next, character do + coloredcharacter[k] = v + end + coloredcharacter.commands = cmds + local newcharacters = {[gid + 0x130000] = coloredcharacter} + characters[gid + 0x130000] = coloredcharacter + if char ~= gid + gid_offset then + newcharacters[char] = coloredcharacter + characters[char] = coloredcharacter + character.colored = char + else + character.colored = gid + 0x130000 + end + font.addcharacters(fontid, {characters = newcharacters}) + end + char = character.colored + character = characters[char] + end + end + + if haspng then + local pngglyph = character.pngglyph + if pngglyph == nil then + local pngblob = hbfont:ot_color_glyph_get_png(gid) + if pngblob then + local glyphimg = cachedpng(pngblob:get_data()) + local pngchar = { } + for k,v in next, character do + pngchar[k] = v + end + local i = img.copy(glyphimg) + i.width = character.width + i.depth = 0 + i.height = character.height + character.depth + pngchar.commands = fonttype and { + {"push"}, {"char", gid_offset + gid}, {"pop"}, + {"down", character.depth}, {"image", i} + } or { {"down", character.depth}, {"image", i} } + if not nominals[gid] then + char = 0x130000 + gid + end + characters[char] = pngchar + pngglyph = char + font.addcharacters(fontid, {characters = {[char] = pngchar}}) + end + character.pngglyph = pngglyph + end + if pngglyph then + char = pngglyph + elseif not fonttype then + -- Color bitmap font with no glyph outlines (like Noto + -- Color Emoji) but has no bitmap for current glyph (most likely + -- `.notdef` glyph). The engine does not know how to embed such + -- fonts, so we don’t want them to reach the backend as it will cause + -- a fatal error. We use `nullfont` instead. That is a hack, but I + -- think it is good enough for now. We could make the glyph virtual + -- with empty commands suh that LuaTeX ignores it, but we still want + -- a missing glyph warning. + -- We insert the glyph node and move on, no further work is needed. + setfont(node, 0) + done = true + end + end + end + if not done then + local oldcharacter = characters[getchar(node)] + -- If the glyph index of current font character is the same as shaped + -- glyph, keep the node char unchanged. Helps with primitives that + -- take characters as input but actually work on glyphs, like + -- `\rpcode`. + if character.commands or not oldcharacter + or character.index ~= oldcharacter.index then + setchar(node, char) + end + local xoffset = (rtl and -glyph.x_offset or glyph.x_offset) * scale + local yoffset = glyph.y_offset * scale + setoffsets(node, xoffset, yoffset) + + fontglyph.used = fonttype and true + + -- The engine will use this string when printing a glyph node e.g. in + -- overfull messages, otherwise it will be trying to print our + -- invalid pseudo Unicode code points. + -- If the string is empty it means this glyph is part of a larger + -- cluster and we don’t to print anything for it as the first glyph + -- in the cluster will have the string of the whole cluster. + local props = properties[node] + if not props then + props = {} + properties[node] = props + end + props.glyph_info = glyph.string or "" + + -- Handle PDF text extraction: + -- * Find how many characters in this cluster and how many glyphs, + -- * If there is more than 0 characters + -- * One glyph: one to one or one to many mapping, can be + -- represented by font’s /ToUnicode + -- * More than one: many to one or many to many mapping, can be + -- represented by /ActualText spans. + -- * If there are zero characters, then this glyph is part of complex + -- cluster that will be covered by an /ActualText span. + local tounicode = glyph.tounicode + if tounicode then + if glyph.nglyphs == 1 + and not character.commands + and not fontglyph.tounicode then + fontglyph.tounicode = tounicode + elseif character.commands or tounicode ~= fontglyph.tounicode then + setprop(node, startactual_p, tounicode) + glyphs[i + glyph.nglyphs - 1].endactual = true + end + end + if glyph.endactual then + setprop(node, endactual_p, true) + end + local x_advance = glyph.x_advance + letterspace + local width = fontglyph.width + if width ~= x_advance then + -- The engine always uses the glyph width from the font, so we need + -- to insert a kern node if the x advance is different. + local kern = newkern((x_advance - width) * scale, node) + head, node = insertkern(head, node, kern, rtl) + end + end + elseif id == glue_t and getsubtype(node) == spaceskip_t then + -- If the glyph advance is different from the font space, then a + -- substitution or positioning was applied to the space glyph changing + -- it from the default, so reset the glue using the new advance. + -- We are intentionally not comparing with the existing glue width as + -- spacing after the period is larger by default in TeX. + local width = (glyph.x_advance + letterspace) * scale + if fontdata.parameters.space ~= width then + setwidth(node, width) + setfield(node, "stretch", width / 2) + setfield(node, "shrink", width / 3) + end + elseif id == kern_t and getsubtype(node) == italiccorr_t then + -- If this is an italic correction node and the previous node is a + -- glyph, update its kern value with the glyph’s italic correction. + local prevchar, prevfontid = ischar(getprev(node)) + if prevfontid == fontid and prevchar and prevchar > 0 then + local italic = characters[prevchar].italic + if italic then + setkern(node, italic) + end + end + end + node = getnext(node) + nodeindex = nodeindex + 1 + end + end + while node ~= run.after do + local oldnode = node + head, node = removenode(head, node) + freenode(oldnode) + end + + return head, node +end + +local function shape_run(head, current, run) + if not run.skip then + -- Font loaded with our loader and an HarfBuzz face is present, do our + -- shaping. + local fontid = run.font + local fontdata = font.getfont(fontid) + local options = fontdata.specification.features.raw + + local glyphs, offset + head, glyphs, offset = shape(head, current, run) + return offset, tonodes(head, current, run, glyphs) + else + return 0, head, run.after + end +end + +function process(head, font, direction) + local newhead, current = head, head + local runs = itemize(head, font, direction) + + local offset = 0 + for i = 1,#runs do + local run = runs[i] + run.start = run.start - offset + local new_offset + new_offset, newhead, current = shape_run(newhead, current, run) + offset = offset + new_offset + end + + return newhead or head +end + +local function pageliteral(data) + local n = newnode(whatsit_t, pdfliteral_t) + setfield(n, "mode", 1) -- page + setdata(n, data) + return n +end + +local function post_process(head) + for n in traverse(head) do + local props = properties[n] + + local startactual, endactual + if props then + startactual = rawget(props, startactual_p) + endactual = rawget(props, endactual_p) + end + + if startactual then + local actualtext = "/Span<</ActualText<FEFF"..startactual..">>>BDC" + head = insertbefore(head, n, pageliteral(actualtext)) + end + + if endactual then + head = insertafter(head, n, pageliteral("EMC")) + end + + local replace = getfield(n, "replace") + if replace then + setfield(n, "replace", post_process(replace)) + end + + local subhead = getfield(n, "head") + if subhead then + setfield(n, "head", post_process(subhead)) + end + end + return head +end + +local function post_process_nodes(head, groupcode) + return tonode(post_process(todirect(head))) +end + +local function run_cleanup() + -- Remove temporary PNG files that we created, if any. + -- FIXME: It would be nice if we wouldn't need this + for _, path in next, pngcachefiles do + osremove(path) + end +end + +local function set_tounicode() + for fontid, fontdata in font.each() do + local hbdata = fontdata.hb + if hbdata and fontid == pdf.getfontname(fontid) then + local characters = fontdata.characters + local newcharacters = {} + local hbshared = hbdata.shared + local glyphs = hbshared.glyphs + local nominals = hbshared.nominals + local gid_offset = hbshared.gid_offset + for gid = 0, #glyphs do + local glyph = glyphs[gid] + if glyph.used then + local character = characters[gid + gid_offset] + newcharacters[gid + gid_offset] = character + local unicode = nominals[gid] + if unicode then + newcharacters[unicode] = character + end + character.tounicode = glyph.tounicode or "FFFD" + character.used = true + end + end + font.addcharacters(fontid, { characters = newcharacters }) + end + end +end + +-- FIXME: Move this into generic parts of luaotfload +local utfchar = utf8.char +local function get_glyph_info(n) + n = todirect(n) + local props = properties[n] + return props and props.glyph_info or utfchar(getchar(n)):gsub('\0', '^^@') +end + +fonts.handlers.otf.registerplugin('harf', process) + +-- luatexbase does not know how to handle `wrapup_run` callback, teach it. +-- TODO: Move these into ltluatex +luatexbase.callbacktypes.wrapup_run = 1 -- simple +luatexbase.callbacktypes.glyph_info = 1 -- simple + +local base_callback_descriptions = luatexbase.callback_descriptions +local base_add_to_callback = luatexbase.add_to_callback +local base_remove_from_callback = luatexbase.remove_from_callback + +-- Remove all existing functions from given callback, insert ours, then +-- reinsert the removed ones, so ours takes a priority. +local function add_to_callback(name, func) + local saved_callbacks = {}, ff, dd + for k, v in next, base_callback_descriptions(name) do + saved_callbacks[k] = { base_remove_from_callback(name, v) } + end + base_add_to_callback(name, func, "Harf "..name.." callback") + for _, v in next, saved_callbacks do + base_add_to_callback(name, v[1], v[2]) + end +end + +add_to_callback('pre_output_filter', post_process_nodes) -- FIXME: Wrong callback, but I want to get rid of the whole function anyway +add_to_callback('wrapup_run', run_cleanup) +add_to_callback('finish_pdffile', set_tounicode) +add_to_callback('glyph_info', get_glyph_info) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua index 6a80546d436..5f7b710d9b1 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua @@ -7,8 +7,8 @@ local ProvidesLuaModule = { name = "luaotfload-init", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / initialization", license = "GPL v2.0" } @@ -78,122 +78,6 @@ local logreport --- filled in after loading the log module --doc]]-- -local init_early = function () - - local store = { } - config = config or { } --- global - config.luaotfload = config.luaotfload or { } - config.lualibs = config.lualibs or { } - config.lualibs.verbose = false - config.lualibs.prefer_merged = true - config.lualibs.load_extended = true - fonts = fonts or { } - - require "lualibs" - - if not lualibs then error "this module requires Luaotfload" end - if not luaotfload then error "this module requires Luaotfload" end - - --[[doc-- - - The logger needs to be in place prior to loading the fontloader due - to order of initialization being crucial for the logger functions - that are swapped. - - --doc]]-- - - luaotfload.loaders.luaotfload "log" - log = luaotfload.log - logreport = log.report - log.set_loglevel (default_log_level) - - logreport ("log", 4, "init", "Concealing callback.register().") - store.trapped_register = callback.register - - callback.register = function (id) - logreport ("log", 4, "init", - "Dummy callback.register() invoked on %s.", - id) - end - - --[[doc-- - - By default, the fontloader requires a number of \emphasis{private - attributes} for internal use. - These must be kept consistent with the attribute handling methods - as provided by \identifier{luatexbase}. - Our strategy is to override the function that allocates new - attributes before we initialize the font loader, making it a - wrapper around \luafunction{luatexbase.new_attribute}.\footnote{% - Many thanks, again, to Hans Hagen for making this part - configurable! - } - The attribute identifiers are prefixed “\fileent{luaotfload@}” to - avoid name clashes. - - --doc]]-- - - local new_attribute = luatexbase.new_attribute - local the_attributes = luatexbase.attributes - - attributes = attributes or { } --- this writes a global, sorry - - attributes.private = function (name) - local attr = "luaotfload@" .. name --- used to be: “otfl@” - local number = the_attributes[attr] - if not number then number = new_attribute(attr) end - return number - end - - luaotfload.loaders.fontloader "basics-gen" - - return store -end --- [init_early] - ---[[doc-- - - These next lines replicate the behavior of - \fileent{luatex-fonts.lua}. - ---doc]]-- - -local push_namespaces = function () - logreport ("log", 4, "init", "push namespace for font loader") - local normalglobal = { } - for k, v in next, _G do - normalglobal[k] = v - end - return normalglobal -end - -local pop_namespaces = function (normalglobal, - isolate, - context_environment) - if normalglobal then - local _G = _G - local mode = "non-destructive" - if isolate then mode = "destructive" end - logreport ("log", 4, "init", "pop namespace from font loader -- " .. mode) - for k, v in next, _G do - if not normalglobal[k] then - context_environment[k] = v - if isolate then - _G[k] = nil - end - end - end - for k, v in next, normalglobal do - _G[k] = v - end - -- just to be sure: - setmetatable(context_environment, _G) - else - logreport ("both", 0, "init", - "irrecoverable error during pop_namespace: no globals to restore") - os.exit () - end -end - --- below paths are relative to the texmf-context local ltx = "tex/generic/context/luatex" local ctx = { "tex/context/base/mkiv", "tex/context/base" } @@ -308,159 +192,71 @@ local load_context_modules = function (pth) end -local init_adapt = function () +local function init_main(early_hook) + config = config or { } --- global + config.luaotfload = config.luaotfload or { } + config.lualibs = config.lualibs or { } + config.lualibs.verbose = false + config.lualibs.prefer_merged = true + config.lualibs.load_extended = true + fonts = fonts or { } + + require "lualibs" - local context_environment = { } - local our_environment = push_namespaces () + if not lualibs then error "this module requires Luaotfload" end + if not luaotfload then error "this module requires Luaotfload" end --[[doc-- - The font loader requires that the attribute with index zero be - zero. We happily oblige. - (Cf. \fileent{luatex-fonts-nod.lua}.) + The logger needs to be in place prior to loading the fontloader due + to order of initialization being crucial for the logger functions + that are swapped. --doc]]-- - tex.attribute[0] = 0 - - return our_environment, context_environment - -end --- [init_adapt] - ---[[doc-- + luaotfload.loaders.luaotfload "log" + log = luaotfload.log + logreport = log.report + log.set_loglevel (default_log_level) - In Context, characters.data is where the data from char-def.lua - resides. The file is huge (>4.4 MB as of 2016) and only a stripped - down version is part of the isolated font loader. Nevertheless, we - include an excerpt generated by the mkcharacters script that contains - a subset of the fields of each character defined and some extra - metadata. + logreport ("log", 4, "init", "Concealing callback.register().") + local trapped_register = callback.register - Currently, these are (compare the mkcharacters script!) + callback.register = function (id) + logreport ("log", 4, "init", + "Dummy callback.register() invoked on %s.", + id) + end - · "direction" - · "mirror" - · "category" - · "textclass" + --[[doc-- - The directional information is required for packages like Simurgh [0] - to work correctly. In an early stage [1] it was necessary to load - further files from Context directly, including the full blown version - of char-def. Since we have no use for most of the so imported - functionality, the required parts have been isolated and are now - instated along with luaotfload-characters.lua. We can extend the set - of imported features easily should it not be enough. + By default, the fontloader requires a number of \emphasis{private + attributes} for internal use. + These must be kept consistent with the attribute handling methods + as provided by \identifier{luatexbase}. + Our strategy is to override the function that allocates new + attributes before we initialize the font loader, making it a + wrapper around \luafunction{luatexbase.new_attribute}.\footnote{% + Many thanks, again, to Hans Hagen for making this part + configurable! + } + The attribute identifiers are prefixed “\fileent{luaotfload@}” to + avoid name clashes. - [0] https://github.com/persian-tex/simurgh - [1] http://tex.stackexchange.com/a/132301/14066 + --doc]]-- ---doc]]-- + local new_attribute = luatexbase.new_attribute + local the_attributes = luatexbase.attributes ---[[--14.12.2018disable characters ---characters = characters or { } --- should be created in basics-gen ---characters.data = nil ---local chardef = "luaotfload-characters" --- ---do --- local setmetatableindex = function (t, f) --- local mt = getmetatable (t) --- if mt then --- mt.__index = f --- else --- setmetatable (t, { __index = f }) --- end --- end --- --- --- there are some special tables for each field that provide access --- --- to fields of the character table by means of a metatable --- --- local mkcharspecial = function (characters, tablename, field) --- --- local chardata = characters.data --- --- if chardata then --- local newspecial = { } --- characters [tablename] = newspecial --> e.g. “characters.data.mirrors” --- --- local idx = function (t, char) --- local c = chardata [char] --- if c then --- local m = c [field] --> e.g. “mirror” --- if m then --- t [char] = m --- return m --- end --- end --- newspecial [char] = false --- return char --- end --- --- setmetatableindex (newspecial, idx) --- end --- --- end --- --- local mkcategories = function (characters) -- different from the others --- --- local chardata = characters.data --- local categories = characters.categories or { } --- characters.categories = categories --- --- setmetatable (categories, { __index = function (t, char) --- if char then --- local c = chardata [char] --- c = c.category or char --- t [char] = c --- return c --- end --- end}) --- --- end --- --- local load_failed = false --- local chardata --> characters.data; loaded on demand --- --- local load_chardef = function () --- --- logreport ("both", 1, "aux", "Loading character metadata from %s.", chardef) --- chardata = dofile (kpse.find_file (chardef, "lua")) --- --- if chardata == nil then --- logreport ("both", 0, "aux", --- "Could not load %s; continuing with empty character table.", --- chardef) --- chardata = { } --- load_failed = true --- end --- --- characters = { } --- nuke metatable --- characters.data = chardata --- characters.classifiers = chardata.classifiers --- chardata.classifiers = nil --- --- --- institute some of the functionality from char-ini.lua --- --- mkcharspecial (characters, "mirrors", "mirror") --- mkcharspecial (characters, "directions", "direction") --- mkcharspecial (characters, "textclasses", "textclass") --- mkcategories (characters) --- --- end --- --- local charindex = function (t, k) --- if chardata == nil and load_failed ~= true then --- load_chardef () --- end --- --- return rawget (characters, k) --- end --- --- setmetatableindex (characters, charindex) --- ---end ---]] --14.12.2018disable characters - -local init_main = function () + local context_environment = luaotfload.fontloader + context_environment.attributes = { + private = function (name) + local attr = "luaotfload@" .. name --- used to be: “otfl@” + local number = the_attributes[attr] + if not number then number = new_attribute(attr) end + return number + end + } --[[doc-- @@ -473,6 +269,20 @@ local init_main = function () local load_fontloader_module = luaotfload.loaders.fontloader local ignore_module = luaotfload.loaders.ignore + load_fontloader_module "basics-gen" + + if early_hook then early_hook() end + + --[[doc-- + + The font loader requires that the attribute with index zero be + zero. We happily oblige. + (Cf. \fileent{luatex-fonts-nod.lua}.) + + --doc]]-- + + tex.attribute[0] = 0 + --[[doc-- Now that things are sorted out we can finally load the @@ -574,14 +384,14 @@ local init_main = function () logreport ("log", 0, "init", "Loading fontloader from absolute path “%s”.", fontloader) - local _void = require (fontloader) + local _void = assert (loadfile (fontloader, nil, context_environment)) () elseif kpsefind_file (fontloader) then local path = kpsefind_file (fontloader) logreport ("log", 0, "init", "Loading fontloader “%s” from kpse-resolved path “%s”.", fontloader, path) - local _void = require (path) + local _void = assert (loadfile (path, nil, context_environment)) () elseif kpsefind_file (("fontloader-%s.lua"):format(fontloader)) then logreport ("log", 0, "init", @@ -605,43 +415,12 @@ local init_main = function () logreport ("log", 0, "init", "Context OpenType loader version “%s”", fonts.handlers.otf.version) + callback.register = trapped_register + nodes = context_environment.nodes + -- setmetatable(context_environment, nil) -- Would be nice, might break the + -- fontloader end --- [init_main] -local init_cleanup = function (store) - --- reinstate all the stuff we had to move out of the way to - --- accomodate the loader - - --[[doc-- - - Here we adjust the globals created during font loader - initialization. If the second argument to - \luafunction{pop_namespaces()} is \verb|true| this will restore the - state of \luafunction{_G}, eliminating every global generated since - the last call to \luafunction{push_namespaces()}. At the moment we - see no reason to do this, and since the font loader is considered - an essential part of \identifier{luatex} as well as a very well - organized piece of code, we happily concede it the right to add to - \luafunction{_G} if needed. - - --doc]]-- - - pop_namespaces (store.our_environment, - false, - store.context_environment) - - --[[doc-- - - \subsection{Callbacks} - After the fontloader is ready we can restore the callback trap - from \identifier{luatexbase}. - - --doc]]-- - - logreport ("log", 4, "init", - "Restoring original callback.register().") - callback.register = store.trapped_register -end --- [init_cleanup] - local init_post_install_callbacks = function () --[[doc-- @@ -654,7 +433,7 @@ local init_post_install_callbacks = function () --doc]]-- -- MK Pass current text direction to simple_font_handler - local handler = nodes.simple_font_handler + local handler = luaotfload.fontloader.nodes.simple_font_handler local callback = function(head, groupcode, _, _, direction) if not direction then direction = tex.get'textdir' @@ -774,20 +553,14 @@ local init_post = function () return n end --- [init_post] -return { - early = init_early, - main = function (store) - local starttime = os.gettimeofday () - store.our_environment, store.context_environment = init_adapt () - init_main () - init_cleanup (store) - logreport ("both", 1, "init", - "fontloader loaded in %0.3f seconds", - os.gettimeofday() - starttime) - local n = init_post () - logreport ("both", 5, "init", "post hook terminated, %d actions performed", n) - return true - end -} - +return function (early_hook) + local starttime = os.gettimeofday () + init_main (early_hook) + logreport ("both", 1, "init", + "fontloader loaded in %0.3f seconds", + os.gettimeofday() - starttime) + local n = init_post () + logreport ("both", 5, "init", "post hook terminated, %d actions performed", n) + return true +end -- vim:tw=79:sw=2:ts=2:expandtab diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua index bbd045e4f8c..a58d59ba1a5 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua @@ -5,8 +5,8 @@ local ProvidesLuaModule = { name = "luaotfload-letterspace", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / color", license = "GPL v2.0", copyright = "PRAGMA ADE / ConTeXt Development Team", diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua index 11e63c571aa..c2c2320ff8b 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua @@ -8,8 +8,8 @@ local ProvidesLuaModule = { name = "luaotfload-loaders", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / callback handling", license = "GPL v2.0" } @@ -27,17 +27,8 @@ if not luaotfload then error "this module requires Luaotfload" end local logreport = luaotfload.log and luaotfload.log.report or print local lua_reader = function (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 - local fullname = resolvers.findfile (fullname) or "" - if fullname ~= "" then + local fullname = specification.resolved + if fullname then local loader = loadfile (fullname) loader = loader and loader () return loader and loader (specification) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua index 04012632fa6..e6bb042b4f5 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua @@ -6,8 +6,8 @@ local ProvidesLuaModule = { name = "luaotfload-log", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / logging", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang", @@ -220,16 +220,16 @@ else end end -stdout = function (writer, category, ...) +local stdout = function (writer, category, ...) local res = { module_name, "|", category, ":" } local nargs = select("#", ...) if nargs == 0 then --writeln tableconcat(res, " ") --return elseif nargs == 1 then - res[#res+1] = select(1, ...) -- around 30% faster than unpack() + res[5] = ... -- around 30% faster than unpack() else - res[#res+1] = stringformat(...) + res[5] = stringformat(...) end writer (tableconcat(res, " ")) end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua index 26bbfab5066..d17a1d9b264 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua @@ -20,8 +20,8 @@ local authors = "\z -- version number is used below! local ProvidesLuaModule = { name = "luaotfload-main", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload entry point", author = authors, copyright = authors, @@ -142,12 +142,12 @@ local timing_info = { t_init = { }, } -local make_loader = function (prefix) +local make_loader = function (prefix, load_helper) return function (name) local t_0 = osgettimeofday () local modname = make_loader_name (prefix, name) --- We don’t want the stack info from inside, so just pcall(). - local ok, data = pcall (require, modname) + local ok, data = pcall (load_helper or require, modname) local t_end = osgettimeofday () timing_info.t_load [name] = t_end - t_0 if not ok then @@ -190,6 +190,16 @@ local dummy_loader = function (name) name) end +local context_environment = setmetatable({}, {__index = _G}) +luaotfload.fontloader = context_environment +local function context_isolated_load(name) + local fullname = kpse.find_file(name, 'lua') + if not fullname then + error(string.format('Fontloader module "%s" could not be found.', name)) + end + return assert(loadfile(fullname, nil, context_environment))(name) +end + local context_loader = function (name, path) luaotfload.log.report ("log", 3, "load", "Loading module “%s” from Context.", @@ -209,7 +219,7 @@ local context_loader = function (name, path) path) end end - local ret = require (modpath) + local ret = context_isolated_load (modpath) local t_end = osgettimeofday () timing_info.t_load [name] = t_end - t_0 @@ -228,7 +238,7 @@ local install_loaders = function () local loaders = { } local loadmodule = make_loader "luaotfload" loaders.luaotfload = loadmodule - loaders.fontloader = make_loader "fontloader" + loaders.fontloader = make_loader ("fontloader", context_isolated_load) loaders.context = context_loader loaders.ignore = dummy_loader ----loaders.plaintex = make_loader "luatex" --=> for Luatex-Plain @@ -275,15 +285,13 @@ luaotfload.main = function () local starttime = osgettimeofday () local init = loadmodule "init" --- fontloader initialization - local store = init.early () --- injects the log module too - local logreport = luaotfload.log.report + init (function () - initialize "parsers" --- fonts.conf and syntax - initialize "configuration" --- configuration options + initialize "parsers" --- fonts.conf and syntax + initialize "configuration" --- configuration options + end) - if not init.main (store) then - logreport ("log", 0, "load", "Main fontloader initialization failed.") - end + local logreport = luaotfload.log.report initialize "loaders" --- Font loading; callbacks initialize "database" --- Font management. @@ -297,11 +305,19 @@ luaotfload.main = function () end initialize "features" --- font request and feature handling + loadmodule "letterspace" --- extra character kerning loadmodule "embolden" --- fake bold loadmodule "notdef" --- missing glyph handling + local harfstatus, harfbuzz = pcall(require, 'luaharfbuzz') + if harfstatus then + luaotfload.harfbuzz = harfbuzz + loadmodule "harf-define" + loadmodule "harf-plug" + end initialize "auxiliary" --- additional high-level functionality loadmodule "multiscript" --- ... + loadmodule "tounicode" luaotfload.aux.start_rewrite_fontname () --- to be migrated to fontspec diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-multiscript.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-multiscript.lua index ed3aef05c36..56d381a9118 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-multiscript.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-multiscript.lua @@ -5,8 +5,8 @@ local ProvidesLuaModule = { name = "luaotfload-multiscript", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / multiscript", license = "GPL v2.0", author = "Marcel Krüger" diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua index 0cc972a0e3e..53f4af8e3ae 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua @@ -5,8 +5,8 @@ local ProvidesLuaModule = { name = "luaotfload-notdef", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / color", license = "GPL v2.0", author = "Marcel Krüger" diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua index f9fd5c919e4..4a2d6305e1c 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua @@ -7,8 +7,8 @@ local ProvidesLuaModule = { name = "luaotfload-parsers", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / filelist", license = "GPL v2.0" } @@ -603,7 +603,9 @@ local combolist = Ct(combodef1 * (comborowsep * combodef)^1) --- Note to self: subfonts apparently start at index 0. Tested with --- Cambria.ttc that includes “Cambria Math” at 0 and “Cambria” at 1. --- Other values cause luatex to segfault. -local subfont = P"(" * Cg((1 - S"()")^1, "sub") * P")" +local subfont = P"(" * Cg(R'09'^1 / function (s) + return tonumber(s) + 1 + end + (1 - S"()")^1, "sub") * P")" --- lookups ----------------------------------------------------------- local fontname = C((1-S":(/")^1) --- like luatex-fonts diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua index 5146f1d20e6..97e85f0a41e 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua @@ -11,8 +11,8 @@ local ProvidesLuaModule = { name = "luaotfload-resolvers", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / resolvers", license = "GPL v2.0" } @@ -148,11 +148,12 @@ end local tex_formats = { "tfm", "ofm" } +local resolvers_findfile = luaotfload.fontloader.resolvers.findfile local resolve_tex_format = function (specification) local name = specification.name for i=1, #tex_formats do local format = tex_formats [i] - local resolved = resolvers.findfile(name, format) + local resolved = resolvers_findfile(name, format) if resolved then return resolved, format end @@ -241,6 +242,7 @@ local function resolve_kpse (specification) end end +local lookup_subfont_index = fonts.names.lookup_subfont_index local function wrap_resolver(resolver) return function (specification) local filename, sub, forced = resolver(specification) @@ -253,6 +255,10 @@ local function wrap_resolver(resolver) specification.filename = filename specification.name = filename specification.sub = sub or specification.sub + if type(specification.sub) == "string" then + specification.sub = + lookup_subfont_index(filename, specification.sub) + end specification.forced = specification.forced or forced if not specification.forced then local suffix = stringlower (filesuffix (filename)) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua index 69948c43caa..3221986ca78 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua @@ -1,18 +1,18 @@ return { ["hashes"]={ - { "fontloader-2019-08-11.lua", "9ad89bd01fccf2f98b8777ad42851c58" }, + { "fontloader-2019-10-29.lua", "8b7d755e08cfef0826429ffa68271eb3" }, { "fontloader-util-fil.lua", "4bb3e4dc72e308d8ed67cd7a80027fa7" }, - { "fontloader-util-str.lua", "3c829af0b336703e62cb5a1cb7a6e503" }, - { "fontloader-l-unicode.lua", "d46cc6cf18fb3f368ef1e404dc9fcb5c" }, + { "fontloader-util-str.lua", "fc15d89c4c35f7338d09fc7644fac181" }, + { "fontloader-l-unicode.lua", "9bc311ce08ce498f9caacb6164ea1d9f" }, { "fontloader-l-math.lua", "a373be3ed2db0d5f98588fa81abca48f" }, { "fontloader-l-boolean.lua", "18ed6c4b2c40dd87224ea33229548d20" }, { "fontloader-l-file.lua", "3d6ea476061292a0da98c3f65cdabe46" }, { "fontloader-l-io.lua", "42608ad95eb2822fdc370d1c11f08fb5" }, - { "fontloader-l-table.lua", "63b13279139d2f94d29238b0d6242330" }, + { "fontloader-l-table.lua", "9844897b04a01bb197427d71de71de2b" }, { "fontloader-l-string.lua", "e1347bef0eeeff9f098df83b30b32df9" }, { "fontloader-l-function.lua", "f771cc91839ebcdfc094083434fbe00f" }, - { "fontloader-l-lpeg.lua", "a5364ddabb490408da9276ea7f7a7ba1" }, - { "fontloader-l-lua.lua", "9e5e9d4f3b8f9e337f28aa2322192b94" }, + { "fontloader-l-lpeg.lua", "efe630e3a9a1d269120e59cfd8fba4ba" }, + { "fontloader-l-lua.lua", "dda8438a34886bb767dbad381f1ea70a" }, { "fontloader-fonts-gbn.lua", "d25472d54c4841db43a745764a63533e" }, { "fontloader-fonts-lig.lua", "b9dbe77ce747d4c35bb2a20ffbe5aa51" }, { "fontloader-fonts-ext.lua", "01015ab3758cdc2af29394e6d502a91a" }, @@ -21,7 +21,7 @@ return { { "fontloader-fonts-enc.lua", "3e71a54297e8f85a1ac438bb0f20dd79" }, { "fontloader-fonts-mis.lua", "bc9eb43c27f63ce9d0fff67e104fe1c6" }, { "fontloader-basics-chr.lua", "58b7ef0c486e06090b362971b9f85e27" }, - { "fontloader-basics-nod.lua", "65064d03c2650a1761ee13ebd9e1400a" }, + { "fontloader-basics-nod.lua", "c05f47077c709bbf12a8758852dc4e06" }, { "fontloader-font-imp-effects.lua", "73a660359a0ec71e44cc2b7225a715ac" }, { "fontloader-font-imp-italics.lua", "fe1ca80fb5ea4a2f8d2d5c484e7ba913" }, { "fontloader-font-imp-ligatures.lua", "043daa4fcccf2560868da359d71d3a4a" }, @@ -31,16 +31,16 @@ return { { "fontloader-font-afk.lua", "54d554530e75c57c56ee76234724e26d" }, { "fontloader-font-one.lua", "987c5c5ed3754ad2feab80985067d59e" }, { "fontloader-font-onr.lua", "d4d2449b4084e6afb1837ae5835082cc" }, - { "fontloader-font-otc.lua", "95a4ff28ba4afb55a978a4aecfd688bf" }, - { "fontloader-font-ocl.lua", "b720867fb19a23f0b50377efd2a3c54a" }, - { "fontloader-font-osd.lua", "79eb2fc4a71364fd73c8b996a109f5df" }, - { "fontloader-font-ots.lua", "d5504847a278385cd0d20ecf1b3d59cc" }, + { "fontloader-font-otc.lua", "1204a2fdc436e644127c0aa38ab69607" }, + { "fontloader-font-ocl.lua", "ba40df1a92b9b42a5c70d20c28f44759" }, + { "fontloader-font-osd.lua", "39e92f6e575741646d75ea79e3be87f3" }, + { "fontloader-font-ots.lua", "d6a0ce4b40cd4ee1895e2248dcf87d37" }, { "fontloader-font-ota.lua", "d6dfb94563d6a52675e274b2e673e4a6" }, { "fontloader-font-otj.lua", "66c7a910d95d4a52b81061de776898e1" }, { "fontloader-font-oto.lua", "52804afd96f4be005f513a012b874668" }, - { "fontloader-font-otl.lua", "940f9c5ad84f4968a8488f4da2d15e2d" }, - { "fontloader-font-oup.lua", "669e479e716999edc626a1f045bd76fa" }, - { "fontloader-font-dsp.lua", "b5bf2f1c198e027a0d4ededcdf3947b4" }, + { "fontloader-font-otl.lua", "ec0241b7465a7713e53c246e8e9fb2a8" }, + { "fontloader-font-oup.lua", "0cef35af01739f52fd09feb5401192ae" }, + { "fontloader-font-dsp.lua", "5d3db0184c903829b2c5bddcb8cdb14c" }, { "fontloader-font-ttf.lua", "44e61cef50dab9b1aaf48130f9367c34" }, { "fontloader-font-cff.lua", "98d5a660ea803b65cb883c009ecf3c0b" }, { "fontloader-font-ott.lua", "aba6d8335a5f38a5a62d3631492f3392" }, @@ -49,43 +49,46 @@ return { { "fontloader-font-vfc.lua", "94937140f2c909e9c831ba021f1ab303" }, { "fontloader-font-map.lua", "f486746e90fe972de4b73e208ac7cbb2" }, { "fontloader-font-cid.lua", "4d87988efa86020a14708ee03c23415f" }, - { "fontloader-font-con.lua", "ca733211a0555d9a93b1e2f7ebc937d3" }, + { "fontloader-font-con.lua", "8b35e7c2203d5b57c61942e07cee2c0a" }, { "fontloader-font-ini.lua", "4299a02110bbd7c0d27e131235c5319d" }, { "fontloader-data-con.lua", "7ce546725b1550f655c78ac9d69419ca" }, - { "fontloader-reference.lua", "759787e7ee75437382c0a2c4f8fe3b81" }, + { "fontloader-reference.lua", "5be3565068a1929b173bde862b48a30e" }, { "fontloader-basics-gen.lua", "b21e91bbd534f77e368f0ec13f865aed" }, { "mktests", "c7cff7025962922944376acc1ffa9c47" }, - { "mkstatus", "64b9a6b302168fced414830a53fdcce1" }, + { "mkstatus", "32b8eee5316ca3100e4434db79d08230" }, { "mkcharacters", "92c24bb582fc84c0365634f29eb89863" }, { "mkglyphlist", "557836886d4f0e6d656eac3ded4456a2" }, { "mkimport", "60e0b11a1a68719033e86a3e0f4d5e86" }, - { "luaotfload-glyphlist.lua", "df822678061548ce6b510a0c1c7fc103" }, + { "luaotfload-glyphlist.lua", "6dc41351ebdb122e044bed6d3fc2ca4b" }, { "luaotfload-characters.lua", "593ce9dccf6ddc4f7d4be0514f581102" }, - { "luaotfload-unicode.lua", "d9ce2f2a07e951be6310e85fdfcc785d" }, - { "luaotfload-resolvers.lua", "0b0d407501e68537971484ac2256af20" }, - { "luaotfload-parsers.lua", "9b199d5157d9972c415aee7f9350df5b" }, - { "luaotfload-multiscript.lua", "3a4cfa1687c9d1694cbf728183bb066e" }, - { "luaotfload-loaders.lua", "007be1e29cf23779f4d9d0097b56cc4a" }, - { "luaotfload-notdef.lua", "982810e9197d2261ffdc3acd5d8dcecf" }, - { "luaotfload-embolden.lua", "92dfba7dbf10484c85f7e3c971691f8e" }, - { "luaotfload-letterspace.lua", "bb123f78712cc0342419f3c2a5f6a940" }, - { "luaotfload-features.lua", "45ab2c6405c678f8834339fe0d9fb47a" }, - { "luaotfload-database.lua", "da3c5b55a086a2213ee825ecc2bf7e0f" }, - { "luaotfload-configuration.lua", "015022f5b9597254afafff26f9f0f98c" }, - { "luaotfload-colors.lua", "81a23496c5f5c855674b05180869b8cf" }, - { "luaotfload-auxiliary.lua", "81432ebaebfce3df73b5949e1001d13c" }, - { "luaotfload-filelist.lua", "aa3c9fa695042573d6f6c2e5d0c23558" }, - { "luaotfload-tool.lua", "1833a47868c3e5958d492bb947d39dec" }, - { "luaotfload-diagnostics.lua", "53dbf51623658f1e325d2e6279a2ee15" }, - { "luaotfload-log.lua", "30491ef5890898d5ae3af44f72e82b1f" }, - { "luaotfload-init.lua", "479854a620629b1934d16723aa4cae0c" }, - { "luaotfload-main.lua", "95c7d3ce348ac83e0659f7332e98eacc" }, + { "luaotfload-tounicode.lua", "b87cab857631c47f5c2bbfa4dc1b5598" }, + { "luaotfload-unicode.lua", "eaf637834d735afce54cf81721b89626" }, + { "luaotfload-resolvers.lua", "7bcd23bf0c4079174679f61c315f54ed" }, + { "luaotfload-parsers.lua", "23b0550fcc6bf872714d882b8d15f465" }, + { "luaotfload-multiscript.lua", "bd0b25f9b9b21ad1e1a24fb88dc5cdbf" }, + { "luaotfload-loaders.lua", "34d130aa4e365639baecfa0481e34d13" }, + { "luaotfload-harf-plug.lua", "59429664d9bebfbf0e0bfa8a8bdd85e3" }, + { "luaotfload-harf-define.lua", "f0aafaecaddbc43f665a076195ed9205" }, + { "luaotfload-notdef.lua", "ce00644d5801c6fac2e274626a52ecf2" }, + { "luaotfload-embolden.lua", "7ff4b7e2970f2748a4d881b23085495d" }, + { "luaotfload-letterspace.lua", "2b24d57529363de4a004510da84bafd9" }, + { "luaotfload-features.lua", "b8c279955bcc473f02ad77b46942eb29" }, + { "luaotfload-database.lua", "131587572dcf49769bec7e085ab61281" }, + { "luaotfload-configuration.lua", "a59a94e07e20998144c91d5eb44b9302" }, + { "luaotfload-colors.lua", "c13f4c88058e2c4869205ad015765070" }, + { "luaotfload-auxiliary.lua", "77bcb55f9d215ad8a61701dc64e9a07e" }, + { "luaotfload-filelist.lua", "96967c2f4ad091f2a8c74a50294c25d5" }, + { "luaotfload-tool.lua", "9a53d4aedf71012530be90303aabe0d9" }, + { "luaotfload-diagnostics.lua", "f521a2b70b24bd23fb23d3d08d7845bf" }, + { "luaotfload-log.lua", "28c5c63d7af789ab7ca5757870dfc595" }, + { "luaotfload-init.lua", "ebb2e936d4c95cab76649897f6af0e25" }, + { "luaotfload-main.lua", "e4208f459c12b57a6996b4c7e9adbb8b" }, }, ["notes"]={ - ["committer"]="Marcel Fabian Krüger <tex@2krueger.de>", - ["description"]="v3.00/2019-09-13", - ["loader"]="fontloader-2019-08-11.lua", - ["revision"]="e758f5d39e3d416e4bc1e2a23918abed744563ae", - ["timestamp"]="2019-09-13 00:43:25 +0200", + ["committer"]="Ulrike Fischer <fischer@troubleshooting-tex.de>", + ["description"]="v3.1/2019-11-04", + ["loader"]="fontloader-2019-10-29.lua", + ["revision"]="cdc212ae76bc0f839d116c8f66af98445ba9f307", + ["timestamp"]="2019-11-03 15:29:57 +0100", }, }
\ No newline at end of file diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-tounicode.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-tounicode.lua new file mode 100644 index 00000000000..3636f79220d --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-tounicode.lua @@ -0,0 +1,200 @@ +----------------------------------------------------------------------- +-- FILE: luaotfload-tounicode.lua +-- DESCRIPTION: part of luaotfload / tounicode overwrites +----------------------------------------------------------------------- + +local ProvidesLuaModule = { + name = "luaotfload-tounicode", + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE + description = "luaotfload submodule / tounicode", + license = "GPL v2.0", + author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger", + copyright = "PRAGMA ADE / ConTeXt Development Team", +} + +if luatexbase and luatexbase.provides_module then + luatexbase.provides_module (ProvidesLuaModule) +end + +local overloads = { + -- rougly based on texglyphlist-g2u.txt + + -- ff = { unicode = {0x0066, 0x0066} }, + -- ffi = { unicode = {0x0066, 0x0066, 0x0069} }, + -- ffl = { unicode = {0x0066, 0x0066, 0x006C} }, + -- fi = { unicode = {0x0066, 0x0069} }, + -- fl = { unicode = {0x0066, 0x006C} }, + longst = { unicode = {0x017F, 0x0074} }, + st = { unicode = {0x0073, 0x0074} }, + AEsmall = { unicode = 0x00E6 }, + Aacutesmall = { unicode = 0x00E1 }, + Acircumflexsmall = { unicode = 0x00E2 }, + Acute = { unicode = 0x00B4 }, + Acutesmall = { unicode = 0x00B4 }, + Adieresissmall = { unicode = 0x00E4 }, + Agravesmall = { unicode = 0x00E0 }, + Aringsmall = { unicode = 0x00E5 }, + Asmall = { unicode = 0x0061 }, + Atildesmall = { unicode = 0x00E3 }, + Brevesmall = { unicode = 0x02D8 }, + Bsmall = { unicode = 0x0062 }, + Caron = { unicode = 0x02C7 }, + Caronsmall = { unicode = 0x02C7 }, + Ccedillasmall = { unicode = 0x00E7 }, + Cedillasmall = { unicode = 0x00B8 }, + Circumflexsmall = { unicode = 0x02C6 }, + Csmall = { unicode = 0x0063 }, + Dieresis = { unicode = 0x00A8 }, + DieresisAcute = { unicode = 0xF6CC }, + DieresisGrave = { unicode = 0xF6CD }, + Dieresissmall = { unicode = 0x00A8 }, + Dotaccentsmall = { unicode = 0x02D9 }, + Dsmall = { unicode = 0x0064 }, + Eacutesmall = { unicode = 0x00E9 }, + Ecircumflexsmall = { unicode = 0x00EA }, + Edieresissmall = { unicode = 0x00EB }, + Egravesmall = { unicode = 0x00E8 }, + Esmall = { unicode = 0x0065 }, + Ethsmall = { unicode = 0x00F0 }, + Fsmall = { unicode = 0x0066 }, + Grave = { unicode = 0x0060 }, + Gravesmall = { unicode = 0x0060 }, + Gsmall = { unicode = 0x0067 }, + Hsmall = { unicode = 0x0068 }, + Hungarumlaut = { unicode = 0x02DD }, + Hungarumlautsmall = { unicode = 0x02DD }, + Iacutesmall = { unicode = 0x00ED }, + Icircumflexsmall = { unicode = 0x00EE }, + Idieresissmall = { unicode = 0x00EF }, + Igravesmall = { unicode = 0x00EC }, + Ismall = { unicode = 0x0069 }, + Jsmall = { unicode = 0x006A }, + Ksmall = { unicode = 0x006B }, + LL = { unicode = {0x004C, 0x004C} }, + Lslashsmall = { unicode = 0x0142 }, + Lsmall = { unicode = 0x006C }, + Macron = { unicode = 0x00AF }, + Macronsmall = { unicode = 0x00AF }, + Msmall = { unicode = 0x006D }, + Nsmall = { unicode = 0x006E }, + Ntildesmall = { unicode = 0x00F1 }, + OEsmall = { unicode = 0x0153 }, + Oacutesmall = { unicode = 0x00F3 }, + Ocircumflexsmall = { unicode = 0x00F4 }, + Odieresissmall = { unicode = 0x00F6 }, + Ogoneksmall = { unicode = 0x02DB }, + Ogravesmall = { unicode = 0x00F2 }, + Oslashsmall = { unicode = 0x00F8 }, + Osmall = { unicode = 0x006F }, + Otildesmall = { unicode = 0x00F5 }, + Psmall = { unicode = 0x0070 }, + Qsmall = { unicode = 0x0071 }, + Ringsmall = { unicode = 0x02DA }, + Rsmall = { unicode = 0x0072 }, + Scaronsmall = { unicode = 0x0161 }, + Ssmall = { unicode = 0x0073 }, + Thornsmall = { unicode = 0x00FE }, + Tildesmall = { unicode = 0x02DC }, + Tsmall = { unicode = 0x0074 }, + Uacutesmall = { unicode = 0x00FA }, + Ucircumflexsmall = { unicode = 0x00FB }, + Udieresissmall = { unicode = 0x00FC }, + Ugravesmall = { unicode = 0x00F9 }, + Usmall = { unicode = 0x0075 }, + Vsmall = { unicode = 0x0076 }, + Wsmall = { unicode = 0x0077 }, + Xsmall = { unicode = 0x0078 }, + Yacutesmall = { unicode = 0x00FD }, + Ydieresissmall = { unicode = 0x00FF }, + Ysmall = { unicode = 0x0079 }, + Zcaronsmall = { unicode = 0x017E }, + Zsmall = { unicode = 0x007A }, + ampersandsmall = { unicode = 0x0026 }, + asuperior = { unicode = 0x0061 }, + bsuperior = { unicode = 0x0062 }, + centinferior = { unicode = 0x00A2 }, + centoldstyle = { unicode = 0x00A2 }, + centsuperior = { unicode = 0x00A2 }, + commainferior = { unicode = 0x002C }, + commasuperior = { unicode = 0x002C }, + copyrightsans = { unicode = 0x00A9 }, + copyrightserif = { unicode = 0x00A9 }, + cyrBreve = { unicode = 0x02D8 }, + cyrFlex = { unicode = {0x00A0, 0x0311} }, + cyrbreve = { unicode = 0x02D8 }, + cyrflex = { unicode = {0x00A0, 0x0311} }, + dblGrave = { unicode = {0x00A0, 0x030F} }, + dblgrave = { unicode = {0x00A0, 0x030F} }, + dieresisacute = { unicode = {0x00A0, 0x0308, 0x0301} }, + dieresisgrave = { unicode = {0x00A0, 0x0308, 0x0300} }, + dollarinferior = { unicode = 0x0024 }, + dollaroldstyle = { unicode = 0x0024 }, + dollarsuperior = { unicode = 0x0024 }, + dotlessj = { unicode = 0x0237 }, + dsuperior = { unicode = 0x0064 }, + eightoldstyle = { unicode = 0x0038 }, + esuperior = { unicode = 0x0065 }, + exclamdownsmall = { unicode = 0x00A1 }, + exclamsmall = { unicode = 0x0021 }, + fiveoldstyle = { unicode = 0x0035 }, + fouroldstyle = { unicode = 0x0034 }, + hypheninferior = { unicode = 0x002D }, + hyphensuperior = { unicode = 0x002D }, + isuperior = { unicode = 0x0069 }, + ll = { unicode = {0x006C, 0x006C} }, + lsuperior = { unicode = 0x006C }, + msuperior = { unicode = 0x006D }, + nineoldstyle = { unicode = 0x0039 }, + onefitted = { unicode = 0x0031 }, + oneoldstyle = { unicode = 0x0031 }, + osuperior = { unicode = 0x006F }, + periodinferior = { unicode = 0x002E }, + periodsuperior = { unicode = 0x002E }, + questiondownsmall = { unicode = 0x00BF }, + questionsmall = { unicode = 0x003F }, + registersans = { unicode = 0x00AE }, + registerserif = { unicode = 0x00AE }, + rsuperior = { unicode = 0x0072 }, + rupiah = { unicode = 0x20A8 }, + sevenoldstyle = { unicode = 0x0037 }, + sixoldstyle = { unicode = 0x0036 }, + ssuperior = { unicode = 0x0073 }, + threeoldstyle = { unicode = 0x0033 }, + trademarksans = { unicode = 0x2122 }, + trademarkserif = { unicode = 0x2122 }, + tsuperior = { unicode = 0x0074 }, + twooldstyle = { unicode = 0x0032 }, + zerooldstyle = { unicode = 0x0030 }, + FFsmall = { unicode = {0x0066, 0x0066} }, + FFIsmall = { unicode = {0x0066, 0x0066, 0x0069} }, + FFLsmall = { unicode = {0x0066, 0x0066, 0x006C} }, + FIsmall = { unicode = {0x0066, 0x0069} }, + FLsmall = { unicode = {0x0066, 0x006C} }, + Germandblssmall = { unicode = {0x0073, 0x0073} }, + SSsmall = { unicode = {0x0073, 0x0073} }, +} +-- For values that are used multiple times +local function registeroverload(mapped) + mapped = {unicode = mapped} + local function multiset(first, ...) + if first then + rawset(overloads, first, mapped) + return multiset(...) + end + end + return multiset +end + +-- These come from ConTeXt +registeroverload { 0x49, 0x4A } ("IJ", "I_J", 0x0132) +registeroverload { 0x69, 0x6A } ("ij", "i_j", 0x0133) +registeroverload { 0x66, 0x66 } ("ff", "f_f", 0xFB00) +registeroverload { 0x66, 0x69 } ("fi", "f_i", 0xFB01) +registeroverload { 0x66, 0x6C } ("fl", "f_l", 0xFB02) +registeroverload { 0x66, 0x66, 0x69 } ("ffi", "f_f_i", 0xFB03) +registeroverload { 0x66, 0x66, 0x6C } ("ffl", "f_f_l", 0xFB04) +registeroverload { 0x66, 0x6A } ("fj", "f_j") +registeroverload { 0x66, 0x6B } ("fk", "f_k") + +fonts.mappings.overloads = overloads diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-unicode.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-unicode.lua index d7cb98a3387..c1bdf3cbd26 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-unicode.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-unicode.lua @@ -5,8 +5,8 @@ local ProvidesLuaModule = { name = "luaotfload-unicode", - version = "3.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / Unicode helpers", license = "CC0 1.0 Universal", author = "Marcel Krüger" diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty index 1dede25f2fd..4dc2553d334 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty @@ -40,7 +40,7 @@ \fi \ifdefined\ProvidesPackage \ProvidesPackage{luaotfload}% - [2019/09/13 v3.00 OpenType layout system] + [2019/11/04 v3.1 OpenType layout system] \fi \directlua{ if xpcall(function ()% |