diff --git a/source/build-aux/texinfo.tex b/source/build-aux/texinfo.tex index faad184e345b058eda6fd880c4070a7950e419c5..3ebea93cb1d604c6b0fa7f1b95fcb6e5b1dda01a 100644 --- a/source/build-aux/texinfo.tex +++ b/source/build-aux/texinfo.tex @@ -3,7 +3,7 @@ % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2025-01-31.21} +\def\texinfoversion{2025-03-22.08} % % Copyright 1985, 1986, 1988, 1990-2025 Free Software Foundation, Inc. % @@ -287,7 +287,6 @@ % Avoid "undefined control sequence" errors. \def\currentchapterdefs{} \def\currentsectiondefs{} -\def\currentsection{} \def\prevchapterdefs{} \def\prevsectiondefs{} \def\currentcolordefs{} @@ -980,18 +979,51 @@ where each line of input produces a line of output.} \newif\ifpdf \newif\ifpdfmakepagedest +% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1 +% can be set). So we test for \relax and 0 as well as being undefined. +\ifx\pdfoutput\thisisundefined +\else + \ifx\pdfoutput\relax + \else + \ifcase\pdfoutput + \else + \pdftrue + \fi + \fi +\fi + +\newif\ifxetex +\ifx\XeTeXrevision\thisisundefined\else + \xetextrue +\fi + \newif\ifluatex \ifx\luatexversion\thisisundefined\else \luatextrue + \ifnum\luatexversion>84 + \pdftrue + \fi \fi +\newif\ifpdforxetex +\ifpdf + \pdforxetextrue +\fi +\ifxetex + \pdforxetextrue +\fi + + + +% Whether to use non-ASCII bytes in internal link targets. Presently this +% is almost always on. +\newif\iftxiuseunicodedestname +\txiuseunicodedestnametrue + % % For LuaTeX % -\newif\iftxiuseunicodedestname -\txiuseunicodedestnamefalse % For pdfTeX etc. - \ifluatex % Use Unicode destination names \txiuseunicodedestnametrue @@ -1045,7 +1077,7 @@ where each line of input produces a line of output.} % \endgroup \def\pdfescapestring#1{\directlua{PDFescstr('\luaescapestring{#1}')}} - \ifnum\luatexversion>84 + \ifpdf % For LuaTeX >= 0.85 \def\pdfdest{\pdfextension dest} \let\pdfoutput\outputmode @@ -1068,33 +1100,6 @@ where each line of input produces a line of output.} \fi \fi -% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1 -% can be set). So we test for \relax and 0 as well as being undefined. -\ifx\pdfoutput\thisisundefined -\else - \ifx\pdfoutput\relax - \else - \ifcase\pdfoutput - \else - \pdftrue - \fi - \fi -\fi - -\newif\ifxetex -\ifx\XeTeXrevision\thisisundefined\else - \xetextrue -\fi - -\newif\ifpdforxetex -\pdforxetexfalse -\ifpdf - \pdforxetextrue -\fi -\ifxetex - \pdforxetextrue -\fi - % Output page labels information. % See PDF reference v.1.7 p.594, section 8.3.1. @@ -1388,9 +1393,6 @@ output) for that.)} \safewhatsit{\pdfdest name{\pdfdestname} xyz}% } % - % used to mark target names; must be expandable. - \def\pdfmkpgn#1{#1} - % % Adding outlines to PDF; macros for calculating structure of outlines % come from Petr Olsak \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% @@ -1416,7 +1418,7 @@ output) for that.)} \def\pdfdestname{#4}% \fi % - \pdfoutline goto name{\pdfmkpgn{\pdfdestname}}#2{\pdfoutlinetext}% + \pdfoutline goto name{\pdfdestname}#2{\pdfoutlinetext}% } % \def\pdfmakeoutlines{% @@ -1427,15 +1429,18 @@ output) for that.)} \def\thischapnum{##2}% \def\thissecnum{0}% \def\thissubsecnum{0}% + \def\indexlastsec{chap\thischapnum}% }% \def\numsecentry##1##2##3##4{% \advancenumber{chap\thischapnum}% \def\thissecnum{##2}% \def\thissubsecnum{0}% + \def\indexlastsec{sec\thissecnum}% }% \def\numsubsecentry##1##2##3##4{% \advancenumber{sec\thissecnum}% \def\thissubsecnum{##2}% + \def\indexlastsec{subsec\thissecnum}% }% \def\numsubsubsecentry##1##2##3##4{% \advancenumber{subsec\thissubsecnum}% @@ -1443,7 +1448,13 @@ output) for that.)} \def\thischapnum{0}% \def\thissecnum{0}% \def\thissubsecnum{0}% + \let\indexlastsec\empty % + % Index initials are subsidiary to whatever sectioning command just + % occurred, usually @appendix or @chapter but occasionally a lower level. + \def\idxinitialentry##1##2##3##4{% + \expandafter\advancenumber\expandafter{\indexlastsec}% + }% % use \def rather than \let here because we redefine \chapentry et % al. a second time, below. \def\appentry{\numchapentry}% @@ -1455,9 +1466,6 @@ output) for that.)} \def\unnsubsecentry{\numsubsecentry}% \def\unnsubsubsecentry{\numsubsubsecentry}% % - % Treat index initials like @section. Note that this is the wrong - % level if the index is not at the level of @appendix or @chapter. - \def\idxinitialentry{\numsecentry}% \readdatafile{toc}% % % Read toc second time, this time actually producing the outlines. @@ -1482,18 +1490,6 @@ output) for that.)} \def\idxinitialentry##1##2##3##4{% \dopdfoutline{##1}{}{idx.##1.##2}{##4}}% % - % PDF outlines are displayed using system fonts, instead of - % document fonts. Therefore we cannot use special characters, - % since the encoding is unknown. For example, the eogonek from - % Latin 2 (0xea) gets translated to a | character. Info from - % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100. - % - % TODO this right, we have to translate 8-bit characters to - % their "best" equivalent, based on the @documentencoding. Too - % much work for too little return. Just use the ASCII equivalents - % we use for the index sort strings. - % - \indexnofonts \ifnodeseen\else \dopdfoutlinecontents \fi % for @contents at beginning \setupdatafile % We can have normal brace characters in the PDF outlines, unlike @@ -1501,9 +1497,9 @@ output) for that.)} \def\{{\lbracecharliteral}% \def\}{\rbracecharliteral}% \catcode`\\=\active \otherbackslash - \input \tocreadfilename + \input \tocreadfilename\relax + \ifnodeseen \dopdfoutlinecontents \fi % for @contents at end \endgroup - \ifnodeseen \dopdfoutlinecontents \fi % for @contents at end } \def\dopdfoutlinecontents{% \expandafter\dopdfoutline\expandafter{\putwordTOC}{}{txi.CONTENTS}{}% @@ -1541,7 +1537,7 @@ output) for that.)} % \def\pdflink#1{\pdflinkpage{#1}{#1}}% \def\pdflinkpage#1#2{% - \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} + \startlink attr{/Border [0 0 0]} goto name{#1} \setcolor{\linkcolor}#2\endlink} \else % non-pdf mode @@ -1644,18 +1640,20 @@ output) for that.)} % horizontal space being required in the PDF viewer. \def\partentry##1##2##3##4{}% ignore parts in the outlines \def\numchapentry##1##2##3##4{% - \dopdfoutline{##2 ##1}{1}{##3}{##4}}% + \dopdfoutline{##2 ##1}{1}{##3}{##4}% + \def\indexseclevel{2}}% \def\numsecentry##1##2##3##4{% - \dopdfoutline{##1}{2}{##3}{##4}}% + \dopdfoutline{##1}{2}{##3}{##4}% + \def\indexseclevel{3}}% \def\numsubsecentry##1##2##3##4{% - \dopdfoutline{##1}{3}{##3}{##4}}% + \dopdfoutline{##1}{3}{##3}{##4}% + \def\indexseclevel{4}}% \def\numsubsubsecentry##1##2##3##4{% - \dopdfoutline{##1}{4}{##3}{##4}}% + \dopdfoutline{##1}{4}{##3}{##4}% + \def\indexseclevel{5}}% % - % Note this is at the wrong level unless the index is in an @appendix - % or @chapter. \def\idxinitialentry##1##2##3##4{% - \dopdfoutline{##1}{2}{idx.##1.##2}{##4}}% + \dopdfoutline{##1}{\indexseclevel}{idx.##1.##2}{##4}}% % \let\appentry\numchapentry% \let\appsecentry\numsecentry% @@ -1680,7 +1678,9 @@ output) for that.)} \def\{{\lbracecharliteral}% \def\}{\rbracecharliteral}% \catcode`\\=\active \otherbackslash + \xetexpreauxfile \input \tocreadfilename\relax + \xetexpostauxfile \ifnodeseen \dopdfoutlinecontents \fi % for @contents at end \endgroup } @@ -5177,8 +5177,8 @@ $$% % \uccode`\1=`\{ \uppercase{\def\{{1}}% \uccode`\1=`\} \uppercase{\def\}{1}}% - \let\lbracechar\{% - \let\rbracechar\}% + \def\lbracechar##1{\{}% + \def\rbracechar##1{\}}% % % % We need to get rid of all macros, leaving only the arguments (if present). @@ -5523,6 +5523,8 @@ $$% \tolerance = 9500 \plainfrenchspacing \everypar = {}% don't want the \kern\-parindent from indentation suppression. + \let\entry\indexentry + \ifxetex\xetexpreauxfile\fi % % See comment in \requireopenindexfile. \def\indexname{#1}\ifx\indexname\indexisfl\def\indexname{f1}\fi @@ -5548,6 +5550,7 @@ $$% \fi \fi \closein 1 + \ifxetex\xetexpostauxfile\fi \endgroup} % Checked in @bye @@ -5583,7 +5586,9 @@ might help (with 'rm \jobname.?? \jobname.??s')% }% \else \begindoublecolumns + \ifxetex\xetexpreauxfile\fi \input \jobname.\indexname s + \ifxetex\xetexpostauxfile\fi \enddoublecolumns \fi }{% @@ -5594,11 +5599,39 @@ might help (with 'rm \jobname.?? \jobname.??s')% % should work because we (hopefully) don't otherwise use @ in index files. %\catcode`\@=12\relax \catcode`\@=0\relax + \ifxetex\xetexpreauxfile\fi \input \jobname.\indexname s + \ifxetex\xetexpostauxfile\fi \enddoublecolumns }% } +\def\indexentry#1#2{% + \let\entrypagetarget\empty + \ifpdforxetex + % only link the index text to the page if no comma appears in the + % list of pages, i.e. there is only one page + \checkpagelistcomma{#2}\pagelistcomma + \expandafter\ifcase\pagelistcomma + \def\entrypagetarget{#2}% + \fi + \fi% + \entryinternal{#1}{#2}% +} + +\def\checkpagelistcomma#1#2{% + \checkpagelistcommaxx#2#1,\finish +} +\def\checkpagelistcommaxx#1#2,#3\finish{% + \def\tmp{#3}% + \ifx\tmp\empty + \def#1{0\relax} + \else + \def#1{1\relax} + \fi +} + + % These macros are used by the sorted index file itself. % Change them to control the appearance of the index. @@ -5673,18 +5706,14 @@ might help (with 'rm \jobname.?? \jobname.??s')% \def\doindexinitialentry#1{% \ifpdforxetex \global\advance\idxinitialno by 1 - \def\indexlbrace{\{} - \def\indexrbrace{\}} - \def\indexbackslash{\realbackslash} - \def\indexatchar{\@} + \def\indexlbrace{\{}% + \def\indexrbrace{\}}% + \def\indexbackslash{\realbackslash}% + \def\indexatchar{\@}% \writetocentry{idxinitial}{\asis #1}{IDX\the\idxinitialno}% % The @asis removes a pair of braces around e.g. {@indexatchar} that % are output by texindex. % - \vbox to 0pt{}% - % This vbox fixes the \pdfdest location for double column formatting. - % Without it, the \pdfdest is output above topskip glue at the top - % of a column as this glue is not added until the first box. \pdfmkdest{idx.\asis #1.IDX\the\idxinitialno}% \fi } @@ -5704,16 +5733,18 @@ might help (with 'rm \jobname.?? \jobname.??s')% \newdimen\entrycontskip \entrycontskip=1em -% for PDF output, whether to make the text of the entry a link to the page -% number. set for @contents and @shortcontents where there is only one -% page number. +% for PDF output, whether to make the text of the entry a link to the section. +% set for @contents and @shortcontents. \newif\iflinkentrytext -% \entry typesets a paragraph consisting of the text (#1), dot leaders, and -% then page number (#2) flushed to the right margin. It is used for index -% and table of contents entries. The paragraph is indented by \leftskip. -% If \tocnodetarget is set, link text to the referenced node. -\def\entry{% +% \entryinternal typesets a paragraph consisting of the text (#1), dot +% leaders, and then page number (#2) flushed to the right margin. It is +% used for index and table of contents entries. The paragraph is indented +% by \leftskip. +% For PDF output, if \linkentrytexttrue and \tocnodetarget is set, link text +% to the referenced node. Else if \entrypagetarget is set, link text to the +% page. +\def\entryinternal{% \begingroup % % Start a new paragraph if necessary, so our assignments below can't @@ -5761,7 +5792,11 @@ might help (with 'rm \jobname.?? \jobname.??s')% \endlink \fi \else - \unhbox\boxA + \ifx\entrypagetarget\empty + \unhbox\boxA + \else + \pdflinkpage{\entrypagetarget}{\unhbox\boxA}% + \fi \fi \else \unhbox\boxA @@ -6433,6 +6468,10 @@ might help (with 'rm \jobname.?? \jobname.??s')% \parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{} \suppressfirstparagraphindent} +% @xrefname - give text with printed name for linking to node and allow +% referencing node, but do not print any heading. +\parseargdef\xrefname{\donoderef{Yomitfromtoc}{#1}}% + % These macros generate a chapter, section, etc. heading only % (including whitespace, linebreaking, etc. around it), % given all the information in convenient, parsed form. @@ -6554,11 +6593,6 @@ might help (with 'rm \jobname.?? \jobname.??s')% \chapfonts \rm \let\footnote=\errfootnoteheading % give better error message % - % Have to define \currentsection before calling \donoderef, because the - % xref code eventually uses it. On the other hand, it has to be called - % after \pchapsepmacro, or the headline will change too soon. - \gdef\currentsection{#1}% - % % Only insert the separating space if we have a chapter/appendix % number, and don't print the unnumbered ``number''. \ifx\temptype\Ynothingkeyword @@ -6585,7 +6619,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% % been typeset. If the destination for the pdf outline is after the % text, then jumping from the outline may wind up with the text not % being visible, for instance under high magnification. - \donoderef{#2}% + \donoderef{#2}{#1}% % % Typeset the actual heading. \nobreak % Avoid page breaks at the interline glue. @@ -6701,21 +6735,17 @@ might help (with 'rm \jobname.?? \jobname.??s')% \ifx\temptype\Ynothingkeyword \setbox0 = \hbox{}% \def\toctype{unn}% - \gdef\currentsection{#1}% \else\ifx\temptype\Yomitfromtockeyword - % for @headings -- no section number, don't include in toc, - % and don't redefine \currentsection. + % for @headings -- no section number, don't include in toc. \setbox0 = \hbox{}% \def\toctype{omit}% \let\sectionlevel=\empty \else\ifx\temptype\Yappendixkeyword \setbox0 = \hbox{#4\enspace}% \def\toctype{app}% - \gdef\currentsection{#1}% \else \setbox0 = \hbox{#4\enspace}% \def\toctype{num}% - \gdef\currentsection{#1}% \fi\fi\fi % % Write the toc entry (before \donoderef). See comments in \chapmacro. @@ -6723,7 +6753,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% % % Write the node reference (= pdf destination for pdftex). % Again, see comments in \chapmacro. - \donoderef{#3}% + \donoderef{#3}{#1}% % % Interline glue will be inserted when the vbox is completed. % That glue will be a valid breakpoint for the page, since it'll be @@ -6955,6 +6985,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% % \def\contents{% \startcontents{\putwordTOC}{\contentsmkdest}% + \ifxetex\xetexpreauxfile\fi \openin 1 \tocreadfilename\space \ifeof 1 \else \findsecnowidths @@ -6966,6 +6997,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% \pdfmakeoutlines \fi \closein 1 + \ifxetex\xetexpostauxfile\fi \endgroup \contentsendroman } @@ -6999,11 +7031,13 @@ might help (with 'rm \jobname.?? \jobname.??s')% \let\numsubsubsecentry = \numsecentry \let\appsubsubsecentry = \numsecentry \let\unnsubsubsecentry = \numsecentry + \ifxetex\xetexpreauxfile\fi \openin 1 \tocreadfilename\space \ifeof 1 \else \readtocfile \fi \closein 1 + \ifxetex\xetexpostauxfile\fi \vfill \eject \contentsalignmacro % in case @setchapternewpage odd is in effect \endgroup @@ -7167,6 +7201,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% \extrasecnoskip=0pt \let\tocnodetarget\empty +\let\entrypagetarget\empty % \tocentry{TITLE}{SEC NO}{NODE}{PAGE} % @@ -7174,7 +7209,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% \def\tocnodetarget{#3}% \def\secno{#2}% \ifx\empty\secno - \entry{#1}{#4}% + \entryinternal{#1}{#4}% \else \ifdim 0pt=\secnowidth \setbox0=\hbox{#2\hskip\labelspace\hskip\extrasecnoskip}% @@ -7185,7 +7220,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% #2\hskip\labelspace\hskip\extrasecnoskip\hfill}% \fi \entrycontskip=\wd0 - \entry{\box0 #1}{#4}% + \entryinternal{\box0 #1}{#4}% \fi } \newdimen\labelspace @@ -8170,18 +8205,11 @@ might help (with 'rm \jobname.?? \jobname.??s')% } \fi -\let\E=\expandafter - % Used at the time of macro expansion. % Argument is macro body with arguments substituted \def\scanmacro#1{% \newlinechar`\^^M - % expand the expansion of \eatleadingcr twice to maybe remove a leading - % newline (and \else and \fi tokens), then call \eatspaces on the result. - \def\xeatspaces##1{% - \E\E\E\E\E\E\E\eatspaces\E\E\E\E\E\E\E{\eatleadingcr##1% - }}% - \def\xempty##1{}% + \def\xeatspaces##1{\eatleadingcrthen\eatspaces{##1}}% % % Process the macro body under the current catcode regime. \scantokens{#1@comment}% @@ -8234,10 +8262,12 @@ might help (with 'rm \jobname.?? \jobname.??s')% \unbrace{\gdef\trim@@@ #1 } #2@{#1} } -{\catcode`\^^M=\other% -\gdef\eatleadingcr#1{\if\noexpand#1\noexpand^^M\else\E#1\fi}}% -% Warning: this won't work for a delimited argument -% or for an empty argument +% Trim a single leading ^^M off a string, then call #1 +{\catcode`\^^M=\active \catcode`\Q=3% +\gdef\eatleadingcrthen #1#2{\eatlcra #1Q#2Q^^MQ}% +\gdef\eatlcra #1#2Q^^M{\eatlcrb #1#2Q}% +\gdef\eatlcrb #1Q#2Q#3Q{#1{#2}}% +} % Trim a single trailing ^^M off a string. {\catcode`\^^M=\other \catcode`\Q=3% @@ -8373,6 +8403,10 @@ might help (with 'rm \jobname.?? \jobname.??s')% % <parameter list> is #, then the preceding argument is delimited by % an opening brace, and that opening brace is not consumed. +% Make @ a letter, so that we can make private-to-Texinfo macro names. +\edef\texiatcatcode{\the\catcode`\@} +\catcode `@=11\relax + % Parse the optional {params} list to @macro or @rmacro. % Set \paramno to the number of arguments, % and \paramlist to a parameter text for the macro (e.g. #1,#2,#3 for a @@ -8385,14 +8419,13 @@ might help (with 'rm \jobname.?? \jobname.??s')% % That gets used by \mbodybackslash (above). % % If there are 10 or more arguments, a different technique is used: see -% \parsemmanyargdef. +% \parsemmanyargdef@@. % \def\parsemargdef#1;{% \paramno=0\def\paramlist{}% \let\hash\relax % \hash is redefined to `#' later to get it into definitions \let\xeatspaces\relax - \let\xempty\relax \parsemargdefxxx#1,;,% \ifnum\paramno<10\relax\else \paramno0\relax @@ -8404,11 +8437,9 @@ might help (with 'rm \jobname.?? \jobname.??s')% \else \let\next=\parsemargdefxxx \advance\paramno by 1 \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname - {\xeatspaces{\hash\the\paramno\noexpand\xempty{}}}% + {\xeatspaces{\hash\the\paramno}}% \edef\paramlist{\paramlist\hash\the\paramno,}% \fi\next} -% the \xempty{} is to give \eatleadingcr an argument in the case of an -% empty macro argument. % \parsemacbody, \parsermacbody % @@ -8419,14 +8450,12 @@ might help (with 'rm \jobname.?? \jobname.??s')% % body to be transformed. % Set \macrobody to the body of the macro, and call \macrodef. % +\catcode `\@\texiatcatcode {\catcode`\ =\other\long\gdef\parsemacbody#1@end macro{% \xdef\macrobody{\eatcr{#1}}\endgroup\macrodef}}% {\catcode`\ =\other\long\gdef\parsermacbody#1@end rmacro{% \xdef\macrobody{\eatcr{#1}}\endgroup\macrodef}}% - -% Make @ a letter, so that we can make private-to-Texinfo macro names. -\edef\texiatcatcode{\the\catcode`\@} -\catcode `@=11\relax +\catcode `\@=11\relax %%%%%%%%%%%%%% Code for > 10 arguments only %%%%%%%%%%%%%%%%%% @@ -8687,15 +8716,13 @@ might help (with 'rm \jobname.?? \jobname.??s')% \noexpand\expandafter \expandafter\noexpand\csname\the\macname @@\endcsname}% \expandafter\xdef\csname\the\macname @@\endcsname##1{% - \noexpand\passargtomacro - \expandafter\noexpand\csname\the\macname @@@\endcsname{##1,}}% + \noexpand\passargtomacro + \expandafter\noexpand\csname\the\macname @@@\endcsname{##1,}}% \expandafter\xdef\csname\the\macname @@@\endcsname##1{% - \expandafter\noexpand\csname\the\macname @@@@\endcsname ##1}% - \expandafter\expandafter - \expandafter\xdef - \expandafter\expandafter - \csname\the\macname @@@@\endcsname\paramlist{% - \endgroup\noexpand\scanmacro{\macrobody}}% + \expandafter\noexpand\csname\the\macname @@@@\endcsname ##1}% + \expandaftergroup{\expandafter\xdef\csname\the\macname @@@@\endcsname}% + \paramlist{% + \endgroup\noexpand\scanmacro{\macrobody}}% \else % 10 or more: \expandafter\xdef\csname\the\macname\endcsname{% \noexpand\getargvals@{\the\macname}{\argl}% @@ -8707,6 +8734,16 @@ might help (with 'rm \jobname.?? \jobname.??s')% \catcode `\@\texiatcatcode\relax % end private-to-Texinfo catcodes +% utility definition to avoid excessive use of \expandafter. call +% as \expandaftergroup{CONTENT}\WORD to expand \WORD exactly once and remove +% braces around CONTENT. +\def\expandaftergroup#1#2{% + \expandafter\expandaftergroupx\expandafter{#2}{#1}% +} +\def\expandaftergroupx#1#2{% + #2#1% +} + \def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} @@ -8876,9 +8913,8 @@ might help (with 'rm \jobname.?? \jobname.??s')% \expandafter\noexpand \csname\the\macname @@@\endcsname##1\noexpand\endlinemacro } - \expandafter\expandafter - \expandafter\xdef - \expandafter\expandafter\csname\the\macname @@@\endcsname\paramlist{% + \expandaftergroup{\expandafter\xdef\csname\the\macname @@@\endcsname}% + \paramlist{% \newlinechar=13 % split \macrobody into lines \noexpand\scantokens{\macrobody}% } @@ -8953,11 +8989,11 @@ might help (with 'rm \jobname.?? \jobname.??s')% \let\lastnode=\empty % Write a cross-reference definition for the current node. #1 is the -% type (Ynumbered, Yappendix, Ynothing). +% type (Ynumbered, Yappendix, Ynothing). #2 is the section title. % -\def\donoderef#1{% +\def\donoderef#1#2{% \ifx\lastnode\empty\else - \setref{\lastnode}{#1}% + \setref{\lastnode}{#1}{#2}% \global\let\lastnode=\empty \setnodeseenonce \fi @@ -8978,21 +9014,28 @@ might help (with 'rm \jobname.?? \jobname.??s')% % \def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} \def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} -\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} - -% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an -% anchor), which consists of three parts: -% 1) NAME-title - the current sectioning name taken from \currentsection, -% or the anchor name. -% 2) NAME-snt - section number and type, passed as the SNT arg, or -% empty for anchors. +\def\anchor#1{% + \savesf \setref{#1}{Yanchor}{#1}\restoresf \ignorespaces +} + +% @namedanchor{NAME, XREFNAME} -- define xref target at arbitrary point +% with label text for cross-references to it. +\def\namedanchor#1{\donamedanchor#1\finish}% +\def\donamedanchor#1,#2\finish{% + \savesf \setref{#1}{Yanchor}{\ignorespaces #2\unskip}\restoresf \ignorespaces +} + +% \setref{NAME}{SNT}{TITLE} defines a cross-reference point NAME (a node +% or an anchor), which consists of three parts: +% 1) NAME-title - the current sectioning name +% 2) NAME-snt - section number and type, passed as the SNT arg. % 3) NAME-pg - the page number. % % This is called from \donoderef, \anchor, and \dofloat. In the case of % floats, there is an additional part, which is not written here: % 4) NAME-lof - the text as it should appear in a @listoffloats. % -\def\setref#1#2{% +\def\setref#1#2#3{% \pdfmkdest{#1}% \iflinks {% @@ -9004,7 +9047,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef ##1}{##2}}% these are parameters of \writexrdef }% - \toks0 = \expandafter{\currentsection}% + \toks0 = {#3}% \immediate \writexrdef{title}{\the\toks0 }% \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc. \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout @@ -9058,15 +9101,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% \setbox\infofilenamebox = \hbox{\infofilename\unskip}% % \startxreflink{#1}{#4}% - {% - % Have to otherify everything special to allow the \csname to - % include an _ in the xref name, etc. - \indexnofonts - \turnoffactive - \def\value##1{##1}% - \expandafter\global\expandafter\let\expandafter\Xthisreftitle - \csname XR#1-title\endcsname - }% + \getrefx{#1-title}\Xthisreftitle % % Float references are printed completely differently: "Figure 1.2" % instead of "[somenode], p.3". \iffloat distinguishes them by @@ -9099,21 +9134,23 @@ might help (with 'rm \jobname.?? \jobname.??s')% % Cross-manual reference with a printed manual name. % \crossmanualxref{\cite{\printedmanual\unskip}}% - % \else\ifdim \wd\infofilenamebox > 0pt % Cross-manual reference with only an info filename (arg 4), no % printed manual name (arg 5). This is essentially the same as % the case above; we output the filename, since we have nothing else. % \crossmanualxref{\code{\infofilename\unskip}}% - % \else % Reference within this manual. % - % Only output a following space if the -snt ref is nonempty, as the ref - % will be empty for @unnumbered and @anchor. - \setbox2 = \hbox{\ignorespaces \refx{#1-snt}}% - \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi + % Only output a following space if the -snt ref is nonempty, as is + % the case for @unnumbered and @anchor. + \getrefx{#1-snt}\tmp + \ifx\tmp\empty\else + \ifx\tmp\Yanchor\else + \tmp\space + \fi + \fi % % output the `[mynode]' via the macro below so it can be overridden. \xrefprintnodename\printedrefname @@ -9169,7 +9206,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% \else % Otherwise just copy the Info node name. \def\printedrefname{\ignorespaces #1}% - \fi% + \fi \fi \fi \fi @@ -9201,7 +9238,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% \ifnum\filenamelength>0 goto file{\the\filename.pdf} name{\pdfdestname}% \else - goto name{\pdfmkpgn{\pdfdestname}}% + goto name{\pdfdestname}% \fi \else % XeTeX \ifnum\filenamelength>0 @@ -9281,6 +9318,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% % \def\Ynothing{} \def\Yomitfromtoc{} +\def\Yanchor{\isanchor} \let\isanchor\relax \def\Ynumbered{% \ifnum\secno=0 \putwordChapter@tie \the\chapno @@ -9307,14 +9345,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% % \refx{NAME} - reference a cross-reference string named NAME. \def\refx#1{% - \requireauxfile - {% - \indexnofonts - \turnoffactive - \def\value##1{##1}% - \expandafter\global\expandafter\let\expandafter\thisrefX - \csname XR#1\endcsname - }% + \getrefx{#1}\thisrefX \ifx\thisrefX\relax % If not defined, say something at least. \angleleft un\-de\-fined\angleright @@ -9335,6 +9366,17 @@ might help (with 'rm \jobname.?? \jobname.??s')% \fi } +% Set #2 to xref string #1 +\def\getrefx#1#2{% + \requireauxfile + {% + \indexnofonts + \turnoffactive + \def\value##1{##1}% + \expandafter\global\expandafter\let\expandafter#2\csname XR#1\endcsname + }% +} + % This is the macro invoked by entries in the aux file. Define a control % sequence for a cross-reference target (we prepend XR to the control sequence % name to avoid collisions). The value is the page number. If this is a float @@ -9399,12 +9441,14 @@ might help (with 'rm \jobname.?? \jobname.??s')% % Read the last existing aux file, if any. No error if none exists. % \def\tryauxfile{% + \ifxetex\xetexpreauxfile\fi \openin 1 \jobname.aux \ifeof 1 \else \readdatafile{aux}% \global\havexrefstrue \fi \closein 1 + \ifxetex\xetexpostauxfile\fi } \def\setupdatafile{% @@ -9790,14 +9834,15 @@ might help (with 'rm \jobname.?? \jobname.??s')% \global\advance\floatno by 1 % {% - % This magic value for \currentsection is output by \setref as the - % XREFLABEL-title value. \xrefX uses it to distinguish float + % This magic value for the third argument of \setref is output as + % the XREFLABEL-title value. \xrefX uses it to distinguish float % labels (which have a completely different output format) from % node and anchor labels. And \xrdef uses it to construct the % lists of floats. % - \edef\currentsection{\floatmagic=\safefloattype}% - \setref{\floatlabel}{Yfloat}% + \edef\tmp{\noexpand\setref{\floatlabel}{Yfloat}% + {\floatmagic=\safefloattype}}% + \tmp }% \fi % @@ -9919,7 +9964,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% % #1 is the control sequence we are passed; we expand into a conditional % which is true if #1 represents a float ref. That is, the magic -% \currentsection value which we \setref above. +% value which we passed to \setref above. % \def\iffloat#1{\expandafter\doiffloat#1==\finish} % @@ -9976,6 +10021,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% \toksA = \expandafter{\csname XR#1-lof\endcsname}% % % use the same \entry macro we use to generate the TOC and index. + \let\entry\entryinternal \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}% \writeentry }} @@ -10071,17 +10117,24 @@ directory should work if nowhere else does.} \fi \fi +\let\xetexpreauxfile\relax +\let\xetexpostauxfile\relax + % Set I/O by bytes instead of UTF-8 sequence for XeTeX and LuaTex % for non-UTF-8 (byte-wise) encodings. % \def\setbytewiseio{% \ifxetex - \XeTeXdefaultencoding "bytes" % For subsequent files to be read - \XeTeXinputencoding "bytes" % For document root file - % Unfortunately, there seems to be no corresponding XeTeX command for - % output encoding. This is a problem for auxiliary index and TOC files. - % The only solution would be perhaps to write out @U{...} sequences in - % place of non-ASCII characters. + % For document root file + \XeTeXinputencoding "bytes" + % + % Setting for subsequent files to be read with @include. + \XeTeXdefaultencoding "bytes" + % + % Use UTF-8 for reading auxiliary index and TOC files, which are + % always output in UTF-8 with XeTeX. + \def\xetexpreauxfile{\XeTeXdefaultencoding "UTF-8"}% + \def\xetexpostauxfile{\XeTeXdefaultencoding "bytes"}% \fi \ifluatex @@ -10713,12 +10766,12 @@ directory should work if nowhere else does.} % Suppress ligature creation from adjacent characters. \ifluatex - \def\nolig{{}} -\else % Braces do not suppress ligature creation in LuaTeX, e.g. in of{}fice % to suppress the "ff" ligature. Using a kern appears to be the only % workaround. \def\nolig{\kern0pt{}} +\else + \def\nolig{{}} \fi % https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_M diff --git a/source/configure b/source/configure index 5c27356634e90ed6e6292bcfd1dd65bde829318c..330d813b53a51663c64559fe45f71d9ca65b248b 100755 --- a/source/configure +++ b/source/configure @@ -813,6 +813,23 @@ enable_native_texlive_build enable_multiplatform enable_cxx_runtime_hack enable_libtool_hack +enable_autosp +enable_axodraw2 +enable_devnag +enable_lacheck +enable_m_tx +enable_pmx +enable_ps2eps +enable_t1utils +enable_texdoctk +enable_tpic2pdftex +enable_vlna +enable_xindy +enable_xindy_rules +enable_xindy_docs +with_clisp_runtime +enable_xml2pmx +enable_xpdfopen enable_web2c with_banner_add with_editor @@ -860,16 +877,88 @@ enable_tektronixwin enable_unitermwin enable_web_progs enable_synctex +enable_afm2pl +enable_bibtex_x +enable_bibtex8 +enable_bibtexu +enable_chktex +enable_cjkutils +enable_detex +enable_dtl +enable_dvi2tty +enable_dvidvi +enable_dviljk +enable_dviout_util +enable_dvipdfm_x +enable_dvipng +enable_debug +enable_timing +with_gs +enable_dvipos +enable_dvipsk +enable_dvisvgm +enable_gregorio +enable_gsftopk +enable_lcdf_typetools +enable_cfftot1 +enable_mmafm +enable_mmpfb +enable_otfinfo +enable_otftotfm +enable_t1dotlessj +enable_t1lint +enable_t1rawafm +enable_t1reencode +enable_t1testpage +enable_ttftotype42 +enable_updmap +enable_makeindexk +enable_makejvf +enable_mendexk +enable_musixtnt +enable_ps2pk +enable_psutils +enable_seetexk +enable_tex4htk +enable_ttf2pk2 +enable_ttfdump +enable_upmendex +enable_xdvik +with_xdvi_x_toolkit enable_texlive enable_linked_scripts with_system_harfbuzz +with_system_icu +with_system_teckit with_system_graphite2 with_system_zziplib +with_system_mpfi +with_mpfi_includes +with_mpfi_libdir +with_system_mpfr +with_mpfr_includes +with_mpfr_libdir +with_system_gmp +with_gmp_includes +with_gmp_libdir +with_system_cairo +with_system_pixman +with_system_gd +with_gd_includes +with_gd_libdir +with_system_potrace +with_potrace_includes +with_potrace_libdir +with_system_freetype2 with_system_libpng +with_system_libpaper +with_libpaper_includes +with_libpaper_libdir with_system_luajit with_system_zlib with_zlib_includes with_zlib_libdir +with_system_ptexenc with_system_kpathsea enable_mktexmf_default enable_mktexpk_default @@ -1552,6 +1641,22 @@ Optional Features: lib/PLATFORM --enable-cxx-runtime-hack link C++ runtime statically --enable-libtool-hack ignore libtool dependency_libs + --disable-autosp do not build the autosp package + --disable-axodraw2 do not build the axodraw2 package + --disable-devnag do not build the devnag package + --disable-lacheck do not build the lacheck package + --disable-m-tx do not build the m-tx package + --disable-pmx do not build the pmx package + --disable-ps2eps do not build the ps2eps package + --disable-t1utils do not build the t1utils package + --disable-texdoctk do not build the texdoctk package + --disable-tpic2pdftex do not build the tpic2pdftex package + --disable-vlna do not build the vlna package + --enable-xindy build the xindy package + --enable-xindy-rules build and install make-rules package + --enable-xindy-docs build and install documentation + --disable-xml2pmx do not build the xml2pmx package + --disable-xpdfopen do not build the xpdfopen package --disable-web2c do not build the web2c (TeX & Co.) package --enable-auto-core cause TeX&MF to dump core, given a certain filename @@ -1599,6 +1704,57 @@ Optional Features: --enable-unitermwin include Uniterm window support --disable-web-progs do not build WEB programs bibtex ... weave --disable-synctex do not build the SyncTeX library and tool + --disable-afm2pl do not build the afm2pl package + --disable-bibtex-x do not build the bibtex-x package + --disable-bibtex8 do not build the bibtex8 program + --disable-bibtexu do not build the bibtexu program + --disable-chktex do not build the chktex package + --disable-cjkutils do not build the cjkutils package + --disable-detex do not build the detex package + --disable-dtl do not build the dtl package + --disable-dvi2tty do not build the dvi2tty package + --disable-dvidvi do not build the dvidvi package + --disable-dviljk do not build the dviljk package + --disable-dviout-util do not build the dviout-util package + --disable-dvipdfm-x do not build the dvipdfm-x package + --disable-dvipng do not build the dvipng package + --disable-debug Compile without debug (-d) option + --enable-timing Output execution time of dvipng + --disable-dvipos do not build the dvipos package + --disable-dvipsk do not build the dvipsk package + --disable-dvisvgm do not build the dvisvgm package + --disable-gregorio do not build the gregorio package + --disable-gsftopk do not build the gsftopk package + --disable-lcdf-typetools + do not build the lcdf-typetools package + --disable-cfftot1 do not build the cfftot1 program + --disable-mmafm do not build the mmafm program + --disable-mmpfb do not build the mmpfb program + --disable-otfinfo do not build the otfinfo program + --disable-otftotfm do not build the otftotfm program + --disable-t1dotlessj do not build the t1dotlessj program + --disable-t1lint do not build the t1lint program + --disable-t1rawafm do not build the t1rawafm program + --disable-t1reencode do not build the t1reencode program + --disable-t1testpage do not build the t1testpage program + --disable-ttftotype42 do not build the ttftotype42 program + --disable-auto-cfftot1 disable running cfftot1 from otftotfm + --disable-auto-t1dotlessj disable running t1dotlessj from otftotfm + --disable-auto-ttftotype42 + disable running ttftotype42 from otftotfm + --disable-auto-updmap disable running updmap from otftotfm + --disable-makeindexk do not build the makeindexk package + --disable-makejvf do not build the makejvf package + --disable-mendexk do not build the mendexk package + --disable-musixtnt do not build the musixtnt package + --disable-ps2pk do not build the ps2pk package + --disable-psutils do not build the psutils package + --disable-seetexk do not build the seetexk package + --disable-tex4htk do not build the tex4htk package + --disable-ttf2pk2 do not build the ttf2pk2 package + --disable-ttfdump do not build the ttfdump package + --disable-upmendex do not build the upmendex package + --disable-xdvik do not build the xdvik package --disable-texlive do not build the texlive (TeX Live scripts) package --disable-linked-scripts do not install the linked scripts --disable-mktexmf-default do not run mktexmf if MF source missing @@ -1636,24 +1792,68 @@ Optional Features: Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-clisp-runtime=PATH + pathname of clisp runtime to install for `xindy', + `default' to derive from clisp, or `system' to use + installed version --with-banner-add=STR add STR to version string appended to banner lines --with-editor=CMD invoke CMD from the `e' option [vi +%d '%s'] or [texworks --position=%d "%s"] --with-mf-x-toolkit use X toolkit for METAFONT + --with-gs=/PATH/TO/gs Hard-wire the location of GhostScript + --with-xdvi-x-toolkit=KIT + Use toolkit KIT (xaw/motif/xaw3d/neXtaw) for xdvi + [default: Xaw] --with-system-harfbuzz use installed harfbuzz headers and library (requires pkg-config) + --with-system-icu use installed ICU headers and libraries (requires + pkg-config or icu-config) + --with-system-teckit use installed teckit headers and library (requires + pkg-config) --with-system-graphite2 use installed graphite2 headers and library (requires pkg-config) --with-system-zziplib use installed zziplib headers and library (requires pkg-config) + --with-system-mpfi use installed mpfi headers and library + --with-mpfi-includes=DIR + mpfi headers installed in DIR + --with-mpfi-libdir=DIR mpfi library installed in DIR + --with-system-mpfr use installed mpfr headers and library + --with-mpfr-includes=DIR + mpfr headers installed in DIR + --with-mpfr-libdir=DIR mpfr library installed in DIR + --with-system-gmp use installed gmp headers and library + --with-gmp-includes=DIR gmp headers installed in DIR + --with-gmp-libdir=DIR gmp library installed in DIR + --with-system-cairo use installed cairo headers and library (requires + pkg-config) + --with-system-pixman use installed pixman headers and library (requires + pkg-config) + --with-system-gd use installed gd headers and library + --with-gd-includes=DIR gd headers installed in DIR + --with-gd-libdir=DIR gd library installed in DIR + --with-system-potrace use installed potrace headers and library + --with-potrace-includes=DIR + potrace headers installed in DIR + --with-potrace-libdir=DIR + potrace library installed in DIR + --with-system-freetype2 use installed freetype2 headers and library + (requires freetype-config) --with-system-libpng use installed libpng headers and library (requires pkg-config) + --with-system-libpaper use installed libpaper headers and library + --with-libpaper-includes=DIR + libpaper headers installed in DIR + --with-libpaper-libdir=DIR + libpaper library installed in DIR --with-system-luajit use installed luajit headers and library (requires pkg-config) --with-system-zlib use installed zlib headers and library --with-zlib-includes=DIR zlib headers installed in DIR --with-zlib-libdir=DIR zlib library installed in DIR + --with-system-ptexenc use installed ptexenc headers and library (requires + pkg-config) --with-system-kpathsea use installed kpathsea headers and library (requires pkg-config) --with-gnu-ld assume the C compiler uses GNU ld [default=no] @@ -5065,6 +5265,333 @@ printf "%s\n" "$as_me: $host -> \`--disable-mfluajit-nowin'" >&6;} esac ;; esac +## utils/autosp/ac/withenable.ac: configure.ac fragment for Tl subdir +## configure options and TL libraries required for autosp. +# Check whether --enable-autosp was given. +if test ${enable_autosp+y} +then : + enableval=$enable_autosp; +fi +case $enable_autosp in #( + yes|no) : + ;; #( + *) : + + enable_autosp=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-autosp=$enable_autosp'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-autosp=$enable_autosp'" >&6;} + ac_configure_args="$ac_configure_args '--enable-autosp=$enable_autosp'" + ;; +esac + +## utils/axodraw2/ac/withenable.ac: configure.ac fragment for TL subdir +## configure options and TL libraries for axodraw2. +# Check whether --enable-axodraw2 was given. +if test ${enable_axodraw2+y} +then : + enableval=$enable_axodraw2; +fi +case $enable_axodraw2 in #( + yes|no) : + ;; #( + *) : + + enable_axodraw2=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-axodraw2=$enable_axodraw2'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-axodraw2=$enable_axodraw2'" >&6;} + ac_configure_args="$ac_configure_args '--enable-axodraw2=$enable_axodraw2'" + ;; +esac + +## utils/devnag/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/devnag/ +## configure options and TL libraries required for devnag +# Check whether --enable-devnag was given. +if test ${enable_devnag+y} +then : + enableval=$enable_devnag; +fi +case $enable_devnag in #( + yes|no) : + ;; #( + *) : + + enable_devnag=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-devnag=$enable_devnag'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-devnag=$enable_devnag'" >&6;} + ac_configure_args="$ac_configure_args '--enable-devnag=$enable_devnag'" + ;; +esac + +## utils/lacheck/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/lacheck/ +## configure options and TL libraries required for lacheck +# Check whether --enable-lacheck was given. +if test ${enable_lacheck+y} +then : + enableval=$enable_lacheck; +fi +case $enable_lacheck in #( + yes|no) : + ;; #( + *) : + + enable_lacheck=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-lacheck=$enable_lacheck'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-lacheck=$enable_lacheck'" >&6;} + ac_configure_args="$ac_configure_args '--enable-lacheck=$enable_lacheck'" + ;; +esac + +## utils/m-tx/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/m-tx/ +## configure options and TL libraries required for mtx +# Check whether --enable-m-tx was given. +if test ${enable_m_tx+y} +then : + enableval=$enable_m_tx; +fi +case $enable_m_tx in #( + yes|no) : + ;; #( + *) : + + enable_m_tx=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-m-tx=$enable_m_tx'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-m-tx=$enable_m_tx'" >&6;} + ac_configure_args="$ac_configure_args '--enable-m-tx=$enable_m_tx'" + ;; +esac + +## utils/pmx/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/pmx/ +## configure options and TL libraries required for pmx +# Check whether --enable-pmx was given. +if test ${enable_pmx+y} +then : + enableval=$enable_pmx; +fi +case $enable_pmx in #( + yes|no) : + ;; #( + *) : + + enable_pmx=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-pmx=$enable_pmx'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-pmx=$enable_pmx'" >&6;} + ac_configure_args="$ac_configure_args '--enable-pmx=$enable_pmx'" + ;; +esac + +## utils/ps2eps/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/ps2eps/ +## configure options and TL libraries required for ps2eps +# Check whether --enable-ps2eps was given. +if test ${enable_ps2eps+y} +then : + enableval=$enable_ps2eps; +fi +case $enable_ps2eps in #( + yes|no) : + ;; #( + *) : + + enable_ps2eps=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-ps2eps=$enable_ps2eps'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-ps2eps=$enable_ps2eps'" >&6;} + ac_configure_args="$ac_configure_args '--enable-ps2eps=$enable_ps2eps'" + ;; +esac + +## utils/t1utils/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/t1utils/ +## configure options and TL libraries required for t1utils +# Check whether --enable-t1utils was given. +if test ${enable_t1utils+y} +then : + enableval=$enable_t1utils; +fi +case $enable_t1utils in #( + yes|no) : + ;; #( + *) : + + enable_t1utils=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-t1utils=$enable_t1utils'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-t1utils=$enable_t1utils'" >&6;} + ac_configure_args="$ac_configure_args '--enable-t1utils=$enable_t1utils'" + ;; +esac + +## utils/texdoctk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/texdoctk/ +## configure options and TL libraries required for texdoctk +# Check whether --enable-texdoctk was given. +if test ${enable_texdoctk+y} +then : + enableval=$enable_texdoctk; +fi +case $enable_texdoctk in #( + yes|no) : + ;; #( + *) : + + enable_texdoctk=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-texdoctk=$enable_texdoctk'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-texdoctk=$enable_texdoctk'" >&6;} + ac_configure_args="$ac_configure_args '--enable-texdoctk=$enable_texdoctk'" + ;; +esac + +## utils/tpic2pdftex/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/tpic2pdftex/ +## configure options and TL libraries required for tpic2pdftex +# Check whether --enable-tpic2pdftex was given. +if test ${enable_tpic2pdftex+y} +then : + enableval=$enable_tpic2pdftex; +fi +case $enable_tpic2pdftex in #( + yes|no) : + ;; #( + *) : + + enable_tpic2pdftex=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-tpic2pdftex=$enable_tpic2pdftex'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-tpic2pdftex=$enable_tpic2pdftex'" >&6;} + ac_configure_args="$ac_configure_args '--enable-tpic2pdftex=$enable_tpic2pdftex'" + ;; +esac + +## utils/vlna/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/vlna/ +## configure options and TL libraries required for vlna +# Check whether --enable-vlna was given. +if test ${enable_vlna+y} +then : + enableval=$enable_vlna; +fi +case $enable_vlna in #( + yes|no) : + ;; #( + *) : + + enable_vlna=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-vlna=$enable_vlna'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-vlna=$enable_vlna'" >&6;} + ac_configure_args="$ac_configure_args '--enable-vlna=$enable_vlna'" + ;; +esac + +## utils/xindy/ac/withenable.ac: configure.ac fragment for TL subdir +## configure options and TL libraries required for xindy. +# Check whether --enable-xindy was given. +if test ${enable_xindy+y} +then : + enableval=$enable_xindy; +fi +case $enable_xindy in #( + yes|no) : + ;; #( + *) : + + enable_xindy=no + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-xindy=$enable_xindy'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-xindy=$enable_xindy'" >&6;} + ac_configure_args="$ac_configure_args '--enable-xindy=$enable_xindy'" + ;; +esac + +## utils/xindy/ac/xindy.ac: configure.ac fragment for the TeX Live subdirectory utils/xindy/ +## configure options for xindy +# Check whether --enable-xindy-rules was given. +if test ${enable_xindy_rules+y} +then : + enableval=$enable_xindy_rules; +fi +# Check whether --enable-xindy-docs was given. +if test ${enable_xindy_docs+y} +then : + enableval=$enable_xindy_docs; +fi + +# Check whether --with-clisp-runtime was given. +if test ${with_clisp_runtime+y} +then : + withval=$with_clisp_runtime; +fi + +## utils/xindy/ac/clisp.ac: configure.ac fragment for the TeX Live subdirectory utils/xindy/ +## configure checks for xindy and clisp +case $with_clisp_runtime in #( + default) : + ;; #( + system) : + if test "x$enable_native_texlive_build" = xyes +then : + as_fn_error $? "you can not use the installed clisp for a native TeX Live build" "$LINENO" 5 +fi ;; #( + "") : + if test "x$enable_native_texlive_build" = xyes +then : + with_clisp_runtime=default +else case e in #( + e) with_clisp_runtime=system ;; +esac +fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--with-clisp-runtime=$with_clisp_runtime'" >&5 +printf "%s\n" "$as_me: Assuming \`--with-clisp-runtime=$with_clisp_runtime'" >&6;} + ac_configure_args="$ac_configure_args '--with-clisp-runtime=$with_clisp_runtime'" ;; #( + *) : + if test ! -f "$with_clisp_runtime" +then : + as_fn_error $? "no such file: \"$with_clisp_runtime\"" "$LINENO" 5 +fi ;; +esac + +## utils/xml2pmx/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/xml2pmx/ +## configure options and TL libraries required for xml2pmx +# Check whether --enable-xml2pmx was given. +if test ${enable_xml2pmx+y} +then : + enableval=$enable_xml2pmx; +fi +case $enable_xml2pmx in #( + yes|no) : + ;; #( + *) : + + enable_xml2pmx=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-xml2pmx=$enable_xml2pmx'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-xml2pmx=$enable_xml2pmx'" >&6;} + ac_configure_args="$ac_configure_args '--enable-xml2pmx=$enable_xml2pmx'" + ;; +esac + +## utils/xpdfopen/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/xpdfopen/ +## configure options and TL libraries required for xpdfopen +# Check whether --enable-xpdfopen was given. +if test ${enable_xpdfopen+y} +then : + enableval=$enable_xpdfopen; +fi +if test "x$with_x" = xno +then : + case $enable_xpdfopen in #( + "") : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \`--without-x' -> \`--disable-xpdfopen'" >&5 +printf "%s\n" "$as_me: \`--without-x' -> \`--disable-xpdfopen'" >&6;} + enable_xpdfopen=no + ac_configure_args="$ac_configure_args '--disable-xpdfopen'" ;; #( + yes) : + as_fn_error $? "Sorry, incompatible options \`--without-x' and \`--enable-xpdfopen'" "$LINENO" 5 ;; #( + *) : + ;; +esac +fi +case $enable_xpdfopen in #( + yes|no) : + ;; #( + *) : + + enable_xpdfopen=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-xpdfopen=$enable_xpdfopen'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-xpdfopen=$enable_xpdfopen'" >&6;} + ac_configure_args="$ac_configure_args '--enable-xpdfopen=$enable_xpdfopen'" + ;; +esac + ## texk/web2c/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/web2c/ ## configure options and TL libraries required for web2c @@ -5579,475 +6106,1919 @@ then : fi -## texk/texlive/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/texlive/ -## configure options and TL libraries required for texlive -# Check whether --enable-texlive was given. -if test ${enable_texlive+y} +## texk/afm2pl/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/afm2pl/ +## configure options and TL libraries required for afm2pl +# Check whether --enable-afm2pl was given. +if test ${enable_afm2pl+y} then : - enableval=$enable_texlive; + enableval=$enable_afm2pl; fi -case $enable_texlive in #( +case $enable_afm2pl in #( yes|no) : ;; #( *) : - enable_texlive=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-texlive=$enable_texlive'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-texlive=$enable_texlive'" >&6;} - ac_configure_args="$ac_configure_args '--enable-texlive=$enable_texlive'" + enable_afm2pl=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-afm2pl=$enable_afm2pl'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-afm2pl=$enable_afm2pl'" >&6;} + ac_configure_args="$ac_configure_args '--enable-afm2pl=$enable_afm2pl'" ;; esac -## texk/texlive/ac/texlive.ac: configure.ac fragment for the TeX Live subdirectory texk/texlive/ -## configure options for texlive -# Check whether --enable-linked-scripts was given. -if test ${enable_linked_scripts+y} +test "x$enable_afm2pl" = xno || { + need_kpathsea=yes +} + +## texk/bibtex-x/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/bibtex-x/ +## configure options and TL libraries required for bibtex-x +# Check whether --enable-bibtex-x was given. +if test ${enable_bibtex_x+y} then : - enableval=$enable_linked_scripts; + enableval=$enable_bibtex_x; fi +case $enable_bibtex_x in #( + yes|no) : + ;; #( + *) : + enable_bibtex_x=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-bibtex-x=$enable_bibtex_x'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-bibtex-x=$enable_bibtex_x'" >&6;} + ac_configure_args="$ac_configure_args '--enable-bibtex-x=$enable_bibtex_x'" + ;; +esac -## libs/pplib/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/pplib/ -## configure options and TL libraries required for pplib - -test "x$need_pplib" = xyes && { - need_zlib=yes +test "x$enable_bibtex_x" = xno || { + need_kpathsea=yes } -## libs/harfbuzz/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/harfbuzz/ -## configure options and TL libraries required for harfbuzz - -# Check whether --with-system-harfbuzz was given. -if test ${with_system_harfbuzz+y} +## texk/bibtex-x/ac/bibtex-x.ac: configure.ac fragment for the TeX Live subdirectory texk/bibtex-x/ +## configure options for bibtex-x +# Check whether --enable-bibtex8 was given. +if test ${enable_bibtex8+y} then : - withval=$with_system_harfbuzz; -fi -if test "x$with_system_harfbuzz" = x; then - if test -f $srcdir/libs/harfbuzz/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`harfbuzz' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`harfbuzz' headers and library from TL tree" >&6;} - with_system_harfbuzz=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`harfbuzz' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`harfbuzz' headers and library" >&6;} - with_system_harfbuzz=yes - fi - ac_configure_args="$ac_configure_args '--with-system-harfbuzz=$with_system_harfbuzz'" -elif test "x$with_system_harfbuzz" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`harfbuzz' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`harfbuzz' headers and library" >&6;} -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`harfbuzz' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`harfbuzz' headers and library from TL tree" >&6;} - if test "x$with_system_harfbuzz" != xno; then - with_system_harfbuzz=no - ac_configure_args="$ac_configure_args '--without-system-harfbuzz'" - fi + enableval=$enable_bibtex8; fi -if test "x$with_system_harfbuzz" = xyes; then - if test "x$with_system_graphite2" = x; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`graphite2' headers and library" >&5 -printf "%s\n" "$as_me: -> installed \`graphite2' headers and library" >&6;} - with_system_graphite2=yes - ac_configure_args="$ac_configure_args '--with-system-graphite2'" - elif test "x$with_system_graphite2" != xyes; then - as_fn_error $? "Sorry, \`--with-system-harfbuzz' requires \`--with-system-graphite2'" "$LINENO" 5 - fi - if test "x$with_system_icu" = x; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`icu' headers and library" >&5 -printf "%s\n" "$as_me: -> installed \`icu' headers and library" >&6;} - with_system_icu=yes - ac_configure_args="$ac_configure_args '--with-system-icu'" - elif test "x$with_system_icu" != xyes; then - as_fn_error $? "Sorry, \`--with-system-harfbuzz' requires \`--with-system-icu'" "$LINENO" 5 - fi + +case $enable_bibtex8 in #( + yes | no) : + ;; #( + *) : + enable_bibtex8=yes ;; +esac +# Check whether --enable-bibtexu was given. +if test ${enable_bibtexu+y} +then : + enableval=$enable_bibtexu; fi -test "x$need_harfbuzz" = xyes && { - need_graphite2=yes - need_icu=yes -} +case $enable_bibtexu in #( + yes | no) : + ;; #( + *) : + enable_bibtexu=yes ;; +esac -## libs/graphite2/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/graphite2/ -## configure options and TL libraries required for graphite2 +test "x$enable_bibtex_x:$enable_bibtexu" = xyes:yes && need_icu=yes -# Check whether --with-system-graphite2 was given. -if test ${with_system_graphite2+y} +## texk/chktex/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/chktex/ +## configure options and TL libraries required for chktex +# Check whether --enable-chktex was given. +if test ${enable_chktex+y} then : - withval=$with_system_graphite2; -fi -if test "x$with_system_graphite2" = x; then - if test -f $srcdir/libs/graphite2/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`graphite2' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`graphite2' headers and library from TL tree" >&6;} - with_system_graphite2=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`graphite2' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`graphite2' headers and library" >&6;} - with_system_graphite2=yes - fi - ac_configure_args="$ac_configure_args '--with-system-graphite2=$with_system_graphite2'" -elif test "x$with_system_graphite2" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`graphite2' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`graphite2' headers and library" >&6;} -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`graphite2' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`graphite2' headers and library from TL tree" >&6;} - if test "x$with_system_graphite2" != xno; then - with_system_graphite2=no - ac_configure_args="$ac_configure_args '--without-system-graphite2'" - fi + enableval=$enable_chktex; fi +case $enable_chktex in #( + yes|no) : + ;; #( + *) : -## libs/zziplib/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/zziplib/ -## configure options and TL libraries required for zziplib + enable_chktex=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-chktex=$enable_chktex'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-chktex=$enable_chktex'" >&6;} + ac_configure_args="$ac_configure_args '--enable-chktex=$enable_chktex'" + ;; +esac -# Check whether --with-system-zziplib was given. -if test ${with_system_zziplib+y} +test "x$enable_chktex" = xno || { + need_kpathsea=yes +} + +## texk/cjkutils/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/cjkutils/ +## configure options and TL libraries required for cjkutils +# Check whether --enable-cjkutils was given. +if test ${enable_cjkutils+y} then : - withval=$with_system_zziplib; -fi -if test "x$with_system_zziplib" = x; then - if test -f $srcdir/libs/zziplib/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`zziplib' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`zziplib' headers and library from TL tree" >&6;} - with_system_zziplib=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`zziplib' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`zziplib' headers and library" >&6;} - with_system_zziplib=yes - fi - ac_configure_args="$ac_configure_args '--with-system-zziplib=$with_system_zziplib'" -elif test "x$with_system_zziplib" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`zziplib' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`zziplib' headers and library" >&6;} -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`zziplib' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`zziplib' headers and library from TL tree" >&6;} - if test "x$with_system_zziplib" != xno; then - with_system_zziplib=no - ac_configure_args="$ac_configure_args '--without-system-zziplib'" - fi -fi -if test "x$with_system_zziplib" = xyes; then - if test "x$with_system_zlib" = x; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`zlib' headers and library" >&5 -printf "%s\n" "$as_me: -> installed \`zlib' headers and library" >&6;} - with_system_zlib=yes - ac_configure_args="$ac_configure_args '--with-system-zlib'" - elif test "x$with_system_zlib" != xyes; then - as_fn_error $? "Sorry, \`--with-system-zziplib' requires \`--with-system-zlib'" "$LINENO" 5 - fi + enableval=$enable_cjkutils; fi +case $enable_cjkutils in #( + yes|no) : + ;; #( + *) : -test "x$need_zziplib" = xyes && { - need_zlib=yes -} + enable_cjkutils=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-cjkutils=$enable_cjkutils'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-cjkutils=$enable_cjkutils'" >&6;} + ac_configure_args="$ac_configure_args '--enable-cjkutils=$enable_cjkutils'" + ;; +esac -## libs/libpng/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/libpng/ -## configure options and TL libraries required for libpng +test "x$enable_cjkutils" = xno || { + need_kpathsea=yes +} -# Check whether --with-system-libpng was given. -if test ${with_system_libpng+y} +## texk/detex/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/detex/ +## configure options and TL libraries required for detex +# Check whether --enable-detex was given. +if test ${enable_detex+y} then : - withval=$with_system_libpng; + enableval=$enable_detex; fi -if test "x$with_system_libpng" = x; then - if test -f $srcdir/libs/libpng/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`libpng' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`libpng' headers and library from TL tree" >&6;} - with_system_libpng=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`libpng' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`libpng' headers and library" >&6;} - with_system_libpng=yes - fi - ac_configure_args="$ac_configure_args '--with-system-libpng=$with_system_libpng'" -elif test "x$with_system_libpng" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`libpng' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`libpng' headers and library" >&6;} -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`libpng' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`libpng' headers and library from TL tree" >&6;} - if test "x$with_system_libpng" != xno; then - with_system_libpng=no - ac_configure_args="$ac_configure_args '--without-system-libpng'" - fi +case $enable_detex in #( + yes|no) : + ;; #( + *) : + + enable_detex=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-detex=$enable_detex'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-detex=$enable_detex'" >&6;} + ac_configure_args="$ac_configure_args '--enable-detex=$enable_detex'" + ;; +esac + +test "x$enable_detex" = xno || { + need_kpathsea=yes +} + +## texk/dtl/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dtl/ +## configure options and TL libraries required for dtl +# Check whether --enable-dtl was given. +if test ${enable_dtl+y} +then : + enableval=$enable_dtl; fi -if test "x$with_system_libpng" = xyes; then - if test "x$with_system_zlib" = x; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`zlib' headers and library" >&5 -printf "%s\n" "$as_me: -> installed \`zlib' headers and library" >&6;} - with_system_zlib=yes - ac_configure_args="$ac_configure_args '--with-system-zlib'" - elif test "x$with_system_zlib" != xyes; then - as_fn_error $? "Sorry, \`--with-system-libpng' requires \`--with-system-zlib'" "$LINENO" 5 - fi +case $enable_dtl in #( + yes|no) : + ;; #( + *) : + + enable_dtl=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dtl=$enable_dtl'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-dtl=$enable_dtl'" >&6;} + ac_configure_args="$ac_configure_args '--enable-dtl=$enable_dtl'" + ;; +esac + +test "x$enable_dtl" = xno || { + need_kpathsea=yes +} + +## texk/dvi2tty/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvi2tty/ +## configure options and TL libraries required for dvi2tty +# Check whether --enable-dvi2tty was given. +if test ${enable_dvi2tty+y} +then : + enableval=$enable_dvi2tty; fi +case $enable_dvi2tty in #( + yes|no) : + ;; #( + *) : -test "x$need_libpng" = xyes && { - need_zlib=yes + enable_dvi2tty=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvi2tty=$enable_dvi2tty'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-dvi2tty=$enable_dvi2tty'" >&6;} + ac_configure_args="$ac_configure_args '--enable-dvi2tty=$enable_dvi2tty'" + ;; +esac + +test "x$enable_dvi2tty" = xno || { + need_ptexenc=yes } -## libs/luajit/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/luajit/ -## configure options and TL libraries required for luajit +## texk/dvidvi/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvidvi/ +## configure options and TL libraries required for dvidvi +# Check whether --enable-dvidvi was given. +if test ${enable_dvidvi+y} +then : + enableval=$enable_dvidvi; +fi +case $enable_dvidvi in #( + yes|no) : + ;; #( + *) : -# Check whether --with-system-luajit was given. -if test ${with_system_luajit+y} + enable_dvidvi=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvidvi=$enable_dvidvi'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-dvidvi=$enable_dvidvi'" >&6;} + ac_configure_args="$ac_configure_args '--enable-dvidvi=$enable_dvidvi'" + ;; +esac + +test "x$enable_dvidvi" = xno || { + need_kpathsea=yes +} + +## texk/dviljk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dviljk/ +## configure options and TL libraries required for dviljk +# Check whether --enable-dviljk was given. +if test ${enable_dviljk+y} then : - withval=$with_system_luajit; + enableval=$enable_dviljk; fi -if test "x$with_system_luajit" = x; then - if test -f $srcdir/libs/luajit/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`luajit' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`luajit' headers and library from TL tree" >&6;} - with_system_luajit=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`luajit' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`luajit' headers and library" >&6;} - with_system_luajit=yes - fi - ac_configure_args="$ac_configure_args '--with-system-luajit=$with_system_luajit'" -elif test "x$with_system_luajit" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`luajit' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`luajit' headers and library" >&6;} -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`luajit' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`luajit' headers and library from TL tree" >&6;} - if test "x$with_system_luajit" != xno; then - with_system_luajit=no - ac_configure_args="$ac_configure_args '--without-system-luajit'" - fi +case $enable_dviljk in #( + yes|no) : + ;; #( + *) : + + enable_dviljk=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dviljk=$enable_dviljk'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-dviljk=$enable_dviljk'" >&6;} + ac_configure_args="$ac_configure_args '--enable-dviljk=$enable_dviljk'" + ;; +esac + +test "x$enable_dviljk" = xno || { + need_kpathsea=yes +} + +## texk/dviout-util/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dviout-util/ +## configure options and TL libraries required for dviout-util +# Check whether --enable-dviout-util was given. +if test ${enable_dviout_util+y} +then : + enableval=$enable_dviout_util; fi +case $enable_dviout_util in #( + yes|no) : + ;; #( + *) : -## libs/lua53/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/lua53/ -## configure options and TL libraries required for lua53 + enable_dviout_util=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dviout-util=$enable_dviout_util'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-dviout-util=$enable_dviout_util'" >&6;} + ac_configure_args="$ac_configure_args '--enable-dviout-util=$enable_dviout_util'" + ;; +esac -## libs/zlib/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/zlib/ -## configure options and TL libraries required for zlib +test "x$enable_dviout_util" = xno || { + need_ptexenc=yes +} -# Check whether --with-system-zlib was given. -if test ${with_system_zlib+y} +## texk/dvipdfm-x/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipdfm-x/ +## configure options and TL libraries required for dvipdfm-x +# Check whether --enable-dvipdfm-x was given. +if test ${enable_dvipdfm_x+y} then : - withval=$with_system_zlib; + enableval=$enable_dvipdfm_x; fi +case $enable_dvipdfm_x in #( + yes|no) : + ;; #( + *) : -# Check whether --with-zlib-includes was given. -if test ${with_zlib_includes+y} + enable_dvipdfm_x=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvipdfm-x=$enable_dvipdfm_x'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-dvipdfm-x=$enable_dvipdfm_x'" >&6;} + ac_configure_args="$ac_configure_args '--enable-dvipdfm-x=$enable_dvipdfm_x'" + ;; +esac + +test "x$enable_dvipdfm_x" = xno || { + need_kpathsea=yes + need_libpng=yes + need_libpaper=yes +} + +## texk/dvipng/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipng/ +## configure options and TL libraries required for dvipng +# Check whether --enable-dvipng was given. +if test ${enable_dvipng+y} then : - withval=$with_zlib_includes; + enableval=$enable_dvipng; fi +case $enable_dvipng in #( + yes|no) : + ;; #( + *) : -# Check whether --with-zlib-libdir was given. -if test ${with_zlib_libdir+y} + enable_dvipng=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvipng=$enable_dvipng'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-dvipng=$enable_dvipng'" >&6;} + ac_configure_args="$ac_configure_args '--enable-dvipng=$enable_dvipng'" + ;; +esac + +test "x$enable_dvipng" = xno || { + need_kpathsea=yes + need_gd=yes +} + +## texk/dvipng/ac/dvipng.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipng/ +## configure options for dvipng +# Check whether --enable-debug was given. +if test ${enable_debug+y} then : - withval=$with_zlib_libdir; + enableval=$enable_debug; fi -if test "x$with_system_zlib" = x; then - if test -f $srcdir/libs/zlib/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`zlib' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`zlib' headers and library from TL tree" >&6;} - with_system_zlib=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`zlib' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`zlib' headers and library" >&6;} - with_system_zlib=yes - fi - ac_configure_args="$ac_configure_args '--with-system-zlib=$with_system_zlib'" -elif test "x$with_system_zlib" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`zlib' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`zlib' headers and library" >&6;} -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`zlib' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`zlib' headers and library from TL tree" >&6;} - if test "x$with_system_zlib" != xno; then - with_system_zlib=no - ac_configure_args="$ac_configure_args '--without-system-zlib'" - fi + +# Check whether --enable-timing was given. +if test ${enable_timing+y} +then : + enableval=$enable_timing; fi -## texk/kpathsea/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/kpathsea/ -## configure options and TL libraries required for kpathsea +# Check whether --with-gs was given. +if test ${with_gs+y} +then : + withval=$with_gs; +fi -# Check whether --with-system-kpathsea was given. -if test ${with_system_kpathsea+y} + +## texk/dvipos/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipos/ +## configure options and TL libraries required for dvipos +# Check whether --enable-dvipos was given. +if test ${enable_dvipos+y} then : - withval=$with_system_kpathsea; + enableval=$enable_dvipos; fi -if test "x$with_system_kpathsea" = x; then - if test -f $srcdir/texk/kpathsea/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`kpathsea' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`kpathsea' headers and library from TL tree" >&6;} - with_system_kpathsea=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`kpathsea' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`kpathsea' headers and library" >&6;} - with_system_kpathsea=yes - fi - ac_configure_args="$ac_configure_args '--with-system-kpathsea=$with_system_kpathsea'" -elif test "x$with_system_kpathsea" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`kpathsea' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`kpathsea' headers and library" >&6;} -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`kpathsea' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`kpathsea' headers and library from TL tree" >&6;} - if test "x$with_system_kpathsea" != xno; then - with_system_kpathsea=no - ac_configure_args="$ac_configure_args '--without-system-kpathsea'" - fi +case $enable_dvipos in #( + yes|no) : + ;; #( + *) : + + enable_dvipos=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvipos=$enable_dvipos'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-dvipos=$enable_dvipos'" >&6;} + ac_configure_args="$ac_configure_args '--enable-dvipos=$enable_dvipos'" + ;; +esac + +test "x$enable_dvipos" = xno || { + need_kpathsea=yes +} + +## texk/dvipsk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipsk/ +## configure options and TL libraries required for dvipsk +# Check whether --enable-dvipsk was given. +if test ${enable_dvipsk+y} +then : + enableval=$enable_dvipsk; fi +case $enable_dvipsk in #( + yes|no) : + ;; #( + *) : -## texk/kpathsea/ac/mktex.ac: configure.ac fragment for the TeX Live -## subdirectory texk/kpathsea. -## configure defaults for mktexfmt & Co. -# Check whether --enable-mktexmf-default was given. -if test ${enable_mktexmf_default+y} + enable_dvipsk=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvipsk=$enable_dvipsk'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-dvipsk=$enable_dvipsk'" >&6;} + ac_configure_args="$ac_configure_args '--enable-dvipsk=$enable_dvipsk'" + ;; +esac + +test "x$enable_dvipsk" = xno || { + need_kpathsea=yes +} + +# texk/dvisvgm/ac/withenable.ac: configure.ac fragment +## configure options and TL libraries required for dvisvgm +# Check whether --enable-dvisvgm was given. +if test ${enable_dvisvgm+y} then : - enableval=$enable_mktexmf_default; + enableval=$enable_dvisvgm; fi -# Check whether --enable-mktexpk-default was given. -if test ${enable_mktexpk_default+y} +case $enable_dvisvgm in #( + yes|no) : + ;; #( + *) : + + enable_dvisvgm=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvisvgm=$enable_dvisvgm'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-dvisvgm=$enable_dvisvgm'" >&6;} + ac_configure_args="$ac_configure_args '--enable-dvisvgm=$enable_dvisvgm'" + ;; +esac + +test "x$enable_dvisvgm" = xno || { + need_kpathsea=yes + need_potrace=yes + need_freetype2=yes + need_zlib=yes +} + +## texk/gregorio/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/gregorio/ +## configure options and TL libraries required for gregorio +# Check whether --enable-gregorio was given. +if test ${enable_gregorio+y} then : - enableval=$enable_mktexpk_default; + enableval=$enable_gregorio; fi -# Check whether --enable-mktextfm-default was given. -if test ${enable_mktextfm_default+y} +case $enable_gregorio in #( + yes|no) : + ;; #( + *) : + + enable_gregorio=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-gregorio=$enable_gregorio'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-gregorio=$enable_gregorio'" >&6;} + ac_configure_args="$ac_configure_args '--enable-gregorio=$enable_gregorio'" + ;; +esac + +test "x$enable_gregorio" = xno || { + need_kpathsea=yes +} + +## texk/gsftopk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/gsftopk/ +## configure options and TL libraries required for gsftopk +# Check whether --enable-gsftopk was given. +if test ${enable_gsftopk+y} then : - enableval=$enable_mktextfm_default; + enableval=$enable_gsftopk; fi -# Check whether --enable-mkocp-default was given. -if test ${enable_mkocp_default+y} +case $enable_gsftopk in #( + yes|no) : + ;; #( + *) : + + enable_gsftopk=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-gsftopk=$enable_gsftopk'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-gsftopk=$enable_gsftopk'" >&6;} + ac_configure_args="$ac_configure_args '--enable-gsftopk=$enable_gsftopk'" + ;; +esac + +test "x$enable_gsftopk" = xno || { + need_kpathsea=yes +} + +## texk/lcdf-typetools/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/lcdf-typetools/ +## configure options and TL libraries required for lcdf-typetools +# Check whether --enable-lcdf-typetools was given. +if test ${enable_lcdf_typetools+y} then : - enableval=$enable_mkocp_default; + enableval=$enable_lcdf_typetools; fi -# Check whether --enable-mkofm-default was given. -if test ${enable_mkofm_default+y} +case $enable_lcdf_typetools in #( + yes|no) : + ;; #( + *) : + + enable_lcdf_typetools=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-lcdf-typetools=$enable_lcdf_typetools'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-lcdf-typetools=$enable_lcdf_typetools'" >&6;} + ac_configure_args="$ac_configure_args '--enable-lcdf-typetools=$enable_lcdf_typetools'" + ;; +esac + +test "x$enable_lcdf_typetools" = xno || { + need_kpathsea=yes +} + +# Define configure options for lcdf-typetools. Extracted from configure.ac +# for ease of building TeX Live. +# +# +# Check whether --enable-cfftot1 was given. +if test ${enable_cfftot1+y} then : - enableval=$enable_mkofm_default; + enableval=$enable_cfftot1; fi -# Check whether --enable-mktexfmt-default was given. -if test ${enable_mktexfmt_default+y} +# Check whether --enable-mmafm was given. +if test ${enable_mmafm+y} then : - enableval=$enable_mktexfmt_default; + enableval=$enable_mmafm; fi -# Check whether --enable-mktextex-default was given. -if test ${enable_mktextex_default+y} +# Check whether --enable-mmpfb was given. +if test ${enable_mmpfb+y} then : - enableval=$enable_mktextex_default; + enableval=$enable_mmpfb; +fi +# Check whether --enable-otfinfo was given. +if test ${enable_otfinfo+y} +then : + enableval=$enable_otfinfo; +fi +# Check whether --enable-otftotfm was given. +if test ${enable_otftotfm+y} +then : + enableval=$enable_otftotfm; +fi +# Check whether --enable-t1dotlessj was given. +if test ${enable_t1dotlessj+y} +then : + enableval=$enable_t1dotlessj; +fi +# Check whether --enable-t1lint was given. +if test ${enable_t1lint+y} +then : + enableval=$enable_t1lint; +fi +# Check whether --enable-t1rawafm was given. +if test ${enable_t1rawafm+y} +then : + enableval=$enable_t1rawafm; +fi +# Check whether --enable-t1reencode was given. +if test ${enable_t1reencode+y} +then : + enableval=$enable_t1reencode; +fi +# Check whether --enable-t1testpage was given. +if test ${enable_t1testpage+y} +then : + enableval=$enable_t1testpage; +fi +# Check whether --enable-ttftotype42 was given. +if test ${enable_ttftotype42+y} +then : + enableval=$enable_ttftotype42; fi +# +# Check whether --enable-cfftot1 was given. +if test ${enable_cfftot1+y} +then : + enableval=$enable_cfftot1; +fi +# Check whether --enable-t1dotlessj was given. +if test ${enable_t1dotlessj+y} +then : + enableval=$enable_t1dotlessj; +fi +# Check whether --enable-ttftotype42 was given. +if test ${enable_ttftotype42+y} +then : + enableval=$enable_ttftotype42; +fi +# Check whether --enable-updmap was given. +if test ${enable_updmap+y} +then : + enableval=$enable_updmap; +fi -# end of kpse_setup macro. -echo 'tldbg:KPSE_SETUP done (toplevel=)' >&5 - +## texk/makeindexk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/makeindexk/ +## configure options and TL libraries required for makeindexk +# Check whether --enable-makeindexk was given. +if test ${enable_makeindexk+y} +then : + enableval=$enable_makeindexk; +fi +case $enable_makeindexk in #( + yes|no) : + ;; #( + *) : -am__api_version='1.17' + enable_makeindexk=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-makeindexk=$enable_makeindexk'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-makeindexk=$enable_makeindexk'" >&6;} + ac_configure_args="$ac_configure_args '--enable-makeindexk=$enable_makeindexk'" + ;; +esac +test "x$enable_makeindexk" = xno || { + need_kpathsea=yes +} - # Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -printf %s "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if test ${ac_cv_path_install+y} +## texk/makejvf/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/makejvf/ +## configure options and TL libraries required for makejvf +# Check whether --enable-makejvf was given. +if test ${enable_makejvf+y} then : - printf %s "(cached) " >&6 -else case e in #( - e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - # Account for fact that we put trailing slashes in our PATH walk. -case $as_dir in #(( - ./ | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done + enableval=$enable_makejvf; +fi +case $enable_makejvf in #( + yes|no) : + ;; #( + *) : + + enable_makejvf=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-makejvf=$enable_makejvf'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-makejvf=$enable_makejvf'" >&6;} + ac_configure_args="$ac_configure_args '--enable-makejvf=$enable_makejvf'" ;; esac - done -IFS=$as_save_IFS +test "x$enable_makejvf" = xno || { + need_ptexenc=yes +} -rm -rf conftest.one conftest.two conftest.dir - ;; -esac -fi - if test ${ac_cv_path_install+y}; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi +## texk/mendexk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/mendexk/ +## configure options and TL libraries required for mendexk +# Check whether --enable-mendexk was given. +if test ${enable_mendexk+y} +then : + enableval=$enable_mendexk; fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -printf "%s\n" "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' +case $enable_mendexk in #( + yes|no) : + ;; #( + *) : -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + enable_mendexk=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-mendexk=$enable_mendexk'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-mendexk=$enable_mendexk'" >&6;} + ac_configure_args="$ac_configure_args '--enable-mendexk=$enable_mendexk'" + ;; +esac -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' +test "x$enable_mendexk" = xno || { + need_ptexenc=yes +} -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether sleep supports fractional seconds" >&5 -printf %s "checking whether sleep supports fractional seconds... " >&6; } -if test ${am_cv_sleep_fractional_seconds+y} +## texk/musixtnt/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/musixtnt/ +## configure options and TL libraries required for musixtnt +# Check whether --enable-musixtnt was given. +if test ${enable_musixtnt+y} +then : + enableval=$enable_musixtnt; +fi +case $enable_musixtnt in #( + yes|no) : + ;; #( + *) : + + enable_musixtnt=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-musixtnt=$enable_musixtnt'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-musixtnt=$enable_musixtnt'" >&6;} + ac_configure_args="$ac_configure_args '--enable-musixtnt=$enable_musixtnt'" + ;; +esac + +test "x$enable_musixtnt" = xno || { + need_kpathsea=yes +} + +## texk/ps2pk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/ps2pk/ +## configure options and TL libraries required for ps2pk +# Check whether --enable-ps2pk was given. +if test ${enable_ps2pk+y} +then : + enableval=$enable_ps2pk; +fi +case $enable_ps2pk in #( + yes|no) : + ;; #( + *) : + + enable_ps2pk=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-ps2pk=$enable_ps2pk'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-ps2pk=$enable_ps2pk'" >&6;} + ac_configure_args="$ac_configure_args '--enable-ps2pk=$enable_ps2pk'" + ;; +esac + +test "x$enable_ps2pk" = xno || { + need_kpathsea=yes +} + +## texk/psutils/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/psutils/ +## configure options and TL libraries required for psutils +# Check whether --enable-psutils was given. +if test ${enable_psutils+y} +then : + enableval=$enable_psutils; +fi +case $enable_psutils in #( + yes|no) : + ;; #( + *) : + + enable_psutils=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-psutils=$enable_psutils'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-psutils=$enable_psutils'" >&6;} + ac_configure_args="$ac_configure_args '--enable-psutils=$enable_psutils'" + ;; +esac + +test "x$enable_psutils" = xno || { + need_kpathsea=yes + need_libpaper=yes +} + +## texk/seetexk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/seetexk/ +## configure options and TL libraries required for seetexk +# Check whether --enable-seetexk was given. +if test ${enable_seetexk+y} +then : + enableval=$enable_seetexk; +fi +case $enable_seetexk in #( + yes|no) : + ;; #( + *) : + + enable_seetexk=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-seetexk=$enable_seetexk'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-seetexk=$enable_seetexk'" >&6;} + ac_configure_args="$ac_configure_args '--enable-seetexk=$enable_seetexk'" + ;; +esac + +test "x$enable_seetexk" = xno || { + need_kpathsea=yes +} + +## texk/tex4htk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/tex4htk/ +## configure options and TL libraries required for tex4htk +# Check whether --enable-tex4htk was given. +if test ${enable_tex4htk+y} +then : + enableval=$enable_tex4htk; +fi +case $enable_tex4htk in #( + yes|no) : + ;; #( + *) : + + enable_tex4htk=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-tex4htk=$enable_tex4htk'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-tex4htk=$enable_tex4htk'" >&6;} + ac_configure_args="$ac_configure_args '--enable-tex4htk=$enable_tex4htk'" + ;; +esac + +test "x$enable_tex4htk" = xno || { + need_kpathsea=yes +} + +## texk/ttf2pk2/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/ttf2pk2/ +## configure options and TL libraries required for ttf2pk +# Check whether --enable-ttf2pk2 was given. +if test ${enable_ttf2pk2+y} +then : + enableval=$enable_ttf2pk2; +fi +case $enable_ttf2pk2 in #( + yes|no) : + ;; #( + *) : + + enable_ttf2pk2=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-ttf2pk2=$enable_ttf2pk2'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-ttf2pk2=$enable_ttf2pk2'" >&6;} + ac_configure_args="$ac_configure_args '--enable-ttf2pk2=$enable_ttf2pk2'" + ;; +esac + +test "x$enable_ttf2pk2" = xno || { + need_kpathsea=yes + need_freetype2=yes +} + +## texk/ttfdump/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/ttfdump/ +## configure options and TL libraries required for ttfdump +# Check whether --enable-ttfdump was given. +if test ${enable_ttfdump+y} +then : + enableval=$enable_ttfdump; +fi +case $enable_ttfdump in #( + yes|no) : + ;; #( + *) : + + enable_ttfdump=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-ttfdump=$enable_ttfdump'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-ttfdump=$enable_ttfdump'" >&6;} + ac_configure_args="$ac_configure_args '--enable-ttfdump=$enable_ttfdump'" + ;; +esac + +test "x$enable_ttfdump" = xno || { + need_kpathsea=yes +} + +## texk/upmendex/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/upmendex/ +## configure options and TL libraries required for upmendex +# Check whether --enable-upmendex was given. +if test ${enable_upmendex+y} +then : + enableval=$enable_upmendex; +fi +case $enable_upmendex in #( + yes|no) : + ;; #( + *) : + + enable_upmendex=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-upmendex=$enable_upmendex'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-upmendex=$enable_upmendex'" >&6;} + ac_configure_args="$ac_configure_args '--enable-upmendex=$enable_upmendex'" + ;; +esac + +test "x$enable_upmendex" = xno || { + need_kpathsea=yes + need_icu=yes +} + +## texk/xdvik/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/xdvik/ +## configure options and TL libraries required for xdvik +# Check whether --enable-xdvik was given. +if test ${enable_xdvik+y} +then : + enableval=$enable_xdvik; +fi +if test "x$with_x" = xno +then : + case $enable_xdvik in #( + "") : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \`--without-x' -> \`--disable-xdvik'" >&5 +printf "%s\n" "$as_me: \`--without-x' -> \`--disable-xdvik'" >&6;} + enable_xdvik=no + ac_configure_args="$ac_configure_args '--disable-xdvik'" ;; #( + yes) : + as_fn_error $? "Sorry, incompatible options \`--without-x' and \`--enable-xdvik'" "$LINENO" 5 ;; #( + *) : + ;; +esac +fi +case $enable_xdvik in #( + yes|no) : + ;; #( + *) : + + enable_xdvik=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-xdvik=$enable_xdvik'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-xdvik=$enable_xdvik'" >&6;} + ac_configure_args="$ac_configure_args '--enable-xdvik=$enable_xdvik'" + ;; +esac + +test "x$enable_xdvik" = xno || { + need_kpathsea=yes + need_freetype2=yes +} + +## texk/xdvik/ac/xdvik.ac: configure.ac fragment for the TeX Live subdirectory texk/xdvik/ +## configure options for xdvik + +# Check whether --with-xdvi-x-toolkit was given. +if test ${with_xdvi_x_toolkit+y} +then : + withval=$with_xdvi_x_toolkit; +fi + + +## texk/texlive/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/texlive/ +## configure options and TL libraries required for texlive +# Check whether --enable-texlive was given. +if test ${enable_texlive+y} +then : + enableval=$enable_texlive; +fi +case $enable_texlive in #( + yes|no) : + ;; #( + *) : + + enable_texlive=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-texlive=$enable_texlive'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-texlive=$enable_texlive'" >&6;} + ac_configure_args="$ac_configure_args '--enable-texlive=$enable_texlive'" + ;; +esac + +## texk/texlive/ac/texlive.ac: configure.ac fragment for the TeX Live subdirectory texk/texlive/ +## configure options for texlive +# Check whether --enable-linked-scripts was given. +if test ${enable_linked_scripts+y} +then : + enableval=$enable_linked_scripts; +fi + + +## libs/pplib/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/pplib/ +## configure options and TL libraries required for pplib + +test "x$need_pplib" = xyes && { + need_zlib=yes +} + +## libs/harfbuzz/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/harfbuzz/ +## configure options and TL libraries required for harfbuzz + +# Check whether --with-system-harfbuzz was given. +if test ${with_system_harfbuzz+y} +then : + withval=$with_system_harfbuzz; +fi +if test "x$with_system_harfbuzz" = x; then + if test -f $srcdir/libs/harfbuzz/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`harfbuzz' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`harfbuzz' headers and library from TL tree" >&6;} + with_system_harfbuzz=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`harfbuzz' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`harfbuzz' headers and library" >&6;} + with_system_harfbuzz=yes + fi + ac_configure_args="$ac_configure_args '--with-system-harfbuzz=$with_system_harfbuzz'" +elif test "x$with_system_harfbuzz" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`harfbuzz' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`harfbuzz' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`harfbuzz' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`harfbuzz' headers and library from TL tree" >&6;} + if test "x$with_system_harfbuzz" != xno; then + with_system_harfbuzz=no + ac_configure_args="$ac_configure_args '--without-system-harfbuzz'" + fi +fi +if test "x$with_system_harfbuzz" = xyes; then + if test "x$with_system_graphite2" = x; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`graphite2' headers and library" >&5 +printf "%s\n" "$as_me: -> installed \`graphite2' headers and library" >&6;} + with_system_graphite2=yes + ac_configure_args="$ac_configure_args '--with-system-graphite2'" + elif test "x$with_system_graphite2" != xyes; then + as_fn_error $? "Sorry, \`--with-system-harfbuzz' requires \`--with-system-graphite2'" "$LINENO" 5 + fi + if test "x$with_system_icu" = x; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`icu' headers and library" >&5 +printf "%s\n" "$as_me: -> installed \`icu' headers and library" >&6;} + with_system_icu=yes + ac_configure_args="$ac_configure_args '--with-system-icu'" + elif test "x$with_system_icu" != xyes; then + as_fn_error $? "Sorry, \`--with-system-harfbuzz' requires \`--with-system-icu'" "$LINENO" 5 + fi +fi + +test "x$need_harfbuzz" = xyes && { + need_graphite2=yes + need_icu=yes +} + +## libs/icu/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/icu/ +## configure options and TL libraries required for icu (modified for XeTeX) + +# Check whether --with-system-icu was given. +if test ${with_system_icu+y} +then : + withval=$with_system_icu; +fi +if test "x$with_system_icu" = x; then + if test -f $srcdir/libs/icu/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`icu' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`icu' headers and library from TL tree" >&6;} + with_system_icu=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`icu' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`icu' headers and library" >&6;} + with_system_icu=yes + fi + ac_configure_args="$ac_configure_args '--with-system-icu=$with_system_icu'" +elif test "x$with_system_icu" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`icu' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`icu' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`icu' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`icu' headers and library from TL tree" >&6;} + if test "x$with_system_icu" != xno; then + with_system_icu=no + ac_configure_args="$ac_configure_args '--without-system-icu'" + fi +fi + +## libs/teckit/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/teckit/ +## configure options and TL libraries required for teckit + +# Check whether --with-system-teckit was given. +if test ${with_system_teckit+y} +then : + withval=$with_system_teckit; +fi +if test "x$with_system_teckit" = x; then + if test -f $srcdir/libs/teckit/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`teckit' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`teckit' headers and library from TL tree" >&6;} + with_system_teckit=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`teckit' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`teckit' headers and library" >&6;} + with_system_teckit=yes + fi + ac_configure_args="$ac_configure_args '--with-system-teckit=$with_system_teckit'" +elif test "x$with_system_teckit" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`teckit' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`teckit' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`teckit' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`teckit' headers and library from TL tree" >&6;} + if test "x$with_system_teckit" != xno; then + with_system_teckit=no + ac_configure_args="$ac_configure_args '--without-system-teckit'" + fi +fi +if test "x$with_system_teckit" = xyes; then + if test "x$with_system_zlib" = x; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`zlib' headers and library" >&5 +printf "%s\n" "$as_me: -> installed \`zlib' headers and library" >&6;} + with_system_zlib=yes + ac_configure_args="$ac_configure_args '--with-system-zlib'" + elif test "x$with_system_zlib" != xyes; then + as_fn_error $? "Sorry, \`--with-system-teckit' requires \`--with-system-zlib'" "$LINENO" 5 + fi +fi + +test "x$need_teckit" = xyes && { + need_zlib=yes +} + +## libs/graphite2/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/graphite2/ +## configure options and TL libraries required for graphite2 + +# Check whether --with-system-graphite2 was given. +if test ${with_system_graphite2+y} +then : + withval=$with_system_graphite2; +fi +if test "x$with_system_graphite2" = x; then + if test -f $srcdir/libs/graphite2/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`graphite2' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`graphite2' headers and library from TL tree" >&6;} + with_system_graphite2=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`graphite2' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`graphite2' headers and library" >&6;} + with_system_graphite2=yes + fi + ac_configure_args="$ac_configure_args '--with-system-graphite2=$with_system_graphite2'" +elif test "x$with_system_graphite2" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`graphite2' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`graphite2' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`graphite2' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`graphite2' headers and library from TL tree" >&6;} + if test "x$with_system_graphite2" != xno; then + with_system_graphite2=no + ac_configure_args="$ac_configure_args '--without-system-graphite2'" + fi +fi + +## libs/zziplib/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/zziplib/ +## configure options and TL libraries required for zziplib + +# Check whether --with-system-zziplib was given. +if test ${with_system_zziplib+y} +then : + withval=$with_system_zziplib; +fi +if test "x$with_system_zziplib" = x; then + if test -f $srcdir/libs/zziplib/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`zziplib' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`zziplib' headers and library from TL tree" >&6;} + with_system_zziplib=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`zziplib' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`zziplib' headers and library" >&6;} + with_system_zziplib=yes + fi + ac_configure_args="$ac_configure_args '--with-system-zziplib=$with_system_zziplib'" +elif test "x$with_system_zziplib" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`zziplib' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`zziplib' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`zziplib' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`zziplib' headers and library from TL tree" >&6;} + if test "x$with_system_zziplib" != xno; then + with_system_zziplib=no + ac_configure_args="$ac_configure_args '--without-system-zziplib'" + fi +fi +if test "x$with_system_zziplib" = xyes; then + if test "x$with_system_zlib" = x; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`zlib' headers and library" >&5 +printf "%s\n" "$as_me: -> installed \`zlib' headers and library" >&6;} + with_system_zlib=yes + ac_configure_args="$ac_configure_args '--with-system-zlib'" + elif test "x$with_system_zlib" != xyes; then + as_fn_error $? "Sorry, \`--with-system-zziplib' requires \`--with-system-zlib'" "$LINENO" 5 + fi +fi + +test "x$need_zziplib" = xyes && { + need_zlib=yes +} + +## libs/xpdf/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/xpdf/ +## configure options and TL libraries required for xpdf +: "kpse_xpdf_options - no-op" +if test "x$with_system_xpdf" = x; then + if test -f $srcdir/libs/xpdf/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`xpdf' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`xpdf' headers and library from TL tree" >&6;} + with_system_xpdf=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`xpdf' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`xpdf' headers and library" >&6;} + with_system_xpdf=yes + fi + ac_configure_args="$ac_configure_args '--with-system-xpdf=$with_system_xpdf'" +elif test "x$with_system_xpdf" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`xpdf' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`xpdf' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`xpdf' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`xpdf' headers and library from TL tree" >&6;} + if test "x$with_system_xpdf" != xno; then + with_system_xpdf=no + ac_configure_args="$ac_configure_args '--without-system-xpdf'" + fi +fi + +## libs/mpfi/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/mpfi/ +## configure options and TL libraries required for mpfi + +# Check whether --with-system-mpfi was given. +if test ${with_system_mpfi+y} +then : + withval=$with_system_mpfi; +fi + +# Check whether --with-mpfi-includes was given. +if test ${with_mpfi_includes+y} +then : + withval=$with_mpfi_includes; +fi + +# Check whether --with-mpfi-libdir was given. +if test ${with_mpfi_libdir+y} +then : + withval=$with_mpfi_libdir; +fi +if test "x$with_system_mpfi" = x; then + if test -f $srcdir/libs/mpfi/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`mpfi' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`mpfi' headers and library from TL tree" >&6;} + with_system_mpfi=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`mpfi' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`mpfi' headers and library" >&6;} + with_system_mpfi=yes + fi + ac_configure_args="$ac_configure_args '--with-system-mpfi=$with_system_mpfi'" +elif test "x$with_system_mpfi" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`mpfi' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`mpfi' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`mpfi' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`mpfi' headers and library from TL tree" >&6;} + if test "x$with_system_mpfi" != xno; then + with_system_mpfi=no + ac_configure_args="$ac_configure_args '--without-system-mpfi'" + fi +fi +if test "x$with_system_mpfi" = xyes; then + if test "x$with_system_mpfr" = x; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`mpfr' headers and library" >&5 +printf "%s\n" "$as_me: -> installed \`mpfr' headers and library" >&6;} + with_system_mpfr=yes + ac_configure_args="$ac_configure_args '--with-system-mpfr'" + elif test "x$with_system_mpfr" != xyes; then + as_fn_error $? "Sorry, \`--with-system-mpfi' requires \`--with-system-mpfr'" "$LINENO" 5 + fi + if test "x$with_system_gmp" = x; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`gmp' headers and library" >&5 +printf "%s\n" "$as_me: -> installed \`gmp' headers and library" >&6;} + with_system_gmp=yes + ac_configure_args="$ac_configure_args '--with-system-gmp'" + elif test "x$with_system_gmp" != xyes; then + as_fn_error $? "Sorry, \`--with-system-mpfi' requires \`--with-system-gmp'" "$LINENO" 5 + fi +fi + +test "x$need_mpfi" = xyes && { + need_mpfr=yes + need_gmp=yes +} + +## libs/mpfr/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/mpfr/ +## configure options and TL libraries required for mpfr + +# Check whether --with-system-mpfr was given. +if test ${with_system_mpfr+y} +then : + withval=$with_system_mpfr; +fi + +# Check whether --with-mpfr-includes was given. +if test ${with_mpfr_includes+y} +then : + withval=$with_mpfr_includes; +fi + +# Check whether --with-mpfr-libdir was given. +if test ${with_mpfr_libdir+y} +then : + withval=$with_mpfr_libdir; +fi +if test "x$with_system_mpfr" = x; then + if test -f $srcdir/libs/mpfr/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`mpfr' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`mpfr' headers and library from TL tree" >&6;} + with_system_mpfr=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`mpfr' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`mpfr' headers and library" >&6;} + with_system_mpfr=yes + fi + ac_configure_args="$ac_configure_args '--with-system-mpfr=$with_system_mpfr'" +elif test "x$with_system_mpfr" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`mpfr' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`mpfr' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`mpfr' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`mpfr' headers and library from TL tree" >&6;} + if test "x$with_system_mpfr" != xno; then + with_system_mpfr=no + ac_configure_args="$ac_configure_args '--without-system-mpfr'" + fi +fi +if test "x$with_system_mpfr" = xyes; then + if test "x$with_system_gmp" = x; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`gmp' headers and library" >&5 +printf "%s\n" "$as_me: -> installed \`gmp' headers and library" >&6;} + with_system_gmp=yes + ac_configure_args="$ac_configure_args '--with-system-gmp'" + elif test "x$with_system_gmp" != xyes; then + as_fn_error $? "Sorry, \`--with-system-mpfr' requires \`--with-system-gmp'" "$LINENO" 5 + fi +fi + +test "x$need_mpfr" = xyes && { + need_gmp=yes +} + +## libs/gmp/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/gmp/ +## configure options and TL libraries required for gmp + +# Check whether --with-system-gmp was given. +if test ${with_system_gmp+y} +then : + withval=$with_system_gmp; +fi + +# Check whether --with-gmp-includes was given. +if test ${with_gmp_includes+y} +then : + withval=$with_gmp_includes; +fi + +# Check whether --with-gmp-libdir was given. +if test ${with_gmp_libdir+y} +then : + withval=$with_gmp_libdir; +fi +if test "x$with_system_gmp" = x; then + if test -f $srcdir/libs/gmp/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`gmp' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`gmp' headers and library from TL tree" >&6;} + with_system_gmp=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`gmp' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`gmp' headers and library" >&6;} + with_system_gmp=yes + fi + ac_configure_args="$ac_configure_args '--with-system-gmp=$with_system_gmp'" +elif test "x$with_system_gmp" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`gmp' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`gmp' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`gmp' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`gmp' headers and library from TL tree" >&6;} + if test "x$with_system_gmp" != xno; then + with_system_gmp=no + ac_configure_args="$ac_configure_args '--without-system-gmp'" + fi +fi + +## libs/cairo/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/cairo/ +## configure options and TL libraries required for cairo + +# Check whether --with-system-cairo was given. +if test ${with_system_cairo+y} +then : + withval=$with_system_cairo; +fi +if test "x$with_system_cairo" = x; then + if test -f $srcdir/libs/cairo/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`cairo' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`cairo' headers and library from TL tree" >&6;} + with_system_cairo=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`cairo' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`cairo' headers and library" >&6;} + with_system_cairo=yes + fi + ac_configure_args="$ac_configure_args '--with-system-cairo=$with_system_cairo'" +elif test "x$with_system_cairo" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`cairo' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`cairo' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`cairo' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`cairo' headers and library from TL tree" >&6;} + if test "x$with_system_cairo" != xno; then + with_system_cairo=no + ac_configure_args="$ac_configure_args '--without-system-cairo'" + fi +fi +if test "x$with_system_cairo" = xyes; then + if test "x$with_system_pixman" = x; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`pixman' headers and library" >&5 +printf "%s\n" "$as_me: -> installed \`pixman' headers and library" >&6;} + with_system_pixman=yes + ac_configure_args="$ac_configure_args '--with-system-pixman'" + elif test "x$with_system_pixman" != xyes; then + as_fn_error $? "Sorry, \`--with-system-cairo' requires \`--with-system-pixman'" "$LINENO" 5 + fi +fi + +test "x$need_cairo" = xyes && { + need_pixman=yes +} + +## libs/pixman/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/pixman/ +## configure options and TL libraries required for pixman + +# Check whether --with-system-pixman was given. +if test ${with_system_pixman+y} +then : + withval=$with_system_pixman; +fi +if test "x$with_system_pixman" = x; then + if test -f $srcdir/libs/pixman/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`pixman' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`pixman' headers and library from TL tree" >&6;} + with_system_pixman=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`pixman' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`pixman' headers and library" >&6;} + with_system_pixman=yes + fi + ac_configure_args="$ac_configure_args '--with-system-pixman=$with_system_pixman'" +elif test "x$with_system_pixman" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`pixman' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`pixman' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`pixman' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`pixman' headers and library from TL tree" >&6;} + if test "x$with_system_pixman" != xno; then + with_system_pixman=no + ac_configure_args="$ac_configure_args '--without-system-pixman'" + fi +fi + +## libs/gd/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/gd/ +## configure options and TL libraries required for gd + +# Check whether --with-system-gd was given. +if test ${with_system_gd+y} +then : + withval=$with_system_gd; +fi + +# Check whether --with-gd-includes was given. +if test ${with_gd_includes+y} +then : + withval=$with_gd_includes; +fi + +# Check whether --with-gd-libdir was given. +if test ${with_gd_libdir+y} +then : + withval=$with_gd_libdir; +fi +if test "x$with_system_gd" = x; then + if test -f $srcdir/libs/gd/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`gd' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`gd' headers and library from TL tree" >&6;} + with_system_gd=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`gd' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`gd' headers and library" >&6;} + with_system_gd=yes + fi + ac_configure_args="$ac_configure_args '--with-system-gd=$with_system_gd'" +elif test "x$with_system_gd" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`gd' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`gd' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`gd' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`gd' headers and library from TL tree" >&6;} + if test "x$with_system_gd" != xno; then + with_system_gd=no + ac_configure_args="$ac_configure_args '--without-system-gd'" + fi +fi +if test "x$with_system_gd" = xyes; then + if test "x$with_system_libpng" = x; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`libpng' headers and library" >&5 +printf "%s\n" "$as_me: -> installed \`libpng' headers and library" >&6;} + with_system_libpng=yes + ac_configure_args="$ac_configure_args '--with-system-libpng'" + elif test "x$with_system_libpng" != xyes; then + as_fn_error $? "Sorry, \`--with-system-gd' requires \`--with-system-libpng'" "$LINENO" 5 + fi + if test "x$with_system_freetype2" = x; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`freetype2' headers and library" >&5 +printf "%s\n" "$as_me: -> installed \`freetype2' headers and library" >&6;} + with_system_freetype2=yes + ac_configure_args="$ac_configure_args '--with-system-freetype2'" + elif test "x$with_system_freetype2" != xyes; then + as_fn_error $? "Sorry, \`--with-system-gd' requires \`--with-system-freetype2'" "$LINENO" 5 + fi +fi + +test "x$need_gd" = xyes && { + need_libpng=yes + need_freetype2=yes +} + +## libs/potrace/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/potrace/ +## configure options and TL libraries required for potrace + +# Check whether --with-system-potrace was given. +if test ${with_system_potrace+y} +then : + withval=$with_system_potrace; +fi + +# Check whether --with-potrace-includes was given. +if test ${with_potrace_includes+y} +then : + withval=$with_potrace_includes; +fi + +# Check whether --with-potrace-libdir was given. +if test ${with_potrace_libdir+y} +then : + withval=$with_potrace_libdir; +fi +if test "x$with_system_potrace" = x; then + if test -f $srcdir/libs/potrace/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`potrace' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`potrace' headers and library from TL tree" >&6;} + with_system_potrace=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`potrace' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`potrace' headers and library" >&6;} + with_system_potrace=yes + fi + ac_configure_args="$ac_configure_args '--with-system-potrace=$with_system_potrace'" +elif test "x$with_system_potrace" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`potrace' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`potrace' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`potrace' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`potrace' headers and library from TL tree" >&6;} + if test "x$with_system_potrace" != xno; then + with_system_potrace=no + ac_configure_args="$ac_configure_args '--without-system-potrace'" + fi +fi + +## libs/freetype2/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/freetype2/ +## configure options and TL libraries required for freetype2 + +# Check whether --with-system-freetype2 was given. +if test ${with_system_freetype2+y} +then : + withval=$with_system_freetype2; +fi +if test "x$with_system_freetype2" = x; then + if test -f $srcdir/libs/freetype2/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`freetype2' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`freetype2' headers and library from TL tree" >&6;} + with_system_freetype2=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`freetype2' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`freetype2' headers and library" >&6;} + with_system_freetype2=yes + fi + ac_configure_args="$ac_configure_args '--with-system-freetype2=$with_system_freetype2'" +elif test "x$with_system_freetype2" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`freetype2' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`freetype2' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`freetype2' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`freetype2' headers and library from TL tree" >&6;} + if test "x$with_system_freetype2" != xno; then + with_system_freetype2=no + ac_configure_args="$ac_configure_args '--without-system-freetype2'" + fi +fi +if test "x$with_system_freetype2" = xyes; then + if test "x$with_system_zlib" = x; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`zlib' headers and library" >&5 +printf "%s\n" "$as_me: -> installed \`zlib' headers and library" >&6;} + with_system_zlib=yes + ac_configure_args="$ac_configure_args '--with-system-zlib'" + elif test "x$with_system_zlib" != xyes; then + as_fn_error $? "Sorry, \`--with-system-freetype2' requires \`--with-system-zlib'" "$LINENO" 5 + fi +fi + +test "x$need_freetype2" = xyes && { + need_zlib=yes +} + +## libs/libpng/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/libpng/ +## configure options and TL libraries required for libpng + +# Check whether --with-system-libpng was given. +if test ${with_system_libpng+y} +then : + withval=$with_system_libpng; +fi +if test "x$with_system_libpng" = x; then + if test -f $srcdir/libs/libpng/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`libpng' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`libpng' headers and library from TL tree" >&6;} + with_system_libpng=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`libpng' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`libpng' headers and library" >&6;} + with_system_libpng=yes + fi + ac_configure_args="$ac_configure_args '--with-system-libpng=$with_system_libpng'" +elif test "x$with_system_libpng" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`libpng' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`libpng' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`libpng' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`libpng' headers and library from TL tree" >&6;} + if test "x$with_system_libpng" != xno; then + with_system_libpng=no + ac_configure_args="$ac_configure_args '--without-system-libpng'" + fi +fi +if test "x$with_system_libpng" = xyes; then + if test "x$with_system_zlib" = x; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`zlib' headers and library" >&5 +printf "%s\n" "$as_me: -> installed \`zlib' headers and library" >&6;} + with_system_zlib=yes + ac_configure_args="$ac_configure_args '--with-system-zlib'" + elif test "x$with_system_zlib" != xyes; then + as_fn_error $? "Sorry, \`--with-system-libpng' requires \`--with-system-zlib'" "$LINENO" 5 + fi +fi + +test "x$need_libpng" = xyes && { + need_zlib=yes +} + +## libs/libpaper/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/libpaper/ +## configure options and TL libraries required for libpaper + +# Check whether --with-system-libpaper was given. +if test ${with_system_libpaper+y} +then : + withval=$with_system_libpaper; +fi + +# Check whether --with-libpaper-includes was given. +if test ${with_libpaper_includes+y} +then : + withval=$with_libpaper_includes; +fi + +# Check whether --with-libpaper-libdir was given. +if test ${with_libpaper_libdir+y} +then : + withval=$with_libpaper_libdir; +fi +if test "x$with_system_libpaper" = x; then + if test -f $srcdir/libs/libpaper/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`libpaper' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`libpaper' headers and library from TL tree" >&6;} + with_system_libpaper=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`libpaper' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`libpaper' headers and library" >&6;} + with_system_libpaper=yes + fi + ac_configure_args="$ac_configure_args '--with-system-libpaper=$with_system_libpaper'" +elif test "x$with_system_libpaper" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`libpaper' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`libpaper' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`libpaper' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`libpaper' headers and library from TL tree" >&6;} + if test "x$with_system_libpaper" != xno; then + with_system_libpaper=no + ac_configure_args="$ac_configure_args '--without-system-libpaper'" + fi +fi + +## libs/luajit/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/luajit/ +## configure options and TL libraries required for luajit + +# Check whether --with-system-luajit was given. +if test ${with_system_luajit+y} +then : + withval=$with_system_luajit; +fi +if test "x$with_system_luajit" = x; then + if test -f $srcdir/libs/luajit/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`luajit' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`luajit' headers and library from TL tree" >&6;} + with_system_luajit=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`luajit' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`luajit' headers and library" >&6;} + with_system_luajit=yes + fi + ac_configure_args="$ac_configure_args '--with-system-luajit=$with_system_luajit'" +elif test "x$with_system_luajit" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`luajit' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`luajit' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`luajit' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`luajit' headers and library from TL tree" >&6;} + if test "x$with_system_luajit" != xno; then + with_system_luajit=no + ac_configure_args="$ac_configure_args '--without-system-luajit'" + fi +fi + +## libs/lua53/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/lua53/ +## configure options and TL libraries required for lua53 + +## libs/zlib/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/zlib/ +## configure options and TL libraries required for zlib + +# Check whether --with-system-zlib was given. +if test ${with_system_zlib+y} +then : + withval=$with_system_zlib; +fi + +# Check whether --with-zlib-includes was given. +if test ${with_zlib_includes+y} +then : + withval=$with_zlib_includes; +fi + +# Check whether --with-zlib-libdir was given. +if test ${with_zlib_libdir+y} +then : + withval=$with_zlib_libdir; +fi +if test "x$with_system_zlib" = x; then + if test -f $srcdir/libs/zlib/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`zlib' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`zlib' headers and library from TL tree" >&6;} + with_system_zlib=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`zlib' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`zlib' headers and library" >&6;} + with_system_zlib=yes + fi + ac_configure_args="$ac_configure_args '--with-system-zlib=$with_system_zlib'" +elif test "x$with_system_zlib" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`zlib' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`zlib' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`zlib' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`zlib' headers and library from TL tree" >&6;} + if test "x$with_system_zlib" != xno; then + with_system_zlib=no + ac_configure_args="$ac_configure_args '--without-system-zlib'" + fi +fi + + +## texk/ptexenc/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/ptexenc/ +## configure options and TL libraries required for ptexenc + +# Check whether --with-system-ptexenc was given. +if test ${with_system_ptexenc+y} +then : + withval=$with_system_ptexenc; +fi +if test "x$with_system_ptexenc" = x; then + if test -f $srcdir/texk/ptexenc/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`ptexenc' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`ptexenc' headers and library from TL tree" >&6;} + with_system_ptexenc=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`ptexenc' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`ptexenc' headers and library" >&6;} + with_system_ptexenc=yes + fi + ac_configure_args="$ac_configure_args '--with-system-ptexenc=$with_system_ptexenc'" +elif test "x$with_system_ptexenc" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`ptexenc' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`ptexenc' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`ptexenc' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`ptexenc' headers and library from TL tree" >&6;} + if test "x$with_system_ptexenc" != xno; then + with_system_ptexenc=no + ac_configure_args="$ac_configure_args '--without-system-ptexenc'" + fi +fi +if test "x$with_system_ptexenc" = xyes; then + if test "x$with_system_kpathsea" = x; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`kpathsea' headers and library" >&5 +printf "%s\n" "$as_me: -> installed \`kpathsea' headers and library" >&6;} + with_system_kpathsea=yes + ac_configure_args="$ac_configure_args '--with-system-kpathsea'" + elif test "x$with_system_kpathsea" != xyes; then + as_fn_error $? "Sorry, \`--with-system-ptexenc' requires \`--with-system-kpathsea'" "$LINENO" 5 + fi +fi + +test "x$need_ptexenc" = xyes && { + need_kpathsea=yes +} + +## texk/kpathsea/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/kpathsea/ +## configure options and TL libraries required for kpathsea + +# Check whether --with-system-kpathsea was given. +if test ${with_system_kpathsea+y} +then : + withval=$with_system_kpathsea; +fi +if test "x$with_system_kpathsea" = x; then + if test -f $srcdir/texk/kpathsea/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`kpathsea' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`kpathsea' headers and library from TL tree" >&6;} + with_system_kpathsea=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`kpathsea' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`kpathsea' headers and library" >&6;} + with_system_kpathsea=yes + fi + ac_configure_args="$ac_configure_args '--with-system-kpathsea=$with_system_kpathsea'" +elif test "x$with_system_kpathsea" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`kpathsea' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`kpathsea' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`kpathsea' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`kpathsea' headers and library from TL tree" >&6;} + if test "x$with_system_kpathsea" != xno; then + with_system_kpathsea=no + ac_configure_args="$ac_configure_args '--without-system-kpathsea'" + fi +fi + +## texk/kpathsea/ac/mktex.ac: configure.ac fragment for the TeX Live +## subdirectory texk/kpathsea. +## configure defaults for mktexfmt & Co. +# Check whether --enable-mktexmf-default was given. +if test ${enable_mktexmf_default+y} +then : + enableval=$enable_mktexmf_default; +fi +# Check whether --enable-mktexpk-default was given. +if test ${enable_mktexpk_default+y} +then : + enableval=$enable_mktexpk_default; +fi +# Check whether --enable-mktextfm-default was given. +if test ${enable_mktextfm_default+y} +then : + enableval=$enable_mktextfm_default; +fi +# Check whether --enable-mkocp-default was given. +if test ${enable_mkocp_default+y} +then : + enableval=$enable_mkocp_default; +fi +# Check whether --enable-mkofm-default was given. +if test ${enable_mkofm_default+y} +then : + enableval=$enable_mkofm_default; +fi +# Check whether --enable-mktexfmt-default was given. +if test ${enable_mktexfmt_default+y} +then : + enableval=$enable_mktexfmt_default; +fi +# Check whether --enable-mktextex-default was given. +if test ${enable_mktextex_default+y} +then : + enableval=$enable_mktextex_default; +fi + + + +# end of kpse_setup macro. +echo 'tldbg:KPSE_SETUP done (toplevel=)' >&5 + + +am__api_version='1.17' + + + # Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +printf %s "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if test ${ac_cv_path_install+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + # Account for fact that we put trailing slashes in our PATH walk. +case $as_dir in #(( + ./ | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + ;; +esac +fi + if test ${ac_cv_path_install+y}; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +printf "%s\n" "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether sleep supports fractional seconds" >&5 +printf %s "checking whether sleep supports fractional seconds... " >&6; } +if test ${am_cv_sleep_fractional_seconds+y} then : printf %s "(cached) " >&6 else case e in #( @@ -22806,6 +24777,12 @@ printf %s "checking for TeX specific libraries to build... " >&6; } echo 'tldbg:_KPSE_RECURSE called: list=texlibs, text=TeX specific libraries, cond=test "x$with_system_[]Kpse_pkg" != xyes && test "x$need_[]Kpse_pkg" = xyes, prefix=texk/.' >&5 MAKE_SUBDIRS= CONF_SUBDIRS= +if test -x $srcdir/texk/ptexenc/configure; then + test "x$with_system_ptexenc" != xyes && test "x$need_ptexenc" = xyes && MAKE_SUBDIRS="texk/ptexenc $MAKE_SUBDIRS" + CONF_SUBDIRS="texk/ptexenc $CONF_SUBDIRS" +else + echo 'tldbg:_KPSE_RECURSE skipping subdir, no (executable) configure: '"$srcdir"'/texk/ptexenc/configure' >&5 +fi if test -x $srcdir/texk/kpathsea/configure; then test "x$with_system_kpathsea" != xyes && test "x$need_kpathsea" = xyes && MAKE_SUBDIRS="texk/kpathsea $MAKE_SUBDIRS" CONF_SUBDIRS="texk/kpathsea $CONF_SUBDIRS" @@ -23373,17 +25350,63 @@ esac else ICU_CONFIG="$ac_cv_prog_ICU_CONFIG" fi -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. -set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_PKG_CONFIG+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$PKG_CONFIG"; then + ac_cv_prog_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_PKG_CONFIG="${ac_tool_prefix}pkg-config" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +PKG_CONFIG=$ac_cv_prog_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +printf "%s\n" "$PKG_CONFIG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_PKG_CONFIG"; then + ac_ct_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_PKG_CONFIG+y} +if test ${ac_cv_prog_ac_ct_PKG_CONFIG+y} then : printf %s "(cached) " >&6 else case e in #( - e) if test -n "$PKG_CONFIG"; then - ac_cv_prog_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test. + e) if test -n "$ac_ct_PKG_CONFIG"; then + ac_cv_prog_ac_ct_PKG_CONFIG="$ac_ct_PKG_CONFIG" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH @@ -23396,7 +25419,7 @@ do esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_PKG_CONFIG="${ac_tool_prefix}pkg-config" + ac_cv_prog_ac_ct_PKG_CONFIG="pkg-config" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi @@ -23407,120 +25430,391 @@ IFS=$as_save_IFS fi ;; esac fi -PKG_CONFIG=$ac_cv_prog_PKG_CONFIG -if test -n "$PKG_CONFIG"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 -printf "%s\n" "$PKG_CONFIG" >&6; } +ac_ct_PKG_CONFIG=$ac_cv_prog_ac_ct_PKG_CONFIG +if test -n "$ac_ct_PKG_CONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_PKG_CONFIG" >&5 +printf "%s\n" "$ac_ct_PKG_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi - - + + if test "x$ac_ct_PKG_CONFIG" = x; then + PKG_CONFIG="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_ct_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_prog_PKG_CONFIG" +fi +if $ICU_CONFIG --version >/dev/null 2>&1; then + ICU_INCLUDES=`$ICU_CONFIG --cppflags` + ICU_LIBS=`$ICU_CONFIG --ldflags-searchpath --ldflags-libsonly --ldflags-system` +elif $PKG_CONFIG --libs icu-uc icu-io >/dev/null 2>&1; then + ICU_INCLUDES=`$PKG_CONFIG --cflags icu-uc icu-io` + ICU_LIBS=`$PKG_CONFIG --libs icu-uc icu-io` +elif test "x$need_icu:$with_system_icu" = xyes:yes; then + as_fn_error $? "did not find either pkg-config or icu-config; one is required for system icu library support" "$LINENO" 5 +fi + +if $PKG_CONFIG harfbuzz; then + HARFBUZZ_INCLUDES=`$PKG_CONFIG harfbuzz --cflags` + HARFBUZZ_LIBS=`$PKG_CONFIG harfbuzz --libs` +elif test "x$need_harfbuzz:$with_system_harfbuzz" = xyes:yes; then + as_fn_error $? "did not find harfbuzz" "$LINENO" 5 +fi + +if $PKG_CONFIG luajit; then + LUAJIT_INCLUDES=`$PKG_CONFIG luajit --cflags` + LUAJIT_LIBS=`$PKG_CONFIG luajit --libs` +elif test "x$need_luajit:$with_system_luajit" = xyes:yes; then + as_fn_error $? "did not find luajit" "$LINENO" 5 +fi + + + + + + +## texk/kpathsea/ac/kpathsea.ac: configure.ac fragment for the TeX Live subdirectory texk/kpathsea/ +## basic check of system kpathsea +if test "x$need_kpathsea:$with_system_kpathsea" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`kpathsea' library" >&5 +printf %s "checking requested system \`kpathsea' library... " >&6; } + CPPFLAGS="$KPATHSEA_INCLUDES $CPPFLAGS" + LIBS="$KPATHSEA_LIBS $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <kpathsea/kpathsea.h> +#include <kpathsea/version.h> +int +main (void) +{ +const char *version = kpathsea_version_string; +kpse_set_program_name("prog", "name"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + syslib_used=yes kpse_res=ok +else case e in #( + e) syslib_status=no kpse_res=failed ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 +printf "%s\n" "$kpse_res" >&6; } +fi + +## texk/ptexenc/ac/ptexenc.ac: configure.ac fragment for the TeX Live subdirectory texk/ptexenc/ +## basic check of system ptexenc +if test "x$need_ptexenc:$with_system_ptexenc" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`ptexenc' library" >&5 +printf %s "checking requested system \`ptexenc' library... " >&6; } + CPPFLAGS="$PTEXENC_INCLUDES $CPPFLAGS" + LIBS="$PTEXENC_LIBS $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ptexenc/ptexenc.h> +int +main (void) +{ +const char *version = ptexenc_version_string; +set_enc_string("prog", "name"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + syslib_used=yes kpse_res=ok +else case e in #( + e) syslib_status=no kpse_res=failed ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 +printf "%s\n" "$kpse_res" >&6; } +fi + +## libs/zlib/ac/zlib.ac: configure.ac fragment for the TeX Live subdirectory libs/zlib/ +## basic check of system zlib +if test "x$need_zlib:$with_system_zlib" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`zlib' library" >&5 +printf %s "checking requested system \`zlib' library... " >&6; } + CPPFLAGS="$ZLIB_INCLUDES $CPPFLAGS" + LIBS="$ZLIB_LIBS $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <zlib.h> +int +main (void) +{ +z_stream stream; +const char *version = zlibVersion(); +deflate(&stream, 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + syslib_used=yes kpse_res=ok +else case e in #( + e) syslib_status=no kpse_res=failed ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 +printf "%s\n" "$kpse_res" >&6; } +fi + +## libs/luajit/ac/luajit.ac: configure.ac fragment for the TeX Live subdirectory libs/luajit/ +## basic check of system luajit +if test "x$need_luajit:$with_system_luajit" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`luajit' library" >&5 +printf %s "checking requested system \`luajit' library... " >&6; } + CPPFLAGS="$LUAJIT_INCLUDES $CPPFLAGS" + LIBS="$LUAJIT_LIBS $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <luajit.h> +int +main (void) +{ +const char *v = LUAJIT_VERSION; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + syslib_used=yes kpse_res=ok +else case e in #( + e) syslib_status=no kpse_res=failed ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 +printf "%s\n" "$kpse_res" >&6; } +fi + +## libs/libpaper/ac/libpaper.ac: configure.ac fragment for the TeX Live subdirectory libs/libpaper/ +## basic check of system libpaper +if test "x$need_libpaper:$with_system_libpaper" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`libpaper' library" >&5 +printf %s "checking requested system \`libpaper' library... " >&6; } + CPPFLAGS="$LIBPAPER_INCLUDES $CPPFLAGS" + LIBS="$LIBPAPER_LIBS $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <paper.h> +int +main (void) +{ +const char *v = defaultpapername(); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + syslib_used=yes kpse_res=ok +else case e in #( + e) syslib_status=no kpse_res=failed ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 +printf "%s\n" "$kpse_res" >&6; } +fi + +## libs/libpng/ac/libpng.ac: configure.ac fragment for the TeX Live subdirectory libs/libpng/ +## basic check of system libpng +if test "x$need_libpng:$with_system_libpng" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`libpng' library" >&5 +printf %s "checking requested system \`libpng' library... " >&6; } + CPPFLAGS="$LIBPNG_INCLUDES $CPPFLAGS" + LIBS="$LIBPNG_LIBS $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <png.h> +int +main (void) +{ +png_structp png; png_voidp io; png_rw_ptr fn; +png_set_read_fn(png, io, fn); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + syslib_used=yes kpse_res=ok +else case e in #( + e) syslib_status=no kpse_res=failed ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 +printf "%s\n" "$kpse_res" >&6; } +fi + +## libs/freetype2/ac/freetype2.ac: configure.ac fragment for the TeX Live subdirectory libs/freetype2/ +## basic check of system freetype2 +if test "x$need_freetype2:$with_system_freetype2" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`freetype2' library" >&5 +printf %s "checking requested system \`freetype2' library... " >&6; } + CPPFLAGS="$FREETYPE2_INCLUDES $CPPFLAGS" + LIBS="$FREETYPE2_LIBS $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ft2build.h> +#include FT_FREETYPE_H +int +main (void) +{ +FT_Library library; FT_Init_FreeType(&library); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + syslib_used=yes kpse_res=ok +else case e in #( + e) syslib_status=no kpse_res=failed ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 +printf "%s\n" "$kpse_res" >&6; } fi -if test -z "$ac_cv_prog_PKG_CONFIG"; then - ac_ct_PKG_CONFIG=$PKG_CONFIG - # Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_PKG_CONFIG+y} + +## libs/potrace/ac/potrace.ac: configure.ac fragment for the TeX Live subdirectory libs/potrace/ +## basic check of system potrace +if test "x$need_potrace:$with_system_potrace" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`potrace' library" >&5 +printf %s "checking requested system \`potrace' library... " >&6; } + CPPFLAGS="$POTRACE_INCLUDES $CPPFLAGS" + LIBS="$POTRACE_LIBS $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <potracelib.h> +int +main (void) +{ +potrace_state_t st; +const char *version = potrace_version(); +potrace_state_free(&st); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" then : - printf %s "(cached) " >&6 + syslib_used=yes kpse_res=ok else case e in #( - e) if test -n "$ac_ct_PKG_CONFIG"; then - ac_cv_prog_ac_ct_PKG_CONFIG="$ac_ct_PKG_CONFIG" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_PKG_CONFIG="pkg-config" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi ;; + e) syslib_status=no kpse_res=failed ;; esac fi -ac_ct_PKG_CONFIG=$ac_cv_prog_ac_ct_PKG_CONFIG -if test -n "$ac_ct_PKG_CONFIG"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_PKG_CONFIG" >&5 -printf "%s\n" "$ac_ct_PKG_CONFIG" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 +printf "%s\n" "$kpse_res" >&6; } fi - if test "x$ac_ct_PKG_CONFIG" = x; then - PKG_CONFIG="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; +## libs/gd/ac/gd.ac: configure.ac fragment for the TeX Live subdirectory libs/gd/ +## basic check of system gd +if test "x$need_gd:$with_system_gd" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`gd' library" >&5 +printf %s "checking requested system \`gd' library... " >&6; } + CPPFLAGS="$GD_INCLUDES $CPPFLAGS" + LIBS="$GD_LIBS $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <gd.h> +int +main (void) +{ +gdImageCreate(1, 2); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + syslib_used=yes kpse_res=ok +else case e in #( + e) syslib_status=no kpse_res=failed ;; esac - PKG_CONFIG=$ac_ct_PKG_CONFIG - fi -else - PKG_CONFIG="$ac_cv_prog_PKG_CONFIG" fi -if $ICU_CONFIG --version >/dev/null 2>&1; then - ICU_INCLUDES=`$ICU_CONFIG --cppflags` - ICU_LIBS=`$ICU_CONFIG --ldflags-searchpath --ldflags-libsonly --ldflags-system` -elif $PKG_CONFIG --libs icu-uc icu-io >/dev/null 2>&1; then - ICU_INCLUDES=`$PKG_CONFIG --cflags icu-uc icu-io` - ICU_LIBS=`$PKG_CONFIG --libs icu-uc icu-io` -elif test "x$need_icu:$with_system_icu" = xyes:yes; then - as_fn_error $? "did not find either pkg-config or icu-config; one is required for system icu library support" "$LINENO" 5 +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 +printf "%s\n" "$kpse_res" >&6; } fi -if $PKG_CONFIG harfbuzz; then - HARFBUZZ_INCLUDES=`$PKG_CONFIG harfbuzz --cflags` - HARFBUZZ_LIBS=`$PKG_CONFIG harfbuzz --libs` -elif test "x$need_harfbuzz:$with_system_harfbuzz" = xyes:yes; then - as_fn_error $? "did not find harfbuzz" "$LINENO" 5 +## libs/pixman/ac/pixman.ac: configure.ac fragment for the TeX Live subdirectory libs/pixman/ +## basic check of system pixman +if test "x$need_pixman:$with_system_pixman" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`pixman' library" >&5 +printf %s "checking requested system \`pixman' library... " >&6; } + CPPFLAGS="$PIXMAN_INCLUDES $CPPFLAGS" + LIBS="$PIXMAN_LIBS $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <pixman.h> +int +main (void) +{ +const char *s = pixman_version_string(); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + syslib_used=yes kpse_res=ok +else case e in #( + e) syslib_status=no kpse_res=failed ;; +esac fi - -if $PKG_CONFIG luajit; then - LUAJIT_INCLUDES=`$PKG_CONFIG luajit --cflags` - LUAJIT_LIBS=`$PKG_CONFIG luajit --libs` -elif test "x$need_luajit:$with_system_luajit" = xyes:yes; then - as_fn_error $? "did not find luajit" "$LINENO" 5 +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 +printf "%s\n" "$kpse_res" >&6; } fi - - - - - -## texk/kpathsea/ac/kpathsea.ac: configure.ac fragment for the TeX Live subdirectory texk/kpathsea/ -## basic check of system kpathsea -if test "x$need_kpathsea:$with_system_kpathsea" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`kpathsea' library" >&5 -printf %s "checking requested system \`kpathsea' library... " >&6; } - CPPFLAGS="$KPATHSEA_INCLUDES $CPPFLAGS" - LIBS="$KPATHSEA_LIBS $LIBS" +## libs/cairo/ac/cairo.ac: configure.ac fragment for the TeX Live subdirectory libs/cairo/ +## basic check of system cairo +if test "x$need_cairo:$with_system_cairo" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`cairo' library" >&5 +printf %s "checking requested system \`cairo' library... " >&6; } + CPPFLAGS="$CAIRO_INCLUDES $CPPFLAGS" + LIBS="$CAIRO_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include <kpathsea/kpathsea.h> -#include <kpathsea/version.h> +#include <cairo.h> int main (void) { -const char *version = kpathsea_version_string; -kpse_set_program_name("prog", "name"); +const char *s = cairo_version_string(); ; return 0; } @@ -23538,22 +25832,20 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ printf "%s\n" "$kpse_res" >&6; } fi -## libs/zlib/ac/zlib.ac: configure.ac fragment for the TeX Live subdirectory libs/zlib/ -## basic check of system zlib -if test "x$need_zlib:$with_system_zlib" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`zlib' library" >&5 -printf %s "checking requested system \`zlib' library... " >&6; } - CPPFLAGS="$ZLIB_INCLUDES $CPPFLAGS" - LIBS="$ZLIB_LIBS $LIBS" +## libs/gmp/ac/gmp.ac: configure.ac fragment for the TeX Live subdirectory libs/gmp/ +## basic check of system gmp +if test "x$need_gmp:$with_system_gmp" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`gmp' library" >&5 +printf %s "checking requested system \`gmp' library... " >&6; } + CPPFLAGS="$GMP_INCLUDES $CPPFLAGS" + LIBS="$GMP_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include <zlib.h> +#include <gmp.h> int main (void) { -z_stream stream; -const char *version = zlibVersion(); -deflate(&stream, 0); +const char *s = gmp_version; ; return 0; } @@ -23571,20 +25863,20 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ printf "%s\n" "$kpse_res" >&6; } fi -## libs/luajit/ac/luajit.ac: configure.ac fragment for the TeX Live subdirectory libs/luajit/ -## basic check of system luajit -if test "x$need_luajit:$with_system_luajit" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`luajit' library" >&5 -printf %s "checking requested system \`luajit' library... " >&6; } - CPPFLAGS="$LUAJIT_INCLUDES $CPPFLAGS" - LIBS="$LUAJIT_LIBS $LIBS" +## libs/mpfr/ac/mpfr.ac: configure.ac fragment for the TeX Live subdirectory libs/mpfr/ +## basic check of system mpfr +if test "x$need_mpfr:$with_system_mpfr" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`mpfr' library" >&5 +printf %s "checking requested system \`mpfr' library... " >&6; } + CPPFLAGS="$MPFR_INCLUDES $CPPFLAGS" + LIBS="$MPFR_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include <luajit.h> +#include <mpfr.h> int main (void) { -const char *v = LUAJIT_VERSION; +const char *s = mpfr_get_version(); ; return 0; } @@ -23602,26 +25894,31 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ printf "%s\n" "$kpse_res" >&6; } fi -## libs/libpng/ac/libpng.ac: configure.ac fragment for the TeX Live subdirectory libs/libpng/ -## basic check of system libpng -if test "x$need_libpng:$with_system_libpng" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`libpng' library" >&5 -printf %s "checking requested system \`libpng' library... " >&6; } - CPPFLAGS="$LIBPNG_INCLUDES $CPPFLAGS" - LIBS="$LIBPNG_LIBS $LIBS" +## libs/xpdf/ac/xpdf.ac: configure.ac fragment for the TeX Live subdirectory libs/xpdf/ +## basic check of system xpdf (a.k.a. poppler, no longer supported in +## TL sources) +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test "x$need_xpdf:$with_system_xpdf" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`xpdf' library" >&5 +printf %s "checking requested system \`xpdf' library... " >&6; } + CPPFLAGS="$XPDF_INCLUDES $CPPFLAGS" + LIBS="$XPDF_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include <png.h> +#include <GfxFont.h> int main (void) { -png_structp png; png_voidp io; png_rw_ptr fn; -png_set_read_fn(png, io, fn); +GfxFont *gfxFont; gfxFont->isOk(); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO" +if ac_fn_cxx_try_link "$LINENO" then : syslib_used=yes kpse_res=ok else case e in #( @@ -23633,6 +25930,11 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 printf "%s\n" "$kpse_res" >&6; } fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu ## libs/zziplib/ac/zziplib.ac: configure.ac fragment for the TeX Live subdirectory libs/zziplib/ ## basic check of system zziplib @@ -23697,6 +25999,89 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ printf "%s\n" "$kpse_res" >&6; } fi +## libs/teckit/ac/teckit.ac: configure.ac fragment for the TeX Live subdirectory libs/teckit/ +## basic check of system teckit +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test "x$need_teckit:$with_system_teckit" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`teckit' library" >&5 +printf %s "checking requested system \`teckit' library... " >&6; } + CPPFLAGS="$TECKIT_INCLUDES $CPPFLAGS" + LIBS="$TECKIT_LIBS $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <teckit/TECkit_Engine.h> +int +main (void) +{ +TECkit_Converter converter; TECkit_DisposeConverter(converter); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO" +then : + syslib_used=yes kpse_res=ok +else case e in #( + e) syslib_status=no kpse_res=failed ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 +printf "%s\n" "$kpse_res" >&6; } +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +## libs/icu/ac/icu.ac: configure.ac fragment for the TeX Live subdirectory libs/icu/ +## basic check of system icu +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test "x$need_icu:$with_system_icu" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`icu' library" >&5 +printf %s "checking requested system \`icu' library... " >&6; } + CPPFLAGS="$ICU_INCLUDES $CPPFLAGS" + LIBS="$ICU_LIBS $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <unicode/ustring.h> +int +main (void) +{ +UErrorCode code; const UChar *src; UChar *dst; +u_strToLower(dst, -1, src, -1, NULL, &code); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO" +then : + syslib_used=yes kpse_res=ok +else case e in #( + e) syslib_status=no kpse_res=failed ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 +printf "%s\n" "$kpse_res" >&6; } +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + ## libs/harfbuzz/ac/harfbuzz.ac: configure.ac fragment for the TeX Live subdirectory libs/harfbuzz/ ## basic check of system harfbuzz if test "x$need_harfbuzz:$with_system_harfbuzz" = xyes:yes; then diff --git a/source/libs/README b/source/libs/README index be663eb9ba978280a78869013660987d57378dad..21a75a336a2fe1e3bb1d37761d3660ae1bc4e7a7 100644 --- a/source/libs/README +++ b/source/libs/README @@ -1,4 +1,4 @@ -$Id: README 74540 2025-03-08 22:22:06Z kakuto $ +$Id: README 74729 2025-03-24 00:38:36Z kakuto $ Public domain. Originally created by Karl Berry, 2005. Libraries we compile for TeX Live. @@ -28,7 +28,7 @@ graphite2 1.3.14 - checked 10apr20 https://sourceforge.net/projects/silgraphite/files/graphite2/ (requires C++11) -harfbuzz 10.4.0 - checked 09mar25 +harfbuzz 11.0.0 - checked 24mar25 https://github.com/harfbuzz/harfbuzz/releases/latest icu 76.1 - checked 27oct24 (requires C++17, e.g., g++13) @@ -52,7 +52,7 @@ luajit 2.1.0-beta3 - checked 20jun17 mpfi 1.5.4 - checked 1feb24 https://perso.ens-lyon.fr/nathalie.revol/software.html#download -mpfr 4.2.1 - checked 1feb24 +mpfr 4.2.2 - checked 21mar25 https://ftp.gnu.org/gnu/mpfr/ pixman 0.42.2 - no longer checked diff --git a/source/libs/harfbuzz/ChangeLog b/source/libs/harfbuzz/ChangeLog index 49a13b5b4c265a5bfabdfaaeb1d0270504542ee5..ed247d02c3ce5f8e297e4aab223c28e684633ca5 100644 --- a/source/libs/harfbuzz/ChangeLog +++ b/source/libs/harfbuzz/ChangeLog @@ -1,3 +1,8 @@ +2025-03-24 Akira Kakuto <kakuto@jcom.zaq.ne.jp> + + Import harfbuzz-11.0.0. + * version.ac, include/Makefile.am: Adjusted. + 2025-03-09 Akira Kakuto <kakuto@jcom.zaq.ne.jp> Import harfbuzz-10.4.0. diff --git a/source/libs/harfbuzz/TLpatches/ChangeLog b/source/libs/harfbuzz/TLpatches/ChangeLog index 32f6c06d46a584ee8a9c0a2e70716046831e53aa..fd8309b60b6b7829fff70dd2b8b97120b1456ec5 100644 --- a/source/libs/harfbuzz/TLpatches/ChangeLog +++ b/source/libs/harfbuzz/TLpatches/ChangeLog @@ -1,3 +1,8 @@ +2025-03-24 Akira Kakuto <kakuto@jcom.zaq.ne.jp> + + Imported harfbuzz-11.0.0 source tree from: + https://github.com/harfbuzz/harfbuzz/releases/download/11.0.0/ + 2025-03-09 Akira Kakuto <kakuto@jcom.zaq.ne.jp> Imported harfbuzz-10.4.0 source tree from: diff --git a/source/libs/harfbuzz/TLpatches/TL-Changes b/source/libs/harfbuzz/TLpatches/TL-Changes index 91b5aa9434eed3bf92759ba782d9264e9eacc50e..7f26b1d211ec2dd78c5ede5fb07657f4c4bc6ac0 100644 --- a/source/libs/harfbuzz/TLpatches/TL-Changes +++ b/source/libs/harfbuzz/TLpatches/TL-Changes @@ -1,5 +1,5 @@ -Changes applied to the harfbuzz-10.4.0/ tree as obtained from: - https://github.com/harfbuzz/harfbuzz/releases/download/10.4.0/ +Changes applied to the harfbuzz-11.0.0/ tree as obtained from: + https://github.com/harfbuzz/harfbuzz/releases/download/11.0.0/ Removed: .clang-format diff --git a/source/libs/harfbuzz/configure b/source/libs/harfbuzz/configure index 43d9ee0e231f31dafaa39453c59e97e41f29cd57..8ae6a92113812fa594e59739552b0729dd5d5a68 100755 --- a/source/libs/harfbuzz/configure +++ b/source/libs/harfbuzz/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for harfbuzz (TeX Live) 10.4.0. +# Generated by GNU Autoconf 2.72 for harfbuzz (TeX Live) 11.0.0. # # Report bugs to <tex-k@tug.org>. # @@ -604,8 +604,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='harfbuzz (TeX Live)' PACKAGE_TARNAME='harfbuzz--tex-live-' -PACKAGE_VERSION='10.4.0' -PACKAGE_STRING='harfbuzz (TeX Live) 10.4.0' +PACKAGE_VERSION='11.0.0' +PACKAGE_STRING='harfbuzz (TeX Live) 11.0.0' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1341,7 +1341,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures harfbuzz (TeX Live) 10.4.0 to adapt to many kinds of systems. +'configure' configures harfbuzz (TeX Live) 11.0.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1413,7 +1413,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of harfbuzz (TeX Live) 10.4.0:";; + short | recursive ) echo "Configuration of harfbuzz (TeX Live) 11.0.0:";; esac cat <<\_ACEOF @@ -1518,7 +1518,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -harfbuzz (TeX Live) configure 10.4.0 +harfbuzz (TeX Live) configure 11.0.0 generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -2075,7 +2075,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by harfbuzz (TeX Live) $as_me 10.4.0, which was +It was created by harfbuzz (TeX Live) $as_me 11.0.0, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -5252,7 +5252,7 @@ fi # Define the identity of the package. PACKAGE='harfbuzz--tex-live-' - VERSION='10.4.0' + VERSION='11.0.0' # Some tools Automake needs. @@ -5440,10 +5440,10 @@ WARNING_CFLAGS=$kpse_cv_warning_cflags echo 'tldbg:KPSE_BASIC done (pkg=harfbuzz, amopt=no-define)' >&5 -HB_VERSION_MAJOR=10 -HB_VERSION_MINOR=4 +HB_VERSION_MAJOR=11 +HB_VERSION_MINOR=0 HB_VERSION_MICRO=0 -HB_VERSION=10.4.0 +HB_VERSION=11.0.0 ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -9292,7 +9292,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by harfbuzz (TeX Live) $as_me 10.4.0, which was +This file was extended by harfbuzz (TeX Live) $as_me 11.0.0, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -9360,7 +9360,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -harfbuzz (TeX Live) config.status 10.4.0 +harfbuzz (TeX Live) config.status 11.0.0 configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt b/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt index 3b4f5aa61e868e6a42e81d7582ae639c2b7db691..203f2396c7a4479878aaf56dfffc0b89d922be23 100644 --- a/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt +++ b/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt @@ -233,7 +233,7 @@ if (HB_HAVE_FREETYPE AND NOT TARGET freetype) set (CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${FREETYPE_INCLUDE_DIRS}) set (CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${FREETYPE_LIBRARIES}) - check_funcs(FT_Get_Var_Blend_Coordinates FT_Set_Var_Blend_Coordinates FT_Done_MM_Var) + check_funcs(FT_Get_Var_Blend_Coordinates FT_Set_Var_Blend_Coordinates FT_Done_MM_Var FT_Get_Transform) endif () if (HB_HAVE_FREETYPE) diff --git a/source/libs/harfbuzz/harfbuzz-src/NEWS b/source/libs/harfbuzz/harfbuzz-src/NEWS index 4e7dbe0d925334055743b0633523b9ced2af9a45..363bcaf827946268e56c58fe01b9976648f3baf5 100644 --- a/source/libs/harfbuzz/harfbuzz-src/NEWS +++ b/source/libs/harfbuzz/harfbuzz-src/NEWS @@ -1,3 +1,64 @@ +Overview of changes leading to 11.0.0 +Monday, March 24, 2025 +==================================== +- There are three new font-functions implementations (integrations) in this + release: + * `hb-coretext` has gained one, calling into the CoreText library, + * `hb-directwrite` has gained one, calling into the DirectWrite library. + * `hb-fontations` has gained one, calling into the Skrifa Rust library. + All three are mostly useful for performance and correctness testing, but some + clients might find them useful. + An API is added to use them from a single API by providing a backend name + string: + * `hb_font_set_funcs_using()` +- Several new APIs are added, to load a font-face using different + "face-loaders", and a single entry point to them all using a loader name + string: + * `hb_ft_face_create_from_file_or_fail()` and + `hb_ft_face_create_from_blob_or_fail()` + * `hb_coretext_face_create_from_file_or_fail()` and + `hb_coretext_face_create_from_blob_or_fail()` + * `hb_directwrite_face_create_from_file_or_fail()` and + `hb_directwrite_face_create_from_blob_or_fail()` + * `hb_face_create_from_file_or_fail_using()` +- All drawing and painting operations using the default, `hb-ot` functions have + become memory allocation-free. +- Several performance optimizations have been implemented. +- Application of the `trak` table during shaping has been improved. +- The `directwrite` shaper now supports font variations, and correctly applies + user features. +- The `hb-directwrite` API and shaper has graduated from experimental. +- Various bug fixes and other improvements. + +- New API: ++hb_malloc ++hb_calloc ++hb_realloc ++hb_free ++hb_face_list_loaders ++hb_face_create_or_fail_using ++hb_face_create_from_file_or_fail_using ++hb_font_list_funcs ++hb_font_set_funcs_using ++hb_coretext_face_create_from_blob_or_fail ++hb_directwrite_face_create_from_file_or_fail ++hb_directwrite_face_create_from_blob_or_fail ++hb_directwrite_font_create ++hb_directwrite_font_get_dw_font_face ++hb_directwrite_font_set_funcs ++hb_fontations_font_set_funcs ++hb_ft_face_create_from_blob_or_fail ++hb_paint_push_font_transform ++hb_paint_push_inverse_font_transform ++HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES ++HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE ++HB_BUFFER_CLUSTER_LEVEL_IS_GRAPHEMES ++HB_BUFFER_CLUSTER_LEVEL_IS_CHARACTERS + +- Deprecated API: ++hb_directwrite_font_get_dw_font + + Overview of changes leading to 10.4.0 Saturday, March 1, 2025 ==================================== diff --git a/source/libs/harfbuzz/harfbuzz-src/README.md b/source/libs/harfbuzz/harfbuzz-src/README.md index 02c1554bd19271970f8b0bb5ab99352d7adcec35..f94a83b54b60718b34d71cb10ffb93edbe381a99 100644 --- a/source/libs/harfbuzz/harfbuzz-src/README.md +++ b/source/libs/harfbuzz/harfbuzz-src/README.md @@ -51,6 +51,8 @@ For custom configurations, see [CONFIG.md](CONFIG.md). For testing and profiling, see [TESTING.md](TESTING.md). +For cross-compiling to Windows from Linux or macOS, see [README.mingw.md](README.mingw.md). + To get a better idea of where HarfBuzz stands in the text rendering stack you may want to read [State of Text Rendering 2024][6]. Here are a few presentation slides about HarfBuzz at the diff --git a/source/libs/harfbuzz/harfbuzz-src/README.mingw.md b/source/libs/harfbuzz/harfbuzz-src/README.mingw.md new file mode 100644 index 0000000000000000000000000000000000000000..aada0f79339dded0993c8657f9e598ffe24d3b65 --- /dev/null +++ b/source/libs/harfbuzz/harfbuzz-src/README.mingw.md @@ -0,0 +1,211 @@ +Most HarfBuzz developers do so on Linux or macOS. However, HarfBuzz is a +cross-platform library and it is important to ensure that it works on Windows +as well. In particular, we use this workflow to develop and test the HarfBuzz +Uniscribe shaper and DirectWrite shaper and font backend, all from Linux or +macOS. + +This document provides instructions for cross-compiling HarfBuzz on Linux or +macOS, for Windows, using the MinGW toolchain, and running tests and utilties +under Wine. + +We then discuss using native Windows Uniscribe or DirectWrite DLLs, which +allows you to test HarfBuzz's shaping against the Microsoft shaping engines +instead of those provided by Wine. + +This document assumes that you are familiar with building HarfBuzz on Linux or +macOS. + +You can build for 32bit or 64bit Windows. If your intention is to use a native +Uniscribe usp10.dll from Windows 7 or before, you would need to build for 32bit. +If you want to use a native DirectWrite DLL from Windows 10 or later, you would +need to build for 64bit. + +We suggest you read to the end of this document before starting, as it provides +a few different ways to build and test HarfBuzz for Windows. + +1. Install Wine. + + - Fedora: `dnf install wine`. + - Ubuntu, 32bit: `apt install wine wine32`. + - Ubuntu, 64bit: `apt install wine wine64`. + - Mac: `brew install wine-stable`. + +2. Install the `mingw-w64` cross-compiler. + + - Fedora, 32bit: `dnf install mingw32-gcc-c++` + - Fedora, 64bit: `dnf install mingw64-gcc-c++` + - Ubuntu, 32bit: `apt install g++-mingw-w64-i686` + - Ubuntu, 64bit: `apt install g++-mingw-w64-x86-64` + - Mac: `brew install mingw-w64` + +3. Install dependencies. + +First, make sure you do not have the mingw32 harfbuzz package, as that will +override our own build: + + - Fedora, 32bit: `dnf remove mingw32-harfbuzz` + - Fedora, 64bit: `dnf remove mingw64-harfbuzz` + +Then install the actual dependencies: + + - Fedora, 32bit: `dnf install mingw32-glib2 mingw32-cairo mingw32-freetype` + - Fedora, 64bit: `dnf install mingw64-glib2 mingw64-cairo mingw64-freetype` + +If you cannot find these packages for your distribution, or you are on macOS, +you can skip to the next step, as meson will automatically download and build +the dependencies for you. + +4. If you are familiar with `meson`, you can use the cross-compile files we +provide to find your way around. But we do not recommend this way. Read until +the end of this section before deciding which one to use. + + - 32bit: `meson --cross-file=.ci/win32-cross-file.txt build-win -Dglib-enabled -Dcairo=enabled -Dgdi=enabled -Ddirectwrite=enabled` + - 64bit: `meson --cross-file=.ci/win64-cross-file.txt build-win -Dglib-enabled -Dcairo=enabled -Dgdi=enabled -Ddirectwrite=enabled` + +In which case, you will proceed to run `ninja` as usual to build: + + - `ninja -C build-win` + +Or you can simply invoke the scripts we provide for our Continuous Integration +system, to configure and build HarfBuzz for you. This is the easiest way to +build HarfBuzz for Windows and how we build our Windows binaries: + + - 32bit: `./.ci/build-win.sh 32 && ln -s build-win32 build-win` + - 64bit: `./.ci/build-win.sh 64 && ln -s build-win64 build-win` + +This might take a while, since, if you do not have the dependencies installed, +meson will download and build them for you. + +5. If everything succeeds, you should have the `hb-shape.exe`, `hb-view.exe`, +`hb-subset.exe`, and `hb-info.exe` executables in `build-win/util`. + +6. Configure your wine to find system mingw libraries. While there, set it also +to find the built HarfBuzz DLLs: + + - Fedora, 32bit: `export WINEPATH="$HOME/harfbuzz/build-win/src;/usr/i686-w64-mingw32/sys-root/mingw/bin"` + - Fedora, 64bit: `export WINEPATH="$HOME/harfbuzz/build-win/src;/usr/x86_64-w64-mingw32/sys-root/mingw/bin"` + - Other systems: `export WINEPATH="$HOME/harfbuzz/build-win/src"` + +Adjust for the path where you have built HarfBuzz. You might want to add this +to your `.bashrc` or `.zshrc` file. + +Alternatively, can skip this step if commands are run through the `meson devenv` +command, which we will introduce in the next step. I personally find it more +convenient to set the `WINEPATH` variable, as it allows me to run the executables +directly from the shell. + +7. Run the `hb-shape` executable under Wine: + + - `wine build-win/util/hb-shape.exe perf/fonts/Roboto-Regular.ttf Test` + +Or using `meson devenv to do the same: + + - `meson devenv -C build-win util/hb-shape.exe $PWD/perf/fonts/Roboto-Regular.ttf Test` + +You probably will get lots of Wine warnings, but if all works fine, you +should see: +``` +[gid57=0+1123|gid74=1+1086|gid88=2+1057|gid89=3+670] +``` + +You can make Wine less verbose, without hiding all errors, by setting: + + - `export WINEDEBUG=fixme-all,warn-all,err-plugplay,err-seh,err-rpc,err-ntoskrnl,err-winediag,err-systray,err-hid` + +Add this to your `.bashrc` or `.zshrc` file as well. + +Next, let's try some non-Latin text. Unfortunately, the command-line parsing of +our cross-compiled glib is not quite Unicode-aware, at least when run under +Wine. So you will need to find some other way to feed Unicode text to the +shaper. There are three different ways you can try: + + - `echo حرف | wine build-win/util/hb-shape.exe perf/fonts/Amiri-Regular.ttf` + - `wine build-win/util/hb-shape.exe perf/fonts/Amiri-Regular.ttf -u 062D,0631,0641` + - `wine build-win/util/hb-shape.exe perf/fonts/Amiri-Regular.ttf --text-file harf.txt` + +To get the Unicode codepoints for a string, you can use the `hb-unicode-decode` +utility: +``` +$ test/shape/hb-unicode-decode حرف +U+062D,U+0631,U+0641 +``` + +8. Next, let's try the `hb-view` utility. By default, `hb-view` outputs ANSI text, +which Wine will not display correctly. You can use the `-o` option to redirect the +output to a file, or just redirect the output using the shell, which will produce +a PNG file. + + - `wine build-win/util/hb-view.exe perf/fonts/Roboto-Regular.ttf Test > test.png` + +7. As noted, if your Linux has `binfmt_misc` enabled, you can run the executables +directly. If not, you can modify the cross-file to use the `exe_wrapper` option as +specified before. + + - `build-win/util/hb-shape.exe perf/fonts/Roboto-Regular.ttf Test` + +If that does not work, you can use the `wine` command as shown above. + +10. You can try running the test suite. If on Linux with `binfmt_misc` enabled, you +can run the tests directly: + + - `ninja -C build-win test` + +For other situations, use `meson devenv`: + + - `meson devenv -C build-win ninja test` + +This might take a couple of minutes to run. Running under Wine is expensive, so +be patient. + +If all goes well, tests should run. If all is well, you should probably see about +400 tests pass, some skipped, but none failing. + +11. In the above testing situation, the `directwrite` test will be disabled +automatically upon detection of running under Wine. The reason the `directwrite` +test would otherwise fails is that we are running against the Wine-provided +DirectWrite DLL, which is an incomplete reimplementation of the DirectWrite API +by Wine, and not the real thing. + +If you want to test the Uniscribe or DirectWrite shapers against the real +Uniscribe / DirectWrite, you can follow the instructions below. + +11. Old Uniscribe: Assuming a 32bit build for now. + +Bring a 32bit version of `usp10.dll` for yourself from +`C:\Windows\SysWOW64\usp10.dll` of your 64bit Windows installation, +or `C:\Windows\System32\usp10.dll` for 32bit Windows installation. + +You want one from Windows 7 or earlier. One that is not just a proxy for +`TextShaping.dll`. Rule of thumb, your `usp10.dll` should have a size more +than 500kb. + +Put the file in `~/.wine/drive_c/windows/syswow64/` so wine can find it. + +You can now tell wine to use the native `usp10.dll`: + + - `export WINEDLLOVERRIDES="usp10=n"` + - `wine build-win/util/hb-shape.exe perf/fonts/Roboto-Regular.ttf Test --shaper=uniscribe` + +12. DirectWrite and new Uniscribe: You can use the same method to test the +DirectWrite shaper against the native DirectWrite DLL. Try with a 64bit build +this time. + +Bring `TextShaping.dll`, `DWrite.dll`, and `usp10.dll` from your 64bit Windows +installation (`C:\Windows\System32`) to `~/.wine/drive_c/windows/system32/`. + +You want the ones from Windows 10 or later. You might have some luck downloading +them from the internet, but be careful with the source. I had success with the +DLLs from [https://dllme.com](dllme.com), but I cannot vouch for the site. + +You can now tell wine to use the native DirectWrite: + + - `export WINEDLLOVERRIDES="textshaping,dwrite,usp10=n"` + - `wine build-win/util/hb-shape.exe perf/fonts/Roboto-Regular.ttf Test --shaper=directwrite` + +If all works well, you should be able to rerun the tests and see all pass this time. + +13. For some old instructions on how to test HarfBuzz's native Indic shaper against +Uniscribe, see: https://github.com/harfbuzz/harfbuzz/issues/3671 + +14. That's it! If you made it this far, you are now able to develop and test +HarfBuzz on Windows, from Linux or macOS. Enjoy! diff --git a/source/libs/harfbuzz/harfbuzz-src/RELEASING.md b/source/libs/harfbuzz/harfbuzz-src/RELEASING.md index e510022a29e42a52717d3868e047e567b7639aa4..a8a6705f295b291aa68cd7d5cd47410d350d18ef 100644 --- a/source/libs/harfbuzz/harfbuzz-src/RELEASING.md +++ b/source/libs/harfbuzz/harfbuzz-src/RELEASING.md @@ -17,7 +17,7 @@ - [ ] Based on severity of changes, decide whether it's a minor or micro release number bump. -- [ ] Search for 'XSince: REPLACEME' on the repository and replace it with the chosen version for the release, e.g. 'Since: 1.4.7'. +- [ ] Search for 'REPLACEME' on the repository and replace it with the chosen version for the release, e.g. 'Since: 1.4.7'. - [ ] Make sure you have correct date and new version at the top of NEWS file. diff --git a/source/libs/harfbuzz/harfbuzz-src/meson.build b/source/libs/harfbuzz/harfbuzz-src/meson.build index 1460c2a9de7ddc3bac4cb7a7ced7d51f9350f675..91c94bf0a356b1f3cc8439cbadc6bc20d4b7fb05 100644 --- a/source/libs/harfbuzz/harfbuzz-src/meson.build +++ b/source/libs/harfbuzz/harfbuzz-src/meson.build @@ -1,11 +1,12 @@ -project('harfbuzz', 'c', 'cpp', +project('harfbuzz', ['c', 'cpp'], meson_version: '>= 0.55.0', - version: '10.4.0', + version: '11.0.0', default_options: [ 'cpp_eh=none', # Just to support msvc, we are passing -fno-exceptions also anyway # 'cpp_rtti=false', # Do NOT enable, wraps inherit it and ICU needs RTTI 'cpp_std=c++11', 'wrap_mode=nofallback', # Use --wrap-mode=default to revert, https://github.com/harfbuzz/harfbuzz/pull/2548 + 'buildtype=debugoptimized', ], ) @@ -102,44 +103,36 @@ check_funcs = [ m_dep = cpp.find_library('m', required: false) -if meson.version().version_compare('>=0.60.0') +# Painful hack to handle multiple dependencies but also respect options +if get_option('freetype').disabled() + freetype_dep = dependency('', required: false) +else # Sadly, FreeType's versioning schemes are different between pkg-config and CMake - # pkg-config: freetype2, cmake: Freetype + + # Try pkg-config name freetype_dep = dependency('freetype2', version: freetype_min_version, method: 'pkg-config', required: false, allow_fallback: false) if not freetype_dep.found() - freetype_dep = dependency('FreeType', + # Try cmake name + freetype_dep = dependency('Freetype', version: freetype_min_version_actual, method: 'cmake', - required: get_option('freetype'), - default_options: ['harfbuzz=disabled'], - allow_fallback: true) - endif -else - # painful hack to handle multiple dependencies but also respect options - freetype_opt = get_option('freetype') - # we want to handle enabled manually after fallbacks, but also handle disabled normally - if freetype_opt.enabled() - freetype_opt = false - endif - # try pkg-config name - freetype_dep = dependency('freetype2', version: freetype_min_version, method: 'pkg-config', required: freetype_opt) - # when disabled, leave it not-found - if not freetype_dep.found() and not get_option('freetype').disabled() - # Try cmake name - freetype_dep = dependency('Freetype', version: freetype_min_version_actual, method: 'cmake', required: false) - # Subproject fallback, `allow_fallback: true` means the fallback will be - # tried even if the freetype option is set to `auto`. + required: false, + allow_fallback: false) + # Subproject fallback if not freetype_dep.found() - freetype_dep = dependency('freetype2', - version: freetype_min_version, - method: 'pkg-config', + freetype_proj = subproject('freetype2', + version: freetype_min_version_actual, required: get_option('freetype'), - default_options: ['harfbuzz=disabled'], - allow_fallback: true) + default_options: ['harfbuzz=disabled']) + if freetype_proj.found() + freetype_dep = freetype_proj.get_variable('freetype_dep') + else + freetype_dep = dependency('', required: false) + endif endif endif endif @@ -227,16 +220,18 @@ endif chafa_dep = dependency('chafa', version: chafa_min_version, required: get_option('chafa')) +fontations_dep_found = false +if get_option('fontations').enabled() + add_languages(['rust'], native: false, required : true) + fontations_dep_found = true +endif + conf = configuration_data() incconfig = include_directories('.') add_project_arguments('-DHAVE_CONFIG_H', language: ['c', 'cpp']) -warn_cflags = [ - '-Wno-non-virtual-dtor', -] - -cpp_args = cpp.get_supported_arguments(warn_cflags) +cpp_args = [] if glib_dep.found() conf.set('HAVE_GLIB', 1) @@ -272,6 +267,10 @@ if chafa_dep.found() conf.set('HAVE_CHAFA', 1) endif +if fontations_dep_found + conf.set('HAVE_FONTATIONS', 1) +endif + if wasm_dep.found() conf.set('HAVE_WASM', 1) conf.set('HB_WASM_MODULE_DIR', '"'+get_option('prefix')+'/'+get_option('libdir')+'/harfbuzz/wasm"') @@ -315,7 +314,7 @@ endif gdi_uniscribe_deps = [] # GDI (Uniscribe) (Windows) if host_machine.system() == 'windows' and not get_option('gdi').disabled() - if (get_option('directwrite').enabled() and + if (get_option('gdi').enabled() and not (cpp.has_header('usp10.h') and cpp.has_header('windows.h'))) error('GDI/Uniscribe was enabled explicitly, but required headers are missing.') endif @@ -335,10 +334,9 @@ endif # DirectWrite (Windows) if host_machine.system() == 'windows' and not get_option('directwrite').disabled() - if get_option('directwrite').enabled() and not cpp.has_header('dwrite_1.h') + if get_option('directwrite').enabled() and not cpp.has_header('dwrite_3.h') error('DirectWrite was enabled explicitly, but required header is missing.') endif - conf.set('HAVE_DIRECTWRITE', 1) endif diff --git a/source/libs/harfbuzz/harfbuzz-src/meson_options.txt b/source/libs/harfbuzz/harfbuzz-src/meson_options.txt index c53cf45fcb41e2e632dd15b584dd2abb3613a0ab..86258f89d0d1edbf24d0fd2d2641394fc5ae1d45 100644 --- a/source/libs/harfbuzz/harfbuzz-src/meson_options.txt +++ b/source/libs/harfbuzz/harfbuzz-src/meson_options.txt @@ -15,10 +15,12 @@ option('graphite2', type: 'feature', value: 'disabled', description: 'Enable Graphite2 complementary shaper') option('freetype', type: 'feature', value: 'auto', description: 'Enable freetype interop helpers') +option('fontations', type: 'feature', value: 'disabled', + description: 'Enabled fontations font functions') option('gdi', type: 'feature', value: 'disabled', description: 'Enable GDI helpers and Uniscribe shaper backend (Windows only)') option('directwrite', type: 'feature', value: 'disabled', - description: 'Enable DirectWrite shaper backend on Windows (experimental)') + description: 'Enable DirectWrite shaper backend on Windows') option('coretext', type: 'feature', value: 'disabled', description: 'Enable CoreText shaper backend on macOS') option('wasm', type: 'feature', value: 'disabled', diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh index cf10e894a410065418737cf8d602de0028ff55f9..16cd96e32d2eceb7b4a3cca6a0d6dd9432598608 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh @@ -47,6 +47,11 @@ namespace OT { struct hb_paint_context_t; } +struct hb_colr_scratch_t +{ + hb_paint_extents_context_t paint_extents; +}; + namespace OT { struct COLR; @@ -90,7 +95,8 @@ public: font (font_), palette ( #ifndef HB_NO_COLOR - font->face->table.CPAL->get_palette_colors (palette_) + // https://github.com/harfbuzz/harfbuzz/issues/5116 + font->face->table.CPAL->get_palette_colors (palette_ < font->face->table.CPAL->get_palette_count () ? palette_ : 0) #endif ), foreground (foreground_), @@ -932,9 +938,9 @@ struct PaintGlyph void paint_glyph (hb_paint_context_t *c) const { TRACE_PAINT (this); - c->funcs->push_inverse_root_transform (c->data, c->font); + c->funcs->push_inverse_font_transform (c->data, c->font); c->funcs->push_clip_glyph (c->data, gid, c->font); - c->funcs->push_root_transform (c->data, c->font); + c->funcs->push_font_transform (c->data, c->font); c->recurse (this+paint); c->funcs->pop_transform (c->data); c->funcs->pop_clip (c->data); @@ -1511,10 +1517,12 @@ struct PaintComposite void paint_glyph (hb_paint_context_t *c) const { TRACE_PAINT (this); + c->funcs->push_group (c->data); c->recurse (this+backdrop); c->funcs->push_group (c->data); c->recurse (this+src); c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int) mode); + c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); } HBUINT8 format; /* format = 32 */ @@ -2079,6 +2087,8 @@ struct COLR { static constexpr hb_tag_t tableTag = HB_OT_TAG_COLR; + bool has_data () const { return has_v0_data () || version; } + bool has_v0_data () const { return numBaseGlyphs; } bool has_v1_data () const { @@ -2112,7 +2122,53 @@ struct COLR { accelerator_t (hb_face_t *face) { colr = hb_sanitize_context_t ().reference_table<COLR> (face); } - ~accelerator_t () { this->colr.destroy (); } + + ~accelerator_t () + { + auto *scratch = cached_scratch.get_relaxed (); + if (scratch) + { + scratch->~hb_colr_scratch_t (); + hb_free (scratch); + } + + colr.destroy (); + } + + + bool has_data () const { return colr->has_data (); } + +#ifndef HB_NO_PAINT + bool + get_extents (hb_font_t *font, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents) const + { + if (unlikely (!has_data ())) return false; + + hb_colr_scratch_t *scratch = acquire_scratch (); + if (unlikely (!scratch)) return true; + bool ret = colr->get_extents (font, glyph, extents, *scratch); + release_scratch (scratch); + return ret; + } + + bool paint_glyph (hb_font_t *font, + hb_codepoint_t glyph, + hb_paint_funcs_t *funcs, void *data, + unsigned int palette_index, + hb_color_t foreground, + bool clip = true) const + { + if (unlikely (!has_data ())) return false; + + hb_colr_scratch_t *scratch = acquire_scratch (); + if (unlikely (!scratch)) return true; + bool ret = colr->paint_glyph (font, glyph, funcs, data, palette_index, foreground, clip, *scratch); + release_scratch (scratch); + return ret; + } +#endif bool is_valid () { return colr.get_blob ()->length; } @@ -2148,7 +2204,33 @@ struct COLR { return colr->get_delta_set_index_map_ptr (); } private: + + hb_colr_scratch_t *acquire_scratch () const + { + hb_colr_scratch_t *scratch = cached_scratch.get_acquire (); + + if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr))) + { + scratch = (hb_colr_scratch_t *) hb_calloc (1, sizeof (hb_colr_scratch_t)); + if (unlikely (!scratch)) + return nullptr; + } + + return scratch; + } + void release_scratch (hb_colr_scratch_t *scratch) const + { + if (!cached_scratch.cmpexch (nullptr, scratch)) + { + scratch->~hb_colr_scratch_t (); + hb_free (scratch); + } + } + + public: hb_blob_ptr_t<COLR> colr; + private: + hb_atomic_t<hb_colr_scratch_t *> cached_scratch; }; void closure_glyphs (hb_codepoint_t glyph, @@ -2520,7 +2602,10 @@ struct COLR #ifndef HB_NO_PAINT bool - get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const + get_extents (hb_font_t *font, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents, + hb_colr_scratch_t &scratch) const { ItemVarStoreInstancer instancer (get_var_store_ptr (), @@ -2534,10 +2619,10 @@ struct COLR } auto *extents_funcs = hb_paint_extents_get_funcs (); - hb_paint_extents_context_t extents_data; - bool ret = paint_glyph (font, glyph, extents_funcs, &extents_data, 0, HB_COLOR(0,0,0,0)); + scratch.paint_extents.clear (); + bool ret = paint_glyph (font, glyph, extents_funcs, &scratch.paint_extents, 0, HB_COLOR(0,0,0,0), true, scratch); - hb_extents_t e = extents_data.get_extents (); + auto e = scratch.paint_extents.get_extents (); if (e.is_void ()) { extents->x_bearing = 0; @@ -2547,6 +2632,7 @@ struct COLR } else { + // Ugh. We need to undo the synthetic slant here. Leave it for now. :-(. extents->x_bearing = e.xmin; extents->y_bearing = e.ymax; extents->width = e.xmax - e.xmin; @@ -2583,7 +2669,12 @@ struct COLR #ifndef HB_NO_PAINT bool - paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette_index, hb_color_t foreground, bool clip = true) const + paint_glyph (hb_font_t *font, + hb_codepoint_t glyph, + hb_paint_funcs_t *funcs, void *data, + unsigned int palette_index, hb_color_t foreground, + bool clip, + hb_colr_scratch_t &scratch) const { ItemVarStoreInstancer instancer (get_var_store_ptr (), get_delta_set_index_map_ptr (), @@ -2609,6 +2700,7 @@ struct COLR if (get_clip (glyph, &extents, instancer)) { font->scale_glyph_extents (&extents); + font->synthetic_glyph_extents (&extents); c.funcs->push_clip_rectangle (c.data, extents.x_bearing, extents.y_bearing + extents.height, @@ -2618,15 +2710,16 @@ struct COLR else { auto *extents_funcs = hb_paint_extents_get_funcs (); - hb_paint_extents_context_t extents_data; + scratch.paint_extents.clear (); paint_glyph (font, glyph, - extents_funcs, &extents_data, + extents_funcs, &scratch.paint_extents, palette_index, foreground, - false); + false, + scratch); - hb_extents_t extents = extents_data.get_extents (); - is_bounded = extents_data.is_bounded (); + auto extents = scratch.paint_extents.get_extents (); + is_bounded = scratch.paint_extents.is_bounded (); c.funcs->push_clip_rectangle (c.data, extents.xmin, @@ -2636,7 +2729,7 @@ struct COLR } } - c.funcs->push_root_transform (c.data, font); + c.funcs->push_font_transform (c.data, font); if (is_bounded) c.recurse (*paint); @@ -2714,9 +2807,7 @@ void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const return; const Paint &paint = paint_offset_lists.get_paint (i); - c->funcs->push_group (c->data); c->recurse (paint); - c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); } } @@ -2728,7 +2819,7 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const if (unlikely (!node.visit (gid))) return; - c->funcs->push_inverse_root_transform (c->data, c->font); + c->funcs->push_inverse_font_transform (c->data, c->font); if (c->funcs->color_glyph (c->data, gid, c->font)) { c->funcs->pop_transform (c->data); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.cc b/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.cc index 3b9eec4fb3be4a34542fd02602ff9773f6ed93d2..5b43f187f10e706c7392682d0ca58e1b9415f508 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.cc @@ -126,24 +126,18 @@ hb_transforming_pen_get_funcs () return static_transforming_pen_funcs.get_unconst (); } - hb_ubytes_t -VarComponent::get_path_at (hb_font_t *font, +VarComponent::get_path_at (const hb_varc_context_t &c, hb_codepoint_t parent_gid, - hb_draw_session_t &draw_session, hb_array_t<const int> coords, hb_transform_t total_transform, hb_ubytes_t total_record, - hb_decycler_t *decycler, - signed *edges_left, - signed depth_left, - hb_glyf_scratch_t &scratch, VarRegionList::cache_t *cache) const { const unsigned char *end = total_record.arrayZ + total_record.length; const unsigned char *record = total_record.arrayZ; - auto &VARC = *font->face->table.VARC->table; + auto &VARC = *c.font->face->table.VARC->table; auto &varStore = &VARC+VARC.varStore; #define READ_UINT32VAR(name) \ @@ -193,9 +187,9 @@ VarComponent::get_path_at (hb_font_t *font, // Axis values - auto &axisIndices = scratch.axisIndices; + auto &axisIndices = c.scratch.axisIndices; axisIndices.clear (); - auto &axisValues = scratch.axisValues; + auto &axisValues = c.scratch.axisValues; axisValues.clear (); if (flags & (unsigned) flags_t::HAVE_AXES) { @@ -222,7 +216,7 @@ VarComponent::get_path_at (hb_font_t *font, * limit on the max number of coords for now. */ if ((flags & (unsigned) flags_t::RESET_UNSPECIFIED_AXES) || coords.length > HB_VAR_COMPOSITE_MAX_AXES) - component_coords = hb_array<int> (font->coords, font->num_coords); + component_coords = hb_array<int> (c.font->coords, c.font->num_coords); // Transform @@ -316,14 +310,18 @@ VarComponent::get_path_at (hb_font_t *font, transform.scaleY = transform.scaleX; total_transform.transform (transform.to_transform ()); - total_transform.scale (font->x_mult ? 1.f / font->x_multf : 0.f, - font->y_mult ? 1.f / font->y_multf : 0.f); + total_transform.scale (c.font->x_mult ? 1.f / c.font->x_multf : 0.f, + c.font->y_mult ? 1.f / c.font->y_multf : 0.f); + + bool same_coords = component_coords.length == coords.length && + component_coords.arrayZ == coords.arrayZ; - VARC.get_path_at (font, gid, - draw_session, component_coords, total_transform, + c.depth_left--; + VARC.get_path_at (c, gid, + component_coords, total_transform, parent_gid, - decycler, edges_left, depth_left - 1, - scratch); + same_coords ? cache : nullptr); + c.depth_left++; } #undef PROCESS_TRANSFORM_COMPONENTS @@ -333,16 +331,12 @@ VarComponent::get_path_at (hb_font_t *font, } bool -VARC::get_path_at (hb_font_t *font, +VARC::get_path_at (const hb_varc_context_t &c, hb_codepoint_t glyph, - hb_draw_session_t &draw_session, hb_array_t<const int> coords, hb_transform_t transform, hb_codepoint_t parent_glyph, - hb_decycler_t *decycler, - signed *edges_left, - signed depth_left, - hb_glyf_scratch_t &scratch) const + VarRegionList::cache_t *parent_cache) const { // Don't recurse on the same glyph. unsigned idx = glyph == parent_glyph ? @@ -350,50 +344,69 @@ VARC::get_path_at (hb_font_t *font, (this+coverage).get_coverage (glyph); if (idx == NOT_COVERED) { - // Build a transforming pen to apply the transform. - hb_draw_funcs_t *transformer_funcs = hb_transforming_pen_get_funcs (); - hb_transforming_pen_context_t context {transform, - draw_session.funcs, - draw_session.draw_data, - &draw_session.st}; - hb_draw_session_t transformer_session {transformer_funcs, &context}; - hb_draw_session_t &shape_draw_session = transform.is_identity () ? draw_session : transformer_session; - - if (!font->face->table.glyf->get_path_at (font, glyph, shape_draw_session, coords, scratch)) + if (c.draw_session) + { + // Build a transforming pen to apply the transform. + hb_draw_funcs_t *transformer_funcs = hb_transforming_pen_get_funcs (); + hb_transforming_pen_context_t context {transform, + c.draw_session->funcs, + c.draw_session->draw_data, + &c.draw_session->st}; + hb_draw_session_t transformer_session {transformer_funcs, &context}; + hb_draw_session_t &shape_draw_session = transform.is_identity () ? *c.draw_session : transformer_session; + + if (!c.font->face->table.glyf->get_path_at (c.font, glyph, shape_draw_session, coords, c.scratch.glyf_scratch)) #ifndef HB_NO_CFF - if (!font->face->table.cff2->get_path_at (font, glyph, shape_draw_session, coords)) - if (!font->face->table.cff1->get_path (font, glyph, shape_draw_session)) // Doesn't have variations + if (!c.font->face->table.cff2->get_path_at (c.font, glyph, shape_draw_session, coords)) + if (!c.font->face->table.cff1->get_path (c.font, glyph, shape_draw_session)) // Doesn't have variations #endif - return false; + return false; + } + else if (c.extents) + { + hb_glyph_extents_t glyph_extents; + if (!c.font->face->table.glyf->get_extents_at (c.font, glyph, &glyph_extents, coords)) +#ifndef HB_NO_CFF + if (!c.font->face->table.cff2->get_extents_at (c.font, glyph, &glyph_extents, coords)) + if (!c.font->face->table.cff1->get_extents (c.font, glyph, &glyph_extents)) // Doesn't have variations +#endif + return false; + + hb_extents_t comp_extents (glyph_extents); + transform.transform_extents (comp_extents); + c.extents->union_ (comp_extents); + } return true; } - if (depth_left <= 0) + if (c.depth_left <= 0) return true; - if (*edges_left <= 0) + if (c.edges_left <= 0) return true; - (*edges_left)--; + (c.edges_left)--; - hb_decycler_node_t node (*decycler); + hb_decycler_node_t node (c.decycler); if (unlikely (!node.visit (glyph))) return true; hb_ubytes_t record = (this+glyphRecords)[idx]; float static_cache[sizeof (void *) * 16]; - VarRegionList::cache_t *cache = (this+varStore).create_cache (hb_array (static_cache)); + VarRegionList::cache_t *cache = parent_cache ? + parent_cache : + (this+varStore).create_cache (hb_array (static_cache)); - transform.scale (font->x_multf, font->y_multf); + transform.scale (c.font->x_multf, c.font->y_multf); - VarCompositeGlyph::get_path_at (font, glyph, - draw_session, coords, transform, + VarCompositeGlyph::get_path_at (c, + glyph, + coords, transform, record, - decycler, edges_left, depth_left, - scratch, cache); - (this+varStore).destroy_cache (cache, hb_array (static_cache)); + if (cache != parent_cache) + (this+varStore).destroy_cache (cache, hb_array (static_cache)); return true; } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.hh index 30e54b6bd2a41611a2d1a065092286bb051cafe9..22cfbb8ca8145a84f47991cb7c36a13dc47ca18e 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.hh @@ -21,6 +21,24 @@ namespace OT { #ifndef HB_NO_VAR_COMPOSITES +struct hb_varc_scratch_t +{ + hb_vector_t<unsigned> axisIndices; + hb_vector_t<float> axisValues; + hb_glyf_scratch_t glyf_scratch; +}; + +struct hb_varc_context_t +{ + hb_font_t *font; + hb_draw_session_t *draw_session; + hb_extents_t *extents; + mutable hb_decycler_t decycler; + mutable signed edges_left; + mutable signed depth_left; + hb_varc_scratch_t &scratch; +}; + struct VarComponent { enum class flags_t : uint32_t @@ -44,41 +62,32 @@ struct VarComponent }; HB_INTERNAL hb_ubytes_t - get_path_at (hb_font_t *font, + get_path_at (const hb_varc_context_t &c, hb_codepoint_t parent_gid, - hb_draw_session_t &draw_session, hb_array_t<const int> coords, hb_transform_t transform, hb_ubytes_t record, - hb_decycler_t *decycler, - signed *edges_left, - signed depth_left, - hb_glyf_scratch_t &scratch, VarRegionList::cache_t *cache = nullptr) const; }; struct VarCompositeGlyph { static void - get_path_at (hb_font_t *font, - hb_codepoint_t glyph, - hb_draw_session_t &draw_session, + get_path_at (const hb_varc_context_t &c, + hb_codepoint_t gid, hb_array_t<const int> coords, hb_transform_t transform, hb_ubytes_t record, - hb_decycler_t *decycler, - signed *edges_left, - signed depth_left, - hb_glyf_scratch_t &scratch, - VarRegionList::cache_t *cache = nullptr) + VarRegionList::cache_t *cache) { while (record) { const VarComponent &comp = * (const VarComponent *) (record.arrayZ); - record = comp.get_path_at (font, glyph, - draw_session, coords, transform, + record = comp.get_path_at (c, + gid, + coords, transform, record, - decycler, edges_left, depth_left, scratch, cache); + cache); } } }; @@ -92,36 +101,47 @@ struct VARC static constexpr hb_tag_t tableTag = HB_TAG ('V', 'A', 'R', 'C'); HB_INTERNAL bool - get_path_at (hb_font_t *font, - hb_codepoint_t glyph, - hb_draw_session_t &draw_session, + get_path_at (const hb_varc_context_t &c, + hb_codepoint_t gid, hb_array_t<const int> coords, - hb_transform_t transform, - hb_codepoint_t parent_glyph, - hb_decycler_t *decycler, - signed *edges_left, - signed depth_left, - hb_glyf_scratch_t &scratch) const; + hb_transform_t transform = HB_TRANSFORM_IDENTITY, + hb_codepoint_t parent_gid = HB_CODEPOINT_INVALID, + VarRegionList::cache_t *parent_cache = nullptr) const; bool get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session, - hb_glyf_scratch_t &scratch) const + hb_varc_scratch_t &scratch) const { - hb_decycler_t decycler; - signed edges = HB_MAX_GRAPH_EDGE_COUNT; - - return get_path_at (font, - gid, - draw_session, - hb_array (font->coords, font->num_coords), - HB_TRANSFORM_IDENTITY, - HB_CODEPOINT_INVALID, - &decycler, - &edges, - HB_MAX_NESTING_LEVEL, - scratch); + hb_varc_context_t c {font, + &draw_session, + nullptr, + hb_decycler_t {}, + HB_MAX_GRAPH_EDGE_COUNT, + HB_MAX_NESTING_LEVEL, + scratch}; + + return get_path_at (c, gid, + hb_array (font->coords, font->num_coords)); + } + + bool + get_extents (hb_font_t *font, + hb_codepoint_t gid, + hb_extents_t *extents, + hb_varc_scratch_t &scratch) const + { + hb_varc_context_t c {font, + nullptr, + extents, + hb_decycler_t {}, + HB_MAX_GRAPH_EDGE_COUNT, + HB_MAX_NESTING_LEVEL, + scratch}; + + return get_path_at (c, gid, + hb_array (font->coords, font->num_coords)); } bool sanitize (hb_sanitize_context_t *c) const @@ -150,7 +170,7 @@ struct VARC auto *scratch = cached_scratch.get_relaxed (); if (scratch) { - scratch->~hb_glyf_scratch_t (); + scratch->~hb_varc_scratch_t (); hb_free (scratch); } @@ -162,34 +182,60 @@ struct VARC { if (!table->has_data ()) return false; - hb_glyf_scratch_t *scratch; + auto *scratch = acquire_scratch (); + if (unlikely (!scratch)) return true; + bool ret = table->get_path (font, gid, draw_session, *scratch); + release_scratch (scratch); + return ret; + } + + bool + get_extents (hb_font_t *font, + hb_codepoint_t gid, + hb_glyph_extents_t *extents) const + { + if (!table->has_data ()) return false; + + hb_extents_t f_extents; + + auto *scratch = acquire_scratch (); + if (unlikely (!scratch)) return true; + bool ret = table->get_extents (font, gid, &f_extents, *scratch); + release_scratch (scratch); + + if (ret) + *extents = f_extents.to_glyph_extents (font->x_scale < 0, font->y_scale < 0); + + return ret; + } + + private: - // Borrow the cached strach buffer. + hb_varc_scratch_t *acquire_scratch () const + { + hb_varc_scratch_t *scratch = cached_scratch.get_acquire (); + + if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr))) { - scratch = cached_scratch.get_acquire (); - if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr))) - { - scratch = (hb_glyf_scratch_t *) hb_calloc (1, sizeof (hb_glyf_scratch_t)); - if (unlikely (!scratch)) - return true; - } + scratch = (hb_varc_scratch_t *) hb_calloc (1, sizeof (hb_varc_scratch_t)); + if (unlikely (!scratch)) + return nullptr; } - bool ret = table->get_path (font, gid, draw_session, *scratch); - - // Put it back. + return scratch; + } + void release_scratch (hb_varc_scratch_t *scratch) const + { if (!cached_scratch.cmpexch (nullptr, scratch)) { - scratch->~hb_glyf_scratch_t (); + scratch->~hb_varc_scratch_t (); hb_free (scratch); } - - return ret; } private: hb_blob_ptr_t<VARC> table; - hb_atomic_ptr_t<hb_glyf_scratch_t> cached_scratch; + hb_atomic_t<hb_varc_scratch_t *> cached_scratch; }; bool has_data () const { return version.major != 0; } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh index fe4ae7b8c542cd71a1ff34fdd0b40f61b6d0692a..b136b150282681787dfb8e16ca5186f5ec058053 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh @@ -429,16 +429,27 @@ struct glyf_accelerator_t } public: - bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const + + bool get_extents (hb_font_t *font, + hb_codepoint_t gid, + hb_glyph_extents_t *extents) const + { return get_extents_at (font, gid, extents, hb_array (font->coords, font->num_coords)); } + + bool get_extents_at (hb_font_t *font, + hb_codepoint_t gid, + hb_glyph_extents_t *extents, + hb_array_t<const int> coords) const { if (unlikely (gid >= num_glyphs)) return false; #ifndef HB_NO_VAR - if (font->num_coords) + if (coords) { hb_glyf_scratch_t scratch; - return get_points (font, gid, points_aggregator_t (font, extents, nullptr, true), - hb_array (font->coords, font->num_coords), + return get_points (font, + gid, + points_aggregator_t (font, extents, nullptr, true), + coords, scratch); } #endif @@ -532,7 +543,7 @@ struct glyf_accelerator_t unsigned int num_glyphs; hb_blob_ptr_t<loca> loca_table; hb_blob_ptr_t<glyf> glyf_table; - hb_atomic_ptr_t<hb_glyf_scratch_t> cached_scratch; + hb_atomic_t<hb_glyf_scratch_t *> cached_scratch; }; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/addTable.py b/source/libs/harfbuzz/harfbuzz-src/src/addTable.py index 103f292dd6a4d70aacfe84b5ef5bb565fa3762b7..8ceda7ae8f0b3ed69355568f170b31f00b9ba070 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/addTable.py +++ b/source/libs/harfbuzz/harfbuzz-src/src/addTable.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + import sys from fontTools.ttLib import TTFont from fontTools.ttLib.tables.DefaultTable import DefaultTable diff --git a/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.py b/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.py index 91bf8b0671a350efffee1e8f7fed7edd706084bb..d0ea303e32bd0b239801e0390dcc623c0184ed36 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.py +++ b/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.py @@ -7,18 +7,26 @@ os.environ['LC_ALL'] = 'C' # otherwise 'nm' prints in wrong order builddir = os.getenv ('builddir', os.path.dirname (__file__)) libs = os.getenv ('libs', '.libs') -IGNORED_SYMBOLS = '|'.join(['_fini', '_init', '_fdata', '_ftext', '_fbss', +IGNORED_SYMBOLS = ['_fini', '_init', '_fdata', '_ftext', '_fbss', '__bss_start', '__bss_start__', '__bss_end__', '_edata', '_end', '_bss_end__', '__end__', '__gcov_.*', 'llvm_.*', 'flush_fn_list', 'writeout_fn_list', 'mangle_path', - 'lprofDirMode', 'reset_fn_list']) + 'lprofDirMode', 'reset_fn_list'] + +# Rust +IGNORED_SYMBOLS += [ + 'rust_eh_personality', + '_ZN3std9panicking11EMPTY_PANIC.*', # 'std::panicking::EMPTY_PANIC::.*' + '_ZN3std3sys3pal4unix4args3imp15ARGV_INIT_ARRAY.*', # 'std::sys::pal::unix::args::imp::ARGV_INIT_ARRAY::.*' + '_ZN17compiler_builtins4math4libm7generic4sqrt9RSQRT_TAB.*', # 'compiler_builtins::math::libm::generic::sqrt::RSQRT_TAB::.*' +] + +IGNORED_SYMBOLS = '|'.join (IGNORED_SYMBOLS) nm = os.getenv ('NM', shutil.which ('nm')) if not nm: print ('check-symbols.py: \'nm\' not found; skipping test') sys.exit (77) -cxxfilt = shutil.which ('c++filt') - tested = False stat = 0 @@ -34,12 +42,6 @@ for soname in ['harfbuzz', 'harfbuzz-subset', 'harfbuzz-icu', 'harfbuzz-gobject' for s in re.findall (r'^.+ [BCDGIRSTu] .+$', subprocess.check_output (nm.split() + [so]).decode ('utf-8'), re.MULTILINE) if not re.match (r'.* %s(%s)\b' % (symprefix, IGNORED_SYMBOLS), s)] - # run again c++filt also if is available - if cxxfilt: - EXPORTED_SYMBOLS = subprocess.check_output ( - [cxxfilt], input='\n'.join (EXPORTED_SYMBOLS).encode () - ).decode ('utf-8').splitlines () - prefix = (symprefix + os.path.basename (so)).replace ('libharfbuzz', 'hb').replace ('-', '_').split ('.')[0] print ('Checking that %s does not expose internal symbols' % so) diff --git a/source/libs/harfbuzz/harfbuzz-src/src/fontations/Cargo.lock b/source/libs/harfbuzz/harfbuzz-src/src/fontations/Cargo.lock new file mode 100644 index 0000000000000000000000000000000000000000..b4cbe2d6e6f31add166476d7d0c1deb5fbb59a5e --- /dev/null +++ b/source/libs/harfbuzz/harfbuzz-src/src/fontations/Cargo.lock @@ -0,0 +1,95 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "bytemuck" +version = "1.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "font-types" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d868ec188a98bb014c606072edd47e52e7ab7297db943b0b28503121e1d037bd" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "harfbuzz_fontations" +version = "0.0.0" +dependencies = [ + "read-fonts", + "skrifa", +] + +[[package]] +name = "proc-macro2" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "read-fonts" +version = "0.27.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f14974c88fb4fd0a7203719f98020209248c9dbebaf9d10d860337797a905097" +dependencies = [ + "bytemuck", + "font-types", +] + +[[package]] +name = "skrifa" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c0ca53de9bb9bee1720c727606275148463cd938eb6bde249dcedeec4967747" +dependencies = [ + "bytemuck", + "read-fonts", +] + +[[package]] +name = "syn" +version = "2.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e02e925281e18ffd9d640e234264753c43edc62d64b2d4cf898f1bc5e75f3fc2" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" diff --git a/source/libs/harfbuzz/harfbuzz-src/src/fontations/Cargo.toml b/source/libs/harfbuzz/harfbuzz-src/src/fontations/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..e239a26c347ff4856bd6929aa0fcf9cdf2f6bdb7 --- /dev/null +++ b/source/libs/harfbuzz/harfbuzz-src/src/fontations/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "harfbuzz_fontations" +edition = "2021" + +[dependencies] +read-fonts = "0.27" +skrifa = "0.29.2" + +[lib] +name = "harfbuzz_fontations" +path = "lib.rs" +crate-type = ["staticlib"] + +[profile.release] +strip = true +lto = "fat" +panic = "abort" +overflow-checks = false +codegen-units = 1 + +[profile.debugoptimized] +inherits = "release" +debug = true +codegen-units = 16 +strip = false + +[profile.dev] +lto = "fat" diff --git a/source/libs/harfbuzz/harfbuzz-src/src/fontations/lib.rs b/source/libs/harfbuzz/harfbuzz-src/src/fontations/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..44ef1b133138aea008c133d3f438aec2c0be1cc5 --- /dev/null +++ b/source/libs/harfbuzz/harfbuzz-src/src/fontations/lib.rs @@ -0,0 +1,944 @@ +#![allow(non_camel_case_types)] +#![allow(non_upper_case_globals)] +include!(concat!(env!("OUT_DIR"), "/hb.rs")); + +use std::alloc::{GlobalAlloc, Layout}; +use std::collections::HashMap; +use std::mem::transmute; +use std::os::raw::c_void; +use std::ptr::null_mut; +use std::sync::atomic::{AtomicPtr, AtomicU32, Ordering}; +use std::sync::{Mutex, OnceLock}; + +use read_fonts::tables::cpal::ColorRecord; +use read_fonts::TableProvider; +use skrifa::charmap::Charmap; +use skrifa::charmap::MapVariant::Variant; +use skrifa::color::{ + Brush, ColorGlyphCollection, ColorPainter, ColorStop, CompositeMode, Extend, Transform, +}; +use skrifa::font::FontRef; +use skrifa::instance::{Location, NormalizedCoord, Size}; +use skrifa::metrics::{BoundingBox, GlyphMetrics}; +use skrifa::outline::pen::OutlinePen; +use skrifa::outline::DrawSettings; +use skrifa::OutlineGlyphCollection; +use skrifa::{GlyphId, GlyphNames, MetadataProvider}; + +struct MyAllocator; + +unsafe impl GlobalAlloc for MyAllocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + assert!(layout.align() <= 2 * std::mem::size_of::<*mut u8>()); + hb_malloc(layout.size()) as *mut u8 + } + + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { + assert!(layout.align() <= 2 * std::mem::size_of::<*mut u8>()); + hb_calloc(layout.size(), 1) as *mut u8 + } + + unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { + assert!(layout.align() <= 2 * std::mem::size_of::<*mut u8>()); + hb_realloc(ptr as *mut c_void, new_size) as *mut u8 + } + + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + assert!(layout.align() <= 2 * std::mem::size_of::<*mut u8>()); + hb_free(ptr as *mut c_void); + } +} + +#[global_allocator] +static GLOBAL: MyAllocator = MyAllocator; + +// A struct for storing your “fontations” data +#[repr(C)] +struct FontationsData<'a> { + face_blob: *mut hb_blob_t, + font: *mut hb_font_t, + font_ref: FontRef<'a>, + char_map: Charmap<'a>, + outline_glyphs: OutlineGlyphCollection<'a>, + color_glyphs: ColorGlyphCollection<'a>, + glyph_names: GlyphNames<'a>, + glyph_from_names: OnceLock<HashMap<String, hb_codepoint_t>>, + size: Size, + + // Mutex for the below + mutex: Mutex<()>, + serial: AtomicU32, + x_mult: f32, + y_mult: f32, + location: Location, + glyph_metrics: Option<GlyphMetrics<'a>>, +} + +impl FontationsData<'_> { + unsafe fn from_hb_font(font: *mut hb_font_t) -> Self { + let face_index = hb_face_get_index(hb_font_get_face(font)); + let face_blob = hb_face_reference_blob(hb_font_get_face(font)); + let blob_length = hb_blob_get_length(face_blob); + let blob_data = hb_blob_get_data(face_blob, null_mut()); + let face_data = std::slice::from_raw_parts(blob_data as *const u8, blob_length as usize); + + let font_ref = FontRef::from_index(face_data, face_index).unwrap(); + + let char_map = Charmap::new(&font_ref); + + let outline_glyphs = font_ref.outline_glyphs(); + + let color_glyphs = font_ref.color_glyphs(); + + let glyph_names = font_ref.glyph_names(); + + let upem = hb_face_get_upem(hb_font_get_face(font)); + + let mut data = FontationsData { + face_blob, + font, + font_ref, + char_map, + outline_glyphs, + color_glyphs, + glyph_names, + glyph_from_names: OnceLock::new(), + size: Size::new(upem as f32), + mutex: Mutex::new(()), + x_mult: 1.0, + y_mult: 1.0, + serial: AtomicU32::new(u32::MAX), + location: Location::default(), + glyph_metrics: None, + }; + + data.check_for_updates(); + + data + } + + unsafe fn _check_for_updates(&mut self) { + let font_serial = hb_font_get_serial(self.font); + let serial = self.serial.load(Ordering::Relaxed); + if serial == font_serial { + return; + } + + let _lock = self.mutex.lock().unwrap(); + + let mut x_scale: i32 = 0; + let mut y_scale: i32 = 0; + hb_font_get_scale(self.font, &mut x_scale, &mut y_scale); + let upem = hb_face_get_upem(hb_font_get_face(self.font)); + self.x_mult = x_scale as f32 / upem as f32; + self.y_mult = y_scale as f32 / upem as f32; + + let mut num_coords: u32 = 0; + let coords = hb_font_get_var_coords_normalized(self.font, &mut num_coords); + let coords = if coords.is_null() { + &[] + } else { + std::slice::from_raw_parts(coords, num_coords as usize) + }; + let all_zeros = coords.iter().all(|&x| x == 0); + // if all zeros, use Location::default() + // otherwise, use the provided coords. + // This currently doesn't seem to have a perf effect on fontations, but it's a good idea to + // check if the coords are all zeros before creating a Location. + self.location = if all_zeros { + Location::default() + } else { + let mut location = Location::new(num_coords as usize); + let coords_mut = location.coords_mut(); + coords_mut + .iter_mut() + .zip(coords.iter().map(|v| NormalizedCoord::from_bits(*v as i16))) + .for_each(|(dest, source)| *dest = source); + location + }; + + let location = transmute::<&Location, &Location>(&self.location); + self.glyph_metrics = Some(self.font_ref.glyph_metrics(self.size, location)); + + self.serial.store(font_serial, Ordering::Release); + } + fn check_for_updates(&mut self) { + unsafe { self._check_for_updates() } + } +} + +extern "C" fn _hb_fontations_data_destroy(font_data: *mut c_void) { + let data = unsafe { Box::from_raw(font_data as *mut FontationsData) }; + + unsafe { + hb_blob_destroy(data.face_blob); + } +} + +fn struct_at_offset<T: Copy>(first: *const T, index: u32, stride: u32) -> T { + unsafe { *((first as *const u8).offset((index * stride) as isize) as *const T) } +} + +fn struct_at_offset_mut<T: Copy>(first: *mut T, index: u32, stride: u32) -> &'static mut T { + unsafe { &mut *((first as *mut u8).offset((index * stride) as isize) as *mut T) } +} + +extern "C" fn _hb_fontations_get_nominal_glyphs( + _font: *mut hb_font_t, + font_data: *mut ::std::os::raw::c_void, + count: ::std::os::raw::c_uint, + first_unicode: *const hb_codepoint_t, + unicode_stride: ::std::os::raw::c_uint, + first_glyph: *mut hb_codepoint_t, + glyph_stride: ::std::os::raw::c_uint, + _user_data: *mut ::std::os::raw::c_void, +) -> ::std::os::raw::c_uint { + let data = unsafe { &*(font_data as *const FontationsData) }; + let char_map = &data.char_map; + + for i in 0..count { + let unicode = struct_at_offset(first_unicode, i, unicode_stride); + let Some(glyph) = char_map.map(unicode) else { + return i; + }; + let glyph_id = glyph.to_u32() as hb_codepoint_t; + *struct_at_offset_mut(first_glyph, i, glyph_stride) = glyph_id; + } + + count +} +extern "C" fn _hb_fontations_get_variation_glyph( + _font: *mut hb_font_t, + font_data: *mut ::std::os::raw::c_void, + unicode: hb_codepoint_t, + variation_selector: hb_codepoint_t, + glyph: *mut hb_codepoint_t, + _user_data: *mut ::std::os::raw::c_void, +) -> hb_bool_t { + let data = unsafe { &*(font_data as *const FontationsData) }; + let char_map = &data.char_map; + + match char_map.map_variant(unicode, variation_selector) { + Some(Variant(glyph_id)) => { + unsafe { *glyph = glyph_id.to_u32() as hb_codepoint_t }; + true as hb_bool_t + } + _ => false as hb_bool_t, + } +} + +extern "C" fn _hb_fontations_get_glyph_h_advances( + _font: *mut hb_font_t, + font_data: *mut ::std::os::raw::c_void, + count: ::std::os::raw::c_uint, + first_glyph: *const hb_codepoint_t, + glyph_stride: ::std::os::raw::c_uint, + first_advance: *mut hb_position_t, + advance_stride: ::std::os::raw::c_uint, + _user_data: *mut ::std::os::raw::c_void, +) { + let data = unsafe { &mut *(font_data as *mut FontationsData) }; + data.check_for_updates(); + + let glyph_metrics = &data.glyph_metrics.as_ref().unwrap(); + + for i in 0..count { + let glyph = struct_at_offset(first_glyph, i, glyph_stride); + let glyph_id = GlyphId::new(glyph); + let advance = (glyph_metrics.advance_width(glyph_id).unwrap_or_default() * data.x_mult) + .round() as i32; + *struct_at_offset_mut(first_advance, i, advance_stride) = advance as hb_position_t; + } +} +extern "C" fn _hb_fontations_get_glyph_extents( + _font: *mut hb_font_t, + font_data: *mut ::std::os::raw::c_void, + glyph: hb_codepoint_t, + extents: *mut hb_glyph_extents_t, + _user_data: *mut ::std::os::raw::c_void, +) -> hb_bool_t { + let data = unsafe { &mut *(font_data as *mut FontationsData) }; + data.check_for_updates(); + + let glyph_metrics = &data.glyph_metrics.as_ref().unwrap(); + + let glyph_id = GlyphId::new(glyph); + let glyph_extents = glyph_metrics.bounds(glyph_id); + let Some(glyph_extents) = glyph_extents else { + return false as hb_bool_t; + }; + + let x_bearing = (glyph_extents.x_min * data.x_mult).round() as hb_position_t; + let width = (glyph_extents.x_max * data.x_mult).round() as hb_position_t - x_bearing; + let y_bearing = (glyph_extents.y_max * data.y_mult).round() as hb_position_t; + let height = (glyph_extents.y_min * data.y_mult).round() as hb_position_t - y_bearing; + + unsafe { + *extents = hb_glyph_extents_t { + x_bearing, + y_bearing, + width, + height, + }; + } + + true as hb_bool_t +} + +extern "C" fn _hb_fontations_get_font_h_extents( + _font: *mut hb_font_t, + font_data: *mut ::std::os::raw::c_void, + extents: *mut hb_font_extents_t, + _user_data: *mut ::std::os::raw::c_void, +) -> hb_bool_t { + let data = unsafe { &mut *(font_data as *mut FontationsData) }; + data.check_for_updates(); + + let font_ref = &data.font_ref; + let size = &data.size; + let location = &data.location; + let metrics = font_ref.metrics(*size, location); + + unsafe { + (*extents).ascender = (metrics.ascent * data.y_mult).round() as hb_position_t; + (*extents).descender = (metrics.descent * data.y_mult).round() as hb_position_t; + (*extents).line_gap = (metrics.leading * data.y_mult).round() as hb_position_t; + } + + true as hb_bool_t +} + +struct HbPen { + x_mult: f32, + y_mult: f32, + draw_state: *mut hb_draw_state_t, + draw_funcs: *mut hb_draw_funcs_t, + draw_data: *mut c_void, +} + +impl OutlinePen for HbPen { + fn move_to(&mut self, x: f32, y: f32) { + unsafe { + hb_draw_move_to( + self.draw_funcs, + self.draw_data, + self.draw_state, + x * self.x_mult, + y * self.y_mult, + ); + } + } + fn line_to(&mut self, x: f32, y: f32) { + unsafe { + hb_draw_line_to( + self.draw_funcs, + self.draw_data, + self.draw_state, + x * self.x_mult, + y * self.y_mult, + ); + } + } + fn quad_to(&mut self, x1: f32, y1: f32, x: f32, y: f32) { + unsafe { + hb_draw_quadratic_to( + self.draw_funcs, + self.draw_data, + self.draw_state, + x1 * self.x_mult, + y1 * self.y_mult, + x * self.x_mult, + y * self.y_mult, + ); + } + } + fn curve_to(&mut self, x1: f32, y1: f32, x2: f32, y2: f32, x: f32, y: f32) { + unsafe { + hb_draw_cubic_to( + self.draw_funcs, + self.draw_data, + self.draw_state, + x1 * self.x_mult, + y1 * self.y_mult, + x2 * self.x_mult, + y2 * self.y_mult, + x * self.x_mult, + y * self.y_mult, + ); + } + } + fn close(&mut self) { + unsafe { + hb_draw_close_path(self.draw_funcs, self.draw_data, self.draw_state); + } + } +} + +extern "C" fn _hb_fontations_draw_glyph( + font: *mut hb_font_t, + font_data: *mut ::std::os::raw::c_void, + glyph: hb_codepoint_t, + draw_funcs: *mut hb_draw_funcs_t, + draw_data: *mut ::std::os::raw::c_void, + _user_data: *mut ::std::os::raw::c_void, +) { + let data = unsafe { &mut *(font_data as *mut FontationsData) }; + data.check_for_updates(); + + let size = &data.size; + let location = &data.location; + let outline_glyphs = &data.outline_glyphs; + + // Create an outline-glyph + let glyph_id = GlyphId::new(glyph); + let Some(outline_glyph) = outline_glyphs.get(glyph_id) else { + return; + }; + let draw_settings = DrawSettings::unhinted(*size, location); + // Allocate zero bytes for the draw_state_t on the stack. + let mut draw_state: hb_draw_state_t = unsafe { std::mem::zeroed::<hb_draw_state_t>() }; + + let slant = unsafe { hb_font_get_synthetic_slant(font) }; + let mut x_scale: i32 = 0; + let mut y_scale: i32 = 0; + unsafe { + hb_font_get_scale(font, &mut x_scale, &mut y_scale); + } + let slant = if y_scale != 0 { + slant as f32 * x_scale as f32 / y_scale as f32 + } else { + 0. + }; + draw_state.slant_xy = slant; + + let mut pen = HbPen { + x_mult: data.x_mult, + y_mult: data.y_mult, + draw_state: &mut draw_state, + draw_funcs, + draw_data, + }; + + let _ = outline_glyph.draw(draw_settings, &mut pen); +} + +struct HbColorPainter<'a> { + font: *mut hb_font_t, + paint_funcs: *mut hb_paint_funcs_t, + paint_data: *mut c_void, + color_records: &'a [ColorRecord], + foreground: hb_color_t, +} + +impl HbColorPainter<'_> { + fn lookup_color(&self, color_index: u16, alpha: f32) -> hb_color_t { + if color_index == 0xFFFF { + // Apply alpha to foreground color + return ((self.foreground & 0xFFFFFF00) + | (((self.foreground & 0xFF) as f32 * alpha).round() as u32)) + as hb_color_t; + } + + let c = self.color_records.get(color_index as usize); + if c.is_some() { + let c = c.unwrap(); + (((c.blue as u32) << 24) + | ((c.green as u32) << 16) + | ((c.red as u32) << 8) + | ((c.alpha as f32 * alpha).round() as u32)) as hb_color_t + } else { + 0 as hb_color_t + } + } + + fn make_color_line(&self, color_line: &ColorLineData) -> hb_color_line_t { + let mut cl = unsafe { std::mem::zeroed::<hb_color_line_t>() }; + cl.data = color_line as *const ColorLineData as *mut ::std::os::raw::c_void; + cl.get_color_stops = Some(_hb_fontations_get_color_stops); + cl.get_extend = Some(_hb_fontations_get_extend); + cl + } +} + +struct ColorLineData<'a> { + painter: &'a HbColorPainter<'a>, + color_stops: &'a [ColorStop], + extend: Extend, +} +extern "C" fn _hb_fontations_get_color_stops( + _color_line: *mut hb_color_line_t, + color_line_data: *mut ::std::os::raw::c_void, + start: ::std::os::raw::c_uint, + count_out: *mut ::std::os::raw::c_uint, + color_stops_out: *mut hb_color_stop_t, + _user_data: *mut ::std::os::raw::c_void, +) -> ::std::os::raw::c_uint { + let color_line_data = unsafe { &*(color_line_data as *const ColorLineData) }; + let color_stops = &color_line_data.color_stops; + if count_out.is_null() { + return color_stops.len() as u32; + } + let count = unsafe { *count_out }; + for i in 0..count { + let Some(stop) = color_stops.get(start as usize + i as usize) else { + unsafe { + *count_out = i; + }; + break; + }; + unsafe { + *(color_stops_out.offset(i as isize)) = hb_color_stop_t { + offset: stop.offset, + color: color_line_data + .painter + .lookup_color(stop.palette_index, stop.alpha), + is_foreground: (stop.palette_index == 0xFFFF) as hb_bool_t, + }; + } + } + color_stops.len() as u32 +} +extern "C" fn _hb_fontations_get_extend( + _color_line: *mut hb_color_line_t, + color_line_data: *mut ::std::os::raw::c_void, + _user_data: *mut ::std::os::raw::c_void, +) -> hb_paint_extend_t { + let color_line_data = unsafe { &*(color_line_data as *const ColorLineData) }; + color_line_data.extend as hb_paint_extend_t // They are the same +} + +pub fn _hb_fontations_unreduce_anchors( + x0: f32, + y0: f32, + x1: f32, + y1: f32, +) -> (f32, f32, f32, f32, f32, f32) { + /* Returns (x0, y0, x1, y1, x2, y2) such that the original + * `_hb_cairo_reduce_anchors` would produce (xx0, yy0, xx1, yy1) + * as outputs. + * The OT spec has the following wording; we just need to + * invert that operation here: + * + * Note: An implementation can derive a single vector, from p₀ to a point p₃, by computing the + * orthogonal projection of the vector from p₀ to p₁ onto a line perpendicular to line p₀p₂ and + * passing through p₀ to obtain point p₃. The linear gradient defined using p₀, p₁ and p₂ as + * described above is functionally equivalent to a linear gradient defined by aligning stop + * offset 0 to p₀ and aligning stop offset 1.0 to p₃, with each color projecting on either side + * of that line in a perpendicular direction. This specification uses three points, p₀, p₁ and + * p₂, as that provides greater flexibility in controlling the placement and rotation of the + * gradient, as well as variations thereof. + */ + + let dx = x1 - x0; + let dy = y1 - y0; + + (x0, y0, x1, y1, x0 + dy, y0 - dx) +} + +impl ColorPainter for HbColorPainter<'_> { + fn push_transform(&mut self, transform: Transform) { + unsafe { + hb_paint_push_transform( + self.paint_funcs, + self.paint_data, + transform.xx, + transform.yx, + transform.xy, + transform.yy, + transform.dx, + transform.dy, + ); + } + } + fn pop_transform(&mut self) { + unsafe { + hb_paint_pop_transform(self.paint_funcs, self.paint_data); + } + } + fn fill_glyph( + &mut self, + glyph_id: GlyphId, + brush_transform: Option<Transform>, + brush: Brush<'_>, + ) { + unsafe { + hb_paint_push_inverse_font_transform(self.paint_funcs, self.paint_data, self.font); + } + self.push_clip_glyph(glyph_id); + unsafe { + hb_paint_push_font_transform(self.paint_funcs, self.paint_data, self.font); + } + if let Some(wrap_in_transform) = brush_transform { + self.push_transform(wrap_in_transform); + self.fill(brush); + self.pop_transform(); + } else { + self.fill(brush); + } + self.pop_transform(); + self.pop_clip(); + self.pop_transform(); + } + fn push_clip_glyph(&mut self, glyph_id: GlyphId) { + unsafe { + hb_paint_push_clip_glyph( + self.paint_funcs, + self.paint_data, + glyph_id.to_u32() as hb_codepoint_t, + self.font, + ); + } + } + fn push_clip_box(&mut self, bbox: BoundingBox) { + unsafe { + hb_paint_push_clip_rectangle( + self.paint_funcs, + self.paint_data, + bbox.x_min, + bbox.y_min, + bbox.x_max, + bbox.y_max, + ); + } + } + fn pop_clip(&mut self) { + unsafe { + hb_paint_pop_clip(self.paint_funcs, self.paint_data); + } + } + fn fill(&mut self, brush: Brush) { + match brush { + Brush::Solid { + palette_index: color_index, + alpha, + } => { + let is_foreground = color_index == 0xFFFF; + unsafe { + hb_paint_color( + self.paint_funcs, + self.paint_data, + is_foreground as hb_bool_t, + self.lookup_color(color_index, alpha), + ); + } + } + Brush::LinearGradient { + color_stops, + extend, + p0, + p1, + } => { + let color_stops = ColorLineData { + painter: self, + color_stops, + extend, + }; + let mut color_line = self.make_color_line(&color_stops); + + let (x0, y0, x1, y1, x2, y2) = + _hb_fontations_unreduce_anchors(p0.x, p0.y, p1.x, p1.y); + + unsafe { + hb_paint_linear_gradient( + self.paint_funcs, + self.paint_data, + &mut color_line, + x0, + y0, + x1, + y1, + x2, + y2, + ); + } + } + Brush::RadialGradient { + color_stops, + extend, + c0, + r0, + c1, + r1, + } => { + let color_stops = ColorLineData { + painter: self, + color_stops, + extend, + }; + let mut color_line = self.make_color_line(&color_stops); + unsafe { + hb_paint_radial_gradient( + self.paint_funcs, + self.paint_data, + &mut color_line, + c0.x, + c0.y, + r0, + c1.x, + c1.y, + r1, + ); + } + } + Brush::SweepGradient { + color_stops, + extend, + c0, + start_angle, + end_angle, + } => { + let color_stops = ColorLineData { + painter: self, + color_stops, + extend, + }; + let mut color_line = self.make_color_line(&color_stops); + // Skrifa has this gem, so we swap end_angle and start_angle + // when passing to our API: + // + // * Convert angles and stops from counter-clockwise to clockwise + // * for the shader if the gradient is not already reversed due to + // * start angle being larger than end angle. + // + // Undo that. + let (start_angle, end_angle) = (360. - start_angle, 360. - end_angle); + let start_angle = start_angle.to_radians(); + let end_angle = end_angle.to_radians(); + unsafe { + hb_paint_sweep_gradient( + self.paint_funcs, + self.paint_data, + &mut color_line, + c0.x, + c0.y, + start_angle, + end_angle, + ); + } + } + } + } + fn push_layer(&mut self, _mode: CompositeMode) { + unsafe { + hb_paint_push_group(self.paint_funcs, self.paint_data); + } + } + fn pop_layer_with_mode(&mut self, mode: CompositeMode) { + let mode = mode as hb_paint_composite_mode_t; // They are the same + unsafe { + hb_paint_pop_group(self.paint_funcs, self.paint_data, mode); + } + } +} + +extern "C" fn _hb_fontations_paint_glyph( + font: *mut hb_font_t, + font_data: *mut ::std::os::raw::c_void, + glyph: hb_codepoint_t, + paint_funcs: *mut hb_paint_funcs_t, + paint_data: *mut ::std::os::raw::c_void, + palette_index: ::std::os::raw::c_uint, + foreground: hb_color_t, + _user_data: *mut ::std::os::raw::c_void, +) { + let data = unsafe { &mut *(font_data as *mut FontationsData) }; + data.check_for_updates(); + + let font_ref = &data.font_ref; + let location = &data.location; + let color_glyphs = &data.color_glyphs; + + // Create an color-glyph + let glyph_id = GlyphId::new(glyph); + let Some(color_glyph) = color_glyphs.get(glyph_id) else { + return; + }; + + let cpal = font_ref.cpal(); + let color_records = if cpal.is_err() { + unsafe { std::slice::from_raw_parts(std::ptr::NonNull::dangling().as_ptr(), 0) } + } else { + let cpal = cpal.unwrap(); + let num_entries = cpal.num_palette_entries().into(); + let color_records = cpal.color_records_array(); + let start_index = cpal.color_record_indices().get(palette_index as usize); + let start_index = if start_index.is_some() { + start_index + } else { + // https://github.com/harfbuzz/harfbuzz/issues/5116 + cpal.color_record_indices().first() + }; + + if let (Some(Ok(color_records)), Some(start_index)) = (color_records, start_index) { + let start_index: usize = start_index.get().into(); + let color_records = &color_records[start_index..start_index + num_entries]; + unsafe { std::slice::from_raw_parts(color_records.as_ptr(), num_entries) } + } else { + unsafe { std::slice::from_raw_parts(std::ptr::NonNull::dangling().as_ptr(), 0) } + } + }; + + let mut painter = HbColorPainter { + font, + paint_funcs, + paint_data, + color_records, + foreground, + }; + unsafe { + hb_paint_push_font_transform(paint_funcs, paint_data, font); + } + let _ = color_glyph.paint(location, &mut painter); +} + +extern "C" fn _hb_fontations_glyph_name( + _font: *mut hb_font_t, + font_data: *mut ::std::os::raw::c_void, + glyph: hb_codepoint_t, + name: *mut ::std::os::raw::c_char, + size: ::std::os::raw::c_uint, + _user_data: *mut ::std::os::raw::c_void, +) -> hb_bool_t { + let data = unsafe { &mut *(font_data as *mut FontationsData) }; + + let glyph_name = data.glyph_names.get(GlyphId::new(glyph)); + match glyph_name { + None => false as hb_bool_t, + Some(glyph_name) => { + let glyph_name = glyph_name.as_str(); + // Copy the glyph name into the buffer, up to size-1 bytes + let len = glyph_name.len().min(size as usize - 1); + unsafe { + std::ptr::copy_nonoverlapping(glyph_name.as_ptr(), name as *mut u8, len); + *name.add(len) = 0; + } + true as hb_bool_t + } + } +} + +extern "C" fn _hb_fontations_glyph_from_name( + _font: *mut hb_font_t, + font_data: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + len: ::std::os::raw::c_int, + glyph: *mut hb_codepoint_t, + _user_data: *mut ::std::os::raw::c_void, +) -> hb_bool_t { + let data = unsafe { &mut *(font_data as *mut FontationsData) }; + + let name = unsafe { std::slice::from_raw_parts(name as *const u8, len as usize) }; + let name = std::str::from_utf8(name).unwrap_or_default(); + + let glyph_from_names = data.glyph_from_names.get_or_init(|| { + data.glyph_names + .iter() + .map(|(gid, name)| (name.to_string(), gid.to_u32())) + .collect() + }); + let glyph_id = glyph_from_names.get(name); + + match glyph_id { + None => false as hb_bool_t, + Some(glyph_id) => { + unsafe { + *glyph = *glyph_id; + } + true as hb_bool_t + } + } +} + +fn _hb_fontations_font_funcs_get() -> *mut hb_font_funcs_t { + static static_ffuncs: AtomicPtr<hb_font_funcs_t> = AtomicPtr::new(null_mut()); + + loop { + let mut ffuncs = static_ffuncs.load(Ordering::Acquire); + + if !ffuncs.is_null() { + return ffuncs; + } + + ffuncs = unsafe { hb_font_funcs_create() }; + + unsafe { + hb_font_funcs_set_nominal_glyphs_func( + ffuncs, + Some(_hb_fontations_get_nominal_glyphs), + null_mut(), + None, + ); + hb_font_funcs_set_variation_glyph_func( + ffuncs, + Some(_hb_fontations_get_variation_glyph), + null_mut(), + None, + ); + hb_font_funcs_set_glyph_h_advances_func( + ffuncs, + Some(_hb_fontations_get_glyph_h_advances), + null_mut(), + None, + ); + hb_font_funcs_set_glyph_extents_func( + ffuncs, + Some(_hb_fontations_get_glyph_extents), + null_mut(), + None, + ); + hb_font_funcs_set_font_h_extents_func( + ffuncs, + Some(_hb_fontations_get_font_h_extents), + null_mut(), + None, + ); + hb_font_funcs_set_draw_glyph_func( + ffuncs, + Some(_hb_fontations_draw_glyph), + null_mut(), + None, + ); + hb_font_funcs_set_paint_glyph_func( + ffuncs, + Some(_hb_fontations_paint_glyph), + null_mut(), + None, + ); + hb_font_funcs_set_glyph_name_func( + ffuncs, + Some(_hb_fontations_glyph_name), + null_mut(), + None, + ); + hb_font_funcs_set_glyph_from_name_func( + ffuncs, + Some(_hb_fontations_glyph_from_name), + null_mut(), + None, + ); + } + + if (static_ffuncs.compare_exchange(null_mut(), ffuncs, Ordering::SeqCst, Ordering::Relaxed)) + == Ok(null_mut()) + { + return ffuncs; + } else { + unsafe { + hb_font_funcs_destroy(ffuncs); + } + } + } +} + +/// # Safety +/// +/// This function is unsafe because it connects with the HarfBuzz API. +#[no_mangle] +pub unsafe extern "C" fn hb_fontations_font_set_funcs(font: *mut hb_font_t) { + let ffuncs = _hb_fontations_font_funcs_get(); + + let data = FontationsData::from_hb_font(font); + let data_ptr = Box::into_raw(Box::new(data)) as *mut c_void; + + hb_font_set_funcs(font, ffuncs, data_ptr, Some(_hb_fontations_data_destroy)); +} diff --git a/source/libs/harfbuzz/harfbuzz-src/src/fontations/meson.build b/source/libs/harfbuzz/harfbuzz-src/src/fontations/meson.build new file mode 100644 index 0000000000000000000000000000000000000000..7f26f3570a3a18d5f7bf50b66bbb372e37d4054c --- /dev/null +++ b/source/libs/harfbuzz/harfbuzz-src/src/fontations/meson.build @@ -0,0 +1,105 @@ +rust = import('unstable-rust') + +hb_rs = rust.bindgen( + input : '../hb.h', + output : 'hb.rs', + include_directories: incsrc, + args : ['--allowlist-function=hb_.*', + '--allowlist-type=hb_.*', + '--no-copy=hb_.*', + ], +) + +cargo = find_program('cargo') +rustfmt = find_program('rustfmt') + +rust_flags = '' +cargo_args = [ + '--package', 'harfbuzz_fontations', + '--lib', + '--target-dir', meson.current_build_dir(), + '--manifest-path', meson.current_source_dir() / 'Cargo.toml', + '-Z', 'build-std=std,panic_abort', + '-Z', 'build-std-features=panic_immediate_abort', +] + +buildtype = get_option('buildtype') +if buildtype == 'release' or buildtype == 'debugoptimized' + cargo_args += ['--profile', buildtype] +endif + +opt_level = get_option('optimization') +rust_flags += ' -C opt-level=' + opt_level + +harfbuzz_fontations = custom_target( + 'harfbuzz_fontations', + input: ['lib.rs', 'Cargo.toml', 'Cargo.lock'], + output: ['libharfbuzz_fontations.a'], + depends: [hb_rs], + env: ['OUT_DIR=' + meson.current_build_dir(), + 'RUSTFLAGS=' + rust_flags, + ], + command: [ + cargo, 'build', + ] + cargo_args + [ + '-Z', 'unstable-options', + '--artifact-dir', meson.current_build_dir(), + ], + install: true, + install_dir: join_paths(get_option('prefix'), 'lib'), +) + +harfbuzz_fontations_dep = declare_dependency( + link_with: harfbuzz_fontations, +) + +clippy_fix = run_target( + 'clippy-fix', + env: ['OUT_DIR=' + meson.current_build_dir()], + depends: [hb_rs, harfbuzz_fontations], + command: [ + cargo, 'clippy', + ] + cargo_args + [ + '--allow-dirty', '--fix', + ], +) +if get_option('tests').enabled() and cargo.found() + test( + 'clippy', + cargo, + env: ['OUT_DIR=' + meson.current_build_dir()], + depends: [hb_rs, harfbuzz_fontations], + args: [ + 'clippy', + ] + cargo_args + [ + '--', '-D', 'warnings', + ], + timeout: 120, + ) +endif + +rustfmt_fix = run_target( + 'rustfmt-fix', + env: ['OUT_DIR=' + meson.current_build_dir()], + depends: [hb_rs], + command: [ + rustfmt, + '--edition', '2021', + '--', + meson.current_source_dir() / 'lib.rs', + ], +) +if get_option('tests').enabled() and rustfmt.found() + test( + 'rustfmt', + rustfmt, + env: ['OUT_DIR=' + meson.current_build_dir()], + depends: [hb_rs], + args: [ + '--check', + '--edition', '2021', + '--', + meson.current_source_dir() / 'lib.rs', + ], + ) +endif diff --git a/source/libs/harfbuzz/harfbuzz-src/src/gen-ragel-artifacts.py b/source/libs/harfbuzz/harfbuzz-src/src/gen-ragel-artifacts.py index 8bbb375bfb80a5467554490d7f360f7d74f0993a..84bd7b22e8c9d847653281796531d288c79ae4c5 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/gen-ragel-artifacts.py +++ b/source/libs/harfbuzz/harfbuzz-src/src/gen-ragel-artifacts.py @@ -19,7 +19,9 @@ outdir = os.path.dirname (OUTPUT) shutil.copy (INPUT, outdir) rl = os.path.basename (INPUT) hh = rl.replace ('.rl', '.hh') -subprocess.Popen (ragel.split() + ['-e', '-F1', '-o', hh, rl], cwd=outdir).wait () +ret = subprocess.Popen (ragel.split() + ['-e', '-F1', '-o', hh, rl], cwd=outdir).wait () +if ret: + sys.exit (ret) # copy it also to src/ shutil.copyfile (os.path.join (outdir, hh), os.path.join (CURRENT_SOURCE_DIR, hh)) diff --git a/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc b/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc index 9ff800daa7f10acc48051c6c1cac5bab9d610c77..985797df492e6adf05f8d119886050236d4921aa 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc @@ -8,6 +8,9 @@ #include "hb-common.cc" #include "hb-coretext-font.cc" #include "hb-coretext-shape.cc" +#include "hb-coretext.cc" +#include "hb-directwrite-font.cc" +#include "hb-directwrite-shape.cc" #include "hb-directwrite.cc" #include "hb-draw.cc" #include "hb-face-builder.cc" diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh index d2626b45f8e5178eb6d69de63ec11377c71a7654..640778e454f674a8687357a0e2ec9b306799f35f 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh @@ -29,6 +29,8 @@ #include "hb-aat-layout.hh" #include "hb-aat-map.hh" +#include "hb-ot-layout-common.hh" +#include "hb-ot-layout-gdef-table.hh" #include "hb-open-type.hh" #include "hb-cache.hh" #include "hb-bit-set.hh" @@ -48,6 +50,61 @@ struct ankr; using hb_aat_class_cache_t = hb_cache_t<15, 8, 7>; static_assert (sizeof (hb_aat_class_cache_t) == 256, ""); +struct hb_aat_scratch_t +{ + hb_aat_scratch_t () = default; + hb_aat_scratch_t (const hb_aat_scratch_t &) = delete; + + hb_aat_scratch_t (hb_aat_scratch_t &&o) + { + buffer_glyph_set.set_relaxed (o.buffer_glyph_set.get_relaxed ()); + o.buffer_glyph_set.set_relaxed (nullptr); + } + hb_aat_scratch_t & operator = (hb_aat_scratch_t &&o) + { + buffer_glyph_set.set_relaxed (o.buffer_glyph_set.get_relaxed ()); + o.buffer_glyph_set.set_relaxed (nullptr); + return *this; + } + ~hb_aat_scratch_t () + { + auto *s = buffer_glyph_set.get_relaxed (); + if (unlikely (!s)) + return; + s->fini (); + hb_free (s); + } + + hb_bit_set_t *create_buffer_glyph_set () const + { + hb_bit_set_t *s = buffer_glyph_set.get_acquire (); + if (s && buffer_glyph_set.cmpexch (s, nullptr)) + return s; + + s = (hb_bit_set_t *) hb_calloc (1, sizeof (hb_bit_set_t)); + if (unlikely (!s)) + return nullptr; + s->init (); + + return s; + } + void destroy_buffer_glyph_set (hb_bit_set_t *s) const + { + if (unlikely (!s)) + return; + if (buffer_glyph_set.cmpexch (nullptr, s)) + return; + s->fini (); + hb_free (s); + } + + mutable hb_atomic_t<hb_bit_set_t *> buffer_glyph_set; +}; + +enum { DELETED_GLYPH = 0xFFFF }; + +#define HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED HB_BUFFER_SCRATCH_FLAG_SHAPER0 + struct hb_aat_apply_context_t : hb_dispatch_context_t<hb_aat_apply_context_t, bool, HB_DEBUG_APPLY> { @@ -64,10 +121,11 @@ struct hb_aat_apply_context_t : hb_buffer_t *buffer; hb_sanitize_context_t sanitizer; const ankr *ankr_table; - const OT::GDEF *gdef_table; + const OT::GDEF &gdef; + bool has_glyph_classes; const hb_sorted_vector_t<hb_aat_map_t::range_flags_t> *range_flags = nullptr; bool using_buffer_glyph_set = false; - hb_bit_set_t buffer_glyph_set; + hb_bit_set_t *buffer_glyph_set = nullptr; const hb_bit_set_t *left_set = nullptr; const hb_bit_set_t *right_set = nullptr; const hb_bit_set_t *machine_glyph_set = nullptr; @@ -90,15 +148,15 @@ struct hb_aat_apply_context_t : void setup_buffer_glyph_set () { - using_buffer_glyph_set = buffer->len >= 4; + using_buffer_glyph_set = buffer->len >= 4 && buffer_glyph_set; - if (using_buffer_glyph_set) - buffer->collect_codepoints (buffer_glyph_set); + if (likely (using_buffer_glyph_set)) + buffer->collect_codepoints (*buffer_glyph_set); } bool buffer_intersects_machine () const { - if (using_buffer_glyph_set) - return buffer_glyph_set.intersects (*machine_glyph_set); + if (likely (using_buffer_glyph_set)) + return buffer_glyph_set->intersects (*machine_glyph_set); // Faster for shorter buffers. for (unsigned i = 0; i < buffer->len; i++) @@ -106,6 +164,66 @@ struct hb_aat_apply_context_t : return true; return false; } + + template <typename T> + HB_NODISCARD bool output_glyphs (unsigned int count, + const T *glyphs) + { + if (likely (using_buffer_glyph_set)) + buffer_glyph_set->add_array (glyphs, count); + for (unsigned int i = 0; i < count; i++) + { + if (glyphs[i] == DELETED_GLYPH) + { + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED; + _hb_glyph_info_set_aat_deleted (&buffer->cur()); + } + else + { +#ifndef HB_NO_OT_LAYOUT + if (has_glyph_classes) + _hb_glyph_info_set_glyph_props (&buffer->cur(), + gdef.get_glyph_props (glyphs[i])); +#endif + } + if (unlikely (!buffer->output_glyph (glyphs[i]))) return false; + } + return true; + } + + HB_NODISCARD bool replace_glyph (hb_codepoint_t glyph) + { + if (glyph == DELETED_GLYPH) + return delete_glyph (); + + if (likely (using_buffer_glyph_set)) + buffer_glyph_set->add (glyph); +#ifndef HB_NO_OT_LAYOUT + if (has_glyph_classes) + _hb_glyph_info_set_glyph_props (&buffer->cur(), + gdef.get_glyph_props (glyph)); +#endif + return buffer->replace_glyph (glyph); + } + + HB_NODISCARD bool delete_glyph () + { + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED; + _hb_glyph_info_set_aat_deleted (&buffer->cur()); + return buffer->replace_glyph (DELETED_GLYPH); + } + + void replace_glyph_inplace (unsigned i, hb_codepoint_t glyph) + { + buffer->info[i].codepoint = glyph; + if (likely (using_buffer_glyph_set)) + buffer_glyph_set->add (glyph); +#ifndef HB_NO_OT_LAYOUT + if (has_glyph_classes) + _hb_glyph_info_set_glyph_props (&buffer->info[i], + gdef.get_glyph_props (glyph)); +#endif + } }; @@ -113,8 +231,6 @@ struct hb_aat_apply_context_t : * Lookup Table */ -enum { DELETED_GLYPH = 0xFFFF }; - template <typename T> struct Lookup; template <typename T> @@ -179,6 +295,7 @@ struct LookupSegmentSingle template <typename set_t, typename filter_t> void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const { + if (first == DELETED_GLYPH) return; if (!filter (value)) return; glyphs.add_range (first, last); } @@ -268,6 +385,7 @@ struct LookupSegmentArray template <typename set_t, typename filter_t> void collect_glyphs_filtered (set_t &glyphs, const void *base, const filter_t &filter) const { + if (first == DELETED_GLYPH) return; const auto &values = base+valuesZ; for (hb_codepoint_t i = first; i <= last; i++) if (filter (values[i - first])) @@ -368,6 +486,7 @@ struct LookupSingle template <typename set_t, typename filter_t> void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const { + if (glyph == DELETED_GLYPH) return; if (!filter (value)) return; glyphs.add (glyph); } @@ -746,6 +865,10 @@ struct StateTable } // And glyphs in those classes. + + if (filter (CLASS_DELETED_GLYPH)) + glyphs.add (DELETED_GLYPH); + (this+classTable).collect_glyphs_filtered (glyphs, num_glyphs, filter); } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh index 4b980ca896f40fee55d9b85f3d686db69158d76d..e5b17ba1d4113195420238b8140dc56332a04463 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh @@ -185,6 +185,9 @@ struct Format1Entry<true> DEFINE_SIZE_STATIC (2); }; + static bool initiateAction (const Entry<EntryData> &entry) + { return entry.flags & Push; } + static bool performAction (const Entry<EntryData> &entry) { return entry.data.kernActionIndex != 0xFFFF; } @@ -325,8 +328,9 @@ struct KerxSubTableFormat1 } else if (buffer->info[idx].mask & kern_mask) { - o.x_advance += c->font->em_scale_x (v); - o.x_offset += c->font->em_scale_x (v); + auto scaled = c->font->em_scale_x (v); + o.x_advance += scaled; + o.x_offset += scaled; } } else @@ -394,10 +398,8 @@ struct KerxSubTableFormat1 template <typename set_t> void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const { - set_t set; - machine.collect_glyphs (set, num_glyphs); - left_set.union_ (set); - right_set.union_ (set); + machine.collect_initial_glyphs (left_set, num_glyphs, *this); + //machine.collect_glyphs (right_set, num_glyphs); // right_set is unused for machine kerning } protected: @@ -671,10 +673,8 @@ struct KerxSubTableFormat4 template <typename set_t> void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const { - set_t set; - machine.collect_glyphs (set, num_glyphs); - left_set.union_ (set); - right_set.union_ (set); + machine.collect_initial_glyphs (left_set, num_glyphs, *this); + //machine.collect_glyphs (right_set, num_glyphs); // right_set is unused for machine kerning } protected: @@ -921,7 +921,18 @@ struct KerxSubTable * The 'kerx' Table */ -using kern_accelerator_data_t = hb_vector_t<hb_pair_t<hb_bit_set_t, hb_bit_set_t>>; +struct kern_subtable_accelerator_data_t +{ + hb_bit_set_t left_set; + hb_bit_set_t right_set; + mutable hb_aat_class_cache_t class_cache; +}; + +struct kern_accelerator_data_t +{ + hb_vector_t<kern_subtable_accelerator_data_t> subtable_accels; + hb_aat_scratch_t scratch; +}; template <typename T> struct KerxTable @@ -985,6 +996,8 @@ struct KerxTable { c->buffer->unsafe_to_concat (); + c->setup_buffer_glyph_set (); + typedef typename T::SubTable SubTable; bool ret = false; @@ -996,12 +1009,25 @@ struct KerxTable { bool reverse; + auto &subtable_accel = accel_data.subtable_accels[i]; + if (!T::Types::extended && (st->u.header.coverage & st->u.header.Variation)) goto skip; if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->u.header.is_horizontal ()) goto skip; + c->left_set = &subtable_accel.left_set; + c->right_set = &subtable_accel.right_set; + c->machine_glyph_set = &subtable_accel.left_set; + c->machine_class_cache = &subtable_accel.class_cache; + + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped subtable %u because no glyph matches", c->lookup_index); + goto skip; + } + reverse = bool (st->u.header.coverage & st->u.header.Backwards) != HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); @@ -1028,9 +1054,6 @@ struct KerxTable if (reverse) c->buffer->reverse (); - c->left_set = &accel_data[i].first; - c->right_set = &accel_data[i].second; - { /* See comment in sanitize() for conditional here. */ hb_sanitize_with_object_t with (&c->sanitizer, i < count - 1 ? st : (const SubTable *) nullptr); @@ -1106,9 +1129,13 @@ struct KerxTable unsigned int count = thiz()->tableCount; for (unsigned int i = 0; i < count; i++) { - hb_bit_set_t left_set, right_set; - st->collect_glyphs (left_set, right_set, num_glyphs); - accel_data.push (hb_pair (left_set, right_set)); + auto &subtable_accel = *accel_data.subtable_accels.push (); + if (unlikely (accel_data.subtable_accels.in_error ())) + return accel_data; + + st->collect_glyphs (subtable_accel.left_set, subtable_accel.right_set, num_glyphs); + subtable_accel.class_cache.clear (); + st = &StructAfter<SubTable> (*st); } @@ -1137,6 +1164,7 @@ struct KerxTable hb_blob_ptr_t<T> table; kern_accelerator_data_t accel_data; + hb_aat_scratch_t scratch; }; }; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh index 617a239fe49732161ca7587c24fc28e028a5e66b..663e47991d411e4aa2c02e3033823eb7a3605f41 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh @@ -30,8 +30,6 @@ #include "hb-open-type.hh" #include "hb-aat-layout-common.hh" #include "hb-ot-layout.hh" -#include "hb-ot-layout-common.hh" -#include "hb-ot-layout-gdef-table.hh" #include "hb-aat-map.hh" /* @@ -178,12 +176,6 @@ struct RearrangementSubtable StateTableDriver<Types, EntryData, Flags> driver (machine, c->face); - if (!c->buffer_intersects_machine ()) - { - (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); - return_trace (false); - } - driver.drive (&dc, c); return_trace (dc.ret); @@ -242,9 +234,7 @@ struct ContextualSubtable ret (false), c (c_), table (table_), - gdef (*c->gdef_table), mark_set (false), - has_glyph_classes (gdef.has_glyph_classes ()), mark (0), subs (table+table->substitutionTables) {} @@ -281,12 +271,7 @@ struct ContextualSubtable if (replacement) { buffer->unsafe_to_break (mark, hb_min (buffer->idx + 1, buffer->len)); - hb_codepoint_t glyph = *replacement; - buffer->info[mark].codepoint = glyph; - c->buffer_glyph_set.add (glyph); - if (has_glyph_classes) - _hb_glyph_info_set_glyph_props (&buffer->info[mark], - gdef.get_glyph_props (*replacement)); + c->replace_glyph_inplace (mark, *replacement); ret = true; } @@ -312,12 +297,7 @@ struct ContextualSubtable } if (replacement) { - hb_codepoint_t glyph = *replacement; - buffer->info[idx].codepoint = glyph; - c->buffer_glyph_set.add (glyph); - if (has_glyph_classes) - _hb_glyph_info_set_glyph_props (&buffer->info[idx], - gdef.get_glyph_props (*replacement)); + c->replace_glyph_inplace (idx, *replacement); ret = true; } @@ -333,9 +313,7 @@ struct ContextualSubtable hb_aat_apply_context_t *c; const ContextualSubtable *table; private: - const OT::GDEF &gdef; bool mark_set; - bool has_glyph_classes; unsigned int mark; const UnsizedListOfOffset16To<Lookup<HBGlyphID16>, HBUINT, void, false> &subs; }; @@ -348,12 +326,6 @@ struct ContextualSubtable StateTableDriver<Types, EntryData, Flags> driver (machine, c->face); - if (!c->buffer_intersects_machine ()) - { - (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); - return_trace (false); - } - driver.drive (&dc, c); return_trace (dc.ret); @@ -581,7 +553,7 @@ struct LigatureSubtable hb_codepoint_t lig = ligatureData; DEBUG_MSG (APPLY, nullptr, "Produced ligature %u", lig); - if (unlikely (!buffer->replace_glyph (lig))) return; + if (unlikely (!c->replace_glyph (lig))) return; unsigned int lig_end = match_positions[(match_length - 1u) % ARRAY_LENGTH (match_positions)] + 1u; /* Now go and delete all subsequent components. */ @@ -589,8 +561,7 @@ struct LigatureSubtable { DEBUG_MSG (APPLY, nullptr, "Skipping ligature component"); if (unlikely (!buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]))) return; - _hb_glyph_info_set_default_ignorable (&buffer->cur()); - if (unlikely (!buffer->replace_glyph (DELETED_GLYPH))) return; + if (!c->delete_glyph ()) return; } if (unlikely (!buffer->move_to (lig_end))) return; @@ -624,12 +595,6 @@ struct LigatureSubtable StateTableDriver<Types, EntryData, Flags> driver (machine, c->face); - if (!c->buffer_intersects_machine ()) - { - (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); - return_trace (false); - } - driver.drive (&dc, c); return_trace (dc.ret); @@ -665,15 +630,6 @@ struct NoncontextualSubtable { TRACE_APPLY (this); - if (!c->buffer_intersects_machine ()) - { - (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); - return_trace (false); - } - - const OT::GDEF &gdef (*c->gdef_table); - bool has_glyph_classes = gdef.has_glyph_classes (); - bool ret = false; unsigned int num_glyphs = c->face->get_num_glyphs (); @@ -703,12 +659,7 @@ struct NoncontextualSubtable const HBGlyphID16 *replacement = substitute.get_value (info[i].codepoint, num_glyphs); if (replacement) { - hb_codepoint_t glyph = *replacement; - info[i].codepoint = glyph; - c->buffer_glyph_set.add (glyph); - if (has_glyph_classes) - _hb_glyph_info_set_glyph_props (&info[i], - gdef.get_glyph_props (*replacement)); + c->replace_glyph_inplace (i, *replacement); ret = true; } } @@ -850,9 +801,7 @@ struct InsertionSubtable if (buffer->idx < buffer->len && !before) if (unlikely (!buffer->copy_glyph ())) return; /* TODO We ignore KashidaLike setting. */ - if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return; - for (unsigned int i = 0; i < count; i++) - c->buffer_glyph_set.add (glyphs[i]); + if (unlikely (!c->output_glyphs (count, glyphs))) return; ret = true; if (buffer->idx < buffer->len && !before) buffer->skip_glyph (); @@ -881,7 +830,8 @@ struct InsertionSubtable if (buffer->idx < buffer->len && !before) if (unlikely (!buffer->copy_glyph ())) return; /* TODO We ignore KashidaLike setting. */ - if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return; + if (unlikely (!c->output_glyphs (count, glyphs))) return; + ret = true; if (buffer->idx < buffer->len && !before) buffer->skip_glyph (); @@ -921,12 +871,6 @@ struct InsertionSubtable StateTableDriver<Types, EntryData, Flags> driver (machine, c->face); - if (!c->buffer_intersects_machine ()) - { - (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); - return_trace (false); - } - driver.drive (&dc, c); return_trace (dc.ret); @@ -1224,6 +1168,7 @@ struct Chain if (hb_none (hb_iter (c->range_flags) | hb_map ([subtable_flags] (const hb_aat_map_t::range_flags_t _) -> bool { return subtable_flags & (_.flags); }))) goto skip; + c->subtable_flags = subtable_flags; c->machine_glyph_set = accel ? &accel->subtables[i].glyph_set : &Null(hb_bit_set_t); c->machine_class_cache = accel ? &accel->subtables[i].class_cache : nullptr; @@ -1233,6 +1178,12 @@ struct Chain bool (coverage & ChainSubtable<Types>::Vertical)) goto skip; + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped chainsubtable %u because no glyph matches", c->lookup_index); + goto skip; + } + /* Buffer contents is always in logical direction. Determine if * we need to reverse before applying this subtable. We reverse * back after if we did reverse indeed. @@ -1376,7 +1327,7 @@ struct mortmorx this->chain_count = table->get_chain_count (); - this->accels = (hb_atomic_ptr_t<hb_aat_layout_chain_accelerator_t> *) hb_calloc (this->chain_count, sizeof (*accels)); + this->accels = (hb_atomic_t<hb_aat_layout_chain_accelerator_t *> *) hb_calloc (this->chain_count, sizeof (*accels)); if (unlikely (!this->accels)) { this->chain_count = 0; @@ -1423,7 +1374,8 @@ struct mortmorx hb_blob_ptr_t<T> table; unsigned int chain_count; - hb_atomic_ptr_t<hb_aat_layout_chain_accelerator_t> *accels; + hb_atomic_t<hb_aat_layout_chain_accelerator_t *> *accels; + hb_aat_scratch_t scratch; }; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh index 508606037ad2443de95e38b2402130565397c71d..24c212c2c165e66116dca24792eeff1d4faaa240 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh @@ -142,9 +142,9 @@ struct TrackData unsigned j = count - 1; // Find the two entries that track is between. - while (i + 1 < count && trackTable[i + 1].get_track_value () < track) + while (i + 1 < count && trackTable[i + 1].get_track_value () <= track) i++; - while (j > 0 && trackTable[j - 1].get_track_value () > track) + while (j > 0 && trackTable[j - 1].get_track_value () >= track) j--; // Exact match. diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc index 9fe77a575958de9245ad1df63c18722ccf51e917..374554466829ad5e860ac907cf3702f4b6b7ae87 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc @@ -58,13 +58,14 @@ AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *p buffer (buffer_), sanitizer (), ankr_table (&Null (AAT::ankr)), - gdef_table ( + gdef ( #ifndef HB_NO_OT_LAYOUT - face->table.GDEF->table + *face->table.GDEF->table #else - &Null (GDEF) + Null (GDEF) #endif ), + has_glyph_classes (gdef.has_glyph_classes ()), lookup_index (0) { sanitizer.init (blob); @@ -203,7 +204,7 @@ hb_aat_layout_find_feature_mapping (hb_tag_t tag) #endif -#ifndef HB_NO_AAT +#ifndef HB_NO_AAT_SHAPE /* * mort/morx/kerx/trak @@ -287,11 +288,14 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, const hb_feature_t *features, unsigned num_features) { - hb_aat_map_builder_t builder (font->face, plan->props); - for (unsigned i = 0; i < num_features; i++) - builder.add_feature (features[i]); hb_aat_map_t map; - builder.compile (map); + if (num_features) + { + hb_aat_map_builder_t builder (font->face, plan->props); + for (unsigned i = 0; i < num_features; i++) + builder.add_feature (features[i]); + builder.compile (map); + } { auto &accel = *font->face->table.morx; @@ -300,7 +304,10 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, { AAT::hb_aat_apply_context_t c (plan, font, buffer, accel.get_blob ()); if (!buffer->message (font, "start table morx")) return; - morx.apply (&c, map, accel); + c.buffer_glyph_set = accel.scratch.create_buffer_glyph_set (); + morx.apply (&c, num_features ? map : plan->aat_map, accel); + accel.scratch.destroy_buffer_glyph_set (c.buffer_glyph_set); + c.buffer_glyph_set = nullptr; (void) buffer->message (font, "end table morx"); return; } @@ -313,34 +320,24 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, { AAT::hb_aat_apply_context_t c (plan, font, buffer, accel.get_blob ()); if (!buffer->message (font, "start table mort")) return; - mort.apply (&c, map, accel); + mort.apply (&c, num_features ? map : plan->aat_map, accel); (void) buffer->message (font, "end table mort"); return; } } } -void -hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer) -{ - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - hb_glyph_position_t *pos = buffer->pos; - for (unsigned int i = 0; i < count; i++) - if (unlikely (info[i].codepoint == AAT::DELETED_GLYPH)) - pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; -} - static bool is_deleted_glyph (const hb_glyph_info_t *info) { - return info->codepoint == AAT::DELETED_GLYPH; + return _hb_glyph_info_is_aat_deleted (info); } void hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer) { - buffer->delete_glyphs_inplace (is_deleted_glyph); + if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED) + buffer->delete_glyphs_inplace (is_deleted_glyph); } /** @@ -371,8 +368,11 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, AAT::hb_aat_apply_context_t c (plan, font, buffer, accel.get_blob ()); if (!buffer->message (font, "start table kerx")) return; + c.buffer_glyph_set = accel.scratch.create_buffer_glyph_set (); c.set_ankr_table (font->face->table.ankr.get ()); accel.apply (&c); + accel.scratch.destroy_buffer_glyph_set (c.buffer_glyph_set); + c.buffer_glyph_set = nullptr; (void) buffer->message (font, "end table kerx"); } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh index c5d6ecb10b0c47ccbacab77f88b6451d38d6bd64..0e4ae6e7b3c0cc92fd2d91a29ef43672460182c3 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh @@ -60,9 +60,6 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, const hb_feature_t *features, unsigned num_features); -HB_INTERNAL void -hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer); - HB_INTERNAL void hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc index 1a0dee022bb17bba14c0195e2b8a8a531bdd55f4..0b85c901e8eb8ba516645b4b125da6c9101d2b18 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc @@ -85,6 +85,11 @@ void hb_aat_map_builder_t::compile (hb_aat_map_t &m) { /* Compute active features per range, and compile each. */ + if (!features.length) + { + hb_aat_layout_compile_map (this, &m); + return; + } /* Sort features by start/end events. */ hb_vector_t<feature_event_t> feature_events; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh index 121c463a56bd2fc73ca8fa3c57c2a36a717e1a80..e92ccbca109cc875df79912f19a64097b73d35de 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh @@ -149,62 +149,47 @@ static inline void _hb_compiler_memory_r_barrier () {} #define hb_atomic_ptr_impl_get_relaxed(P) (*(P)) #endif #ifndef hb_atomic_int_impl_set -inline void hb_atomic_int_impl_set (int *AI, int v) { _hb_memory_w_barrier (); *AI = v; } -inline void hb_atomic_int_impl_set (short *AI, short v) { _hb_memory_w_barrier (); *AI = v; } +template <typename T> +inline void hb_atomic_int_impl_set (T *AI, T v) { _hb_memory_w_barrier (); *AI = v; } #endif #ifndef hb_atomic_int_impl_get -inline int hb_atomic_int_impl_get (const int *AI) { int v = *AI; _hb_memory_r_barrier (); return v; } -inline short hb_atomic_int_impl_get (const short *AI) { short v = *AI; _hb_memory_r_barrier (); return v; } +template <typename T> +inline T hb_atomic_int_impl_get (const T *AI) { T v = *AI; _hb_memory_r_barrier (); return v; } #endif #ifndef hb_atomic_ptr_impl_get inline void *hb_atomic_ptr_impl_get (void ** const P) { void *v = *P; _hb_memory_r_barrier (); return v; } #endif -struct hb_atomic_short_t +template <typename T> +struct hb_atomic_t { - hb_atomic_short_t () = default; - constexpr hb_atomic_short_t (short v) : v (v) {} + hb_atomic_t () = default; + constexpr hb_atomic_t (T v) : v (v) {} - hb_atomic_short_t& operator = (short v_) { set_relaxed (v_); return *this; } - operator short () const { return get_relaxed (); } + hb_atomic_t& operator = (T v_) { set_relaxed (v_); return *this; } + operator T () const { return get_relaxed (); } - void set_relaxed (short v_) { hb_atomic_int_impl_set_relaxed (&v, v_); } - void set_release (short v_) { hb_atomic_int_impl_set (&v, v_); } - short get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); } - short get_acquire () const { return hb_atomic_int_impl_get (&v); } - short inc () { return hb_atomic_int_impl_add (&v, 1); } - short dec () { return hb_atomic_int_impl_add (&v, -1); } + void set_relaxed (T v_) { hb_atomic_int_impl_set_relaxed (&v, v_); } + void set_release (T v_) { hb_atomic_int_impl_set (&v, v_); } + T get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); } + T get_acquire () const { return hb_atomic_int_impl_get (&v); } + T inc () { return hb_atomic_int_impl_add (&v, 1); } + T dec () { return hb_atomic_int_impl_add (&v, -1); } - short v = 0; -}; - -struct hb_atomic_int_t -{ - hb_atomic_int_t () = default; - constexpr hb_atomic_int_t (int v) : v (v) {} + int operator ++ (int) { return inc (); } + int operator -- (int) { return dec (); } + long operator |= (long v_) { set_relaxed (get_relaxed () | v_); return *this; } - hb_atomic_int_t& operator = (int v_) { set_relaxed (v_); return *this; } - operator int () const { return get_relaxed (); } - - void set_relaxed (int v_) { hb_atomic_int_impl_set_relaxed (&v, v_); } - void set_release (int v_) { hb_atomic_int_impl_set (&v, v_); } - int get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); } - int get_acquire () const { return hb_atomic_int_impl_get (&v); } - int inc () { return hb_atomic_int_impl_add (&v, 1); } - int dec () { return hb_atomic_int_impl_add (&v, -1); } - - int v = 0; + T v = 0; }; -template <typename P> -struct hb_atomic_ptr_t +template <typename T> +struct hb_atomic_t<T*> { - typedef hb_remove_pointer<P> T; - - hb_atomic_ptr_t () = default; - constexpr hb_atomic_ptr_t (T* v) : v (v) {} - hb_atomic_ptr_t (const hb_atomic_ptr_t &other) = delete; + hb_atomic_t () = default; + constexpr hb_atomic_t (T* v) : v (v) {} + hb_atomic_t (const hb_atomic_t &other) = delete; void init (T* v_ = nullptr) { set_relaxed (v_); } void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh index 4607b884d5b3c109c71544452bb10eaa8c8da7b8..ec462c7d415d9c1d05da45cbffe56d5ed6e588b7 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh @@ -77,7 +77,7 @@ struct hb_bit_set_t bool successful = true; /* Allocations successful */ mutable unsigned int population = 0; - mutable hb_atomic_int_t last_page_lookup = 0; + mutable hb_atomic_t<unsigned> last_page_lookup = 0; hb_sorted_vector_t<page_map_t> page_map; hb_vector_t<page_t> pages; @@ -88,7 +88,7 @@ struct hb_bit_set_t { if (unlikely (!successful)) return false; - if (pages.length < count && count <= 2) + if (pages.length < count && (unsigned) pages.allocated < count && count <= 2) exact_size = true; // Most sets are small and local if (unlikely (!pages.resize (count, clear, exact_size) || diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-vector.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-vector.hh new file mode 100644 index 0000000000000000000000000000000000000000..58084e59a3d7e1c9acf8891d6bb27c391438fb79 --- /dev/null +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-vector.hh @@ -0,0 +1,195 @@ +/* + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_BIT_VECTOR_HH +#define HB_BIT_VECTOR_HH + +#include "hb.hh" + +#include "hb-atomic.hh" + +struct hb_min_max_t +{ + void add (hb_codepoint_t v) { min_v = hb_min (min_v, v); max_v = hb_max (max_v, v); } + void add_range (hb_codepoint_t a, hb_codepoint_t b) + { + min_v = hb_min (min_v, a); + max_v = hb_max (max_v, b); + } + + template <typename set_t> + void union_ (const set_t &set) + { + hb_codepoint_t set_min = set.get_min (); + if (unlikely (set_min == HB_CODEPOINT_INVALID)) + return; + hb_codepoint_t set_max = set.get_max (); + min_v = hb_min (min_v, set_min); + max_v = hb_max (max_v, set_max); + } + + hb_codepoint_t get_min () const { return min_v; } + hb_codepoint_t get_max () const { return max_v; } + + private: + hb_codepoint_t min_v = HB_CODEPOINT_INVALID; + hb_codepoint_t max_v = 0; +}; + +template <bool atomic = false> +struct hb_bit_vector_t +{ + using int_t = uint64_t; + using elt_t = typename std::conditional<atomic, hb_atomic_t<int_t>, int_t>::type; + + hb_bit_vector_t () = delete; + hb_bit_vector_t (const hb_bit_vector_t &other) = delete; + hb_bit_vector_t &operator= (const hb_bit_vector_t &other) = delete; + + // Move + hb_bit_vector_t (hb_bit_vector_t &&other) + : min_v (other.min_v), max_v (other.max_v), count (other.count), elts (other.elts) + { + other.min_v = other.max_v = other.count = 0; + other.elts = nullptr; + } + hb_bit_vector_t &operator= (hb_bit_vector_t &&other) + { + hb_swap (min_v, other.min_v); + hb_swap (max_v, other.max_v); + hb_swap (count, other.count); + hb_swap (elts, other.elts); + return *this; + } + + hb_bit_vector_t (unsigned min_v, unsigned max_v) + : min_v (min_v), max_v (max_v) + { + if (unlikely (min_v >= max_v)) + { + min_v = max_v = count = 0; + return; + } + + unsigned num = (max_v - min_v + sizeof (int_t) * 8) / (sizeof (int_t) * 8); + elts = (elt_t *) hb_calloc (num, sizeof (int_t)); + if (unlikely (!elts)) + { + min_v = max_v = count = 0; + return; + } + + count = max_v - min_v + 1; + } + ~hb_bit_vector_t () + { + hb_free (elts); + } + + void add (hb_codepoint_t g) { elt (g) |= mask (g); } + void del (hb_codepoint_t g) { elt (g) &= ~mask (g); } + void set (hb_codepoint_t g, bool value) { if (value) add (g); else del (g); } + bool get (hb_codepoint_t g) const { return elt (g) & mask (g); } + bool has (hb_codepoint_t g) const { return get (g); } + bool may_have (hb_codepoint_t g) const { return get (g); } + + bool operator [] (hb_codepoint_t g) const { return get (g); } + bool operator () (hb_codepoint_t g) const { return get (g); } + + void add_range (hb_codepoint_t a, hb_codepoint_t b) + { + if (unlikely (!count || a > b || a < min_v || b > max_v)) + return; + + elt_t *la = &elt (a); + elt_t *lb = &elt (b); + if (la == lb) + *la |= (mask (b) << 1) - mask(a); + else + { + *la |= ~(mask (a) - 1llu); + la++; + + hb_memset (la, 0xff, (char *) lb - (char *) la); + + *lb |= ((mask (b) << 1) - 1llu); + } + } + void del_range (hb_codepoint_t a, hb_codepoint_t b) + { + if (unlikely (!count || a > b || a < min_v || b > max_v)) + return; + + elt_t *la = &elt (a); + elt_t *lb = &elt (b); + if (la == lb) + *la &= ~((mask (b) << 1llu) - mask(a)); + else + { + *la &= mask (a) - 1; + la++; + + hb_memset (la, 0, (char *) lb - (char *) la); + + *lb &= ~((mask (b) << 1) - 1llu); + } + } + void set_range (hb_codepoint_t a, hb_codepoint_t b, bool v) + { if (v) add_range (a, b); else del_range (a, b); } + + template <typename set_t> + void union_ (const set_t &set) + { + for (hb_codepoint_t g : set) + add (g); + } + + static const unsigned int ELT_BITS = sizeof (elt_t) * 8; + static constexpr unsigned ELT_MASK = ELT_BITS - 1; + + static constexpr elt_t zero = 0; + + elt_t &elt (hb_codepoint_t g) + { + g -= min_v; + if (unlikely (g >= count)) + return Crap(elt_t); + return elts[g / ELT_BITS]; + } + const elt_t& elt (hb_codepoint_t g) const + { + g -= min_v; + if (unlikely (g >= count)) + return Null(elt_t); + return elts[g / ELT_BITS]; + } + + static constexpr int_t mask (hb_codepoint_t g) { return elt_t (1) << (g & ELT_MASK); } + + hb_codepoint_t min_v = 0, max_v = 0, count = 0; + elt_t *elts = nullptr; +}; + + +#endif /* HB_BIT_VECTOR_HH */ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.hh index 471bbb93fdbdf665275eae9ff0b7710fa446e2d0..b5bb3f4b29afb8abfe98c26b3910416e253a0e77 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.hh @@ -34,57 +34,66 @@ #line 36 "hb-buffer-deserialize-json.hh" static const unsigned char _deserialize_json_trans_keys[] = { - 0u, 0u, 9u, 123u, 9u, 123u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, - 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, - 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, - 9u, 125u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, - 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, - 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 34u, 92u, - 9u, 125u, 34u, 92u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, - 9u, 93u, 9u, 123u, 0u, 0u, 0 + 0u, 0u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, + 9u, 125u, 9u, 125u, 9u, 93u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, + 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, + 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, + 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, + 9u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 34u, 92u, 9u, 125u, + 34u, 92u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 123u, + 9u, 123u, 9u, 123u, 0 }; static const char _deserialize_json_key_spans[] = { - 0, 115, 115, 26, 21, 2, 1, 50, - 49, 10, 117, 117, 117, 1, 50, 49, - 10, 117, 117, 1, 1, 50, 49, 117, - 117, 2, 1, 50, 49, 10, 117, 117, - 1, 50, 49, 10, 117, 117, 1, 1, - 50, 49, 117, 117, 1, 50, 49, 59, - 117, 59, 117, 117, 1, 50, 49, 117, - 85, 115, 0 + 0, 26, 21, 2, 1, 50, 49, 10, + 117, 117, 85, 117, 1, 50, 49, 10, + 117, 117, 1, 1, 50, 49, 117, 117, + 2, 1, 50, 49, 10, 117, 117, 1, + 50, 49, 10, 117, 117, 1, 1, 50, + 49, 117, 117, 1, 50, 49, 59, 117, + 59, 117, 117, 1, 50, 49, 117, 115, + 115, 115 }; static const short _deserialize_json_index_offsets[] = { - 0, 0, 116, 232, 259, 281, 284, 286, - 337, 387, 398, 516, 634, 752, 754, 805, - 855, 866, 984, 1102, 1104, 1106, 1157, 1207, - 1325, 1443, 1446, 1448, 1499, 1549, 1560, 1678, - 1796, 1798, 1849, 1899, 1910, 2028, 2146, 2148, - 2150, 2201, 2251, 2369, 2487, 2489, 2540, 2590, - 2650, 2768, 2828, 2946, 3064, 3066, 3117, 3167, - 3285, 3371, 3487 + 0, 0, 27, 49, 52, 54, 105, 155, + 166, 284, 402, 488, 606, 608, 659, 709, + 720, 838, 956, 958, 960, 1011, 1061, 1179, + 1297, 1300, 1302, 1353, 1403, 1414, 1532, 1650, + 1652, 1703, 1753, 1764, 1882, 2000, 2002, 2004, + 2055, 2105, 2223, 2341, 2343, 2394, 2444, 2504, + 2622, 2682, 2800, 2918, 2920, 2971, 3021, 3139, + 3255, 3371 }; static const char _deserialize_json_indicies[] = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 2, 1, 3, 1, 4, 5, + 1, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 8, 1, 9, 10, 1, 11, 1, 11, + 11, 11, 11, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 12, 1, 12, 12, 12, 12, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 12, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 13, 1, + 1, 14, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 1, 16, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 1, 18, + 18, 18, 18, 18, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 18, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 1, 2, 2, 2, - 2, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -93,66 +102,66 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 20, 1, 21, 21, 21, + 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 3, - 1, 4, 4, 4, 4, 4, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 4, 1, 5, 1, 6, 1, 7, 8, - 1, 9, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 11, 1, 12, 13, 1, 14, 1, 14, - 14, 14, 14, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 15, 1, 15, 15, 15, 15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 15, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 16, 1, - 1, 17, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 1, 19, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 1, 21, - 21, 21, 21, 21, 1, 1, 1, 1, + 1, 22, 1, 22, 22, 22, 22, 22, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 22, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 23, + 1, 18, 18, 18, 18, 18, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 18, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 19, 1, 1, 1, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 23, 1, 24, 24, 24, - 24, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 20, 1, 24, + 1, 24, 24, 24, 24, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 25, 1, 25, 25, 25, 25, + 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 25, 1, 21, 21, 21, 21, 21, + 26, 1, 1, 27, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 1, 29, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 1, 31, 31, 31, 31, 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 21, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 22, 1, - 1, 1, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 1, 1, 1, 1, + 31, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 32, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -160,86 +169,86 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 23, - 1, 26, 1, 26, 26, 26, 26, 26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 26, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 33, 1, 31, + 31, 31, 31, 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 27, 1, 27, 27, - 27, 27, 27, 1, 1, 1, 1, 1, + 1, 1, 32, 1, 1, 1, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 28, 1, 1, 29, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 1, - 31, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 1, 33, 33, 33, 33, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 33, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 34, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 33, 1, 34, 1, 35, + 1, 35, 35, 35, 35, 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 36, 1, 36, 36, 36, 36, + 36, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 35, - 1, 33, 33, 33, 33, 33, 1, 1, + 1, 1, 1, 36, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 37, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 1, 39, 39, + 39, 39, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 33, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 34, 1, 1, 1, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 35, 1, 36, - 1, 37, 1, 37, 37, 37, 37, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 41, 1, 39, 39, 39, 39, + 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 38, 1, 38, 38, - 38, 38, 38, 1, 1, 1, 1, 1, + 1, 1, 1, 39, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 40, + 1, 1, 1, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 38, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 39, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 1, - 41, 41, 41, 41, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 41, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 42, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 41, 1, 43, 44, 1, 45, 1, 45, + 45, 45, 45, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 46, 1, 46, 46, 46, 46, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 43, 1, 41, 41, - 41, 41, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 41, 1, 1, + 1, 46, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 47, 1, + 1, 48, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 1, 50, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 1, 52, + 52, 52, 52, 52, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 42, 1, 1, 1, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 1, + 1, 1, 1, 1, 1, 1, 52, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 53, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -247,43 +256,43 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 43, 1, 45, 46, 1, 47, - 1, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 47, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 54, 1, 52, 52, 52, + 52, 52, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 52, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 48, 1, 48, 48, 48, 48, - 48, 1, 1, 1, 1, 1, 1, 1, + 53, 1, 1, 1, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 48, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 49, 1, 1, 50, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 1, 52, 53, - 53, 53, 53, 53, 53, 53, 53, 53, - 1, 54, 54, 54, 54, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 54, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 55, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 54, 1, 55, 1, 55, 55, 55, + 55, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 56, 1, + 56, 56, 56, 56, 56, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 56, 1, 54, - 54, 54, 54, 54, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 56, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 54, 1, + 1, 1, 1, 1, 57, 1, 1, 58, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 1, 60, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 1, 62, 62, 62, + 62, 62, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 55, 1, 1, 1, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, + 1, 1, 1, 1, 62, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -291,42 +300,42 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 56, 1, 57, 1, 57, - 57, 57, 57, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 64, 1, 62, 62, 62, 62, 62, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 58, 1, 58, 58, 58, 58, 58, 1, + 1, 1, 62, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 63, 1, + 1, 1, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 58, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 59, 1, - 1, 60, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 1, 62, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 1, 64, - 64, 64, 64, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 64, + 1, 65, 1, 66, 1, 66, 66, 66, + 66, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 67, 1, + 67, 67, 67, 67, 67, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 67, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 68, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 1, 70, 70, 70, 70, 70, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 66, 1, 64, 64, 64, - 64, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 64, 1, 1, 1, + 1, 70, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 71, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 65, 1, 1, 1, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -335,41 +344,49 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 66, 1, 67, 1, 68, 1, 68, - 68, 68, 68, 68, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 72, 1, + 70, 70, 70, 70, 70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 68, 1, + 1, 1, 1, 1, 1, 1, 1, 70, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 71, 1, 1, 1, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 69, 1, 69, 69, 69, 69, 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 70, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 1, 72, 72, 72, 72, - 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 72, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 73, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 72, 1, 74, 1, + 74, 74, 74, 74, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 75, 1, 75, 75, 75, 75, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 75, 1, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 77, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 1, 80, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 81, + 79, 82, 82, 82, 82, 82, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 74, 1, 72, 72, 72, 72, 72, 1, + 82, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 83, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 72, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 73, 1, 1, - 1, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -377,33 +394,19 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 74, 1, - 76, 1, 76, 76, 76, 76, 76, 1, + 1, 1, 1, 1, 1, 84, 1, 79, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 77, 1, 77, 77, 77, - 77, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 77, 1, 78, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 79, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 1, 82, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 83, 81, 84, 84, 84, 84, 84, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 79, 1, 85, 85, 85, 85, 85, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 84, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 85, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 85, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 86, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -412,36 +415,43 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 86, - 1, 81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 87, + 1, 85, 85, 85, 85, 85, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 85, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 86, 1, 1, 1, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 81, 1, 87, 87, 87, - 87, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 88, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 87, 1, 89, + 1, 89, 89, 89, 89, 89, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 89, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 90, 1, 90, 90, 90, 90, + 90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 91, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 1, 85, 85, + 85, 85, 85, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 89, 1, 87, 87, 87, 87, 87, + 1, 1, 1, 1, 1, 85, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 86, 1, 1, 1, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 87, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 88, 1, - 1, 1, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -449,49 +459,39 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 89, - 1, 91, 1, 91, 91, 91, 91, 91, + 1, 1, 87, 1, 94, 94, 94, 94, + 94, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 94, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 91, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 92, 1, 92, 92, - 92, 92, 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 93, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 1, - 87, 87, 87, 87, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 87, + 1, 1, 1, 1, 1, 1, 95, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 88, 1, 1, 1, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 96, 1, + 95, 95, 95, 95, 95, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 95, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 89, 1, 96, 96, - 96, 96, 96, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 96, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 97, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 98, 1, 2, 2, 2, 2, - 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 96, 1, 23, 23, 23, 23, + 23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 1, 1, 1, 1, + 1, 1, 1, 23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -502,47 +502,47 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 1, - 1, 0 + 1, 1, 1, 1, 1, 1, 96, 1, + 0 }; static const char _deserialize_json_trans_targs[] = { - 1, 0, 2, 3, 3, 4, 5, 19, - 25, 38, 44, 52, 6, 13, 7, 8, - 9, 10, 12, 10, 12, 11, 3, 56, - 11, 56, 14, 15, 16, 17, 18, 17, - 18, 11, 3, 56, 20, 21, 22, 23, - 24, 11, 3, 56, 24, 26, 32, 27, - 28, 29, 30, 31, 30, 31, 11, 3, - 56, 33, 34, 35, 36, 37, 36, 37, - 11, 3, 56, 39, 40, 41, 42, 43, - 11, 3, 56, 43, 45, 46, 47, 50, - 51, 47, 48, 49, 11, 3, 56, 11, - 3, 56, 51, 53, 54, 50, 55, 55, - 56, 57, 58 + 1, 0, 2, 3, 18, 24, 37, 43, + 51, 4, 12, 5, 6, 7, 8, 11, + 8, 11, 9, 1, 10, 9, 10, 57, + 13, 14, 15, 16, 17, 16, 17, 9, + 1, 10, 19, 20, 21, 22, 23, 9, + 1, 10, 23, 25, 31, 26, 27, 28, + 29, 30, 29, 30, 9, 1, 10, 32, + 33, 34, 35, 36, 35, 36, 9, 1, + 10, 38, 39, 40, 41, 42, 9, 1, + 10, 42, 44, 45, 46, 49, 50, 46, + 47, 48, 9, 1, 10, 9, 1, 10, + 50, 52, 53, 49, 54, 54, 55, 56, + 1 }; static const char _deserialize_json_trans_actions[] = { - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 0, 0, 3, 3, 4, - 0, 5, 0, 0, 2, 2, 2, 0, - 0, 6, 6, 7, 0, 0, 0, 2, - 2, 8, 8, 9, 0, 0, 0, 0, - 0, 2, 2, 2, 0, 0, 10, 10, - 11, 0, 0, 2, 2, 2, 0, 0, - 12, 12, 13, 0, 0, 0, 2, 2, - 14, 14, 15, 0, 0, 0, 2, 16, - 16, 0, 17, 0, 18, 18, 19, 20, - 20, 21, 17, 0, 0, 22, 22, 23, - 0, 0, 0 + 0, 0, 0, 0, 0, 1, 1, 1, + 0, 0, 2, 2, 2, 0, 0, 3, + 0, 0, 1, 1, 1, 0, 0, 4, + 4, 4, 0, 0, 0, 1, 1, 5, + 5, 5, 0, 0, 0, 0, 0, 1, + 1, 1, 0, 0, 6, 6, 6, 0, + 0, 1, 1, 1, 0, 0, 7, 7, + 7, 0, 0, 0, 1, 1, 8, 8, + 8, 0, 0, 0, 1, 9, 9, 0, + 10, 0, 11, 11, 11, 12, 12, 12, + 10, 0, 0, 13, 13, 14, 0, 0, + 15 }; -static const int deserialize_json_start = 1; -static const int deserialize_json_first_final = 56; +static const int deserialize_json_start = 55; +static const int deserialize_json_first_final = 55; static const int deserialize_json_error = 0; -static const int deserialize_json_en_main = 1; +static const int deserialize_json_en_main = 55; #line 111 "hb-buffer-deserialize-json.rl" @@ -595,14 +595,14 @@ _resume: goto _again; switch ( _deserialize_json_trans_actions[_trans] ) { - case 1: + case 15: #line 38 "hb-buffer-deserialize-json.rl" { hb_memset (&info, 0, sizeof (info)); hb_memset (&pos , 0, sizeof (pos )); } break; - case 5: + case 3: #line 43 "hb-buffer-deserialize-json.rl" { buffer->add_info (info); @@ -612,21 +612,21 @@ _resume: *end_ptr = p; } break; - case 2: + case 1: #line 51 "hb-buffer-deserialize-json.rl" { tok = p; } break; - case 17: + case 10: #line 55 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_glyphs ())) return false; } break; - case 23: + case 14: #line 56 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_unicode ())) return false; } break; - case 18: + case 11: #line 58 "hb-buffer-deserialize-json.rl" { /* TODO Unescape \" and \\ if found. */ @@ -636,35 +636,35 @@ _resume: return false; } break; - case 20: + case 12: #line 66 "hb-buffer-deserialize-json.rl" { if (!parse_uint (tok, p, &info.codepoint)) return false; } break; - case 8: + case 5: #line 67 "hb-buffer-deserialize-json.rl" { if (!parse_uint (tok, p, &info.cluster )) return false; } break; - case 10: + case 6: #line 68 "hb-buffer-deserialize-json.rl" { if (!parse_int (tok, p, &pos.x_offset )) return false; } break; - case 12: + case 7: #line 69 "hb-buffer-deserialize-json.rl" { if (!parse_int (tok, p, &pos.y_offset )) return false; } break; - case 3: + case 2: #line 70 "hb-buffer-deserialize-json.rl" { if (!parse_int (tok, p, &pos.x_advance)) return false; } break; - case 6: + case 4: #line 71 "hb-buffer-deserialize-json.rl" { if (!parse_int (tok, p, &pos.y_advance)) return false; } break; - case 14: + case 8: #line 72 "hb-buffer-deserialize-json.rl" { if (!parse_uint (tok, p, &info.mask )) return false; } break; - case 16: + case 9: #line 51 "hb-buffer-deserialize-json.rl" { tok = p; @@ -672,7 +672,7 @@ _resume: #line 55 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_glyphs ())) return false; } break; - case 22: + case 13: #line 51 "hb-buffer-deserialize-json.rl" { tok = p; @@ -680,109 +680,7 @@ _resume: #line 56 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_unicode ())) return false; } break; - case 19: -#line 58 "hb-buffer-deserialize-json.rl" - { - /* TODO Unescape \" and \\ if found. */ - if (!hb_font_glyph_from_string (font, - tok+1, p - tok - 2, /* Skip "" */ - &info.codepoint)) - return false; -} -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 21: -#line 66 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.codepoint)) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 9: -#line 67 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 11: -#line 68 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_offset )) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 13: -#line 69 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 4: -#line 70 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 7: -#line 71 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 15: -#line 72 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.mask )) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; -#line 786 "hb-buffer-deserialize-json.hh" +#line 684 "hb-buffer-deserialize-json.hh" } _again: @@ -799,7 +697,7 @@ _again: *end_ptr = p; - return p == pe && *(p-1) != ']'; + return p == pe; } #endif /* HB_BUFFER_DESERIALIZE_JSON_HH */ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.rl b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.rl index 2f1ad9118c4435a7aee54bc9c07cdecba55b8324..eb092bfe924a7fb5163f7eee72bf44eea512c37e 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.rl +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.rl @@ -101,12 +101,12 @@ element = glyph @ensure_glyphs | yadvance | glyphflags; item = - ( '{' space* element (comma element)* space* '}') + ( '{' space* element (comma element)* space* '}' space* (','|']') space* ) >clear_item @add_item ; -main := space* '['? space* item (comma item)* space* (','|']')?; +main := space* '['? space* item*; }%% @@ -133,7 +133,7 @@ _hb_buffer_deserialize_json (hb_buffer_t *buffer, *end_ptr = p; - return p == pe && *(p-1) != ']'; + return p == pe; } #endif /* HB_BUFFER_DESERIALIZE_JSON_HH */ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-glyphs.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-glyphs.hh index ea81273b31ca3b086b2425df0046ff3b524893fd..fe70b4fc1d5b5aad3818223b88343c5a441e18cd 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-glyphs.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-glyphs.hh @@ -34,285 +34,247 @@ #line 36 "hb-buffer-deserialize-text-glyphs.hh" static const unsigned char _deserialize_text_glyphs_trans_keys[] = { - 0u, 0u, 48u, 57u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, - 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 43u, 124u, 9u, 124u, 9u, 124u, - 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, - 9u, 124u, 9u, 124u, 9u, 124u, 0 + 0u, 0u, 35u, 124u, 48u, 57u, 93u, 124u, 45u, 57u, 48u, 57u, 35u, 124u, 45u, 57u, + 48u, 57u, 35u, 124u, 35u, 124u, 35u, 124u, 48u, 57u, 35u, 124u, 45u, 57u, 48u, 57u, + 44u, 44u, 45u, 57u, 48u, 57u, 35u, 124u, 35u, 124u, 44u, 57u, 35u, 124u, 43u, 124u, + 48u, 124u, 35u, 124u, 35u, 124u, 35u, 124u, 0 }; static const char _deserialize_text_glyphs_key_spans[] = { - 0, 10, 13, 10, 13, 10, 10, 13, - 10, 1, 13, 10, 14, 82, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116 + 0, 90, 10, 32, 13, 10, 90, 13, + 10, 90, 90, 90, 10, 90, 13, 10, + 1, 13, 10, 90, 90, 14, 90, 82, + 77, 90, 90, 90 }; static const short _deserialize_text_glyphs_index_offsets[] = { - 0, 0, 11, 25, 36, 50, 61, 72, - 86, 97, 99, 113, 124, 139, 222, 339, - 456, 573, 690, 807, 924, 1041, 1158, 1275, - 1392, 1509, 1626 + 0, 0, 91, 102, 135, 149, 160, 251, + 265, 276, 367, 458, 549, 560, 651, 665, + 676, 678, 692, 703, 794, 885, 900, 991, + 1074, 1152, 1243, 1334 }; static const char _deserialize_text_glyphs_indicies[] = { - 0, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 1, 3, 1, 1, 4, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 1, 6, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 1, 8, 1, 1, - 9, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 1, 11, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 1, 13, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 1, 15, 1, 1, 16, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 1, 18, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 1, 20, 1, 21, 1, 1, 22, - 23, 23, 23, 23, 23, 23, 23, 23, - 23, 1, 24, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 1, 20, 1, 1, - 1, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 1, 26, 26, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 26, 1, - 1, 26, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 26, 26, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 26, 1, 28, - 28, 28, 28, 28, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 28, 27, - 27, 29, 27, 27, 27, 27, 27, 27, - 27, 30, 1, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 31, 27, 27, 32, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 33, 1, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, + 1, 0, 0, 0, 0, 0, 0, + 0, 2, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7, 0, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 3, 10, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 10, 3, + 11, 3, 3, 12, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 3, 14, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 3, 16, 3, 3, 3, 3, 3, 3, + 3, 3, 17, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 18, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 18, 3, 19, 3, 3, 20, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 3, 22, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 3, 24, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 25, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 25, 3, + 24, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 25, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 25, 3, 16, 3, 3, 3, 3, + 3, 3, 3, 3, 17, 3, 3, 3, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 18, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 18, 3, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 28, 27, 34, 34, 34, 34, - 34, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 34, 26, 26, 35, 26, - 26, 26, 26, 26, 26, 26, 36, 1, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 37, 26, 26, 38, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 39, - 1, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 40, - 26, 41, 41, 41, 41, 41, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 41, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 42, 1, 43, 43, - 43, 43, 43, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 43, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 44, 1, 41, 41, 41, 41, 41, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 41, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 42, 1, - 46, 46, 46, 46, 46, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 46, - 1, 1, 47, 1, 1, 1, 1, 1, - 1, 1, 1, 48, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 49, 1, 50, 50, 50, - 50, 50, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 50, 1, 1, 51, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 52, 1, 50, 50, 50, 50, 50, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 50, 1, 1, 51, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 52, 1, 46, - 46, 46, 46, 46, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 46, 1, - 1, 47, 1, 1, 1, 1, 1, 1, - 1, 1, 48, 1, 1, 1, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 49, 1, 53, 53, 53, 53, - 53, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 53, 1, 1, 54, 1, - 1, 1, 1, 1, 1, 1, 55, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 56, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 57, - 1, 58, 58, 58, 58, 58, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 58, 1, 1, 59, 1, 1, 1, 1, - 1, 1, 1, 60, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 61, 1, 58, 58, - 58, 58, 58, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 58, 1, 1, - 59, 1, 1, 1, 1, 1, 1, 1, - 60, 1, 1, 1, 1, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 61, 1, 53, 53, 53, 53, 53, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 53, 1, 1, 54, 1, 1, - 1, 1, 1, 1, 1, 55, 1, 1, - 1, 1, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 1, 1, 1, 1, - 1, 1, 56, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 57, 1, - 0 + 3, 28, 3, 3, 3, 3, 3, 3, + 3, 29, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 30, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 31, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 31, 3, 32, 3, 3, 33, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 3, 35, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 3, 37, 3, 38, + 3, 3, 39, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 3, 41, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 3, + 43, 3, 3, 3, 3, 3, 3, 3, + 44, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 45, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 45, 3, 43, 3, 3, 3, 3, + 3, 3, 3, 44, 3, 3, 3, 3, + 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 45, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 45, 3, 37, 3, + 3, 3, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 3, 28, 3, 3, + 3, 3, 3, 3, 3, 29, 3, 3, + 3, 3, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 3, 3, 3, 3, + 3, 3, 30, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 31, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 31, 3, + 0, 0, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 0, 3, 3, 0, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 0, 0, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 0, 3, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 10, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 10, + 3, 49, 48, 48, 48, 48, 48, 48, + 48, 50, 3, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 51, 48, 48, 52, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 53, 54, 55, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 55, 48, 57, 56, 56, 56, + 56, 56, 56, 56, 58, 3, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 59, 56, + 56, 60, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 61, 62, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 62, 56, 63, + 48, 48, 48, 48, 48, 48, 48, 64, + 3, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 65, 48, 48, 66, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 54, 67, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 67, 48, 0 }; static const char _deserialize_text_glyphs_trans_targs[] = { - 16, 0, 18, 3, 19, 22, 19, 22, - 5, 20, 21, 20, 21, 23, 26, 8, - 9, 12, 9, 12, 10, 11, 24, 25, - 24, 25, 15, 15, 14, 1, 2, 6, - 7, 13, 15, 1, 2, 6, 7, 13, - 14, 17, 14, 17, 14, 18, 17, 1, - 4, 14, 17, 1, 14, 17, 1, 2, - 7, 14, 17, 1, 2, 14, 26 + 1, 2, 4, 0, 12, 14, 23, 26, + 3, 24, 26, 5, 6, 11, 6, 11, + 2, 7, 26, 8, 9, 10, 9, 10, + 2, 26, 13, 22, 2, 4, 14, 26, + 15, 16, 21, 16, 21, 17, 18, 19, + 20, 19, 20, 2, 4, 26, 22, 24, + 1, 2, 4, 12, 14, 27, 23, 26, + 1, 2, 4, 12, 14, 23, 26, 2, + 4, 12, 14, 26 }; static const char _deserialize_text_glyphs_trans_actions[] = { - 1, 0, 1, 1, 1, 1, 0, 0, - 1, 1, 1, 0, 0, 1, 1, 1, - 1, 1, 0, 0, 2, 1, 1, 1, - 0, 0, 0, 4, 3, 5, 5, 5, - 5, 4, 6, 7, 7, 7, 7, 0, - 6, 8, 8, 0, 0, 0, 9, 10, - 10, 9, 11, 12, 11, 13, 14, 14, - 14, 13, 15, 16, 16, 15, 0 + 0, 1, 1, 0, 1, 1, 0, 1, + 2, 2, 3, 2, 2, 2, 0, 0, + 4, 4, 4, 2, 2, 2, 0, 0, + 5, 5, 2, 2, 6, 6, 6, 6, + 2, 2, 2, 0, 0, 7, 2, 2, + 2, 0, 0, 8, 8, 8, 0, 0, + 9, 10, 10, 10, 10, 9, 9, 10, + 12, 13, 13, 13, 13, 12, 13, 14, + 14, 14, 14, 14 }; static const char _deserialize_text_glyphs_eof_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3, 6, - 8, 0, 8, 9, 11, 11, 9, 13, - 15, 15, 13 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 11, 0 }; -static const int deserialize_text_glyphs_start = 14; -static const int deserialize_text_glyphs_first_final = 14; +static const int deserialize_text_glyphs_start = 25; +static const int deserialize_text_glyphs_first_final = 25; static const int deserialize_text_glyphs_error = 0; -static const int deserialize_text_glyphs_en_main = 14; +static const int deserialize_text_glyphs_en_main = 25; -#line 98 "hb-buffer-deserialize-text-glyphs.rl" +#line 99 "hb-buffer-deserialize-text-glyphs.rl" static hb_bool_t @@ -322,39 +284,22 @@ _hb_buffer_deserialize_text_glyphs (hb_buffer_t *buffer, const char **end_ptr, hb_font_t *font) { - const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe; + const char *p = buf, *pe = buf + buf_len, *eof = pe; /* Ensure we have positions. */ (void) hb_buffer_get_glyph_positions (buffer, nullptr); - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? '|' : '[')) - *end_ptr = ++p; - - const char *end = strchr ((char *) p, ']'); - if (end) - pe = eof = end; - else - { - end = strrchr ((char *) p, '|'); - if (end) - pe = eof = end; - else - pe = eof = p; - } - const char *tok = nullptr; int cs; hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; -#line 353 "hb-buffer-deserialize-text-glyphs.hh" +#line 298 "hb-buffer-deserialize-text-glyphs.hh" { cs = deserialize_text_glyphs_start; } -#line 358 "hb-buffer-deserialize-text-glyphs.hh" +#line 303 "hb-buffer-deserialize-text-glyphs.hh" { int _slen; int _trans; @@ -379,13 +324,13 @@ _resume: goto _again; switch ( _deserialize_text_glyphs_trans_actions[_trans] ) { - case 1: + case 2: #line 51 "hb-buffer-deserialize-text-glyphs.rl" { tok = p; } break; - case 7: + case 1: #line 55 "hb-buffer-deserialize-text-glyphs.rl" { /* TODO Unescape delimiters. */ @@ -395,27 +340,31 @@ _resume: return false; } break; - case 14: + case 6: #line 63 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_uint (tok, p, &info.cluster )) return false; } break; - case 2: + case 7: #line 64 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_int (tok, p, &pos.x_offset )) return false; } break; - case 16: + case 8: #line 65 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_int (tok, p, &pos.y_offset )) return false; } break; - case 10: + case 4: #line 66 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_int (tok, p, &pos.x_advance)) return false; } break; - case 12: + case 5: #line 67 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_int (tok, p, &pos.y_advance)) return false; } break; - case 4: + case 3: +#line 68 "hb-buffer-deserialize-text-glyphs.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } + break; + case 9: #line 38 "hb-buffer-deserialize-text-glyphs.rl" { hb_memset (&info, 0, sizeof (info)); @@ -426,7 +375,16 @@ _resume: tok = p; } break; - case 6: + case 10: +#line 38 "hb-buffer-deserialize-text-glyphs.rl" + { + hb_memset (&info, 0, sizeof (info)); + hb_memset (&pos , 0, sizeof (pos )); +} +#line 51 "hb-buffer-deserialize-text-glyphs.rl" + { + tok = p; +} #line 55 "hb-buffer-deserialize-text-glyphs.rl" { /* TODO Unescape delimiters. */ @@ -434,67 +392,9 @@ _resume: tok, p - tok, &info.codepoint)) return false; -} -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 13: -#line 63 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 15: -#line 65 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 9: -#line 66 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 11: -#line 67 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; } break; - case 8: -#line 68 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_uint (tok, p, &info.mask )) return false; } + case 12: #line 43 "hb-buffer-deserialize-text-glyphs.rl" { buffer->add_info (info); @@ -503,8 +403,6 @@ _resume: buffer->pos[buffer->len - 1] = pos; *end_ptr = p; } - break; - case 5: #line 38 "hb-buffer-deserialize-text-glyphs.rl" { hb_memset (&info, 0, sizeof (info)); @@ -514,6 +412,8 @@ _resume: { tok = p; } + break; + case 14: #line 55 "hb-buffer-deserialize-text-glyphs.rl" { /* TODO Unescape delimiters. */ @@ -522,8 +422,6 @@ _resume: &info.codepoint)) return false; } - break; - case 3: #line 38 "hb-buffer-deserialize-text-glyphs.rl" { hb_memset (&info, 0, sizeof (info)); @@ -532,57 +430,9 @@ _resume: #line 51 "hb-buffer-deserialize-text-glyphs.rl" { tok = p; -} -#line 55 "hb-buffer-deserialize-text-glyphs.rl" - { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; -#line 554 "hb-buffer-deserialize-text-glyphs.hh" - } - -_again: - if ( cs == 0 ) - goto _out; - if ( ++p != pe ) - goto _resume; - _test_eof: {} - if ( p == eof ) - { - switch ( _deserialize_text_glyphs_eof_actions[cs] ) { - case 6: -#line 55 "hb-buffer-deserialize-text-glyphs.rl" - { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; } break; case 13: -#line 63 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } #line 43 "hb-buffer-deserialize-text-glyphs.rl" { buffer->add_info (info); @@ -591,56 +441,6 @@ _again: buffer->pos[buffer->len - 1] = pos; *end_ptr = p; } - break; - case 15: -#line 65 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 9: -#line 66 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 11: -#line 67 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 8: -#line 68 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_uint (tok, p, &info.mask )) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 3: #line 38 "hb-buffer-deserialize-text-glyphs.rl" { hb_memset (&info, 0, sizeof (info)); @@ -658,6 +458,20 @@ _again: &info.codepoint)) return false; } + break; +#line 463 "hb-buffer-deserialize-text-glyphs.hh" + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + switch ( _deserialize_text_glyphs_eof_actions[cs] ) { + case 11: #line 43 "hb-buffer-deserialize-text-glyphs.rl" { buffer->add_info (info); @@ -667,22 +481,15 @@ _again: *end_ptr = p; } break; -#line 671 "hb-buffer-deserialize-text-glyphs.hh" +#line 485 "hb-buffer-deserialize-text-glyphs.hh" } } _out: {} } -#line 136 "hb-buffer-deserialize-text-glyphs.rl" - +#line 120 "hb-buffer-deserialize-text-glyphs.rl" - if (pe < orig_pe && *pe == ']') - { - pe++; - if (p == pe) - p++; - } *end_ptr = p; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-glyphs.rl b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-glyphs.rl index 21db14b568bbfd930d6218eb9599e21f5c2c3f60..8efedb8d36862a297686def3aec177b810a5ff88 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-glyphs.rl +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-glyphs.rl @@ -86,14 +86,15 @@ glyph_item = offsets? advances? glyphflags? + ( '|' | ']') ) >clear_item %add_item ; -glyphs = glyph_item (space* '|' space* glyph_item)* space*; +glyphs = '['? glyph_item* ; -main := space* glyphs; +main := glyphs; }%% @@ -104,28 +105,11 @@ _hb_buffer_deserialize_text_glyphs (hb_buffer_t *buffer, const char **end_ptr, hb_font_t *font) { - const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe; + const char *p = buf, *pe = buf + buf_len, *eof = pe; /* Ensure we have positions. */ (void) hb_buffer_get_glyph_positions (buffer, nullptr); - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? '|' : '[')) - *end_ptr = ++p; - - const char *end = strchr ((char *) p, ']'); - if (end) - pe = eof = end; - else - { - end = strrchr ((char *) p, '|'); - if (end) - pe = eof = end; - else - pe = eof = p; - } - const char *tok = nullptr; int cs; hb_glyph_info_t info = {0}; @@ -135,13 +119,6 @@ _hb_buffer_deserialize_text_glyphs (hb_buffer_t *buffer, write exec; }%% - if (pe < orig_pe && *pe == ']') - { - pe++; - if (p == pe) - p++; - } - *end_ptr = p; return p == pe; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-unicode.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-unicode.hh index a8cdf67e73e22a3a159644cd11e124972a76e0b7..26ec0b42257c91ddb8fa9778bdf32f296b23a301 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-unicode.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-unicode.hh @@ -34,135 +34,106 @@ #line 36 "hb-buffer-deserialize-text-unicode.hh" static const unsigned char _deserialize_text_unicode_trans_keys[] = { - 0u, 0u, 9u, 117u, 43u, 102u, 48u, 102u, 48u, 57u, 9u, 124u, 9u, 124u, 9u, 124u, - 9u, 124u, 0 + 0u, 0u, 43u, 102u, 48u, 102u, 48u, 124u, 48u, 57u, 62u, 124u, 48u, 124u, 60u, 117u, + 85u, 117u, 85u, 117u, 0 }; static const char _deserialize_text_unicode_key_spans[] = { - 0, 109, 60, 55, 10, 116, 116, 116, - 116 + 0, 60, 55, 77, 10, 63, 77, 58, + 33, 33 }; static const short _deserialize_text_unicode_index_offsets[] = { - 0, 0, 110, 171, 227, 238, 355, 472, - 589 + 0, 0, 61, 117, 195, 206, 270, 348, + 407, 441 }; static const char _deserialize_text_unicode_indicies[] = { - 0, 0, 0, 0, 0, 1, 1, + 0, 1, 1, 1, 1, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 1, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 1, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 1, 1, 1, 4, 5, 1, 1, 3, + 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, + 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 5, 1, 6, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 1, 3, - 1, 1, 1, 1, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 1, 1, - 1, 1, 1, 1, 1, 4, 4, 4, - 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 4, 4, 4, - 4, 4, 4, 1, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 1, 1, - 1, 1, 1, 1, 1, 4, 4, 4, - 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 4, 4, 4, - 4, 4, 4, 1, 5, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 1, 7, - 7, 7, 7, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 7, 1, + 1, 1, 1, 1, 1, 8, 1, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 1, 1, 1, 9, 1, 1, 1, 8, - 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 8, - 8, 8, 8, 8, 8, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 10, 1, 11, 11, 11, 11, - 11, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 11, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, - 1, 12, 12, 12, 12, 12, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 12, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 8, 1, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 13, 1, 12, 12, - 12, 12, 12, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 12, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 11, 1, + 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 11, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 13, 1, 0 + 1, 1, 12, 1, 0 }; static const char _deserialize_text_unicode_trans_targs[] = { - 1, 0, 2, 3, 5, 7, 8, 6, - 5, 4, 1, 6, 6, 1, 8 + 2, 0, 3, 3, 4, 9, 5, 6, + 9, 6, 8, 1, 1 }; static const char _deserialize_text_unicode_trans_actions[] = { - 0, 0, 1, 0, 2, 2, 2, 3, - 0, 4, 3, 0, 5, 5, 0 + 0, 0, 1, 0, 2, 2, 1, 1, + 3, 0, 0, 4, 6 }; static const char _deserialize_text_unicode_eof_actions[] = { - 0, 0, 0, 0, 0, 3, 0, 5, - 5 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5 }; -static const int deserialize_text_unicode_start = 1; -static const int deserialize_text_unicode_first_final = 5; +static const int deserialize_text_unicode_start = 7; +static const int deserialize_text_unicode_first_final = 7; static const int deserialize_text_unicode_error = 0; -static const int deserialize_text_unicode_en_main = 1; +static const int deserialize_text_unicode_en_main = 7; -#line 79 "hb-buffer-deserialize-text-unicode.rl" +#line 80 "hb-buffer-deserialize-text-unicode.rl" static hb_bool_t @@ -172,37 +143,19 @@ _hb_buffer_deserialize_text_unicode (hb_buffer_t *buffer, const char **end_ptr, hb_font_t *font) { - const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe; - - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? '|' : '<')) - *end_ptr = ++p; - - const char *end = strchr ((char *) p, '>'); - if (end) - pe = eof = end; - else - { - end = strrchr ((char *) p, '|'); - if (end) - pe = eof = end; - else - pe = eof = p; - } - + const char *p = buf, *pe = buf + buf_len, *eof = pe; const char *tok = nullptr; int cs; hb_glyph_info_t info = {0}; const hb_glyph_position_t pos = {0}; -#line 201 "hb-buffer-deserialize-text-unicode.hh" +#line 154 "hb-buffer-deserialize-text-unicode.hh" { cs = deserialize_text_unicode_start; } -#line 206 "hb-buffer-deserialize-text-unicode.hh" +#line 159 "hb-buffer-deserialize-text-unicode.hh" { int _slen; int _trans; @@ -227,38 +180,27 @@ _resume: goto _again; switch ( _deserialize_text_unicode_trans_actions[_trans] ) { - case 1: + case 4: #line 38 "hb-buffer-deserialize-text-unicode.rl" { hb_memset (&info, 0, sizeof (info)); } break; - case 2: + case 1: #line 51 "hb-buffer-deserialize-text-unicode.rl" { tok = p; } break; - case 4: + case 2: #line 55 "hb-buffer-deserialize-text-unicode.rl" {if (!parse_hex (tok, p, &info.codepoint )) return false; } break; case 3: -#line 55 "hb-buffer-deserialize-text-unicode.rl" - {if (!parse_hex (tok, p, &info.codepoint )) return false; } -#line 42 "hb-buffer-deserialize-text-unicode.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - if (buffer->have_positions) - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 5: #line 57 "hb-buffer-deserialize-text-unicode.rl" { if (!parse_uint (tok, p, &info.cluster )) return false; } + break; + case 6: #line 42 "hb-buffer-deserialize-text-unicode.rl" { buffer->add_info (info); @@ -267,9 +209,13 @@ _resume: if (buffer->have_positions) buffer->pos[buffer->len - 1] = pos; *end_ptr = p; +} +#line 38 "hb-buffer-deserialize-text-unicode.rl" + { + hb_memset (&info, 0, sizeof (info)); } break; -#line 273 "hb-buffer-deserialize-text-unicode.hh" +#line 219 "hb-buffer-deserialize-text-unicode.hh" } _again: @@ -281,22 +227,7 @@ _again: if ( p == eof ) { switch ( _deserialize_text_unicode_eof_actions[cs] ) { - case 3: -#line 55 "hb-buffer-deserialize-text-unicode.rl" - {if (!parse_hex (tok, p, &info.codepoint )) return false; } -#line 42 "hb-buffer-deserialize-text-unicode.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - if (buffer->have_positions) - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; case 5: -#line 57 "hb-buffer-deserialize-text-unicode.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } #line 42 "hb-buffer-deserialize-text-unicode.rl" { buffer->add_info (info); @@ -307,22 +238,15 @@ _again: *end_ptr = p; } break; -#line 311 "hb-buffer-deserialize-text-unicode.hh" +#line 242 "hb-buffer-deserialize-text-unicode.hh" } } _out: {} } -#line 115 "hb-buffer-deserialize-text-unicode.rl" - +#line 98 "hb-buffer-deserialize-text-unicode.rl" - if (pe < orig_pe && *pe == '>') - { - pe++; - if (p == pe) - p++; - } *end_ptr = p; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-unicode.rl b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-unicode.rl index 92873b804f3b18f663fb71df50c6d3c36e925153..1e123c8b216efb81e0c5ca1f33cff28f84c5a738 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-unicode.rl +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-unicode.rl @@ -67,14 +67,15 @@ unicode_item = ( unicode cluster? + ('|' | '>') ) >clear_item %add_item ; -unicodes = unicode_item (space* '|' space* unicode_item)* space*; +unicodes = '<'? unicode_item*; -main := space* unicodes; +main := unicodes; }%% @@ -85,25 +86,7 @@ _hb_buffer_deserialize_text_unicode (hb_buffer_t *buffer, const char **end_ptr, hb_font_t *font) { - const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe; - - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? '|' : '<')) - *end_ptr = ++p; - - const char *end = strchr ((char *) p, '>'); - if (end) - pe = eof = end; - else - { - end = strrchr ((char *) p, '|'); - if (end) - pe = eof = end; - else - pe = eof = p; - } - + const char *p = buf, *pe = buf + buf_len, *eof = pe; const char *tok = nullptr; int cs; @@ -114,13 +97,6 @@ _hb_buffer_deserialize_text_unicode (hb_buffer_t *buffer, write exec; }%% - if (pe < orig_pe && *pe == '>') - { - pe++; - if (p == pe) - p++; - } - *end_ptr = p; return p == pe; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc index 16f189519b199c817ef9afe64aafb222edc28da2..b71aa72199631043cbe92c0340afabe777be409d 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc @@ -169,11 +169,13 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) { hb_glyph_extents_t extents; - hb_font_get_glyph_extents(font, info[i].codepoint, &extents); - p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d", - extents.x_bearing, extents.y_bearing)); - p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d", - extents.width, extents.height)); + if (hb_font_get_glyph_extents(font, info[i].codepoint, &extents)) + { + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d", + extents.x_bearing, extents.y_bearing)); + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d", + extents.width, extents.height)); + } } *p++ = '}'; @@ -318,8 +320,8 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) { hb_glyph_extents_t extents; - hb_font_get_glyph_extents(font, info[i].codepoint, &extents); - p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height)); + if (hb_font_get_glyph_extents(font, info[i].codepoint, &extents)) + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height)); } if (i == end-1) { @@ -737,8 +739,7 @@ parse_hex (const char *pp, const char *end, uint32_t *pv) * Deserializes glyphs @buffer from textual representation in the format * produced by hb_buffer_serialize_glyphs(). * - * Return value: `true` if parse was successful, `false` if an error - * occurred. + * Return value: `true` if the full string was parsed, `false` otherwise. * * Since: 0.9.7 **/ @@ -810,8 +811,7 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, * Deserializes Unicode @buffer from textual representation in the format * produced by hb_buffer_serialize_unicode(). * - * Return value: `true` if parse was successful, `false` if an error - * occurred. + * Return value: `true` if the full string was parsed, `false` otherwise. * * Since: 2.7.3 **/ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc index 345f08d260f7fb893fe96ff4af39e38300d06a9f..76f821637af1ece3dc2a3985ce9f9ae4a7387a51 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc @@ -63,23 +63,24 @@ static bool buffer_verify_monotone (hb_buffer_t *buffer, hb_font_t *font) { - /* Check that clusters are monotone. */ - if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES || - buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) + if (!HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE (buffer->cluster_level)) { - bool is_forward = HB_DIRECTION_IS_FORWARD (hb_buffer_get_direction (buffer)); + /* Cannot perform this check without monotone clusters. */ + return true; + } - unsigned int num_glyphs; - hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &num_glyphs); + bool is_forward = HB_DIRECTION_IS_FORWARD (hb_buffer_get_direction (buffer)); - for (unsigned int i = 1; i < num_glyphs; i++) - if (info[i-1].cluster != info[i].cluster && - (info[i-1].cluster < info[i].cluster) != is_forward) - { - buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "clusters are not monotone."); - return false; - } - } + unsigned int num_glyphs; + hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &num_glyphs); + + for (unsigned int i = 1; i < num_glyphs; i++) + if (info[i-1].cluster != info[i].cluster && + (info[i-1].cluster < info[i].cluster) != is_forward) + { + buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "clusters are not monotone."); + return false; + } return true; } @@ -92,8 +93,7 @@ buffer_verify_unsafe_to_break (hb_buffer_t *buffer, unsigned int num_features, const char * const *shapers) { - if (buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES && - buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) + if (!HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE (buffer->cluster_level)) { /* Cannot perform this check without monotone clusters. */ return true; @@ -207,8 +207,7 @@ buffer_verify_unsafe_to_concat (hb_buffer_t *buffer, unsigned int num_features, const char * const *shapers) { - if (buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES && - buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) + if (!HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE (buffer->cluster_level)) { /* Cannot perform this check without monotone clusters. */ return true; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc index d0c40664a66820fde9bad621b761463a0568aa3b..7fb95fe7e190d74e5f98ecb0d0ab81e06aa2e50c 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc @@ -518,7 +518,7 @@ void hb_buffer_t::merge_clusters_impl (unsigned int start, unsigned int end) { - if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) + if (!HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE (cluster_level)) { unsafe_to_break (start, end); return; @@ -551,7 +551,7 @@ void hb_buffer_t::merge_out_clusters (unsigned int start, unsigned int end) { - if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) + if (!HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE (cluster_level)) return; if (unlikely (end - start < 2)) diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h index dd0edb9b7d799207ce9c66bbe666b2f6242eca03..705b767b66aa47b9e1acfe21eb954d7db09874f2 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h @@ -422,18 +422,34 @@ hb_buffer_get_flags (const hb_buffer_t *buffer); * @HB_BUFFER_CLUSTER_LEVEL_CHARACTERS: Don't group cluster values. * @HB_BUFFER_CLUSTER_LEVEL_DEFAULT: Default cluster level, * equal to @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES. - * + * @HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES: Only group clusters, but don't enforce monotone order. + * * Data type for holding HarfBuzz's clustering behavior options. The cluster level - * dictates one aspect of how HarfBuzz will treat non-base characters + * dictates one aspect of how HarfBuzz will treat non-base characters * during shaping. * * In @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES, non-base * characters are merged into the cluster of the base character that precedes them. + * There is also cluster merging every time the clusters will otherwise become non-monotone. * * In @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS, non-base characters are initially * assigned their own cluster values, which are not merged into preceding base * clusters. This allows HarfBuzz to perform additional operations like reorder - * sequences of adjacent marks. + * sequences of adjacent marks. The output is still monotone, but the cluster + * values are more granular. + * + * In @HB_BUFFER_CLUSTER_LEVEL_CHARACTERS, non-base characters are assigned their + * own cluster values, which are not merged into preceding base clusters. Moreover, + * the cluster values are not merged into monotone order. This is the most granular + * cluster level, and it is useful for clients that need to know the exact cluster + * values of each character, but is harder to use for clients, since clusters + * might appear in any order. + * + * In @HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES, non-base characters are merged into the + * cluster of the base character that precedes them. This is similar to the Unicode + * Grapheme Cluster algorithm, but it is not exactly the same. The output is + * not forced to be monotone. This is useful for clients that want to use HarfBuzz + * as a cheap implementation of the Unicode Grapheme Cluster algorithm. * * @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES is the default, because it maintains * backward compatibility with older versions of HarfBuzz. New client programs that @@ -446,9 +462,52 @@ typedef enum { HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES = 0, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS = 1, HB_BUFFER_CLUSTER_LEVEL_CHARACTERS = 2, + HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES = 3, HB_BUFFER_CLUSTER_LEVEL_DEFAULT = HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES } hb_buffer_cluster_level_t; +/** + * HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE: + * @level: #hb_buffer_cluster_level_t to test + * + * Tests whether a cluster level groups cluster values into monotone order. + * Requires that the level be valid. + * + * Since: 11.0.0 + */ +#define HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE(level) \ + ((bool) ((1u << (unsigned) (level)) & \ + ((1u << HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) | \ + (1u << HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS)))) + +/** + * HB_BUFFER_CLUSTER_LEVEL_IS_GRAPHEMES: + * @level: #hb_buffer_cluster_level_t to test + * + * Tests whether a cluster level groups cluster values by graphemes. Requires + * that the level be valid. + * + * Since: 11.0.0 + */ +#define HB_BUFFER_CLUSTER_LEVEL_IS_GRAPHEMES(level) \ + ((bool) ((1u << (unsigned) (level)) & \ + ((1u << HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) | \ + (1u << HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES)))) + +/** + * HB_BUFFER_CLUSTER_LEVEL_IS_CHARACTERS + * @level: #hb_buffer_cluster_level_t to test + * + * Tests whether a cluster level does not group cluster values by graphemes. + * Requires that the level be valid. + * + * Since: 11.0.0 + */ +#define HB_BUFFER_CLUSTER_LEVEL_IS_CHARACTERS(level) \ + ((bool) ((1u << (unsigned) (level)) & \ + ((1u << HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARCATERS) | \ + (1u << HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)))) + HB_EXTERN void hb_buffer_set_cluster_level (hb_buffer_t *buffer, hb_buffer_cluster_level_t cluster_level); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh index 6d8a54cf102f345834891636a024ea20d5e0aac0..882a71a9daf00f99d592c1f1bb7d0011e4a82bd3 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh @@ -52,11 +52,11 @@ struct hb_cache_t { using item_t = typename std::conditional<thread_safe, typename std::conditional<key_bits + value_bits - cache_bits <= 16, - hb_atomic_short_t, - hb_atomic_int_t>::type, + hb_atomic_t<unsigned short>, + hb_atomic_t<unsigned int>>::type, typename std::conditional<key_bits + value_bits - cache_bits <= 16, - short, - int>::type + unsigned short, + unsigned int>::type >::type; static_assert ((key_bits >= cache_bits), ""); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo-utils.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo-utils.cc index ec1499e861e2bd0f9a85f8e360ab0cc60b9e5373..85c62d39a9598f91543a7493389ab81dcbc0f9a3 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo-utils.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo-utils.cc @@ -726,6 +726,9 @@ _hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops, float span; span = angles[n_stops - 1] - angles[0]; + if (!span) + goto done; + k = 0; if (angles[0] >= 0) { diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh index 06fbb72c61e16f7aa0bb65f50557eb1cd2525b8b..790aae345abd562f2eb49579ded7273e405f7c5b 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh @@ -71,7 +71,8 @@ struct cff2_cs_interp_env_t : cs_interp_env_t<ELEM, CFF2Subrs> template <typename ACC> cff2_cs_interp_env_t (const hb_ubytes_t &str, ACC &acc, unsigned int fd, const int *coords_=nullptr, unsigned int num_coords_=0) - : SUPER (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs) + : SUPER (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs), + cached_scalars_vector (&acc.cached_scalars_vector) { coords = coords_; num_coords = num_coords_; @@ -80,9 +81,39 @@ struct cff2_cs_interp_env_t : cs_interp_env_t<ELEM, CFF2Subrs> set_ivs (acc.privateDicts[fd].ivs); } - void fini () + ~cff2_cs_interp_env_t () { - SUPER::fini (); + release_scalars_vector (scalars); + } + + hb_vector_t<float> *acquire_scalars_vector () const + { + hb_vector_t<float> *scalars = cached_scalars_vector->get_acquire (); + + if (!scalars || !cached_scalars_vector->cmpexch (scalars, nullptr)) + { + scalars = (hb_vector_t<float> *) hb_calloc (1, sizeof (hb_vector_t<float>)); + if (unlikely (!scalars)) + return nullptr; + scalars->init (); + } + + return scalars; + } + + void release_scalars_vector (hb_vector_t<float> *scalars) const + { + if (!scalars) + return; + + scalars->clear (); + + if (!cached_scalars_vector->cmpexch (nullptr, scalars)) + { + scalars->fini (); + hb_free (scalars); + } + scalars = nullptr; } op_code_t fetch_op () @@ -111,14 +142,20 @@ struct cff2_cs_interp_env_t : cs_interp_env_t<ELEM, CFF2Subrs> { if (!seen_blend) { - region_count = varStore->varStore.get_region_index_count (get_ivs ()); - if (do_blend) + scalars = acquire_scalars_vector (); + if (unlikely (!scalars)) + SUPER::set_error (); + else { - if (unlikely (!scalars.resize_exact (region_count))) - SUPER::set_error (); - else - varStore->varStore.get_region_scalars (get_ivs (), coords, num_coords, - &scalars[0], region_count); + region_count = varStore->varStore.get_region_index_count (get_ivs ()); + if (do_blend) + { + if (unlikely (!scalars->resize_exact (region_count))) + SUPER::set_error (); + else + varStore->varStore.get_region_scalars (get_ivs (), coords, num_coords, + &(*scalars)[0], region_count); + } } seen_blend = true; } @@ -149,11 +186,11 @@ struct cff2_cs_interp_env_t : cs_interp_env_t<ELEM, CFF2Subrs> double v = 0; if (do_blend) { - if (likely (scalars.length == deltas.length)) + if (likely (scalars && scalars->length == deltas.length)) { - unsigned count = scalars.length; + unsigned count = scalars->length; for (unsigned i = 0; i < count; i++) - v += (double) scalars.arrayZ[i] * deltas.arrayZ[i].to_real (); + v += (double) scalars->arrayZ[i] * deltas.arrayZ[i].to_real (); } } return v; @@ -167,7 +204,8 @@ struct cff2_cs_interp_env_t : cs_interp_env_t<ELEM, CFF2Subrs> const CFF2ItemVariationStore *varStore; unsigned int region_count; unsigned int ivs; - hb_vector_t<float> scalars; + hb_vector_t<float> *scalars = nullptr; + hb_atomic_t<hb_vector_t<float> *> *cached_scalars_vector = nullptr; bool do_blend; bool seen_vsindex_ = false; bool seen_blend = false; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc index 5d77433b3fec63675c5570059a64e888cbdbc9e0..16fd883d2099ac43613e00b7d814a78c11381fc1 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc @@ -42,7 +42,7 @@ /* hb_options_t */ -hb_atomic_int_t _hb_options; +hb_atomic_t<unsigned> _hb_options; void _hb_options_init () @@ -273,7 +273,7 @@ struct hb_language_item_t { /* Thread-safe lockfree language list */ -static hb_atomic_ptr_t <hb_language_item_t> langs; +static hb_atomic_t<hb_language_item_t *> langs; static inline void free_langs () @@ -403,7 +403,7 @@ hb_language_to_string (hb_language_t language) hb_language_t hb_language_get_default () { - static hb_atomic_ptr_t <hb_language_t> default_language; + static hb_atomic_t<hb_language_t> default_language; hb_language_t language = default_language; if (unlikely (language == HB_LANGUAGE_INVALID)) @@ -968,6 +968,9 @@ hb_feature_from_string (const char *str, int len, * understood by hb_feature_from_string(). The client in responsible for * allocating big enough size for @buf, 128 bytes is more than enough. * + * Note that the feature value will be omitted if it is '1', but the + * string won't include any whitespace. + * * Since: 0.9.5 **/ void @@ -1121,6 +1124,8 @@ get_C_locale () * understood by hb_variation_from_string(). The client in responsible for * allocating big enough size for @buf, 128 bytes is more than enough. * + * Note that the string won't include any whitespace. + * * Since: 1.4.2 */ void @@ -1212,6 +1217,58 @@ uint8_t return hb_color_get_blue (color); } +/** + * hb_malloc: + * @size: The size of the memory to allocate. + * + * Allocates @size bytes of memory, using the allocator set at + * compile-time. Typically just malloc(). + * + * Return value: A pointer to the allocated memory. + * + * Since: 11.0.0 + **/ +void* hb_malloc(size_t size) { return hb_malloc_impl (size); } + +/** + * hb_calloc: + * @nmemb: The number of elements to allocate. + * @size: The size of each element. + * + * Allocates @nmemb elements of @size bytes each, initialized to zero, + * using the allocator set at compile-time. Typically just calloc(). + * + * Return value: A pointer to the allocated memory. + * + * Since: 11.0.0 + **/ +void* hb_calloc(size_t nmemb, size_t size) { return hb_calloc_impl (nmemb, size); } + +/** + * hb_realloc: + * @ptr: The pointer to the memory to reallocate. + * @size: The new size of the memory. + * + * Reallocates the memory pointed to by @ptr to @size bytes, using the + * allocator set at compile-time. Typically just realloc(). + * + * Return value: A pointer to the reallocated memory. + * + * Since: 11.0.0 + **/ +void* hb_realloc(void *ptr, size_t size) { return hb_realloc_impl (ptr, size); } + +/** + * hb_free: + * @ptr: The pointer to the memory to free. + * + * Frees the memory pointed to by @ptr, using the allocator set at + * compile-time. Typically just free(). + * + * Since: 11.0.0 + **/ +void hb_free(void *ptr) { hb_free_impl (ptr); } + /* If there is no visibility control, then hb-static.cc will NOT * define anything. Instead, we get it to define one set in here diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h b/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h index 1108545481652cc5876cbf740cbb870dd8e7e619..1d7b824b6103c6a202e36d84da7733c497f99a59 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h @@ -65,6 +65,7 @@ typedef unsigned __int64 uint64_t; #else # include <inttypes.h> #endif +#include <stddef.h> #if defined(__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) #define HB_DEPRECATED __attribute__((__deprecated__)) @@ -948,6 +949,16 @@ typedef struct hb_glyph_extents_t { */ typedef struct hb_font_t hb_font_t; +/* Not of much use to clients. */ +HB_EXTERN void* +hb_malloc (size_t size); +HB_EXTERN void* +hb_calloc (size_t nmemb, size_t size); +HB_EXTERN void* +hb_realloc (void *ptr, size_t size); +HB_EXTERN void +hb_free (void *ptr); + HB_END_DECLS #endif /* HB_COMMON_H */ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-font.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-font.cc index b9726373d5037fd732964eebe0fd18a100b225cb..76c1fa02d3c1a2ac21147c085f128e2440734c8a 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-font.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-font.cc @@ -28,7 +28,7 @@ #ifdef HAVE_CORETEXT -#include "hb-coretext.h" +#include "hb-coretext.hh" #include "hb-draw.hh" #include "hb-font.hh" @@ -42,24 +42,17 @@ # define kCTFontOrientationVertical kCTFontVerticalOrientation #endif -#define MAX_GLYPHS 64u - -static void -_hb_coretext_font_destroy (void *font_data) -{ - CTFontRef ct_font = (CTFontRef) font_data; - - CFRelease (ct_font); -} +#define MAX_GLYPHS 256u static hb_bool_t -hb_coretext_get_nominal_glyph (hb_font_t *font HB_UNUSED, - void *font_data, +hb_coretext_get_nominal_glyph (hb_font_t *font, + void *font_data HB_UNUSED, hb_codepoint_t unicode, hb_codepoint_t *glyph, void *user_data HB_UNUSED) { - CTFontRef ct_font = (CTFontRef) font_data; + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; + UniChar ch[2]; CGGlyph cg_glyph[2]; unsigned count = 0; @@ -85,7 +78,7 @@ hb_coretext_get_nominal_glyph (hb_font_t *font HB_UNUSED, } static unsigned int -hb_coretext_get_nominal_glyphs (hb_font_t *font HB_UNUSED, +hb_coretext_get_nominal_glyphs (hb_font_t *font, void *font_data, unsigned int count, const hb_codepoint_t *first_unicode, @@ -94,6 +87,8 @@ hb_coretext_get_nominal_glyphs (hb_font_t *font HB_UNUSED, unsigned int glyph_stride, void *user_data HB_UNUSED) { + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; + // If any non-BMP codepoint is requested, use the slow path. bool slow_path = false; auto *unicode = first_unicode; @@ -119,8 +114,6 @@ hb_coretext_get_nominal_glyphs (hb_font_t *font HB_UNUSED, return count; } - CTFontRef ct_font = (CTFontRef) font_data; - UniChar ch[MAX_GLYPHS]; CGGlyph cg_glyph[MAX_GLYPHS]; for (unsigned i = 0; i < count; i += MAX_GLYPHS) @@ -152,14 +145,14 @@ hb_coretext_get_nominal_glyphs (hb_font_t *font HB_UNUSED, } static hb_bool_t -hb_coretext_get_variation_glyph (hb_font_t *font HB_UNUSED, - void *font_data, +hb_coretext_get_variation_glyph (hb_font_t *font, + void *font_data HB_UNUSED, hb_codepoint_t unicode, hb_codepoint_t variation_selector, hb_codepoint_t *glyph, void *user_data HB_UNUSED) { - CTFontRef ct_font = (CTFontRef) font_data; + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; UniChar ch[4]; CGGlyph cg_glyph[4]; @@ -194,12 +187,17 @@ hb_coretext_get_variation_glyph (hb_font_t *font HB_UNUSED, if (cg_glyph[i]) return false; + // Humm. CoreText falls back to the default glyph if the variation selector + // is not supported. We cannot truly detect that case. So, in essence, + // we are always returning true here... + *glyph = cg_glyph[0]; return true; } static void -hb_coretext_get_glyph_h_advances (hb_font_t* font, void* font_data, +hb_coretext_get_glyph_h_advances (hb_font_t* font, + void* font_data HB_UNUSED, unsigned count, const hb_codepoint_t *first_glyph, unsigned glyph_stride, @@ -207,7 +205,7 @@ hb_coretext_get_glyph_h_advances (hb_font_t* font, void* font_data, unsigned advance_stride, void *user_data HB_UNUSED) { - CTFontRef ct_font = (CTFontRef) font_data; + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; CGFloat ct_font_size = CTFontGetSize (ct_font); CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size; @@ -233,7 +231,8 @@ hb_coretext_get_glyph_h_advances (hb_font_t* font, void* font_data, #ifndef HB_NO_VERTICAL static void -hb_coretext_get_glyph_v_advances (hb_font_t* font, void* font_data, +hb_coretext_get_glyph_v_advances (hb_font_t* font, + void* font_data HB_UNUSED, unsigned count, const hb_codepoint_t *first_glyph, unsigned glyph_stride, @@ -241,7 +240,7 @@ hb_coretext_get_glyph_v_advances (hb_font_t* font, void* font_data, unsigned advance_stride, void *user_data HB_UNUSED) { - CTFontRef ct_font = (CTFontRef) font_data; + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; CGFloat ct_font_size = CTFontGetSize (ct_font); CGFloat y_mult = (CGFloat) -font->y_scale / ct_font_size; @@ -264,18 +263,16 @@ hb_coretext_get_glyph_v_advances (hb_font_t* font, void* font_data, } } } -#endif -#ifndef HB_NO_VERTICAL static hb_bool_t hb_coretext_get_glyph_v_origin (hb_font_t *font, - void *font_data, + void *font_data HB_UNUSED, hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y, void *user_data HB_UNUSED) { - CTFontRef ct_font = (CTFontRef) font_data; + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; CGFloat ct_font_size = CTFontGetSize (ct_font); CGFloat x_mult = (CGFloat) -font->x_scale / ct_font_size; @@ -294,12 +291,12 @@ hb_coretext_get_glyph_v_origin (hb_font_t *font, static hb_bool_t hb_coretext_get_glyph_extents (hb_font_t *font, - void *font_data, + void *font_data HB_UNUSED, hb_codepoint_t glyph, hb_glyph_extents_t *extents, void *user_data HB_UNUSED) { - CTFontRef ct_font = (CTFontRef) font_data; + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; CGFloat ct_font_size = CTFontGetSize (ct_font); CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size; @@ -310,20 +307,21 @@ hb_coretext_get_glyph_extents (hb_font_t *font, kCTFontOrientationDefault, glyphs, NULL, 1); extents->x_bearing = round (bounds.origin.x * x_mult); - extents->y_bearing = round (bounds.origin.y * y_mult); + extents->y_bearing = round ((bounds.origin.y + bounds.size.height) * y_mult); extents->width = round (bounds.size.width * x_mult); - extents->height = round (bounds.size.height * y_mult); + extents->height = round (bounds.origin.y * y_mult) - extents->y_bearing; return true; } static hb_bool_t hb_coretext_get_font_h_extents (hb_font_t *font, - void *font_data, + void *font_data HB_UNUSED, hb_font_extents_t *metrics, void *user_data HB_UNUSED) { - CTFontRef ct_font = (CTFontRef) font_data; + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; + CGFloat ct_font_size = CTFontGetSize (ct_font); CGFloat y_mult = (CGFloat) font->y_scale / ct_font_size; @@ -371,7 +369,7 @@ hb_coretext_draw_glyph (hb_font_t *font, hb_draw_funcs_t *draw_funcs, void *draw_data, void *user_data) { - CTFontRef ct_font = (CTFontRef) font_data; + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; CGFloat ct_font_size = CTFontGetSize (ct_font); CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size; @@ -415,17 +413,20 @@ hb_coretext_get_glyph_name (hb_font_t *font, (UInt8 *) name, size, &len); name[len] = '\0'; + + CFRelease (cf_name); + return true; } static hb_bool_t -hb_coretext_get_glyph_from_name (hb_font_t *font HB_UNUSED, - void *font_data, +hb_coretext_get_glyph_from_name (hb_font_t *font, + void *font_data HB_UNUSED, const char *name, int len, hb_codepoint_t *glyph, void *user_data HB_UNUSED) { - CTFontRef ct_font = (CTFontRef) font_data; + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; if (len == -1) len = strlen (name); @@ -458,10 +459,8 @@ static struct hb_coretext_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t hb_font_funcs_set_font_h_extents_func (funcs, hb_coretext_get_font_h_extents, nullptr, nullptr); hb_font_funcs_set_glyph_h_advances_func (funcs, hb_coretext_get_glyph_h_advances, nullptr, nullptr); - //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_coretext_get_glyph_h_origin, nullptr, nullptr); #ifndef HB_NO_VERTICAL - //hb_font_funcs_set_font_v_extents_func (funcs, hb_coretext_get_font_v_extents, nullptr, nullptr); hb_font_funcs_set_glyph_v_advances_func (funcs, hb_coretext_get_glyph_v_advances, nullptr, nullptr); hb_font_funcs_set_glyph_v_origin_func (funcs, hb_coretext_get_glyph_v_origin, nullptr, nullptr); #endif @@ -530,8 +529,7 @@ hb_coretext_font_set_funcs (hb_font_t *font) hb_font_set_funcs (font, _hb_coretext_get_font_funcs (), - (void *) CFRetain (ct_font), - _hb_coretext_font_destroy); + nullptr, nullptr); } #undef MAX_GLYPHS diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-shape.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-shape.cc index 0bb235f6d0a16d7b1ff569319ab6a1957ff6a688..c874d49565cc23e7be9aed8395a0d53308b0ce04 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-shape.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-shape.cc @@ -32,279 +32,9 @@ #include "hb-shaper-impl.hh" -#include "hb-coretext.h" +#include "hb-coretext.hh" #include "hb-aat-layout.hh" - -/** - * SECTION:hb-coretext - * @title: hb-coretext - * @short_description: CoreText integration - * @include: hb-coretext.h - * - * Functions for using HarfBuzz with the CoreText fonts. - **/ - -static CTFontRef create_ct_font (CGFontRef cg_font, CGFloat font_size); - -static void -release_table_data (void *user_data) -{ - CFDataRef cf_data = reinterpret_cast<CFDataRef> (user_data); - CFRelease(cf_data); -} - -static hb_blob_t * -_hb_cg_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) -{ - CGFontRef cg_font = reinterpret_cast<CGFontRef> (user_data); - CFDataRef cf_data = CGFontCopyTableForTag (cg_font, tag); - if (unlikely (!cf_data)) - return nullptr; - - const char *data = reinterpret_cast<const char*> (CFDataGetBytePtr (cf_data)); - const size_t length = CFDataGetLength (cf_data); - if (!data || !length) - { - CFRelease (cf_data); - return nullptr; - } - - return hb_blob_create (data, length, HB_MEMORY_MODE_READONLY, - reinterpret_cast<void *> (const_cast<__CFData *> (cf_data)), - release_table_data); -} - -static unsigned -_hb_cg_get_table_tags (const hb_face_t *face HB_UNUSED, - unsigned int start_offset, - unsigned int *table_count, - hb_tag_t *table_tags, - void *user_data) -{ - CGFontRef cg_font = reinterpret_cast<CGFontRef> (user_data); - - CTFontRef ct_font = create_ct_font (cg_font, (CGFloat) HB_CORETEXT_DEFAULT_FONT_SIZE); - - auto arr = CTFontCopyAvailableTables (ct_font, kCTFontTableOptionNoOptions); - - unsigned population = (unsigned) CFArrayGetCount (arr); - unsigned end_offset; - - if (!table_count) - goto done; - - if (unlikely (start_offset >= population)) - { - *table_count = 0; - goto done; - } - - end_offset = start_offset + *table_count; - if (unlikely (end_offset < start_offset)) - { - *table_count = 0; - goto done; - } - end_offset= hb_min (end_offset, (unsigned) population); - - *table_count = end_offset - start_offset; - for (unsigned i = start_offset; i < end_offset; i++) - { - CTFontTableTag tag = (CTFontTableTag)(uintptr_t) CFArrayGetValueAtIndex (arr, i); - table_tags[i - start_offset] = tag; - } - -done: - CFRelease (arr); - CFRelease (ct_font); - return population; -} - -static void -_hb_cg_font_release (void *data) -{ - CGFontRelease ((CGFontRef) data); -} - - -static CTFontDescriptorRef -get_last_resort_font_desc () -{ - // TODO Handle allocation failures? - CTFontDescriptorRef last_resort = CTFontDescriptorCreateWithNameAndSize (CFSTR("LastResort"), 0); - CFArrayRef cascade_list = CFArrayCreate (kCFAllocatorDefault, - (const void **) &last_resort, - 1, - &kCFTypeArrayCallBacks); - CFRelease (last_resort); - CFDictionaryRef attributes = CFDictionaryCreate (kCFAllocatorDefault, - (const void **) &kCTFontCascadeListAttribute, - (const void **) &cascade_list, - 1, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - CFRelease (cascade_list); - - CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes); - CFRelease (attributes); - return font_desc; -} - -static void -release_data (void *info, const void *data, size_t size) -{ - assert (hb_blob_get_length ((hb_blob_t *) info) == size && - hb_blob_get_data ((hb_blob_t *) info, nullptr) == data); - - hb_blob_destroy ((hb_blob_t *) info); -} - -static CGFontRef -create_cg_font (hb_face_t *face) -{ - CGFontRef cg_font = nullptr; - if (face->destroy == _hb_cg_font_release) - { - cg_font = CGFontRetain ((CGFontRef) face->user_data); - } - else - { - hb_blob_t *blob = hb_face_reference_blob (face); - unsigned int blob_length; - const char *blob_data = hb_blob_get_data (blob, &blob_length); - if (unlikely (!blob_length)) - DEBUG_MSG (CORETEXT, face, "Face has empty blob"); - - CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data); - if (likely (provider)) - { - cg_font = CGFontCreateWithDataProvider (provider); - if (unlikely (!cg_font)) - DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed"); - CGDataProviderRelease (provider); - } - } - return cg_font; -} - -static CTFontRef -create_ct_font (CGFontRef cg_font, CGFloat font_size) -{ - CTFontRef ct_font = nullptr; - - /* CoreText does not enable trak table usage / tracking when creating a CTFont - * using CTFontCreateWithGraphicsFont. The only way of enabling tracking seems - * to be through the CTFontCreateUIFontForLanguage call. */ - CFStringRef cg_postscript_name = CGFontCopyPostScriptName (cg_font); - if (CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSText")) || - CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSDisplay"))) - { -#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1080 -# define kCTFontUIFontSystem kCTFontSystemFontType -# define kCTFontUIFontEmphasizedSystem kCTFontEmphasizedSystemFontType -#endif - CTFontUIFontType font_type = kCTFontUIFontSystem; - if (CFStringHasSuffix (cg_postscript_name, CFSTR ("-Bold"))) - font_type = kCTFontUIFontEmphasizedSystem; - - ct_font = CTFontCreateUIFontForLanguage (font_type, font_size, nullptr); - CFStringRef ct_result_name = CTFontCopyPostScriptName(ct_font); - if (CFStringCompare (ct_result_name, cg_postscript_name, 0) != kCFCompareEqualTo) - { - CFRelease(ct_font); - ct_font = nullptr; - } - CFRelease (ct_result_name); - } - CFRelease (cg_postscript_name); - - if (!ct_font) - ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, nullptr, nullptr); - - if (unlikely (!ct_font)) { - DEBUG_MSG (CORETEXT, cg_font, "Font CTFontCreateWithGraphicsFont() failed"); - return nullptr; - } - - /* crbug.com/576941 and crbug.com/625902 and the investigation in the latter - * bug indicate that the cascade list reconfiguration occasionally causes - * crashes in CoreText on OS X 10.9, thus let's skip this step on older - * operating system versions. Except for the emoji font, where _not_ - * reconfiguring the cascade list causes CoreText crashes. For details, see - * crbug.com/549610 */ - // 0x00070000 stands for "kCTVersionNumber10_10", see CoreText.h -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - if (&CTGetCoreTextVersion != nullptr && CTGetCoreTextVersion() < 0x00070000) { -#pragma GCC diagnostic pop - CFStringRef fontName = CTFontCopyPostScriptName (ct_font); - bool isEmojiFont = CFStringCompare (fontName, CFSTR("AppleColorEmoji"), 0) == kCFCompareEqualTo; - CFRelease (fontName); - if (!isEmojiFont) - return ct_font; - } - - CFURLRef original_url = nullptr; -#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - ATSFontRef atsFont; - FSRef fsref; - OSStatus status; - atsFont = CTFontGetPlatformFont (ct_font, NULL); - status = ATSFontGetFileReference (atsFont, &fsref); - if (status == noErr) - original_url = CFURLCreateFromFSRef (NULL, &fsref); -#else - original_url = (CFURLRef) CTFontCopyAttribute (ct_font, kCTFontURLAttribute); -#endif - - /* Create font copy with cascade list that has LastResort first; this speeds up CoreText - * font fallback which we don't need anyway. */ - { - CTFontDescriptorRef last_resort_font_desc = get_last_resort_font_desc (); - CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (ct_font, 0.0, nullptr, last_resort_font_desc); - CFRelease (last_resort_font_desc); - if (new_ct_font) - { - /* The CTFontCreateCopyWithAttributes call fails to stay on the same font - * when reconfiguring the cascade list and may switch to a different font - * when there are fonts that go by the same name, since the descriptor is - * just name and size. - * - * Avoid reconfiguring the cascade lists if the new font is outside the - * system locations that we cannot access from the sandboxed renderer - * process in Blink. This can be detected by the new file URL location - * that the newly found font points to. */ - CFURLRef new_url = nullptr; -#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - atsFont = CTFontGetPlatformFont (new_ct_font, NULL); - status = ATSFontGetFileReference (atsFont, &fsref); - if (status == noErr) - new_url = CFURLCreateFromFSRef (NULL, &fsref); -#else - new_url = (CFURLRef) CTFontCopyAttribute (new_ct_font, kCTFontURLAttribute); -#endif - // Keep reconfigured font if URL cannot be retrieved (seems to be the case - // on Mac OS 10.12 Sierra), speculative fix for crbug.com/625606 - if (!original_url || !new_url || CFEqual (original_url, new_url)) { - CFRelease (ct_font); - ct_font = new_ct_font; - } else { - CFRelease (new_ct_font); - DEBUG_MSG (CORETEXT, ct_font, "Discarding reconfigured CTFont, location changed."); - } - if (new_url) - CFRelease (new_url); - } - else - DEBUG_MSG (CORETEXT, ct_font, "Font copy with empty cascade list failed"); - } - - if (original_url) - CFRelease (original_url); - return ct_font; -} - hb_coretext_face_data_t * _hb_coretext_shaper_face_data_create (hb_face_t *face) { @@ -325,102 +55,6 @@ _hb_coretext_shaper_face_data_destroy (hb_coretext_face_data_t *data) CFRelease ((CGFontRef) data); } -/** - * hb_coretext_face_create: - * @cg_font: The CGFontRef to work upon - * - * Creates an #hb_face_t face object from the specified - * CGFontRef. - * - * Return value: (transfer full): The new face object - * - * Since: 0.9.10 - */ -hb_face_t * -hb_coretext_face_create (CGFontRef cg_font) -{ - hb_face_t *face = hb_face_create_for_tables (_hb_cg_reference_table, CGFontRetain (cg_font), _hb_cg_font_release); - hb_face_set_get_table_tags_func (face, _hb_cg_get_table_tags, cg_font, nullptr); - return face; -} - -/** - * hb_coretext_face_create_from_file_or_fail: - * @file_name: A font filename - * @index: The index of the face within the file - * - * Creates an #hb_face_t face object from the specified - * font file and face index. - * - * This is similar in functionality to hb_face_create_from_file_or_fail(), - * but uses the CoreText library for loading the font file. - * - * Return value: (transfer full): The new face object, or `NULL` if - * no face is found at the specified index or the file cannot be read. - * - * Since: 10.1.0 - */ -hb_face_t * -hb_coretext_face_create_from_file_or_fail (const char *file_name, - unsigned int index) -{ - auto url = CFURLCreateFromFileSystemRepresentation (nullptr, - (const UInt8 *) file_name, - strlen (file_name), - false); - if (unlikely (!url)) - return nullptr; - - auto ct_font_desc_array = CTFontManagerCreateFontDescriptorsFromURL (url); - if (unlikely (!ct_font_desc_array)) - { - CFRelease (url); - return nullptr; - } - auto ct_font_desc = (CFArrayGetCount (ct_font_desc_array) > index) ? - (CTFontDescriptorRef) CFArrayGetValueAtIndex (ct_font_desc_array, index) : nullptr; - if (unlikely (!ct_font_desc)) - { - CFRelease (ct_font_desc_array); - CFRelease (url); - return nullptr; - } - CFRelease (url); - auto ct_font = ct_font_desc ? CTFontCreateWithFontDescriptor (ct_font_desc, 0, nullptr) : nullptr; - CFRelease (ct_font_desc_array); - if (unlikely (!ct_font)) - return nullptr; - - auto cg_font = ct_font ? CTFontCopyGraphicsFont (ct_font, nullptr) : nullptr; - CFRelease (ct_font); - if (unlikely (!cg_font)) - return nullptr; - - hb_face_t *face = hb_coretext_face_create (cg_font); - CFRelease (cg_font); - if (unlikely (hb_face_is_immutable (face))) - return nullptr; - - return face; -} - -/** - * hb_coretext_face_get_cg_font: - * @face: The #hb_face_t to work upon - * - * Fetches the CGFontRef associated with an #hb_face_t - * face object - * - * Return value: the CGFontRef found - * - * Since: 0.9.10 - */ -CGFontRef -hb_coretext_face_get_cg_font (hb_face_t *face) -{ - return (CGFontRef) (const void *) face->data.coretext; -} - hb_coretext_font_data_t * _hb_coretext_shaper_font_data_create (hb_font_t *font) @@ -439,7 +73,9 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) return nullptr; } - if (font->num_coords) + unsigned num_axes = hb_ot_var_get_axis_count (face); + // https://github.com/harfbuzz/harfbuzz/issues/5163 + if (num_axes) { CFMutableDictionaryRef variations = CFDictionaryCreateMutable (kCFAllocatorDefault, @@ -447,14 +83,15 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - for (unsigned i = 0; i < font->num_coords; i++) + unsigned count = hb_max (num_axes, font->num_coords); + for (unsigned i = 0; i < count; i++) { hb_ot_var_axis_info_t info; unsigned int c = 1; hb_ot_var_get_axis_infos (font->face, i, &c, &info); - if (font->design_coords[i] == info.default_value) - continue; - float v = hb_clamp (font->design_coords[i], info.min_value, info.max_value); + float v = i < font->num_coords ? + hb_clamp (font->design_coords[i], info.min_value, info.max_value) : + info.default_value; CFNumberRef tag_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &info.tag); CFNumberRef value_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberFloatType, &v); @@ -489,94 +126,6 @@ _hb_coretext_shaper_font_data_destroy (hb_coretext_font_data_t *data) CFRelease ((CTFontRef) data); } -/** - * hb_coretext_font_create: - * @ct_font: The CTFontRef to work upon - * - * Creates an #hb_font_t font object from the specified - * CTFontRef. - * - * The created font uses the default font functions implemented - * natively by HarfBuzz. If you want to use the CoreText font functions - * instead (rarely needed), you can do so by calling - * by hb_coretext_font_set_funcs(). - * - * Return value: (transfer full): The new font object - * - * Since: 1.7.2 - **/ -hb_font_t * -hb_coretext_font_create (CTFontRef ct_font) -{ - CGFontRef cg_font = CTFontCopyGraphicsFont (ct_font, nullptr); - hb_face_t *face = hb_coretext_face_create (cg_font); - CFRelease (cg_font); - hb_font_t *font = hb_font_create (face); - hb_face_destroy (face); - - if (unlikely (hb_object_is_immutable (font))) - return font; - - hb_font_set_ptem (font, CTFontGetSize (ct_font)); - - /* Copy font variations */ - CFDictionaryRef variations = CTFontCopyVariation (ct_font); - if (variations) - { - hb_vector_t<hb_variation_t> vars; - hb_vector_t<CFTypeRef> keys; - hb_vector_t<CFTypeRef> values; - - CFIndex count = CFDictionaryGetCount (variations); - if (unlikely (!vars.alloc_exact (count) || !keys.resize_exact (count) || !values.resize_exact (count))) - goto done; - - // Fetch them one by one and collect in a vector of our own. - CFDictionaryGetKeysAndValues (variations, keys.arrayZ, values.arrayZ); - for (CFIndex i = 0; i < count; i++) - { - int tag; - float value; - CFNumberGetValue ((CFNumberRef) keys.arrayZ[i], kCFNumberIntType, &tag); - CFNumberGetValue ((CFNumberRef) values.arrayZ[i], kCFNumberFloatType, &value); - - hb_variation_t var = {tag, value}; - vars.push (var); - } - hb_font_set_variations (font, vars.arrayZ, vars.length); - -done: - CFRelease (variations); - } - - /* Let there be dragons here... */ - font->data.coretext.cmpexch (nullptr, (hb_coretext_font_data_t *) CFRetain (ct_font)); - - // https://github.com/harfbuzz/harfbuzz/pull/4895#issuecomment-2408471254 - //hb_coretext_font_set_funcs (font); - - return font; -} - -/** - * hb_coretext_font_get_ct_font: - * @font: #hb_font_t to work upon - * - * Fetches the CTFontRef associated with the specified - * #hb_font_t font object. - * - * Return value: the CTFontRef found - * - * Since: 0.9.10 - */ -CTFontRef -hb_coretext_font_get_ct_font (hb_font_t *font) -{ - CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; - return ct_font ? (CTFontRef) ct_font : nullptr; -} - - /* * shaper */ @@ -646,7 +195,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, * B1 M1 B2 M2, and B1-B2 form a ligature, M2's cluster will * continue pointing to B2 even though B2 was merged into B1's * cluster... */ - if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) + if (HB_BUFFER_CLUSTER_LEVEL_IS_GRAPHEMES (buffer->cluster_level)) { hb_unicode_funcs_t *unicode = buffer->unicode; unsigned int count = buffer->len; @@ -1010,7 +559,7 @@ resize_and_retry: CFArrayRef glyph_runs = CTLineGetGlyphRuns (line); unsigned int num_runs = CFArrayGetCount (glyph_runs); - DEBUG_MSG (CORETEXT, nullptr, "Num runs: %d", num_runs); + DEBUG_MSG (CORETEXT, nullptr, "Num runs: %u", num_runs); buffer->len = 0; uint32_t status_or = 0; @@ -1292,7 +841,7 @@ resize_and_retry: * or the native OT backend, only that the cluster indices will be * monotonic in the output buffer. */ if (count > 1 && (status_or & kCTRunStatusNonMonotonic) && - buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) + HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE (buffer->cluster_level)) { hb_glyph_info_t *info = buffer->info; if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc new file mode 100644 index 0000000000000000000000000000000000000000..6c0525b3a07dd951b707c034ef587797b2107f24 --- /dev/null +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc @@ -0,0 +1,572 @@ +/* + * Copyright © 2012,2013 Mozilla Foundation. + * Copyright © 2012,2013 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Mozilla Author(s): Jonathan Kew + * Google Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#ifdef HAVE_CORETEXT + +#include "hb-shaper-impl.hh" + +#include "hb-coretext.hh" + + +/** + * SECTION:hb-coretext + * @title: hb-coretext + * @short_description: CoreText integration + * @include: hb-coretext.h + * + * Functions for using HarfBuzz with the CoreText fonts. + **/ + +static void +release_table_data (void *user_data) +{ + CFDataRef cf_data = reinterpret_cast<CFDataRef> (user_data); + CFRelease(cf_data); +} + +static hb_blob_t * +_hb_cg_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) +{ + CGFontRef cg_font = reinterpret_cast<CGFontRef> (user_data); + CFDataRef cf_data = CGFontCopyTableForTag (cg_font, tag); + if (unlikely (!cf_data)) + return nullptr; + + const char *data = reinterpret_cast<const char*> (CFDataGetBytePtr (cf_data)); + const size_t length = CFDataGetLength (cf_data); + if (!data || !length) + { + CFRelease (cf_data); + return nullptr; + } + + return hb_blob_create (data, length, HB_MEMORY_MODE_READONLY, + reinterpret_cast<void *> (const_cast<__CFData *> (cf_data)), + release_table_data); +} + +static unsigned +_hb_cg_get_table_tags (const hb_face_t *face HB_UNUSED, + unsigned int start_offset, + unsigned int *table_count, + hb_tag_t *table_tags, + void *user_data) +{ + CGFontRef cg_font = reinterpret_cast<CGFontRef> (user_data); + + CTFontRef ct_font = create_ct_font (cg_font, (CGFloat) HB_CORETEXT_DEFAULT_FONT_SIZE); + + auto arr = CTFontCopyAvailableTables (ct_font, kCTFontTableOptionNoOptions); + + unsigned population = (unsigned) CFArrayGetCount (arr); + unsigned end_offset; + + if (!table_count) + goto done; + + if (unlikely (start_offset >= population)) + { + *table_count = 0; + goto done; + } + + end_offset = start_offset + *table_count; + if (unlikely (end_offset < start_offset)) + { + *table_count = 0; + goto done; + } + end_offset= hb_min (end_offset, (unsigned) population); + + *table_count = end_offset - start_offset; + for (unsigned i = start_offset; i < end_offset; i++) + { + CTFontTableTag tag = (CTFontTableTag)(uintptr_t) CFArrayGetValueAtIndex (arr, i); + table_tags[i - start_offset] = tag; + } + +done: + CFRelease (arr); + CFRelease (ct_font); + return population; +} + +static void +_hb_cg_font_release (void *data) +{ + CGFontRelease ((CGFontRef) data); +} + + +static CTFontDescriptorRef +get_last_resort_font_desc () +{ + // TODO Handle allocation failures? + CTFontDescriptorRef last_resort = CTFontDescriptorCreateWithNameAndSize (CFSTR("LastResort"), 0); + CFArrayRef cascade_list = CFArrayCreate (kCFAllocatorDefault, + (const void **) &last_resort, + 1, + &kCFTypeArrayCallBacks); + CFRelease (last_resort); + CFDictionaryRef attributes = CFDictionaryCreate (kCFAllocatorDefault, + (const void **) &kCTFontCascadeListAttribute, + (const void **) &cascade_list, + 1, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFRelease (cascade_list); + + CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes); + CFRelease (attributes); + return font_desc; +} + +static void +release_data (void *info, const void *data, size_t size) +{ + assert (hb_blob_get_length ((hb_blob_t *) info) == size && + hb_blob_get_data ((hb_blob_t *) info, nullptr) == data); + + hb_blob_destroy ((hb_blob_t *) info); +} + +CGFontRef +create_cg_font (CFArrayRef ct_font_desc_array, unsigned int named_instance_index) +{ + if (named_instance_index == 0) + { + // Default instance. We don't know which one is it. Return the first one. + // We will set the correct variations on it later. + } + else + named_instance_index--; + auto ct_font_desc = (CFArrayGetCount (ct_font_desc_array) > named_instance_index) ? + (CTFontDescriptorRef) CFArrayGetValueAtIndex (ct_font_desc_array, named_instance_index) : nullptr; + if (unlikely (!ct_font_desc)) + { + CFRelease (ct_font_desc_array); + return nullptr; + } + auto ct_font = ct_font_desc ? CTFontCreateWithFontDescriptor (ct_font_desc, 0, nullptr) : nullptr; + CFRelease (ct_font_desc_array); + if (unlikely (!ct_font)) + return nullptr; + + auto cg_font = ct_font ? CTFontCopyGraphicsFont (ct_font, nullptr) : nullptr; + CFRelease (ct_font); + + return cg_font; +} + +CGFontRef +create_cg_font (hb_blob_t *blob, unsigned int index) +{ + hb_blob_make_immutable (blob); + unsigned int blob_length; + const char *blob_data = hb_blob_get_data (blob, &blob_length); + if (unlikely (!blob_length)) + DEBUG_MSG (CORETEXT, blob, "Empty blob"); + + unsigned ttc_index = index & 0xFFFF; + unsigned named_instance_index = index >> 16; + + if (ttc_index != 0) + { + DEBUG_MSG (CORETEXT, blob, "TTC index %d not supported", ttc_index); + return nullptr; // CoreText does not support TTCs + } + + if (unlikely (named_instance_index != 0)) + { + auto ct_font_desc_array = CTFontManagerCreateFontDescriptorsFromData (CFDataCreate (kCFAllocatorDefault, (const UInt8 *) blob_data, blob_length)); + if (unlikely (!ct_font_desc_array)) + return nullptr; + return create_cg_font (ct_font_desc_array, named_instance_index); + } + + hb_blob_reference (blob); + CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data); + CGFontRef cg_font = nullptr; + if (likely (provider)) + { + cg_font = CGFontCreateWithDataProvider (provider); + if (unlikely (!cg_font)) + DEBUG_MSG (CORETEXT, blob, "CGFontCreateWithDataProvider() failed"); + CGDataProviderRelease (provider); + } + return cg_font; +} + +CGFontRef +create_cg_font (hb_face_t *face) +{ + CGFontRef cg_font = nullptr; + if (face->destroy == _hb_cg_font_release) + cg_font = CGFontRetain ((CGFontRef) face->user_data); + else + { + hb_blob_t *blob = hb_face_reference_blob (face); + cg_font = create_cg_font (blob, face->index); + hb_blob_destroy (blob); + } + return cg_font; +} + +CTFontRef +create_ct_font (CGFontRef cg_font, CGFloat font_size) +{ + CTFontRef ct_font = nullptr; + + /* CoreText does not enable trak table usage / tracking when creating a CTFont + * using CTFontCreateWithGraphicsFont. The only way of enabling tracking seems + * to be through the CTFontCreateUIFontForLanguage call. */ + CFStringRef cg_postscript_name = CGFontCopyPostScriptName (cg_font); + if (CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSText")) || + CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSDisplay"))) + { +#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1080 +# define kCTFontUIFontSystem kCTFontSystemFontType +# define kCTFontUIFontEmphasizedSystem kCTFontEmphasizedSystemFontType +#endif + CTFontUIFontType font_type = kCTFontUIFontSystem; + if (CFStringHasSuffix (cg_postscript_name, CFSTR ("-Bold"))) + font_type = kCTFontUIFontEmphasizedSystem; + + ct_font = CTFontCreateUIFontForLanguage (font_type, font_size, nullptr); + CFStringRef ct_result_name = CTFontCopyPostScriptName(ct_font); + if (CFStringCompare (ct_result_name, cg_postscript_name, 0) != kCFCompareEqualTo) + { + CFRelease(ct_font); + ct_font = nullptr; + } + CFRelease (ct_result_name); + } + CFRelease (cg_postscript_name); + + if (!ct_font) + ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, nullptr, nullptr); + + if (unlikely (!ct_font)) { + DEBUG_MSG (CORETEXT, cg_font, "Font CTFontCreateWithGraphicsFont() failed"); + return nullptr; + } + + /* crbug.com/576941 and crbug.com/625902 and the investigation in the latter + * bug indicate that the cascade list reconfiguration occasionally causes + * crashes in CoreText on OS X 10.9, thus let's skip this step on older + * operating system versions. Except for the emoji font, where _not_ + * reconfiguring the cascade list causes CoreText crashes. For details, see + * crbug.com/549610 */ + // 0x00070000 stands for "kCTVersionNumber10_10", see CoreText.h +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + if (&CTGetCoreTextVersion != nullptr && CTGetCoreTextVersion() < 0x00070000) { +#pragma GCC diagnostic pop + CFStringRef fontName = CTFontCopyPostScriptName (ct_font); + bool isEmojiFont = CFStringCompare (fontName, CFSTR("AppleColorEmoji"), 0) == kCFCompareEqualTo; + CFRelease (fontName); + if (!isEmojiFont) + return ct_font; + } + + CFURLRef original_url = nullptr; +#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1060 + ATSFontRef atsFont; + FSRef fsref; + OSStatus status; + atsFont = CTFontGetPlatformFont (ct_font, NULL); + status = ATSFontGetFileReference (atsFont, &fsref); + if (status == noErr) + original_url = CFURLCreateFromFSRef (NULL, &fsref); +#else + original_url = (CFURLRef) CTFontCopyAttribute (ct_font, kCTFontURLAttribute); +#endif + + /* Create font copy with cascade list that has LastResort first; this speeds up CoreText + * font fallback which we don't need anyway. */ + { + CTFontDescriptorRef last_resort_font_desc = get_last_resort_font_desc (); + CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (ct_font, 0.0, nullptr, last_resort_font_desc); + CFRelease (last_resort_font_desc); + if (new_ct_font) + { + /* The CTFontCreateCopyWithAttributes call fails to stay on the same font + * when reconfiguring the cascade list and may switch to a different font + * when there are fonts that go by the same name, since the descriptor is + * just name and size. + * + * Avoid reconfiguring the cascade lists if the new font is outside the + * system locations that we cannot access from the sandboxed renderer + * process in Blink. This can be detected by the new file URL location + * that the newly found font points to. */ + CFURLRef new_url = nullptr; +#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1060 + atsFont = CTFontGetPlatformFont (new_ct_font, NULL); + status = ATSFontGetFileReference (atsFont, &fsref); + if (status == noErr) + new_url = CFURLCreateFromFSRef (NULL, &fsref); +#else + new_url = (CFURLRef) CTFontCopyAttribute (new_ct_font, kCTFontURLAttribute); +#endif + // Keep reconfigured font if URL cannot be retrieved (seems to be the case + // on Mac OS 10.12 Sierra), speculative fix for crbug.com/625606 + if (!original_url || !new_url || CFEqual (original_url, new_url)) { + CFRelease (ct_font); + ct_font = new_ct_font; + } else { + CFRelease (new_ct_font); + DEBUG_MSG (CORETEXT, ct_font, "Discarding reconfigured CTFont, location changed."); + } + if (new_url) + CFRelease (new_url); + } + else + DEBUG_MSG (CORETEXT, ct_font, "Font copy with empty cascade list failed"); + } + + if (original_url) + CFRelease (original_url); + return ct_font; +} + +/** + * hb_coretext_face_create: + * @cg_font: The CGFontRef to work upon + * + * Creates an #hb_face_t face object from the specified + * CGFontRef. + * + * Return value: (transfer full): The new face object + * + * Since: 0.9.10 + */ +hb_face_t * +hb_coretext_face_create (CGFontRef cg_font) +{ + hb_face_t *face = hb_face_create_for_tables (_hb_cg_reference_table, CGFontRetain (cg_font), _hb_cg_font_release); + hb_face_set_get_table_tags_func (face, _hb_cg_get_table_tags, cg_font, nullptr); + return face; +} + +/** + * hb_coretext_face_create_from_file_or_fail: + * @file_name: A font filename + * @index: The index of the face within the file + * + * Creates an #hb_face_t face object from the specified + * font file and face index. + * + * This is similar in functionality to hb_face_create_from_file_or_fail(), + * but uses the CoreText library for loading the font file. + * + * Return value: (transfer full): The new face object, or `NULL` if + * no face is found at the specified index or the file cannot be read. + * + * Since: 10.1.0 + */ +hb_face_t * +hb_coretext_face_create_from_file_or_fail (const char *file_name, + unsigned int index) +{ + auto url = CFURLCreateFromFileSystemRepresentation (nullptr, + (const UInt8 *) file_name, + strlen (file_name), + false); + if (unlikely (!url)) + return nullptr; + + auto ct_font_desc_array = CTFontManagerCreateFontDescriptorsFromURL (url); + if (unlikely (!ct_font_desc_array)) + { + CFRelease (url); + return nullptr; + } + + unsigned ttc_index = index & 0xFFFF; + unsigned named_instance_index = index >> 16; + + if (ttc_index != 0) + { + DEBUG_MSG (CORETEXT, nullptr, "TTC index %d not supported", ttc_index); + return nullptr; // CoreText does not support TTCs + } + + auto cg_font = create_cg_font (ct_font_desc_array, named_instance_index); + CFRelease (url); + + hb_face_t *face = hb_coretext_face_create (cg_font); + CFRelease (cg_font); + if (unlikely (hb_face_is_immutable (face))) + return nullptr; + + hb_face_set_index (face, index); + + return face; +} + +/** + * hb_coretext_face_create_from_blob_or_fail: + * @blob: A blob containing the font data + * @index: The index of the face within the blob + * + * Creates an #hb_face_t face object from the specified + * blob and face index. + * + * This is similar in functionality to hb_face_create_from_blob_or_fail(), + * but uses the CoreText library for loading the font data. + * + * Return value: (transfer full): The new face object, or `NULL` if + * no face is found at the specified index or the blob cannot be read. + * + * Since: 11.0.0 + */ +hb_face_t * +hb_coretext_face_create_from_blob_or_fail (hb_blob_t *blob, + unsigned int index) +{ + auto cg_font = create_cg_font (blob, index); + if (unlikely (!cg_font)) + return nullptr; + + hb_face_t *face = hb_coretext_face_create (cg_font); + CFRelease (cg_font); + if (unlikely (hb_face_is_immutable (face))) + return nullptr; + + hb_face_set_index (face, index); + + return face; +} + +/** + * hb_coretext_face_get_cg_font: + * @face: The #hb_face_t to work upon + * + * Fetches the CGFontRef associated with an #hb_face_t + * face object + * + * Return value: the CGFontRef found + * + * Since: 0.9.10 + */ +CGFontRef +hb_coretext_face_get_cg_font (hb_face_t *face) +{ + return (CGFontRef) (const void *) face->data.coretext; +} + +/** + * hb_coretext_font_create: + * @ct_font: The CTFontRef to work upon + * + * Creates an #hb_font_t font object from the specified + * CTFontRef. + * + * The created font uses the default font functions implemented + * natively by HarfBuzz. If you want to use the CoreText font functions + * instead (rarely needed), you can do so by calling + * by hb_coretext_font_set_funcs(). + * + * Return value: (transfer full): The new font object + * + * Since: 1.7.2 + **/ +hb_font_t * +hb_coretext_font_create (CTFontRef ct_font) +{ + CGFontRef cg_font = CTFontCopyGraphicsFont (ct_font, nullptr); + hb_face_t *face = hb_coretext_face_create (cg_font); + CFRelease (cg_font); + hb_font_t *font = hb_font_create (face); + hb_face_destroy (face); + + if (unlikely (hb_object_is_immutable (font))) + return font; + + hb_font_set_ptem (font, CTFontGetSize (ct_font)); + + /* Copy font variations */ + CFDictionaryRef variations = CTFontCopyVariation (ct_font); + if (variations) + { + hb_vector_t<hb_variation_t> vars; + hb_vector_t<CFTypeRef> keys; + hb_vector_t<CFTypeRef> values; + + CFIndex count = CFDictionaryGetCount (variations); + if (unlikely (!vars.alloc_exact (count) || !keys.resize_exact (count) || !values.resize_exact (count))) + goto done; + + // Fetch them one by one and collect in a vector of our own. + CFDictionaryGetKeysAndValues (variations, keys.arrayZ, values.arrayZ); + for (CFIndex i = 0; i < count; i++) + { + int tag; + float value; + CFNumberGetValue ((CFNumberRef) keys.arrayZ[i], kCFNumberIntType, &tag); + CFNumberGetValue ((CFNumberRef) values.arrayZ[i], kCFNumberFloatType, &value); + + hb_variation_t var = {tag, value}; + vars.push (var); + } + hb_font_set_variations (font, vars.arrayZ, vars.length); + +done: + CFRelease (variations); + } + + /* Let there be dragons here... */ + font->data.coretext.cmpexch (nullptr, (hb_coretext_font_data_t *) CFRetain (ct_font)); + + // https://github.com/harfbuzz/harfbuzz/pull/4895#issuecomment-2408471254 + //hb_coretext_font_set_funcs (font); + + return font; +} + +/** + * hb_coretext_font_get_ct_font: + * @font: #hb_font_t to work upon + * + * Fetches the CTFontRef associated with the specified + * #hb_font_t font object. + * + * Return value: the CTFontRef found + * + * Since: 0.9.10 + */ +CTFontRef +hb_coretext_font_get_ct_font (hb_font_t *font) +{ + return (CTFontRef) (const void *) font->data.coretext; +} + + +#endif diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.h b/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.h index 3626f1c12f2499e137deec8eb7fe423ec3cd2241..a7c7fee76740ea6be8a54bc9cb117a4603d6afe7 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.h +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.h @@ -84,6 +84,10 @@ HB_EXTERN hb_face_t * hb_coretext_face_create_from_file_or_fail (const char *file_name, unsigned int index); +HB_EXTERN hb_face_t * +hb_coretext_face_create_from_blob_or_fail (hb_blob_t *blob, + unsigned int index); + HB_EXTERN hb_font_t * hb_coretext_font_create (CTFontRef ct_font); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.hh new file mode 100644 index 0000000000000000000000000000000000000000..5f58d2abffd39a198efdcf6b716732c23c1c3328 --- /dev/null +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.hh @@ -0,0 +1,53 @@ +/* + * Copyright © 2012,2013 Mozilla Foundation. + * Copyright © 2012,2013 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Mozilla Author(s): Jonathan Kew + * Google Author(s): Behdad Esfahbod + */ + + +#ifndef HB_CORETEXT_HH +#define HB_CORETEXT_HH + +#include "hb.hh" + +#include "hb-coretext.h" + +#include "hb-aat-layout.hh" + + +HB_INTERNAL CGFontRef +create_cg_font (CFArrayRef ct_font_desc_array, unsigned int index); + +HB_INTERNAL CGFontRef +create_cg_font (hb_blob_t *blob, unsigned int index); + +HB_INTERNAL CGFontRef +create_cg_font (hb_face_t *face); + +HB_INTERNAL CTFontRef +create_ct_font (CGFontRef cg_font, CGFloat font_size); + + +#endif /* HB_CORETEXT_HH */ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh index 559db4067e240b4cfb9959d68e29d351994e886c..f79b42bc4b3282590a63053ed090fb368d233112 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh @@ -49,15 +49,15 @@ struct hb_options_t }; union hb_options_union_t { - int i; + unsigned i; hb_options_t opts; }; -static_assert ((sizeof (hb_atomic_int_t) >= sizeof (hb_options_union_t)), ""); +static_assert ((sizeof (hb_atomic_t<unsigned>) >= sizeof (hb_options_union_t)), ""); HB_INTERNAL void _hb_options_init (); -extern HB_INTERNAL hb_atomic_int_t _hb_options; +extern HB_INTERNAL hb_atomic_t<unsigned> _hb_options; static inline hb_options_t hb_options () diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite-font.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite-font.cc new file mode 100644 index 0000000000000000000000000000000000000000..9752110e474d98b1d3cdc887ecde449e7cea830a --- /dev/null +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite-font.cc @@ -0,0 +1,388 @@ +/* + * Copyright © 2025 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#ifdef HAVE_DIRECTWRITE + +#include "hb-directwrite.h" + +#include <d2d1.h> + +#include "hb-draw.hh" +#include "hb-font.hh" +#include "hb-machinery.hh" + +#define MAX_GLYPHS 256u + +static unsigned int +hb_directwrite_get_nominal_glyphs (hb_font_t *font, + void *font_data HB_UNUSED, + unsigned int count, + const hb_codepoint_t *first_unicode, + unsigned int unicode_stride, + hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + void *user_data HB_UNUSED) +{ + IDWriteFontFace *dw_face = (IDWriteFontFace *) (const void *) font->data.directwrite; + + for (unsigned i = 0; i < count;) + { + UINT32 unicodes[MAX_GLYPHS]; + UINT16 gids[MAX_GLYPHS]; + + unsigned n = hb_min (MAX_GLYPHS, count - i); + + for (unsigned j = 0; j < n; j++) + { + unicodes[j] = *first_unicode; + first_unicode = &StructAtOffset<const hb_codepoint_t> (first_unicode, unicode_stride); + } + + if (!SUCCEEDED (dw_face->GetGlyphIndices (unicodes, n, gids))) + return i; + + for (unsigned j = 0; j < n; j++) + { + if (!gids[j]) + return i + j; + *first_glyph = gids[j]; + first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride); + } + + i += n; + } + + return count; +} + +static hb_bool_t +hb_directwrite_get_font_h_extents (hb_font_t *font, + void *font_data HB_UNUSED, + hb_font_extents_t *metrics, + void *user_data HB_UNUSED) +{ + IDWriteFontFace *dw_face = (IDWriteFontFace *) (const void *) font->data.directwrite; + + DWRITE_FONT_METRICS dw_metrics; + dw_face->GetMetrics (&dw_metrics); + + metrics->ascender = font->em_scale_y (dw_metrics.ascent); + metrics->descender = -font->em_scale_y (dw_metrics.descent); + metrics->line_gap = font->em_scale_y (dw_metrics.lineGap); + + return true; +} + +static void +hb_directwrite_get_glyph_h_advances (hb_font_t* font, + void* font_data HB_UNUSED, + unsigned count, + const hb_codepoint_t *first_glyph, + unsigned glyph_stride, + hb_position_t *first_advance, + unsigned advance_stride, + void *user_data HB_UNUSED) +{ + IDWriteFontFace *dw_face = (IDWriteFontFace *) (const void *) font->data.directwrite; + + IDWriteFontFace1 *dw_face1 = nullptr; + dw_face->QueryInterface (__uuidof(IDWriteFontFace1), (void**)&dw_face1); + assert (dw_face1); + + for (unsigned i = 0; i < count;) + { + UINT16 gids[MAX_GLYPHS]; + INT32 advances[MAX_GLYPHS]; + + unsigned n = hb_min (MAX_GLYPHS, count - i); + + for (unsigned j = 0; j < n; j++) + { + gids[j] = *first_glyph; + advances[j] = 0; + first_glyph = &StructAtOffset<const hb_codepoint_t> (first_glyph, glyph_stride); + } + dw_face1->GetDesignGlyphAdvances (n, gids, advances, false); + for (unsigned j = 0; j < n; j++) + { + *first_advance = font->em_scale_x (advances[j]); + first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride); + } + + i += n; + } +} + +#ifndef HB_NO_VERTICAL + +static void +hb_directwrite_get_glyph_v_advances (hb_font_t* font, + void* font_data HB_UNUSED, + unsigned count, + const hb_codepoint_t *first_glyph, + unsigned glyph_stride, + hb_position_t *first_advance, + unsigned advance_stride, + void *user_data HB_UNUSED) +{ + IDWriteFontFace *dw_face = (IDWriteFontFace *) (const void *) font->data.directwrite; + + IDWriteFontFace1 *dw_face1 = nullptr; + dw_face->QueryInterface (__uuidof(IDWriteFontFace1), (void**)&dw_face1); + assert (dw_face1); + + for (unsigned i = 0; i < count;) + { + UINT16 gids[MAX_GLYPHS]; + INT32 advances[MAX_GLYPHS]; + + unsigned n = hb_min (MAX_GLYPHS, count - i); + + for (unsigned j = 0; j < n; j++) + { + gids[j] = *first_glyph; + advances[j] = 0; + first_glyph = &StructAtOffset<const hb_codepoint_t> (first_glyph, glyph_stride); + } + dw_face1->GetDesignGlyphAdvances (n, gids, advances, true); + for (unsigned j = 0; j < n; j++) + { + *first_advance = -font->em_scale_y (advances[j]); + first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride); + } + + i += n; + } +} + +static hb_bool_t +hb_directwrite_get_glyph_v_origin (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_position_t *x, + hb_position_t *y, + void *user_data HB_UNUSED) +{ + IDWriteFontFace *dw_face = (IDWriteFontFace *) (const void *) font->data.directwrite; + + UINT16 gid = glyph; + DWRITE_GLYPH_METRICS metrics; + + if (FAILED (dw_face->GetDesignGlyphMetrics (&gid, 1, &metrics))) + return false; + + *x = font->em_scale_x (metrics.advanceWidth / 2); + *y = font->em_scale_y (metrics.verticalOriginY); // Untested + + return true; +} +#endif + +static hb_bool_t +hb_directwrite_get_glyph_extents (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents, + void *user_data HB_UNUSED) +{ + IDWriteFontFace *dw_face = (IDWriteFontFace *) (const void *) font->data.directwrite; + + UINT16 gid = glyph; + DWRITE_GLYPH_METRICS metrics; + + if (FAILED (dw_face->GetDesignGlyphMetrics (&gid, 1, &metrics))) + return false; + + extents->x_bearing = font->em_scale_x (metrics.leftSideBearing); + extents->y_bearing = font->em_scale_y (metrics.verticalOriginY - metrics.topSideBearing); + extents->width = font->em_scale_x (metrics.advanceWidth - metrics.rightSideBearing) - extents->x_bearing; + extents->height = font->em_scale_y (metrics.verticalOriginY - metrics.advanceHeight + metrics.bottomSideBearing) - extents->y_bearing; // Magic + + return true; +} + + +#ifndef HB_NO_DRAW + +class GeometrySink : public IDWriteGeometrySink +{ + hb_font_t *font; + hb_draw_session_t drawing; + +public: + GeometrySink(hb_font_t *font, + hb_draw_funcs_t *draw_funcs, + void *draw_data) + : font (font), drawing ({draw_funcs, draw_data, font->slant}) {} + + virtual ~GeometrySink() {} + + HRESULT STDMETHODCALLTYPE Close() override { return S_OK; } + void STDMETHODCALLTYPE SetFillMode(D2D1_FILL_MODE) override {} + void STDMETHODCALLTYPE SetSegmentFlags(D2D1_PATH_SEGMENT) override {} + + IFACEMETHOD(QueryInterface)(REFIID, void **) override { return E_NOINTERFACE; } + IFACEMETHOD_(ULONG, AddRef)() override { return 1; } + IFACEMETHOD_(ULONG, Release)() override { return 1; } + + void STDMETHODCALLTYPE BeginFigure(D2D1_POINT_2F startPoint, D2D1_FIGURE_BEGIN) override + { + drawing.move_to (font->em_scalef_x (startPoint.x), -font->em_scalef_y (startPoint.y)); + } + + void STDMETHODCALLTYPE AddBeziers(const D2D1_BEZIER_SEGMENT *beziers, UINT beziersCount) override + { + for (unsigned i = 0; i < beziersCount; ++i) + drawing.cubic_to (font->em_scalef_x (beziers[i].point1.x), -font->em_scalef_y (beziers[i].point1.y), + font->em_scalef_x (beziers[i].point2.x), -font->em_scalef_y (beziers[i].point2.y), + font->em_scalef_x (beziers[i].point3.x), -font->em_scalef_y (beziers[i].point3.y)); + } + + void STDMETHODCALLTYPE AddLines(const D2D1_POINT_2F *points, UINT pointsCount) override + { + for (unsigned i = 0; i < pointsCount; ++i) + drawing.line_to (font->em_scalef_x (points[i].x), -font->em_scalef_y (points[i].y)); + } + + void STDMETHODCALLTYPE EndFigure(D2D1_FIGURE_END) override + { + drawing.close_path (); + } +}; + +static void +hb_directwrite_draw_glyph (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data) +{ + IDWriteFontFace *dw_face = (IDWriteFontFace *) (const void *) font->data.directwrite; + + GeometrySink sink (font, draw_funcs, draw_data); + UINT16 gid = static_cast<UINT16>(glyph); + unsigned upem = font->face->get_upem(); + + (void) dw_face->GetGlyphRunOutline (upem, + &gid, nullptr, nullptr, + 1, + false, false, + &sink); +} + +#endif + +static inline void free_static_directwrite_funcs (); + +static struct hb_directwrite_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_directwrite_font_funcs_lazy_loader_t> +{ + static hb_font_funcs_t *create () + { + hb_font_funcs_t *funcs = hb_font_funcs_create (); + + hb_font_funcs_set_nominal_glyphs_func (funcs, hb_directwrite_get_nominal_glyphs, nullptr, nullptr); + //hb_font_funcs_set_variation_glyph_func (funcs, hb_directwrite_get_variation_glyph, nullptr, nullptr); + + hb_font_funcs_set_font_h_extents_func (funcs, hb_directwrite_get_font_h_extents, nullptr, nullptr); + hb_font_funcs_set_glyph_h_advances_func (funcs, hb_directwrite_get_glyph_h_advances, nullptr, nullptr); + +#ifndef HB_NO_VERTICAL + hb_font_funcs_set_glyph_v_advances_func (funcs, hb_directwrite_get_glyph_v_advances, nullptr, nullptr); + hb_font_funcs_set_glyph_v_origin_func (funcs, hb_directwrite_get_glyph_v_origin, nullptr, nullptr); +#endif + +#ifndef HB_NO_DRAW + hb_font_funcs_set_draw_glyph_func (funcs, hb_directwrite_draw_glyph, nullptr, nullptr); +#endif + + hb_font_funcs_set_glyph_extents_func (funcs, hb_directwrite_get_glyph_extents, nullptr, nullptr); + +#ifndef HB_NO_OT_FONT_GLYPH_NAMES + //hb_font_funcs_set_glyph_name_func (funcs, hb_directwrite_get_glyph_name, nullptr, nullptr); + //hb_font_funcs_set_glyph_from_name_func (funcs, hb_directwrite_get_glyph_from_name, nullptr, nullptr); +#endif + + hb_font_funcs_make_immutable (funcs); + + hb_atexit (free_static_directwrite_funcs); + + return funcs; + } +} static_directwrite_funcs; + +static inline +void free_static_directwrite_funcs () +{ + static_directwrite_funcs.free_instance (); +} + +static hb_font_funcs_t * +_hb_directwrite_get_font_funcs () +{ + return static_directwrite_funcs.get_unconst (); +} + +/** + * hb_directwrite_font_set_funcs: + * @font: #hb_font_t to work upon + * + * Configures the font-functions structure of the specified + * #hb_font_t font object to use DirectWrite font functions. + * + * In particular, you can use this function to configure an + * existing #hb_face_t face object for use with DirectWrite font + * functions even if that #hb_face_t face object was initially + * created with hb_face_create(), and therefore was not + * initially configured to use DirectWrite font functions. + * + * <note>Note: Internally, this function creates a DirectWrite font. + * </note> + * + * Since: 11.0.0 + **/ +void +hb_directwrite_font_set_funcs (hb_font_t *font) +{ + IDWriteFontFace *dw_face = (IDWriteFontFace *) (const void *) font->data.directwrite; + if (unlikely (!dw_face)) + { + hb_font_set_funcs (font, + hb_font_funcs_get_empty (), + nullptr, nullptr); + return; + } + + dw_face->AddRef (); + hb_font_set_funcs (font, + _hb_directwrite_get_font_funcs (), + nullptr, nullptr); +} + +#undef MAX_GLYPHS + +#endif diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite-shape.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite-shape.cc new file mode 100644 index 0000000000000000000000000000000000000000..485075e64644f96b8721b65bfcec0a8567399b83 --- /dev/null +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite-shape.cc @@ -0,0 +1,656 @@ +/* + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#ifdef HAVE_DIRECTWRITE + +#include "hb-shaper-impl.hh" + +#include "hb-directwrite.hh" + +#include "hb-ms-feature-ranges.hh" + + +/* +* shaper face data +*/ + +hb_directwrite_face_data_t * +_hb_directwrite_shaper_face_data_create (hb_face_t *face) +{ + hb_blob_t *blob = hb_face_reference_blob (face); + + hb_directwrite_face_data_t *data = (hb_directwrite_face_data_t *) dw_face_create (blob, face->index); + + hb_blob_destroy (blob); + + return data; +} + +void +_hb_directwrite_shaper_face_data_destroy (hb_directwrite_face_data_t *data) +{ + ((IDWriteFontFace *) data)->Release (); +} + + +/* + * shaper font data + */ + +struct hb_directwrite_font_data_t {}; + +hb_directwrite_font_data_t * +_hb_directwrite_shaper_font_data_create (hb_font_t *font) +{ + IDWriteFontFace *fontFace = (IDWriteFontFace *) (const void *) font->face->data.directwrite; + + /* + * Set up variations. + */ + IDWriteFontFace5 *fontFaceVariations = nullptr; + { + IDWriteFontFace5 *fontFace5; + if (SUCCEEDED (fontFace->QueryInterface (__uuidof (IDWriteFontFace5), (void **) &fontFace5))) + { + IDWriteFontResource *fontResource; + if (SUCCEEDED (fontFace5->GetFontResource (&fontResource))) + { + hb_vector_t<DWRITE_FONT_AXIS_VALUE> axis_values; + if (likely (axis_values.resize_exact (font->num_coords))) + { + for (unsigned int i = 0; i < font->num_coords; i++) + { + hb_ot_var_axis_info_t info; + unsigned int c = 1; + hb_ot_var_get_axis_infos (font->face, i, &c, &info); + axis_values[i].axisTag = (DWRITE_FONT_AXIS_TAG) hb_uint32_swap (info.tag); + axis_values[i].value = i < font->num_coords ? + hb_clamp (font->design_coords[i], info.min_value, info.max_value) : + info.default_value; + } + + fontResource->CreateFontFace (DWRITE_FONT_SIMULATIONS::DWRITE_FONT_SIMULATIONS_NONE, + axis_values.arrayZ, axis_values.length, &fontFaceVariations); + } + fontResource->Release (); + } + fontFace5->Release (); + } + } + + return (hb_directwrite_font_data_t *) fontFaceVariations; +} + +void +_hb_directwrite_shaper_font_data_destroy (hb_directwrite_font_data_t *data) +{ + ((IDWriteFontFace *) data)->Release (); +} + + +// Most of TextAnalysis is originally written by Bas Schouten for Mozilla project +// but now is relicensed to MIT for HarfBuzz use +class TextAnalysis : public IDWriteTextAnalysisSource, public IDWriteTextAnalysisSink +{ +private: + hb_reference_count_t mRefCount; +public: + IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject) + { return S_OK; } + IFACEMETHOD_ (ULONG, AddRef) () + { + return mRefCount.inc () + 1; + } + IFACEMETHOD_ (ULONG, Release) () + { + signed refCount = mRefCount.dec () - 1; + assert (refCount >= 0); + if (refCount) + return refCount; + delete this; + return 0; + } + + // A single contiguous run of characters containing the same analysis + // results. + struct Run + { + uint32_t mTextStart; // starting text position of this run + uint32_t mTextLength; // number of contiguous code units covered + uint32_t mGlyphStart; // starting glyph in the glyphs array + uint32_t mGlyphCount; // number of glyphs associated with this run + // text + DWRITE_SCRIPT_ANALYSIS mScript; + uint8_t mBidiLevel; + bool mIsSideways; + + bool ContainsTextPosition (uint32_t aTextPosition) const + { + return aTextPosition >= mTextStart && + aTextPosition < mTextStart + mTextLength; + } + + Run *nextRun; + }; + +public: + TextAnalysis (const wchar_t* text, uint32_t textLength, + const wchar_t* localeName, DWRITE_READING_DIRECTION readingDirection) + : mTextLength (textLength), mText (text), mLocaleName (localeName), + mReadingDirection (readingDirection), mCurrentRun (nullptr) + { + mRefCount.init (); + } + virtual ~TextAnalysis () + { + // delete runs, except mRunHead which is part of the TextAnalysis object + for (Run *run = mRunHead.nextRun; run;) + { + Run *origRun = run; + run = run->nextRun; + delete origRun; + } + } + + STDMETHODIMP + GenerateResults (IDWriteTextAnalyzer* textAnalyzer, Run **runHead) + { + // Analyzes the text using the script analyzer and returns + // the result as a series of runs. + + HRESULT hr = S_OK; + + // Initially start out with one result that covers the entire range. + // This result will be subdivided by the analysis processes. + mRunHead.mTextStart = 0; + mRunHead.mTextLength = mTextLength; + mRunHead.mBidiLevel = + (mReadingDirection == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT); + mRunHead.nextRun = nullptr; + mCurrentRun = &mRunHead; + + // Call each of the analyzers in sequence, recording their results. + if (SUCCEEDED (hr = textAnalyzer->AnalyzeScript (this, 0, mTextLength, this))) + *runHead = &mRunHead; + + return hr; + } + + // IDWriteTextAnalysisSource implementation + + IFACEMETHODIMP + GetTextAtPosition (uint32_t textPosition, + OUT wchar_t const** textString, + OUT uint32_t* textLength) + { + if (textPosition >= mTextLength) + { + // No text at this position, valid query though. + *textString = nullptr; + *textLength = 0; + } + else + { + *textString = mText + textPosition; + *textLength = mTextLength - textPosition; + } + return S_OK; + } + + IFACEMETHODIMP + GetTextBeforePosition (uint32_t textPosition, + OUT wchar_t const** textString, + OUT uint32_t* textLength) + { + if (textPosition == 0 || textPosition > mTextLength) + { + // Either there is no text before here (== 0), or this + // is an invalid position. The query is considered valid though. + *textString = nullptr; + *textLength = 0; + } + else + { + *textString = mText; + *textLength = textPosition; + } + return S_OK; + } + + IFACEMETHODIMP_ (DWRITE_READING_DIRECTION) + GetParagraphReadingDirection () { return mReadingDirection; } + + IFACEMETHODIMP GetLocaleName (uint32_t textPosition, uint32_t* textLength, + wchar_t const** localeName) + { return S_OK; } + + IFACEMETHODIMP + GetNumberSubstitution (uint32_t textPosition, + OUT uint32_t* textLength, + OUT IDWriteNumberSubstitution** numberSubstitution) + { + // We do not support number substitution. + *numberSubstitution = nullptr; + *textLength = mTextLength - textPosition; + + return S_OK; + } + + // IDWriteTextAnalysisSink implementation + + IFACEMETHODIMP + SetScriptAnalysis (uint32_t textPosition, uint32_t textLength, + DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis) + { + SetCurrentRun (textPosition); + SplitCurrentRun (textPosition); + while (textLength > 0) + { + Run *run = FetchNextRun (&textLength); + run->mScript = *scriptAnalysis; + } + + return S_OK; + } + + IFACEMETHODIMP + SetLineBreakpoints (uint32_t textPosition, + uint32_t textLength, + const DWRITE_LINE_BREAKPOINT* lineBreakpoints) + { return S_OK; } + + IFACEMETHODIMP SetBidiLevel (uint32_t textPosition, uint32_t textLength, + uint8_t explicitLevel, uint8_t resolvedLevel) + { return S_OK; } + + IFACEMETHODIMP + SetNumberSubstitution (uint32_t textPosition, uint32_t textLength, + IDWriteNumberSubstitution* numberSubstitution) + { return S_OK; } + +protected: + Run *FetchNextRun (IN OUT uint32_t* textLength) + { + // Used by the sink setters, this returns a reference to the next run. + // Position and length are adjusted to now point after the current run + // being returned. + + Run *origRun = mCurrentRun; + // Split the tail if needed (the length remaining is less than the + // current run's size). + if (*textLength < mCurrentRun->mTextLength) + SplitCurrentRun (mCurrentRun->mTextStart + *textLength); + else + // Just advance the current run. + mCurrentRun = mCurrentRun->nextRun; + *textLength -= origRun->mTextLength; + + // Return a reference to the run that was just current. + return origRun; + } + + void SetCurrentRun (uint32_t textPosition) + { + // Move the current run to the given position. + // Since the analyzers generally return results in a forward manner, + // this will usually just return early. If not, find the + // corresponding run for the text position. + + if (mCurrentRun && mCurrentRun->ContainsTextPosition (textPosition)) + return; + + for (Run *run = &mRunHead; run; run = run->nextRun) + if (run->ContainsTextPosition (textPosition)) + { + mCurrentRun = run; + return; + } + assert (0); // We should always be able to find the text position in one of our runs + } + + void SplitCurrentRun (uint32_t splitPosition) + { + if (!mCurrentRun) + { + assert (0); // SplitCurrentRun called without current run + // Shouldn't be calling this when no current run is set! + return; + } + // Split the current run. + if (splitPosition <= mCurrentRun->mTextStart) + { + // No need to split, already the start of a run + // or before it. Usually the first. + return; + } + Run *newRun = new Run; + + *newRun = *mCurrentRun; + + // Insert the new run in our linked list. + newRun->nextRun = mCurrentRun->nextRun; + mCurrentRun->nextRun = newRun; + + // Adjust runs' text positions and lengths. + uint32_t splitPoint = splitPosition - mCurrentRun->mTextStart; + newRun->mTextStart += splitPoint; + newRun->mTextLength -= splitPoint; + mCurrentRun->mTextLength = splitPoint; + mCurrentRun = newRun; + } + +protected: + // Input + // (weak references are fine here, since this class is a transient + // stack-based helper that doesn't need to copy data) + uint32_t mTextLength; + const wchar_t* mText; + const wchar_t* mLocaleName; + DWRITE_READING_DIRECTION mReadingDirection; + + // Current processing state. + Run *mCurrentRun; + + // Output is a list of runs starting here + Run mRunHead; +}; + +/* + * shaper + */ + +hb_bool_t +_hb_directwrite_shape (hb_shape_plan_t *shape_plan, + hb_font_t *font, + hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned int num_features) +{ + IDWriteFontFace *fontFace = (IDWriteFontFace *) (const void *) font->data.directwrite; + auto *global = get_directwrite_global (); + if (unlikely (!global)) + return false; + IDWriteFactory *dwriteFactory = global->dwriteFactory; + + IDWriteTextAnalyzer* analyzer; + dwriteFactory->CreateTextAnalyzer (&analyzer); + + unsigned int scratch_size; + hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size); +#define ALLOCATE_ARRAY(Type, name, len) \ + Type *name = (Type *) scratch; \ + do { \ + unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \ + assert (_consumed <= scratch_size); \ + scratch += _consumed; \ + scratch_size -= _consumed; \ + } while (0) + +#define utf16_index() var1.u32 + + ALLOCATE_ARRAY (wchar_t, textString, buffer->len * 2); + + unsigned int chars_len = 0; + for (unsigned int i = 0; i < buffer->len; i++) + { + hb_codepoint_t c = buffer->info[i].codepoint; + buffer->info[i].utf16_index () = chars_len; + if (likely (c <= 0xFFFFu)) + textString[chars_len++] = c; + else if (unlikely (c > 0x10FFFFu)) + textString[chars_len++] = 0xFFFDu; + else + { + textString[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10); + textString[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1u << 10) - 1)); + } + } + + ALLOCATE_ARRAY (WORD, log_clusters, chars_len); + /* Need log_clusters to assign features. */ + chars_len = 0; + for (unsigned int i = 0; i < buffer->len; i++) + { + hb_codepoint_t c = buffer->info[i].codepoint; + unsigned int cluster = buffer->info[i].cluster; + log_clusters[chars_len++] = cluster; + if (hb_in_range (c, 0x10000u, 0x10FFFFu)) + log_clusters[chars_len++] = cluster; /* Surrogates. */ + } + + DWRITE_READING_DIRECTION readingDirection; + readingDirection = buffer->props.direction ? + DWRITE_READING_DIRECTION_RIGHT_TO_LEFT : + DWRITE_READING_DIRECTION_LEFT_TO_RIGHT; + + /* + * There's an internal 16-bit limit on some things inside the analyzer, + * but we never attempt to shape a word longer than 64K characters + * in a single gfxShapedWord, so we cannot exceed that limit. + */ + uint32_t textLength = chars_len; + + TextAnalysis analysis (textString, textLength, nullptr, readingDirection); + TextAnalysis::Run *runHead; + HRESULT hr; + hr = analysis.GenerateResults (analyzer, &runHead); + +#define FAIL(...) \ + HB_STMT_START { \ + DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \ + return false; \ + } HB_STMT_END + + if (FAILED (hr)) + FAIL ("Analyzer failed to generate results."); + + uint32_t maxGlyphCount = 3 * textLength / 2 + 16; + uint32_t glyphCount; + bool isRightToLeft = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); + + const wchar_t localeName[20] = {0}; + if (buffer->props.language) + mbstowcs ((wchar_t*) localeName, + hb_language_to_string (buffer->props.language), 20); + + /* + * Set up features. + */ + static_assert ((sizeof (DWRITE_TYPOGRAPHIC_FEATURES) == sizeof (hb_ms_features_t)), ""); + static_assert ((sizeof (DWRITE_FONT_FEATURE) == sizeof (hb_ms_feature_t)), ""); + hb_vector_t<hb_ms_features_t *> range_features; + hb_vector_t<uint32_t> range_char_counts; + + // https://github.com/harfbuzz/harfbuzz/pull/5114 + // The data allocated by these two vectors are used by the above two, so they + // should remain alive as long as the above two are. + hb_vector_t<hb_ms_feature_t> feature_records; + hb_vector_t<hb_ms_range_record_t> range_records; + if (num_features) + { + if (hb_ms_setup_features (features, num_features, feature_records, range_records)) + { + hb_ms_make_feature_ranges (feature_records, + range_records, + 0, + chars_len, + log_clusters, + range_features, + range_char_counts); + } + } + + uint16_t* clusterMap; + clusterMap = new uint16_t[textLength]; + DWRITE_SHAPING_TEXT_PROPERTIES* textProperties; + textProperties = new DWRITE_SHAPING_TEXT_PROPERTIES[textLength]; + +retry_getglyphs: + uint16_t* glyphIndices = new uint16_t[maxGlyphCount]; + DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProperties; + glyphProperties = new DWRITE_SHAPING_GLYPH_PROPERTIES[maxGlyphCount]; + + hr = analyzer->GetGlyphs (textString, + chars_len, + fontFace, + false, + isRightToLeft, + &runHead->mScript, + localeName, + nullptr, + (const DWRITE_TYPOGRAPHIC_FEATURES**) range_features.arrayZ, + range_char_counts.arrayZ, + range_features.length, + maxGlyphCount, + clusterMap, + textProperties, + glyphIndices, + glyphProperties, + &glyphCount); + + if (unlikely (hr == HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER))) + { + delete [] glyphIndices; + delete [] glyphProperties; + + maxGlyphCount *= 2; + + goto retry_getglyphs; + } + if (FAILED (hr)) + FAIL ("Analyzer failed to get glyphs."); + + float* glyphAdvances = new float[maxGlyphCount]; + DWRITE_GLYPH_OFFSET* glyphOffsets = new DWRITE_GLYPH_OFFSET[maxGlyphCount]; + + /* The -2 in the following is to compensate for possible + * alignment needed after the WORD array. sizeof (WORD) == 2. */ + unsigned int glyphs_size = (scratch_size * sizeof (int) - 2) + / (sizeof (WORD) + + sizeof (DWRITE_SHAPING_GLYPH_PROPERTIES) + + sizeof (int) + + sizeof (DWRITE_GLYPH_OFFSET) + + sizeof (uint32_t)); + ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size); + +#undef ALLOCATE_ARRAY + + unsigned fontEmSize = font->face->get_upem (); + + float x_mult = font->x_multf; + float y_mult = font->y_multf; + + hr = analyzer->GetGlyphPlacements (textString, + clusterMap, + textProperties, + chars_len, + glyphIndices, + glyphProperties, + glyphCount, + fontFace, + fontEmSize, + false, + isRightToLeft, + &runHead->mScript, + localeName, + (const DWRITE_TYPOGRAPHIC_FEATURES**) range_features.arrayZ, + range_char_counts.arrayZ, + range_features.length, + glyphAdvances, + glyphOffsets); + + if (FAILED (hr)) + FAIL ("Analyzer failed to get glyph placements."); + + /* Ok, we've got everything we need, now compose output buffer, + * very, *very*, carefully! */ + + /* Calculate visual-clusters. That's what we ship. */ + for (unsigned int i = 0; i < glyphCount; i++) + vis_clusters[i] = (uint32_t) -1; + for (unsigned int i = 0; i < buffer->len; i++) + { + uint32_t *p = + &vis_clusters[log_clusters[buffer->info[i].utf16_index ()]]; + *p = hb_min (*p, buffer->info[i].cluster); + } + for (unsigned int i = 1; i < glyphCount; i++) + if (vis_clusters[i] == (uint32_t) -1) + vis_clusters[i] = vis_clusters[i - 1]; + +#undef utf16_index + + if (unlikely (!buffer->ensure (glyphCount))) + FAIL ("Buffer in error"); + +#undef FAIL + + /* Set glyph infos */ + buffer->len = 0; + for (unsigned int i = 0; i < glyphCount; i++) + { + hb_glyph_info_t *info = &buffer->info[buffer->len++]; + + info->codepoint = glyphIndices[i]; + info->cluster = vis_clusters[i]; + + /* The rest is crap. Let's store position info there for now. */ + info->mask = glyphAdvances[i]; + info->var1.i32 = glyphOffsets[i].advanceOffset; + info->var2.i32 = glyphOffsets[i].ascenderOffset; + } + + /* Set glyph positions */ + buffer->clear_positions (); + for (unsigned int i = 0; i < glyphCount; i++) + { + hb_glyph_info_t *info = &buffer->info[i]; + hb_glyph_position_t *pos = &buffer->pos[i]; + + /* TODO vertical */ + pos->x_advance = round (x_mult * (int32_t) info->mask); + pos->x_offset = round (x_mult * (isRightToLeft ? -info->var1.i32 : info->var1.i32)); + pos->y_offset = round (y_mult * info->var2.i32); + } + + if (isRightToLeft) hb_buffer_reverse (buffer); + + buffer->clear_glyph_flags (); + buffer->unsafe_to_break (); + + delete [] clusterMap; + delete [] glyphIndices; + delete [] textProperties; + delete [] glyphProperties; + delete [] glyphAdvances; + delete [] glyphOffsets; + + /* Wow, done! */ + return true; +} + + +#endif diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc index 5b191262a2382ab39133406bc2eec9e4d9ef393f..9c4bab95df59420de45193661a0a5cbc8acbfb90 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc @@ -26,14 +26,10 @@ #ifdef HAVE_DIRECTWRITE -#include "hb-shaper-impl.hh" +#include "hb-directwrite.hh" -#include <dwrite_1.h> -#include <dwrite_3.h> +#include "hb-font.hh" -#include "hb-directwrite.h" - -#include "hb-ms-feature-ranges.hh" /** * SECTION:hb-directwrite @@ -44,173 +40,89 @@ * Functions for using HarfBuzz with DirectWrite fonts. **/ -/* Declare object creator for dynamic support of DWRITE */ -typedef HRESULT (WINAPI *t_DWriteCreateFactory)( - DWRITE_FACTORY_TYPE factoryType, - REFIID iid, - IUnknown **factory -); - - -/* - * DirectWrite font stream helpers - */ +static inline void free_static_directwrite_global (); -// This is a font loader which provides only one font (unlike its original design). -// For a better implementation which was also source of this -// and DWriteFontFileStream, have a look at to NativeFontResourceDWrite.cpp in Mozilla -class DWriteFontFileLoader : public IDWriteFontFileLoader +static struct hb_directwrite_global_lazy_loader_t : hb_lazy_loader_t<hb_directwrite_global_t, + hb_directwrite_global_lazy_loader_t> { -private: - IDWriteFontFileStream *mFontFileStream; -public: - DWriteFontFileLoader (IDWriteFontFileStream *fontFileStream) - { mFontFileStream = fontFileStream; } - - // IUnknown interface - IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject) - { return S_OK; } - IFACEMETHOD_ (ULONG, AddRef) () { return 1; } - IFACEMETHOD_ (ULONG, Release) () { return 1; } - - // IDWriteFontFileLoader methods - virtual HRESULT STDMETHODCALLTYPE - CreateStreamFromKey (void const* fontFileReferenceKey, - uint32_t fontFileReferenceKeySize, - OUT IDWriteFontFileStream** fontFileStream) + static hb_directwrite_global_t * create () { - *fontFileStream = mFontFileStream; - return S_OK; - } + hb_directwrite_global_t *global = new hb_directwrite_global_t; - virtual ~DWriteFontFileLoader() {} -}; + if (unlikely (!global)) + return nullptr; + if (unlikely (!global->success)) + { + delete global; + return nullptr; + } -class DWriteFontFileStream : public IDWriteFontFileStream -{ -private: - uint8_t *mData; - uint32_t mSize; -public: - DWriteFontFileStream (uint8_t *aData, uint32_t aSize) - { - mData = aData; - mSize = aSize; - } + hb_atexit (free_static_directwrite_global); - // IUnknown interface - IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject) - { return S_OK; } - IFACEMETHOD_ (ULONG, AddRef) () { return 1; } - IFACEMETHOD_ (ULONG, Release) () { return 1; } - - // IDWriteFontFileStream methods - virtual HRESULT STDMETHODCALLTYPE - ReadFileFragment (void const** fragmentStart, - UINT64 fileOffset, - UINT64 fragmentSize, - OUT void** fragmentContext) + return global; + } + static void destroy (hb_directwrite_global_t *l) { - // We are required to do bounds checking. - if (fileOffset + fragmentSize > mSize) return E_FAIL; - - // truncate the 64 bit fileOffset to size_t sized index into mData - size_t index = static_cast<size_t> (fileOffset); - - // We should be alive for the duration of this. - *fragmentStart = &mData[index]; - *fragmentContext = nullptr; - return S_OK; + delete l; } - - virtual void STDMETHODCALLTYPE - ReleaseFileFragment (void* fragmentContext) {} - - virtual HRESULT STDMETHODCALLTYPE - GetFileSize (OUT UINT64* fileSize) + static hb_directwrite_global_t * get_null () { - *fileSize = mSize; - return S_OK; + return nullptr; } +} static_directwrite_global; - virtual HRESULT STDMETHODCALLTYPE - GetLastWriteTime (OUT UINT64* lastWriteTime) { return E_NOTIMPL; } - - virtual ~DWriteFontFileStream() {} -}; +static inline +void free_static_directwrite_global () +{ + static_directwrite_global.free_instance (); +} -/* -* shaper face data -*/ +hb_directwrite_global_t * +get_directwrite_global () +{ + return static_directwrite_global.get_unconst (); +} -struct hb_directwrite_face_data_t +DWriteFontFileStream::DWriteFontFileStream (hb_blob_t *blob) { - HMODULE dwrite_dll; - IDWriteFactory *dwriteFactory; - IDWriteFontFile *fontFile; - DWriteFontFileStream *fontFileStream; - DWriteFontFileLoader *fontFileLoader; - IDWriteFontFace *fontFace; - hb_blob_t *faceBlob; -}; + auto *global = get_directwrite_global (); + mLoader = global->fontFileLoader; + mRefCount.init (); + mLoader->AddRef (); + hb_blob_make_immutable (blob); + mBlob = hb_blob_reference (blob); + mData = (uint8_t *) hb_blob_get_data (blob, &mSize); + fontFileKey = mLoader->RegisterFontFileStream (this); +} -hb_directwrite_face_data_t * -_hb_directwrite_shaper_face_data_create (hb_face_t *face) +DWriteFontFileStream::~DWriteFontFileStream() { - hb_directwrite_face_data_t *data = new hb_directwrite_face_data_t; - if (unlikely (!data)) - return nullptr; + mLoader->UnregisterFontFileStream (fontFileKey); + mLoader->Release (); + hb_blob_destroy (mBlob); +} +IDWriteFontFace * +dw_face_create (hb_blob_t *blob, unsigned index) +{ #define FAIL(...) \ HB_STMT_START { \ DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \ return nullptr; \ } HB_STMT_END - data->dwrite_dll = LoadLibrary (TEXT ("DWRITE")); - if (unlikely (!data->dwrite_dll)) - FAIL ("Cannot find DWrite.DLL"); - - t_DWriteCreateFactory p_DWriteCreateFactory; - -#if defined(__GNUC__) || defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-function-type" -#endif - - p_DWriteCreateFactory = (t_DWriteCreateFactory) - GetProcAddress (data->dwrite_dll, "DWriteCreateFactory"); - -#if defined(__GNUC__) || defined(__clang__) -#pragma GCC diagnostic pop -#endif + auto *global = get_directwrite_global (); + if (unlikely (!global)) + FAIL ("Couldn't load DirectWrite!"); - if (unlikely (!p_DWriteCreateFactory)) - FAIL ("Cannot find DWriteCreateFactory()."); - - HRESULT hr; - - // TODO: factory and fontFileLoader should be cached separately - IDWriteFactory* dwriteFactory; - hr = p_DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), - (IUnknown**) &dwriteFactory); - - if (unlikely (hr != S_OK)) - FAIL ("Failed to run DWriteCreateFactory()."); - - hb_blob_t *blob = hb_face_reference_blob (face); - DWriteFontFileStream *fontFileStream; - fontFileStream = new DWriteFontFileStream ((uint8_t *) hb_blob_get_data (blob, nullptr), - hb_blob_get_length (blob)); - - DWriteFontFileLoader *fontFileLoader = new DWriteFontFileLoader (fontFileStream); - dwriteFactory->RegisterFontFileLoader (fontFileLoader); + DWriteFontFileStream *fontFileStream = new DWriteFontFileStream (blob); IDWriteFontFile *fontFile; - uint64_t fontFileKey = 0; - hr = dwriteFactory->CreateCustomFontFileReference (&fontFileKey, sizeof (fontFileKey), - fontFileLoader, &fontFile); + auto hr = global->dwriteFactory->CreateCustomFontFileReference (&fontFileStream->fontFileKey, sizeof (fontFileStream->fontFileKey), + global->fontFileLoader, &fontFile); + + fontFileStream->Release (); if (FAILED (hr)) FAIL ("Failed to load font file from data!"); @@ -221,585 +133,19 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face) uint32_t numberOfFaces; hr = fontFile->Analyze (&isSupported, &fileType, &faceType, &numberOfFaces); if (FAILED (hr) || !isSupported) - FAIL ("Font file is not supported."); - -#undef FAIL - - IDWriteFontFace *fontFace; - dwriteFactory->CreateFontFace (faceType, 1, &fontFile, 0, - DWRITE_FONT_SIMULATIONS_NONE, &fontFace); - - data->dwriteFactory = dwriteFactory; - data->fontFile = fontFile; - data->fontFileStream = fontFileStream; - data->fontFileLoader = fontFileLoader; - data->fontFace = fontFace; - data->faceBlob = blob; - - return data; -} - -void -_hb_directwrite_shaper_face_data_destroy (hb_directwrite_face_data_t *data) -{ - if (data->fontFace) - data->fontFace->Release (); - if (data->fontFile) - data->fontFile->Release (); - if (data->dwriteFactory) - { - if (data->fontFileLoader) - data->dwriteFactory->UnregisterFontFileLoader (data->fontFileLoader); - data->dwriteFactory->Release (); - } - delete data->fontFileLoader; - delete data->fontFileStream; - hb_blob_destroy (data->faceBlob); - if (data->dwrite_dll) - FreeLibrary (data->dwrite_dll); - delete data; -} - - -/* - * shaper font data - */ - -struct hb_directwrite_font_data_t {}; - -hb_directwrite_font_data_t * -_hb_directwrite_shaper_font_data_create (hb_font_t *font) -{ - return (hb_directwrite_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; -} - -void -_hb_directwrite_shaper_font_data_destroy (hb_directwrite_font_data_t *data) -{ - if (data != HB_SHAPER_DATA_SUCCEEDED) - ((IDWriteFont *) (const void *) data)->Release(); -} - - -// Most of TextAnalysis is originally written by Bas Schouten for Mozilla project -// but now is relicensed to MIT for HarfBuzz use -class TextAnalysis : public IDWriteTextAnalysisSource, public IDWriteTextAnalysisSink -{ -public: - - IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject) - { return S_OK; } - IFACEMETHOD_ (ULONG, AddRef) () { return 1; } - IFACEMETHOD_ (ULONG, Release) () { return 1; } - - // A single contiguous run of characters containing the same analysis - // results. - struct Run - { - uint32_t mTextStart; // starting text position of this run - uint32_t mTextLength; // number of contiguous code units covered - uint32_t mGlyphStart; // starting glyph in the glyphs array - uint32_t mGlyphCount; // number of glyphs associated with this run - // text - DWRITE_SCRIPT_ANALYSIS mScript; - uint8_t mBidiLevel; - bool mIsSideways; - - bool ContainsTextPosition (uint32_t aTextPosition) const - { - return aTextPosition >= mTextStart && - aTextPosition < mTextStart + mTextLength; - } - - Run *nextRun; - }; - -public: - TextAnalysis (const wchar_t* text, uint32_t textLength, - const wchar_t* localeName, DWRITE_READING_DIRECTION readingDirection) - : mTextLength (textLength), mText (text), mLocaleName (localeName), - mReadingDirection (readingDirection), mCurrentRun (nullptr) {} - ~TextAnalysis () - { - // delete runs, except mRunHead which is part of the TextAnalysis object - for (Run *run = mRunHead.nextRun; run;) - { - Run *origRun = run; - run = run->nextRun; - delete origRun; - } - } - - STDMETHODIMP - GenerateResults (IDWriteTextAnalyzer* textAnalyzer, Run **runHead) - { - // Analyzes the text using the script analyzer and returns - // the result as a series of runs. - - HRESULT hr = S_OK; - - // Initially start out with one result that covers the entire range. - // This result will be subdivided by the analysis processes. - mRunHead.mTextStart = 0; - mRunHead.mTextLength = mTextLength; - mRunHead.mBidiLevel = - (mReadingDirection == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT); - mRunHead.nextRun = nullptr; - mCurrentRun = &mRunHead; - - // Call each of the analyzers in sequence, recording their results. - if (SUCCEEDED (hr = textAnalyzer->AnalyzeScript (this, 0, mTextLength, this))) - *runHead = &mRunHead; - - return hr; - } - - // IDWriteTextAnalysisSource implementation - - IFACEMETHODIMP - GetTextAtPosition (uint32_t textPosition, - OUT wchar_t const** textString, - OUT uint32_t* textLength) - { - if (textPosition >= mTextLength) - { - // No text at this position, valid query though. - *textString = nullptr; - *textLength = 0; - } - else - { - *textString = mText + textPosition; - *textLength = mTextLength - textPosition; - } - return S_OK; - } - - IFACEMETHODIMP - GetTextBeforePosition (uint32_t textPosition, - OUT wchar_t const** textString, - OUT uint32_t* textLength) - { - if (textPosition == 0 || textPosition > mTextLength) - { - // Either there is no text before here (== 0), or this - // is an invalid position. The query is considered valid though. - *textString = nullptr; - *textLength = 0; - } - else - { - *textString = mText; - *textLength = textPosition; - } - return S_OK; - } - - IFACEMETHODIMP_ (DWRITE_READING_DIRECTION) - GetParagraphReadingDirection () { return mReadingDirection; } - - IFACEMETHODIMP GetLocaleName (uint32_t textPosition, uint32_t* textLength, - wchar_t const** localeName) - { return S_OK; } - - IFACEMETHODIMP - GetNumberSubstitution (uint32_t textPosition, - OUT uint32_t* textLength, - OUT IDWriteNumberSubstitution** numberSubstitution) - { - // We do not support number substitution. - *numberSubstitution = nullptr; - *textLength = mTextLength - textPosition; - - return S_OK; - } - - // IDWriteTextAnalysisSink implementation - - IFACEMETHODIMP - SetScriptAnalysis (uint32_t textPosition, uint32_t textLength, - DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis) - { - SetCurrentRun (textPosition); - SplitCurrentRun (textPosition); - while (textLength > 0) - { - Run *run = FetchNextRun (&textLength); - run->mScript = *scriptAnalysis; - } - - return S_OK; - } - - IFACEMETHODIMP - SetLineBreakpoints (uint32_t textPosition, - uint32_t textLength, - const DWRITE_LINE_BREAKPOINT* lineBreakpoints) - { return S_OK; } - - IFACEMETHODIMP SetBidiLevel (uint32_t textPosition, uint32_t textLength, - uint8_t explicitLevel, uint8_t resolvedLevel) - { return S_OK; } - - IFACEMETHODIMP - SetNumberSubstitution (uint32_t textPosition, uint32_t textLength, - IDWriteNumberSubstitution* numberSubstitution) - { return S_OK; } - -protected: - Run *FetchNextRun (IN OUT uint32_t* textLength) { - // Used by the sink setters, this returns a reference to the next run. - // Position and length are adjusted to now point after the current run - // being returned. - - Run *origRun = mCurrentRun; - // Split the tail if needed (the length remaining is less than the - // current run's size). - if (*textLength < mCurrentRun->mTextLength) - SplitCurrentRun (mCurrentRun->mTextStart + *textLength); - else - // Just advance the current run. - mCurrentRun = mCurrentRun->nextRun; - *textLength -= origRun->mTextLength; - - // Return a reference to the run that was just current. - return origRun; - } - - void SetCurrentRun (uint32_t textPosition) - { - // Move the current run to the given position. - // Since the analyzers generally return results in a forward manner, - // this will usually just return early. If not, find the - // corresponding run for the text position. - - if (mCurrentRun && mCurrentRun->ContainsTextPosition (textPosition)) - return; - - for (Run *run = &mRunHead; run; run = run->nextRun) - if (run->ContainsTextPosition (textPosition)) - { - mCurrentRun = run; - return; - } - assert (0); // We should always be able to find the text position in one of our runs - } - - void SplitCurrentRun (uint32_t splitPosition) - { - if (!mCurrentRun) - { - assert (0); // SplitCurrentRun called without current run - // Shouldn't be calling this when no current run is set! - return; - } - // Split the current run. - if (splitPosition <= mCurrentRun->mTextStart) - { - // No need to split, already the start of a run - // or before it. Usually the first. - return; - } - Run *newRun = new Run; - - *newRun = *mCurrentRun; - - // Insert the new run in our linked list. - newRun->nextRun = mCurrentRun->nextRun; - mCurrentRun->nextRun = newRun; - - // Adjust runs' text positions and lengths. - uint32_t splitPoint = splitPosition - mCurrentRun->mTextStart; - newRun->mTextStart += splitPoint; - newRun->mTextLength -= splitPoint; - mCurrentRun->mTextLength = splitPoint; - mCurrentRun = newRun; - } - -protected: - // Input - // (weak references are fine here, since this class is a transient - // stack-based helper that doesn't need to copy data) - uint32_t mTextLength; - const wchar_t* mText; - const wchar_t* mLocaleName; - DWRITE_READING_DIRECTION mReadingDirection; - - // Current processing state. - Run *mCurrentRun; - - // Output is a list of runs starting here - Run mRunHead; -}; - -/* - * shaper - */ - -hb_bool_t -_hb_directwrite_shape (hb_shape_plan_t *shape_plan, - hb_font_t *font, - hb_buffer_t *buffer, - const hb_feature_t *features, - unsigned int num_features) -{ - hb_face_t *face = font->face; - const hb_directwrite_face_data_t *face_data = face->data.directwrite; - IDWriteFactory *dwriteFactory = face_data->dwriteFactory; - IDWriteFontFace *fontFace = face_data->fontFace; - - IDWriteTextAnalyzer* analyzer; - dwriteFactory->CreateTextAnalyzer (&analyzer); - - unsigned int scratch_size; - hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size); -#define ALLOCATE_ARRAY(Type, name, len) \ - Type *name = (Type *) scratch; \ - do { \ - unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \ - assert (_consumed <= scratch_size); \ - scratch += _consumed; \ - scratch_size -= _consumed; \ - } while (0) - -#define utf16_index() var1.u32 - - ALLOCATE_ARRAY (wchar_t, textString, buffer->len * 2); - - unsigned int chars_len = 0; - for (unsigned int i = 0; i < buffer->len; i++) - { - hb_codepoint_t c = buffer->info[i].codepoint; - buffer->info[i].utf16_index () = chars_len; - if (likely (c <= 0xFFFFu)) - textString[chars_len++] = c; - else if (unlikely (c > 0x10FFFFu)) - textString[chars_len++] = 0xFFFDu; - else - { - textString[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10); - textString[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1u << 10) - 1)); - } - } - - ALLOCATE_ARRAY (WORD, log_clusters, chars_len); - /* Need log_clusters to assign features. */ - chars_len = 0; - for (unsigned int i = 0; i < buffer->len; i++) - { - hb_codepoint_t c = buffer->info[i].codepoint; - unsigned int cluster = buffer->info[i].cluster; - log_clusters[chars_len++] = cluster; - if (hb_in_range (c, 0x10000u, 0x10FFFFu)) - log_clusters[chars_len++] = cluster; /* Surrogates. */ - } - - DWRITE_READING_DIRECTION readingDirection; - readingDirection = buffer->props.direction ? - DWRITE_READING_DIRECTION_RIGHT_TO_LEFT : - DWRITE_READING_DIRECTION_LEFT_TO_RIGHT; - - /* - * There's an internal 16-bit limit on some things inside the analyzer, - * but we never attempt to shape a word longer than 64K characters - * in a single gfxShapedWord, so we cannot exceed that limit. - */ - uint32_t textLength = chars_len; - - TextAnalysis analysis (textString, textLength, nullptr, readingDirection); - TextAnalysis::Run *runHead; - HRESULT hr; - hr = analysis.GenerateResults (analyzer, &runHead); - -#define FAIL(...) \ - HB_STMT_START { \ - DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \ - return false; \ - } HB_STMT_END - - if (FAILED (hr)) - FAIL ("Analyzer failed to generate results."); - - uint32_t maxGlyphCount = 3 * textLength / 2 + 16; - uint32_t glyphCount; - bool isRightToLeft = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); - - const wchar_t localeName[20] = {0}; - if (buffer->props.language) - mbstowcs ((wchar_t*) localeName, - hb_language_to_string (buffer->props.language), 20); - - /* - * Set up features. - */ - static_assert ((sizeof (DWRITE_TYPOGRAPHIC_FEATURES) == sizeof (hb_ms_features_t)), ""); - static_assert ((sizeof (DWRITE_FONT_FEATURE) == sizeof (hb_ms_feature_t)), ""); - hb_vector_t<hb_ms_features_t *> range_features; - hb_vector_t<uint32_t> range_char_counts; - if (num_features) - { - hb_vector_t<hb_ms_feature_t> feature_records; - hb_vector_t<hb_ms_range_record_t> range_records; - if (hb_ms_setup_features (features, num_features, feature_records, range_records)) - hb_ms_make_feature_ranges (feature_records, - range_records, - 0, - chars_len, - log_clusters, - range_features, - range_char_counts); - } - - uint16_t* clusterMap; - clusterMap = new uint16_t[textLength]; - DWRITE_SHAPING_TEXT_PROPERTIES* textProperties; - textProperties = new DWRITE_SHAPING_TEXT_PROPERTIES[textLength]; - -retry_getglyphs: - uint16_t* glyphIndices = new uint16_t[maxGlyphCount]; - DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProperties; - glyphProperties = new DWRITE_SHAPING_GLYPH_PROPERTIES[maxGlyphCount]; - - hr = analyzer->GetGlyphs (textString, - chars_len, - fontFace, - false, - isRightToLeft, - &runHead->mScript, - localeName, - nullptr, - (const DWRITE_TYPOGRAPHIC_FEATURES**) range_features.arrayZ, - range_char_counts.arrayZ, - range_features.length, - maxGlyphCount, - clusterMap, - textProperties, - glyphIndices, - glyphProperties, - &glyphCount); - - if (unlikely (hr == HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER))) - { - delete [] glyphIndices; - delete [] glyphProperties; - - maxGlyphCount *= 2; - - goto retry_getglyphs; - } - if (FAILED (hr)) - FAIL ("Analyzer failed to get glyphs."); - - float* glyphAdvances = new float[maxGlyphCount]; - DWRITE_GLYPH_OFFSET* glyphOffsets = new DWRITE_GLYPH_OFFSET[maxGlyphCount]; - - /* The -2 in the following is to compensate for possible - * alignment needed after the WORD array. sizeof (WORD) == 2. */ - unsigned int glyphs_size = (scratch_size * sizeof (int) - 2) - / (sizeof (WORD) + - sizeof (DWRITE_SHAPING_GLYPH_PROPERTIES) + - sizeof (int) + - sizeof (DWRITE_GLYPH_OFFSET) + - sizeof (uint32_t)); - ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size); - -#undef ALLOCATE_ARRAY - - int fontEmSize = font->face->get_upem (); - if (fontEmSize < 0) fontEmSize = -fontEmSize; - - if (fontEmSize < 0) fontEmSize = -fontEmSize; - double x_mult = (double) font->x_scale / fontEmSize; - double y_mult = (double) font->y_scale / fontEmSize; - - hr = analyzer->GetGlyphPlacements (textString, - clusterMap, - textProperties, - chars_len, - glyphIndices, - glyphProperties, - glyphCount, - fontFace, - fontEmSize, - false, - isRightToLeft, - &runHead->mScript, - localeName, - (const DWRITE_TYPOGRAPHIC_FEATURES**) range_features.arrayZ, - range_char_counts.arrayZ, - range_features.length, - glyphAdvances, - glyphOffsets); - - if (FAILED (hr)) - FAIL ("Analyzer failed to get glyph placements."); - - /* Ok, we've got everything we need, now compose output buffer, - * very, *very*, carefully! */ - - /* Calculate visual-clusters. That's what we ship. */ - for (unsigned int i = 0; i < glyphCount; i++) - vis_clusters[i] = (uint32_t) -1; - for (unsigned int i = 0; i < buffer->len; i++) - { - uint32_t *p = - &vis_clusters[log_clusters[buffer->info[i].utf16_index ()]]; - *p = hb_min (*p, buffer->info[i].cluster); + fontFile->Release (); + FAIL ("Font file is not supported."); } - for (unsigned int i = 1; i < glyphCount; i++) - if (vis_clusters[i] == (uint32_t) -1) - vis_clusters[i] = vis_clusters[i - 1]; - -#undef utf16_index - - if (unlikely (!buffer->ensure (glyphCount))) - FAIL ("Buffer in error"); #undef FAIL - /* Set glyph infos */ - buffer->len = 0; - for (unsigned int i = 0; i < glyphCount; i++) - { - hb_glyph_info_t *info = &buffer->info[buffer->len++]; - - info->codepoint = glyphIndices[i]; - info->cluster = vis_clusters[i]; - - /* The rest is crap. Let's store position info there for now. */ - info->mask = glyphAdvances[i]; - info->var1.i32 = glyphOffsets[i].advanceOffset; - info->var2.i32 = glyphOffsets[i].ascenderOffset; - } - - /* Set glyph positions */ - buffer->clear_positions (); - for (unsigned int i = 0; i < glyphCount; i++) - { - hb_glyph_info_t *info = &buffer->info[i]; - hb_glyph_position_t *pos = &buffer->pos[i]; - - /* TODO vertical */ - pos->x_advance = x_mult * (int32_t) info->mask; - pos->x_offset = x_mult * (isRightToLeft ? -info->var1.i32 : info->var1.i32); - pos->y_offset = y_mult * info->var2.i32; - } + IDWriteFontFace *fontFace = nullptr; + global->dwriteFactory->CreateFontFace (faceType, 1, &fontFile, index, + DWRITE_FONT_SIMULATIONS_NONE, &fontFace); + fontFile->Release (); - if (isRightToLeft) hb_buffer_reverse (buffer); - - buffer->clear_glyph_flags (); - buffer->unsafe_to_break (); - - delete [] clusterMap; - delete [] glyphIndices; - delete [] textProperties; - delete [] glyphProperties; - delete [] glyphAdvances; - delete [] glyphOffsets; - - /* Wow, done! */ - return true; + return fontFace; } struct _hb_directwrite_font_table_context { @@ -823,8 +169,8 @@ _hb_directwrite_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void * uint32_t length; void *table_context; BOOL exists; - if (!dw_face || FAILED (dw_face->TryGetFontTable (hb_uint32_swap (tag), &data, - &length, &table_context, &exists))) + if (FAILED (dw_face->TryGetFontTable (hb_uint32_swap (tag), &data, + &length, &table_context, &exists))) return nullptr; if (!data || !exists || !length) @@ -834,6 +180,11 @@ _hb_directwrite_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void * } _hb_directwrite_font_table_context *context = (_hb_directwrite_font_table_context *) hb_malloc (sizeof (_hb_directwrite_font_table_context)); + if (unlikely (!context)) + { + dw_face->ReleaseFontTable (table_context); + return nullptr; + } context->face = dw_face; context->table_context = table_context; @@ -844,8 +195,7 @@ _hb_directwrite_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void * static void _hb_directwrite_face_release (void *data) { - if (data) - ((IDWriteFontFace *) data)->Release (); + ((IDWriteFontFace *) data)->Release (); } /** @@ -861,10 +211,82 @@ _hb_directwrite_face_release (void *data) hb_face_t * hb_directwrite_face_create (IDWriteFontFace *dw_face) { - if (dw_face) - dw_face->AddRef (); - return hb_face_create_for_tables (_hb_directwrite_reference_table, dw_face, - _hb_directwrite_face_release); + if (!dw_face) + return hb_face_get_empty (); + + dw_face->AddRef (); + hb_face_t *face = hb_face_create_for_tables (_hb_directwrite_reference_table, + dw_face, + _hb_directwrite_face_release); + + hb_face_set_index (face, dw_face->GetIndex ()); + hb_face_set_glyph_count (face, dw_face->GetGlyphCount ()); + + return face; +} + +/** + * hb_directwrite_face_create_from_file_or_fail: + * @file_name: A font filename + * @index: The index of the face within the file + * + * Creates an #hb_face_t face object from the specified + * font file and face index. + * + * This is similar in functionality to hb_face_create_from_file_or_fail(), + * but uses the DirectWrite library for loading the font file. + * + * Return value: (transfer full): The new face object, or `NULL` if + * no face is found at the specified index or the file cannot be read. + * + * Since: 11.0.0 + */ +hb_face_t * +hb_directwrite_face_create_from_file_or_fail (const char *file_name, + unsigned int index) +{ + auto *blob = hb_blob_create_from_file_or_fail (file_name); + if (unlikely (!blob)) + return nullptr; + + return hb_directwrite_face_create_from_blob_or_fail (blob, index); +} + +/** + * hb_directwrite_face_create_from_blob_or_fail: + * @blob: A blob containing the font data + * @index: The index of the face within the blob + * + * Creates an #hb_face_t face object from the specified + * blob and face index. + * + * This is similar in functionality to hb_face_create_from_blob_or_fail(), + * but uses the DirectWrite library for loading the font data. + * + * Return value: (transfer full): The new face object, or `NULL` if + * no face is found at the specified index or the blob cannot be read. + * + * Since: 11.0.0 + */ +HB_EXTERN hb_face_t * +hb_directwrite_face_create_from_blob_or_fail (hb_blob_t *blob, + unsigned int index) +{ + IDWriteFontFace *dw_face = dw_face_create (blob, index); + if (unlikely (!dw_face)) + return nullptr; + + hb_face_t *face = hb_directwrite_face_create (dw_face); + if (unlikely (hb_object_is_immutable (face))) + { + dw_face->Release (); + return face; + } + + /* Let there be dragons here... */ + face->data.directwrite.cmpexch (nullptr, (hb_directwrite_face_data_t *) dw_face); + + return face; } /** @@ -880,7 +302,7 @@ hb_directwrite_face_create (IDWriteFontFace *dw_face) IDWriteFontFace * hb_directwrite_face_get_dw_font_face (hb_face_t *face) { - return face->data.directwrite->fontFace; + return (IDWriteFontFace *) (const void *) face->data.directwrite; } #ifndef HB_DISABLE_DEPRECATED @@ -906,29 +328,25 @@ hb_directwrite_face_get_font_face (hb_face_t *face) /** * hb_directwrite_font_create: - * @dw_font: a DirectWrite IDWriteFont object. + * @dw_face: a DirectWrite IDWriteFontFace object. * - * Constructs a new font object from the specified DirectWrite IDWriteFont. + * Constructs a new font object from the specified DirectWrite IDWriteFontFace. * * Return value: #hb_font_t object corresponding to the given input * - * Since: 10.3.0 + * Since: 11.0.0 **/ hb_font_t * -hb_directwrite_font_create (IDWriteFont *dw_font) +hb_directwrite_font_create (IDWriteFontFace *dw_face) { - IDWriteFontFace *dw_face = nullptr; IDWriteFontFace5 *dw_face5 = nullptr; - if (FAILED (dw_font->CreateFontFace (&dw_face))) - return hb_font_get_empty (); - hb_face_t *face = hb_directwrite_face_create (dw_face); hb_font_t *font = hb_font_create (face); hb_face_destroy (face); if (unlikely (hb_object_is_immutable (font))) - goto done; + return font; /* Copy font variations */ if (SUCCEEDED (dw_face->QueryInterface (__uuidof (IDWriteFontFace5), (void**) &dw_face5))) @@ -945,7 +363,7 @@ hb_directwrite_font_create (IDWriteFont *dw_font) { for (uint32_t i = 0; i < count; ++i) { - hb_tag_t tag = values[i].axisTag; + hb_tag_t tag = hb_uint32_swap (values[i].axisTag); float value = values[i].value; vars[i] = {tag, value}; } @@ -956,28 +374,45 @@ hb_directwrite_font_create (IDWriteFont *dw_font) dw_face5->Release (); } - dw_font->AddRef (); - font->data.directwrite.cmpexch (nullptr, (hb_directwrite_font_data_t *) dw_font); + /* Let there be dragons here... */ + dw_face->AddRef (); + font->data.directwrite.cmpexch (nullptr, (hb_directwrite_font_data_t *) dw_face); -done: - dw_face->Release (); return font; } +/** +* hb_directwrite_font_get_dw_font_face: +* @font: a #hb_font_t object +* +* Gets the DirectWrite IDWriteFontFace associated with @font. +* +* Return value: DirectWrite IDWriteFontFace object corresponding to the given input +* +* Since: 11.0.0 +**/ +IDWriteFontFace * +hb_directwrite_font_get_dw_font_face (hb_font_t *font) +{ + return (IDWriteFontFace *) (const void *) font->data.directwrite; +} + + /** * hb_directwrite_font_get_dw_font: * @font: a #hb_font_t object * -* Gets the DirectWrite IDWriteFont associated with @font. +* Deprecated. * -* Return value: DirectWrite IDWriteFont object corresponding to the given input +* Return value: Returns `NULL`. * * Since: 10.3.0 +* Deprecated: 11.0.0: **/ IDWriteFont * hb_directwrite_font_get_dw_font (hb_font_t *font) { - return (IDWriteFont *) (const void *) font->data.directwrite; + return nullptr; } #endif diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.h b/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.h index 121569c15362c9a4a053424514275f07e6bc5bcf..a05b1a40ebb8c9fe7ee6289a027d09d65bd75281 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.h +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.h @@ -27,19 +27,32 @@ #include "hb.h" +#include <dwrite_3.h> + HB_BEGIN_DECLS HB_EXTERN hb_face_t * hb_directwrite_face_create (IDWriteFontFace *dw_face); +HB_EXTERN hb_face_t * +hb_directwrite_face_create_from_file_or_fail (const char *file_name, + unsigned int index); + +HB_EXTERN hb_face_t * +hb_directwrite_face_create_from_blob_or_fail (hb_blob_t *blob, + unsigned int index); + HB_EXTERN IDWriteFontFace * hb_directwrite_face_get_dw_font_face (hb_face_t *face); HB_EXTERN hb_font_t * -hb_directwrite_font_create (IDWriteFont *dw_font); +hb_directwrite_font_create (IDWriteFontFace *dw_face); -HB_EXTERN IDWriteFont * -hb_directwrite_font_get_dw_font (hb_font_t *font); +HB_EXTERN IDWriteFontFace * +hb_directwrite_font_get_dw_font_face (hb_font_t *font); + +HB_EXTERN void +hb_directwrite_font_set_funcs (hb_font_t *font); #ifndef HB_DISABLE_DEPRECATED @@ -47,6 +60,10 @@ HB_DEPRECATED_FOR (hb_directwrite_face_get_dw_font_face) HB_EXTERN IDWriteFontFace * hb_directwrite_face_get_font_face (hb_face_t *face); +HB_DEPRECATED +HB_EXTERN IDWriteFont * +hb_directwrite_font_get_dw_font (hb_font_t *font); + #endif HB_END_DECLS diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.hh new file mode 100644 index 0000000000000000000000000000000000000000..f51ab059abd93db38876564939eb12b819017621 --- /dev/null +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.hh @@ -0,0 +1,243 @@ +/* + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + + +#ifndef HB_DIRECTWRITE_HH +#define HB_DIRECTWRITE_HH + +#include "hb.hh" + +#include "hb-directwrite.h" + +#include "hb-mutex.hh" +#include "hb-map.hh" + +/* + * DirectWrite font stream helpers + */ + +// Have a look at to NativeFontResourceDWrite.cpp in Mozilla + + +/* Declare object creator for dynamic support of DWRITE */ +typedef HRESULT (WINAPI *t_DWriteCreateFactory)( + DWRITE_FACTORY_TYPE factoryType, + REFIID iid, + IUnknown **factory +); + +class DWriteFontFileLoader : public IDWriteFontFileLoader +{ +private: + hb_reference_count_t mRefCount; + hb_mutex_t mutex; + hb_hashmap_t<uint64_t, IDWriteFontFileStream *> mFontStreams; + uint64_t mNextFontFileKey = 0; +public: + DWriteFontFileLoader () + { + mRefCount.init (); + } + + uint64_t RegisterFontFileStream (IDWriteFontFileStream *fontFileStream) + { + fontFileStream->AddRef (); + auto lock = hb_lock_t (mutex); + mFontStreams.set (mNextFontFileKey, fontFileStream); + return mNextFontFileKey++; + } + void UnregisterFontFileStream (uint64_t fontFileKey) + { + auto lock = hb_lock_t (mutex); + IDWriteFontFileStream *stream = mFontStreams.get (fontFileKey); + if (stream) + { + mFontStreams.del (fontFileKey); + stream->Release (); + } + } + + // IUnknown interface + IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject) + { return S_OK; } + IFACEMETHOD_ (ULONG, AddRef) () + { + return mRefCount.inc () + 1; + } + IFACEMETHOD_ (ULONG, Release) () + { + signed refCount = mRefCount.dec () - 1; + assert (refCount >= 0); + if (refCount) + return refCount; + delete this; + return 0; + } + + // IDWriteFontFileLoader methods + virtual HRESULT STDMETHODCALLTYPE + CreateStreamFromKey (void const* fontFileReferenceKey, + uint32_t fontFileReferenceKeySize, + OUT IDWriteFontFileStream** fontFileStream) + { + if (fontFileReferenceKeySize != sizeof (uint64_t)) + return E_INVALIDARG; + uint64_t fontFileKey = * (uint64_t *) fontFileReferenceKey; + IDWriteFontFileStream *stream = mFontStreams.get (fontFileKey); + if (!stream) + return E_FAIL; + stream->AddRef (); + *fontFileStream = stream; + return S_OK; + } + + virtual ~DWriteFontFileLoader() + { + for (auto v : mFontStreams.values ()) + v->Release (); + } +}; + +class DWriteFontFileStream : public IDWriteFontFileStream +{ +private: + hb_reference_count_t mRefCount; + hb_blob_t *mBlob; + uint8_t *mData; + unsigned mSize; + DWriteFontFileLoader *mLoader; +public: + uint64_t fontFileKey; +public: + DWriteFontFileStream (hb_blob_t *blob); + + // IUnknown interface + IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject) + { return S_OK; } + IFACEMETHOD_ (ULONG, AddRef) () + { + return mRefCount.inc () + 1; + } + IFACEMETHOD_ (ULONG, Release) () + { + signed refCount = mRefCount.dec () - 1; + assert (refCount >= 0); + if (refCount) + return refCount; + delete this; + return 0; + } + + // IDWriteFontFileStream methods + virtual HRESULT STDMETHODCALLTYPE + ReadFileFragment (void const** fragmentStart, + UINT64 fileOffset, + UINT64 fragmentSize, + OUT void** fragmentContext) + { + // We are required to do bounds checking. + if (fileOffset + fragmentSize > mSize) return E_FAIL; + + // truncate the 64 bit fileOffset to size_t sized index into mData + size_t index = static_cast<size_t> (fileOffset); + + // We should be alive for the duration of this. + *fragmentStart = &mData[index]; + *fragmentContext = nullptr; + return S_OK; + } + + virtual void STDMETHODCALLTYPE + ReleaseFileFragment (void* fragmentContext) {} + + virtual HRESULT STDMETHODCALLTYPE + GetFileSize (OUT UINT64* fileSize) + { + *fileSize = mSize; + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE + GetLastWriteTime (OUT UINT64* lastWriteTime) { return E_NOTIMPL; } + + virtual ~DWriteFontFileStream(); +}; + +struct hb_directwrite_global_t +{ + hb_directwrite_global_t () + { + dwrite_dll = LoadLibraryW (L"DWrite.dll"); + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" +#endif + + t_DWriteCreateFactory p_DWriteCreateFactory = (t_DWriteCreateFactory) + GetProcAddress (dwrite_dll, "DWriteCreateFactory"); + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif + + if (unlikely (!p_DWriteCreateFactory)) + return; + + HRESULT hr = p_DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), + (IUnknown**) &dwriteFactory); + + if (unlikely (hr != S_OK)) + return; + + fontFileLoader = new DWriteFontFileLoader (); + dwriteFactory->RegisterFontFileLoader (fontFileLoader); + + success = true; + } + ~hb_directwrite_global_t () + { + if (fontFileLoader) + fontFileLoader->Release (); + if (dwriteFactory) + dwriteFactory->Release (); + if (dwrite_dll) + FreeLibrary (dwrite_dll); + } + + bool success = false; + HMODULE dwrite_dll; + IDWriteFactory *dwriteFactory; + DWriteFontFileLoader *fontFileLoader; +}; + + +HB_INTERNAL hb_directwrite_global_t * +get_directwrite_global (); + +HB_INTERNAL IDWriteFontFace * +dw_face_create (hb_blob_t *blob, unsigned index); + + +#endif /* HB_DIRECTWRITE_HH */ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h b/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h index 6306b69c09b56948188377fccf4d693ccb013ce4..de36901e2a70af7aa16fa6bbd755944c79215964 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h @@ -41,9 +41,16 @@ HB_BEGIN_DECLS * @path_start_y: Y component of the start of current path * @current_x: X component of current point * @current_y: Y component of current point + * @slant_xy: (Since: 11.0.0): Slanting factor for synthetic oblique * * Current drawing state. * + * The @slant_xy is a slanting factor for synthetic oblique. If the font's + * oblique angle is not 0, this factor is used to slant the drawing. For + * fonts with uniform x and y scales, this factor is calculated as + * tan(oblique_angle). For fonts with non-uniform scales, this factor is + * calculated as tan(oblique_angle) * x_scale / y_scale, or 0 if y_scale is 0. + * * Since: 4.0.0 **/ typedef struct hb_draw_state_t { @@ -55,6 +62,8 @@ typedef struct hb_draw_state_t { float current_x; float current_y; + float slant_xy; + /*< private >*/ hb_var_num_t reserved1; hb_var_num_t reserved2; @@ -62,7 +71,6 @@ typedef struct hb_draw_state_t { hb_var_num_t reserved4; hb_var_num_t reserved5; hb_var_num_t reserved6; - hb_var_num_t reserved7; } hb_draw_state_t; /** @@ -70,7 +78,7 @@ typedef struct hb_draw_state_t { * * The default #hb_draw_state_t at the start of glyph drawing. */ -#define HB_DRAW_STATE_DEFAULT {0, 0.f, 0.f, 0.f, 0.f, {0.}, {0.}, {0.}, {0.}, {0.}, {0.}, {0.}} +#define HB_DRAW_STATE_DEFAULT {0, 0.f, 0.f, 0.f, 0.f, 0.f, {0.}, {0.}, {0.}, {0.}, {0.}, {0.}} /** diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.hh index 87d03a4882244449ed8aa66bee8d68ba1c25a9b0..15978cdf0a37bcd32eee299f6b447c5f114fb514 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.hh @@ -99,6 +99,10 @@ struct hb_draw_funcs_t float to_x, float to_y) { if (unlikely (st.path_open)) close_path (draw_data, st); + + if (st.slant_xy) + to_x += to_y * st.slant_xy; + st.current_x = to_x; st.current_y = to_y; } @@ -109,7 +113,12 @@ struct hb_draw_funcs_t float to_x, float to_y) { if (unlikely (!st.path_open)) start_path (draw_data, st); + + if (st.slant_xy) + to_x += to_y * st.slant_xy; + emit_line_to (draw_data, st, to_x, to_y); + st.current_x = to_x; st.current_y = to_y; } @@ -121,7 +130,15 @@ struct hb_draw_funcs_t float to_x, float to_y) { if (unlikely (!st.path_open)) start_path (draw_data, st); + + if (st.slant_xy) + { + control_x += control_y * st.slant_xy; + to_x += to_y * st.slant_xy; + } + emit_quadratic_to (draw_data, st, control_x, control_y, to_x, to_y); + st.current_x = to_x; st.current_y = to_y; } @@ -134,7 +151,16 @@ struct hb_draw_funcs_t float to_x, float to_y) { if (unlikely (!st.path_open)) start_path (draw_data, st); + + if (st.slant_xy) + { + control1_x += control1_y * st.slant_xy; + control2_x += control2_y * st.slant_xy; + to_x += to_y * st.slant_xy; + } + emit_cubic_to (draw_data, st, control1_x, control1_y, control2_x, control2_y, to_x, to_y); + st.current_x = to_x; st.current_y = to_y; } @@ -168,46 +194,32 @@ DECLARE_NULL_INSTANCE (hb_draw_funcs_t); struct hb_draw_session_t { - hb_draw_session_t (hb_draw_funcs_t *funcs_, void *draw_data_, float slant_ = 0.f) - : slant {slant_}, not_slanted {slant == 0.f}, - funcs {funcs_}, draw_data {draw_data_}, st HB_DRAW_STATE_DEFAULT - {} + hb_draw_session_t (hb_draw_funcs_t *funcs_, void *draw_data_, float slant_xy = 0.f) + : funcs {funcs_}, draw_data {draw_data_}, st HB_DRAW_STATE_DEFAULT + { st.slant_xy = slant_xy; } ~hb_draw_session_t () { close_path (); } HB_ALWAYS_INLINE void move_to (float to_x, float to_y) { - if (likely (not_slanted)) - funcs->move_to (draw_data, st, - to_x, to_y); - else - funcs->move_to (draw_data, st, - to_x + to_y * slant, to_y); + funcs->move_to (draw_data, st, + to_x, to_y); } HB_ALWAYS_INLINE void line_to (float to_x, float to_y) { - if (likely (not_slanted)) - funcs->line_to (draw_data, st, - to_x, to_y); - else - funcs->line_to (draw_data, st, - to_x + to_y * slant, to_y); + funcs->line_to (draw_data, st, + to_x, to_y); } void HB_ALWAYS_INLINE quadratic_to (float control_x, float control_y, float to_x, float to_y) { - if (likely (not_slanted)) - funcs->quadratic_to (draw_data, st, - control_x, control_y, - to_x, to_y); - else - funcs->quadratic_to (draw_data, st, - control_x + control_y * slant, control_y, - to_x + to_y * slant, to_y); + funcs->quadratic_to (draw_data, st, + control_x, control_y, + to_x, to_y); } void HB_ALWAYS_INLINE @@ -215,16 +227,10 @@ struct hb_draw_session_t float control2_x, float control2_y, float to_x, float to_y) { - if (likely (not_slanted)) - funcs->cubic_to (draw_data, st, - control1_x, control1_y, - control2_x, control2_y, - to_x, to_y); - else - funcs->cubic_to (draw_data, st, - control1_x + control1_y * slant, control1_y, - control2_x + control2_y * slant, control2_y, - to_x + to_y * slant, to_y); + funcs->cubic_to (draw_data, st, + control1_x, control1_y, + control2_x, control2_y, + to_x, to_y); } HB_ALWAYS_INLINE void close_path () @@ -233,8 +239,6 @@ struct hb_draw_session_t } public: - float slant; - bool not_slanted; hb_draw_funcs_t *funcs; void *draw_data; hb_draw_state_t st; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc index 002bb37d4c7b2ed772f8b7d878b4de3d4d895868..9051247bc95ffec966fac016cc26c9afa4fc4706 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc @@ -34,6 +34,16 @@ #include "hb-ot-face.hh" #include "hb-ot-cmap-table.hh" +#ifdef HAVE_FREETYPE +#include "hb-ft.h" +#endif +#ifdef HAVE_CORETEXT +#include "hb-coretext.h" +#endif +#ifdef HAVE_DIRECTWRITE +#include "hb-directwrite.h" +#endif + /** * SECTION:hb-face @@ -72,14 +82,14 @@ hb_face_count (hb_blob_t *blob) if (unlikely (!blob)) return 0; - /* TODO We shouldn't be sanitizing blob. Port to run sanitizer and return if not sane. */ - /* Make API signature const after. */ - hb_blob_t *sanitized = hb_sanitize_context_t ().sanitize_blob<OT::OpenTypeFontFile> (hb_blob_reference (blob)); - const OT::OpenTypeFontFile& ot = *sanitized->as<OT::OpenTypeFontFile> (); - unsigned int ret = ot.get_face_count (); - hb_blob_destroy (sanitized); + hb_sanitize_context_t c (blob); + + const char *start = hb_blob_get_data (blob, nullptr); + auto *ot = reinterpret_cast<OT::OpenTypeFontFile *> (const_cast<char *> (start)); + if (unlikely (!ot->sanitize (&c))) + return 0; - return ret; + return ot->get_face_count (); } /* @@ -318,7 +328,209 @@ hb_face_create_from_file_or_fail (const char *file_name, return face; } + +static struct supported_face_loaders_t { + char name[16]; + hb_face_t * (*from_file) (const char *font_file, unsigned face_index); + hb_face_t * (*from_blob) (hb_blob_t *blob, unsigned face_index); +} supported_face_loaders[] = +{ + {"ot", +#ifndef HB_NO_OPEN + hb_face_create_from_file_or_fail, +#else + nullptr, +#endif + hb_face_create_or_fail + }, +#ifdef HAVE_FREETYPE + {"ft", + hb_ft_face_create_from_file_or_fail, + hb_ft_face_create_from_blob_or_fail + }, +#endif +#ifdef HAVE_CORETEXT + {"coretext", + hb_coretext_face_create_from_file_or_fail, + hb_coretext_face_create_from_blob_or_fail + }, #endif +#ifdef HAVE_DIRECTWRITE + {"directwrite", + hb_directwrite_face_create_from_file_or_fail, + hb_directwrite_face_create_from_blob_or_fail + }, +#endif +}; + +static const char *get_default_loader_name () +{ + static hb_atomic_t<const char *> static_loader_name; + const char *loader_name = static_loader_name.get_acquire (); + if (!loader_name) + { + loader_name = getenv ("HB_FACE_LOADER"); + if (!loader_name) + loader_name = ""; + if (!static_loader_name.cmpexch (nullptr, loader_name)) + loader_name = static_loader_name.get_acquire (); + } + return loader_name; +} + +/** + * hb_face_create_from_file_or_fail_using: + * @file_name: A font filename + * @index: The index of the face within the file + * @loader_name: (nullable): The name of the loader to use, or `NULL` + * + * A thin wrapper around the face loader functions registered with HarfBuzz. + * If @loader_name is `NULL` or the empty string, the first available loader + * is used. + * + * For example, the FreeType ("ft") loader might be able to load + * WOFF and WOFF2 files if FreeType is built with those features, + * whereas the OpenType ("ot") loader will not. + * + * Return value: (transfer full): The new face object, or `NULL` if + * the file cannot be read or the loader fails to load the face. + * + * Since: 11.0.0 + **/ +hb_face_t * +hb_face_create_from_file_or_fail_using (const char *file_name, + unsigned int index, + const char *loader_name) +{ + // Duplicated in hb_face_create_or_fail_using + bool retry = false; + if (!loader_name || !*loader_name) + { + loader_name = get_default_loader_name (); + retry = true; + } + if (loader_name && !*loader_name) loader_name = nullptr; + +retry: + for (unsigned i = 0; i < ARRAY_LENGTH (supported_face_loaders); i++) + { + if (!loader_name || (supported_face_loaders[i].from_file && !strcmp (supported_face_loaders[i].name, loader_name))) + return supported_face_loaders[i].from_file (file_name, index); + } + + if (retry) + { + retry = false; + loader_name = nullptr; + goto retry; + } + + return nullptr; +} + +/** + * hb_face_create_or_fail_using: + * @blob: #hb_blob_t to work upon + * @index: The index of the face within @blob + * @loader_name: (nullable): The name of the loader to use, or `NULL` + * + * A thin wrapper around the face loader functions registered with HarfBuzz. + * If @loader_name is `NULL` or the empty string, the first available loader + * is used. + * + * For example, the FreeType ("ft") loader might be able to load + * WOFF and WOFF2 files if FreeType is built with those features, + * whereas the OpenType ("ot") loader will not. + * + * Return value: (transfer full): The new face object, or `NULL` if + * the loader fails to load the face. + * + * Since: 11.0.0 + **/ +hb_face_t * +hb_face_create_or_fail_using (hb_blob_t *blob, + unsigned int index, + const char *loader_name) +{ + // Duplicated in hb_face_create_from_file_or_fail_using + bool retry = false; + if (!loader_name || !*loader_name) + { + loader_name = get_default_loader_name (); + retry = true; + } + if (loader_name && !*loader_name) loader_name = nullptr; + +retry: + for (unsigned i = 0; i < ARRAY_LENGTH (supported_face_loaders); i++) + { + if (!loader_name || (supported_face_loaders[i].from_blob && !strcmp (supported_face_loaders[i].name, loader_name))) + return supported_face_loaders[i].from_blob (blob, index); + } + + if (retry) + { + retry = false; + loader_name = nullptr; + goto retry; + } + + return nullptr; +} + +static inline void free_static_face_loader_list (); + +static const char * const nil_face_loader_list[] = {nullptr}; + +static struct hb_face_loader_list_lazy_loader_t : hb_lazy_loader_t<const char *, + hb_face_loader_list_lazy_loader_t> +{ + static const char ** create () + { + const char **face_loader_list = (const char **) hb_calloc (1 + ARRAY_LENGTH (supported_face_loaders), sizeof (const char *)); + if (unlikely (!face_loader_list)) + return nullptr; + + unsigned i; + for (i = 0; i < ARRAY_LENGTH (supported_face_loaders); i++) + face_loader_list[i] = supported_face_loaders[i].name; + face_loader_list[i] = nullptr; + + hb_atexit (free_static_face_loader_list); + + return face_loader_list; + } + static void destroy (const char **l) + { hb_free (l); } + static const char * const * get_null () + { return nil_face_loader_list; } +} static_face_loader_list; + +static inline +void free_static_face_loader_list () +{ + static_face_loader_list.free_instance (); +} + +/** + * hb_face_list_loaders: + * + * Retrieves the list of face loaders supported by HarfBuzz. + * + * Return value: (transfer none) (array zero-terminated=1): a + * `NULL`-terminated array of supported face loaders + * constant strings. The returned array is owned by HarfBuzz + * and should not be modified or freed. + * + * Since: 11.0.0 + **/ +const char ** +hb_face_list_loaders () +{ + return static_face_loader_list.get_unconst (); +} +#endif + /** * hb_face_get_empty: diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h b/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h index afc198547734a53ceaeac463b199b9a7850f1c1b..5d39a48cc63e9dc5fa9272f1bf0f376e2c625940 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h @@ -63,10 +63,24 @@ HB_EXTERN hb_face_t * hb_face_create_or_fail (hb_blob_t *blob, unsigned int index); +HB_EXTERN hb_face_t * +hb_face_create_or_fail_using (hb_blob_t *blob, + unsigned int index, + const char *loader_name); + HB_EXTERN hb_face_t * hb_face_create_from_file_or_fail (const char *file_name, unsigned int index); +HB_EXTERN hb_face_t * +hb_face_create_from_file_or_fail_using (const char *file_name, + unsigned int index, + const char *loader_name); + +HB_EXTERN const char ** +hb_face_list_loaders (void); + + /** * hb_reference_table_func_t: * @face: an #hb_face_t to reference table for diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh index 6401568326b2f3ba3d6460f8c974ea061400937c..77c2437213cab62ca35d230ca0d734a0c069f463 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh @@ -49,8 +49,8 @@ struct hb_face_t hb_object_header_t header; unsigned int index; /* Face index in a collection, zero-based. */ - mutable hb_atomic_int_t upem; /* Units-per-EM. */ - mutable hb_atomic_int_t num_glyphs; /* Number of glyphs. */ + mutable hb_atomic_t<unsigned> upem; /* Units-per-EM. */ + mutable hb_atomic_t<unsigned> num_glyphs;/* Number of glyphs. */ hb_reference_table_func_t reference_table_func; void *user_data; @@ -70,7 +70,7 @@ struct hb_face_t plan_node_t *next; }; #ifndef HB_NO_SHAPER - hb_atomic_ptr_t<plan_node_t> shape_plans; + hb_atomic_t<plan_node_t *> shape_plans; #endif hb_blob_t *reference_table (hb_tag_t tag) const diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc index 96b79ecca752d052226650be0463a26a641cd424..b73a87048812d9438a77900940f23c53376dab8f 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc @@ -38,6 +38,22 @@ #include "hb-ot-var-avar-table.hh" #include "hb-ot-var-fvar-table.hh" +#ifndef HB_NO_OT_FONT +#include "hb-ot.h" +#endif +#ifdef HAVE_FREETYPE +#include "hb-ft.h" +#endif +#ifdef HAVE_FONTATIONS +#include "hb-fontations.h" +#endif +#ifdef HAVE_CORETEXT +#include "hb-coretext.h" +#endif +#ifdef HAVE_DIRECTWRITE +#include "hb-directwrite.h" +#endif + /** * SECTION:hb-font @@ -1854,10 +1870,7 @@ hb_font_create (hb_face_t *face) { hb_font_t *font = _hb_font_create (face); -#ifndef HB_NO_OT_FONT - /* Install our in-house, very lightweight, funcs. */ - hb_ot_font_set_funcs (font); -#endif + hb_font_set_funcs_using (font, nullptr); #ifndef HB_NO_VAR if (face && face->index >> 16) @@ -1880,7 +1893,7 @@ _hb_font_adopt_var_coords (hb_font_t *font, font->design_coords = design_coords; font->num_coords = coords_length; - font->mults_changed (); // Easiest to call this to drop cached data + font->changed (); } /** @@ -1935,7 +1948,8 @@ hb_font_create_sub_font (hb_font_t *parent) } } - font->mults_changed (); + font->changed (); + font->serial_coords = font->serial; return font; } @@ -2023,7 +2037,7 @@ hb_font_set_user_data (hb_font_t *font, hb_bool_t replace) { if (!hb_object_is_immutable (font)) - font->serial++; + font->changed (); return hb_object_set_user_data (font, key, data, destroy, replace); } @@ -2098,7 +2112,7 @@ hb_font_is_immutable (hb_font_t *font) unsigned int hb_font_get_serial (hb_font_t *font) { - return font->serial; + return font->serial.get_acquire (); } /** @@ -2117,9 +2131,7 @@ hb_font_changed (hb_font_t *font) if (hb_object_is_immutable (font)) return; - font->serial++; - - font->mults_changed (); + font->changed (); } /** @@ -2141,8 +2153,6 @@ hb_font_set_parent (hb_font_t *font, if (parent == font->parent) return; - font->serial++; - if (!parent) parent = hb_font_get_empty (); @@ -2151,6 +2161,8 @@ hb_font_set_parent (hb_font_t *font, font->parent = hb_font_reference (parent); hb_font_destroy (old); + + font->changed (); } /** @@ -2188,8 +2200,6 @@ hb_font_set_face (hb_font_t *font, if (face == font->face) return; - font->serial++; - if (unlikely (!face)) face = hb_face_get_empty (); @@ -2197,9 +2207,11 @@ hb_font_set_face (hb_font_t *font, hb_face_make_immutable (face); font->face = hb_face_reference (face); - font->mults_changed (); + font->changed (); hb_face_destroy (old); + + font->changed (); } /** @@ -2244,8 +2256,6 @@ hb_font_set_funcs (hb_font_t *font, return; } - font->serial++; - if (font->destroy) font->destroy (font->user_data); @@ -2257,6 +2267,8 @@ hb_font_set_funcs (hb_font_t *font, font->klass = klass; font->user_data = font_data; font->destroy = destroy; + + font->changed (); } /** @@ -2283,15 +2295,151 @@ hb_font_set_funcs_data (hb_font_t *font, return; } - font->serial++; - if (font->destroy) font->destroy (font->user_data); font->user_data = font_data; font->destroy = destroy; + + font->changed (); } +static struct supported_font_funcs_t { + char name[16]; + void (*func) (hb_font_t *); +} supported_font_funcs[] = +{ +#ifndef HB_NO_OT_FONT + {"ot", hb_ot_font_set_funcs}, +#endif +#ifdef HAVE_FREETYPE + {"ft", hb_ft_font_set_funcs}, +#endif +#ifdef HAVE_FONTATIONS + {"fontations",hb_fontations_font_set_funcs}, +#endif +#ifdef HAVE_CORETEXT + {"coretext", hb_coretext_font_set_funcs}, +#endif +#ifdef HAVE_DIRECTWRITE + {"directwrite",hb_directwrite_font_set_funcs}, +#endif +}; + +static const char *get_default_funcs_name () +{ + static hb_atomic_t<const char *> static_funcs_name; + const char *name = static_funcs_name.get_acquire (); + if (!name) + { + name = getenv ("HB_FONT_FUNCS"); + if (!name) + name = ""; + if (!static_funcs_name.cmpexch (nullptr, name)) + name = static_funcs_name.get_acquire (); + } + return name; +} + +/** + * hb_font_set_funcs_using: + * @font: #hb_font_t to work upon + * @name: The name of the font-functions structure to use, or `NULL` + * + * Sets the font-functions structure to use for a font, based on the + * specified name. + * + * If @name is `NULL` or the empty string, the default (first) functioning font-functions + * are used. This default can be changed by setting the `HB_FONT_FUNCS` environment + * variable to the name of the desired font-functions. + * + * Return value: `true` if the font-functions was found and set, `false` otherwise + * + * Since: 11.0.0 + **/ +hb_bool_t +hb_font_set_funcs_using (hb_font_t *font, + const char *name) +{ + bool retry = false; + + if (!name || !*name) + { + name = get_default_funcs_name (); + retry = true; + } + if (name && !*name) name = nullptr; + +retry: + for (unsigned i = 0; i < ARRAY_LENGTH (supported_font_funcs); i++) + if (!name || strcmp (supported_font_funcs[i].name, name) == 0) + { + supported_font_funcs[i].func (font); + if (name || font->klass != hb_font_funcs_get_empty ()) + return true; + } + + if (retry) + { + retry = false; + name = nullptr; + goto retry; + } + + return false; +} + +static inline void free_static_font_funcs_list (); + +static const char * const nil_font_funcs_list[] = {nullptr}; + +static struct hb_font_funcs_list_lazy_loader_t : hb_lazy_loader_t<const char *, + hb_font_funcs_list_lazy_loader_t> +{ + static const char ** create () + { + const char **font_funcs_list = (const char **) hb_calloc (1 + ARRAY_LENGTH (supported_font_funcs), sizeof (const char *)); + if (unlikely (!font_funcs_list)) + return nullptr; + + unsigned i; + for (i = 0; i < ARRAY_LENGTH (supported_font_funcs); i++) + font_funcs_list[i] = supported_font_funcs[i].name; + font_funcs_list[i] = nullptr; + + hb_atexit (free_static_font_funcs_list); + + return font_funcs_list; + } + static void destroy (const char **l) + { hb_free (l); } + static const char * const * get_null () + { return nil_font_funcs_list; } +} static_font_funcs_list; + +static inline +void free_static_font_funcs_list () +{ + static_font_funcs_list.free_instance (); +} + +/** + * hb_font_list_funcs: + * + * Retrieves the list of font functions supported by HarfBuzz. + * + * Return value: (transfer none) (array zero-terminated=1): a + * `NULL`-terminated array of supported font functions + * constant strings. The returned array is owned by HarfBuzz + * and should not be modified or freed. + * + * Since: 11.0.0 + **/ +const char ** +hb_font_list_funcs () +{ + return static_font_funcs_list.get_unconst (); +} /** * hb_font_set_scale: @@ -2339,11 +2487,10 @@ hb_font_set_scale (hb_font_t *font, if (font->x_scale == x_scale && font->y_scale == y_scale) return; - font->serial++; - font->x_scale = x_scale; font->y_scale = y_scale; - font->mults_changed (); + + font->changed (); } /** @@ -2390,10 +2537,10 @@ hb_font_set_ppem (hb_font_t *font, if (font->x_ppem == x_ppem && font->y_ppem == y_ppem) return; - font->serial++; - font->x_ppem = x_ppem; font->y_ppem = y_ppem; + + font->changed (); } /** @@ -2437,9 +2584,9 @@ hb_font_set_ptem (hb_font_t *font, if (font->ptem == ptem) return; - font->serial++; - font->ptem = ptem; + + font->changed (); } /** @@ -2499,12 +2646,11 @@ hb_font_set_synthetic_bold (hb_font_t *font, font->embolden_in_place == (bool) in_place) return; - font->serial++; - font->x_embolden = x_embolden; font->y_embolden = y_embolden; font->embolden_in_place = in_place; - font->mults_changed (); + + font->changed (); } /** @@ -2558,10 +2704,9 @@ hb_font_set_synthetic_slant (hb_font_t *font, float slant) if (font->slant == slant) return; - font->serial++; - font->slant = slant; - font->mults_changed (); + + font->changed (); } /** @@ -2607,8 +2752,6 @@ hb_font_set_variations (hb_font_t *font, if (hb_object_is_immutable (font)) return; - font->serial_coords = ++font->serial; - if (!variations_length && font->instance_index == HB_FONT_NO_VAR_NAMED_INSTANCE) { hb_font_set_var_coords_normalized (font, nullptr, 0); @@ -2677,8 +2820,6 @@ hb_font_set_variation (hb_font_t *font, if (hb_object_is_immutable (font)) return; - font->serial_coords = ++font->serial; - // TODO Share some of this code with set_variations() const OT::fvar &fvar = *font->face->table.fvar; @@ -2749,8 +2890,6 @@ hb_font_set_var_coords_design (hb_font_t *font, if (hb_object_is_immutable (font)) return; - font->serial_coords = ++font->serial; - int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr; float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr; @@ -2787,8 +2926,6 @@ hb_font_set_var_named_instance (hb_font_t *font, if (font->instance_index == instance_index) return; - font->serial_coords = ++font->serial; - font->instance_index = instance_index; hb_font_set_variations (font, nullptr, 0); } @@ -2834,8 +2971,6 @@ hb_font_set_var_coords_normalized (hb_font_t *font, if (hb_object_is_immutable (font)) return; - font->serial_coords = ++font->serial; - int *copy = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr; int *unmapped = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr; float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (design_coords[0])) : nullptr; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h b/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h index 3c2355af2d7254936bd71b0b7504372fa5169a50..478c808e128eb43fc0eb498a8cebc58f65ab9568 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h @@ -1052,6 +1052,12 @@ hb_font_set_funcs_data (hb_font_t *font, void *font_data, hb_destroy_func_t destroy); +HB_EXTERN hb_bool_t +hb_font_set_funcs_using (hb_font_t *font, + const char *name); + +HB_EXTERN const char ** +hb_font_list_funcs (void); HB_EXTERN void hb_font_set_scale (hb_font_t *font, diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh index 4c8190b0dd17d297acbbf9ca0bb44a510d2100e5..5945ec1c2fe3d774e8364fe21f7edb49c7713310 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh @@ -32,6 +32,7 @@ #include "hb.hh" #include "hb-face.hh" +#include "hb-atomic.hh" #include "hb-shaper.hh" @@ -105,8 +106,8 @@ DECLARE_NULL_INSTANCE (hb_font_funcs_t); struct hb_font_t { hb_object_header_t header; - unsigned int serial; - unsigned int serial_coords; + hb_atomic_t<unsigned> serial; + hb_atomic_t<unsigned> serial_coords; hb_font_t *parent; hb_face_t *face; @@ -191,22 +192,33 @@ struct hb_font_t void scale_glyph_extents (hb_glyph_extents_t *extents) { - float x1 = em_fscale_x (extents->x_bearing); - float y1 = em_fscale_y (extents->y_bearing); - float x2 = em_fscale_x (extents->x_bearing + extents->width); - float y2 = em_fscale_y (extents->y_bearing + extents->height); - - /* Apply slant. */ - if (slant_xy) - { - x1 += hb_min (y1 * slant_xy, y2 * slant_xy); - x2 += hb_max (y1 * slant_xy, y2 * slant_xy); - } + float x1 = em_scale_x (extents->x_bearing); + float y1 = em_scale_y (extents->y_bearing); + float x2 = em_scale_x (extents->x_bearing + extents->width); + float y2 = em_scale_y (extents->y_bearing + extents->height); extents->x_bearing = floorf (x1); extents->y_bearing = floorf (y1); extents->width = ceilf (x2) - extents->x_bearing; extents->height = ceilf (y2) - extents->y_bearing; + } + + void synthetic_glyph_extents (hb_glyph_extents_t *extents) + { + /* Apply slant. */ + if (slant_xy) + { + hb_position_t x1 = extents->x_bearing; + hb_position_t y1 = extents->y_bearing; + hb_position_t x2 = extents->x_bearing + extents->width; + hb_position_t y2 = extents->y_bearing + extents->height; + + x1 += floorf (hb_min (y1 * slant_xy, y2 * slant_xy)); + x2 += ceilf (hb_max (y1 * slant_xy, y2 * slant_xy)); + + extents->x_bearing = x1; + extents->width = x2 - extents->x_bearing; + } if (x_strength || y_strength) { @@ -389,10 +401,14 @@ struct hb_font_t hb_glyph_extents_t *extents) { hb_memset (extents, 0, sizeof (*extents)); - return klass->get.f.glyph_extents (this, user_data, - glyph, - extents, - !klass->user_data ? nullptr : klass->user_data->glyph_extents); + bool ret = klass->get.f.glyph_extents (this, user_data, + glyph, + extents, + !klass->user_data ? nullptr : klass->user_data->glyph_extents); + if (ret) + synthetic_glyph_extents (extents); + + return ret; } hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index, @@ -686,7 +702,7 @@ struct hb_font_t return false; } - void mults_changed () + void changed () { float upem = face->get_upem (); @@ -703,6 +719,8 @@ struct hb_font_t slant_xy = y_scale ? slant * x_scale / y_scale : 0.f; data.fini (); + + serial++; } hb_position_t em_mult (int16_t v, int64_t mult) diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-fontations.h b/source/libs/harfbuzz/harfbuzz-src/src/hb-fontations.h new file mode 100644 index 0000000000000000000000000000000000000000..6a3fce0b577eaffff447bec351f1e8b77747a3b7 --- /dev/null +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-fontations.h @@ -0,0 +1,56 @@ +/* + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_FONTATIONS_H +#define HB_FONTATIONS_H + +#include "hb.h" + +/** + * SECTION: hb-fontations + * @title: hb-fontations + * @short_description: Fontations integration + * @include: hb-fontations.h + * + * Functions for using HarfBuzz with + * [Fontations](https://github.com/googlefonts/fontations/) fonts. + **/ + +HB_BEGIN_DECLS + +/** + * hb_fontations_font_set_funcs: + * @font: #hb_font_t to work upon + * + * Configures the font-functions structure of the specified #hb_font_t font + * object to use Fontations font functions. + * + * Since: 11.0.0 + **/ +HB_EXTERN void +hb_fontations_font_set_funcs (hb_font_t *font); + +HB_END_DECLS + +#endif /* HB_FONTATIONS_H */ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh index c96698369d13f1521547cef65a94599b7309a629..b41d5555374876b5a31a5af64f42a27827788c46 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh @@ -83,7 +83,7 @@ struct hb_ft_paint_context_t hb_ft_paint_context_t (const hb_ft_font_t *ft_font, hb_font_t *font, hb_paint_funcs_t *paint_funcs, void *paint_data, - FT_Color *palette, + hb_array_t<const FT_Color> palette, unsigned palette_index, hb_color_t foreground) : ft_font (ft_font), font(font), @@ -103,7 +103,7 @@ struct hb_ft_paint_context_t hb_font_t *font; hb_paint_funcs_t *funcs; void *data; - FT_Color *palette; + hb_array_t<const FT_Color> palette; unsigned palette_index; hb_color_t foreground; hb_decycler_t glyphs_decycler; @@ -167,7 +167,7 @@ _hb_ft_color_line_get_color_stops (hb_color_line_t *color_line, hb_color_get_red (color), (hb_color_get_alpha (color) * stop.color.alpha) >> 14); } - else + else if (c->palette) { FT_Color ft_color = c->palette[stop.color.palette_index]; color_stops->color = HB_COLOR (ft_color.blue, @@ -175,6 +175,8 @@ _hb_ft_color_line_get_color_stops (hb_color_line_t *color_line, ft_color.red, (ft_color.alpha * stop.color.alpha) >> 14); } + else + color_stops->color = HB_COLOR (0, 0, 0, 0); } color_stops++; @@ -229,9 +231,7 @@ _hb_ft_paint (hb_ft_paint_context_t *c, if (unlikely (!node.visit ((uintptr_t) other_paint.p))) continue; - c->funcs->push_group (c->data); c->recurse (other_paint); - c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); } } break; @@ -316,11 +316,11 @@ _hb_ft_paint (hb_ft_paint_context_t *c, break; case FT_COLR_PAINTFORMAT_GLYPH: { - c->funcs->push_inverse_root_transform (c->data, c->font); + c->funcs->push_inverse_font_transform (c->data, c->font); c->ft_font->lock.unlock (); c->funcs->push_clip_glyph (c->data, paint.u.glyph.glyphID, c->font); c->ft_font->lock.lock (); - c->funcs->push_root_transform (c->data, c->font); + c->funcs->push_font_transform (c->data, c->font); c->recurse (paint.u.glyph.paint); c->funcs->pop_transform (c->data); c->funcs->pop_clip (c->data); @@ -335,7 +335,7 @@ _hb_ft_paint (hb_ft_paint_context_t *c, if (unlikely (!node.visit (gid))) return; - c->funcs->push_inverse_root_transform (c->data, c->font); + c->funcs->push_inverse_font_transform (c->data, c->font); c->ft_font->lock.unlock (); if (c->funcs->color_glyph (c->data, gid, c->font)) { @@ -451,10 +451,12 @@ _hb_ft_paint (hb_ft_paint_context_t *c, break; case FT_COLR_PAINTFORMAT_COMPOSITE: { + c->funcs->push_group (c->data); c->recurse (paint.u.composite.backdrop_paint); c->funcs->push_group (c->data); c->recurse (paint.u.composite.source_paint); c->funcs->pop_group (c->data, _hb_ft_paint_composite_mode (paint.u.composite.composite_mode)); + c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); } break; @@ -479,17 +481,24 @@ hb_ft_paint_glyph_colr (hb_font_t *font, /* Face is locked. */ - FT_Error error; - FT_Color* palette; + FT_Palette_Data palette_data = {}; + FT_Color* palette = NULL; FT_LayerIterator iterator; FT_Bool have_layers; FT_UInt layer_glyph_index; FT_UInt layer_color_index; - error = FT_Palette_Select(ft_face, palette_index, &palette); - if (error) - palette = NULL; + (void) FT_Palette_Data_Get(ft_face, &palette_data); + (void) FT_Palette_Select(ft_face, palette_index, &palette); + if (!palette) + { + // https://github.com/harfbuzz/harfbuzz/issues/5116 + (void) FT_Palette_Select(ft_face, 0, &palette); + } + + auto palette_array = hb_array ((const FT_Color *) palette, + palette ? palette_data.num_palette_entries : 0); /* COLRv1 */ FT_OpaquePaint paint = {0}; @@ -499,7 +508,7 @@ hb_ft_paint_glyph_colr (hb_font_t *font, { hb_ft_paint_context_t c (ft_font, font, paint_funcs, paint_data, - palette, palette_index, foreground); + palette_array, palette_index, foreground); hb_decycler_node_t node (c.glyphs_decycler); node.visit (gid); @@ -524,10 +533,10 @@ hb_ft_paint_glyph_colr (hb_font_t *font, hb_paint_extents_context_t extents_data; hb_ft_paint_context_t ce (ft_font, font, extents_funcs, &extents_data, - palette, palette_index, foreground); + palette_array, palette_index, foreground); hb_decycler_node_t node2 (ce.glyphs_decycler); node2.visit (gid); - ce.funcs->push_root_transform (ce.data, font); + ce.funcs->push_font_transform (ce.data, font); ce.recurse (paint); ce.funcs->pop_transform (ce.data); hb_extents_t extents = extents_data.get_extents (); @@ -540,7 +549,7 @@ hb_ft_paint_glyph_colr (hb_font_t *font, extents.ymax); } - c.funcs->push_root_transform (c.data, font); + c.funcs->push_font_transform (c.data, font); if (is_bounded) { diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc index efb4b7d2435dd711228e3719fe583c39a7a82777..756ba8a54bb73b52f3b8e0e4cbb962c5b38aa2e5 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc @@ -101,7 +101,7 @@ struct hb_ft_font_t mutable hb_mutex_t lock; /* Protects members below. */ FT_Face ft_face; - mutable unsigned cached_serial; + mutable hb_atomic_t<unsigned> cached_serial; mutable hb_ft_advance_cache_t advance_cache; }; @@ -118,7 +118,7 @@ _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref) ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; - ft_font->cached_serial = (unsigned) -1; + ft_font->cached_serial = UINT_MAX; new (&ft_font->advance_cache) hb_ft_advance_cache_t; return ft_font; @@ -213,9 +213,10 @@ _hb_ft_hb_font_check_changed (hb_font_t *font, { if (font->serial != ft_font->cached_serial) { + hb_lock_t lock (ft_font->lock); _hb_ft_hb_font_changed (font, ft_font->ft_face); ft_font->advance_cache.clear (); - ft_font->cached_serial = font->serial; + ft_font->cached_serial.set_release (font->serial.get_acquire ()); return true; } return false; @@ -478,6 +479,8 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + _hb_ft_hb_font_check_changed (font, ft_font); + hb_position_t *orig_first_advance = first_advance; hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; @@ -561,6 +564,8 @@ hb_ft_get_glyph_v_advance (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + _hb_ft_hb_font_check_changed (font, ft_font); + hb_lock_t lock (ft_font->lock); FT_Fixed v; float y_mult; @@ -614,6 +619,8 @@ hb_ft_get_glyph_v_origin (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + _hb_ft_hb_font_check_changed (font, ft_font); + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; float x_mult, y_mult; @@ -658,6 +665,8 @@ hb_ft_get_glyph_h_kerning (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + _hb_ft_hb_font_check_changed (font, ft_font); + hb_lock_t lock (ft_font->lock); FT_Vector kerningv; @@ -677,10 +686,12 @@ hb_ft_get_glyph_extents (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + _hb_ft_hb_font_check_changed (font, ft_font); + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; float x_mult, y_mult; - float slant_xy = font->slant_xy; + #ifdef HAVE_FT_GET_TRANSFORM if (ft_font->transform) { @@ -708,34 +719,11 @@ hb_ft_get_glyph_extents (hb_font_t *font, float x2 = x1 + x_mult * ft_face->glyph->metrics.width; float y2 = y1 + y_mult * -ft_face->glyph->metrics.height; - /* Apply slant. */ - if (slant_xy) - { - x1 += hb_min (y1 * slant_xy, y2 * slant_xy); - x2 += hb_max (y1 * slant_xy, y2 * slant_xy); - } - extents->x_bearing = floorf (x1); extents->y_bearing = floorf (y1); extents->width = ceilf (x2) - extents->x_bearing; extents->height = ceilf (y2) - extents->y_bearing; - if (font->x_strength || font->y_strength) - { - /* Y */ - int y_shift = font->y_strength; - if (font->y_scale < 0) y_shift = -y_shift; - extents->y_bearing += y_shift; - extents->height -= y_shift; - - /* X */ - int x_shift = font->x_strength; - if (font->x_scale < 0) x_shift = -x_shift; - if (font->embolden_in_place) - extents->x_bearing -= x_shift / 2; - extents->width += x_shift; - } - return true; } @@ -749,6 +737,8 @@ hb_ft_get_glyph_contour_point (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + _hb_ft_hb_font_check_changed (font, ft_font); + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; @@ -826,6 +816,8 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + _hb_ft_hb_font_check_changed (font, ft_font); + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; float y_mult; @@ -916,6 +908,8 @@ hb_ft_draw_glyph (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + _hb_ft_hb_font_check_changed (font, ft_font); + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; @@ -990,6 +984,8 @@ hb_ft_paint_glyph (hb_font_t *font, void *user_data) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + _hb_ft_hb_font_check_changed (font, ft_font); + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; @@ -1079,10 +1075,8 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft hb_font_funcs_set_font_h_extents_func (funcs, hb_ft_get_font_h_extents, nullptr, nullptr); hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ft_get_glyph_h_advances, nullptr, nullptr); - //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ft_get_glyph_h_origin, nullptr, nullptr); #ifndef HB_NO_VERTICAL - //hb_font_funcs_set_font_v_extents_func (funcs, hb_ft_get_font_v_extents, nullptr, nullptr); hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, nullptr, nullptr); hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ft_get_glyph_v_origin, nullptr, nullptr); #endif @@ -1090,7 +1084,6 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft #ifndef HB_NO_OT_SHAPE_FALLBACK hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ft_get_glyph_h_kerning, nullptr, nullptr); #endif - //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ft_get_glyph_v_kerning, nullptr, nullptr); hb_font_funcs_set_glyph_extents_func (funcs, hb_ft_get_glyph_extents, nullptr, nullptr); hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ft_get_glyph_contour_point, nullptr, nullptr); hb_font_funcs_set_glyph_name_func (funcs, hb_ft_get_glyph_name, nullptr, nullptr); @@ -1456,6 +1449,10 @@ hb_ft_font_changed (hb_font_t *font) * variation-axis settings on the @font. * This call is fast if nothing has changed on @font. * + * Note that as of version 11.0.0, calling this function is not necessary, + * as HarfBuzz will automatically detect changes to the font and update + * the underlying FT_Face as needed. + * * Return value: true if changed, false otherwise * * Since: 4.4.0 @@ -1587,7 +1584,8 @@ destroy_ft_library (void *arg) * font file and face index. * * This is similar in functionality to hb_face_create_from_file_or_fail(), - * but uses the FreeType library for loading the font file. + * but uses the FreeType library for loading the font file. This can + * be useful, for example, to load WOFF and WOFF2 font data. * * Return value: (transfer full): The new face object, or `NULL` if * no face is found at the specified index or the file cannot be read. @@ -1624,6 +1622,75 @@ hb_ft_face_create_from_file_or_fail (const char *file_name, return face; } +static hb_user_data_key_t ft_blob_key = {0}; + +static void +_destroy_blob (void *p) +{ + hb_blob_destroy ((hb_blob_t *) p); +} + +/** + * hb_ft_face_create_from_blob_or_fail: + * @blob: A blob + * @index: The index of the face within the blob + * + * Creates an #hb_face_t face object from the specified + * font blob and face index. + * + * This is similar in functionality to hb_face_create_from_blob_or_fail(), + * but uses the FreeType library for loading the font blob. This can + * be useful, for example, to load WOFF and WOFF2 font data. + * + * Return value: (transfer full): The new face object, or `NULL` if + * loading fails (eg. blob does not contain valid font data). + * + * Since: 11.0.0 + */ +hb_face_t * +hb_ft_face_create_from_blob_or_fail (hb_blob_t *blob, + unsigned int index) +{ + FT_Library ft_library = reference_ft_library (); + if (unlikely (!ft_library)) + { + DEBUG_MSG (FT, ft_library, "reference_ft_library failed"); + return nullptr; + } + + hb_blob_make_immutable (blob); + unsigned blob_size; + const char *blob_data = hb_blob_get_data (blob, &blob_size); + + FT_Face ft_face; + if (unlikely (FT_New_Memory_Face (ft_library, + (const FT_Byte *) blob_data, + blob_size, + index, + &ft_face))) + return nullptr; + + hb_face_t *face = hb_ft_face_create_referenced (ft_face); + FT_Done_Face (ft_face); + + ft_face->generic.data = ft_library; + ft_face->generic.finalizer = finalize_ft_library; + + if (hb_face_is_immutable (face)) + return nullptr; + + // Hook the blob to the hb_face_t, since FT_Face still needs it. + hb_blob_reference (blob); + if (!hb_face_set_user_data (face, &ft_blob_key, blob, _destroy_blob, true)) + { + hb_blob_destroy (blob); + hb_face_destroy (face); + return nullptr; + } + + return face; +} + static void _release_blob (void *arg) { diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h b/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h index 42bfb4f46744d5c064c492f7d7d66365002ff646..227b4f221bf2b2c01c016a1e82bfea4626c576f6 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h @@ -88,6 +88,10 @@ HB_EXTERN hb_face_t * hb_ft_face_create_from_file_or_fail (const char *file_name, unsigned int index); +HB_EXTERN hb_face_t * +hb_ft_face_create_from_blob_or_fail (hb_blob_t *blob, + unsigned int index); + /* * hb-font from ft-face. */ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-geometry.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-geometry.hh index 2f7fcb32857bb586d15abdcd8ca402677b64d7bc..c22a26a404a65f2a5dca6754b3f6c1a456835051 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-geometry.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-geometry.hh @@ -30,6 +30,11 @@ struct hb_extents_t { hb_extents_t () {} + hb_extents_t (const hb_glyph_extents_t &extents) : + xmin (hb_min (extents.x_bearing, extents.x_bearing + extents.width)), + ymin (hb_min (extents.y_bearing, extents.y_bearing + extents.height)), + xmax (hb_max (extents.x_bearing, extents.x_bearing + extents.width)), + ymax (hb_max (extents.y_bearing, extents.y_bearing + extents.height)) {} hb_extents_t (float xmin, float ymin, float xmax, float ymax) : xmin (xmin), ymin (ymin), xmax (xmax), ymax (ymax) {} @@ -38,6 +43,12 @@ struct hb_extents_t void union_ (const hb_extents_t &o) { + if (o.is_empty ()) return; + if (is_empty ()) + { + *this = o; + return; + } xmin = hb_min (xmin, o.xmin); ymin = hb_min (ymin, o.ymin); xmax = hb_max (xmax, o.xmax); @@ -46,6 +57,11 @@ struct hb_extents_t void intersect (const hb_extents_t &o) { + if (o.is_empty () || is_empty ()) + { + *this = hb_extents_t {}; + return; + } xmin = hb_max (xmin, o.xmin); ymin = hb_max (ymin, o.ymin); xmax = hb_min (xmax, o.xmax); @@ -69,6 +85,18 @@ struct hb_extents_t } } + hb_glyph_extents_t to_glyph_extents (bool xneg = false, bool yneg = false) const + { + hb_position_t x0 = (hb_position_t) roundf (xmin); + hb_position_t y0 = (hb_position_t) roundf (ymin); + hb_position_t x1 = (hb_position_t) roundf (xmax); + hb_position_t y1 = (hb_position_t) roundf (ymax); + return hb_glyph_extents_t {xneg ? x1 : x0, + yneg ? y0 : y1, + xneg ? x0 - x1 : x1 - x0, + yneg ? y1 - y0 : y0 - y1}; + } + float xmin = 0.f; float ymin = 0.f; float xmax = -1.f; @@ -218,7 +246,7 @@ struct hb_bounds_t EMPTY, }; - hb_bounds_t (status_t status) : status (status) {} + hb_bounds_t (status_t status = UNBOUNDED) : status (status) {} hb_bounds_t (const hb_extents_t &extents) : status (extents.is_empty () ? EMPTY : BOUNDED), extents (extents) {} diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc index 7ea0386223871c134ed20b9f50737e2eaf17c299..c547134d5f3f3be21b0ab33e80c18ba20bc0f34c 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc @@ -68,7 +68,7 @@ struct hb_graphite2_face_data_t { hb_face_t *face; gr_face *grface; - hb_atomic_ptr_t<hb_graphite2_tablelist_t> tlist; + hb_atomic_t<hb_graphite2_tablelist_t *> tlist; }; static const void *hb_graphite2_get_table (const void *data, unsigned int tag, size_t *len) diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh index ecff94f1b642e35778f887220e393ad795775923..6127c4d0ce53b7b8c314f120a89eb09801a94c5f 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh @@ -273,7 +273,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> private: /* Must only have one pointer. */ - hb_atomic_ptr_t<Stored *> instance; + hb_atomic_t<Stored *> instance; }; /* Specializations. */ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh index 5cffe1666b984b656d8607b373182b9369fb37b8..7b34d671fbfeb5796b2ce51a7e0ab480b60c5974 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh @@ -142,7 +142,7 @@ struct hb_lockable_set_t struct hb_reference_count_t { - mutable hb_atomic_int_t ref_count; + mutable hb_atomic_t<int> ref_count; void init (int v = 1) { ref_count = v; } int get_relaxed () const { return ref_count; } @@ -213,8 +213,8 @@ struct hb_user_data_array_t struct hb_object_header_t { hb_reference_count_t ref_count; - mutable hb_atomic_int_t writable = 0; - hb_atomic_ptr_t<hb_user_data_array_t> user_data; + mutable hb_atomic_t<bool> writable = false; + hb_atomic_t<hb_user_data_array_t *> user_data; bool is_inert () const { return !ref_count.get_relaxed (); } }; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh index 7437fddfa3822bda34c1fe7d60ac0549ca8817f4..f2040ea5c9c0698088c4762300dfc67c781f6169 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh @@ -1888,7 +1888,7 @@ struct TupleValues bool ensure_run () { - if (likely (run_count > 0)) return true; + if (run_count > 0) return true; if (unlikely (p >= end)) { @@ -1943,6 +1943,11 @@ struct TupleValues unsigned count = hb_min (n - i, (unsigned) run_count); switch (width) { + case 0: + { + arrayZ += count; + break; + } case 1: { const auto *pp = (const HBINT8 *) p; @@ -1958,6 +1963,8 @@ struct TupleValues #endif for (; j < count; j++) *arrayZ++ += scaled ? *pp++ * scale : *pp++; + + p = (const unsigned char *) pp; } break; case 2: @@ -1975,6 +1982,8 @@ struct TupleValues #endif for (; j < count; j++) *arrayZ++ += scaled ? *pp++ * scale : *pp++; + + p = (const unsigned char *) pp; } break; case 4: @@ -1982,10 +1991,11 @@ struct TupleValues const auto *pp = (const HBINT32 *) p; for (unsigned j = 0; j < count; j++) *arrayZ++ += scaled ? *pp++ * scale : *pp++; + + p = (const unsigned char *) pp; } break; } - p += count * width; run_count -= count; i += count; } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh index 666efeb925c8c26a8458091ac0b6b99b8b351954..9d3f4b2495372b156aefe1e820efb3ba33d52fd1 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh @@ -1176,7 +1176,8 @@ struct cff1 if (unlikely (!font_interp.interpret (*font))) goto fail; PRIVDICTVAL *priv = &privateDicts[i]; const hb_ubytes_t privDictStr = StructAtOffsetOrNull<UnsizedByteStr> (cff, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); - if (unlikely (privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; + if (unlikely (font->privateDictInfo.size && + privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; num_interp_env_t env2 (privDictStr); dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp (env2); priv->init (); @@ -1191,7 +1192,8 @@ struct cff1 PRIVDICTVAL *priv = &privateDicts[0]; const hb_ubytes_t privDictStr = StructAtOffsetOrNull<UnsizedByteStr> (cff, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); - if (unlikely (privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; + if (font->privateDictInfo.size && + unlikely (privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; num_interp_env_t env (privDictStr); dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp (env); priv->init (); @@ -1483,7 +1485,7 @@ struct cff1 int cmp (const gname_t &a) const { return cmp (&a, this); } }; - mutable hb_atomic_ptr_t<hb_sorted_vector_t<gname_t>> glyph_names; + mutable hb_atomic_t<hb_sorted_vector_t<gname_t> *> glyph_names; typedef accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t> SUPER; }; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc index 57023cb912cc416235fa580ca12c890a8e0b76b0..4157bd3b56936db93ef1898cd8190d5a4f3c8d9b 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc @@ -102,6 +102,14 @@ struct cff2_cs_opset_extents_t : cff2_cs_opset_t<cff2_cs_opset_extents_t, cff2_e bool OT::cff2::accelerator_t::get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const +{ + return get_extents_at (font, glyph, extents, hb_array (font->coords, font->num_coords)); +} + +bool OT::cff2::accelerator_t::get_extents_at (hb_font_t *font, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents, + hb_array_t<const int> coords) const { #ifdef HB_NO_OT_FONT_CFF /* XXX Remove check when this code moves to .hh file. */ @@ -112,7 +120,7 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font, unsigned int fd = fdSelect->get_fd (glyph); const hb_ubytes_t str = (*charStrings)[glyph]; - cff2_cs_interp_env_t<number_t> env (str, *this, fd, font->coords, font->num_coords); + cff2_cs_interp_env_t<number_t> env (str, *this, fd, coords.arrayZ, coords.length); cff2_cs_interpreter_t<cff2_cs_opset_extents_t, cff2_extents_param_t, number_t> interp (env); cff2_extents_param_t param; if (unlikely (!interp.interpret (param))) return false; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh index 0074d5bd85a90ac87f604c32d3e92dba93cc8a0d..536c918f0e3cf9c4ae4e19ffffb9a5492f56391b 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh @@ -458,7 +458,8 @@ struct cff2 if (unlikely (!font_interp.interpret (*font))) goto fail; const hb_ubytes_t privDictStr = StructAtOffsetOrNull<UnsizedByteStr> (cff2, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); - if (unlikely (privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; + if (unlikely (font->privateDictInfo.size && + privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; cff2_priv_dict_interp_env_t env2 (privDictStr); dict_interpreter_t<PRIVOPSET, PRIVDICTVAL, cff2_priv_dict_interp_env_t> priv_interp (env2); privateDicts[i].init (); @@ -481,6 +482,13 @@ struct cff2 privateDicts.fini (); hb_blob_destroy (blob); blob = nullptr; + + auto *scalars = cached_scalars_vector.get_acquire (); + if (scalars && cached_scalars_vector.cmpexch (scalars, nullptr)) + { + scalars->fini (); + hb_free (scalars); + } } hb_vector_t<uint16_t> *create_glyph_to_sid_map () const @@ -508,6 +516,8 @@ struct cff2 hb_vector_t<cff2_font_dict_values_t> fontDicts; hb_vector_t<PRIVDICTVAL> privateDicts; + mutable hb_atomic_t<hb_vector_t<float> *> cached_scalars_vector; + unsigned int num_glyphs = 0; }; @@ -518,6 +528,10 @@ struct cff2 HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; + HB_INTERNAL bool get_extents_at (hb_font_t *font, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents, + hb_array_t<const int> coords) const; HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const; HB_INTERNAL bool get_path_at (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session, hb_array_t<const int> coords) const; }; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc index 37d42e08d94e6f75437574438c203aa6e27d3b66..1436fe563f4342bc479ba3cc73f7a5cb4873045a 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc @@ -204,7 +204,7 @@ hb_ot_color_palette_get_colors (hb_face_t *face, hb_bool_t hb_ot_color_has_layers (hb_face_t *face) { - return face->table.COLR->has_v0_data (); + return face->table.COLR->colr->has_v0_data (); } /** @@ -221,7 +221,7 @@ hb_ot_color_has_layers (hb_face_t *face) hb_bool_t hb_ot_color_has_paint (hb_face_t *face) { - return face->table.COLR->has_v1_data (); + return face->table.COLR->colr->has_v1_data (); } /** @@ -240,7 +240,7 @@ hb_bool_t hb_ot_color_glyph_has_paint (hb_face_t *face, hb_codepoint_t glyph) { - return face->table.COLR->has_paint_for_glyph (glyph); + return face->table.COLR->colr->has_paint_for_glyph (glyph); } /** @@ -266,7 +266,7 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, unsigned int *layer_count, /* IN/OUT. May be NULL. */ hb_ot_color_layer_t *layers /* OUT. May be NULL. */) { - return face->table.COLR->get_glyph_layers (glyph, start_offset, layer_count, layers); + return face->table.COLR->colr->get_glyph_layers (glyph, start_offset, layer_count, layers); } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face-table-list.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face-table-list.hh index 97825f4d19c75acd665250d66b98936abff9d76a..afc8aa476e290274117b02042ffc3ed8d9fa2306 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face-table-list.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face-table-list.hh @@ -136,7 +136,7 @@ HB_OT_TABLE (AAT, feat) /* OpenType color fonts. */ #ifndef HB_NO_COLOR -HB_OT_CORE_TABLE (OT, COLR) +HB_OT_ACCELERATOR (OT, COLR) HB_OT_CORE_TABLE (OT, CPAL) HB_OT_ACCELERATOR (OT, CBDT) HB_OT_ACCELERATOR (OT, sbix) diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc index 1cf14f3ebc62a9f8d53bbd036d7b3fde90d6f072..d17f088073c309995ff712d9ca777da9f672fd84 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc @@ -36,6 +36,7 @@ #include "hb-ot-name-table.hh" #include "hb-ot-post-table.hh" #include "OT/Color/CBDT/CBDT.hh" +#include "OT/Color/COLR/COLR.hh" #include "OT/Color/sbix/sbix.hh" #include "OT/Color/svg/svg.hh" #include "hb-ot-layout-gdef-table.hh" diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc index edfece170b8f308d03fc2a775c3c01ba5b4cba5d..9bd0db4b8acbc6cc10ca1ab2f466bd0daacce693 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc @@ -85,8 +85,8 @@ struct hb_ot_font_t #endif /* h_advance caching */ - mutable hb_atomic_int_t cached_coords_serial; - mutable hb_atomic_ptr_t<hb_ot_font_advance_cache_t> advance_cache; + mutable hb_atomic_t<int> cached_coords_serial; + mutable hb_atomic_t<hb_ot_font_advance_cache_t *> advance_cache; }; static hb_ot_font_t * @@ -471,6 +471,9 @@ hb_ot_get_glyph_extents (hb_font_t *font, const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; const hb_ot_face_t *ot_face = ot_font->ot_face; +#ifndef HB_NO_VAR_COMPOSITES + if (ot_face->VARC->get_extents (font, glyph, extents)) return true; +#endif #if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR) if (ot_face->sbix->get_extents (font, glyph, extents)) return true; if (ot_face->CBDT->get_extents (font, glyph, extents)) return true; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh index d11a913c7128b6e66d841027be7c0cfa5ae695eb..33865450125f3f860d6b8eed53919b62cfa6a391 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh @@ -27,6 +27,7 @@ #ifndef HB_OT_KERN_TABLE_HH #define HB_OT_KERN_TABLE_HH +#include "hb-aat-layout-common.hh" #include "hb-aat-layout-kerx-table.hh" @@ -400,6 +401,7 @@ struct kern hb_blob_ptr_t<kern> table; AAT::kern_accelerator_data_t accel_data; + AAT::hb_aat_scratch_t scratch; }; protected: diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh index f9a5c1b9cfb4bf5c91ab68ff98faa72f4f78da0a..ad54a1d79c5ae06ef18030d7b0a1ff65c93f04b7 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh @@ -2565,7 +2565,7 @@ struct VarRegionList if (cache) { cached_value = &(cache[region_index]); - if (likely (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID)) + if (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID) return *cached_value; } @@ -2743,7 +2743,7 @@ struct SparseVarRegionList if (cache) { cached_value = &(cache[region_index]); - if (likely (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID)) + if (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID) return *cached_value; } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh index 183e08ccc3ea9d6514c370ced23bb82f125d2874..7d49710d11e3a582e7fc713bbd8db38920718767 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh @@ -4900,7 +4900,7 @@ struct GSUBGPOS this->lookup_count = table->get_lookup_count (); - this->accels = (hb_atomic_ptr_t<hb_ot_layout_lookup_accelerator_t> *) hb_calloc (this->lookup_count, sizeof (*accels)); + this->accels = (hb_atomic_t<hb_ot_layout_lookup_accelerator_t *> *) hb_calloc (this->lookup_count, sizeof (*accels)); if (unlikely (!this->accels)) { this->lookup_count = 0; @@ -4948,7 +4948,7 @@ struct GSUBGPOS hb_blob_ptr_t<T> table; unsigned int lookup_count; - hb_atomic_ptr_t<hb_ot_layout_lookup_accelerator_t> *accels; + hb_atomic_t<hb_ot_layout_lookup_accelerator_t *> *accels; }; protected: diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc index f7ad72fd4e9754fb385f8d3f582923f41f5e025c..3aca40eb7a9d57e99edbf9ade28cc6b1e026b150 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc @@ -131,13 +131,15 @@ hb_ot_layout_kern (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { - hb_blob_t *blob = font->face->table.kern.get_blob (); - const auto& kern = *font->face->table.kern; + auto &accel = *font->face->table.kern; + hb_blob_t *blob = accel.get_blob (); AAT::hb_aat_apply_context_t c (plan, font, buffer, blob); if (!buffer->message (font, "start table kern")) return; - kern.apply (&c); + c.buffer_glyph_set = accel.scratch.create_buffer_glyph_set (); + accel.apply (&c); + accel.scratch.destroy_buffer_glyph_set (c.buffer_glyph_set); (void) buffer->message (font, "end table kern"); } #endif diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh index 52dafbba4ea903d0818b5a21df6926dcac76bb92..ddec57e068f41dac662579070147229490d6b3cf 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh @@ -202,7 +202,8 @@ enum hb_unicode_props_flags_t { /* If GEN_CAT=FORMAT, top byte masks: */ UPROPS_MASK_Cf_ZWJ = 0x0100u, UPROPS_MASK_Cf_ZWNJ = 0x0200u, - UPROPS_MASK_Cf_VS = 0x0400u + UPROPS_MASK_Cf_VS = 0x0400u, + UPROPS_MASK_Cf_AAT_DELETED = 0x0800u }; HB_MARK_AS_FLAG_T (hb_unicode_props_flags_t); @@ -386,6 +387,8 @@ _hb_grapheme_group_func (const hb_glyph_info_t& a HB_UNUSED, static inline void _hb_ot_layout_reverse_graphemes (hb_buffer_t *buffer) { + // MONOTONE_GRAPHEMES was already applied and is taken care of by _hb_grapheme_group_func. + // So we just check for MONOTONE_CHARACTERS here. buffer->reverse_groups (_hb_grapheme_group_func, buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); } @@ -418,6 +421,17 @@ _hb_glyph_info_flip_joiners (hb_glyph_info_t *info) return; info->unicode_props() ^= UPROPS_MASK_Cf_ZWNJ | UPROPS_MASK_Cf_ZWJ; } +static inline bool +_hb_glyph_info_is_aat_deleted (const hb_glyph_info_t *info) +{ + return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_AAT_DELETED); +} +static inline void +_hb_glyph_info_set_aat_deleted (hb_glyph_info_t *info) +{ + _hb_glyph_info_set_general_category (info, HB_UNICODE_GENERAL_CATEGORY_FORMAT); + info->unicode_props() |= UPROPS_MASK_Cf_AAT_DELETED; +} /* lig_props: aka lig_id / lig_comp * diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh index 18ecea182564711b5542bf32badefcffa7307aa1..c8a58bdf85ea3118f45193a30379f429e914660e 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh @@ -290,7 +290,7 @@ struct post const Array16Of<HBUINT16> *glyphNameIndex = nullptr; hb_vector_t<uint32_t> index_to_offset; const uint8_t *pool = nullptr; - hb_atomic_ptr_t<uint16_t *> gids_sorted_by_name; + hb_atomic_t<uint16_t *> gids_sorted_by_name; }; bool has_data () const { return version.to_int (); } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc index c9defc49a20e092680ef67212d2c95f29d1aba04..dfc6be0fbd6ea7c86d48b4ed2dac9ad5f589cf8b 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc @@ -84,6 +84,7 @@ hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *fac props (props), map (face, props) #ifndef HB_NO_AAT_SHAPE + , aat_map (face, props) , apply_morx (_hb_apply_morx (face, props)) #endif { @@ -106,6 +107,10 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, plan.props = props; plan.shaper = shaper; map.compile (plan.map, key); +#ifndef HB_NO_AAT_SHAPE + if (apply_morx) + aat_map.compile (plan.aat_map); +#endif #ifndef HB_NO_OT_SHAPE_FRACTIONS plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c')); @@ -551,7 +556,7 @@ hb_form_clusters (hb_buffer_t *buffer) if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII)) return; - if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) + if (HB_BUFFER_CLUSTER_LEVEL_IS_GRAPHEMES (buffer->cluster_level)) foreach_grapheme (buffer, start, end) buffer->merge_clusters (start, end); else @@ -609,7 +614,7 @@ hb_ensure_native_direction (hb_buffer_t *buffer) * Ogham fonts are supposed to be implemented BTT or not. Need to research that * first. */ if ((HB_DIRECTION_IS_HORIZONTAL (direction) && - direction != horiz_dir && horiz_dir != HB_DIRECTION_INVALID) || + direction != horiz_dir && HB_DIRECTION_IS_VALID (horiz_dir)) || (HB_DIRECTION_IS_VERTICAL (direction) && direction != HB_DIRECTION_TTB)) { @@ -1109,10 +1114,6 @@ hb_ot_position_plan (const hb_ot_shape_context_t *c) /* Finish off. Has to follow a certain order. */ hb_ot_layout_position_finish_advances (c->font, c->buffer); hb_ot_zero_width_default_ignorables (c->buffer); -#ifndef HB_NO_AAT_SHAPE - if (c->plan->apply_morx) - hb_aat_layout_zero_width_deleted_glyphs (c->buffer); -#endif hb_ot_layout_position_finish_offsets (c->font, c->buffer); /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh index 791bc6896bb12ce477373070deb00f604c651ee3..49398818539b9891d9cb0e8a064456885cd6f12a 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh @@ -66,6 +66,7 @@ struct hb_ot_shape_plan_t hb_segment_properties_t props; const struct hb_ot_shaper_t *shaper; hb_ot_map_t map; + hb_aat_map_t aat_map; const void *data; #ifndef HB_NO_OT_SHAPE_FRACTIONS hb_mask_t frac_mask, numr_mask, dnom_mask; @@ -141,6 +142,7 @@ struct hb_ot_shape_planner_t hb_segment_properties_t props; hb_ot_map_builder_t map; #ifndef HB_NO_AAT_SHAPE + hb_aat_map_builder_t aat_map; bool apply_morx : 1; #else static constexpr bool apply_morx = false; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc index 4e3b512b482f752a8d8f8008648ea278b42d0d81..44b670fcc02f2fb2e302e650b910e60ffe7fa40a 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc @@ -260,7 +260,7 @@ struct arabic_shape_plan_t * mask_array[NONE] == 0. */ hb_mask_t mask_array[ARABIC_NUM_FEATURES + 1]; - hb_atomic_ptr_t<arabic_fallback_plan_t> fallback_plan; + hb_atomic_t<arabic_fallback_plan_t *> fallback_plan; unsigned int do_fallback : 1; unsigned int has_stch : 1; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-hangul.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-hangul.cc index c90476bc468b1b5f287c4236cef67a8373f4e4a1..50ea5327295f5f5cef5ced3bead83f15201fc3ca 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-hangul.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-hangul.cc @@ -298,8 +298,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, end = start + 2; if (unlikely (!buffer->successful)) break; - if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) - buffer->merge_out_clusters (start, end); + buffer->merge_out_clusters (start, end); continue; } } @@ -372,8 +371,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, if (i < end) info[i++].hangul_shaping_feature() = TJMO; - if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) - buffer->merge_out_clusters (start, end); + buffer->merge_out_clusters (start, end); continue; } else if ((!tindex && buffer->idx + 1 < count && isT (buffer->cur(+1).codepoint))) diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc index f8c970fc3eb5e3c26f69a834181cffc37b8935aa..5f57a672ee7122d04dfc69d84326cbe533725ed1 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc @@ -301,7 +301,7 @@ struct indic_shape_plan_t #else static constexpr bool uniscribe_bug_compatible = false; #endif - mutable hb_atomic_int_t virama_glyph; + mutable hb_atomic_t<hb_codepoint_t> virama_glyph; hb_indic_would_substitute_feature_t rphf; hb_indic_would_substitute_feature_t pref; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-thai.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-thai.cc index 6cd67cde35e65d94aed8ee88dc0b26acf466b057..6124a2114f8f84ed04a134a2d5de8e2edd778809 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-thai.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-thai.cc @@ -360,7 +360,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, { /* Since we decomposed, and NIKHAHIT is combining, merge clusters with the * previous cluster. */ - if (start && buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) + if (start) buffer->merge_out_clusters (start - 1, end); } } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc index 0c63756b14d4cc31ebe4d08adb76999620f38e2d..b70db154c58ad3cc584dafb9115a1e7d6de2113e 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc @@ -326,7 +326,7 @@ hb_ot_tags_from_language (const char *lang_str, hb_tag_t lang_tag = hb_tag_from_string (lang_str, first_len); - static hb_atomic_int_t last_tag_idx; /* Poor man's cache. */ + static hb_atomic_t<unsigned> last_tag_idx = 0; /* Poor man's cache. */ unsigned tag_idx = last_tag_idx; if (likely (tag_idx < ot_languages_len && ot_languages[tag_idx].language == lang_tag) || diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh index b388c7143c7c120333417bd6f1900fa4717c1237..b32720be7ca45828f951bc08dc6140b62cd3076a 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh @@ -53,10 +53,6 @@ struct hb_glyf_scratch_t contour_point_vector_t deltas; hb_vector_t<unsigned int> shared_indices; hb_vector_t<unsigned int> private_indices; - - // VARC - hb_vector_t<unsigned> axisIndices; - hb_vector_t<float> axisValues; }; namespace OT { diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-paint-extents.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-paint-extents.hh index 2d4491e07172987b392751ff6fcc162333f38413..708af4a860222226e262728b8feebc3be6305369 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-paint-extents.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-paint-extents.hh @@ -35,13 +35,22 @@ typedef struct hb_paint_extents_context_t hb_paint_extents_context_t; struct hb_paint_extents_context_t { - hb_paint_extents_context_t () + void clear () { + transforms.clear (); + clips.clear (); + groups.clear (); + transforms.push (hb_transform_t{}); clips.push (hb_bounds_t{hb_bounds_t::UNBOUNDED}); groups.push (hb_bounds_t{hb_bounds_t::EMPTY}); } + hb_paint_extents_context_t () + { + clear (); + } + hb_extents_t get_extents () { return groups.tail().extents; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.cc index 8eb24eb28b2ea66afc31f47bddba52671b1d52aa..755b181696e8bca6b41980a96e10ed94c614b42d 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.cc @@ -464,6 +464,42 @@ hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, funcs->push_transform (paint_data, xx, yx, xy, yy, dx, dy); } +/** + * hb_paint_push_font_transform: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * @font: a font + * + * Push the transform reflecting the font's scale and slant + * settings onto the paint functions. + * + * Since: 11.0.0 + */ +void +hb_paint_push_font_transform (hb_paint_funcs_t *funcs, void *paint_data, + const hb_font_t *font) +{ + funcs->push_font_transform (paint_data, font); +} + +/** + * hb_paint_push_inverse_font_transform: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * @font: a font + * + * Push the inverse of the transform reflecting the font's + * scale and slant settings onto the paint functions. + * + * Since: 11.0.0 + */ +void +hb_paint_push_inverse_font_transform (hb_paint_funcs_t *funcs, void *paint_data, + const hb_font_t *font) +{ + funcs->push_inverse_font_transform (paint_data, font); +} + /** * hb_paint_pop_transform: * @funcs: paint functions @@ -646,7 +682,7 @@ hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, float x0, float y0, float r0, float x1, float y1, float r1) { - funcs->radial_gradient (paint_data, color_line, x0, y0, r0, y1, x1, r1); + funcs->radial_gradient (paint_data, color_line, x0, y0, r0, x1, y1, r1); } /** diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.h b/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.h index d8896a5230a295c6f82029175963fffd64fbc42c..309213e2d7a82eeda0e1d22d076355616132fb6d 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.h +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.h @@ -956,6 +956,14 @@ hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, float xy, float yy, float dx, float dy); +HB_EXTERN void +hb_paint_push_font_transform (hb_paint_funcs_t *funcs, void *paint_data, + const hb_font_t *font); + +HB_EXTERN void +hb_paint_push_inverse_font_transform (hb_paint_funcs_t *funcs, void *paint_data, + const hb_font_t *font); + HB_EXTERN void hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.hh index 56b790dbee9886a0b17ce9452c52f158fdd511c5..5a7b903a072e9c67917240d205fffa9695ae99b0 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.hh @@ -157,7 +157,7 @@ struct hb_paint_funcs_t /* Internal specializations. */ - void push_root_transform (void *paint_data, + void push_font_transform (void *paint_data, const hb_font_t *font) { float upem = font->face->get_upem (); @@ -168,8 +168,8 @@ struct hb_paint_funcs_t xscale/upem, 0, slant * yscale/upem, yscale/upem, 0, 0); } - void push_inverse_root_transform (void *paint_data, - hb_font_t *font) + void push_inverse_font_transform (void *paint_data, + const hb_font_t *font) { float upem = font->face->get_upem (); int xscale = font->x_scale ? font->x_scale : upem; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh index f098bd4c1db539e14f7e1afc1c40b90cceece801..5cd983c0081c8264bfe8a7a87abd3657d39a48d3 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh @@ -30,6 +30,7 @@ #include "hb.hh" #include "hb-bit-set-invertible.hh" +#include "hb-bit-vector.hh" // Just to include template <typename impl_t> diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc index 844f7b9e806a5445e8c130241d474c5b7f2d3d26..c62f8c6bcdd8b7a61346d9f2e20a8f0854a00dbd 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc @@ -91,8 +91,10 @@ void free_static_shaper_list () * * Retrieves the list of shapers supported by HarfBuzz. * - * Return value: (transfer none) (array zero-terminated=1): an array of - * constant strings + * Return value: (transfer none) (array zero-terminated=1): a + * `NULL`-terminated array of supported shapers constant string. + * The returned array is owned by HarfBuzz and should not be + * modified or freed. * * Since: 0.9.2 **/ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc index c9bd0a61bf81299ad7f6255c0f804a1d173a71e2..e328bc48a49ef3023f056bc674be3dd5f0110436 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc @@ -41,6 +41,7 @@ #include "hb-ot-maxp-table.hh" #ifndef HB_NO_VISIBILITY + #include "hb-ot-name-language-static.hh" uint64_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = {}; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh index c3f7b40c8136bc79b9df26f7ec426bddf91f322c..c6532ad5eccdd5faa14d762a4cd67c83d9ae5c9e 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh @@ -570,7 +570,7 @@ struct cff_subset_accelerator_t parsed_cs_str_vec_t parsed_charstrings; parsed_cs_str_vec_t parsed_global_subrs; hb_vector_t<parsed_cs_str_vec_t> parsed_local_subrs; - mutable hb_atomic_ptr_t<glyph_to_sid_map_t> glyph_to_sid_map; + mutable hb_atomic_t<glyph_to_sid_map_t *> glyph_to_sid_map; private: hb_blob_t* original_blob; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh index 0e01d010f37c08a65ed99be73c21bfc7dcbd0f2c..2c1344c03a35411d4ff3bb3eda9f4369eed33d33 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh @@ -90,7 +90,13 @@ struct hb_vector_t { auto iter = hb_iter (o); if (iter.is_random_access_iterator || iter.has_fast_len) - alloc (hb_len (iter), true); + { + if (unlikely (!alloc (hb_len (iter), true))) + return; + unsigned count = hb_len (iter); + for (unsigned i = 0; i < count; i++) + push_has_room (*iter++); + } while (iter) { if (unlikely (!alloc (length + 1))) @@ -436,7 +442,6 @@ struct hb_vector_t new_allocated += (new_allocated >> 1) + 8; } - /* Reallocate */ bool overflows = diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-wasm-shape.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-wasm-shape.cc index a8b91879a43e48ccc18d665787b8cbb483ee7014..f83329e1c1bef0c3f92c53e5212f7c4feeb55c84 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-wasm-shape.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-wasm-shape.cc @@ -113,7 +113,7 @@ struct hb_wasm_shape_plan_t { struct hb_wasm_face_data_t { hb_blob_t *wasm_blob; wasm_module_t wasm_module; - mutable hb_atomic_ptr_t<hb_wasm_shape_plan_t> plan; + mutable hb_atomic_t<hb_wasm_shape_plan_t *> plan; }; static bool diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb.hh index 7c265483ff2c51aa9914925b7be364bcc17316c4..ffbfef099fbf8848ee12b2574b13df1a9e3ae67a 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb.hh @@ -230,33 +230,6 @@ #define HB_PASTE(a,b) HB_PASTE1(a,b) -/* Compile-time custom allocator support. */ - -#if !defined(HB_CUSTOM_MALLOC) \ - && defined(hb_malloc_impl) \ - && defined(hb_calloc_impl) \ - && defined(hb_realloc_impl) \ - && defined(hb_free_impl) -#define HB_CUSTOM_MALLOC -#endif - -#ifdef HB_CUSTOM_MALLOC -extern "C" void* hb_malloc_impl(size_t size); -extern "C" void* hb_calloc_impl(size_t nmemb, size_t size); -extern "C" void* hb_realloc_impl(void *ptr, size_t size); -extern "C" void hb_free_impl(void *ptr); -#define hb_malloc hb_malloc_impl -#define hb_calloc hb_calloc_impl -#define hb_realloc hb_realloc_impl -#define hb_free hb_free_impl -#else -#define hb_malloc malloc -#define hb_calloc calloc -#define hb_realloc realloc -#define hb_free free -#endif - - /* * Compiler attributes */ @@ -282,7 +255,7 @@ extern "C" void hb_free_impl(void *ptr); #define __attribute__(x) #endif -#if defined(__MINGW32__) && (__GNUC__ >= 3) +#if defined(__MINGW32__) && (__GNUC__ >= 3) && !defined(__clang__) #define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (gnu_printf, format_idx, arg_idx))) #elif defined(__GNUC__) && (__GNUC__ >= 3) #define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx))) @@ -539,6 +512,29 @@ static_assert ((sizeof (hb_var_int_t) == 4), ""); #define HB_PI 3.14159265358979f #define HB_2_PI (2.f * HB_PI) +/* Compile-time custom allocator support. */ + +#if !defined(HB_CUSTOM_MALLOC) \ + && defined(hb_malloc_impl) \ + && defined(hb_calloc_impl) \ + && defined(hb_realloc_impl) \ + && defined(hb_free_impl) +#define HB_CUSTOM_MALLOC +#endif + +#ifdef HB_CUSTOM_MALLOC +extern "C" void* hb_malloc_impl(size_t size); +extern "C" void* hb_calloc_impl(size_t nmemb, size_t size); +extern "C" void* hb_realloc_impl(void *ptr, size_t size); +extern "C" void hb_free_impl(void *ptr); +#else +#define hb_malloc_impl malloc +#define hb_calloc_impl calloc +#define hb_realloc_impl realloc +#define hb_free_impl free +#endif + + /* Headers we include for everyone. Keep topologically sorted by dependency. * They express dependency amongst themselves, but no other file should include diff --git a/source/libs/harfbuzz/harfbuzz-src/src/justify.py b/source/libs/harfbuzz/harfbuzz-src/src/justify.py index db2fb70104afa6fe02f30dcb745505e98e8dbbf8..8458d2ec681f639c5037469042f4f6e6100d72d0 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/justify.py +++ b/source/libs/harfbuzz/harfbuzz-src/src/justify.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + import gi gi.require_version("Gtk", "3.0") diff --git a/source/libs/harfbuzz/harfbuzz-src/src/meson.build b/source/libs/harfbuzz/harfbuzz-src/src/meson.build index 8e40e049893f1a9445290064063ef4dd7f1778ae..2ef82092ec782c4ad14d01b1d971bf00f63c6a66 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/meson.build +++ b/source/libs/harfbuzz/harfbuzz-src/src/meson.build @@ -28,6 +28,9 @@ hb_base_sources = files( 'hb-atomic.hh', 'hb-bimap.hh', 'hb-bit-page.hh', + 'hb-bit-set.hh', + 'hb-bit-set-invertible.hh', + 'hb-bit-vector.hh', 'hb-blob.cc', 'hb-blob.hh', 'hb-buffer-serialize.cc', @@ -199,6 +202,7 @@ hb_base_sources = files( 'hb-ot-os2-unicode-ranges.hh', 'hb-ot-post-macroman.hh', 'hb-ot-post-table.hh', + 'hb-ot-post-table-v2subset.hh', 'hb-ot-shaper-arabic-fallback.hh', 'hb-ot-shaper-arabic-joining-list.hh', 'hb-ot-shaper-arabic-pua.hh', @@ -241,7 +245,9 @@ hb_base_sources = files( 'hb-ot-var-varc-table.hh', 'hb-ot-var.cc', 'hb-ot-vorg-table.hh', + 'hb-priority-queue.hh', 'hb-pool.hh', + 'hb-repacker.hh', 'hb-sanitize.hh', 'hb-serialize.hh', 'hb-set-digest.hh', @@ -326,6 +332,9 @@ hb_base_headers += hb_version_h hb_ft_sources = files('hb-ft.cc', 'hb-ft-colr.hh') hb_ft_headers = files('hb-ft.h') +hb_fontations_sources = files() +hb_fontations_headers = files('hb-fontations.h') + hb_glib_sources = files('hb-glib.cc') hb_glib_headers = files('hb-glib.h') @@ -340,6 +349,7 @@ hb_wasm_sources = files( 'hb-wasm-api-common.hh', 'hb-wasm-api-face.hh', 'hb-wasm-api-font.hh', + 'hb-wasm-api-list.hh', 'hb-wasm-api-shape.hh', 'hb-wasm-shape.cc', ) @@ -347,10 +357,10 @@ hb_wasm_headers = files() # System-dependent sources and headers -hb_coretext_sources = files('hb-coretext-shape.cc', 'hb-coretext-font.cc') +hb_coretext_sources = files('hb-coretext.cc', 'hb-coretext.hh', 'hb-coretext-font.cc', 'hb-coretext-shape.cc') hb_coretext_headers = files('hb-coretext.h') -hb_directwrite_sources = files('hb-directwrite.cc') +hb_directwrite_sources = files('hb-directwrite.cc', 'hb-directwrite.hh', 'hb-directwrite-font.cc', 'hb-directwrite-shape.cc') hb_directwrite_headers = files('hb-directwrite.h') hb_gdi_sources = files('hb-gdi.cc') @@ -513,6 +523,15 @@ if conf.get('HAVE_CORETEXT', 0) == 1 harfbuzz_deps += coretext_deps endif +if conf.get('HAVE_FONTATIONS', 0) == 1 + + subdir('fontations') + + hb_sources += hb_fontations_sources + hb_headers += hb_fontations_headers + harfbuzz_deps += [harfbuzz_fontations_dep] +endif + have_icu = conf.get('HAVE_ICU', 0) == 1 have_icu_builtin = conf.get('HAVE_ICU_BUILTIN', 0) == 1 if have_icu and have_icu_builtin @@ -650,6 +669,7 @@ if conf.get('HAVE_CAIRO', 0) == 1 hb_cairo_sources = [ 'hb-cairo.cc', 'hb-cairo-utils.cc', + 'hb-cairo-utils.hh', 'hb-static.cc' ] @@ -663,7 +683,7 @@ if conf.get('HAVE_CAIRO', 0) == 1 include_directories: incconfig, dependencies: [m_dep, cairo_dep], link_with: [libharfbuzz], - cpp_args: cpp_args + extra_hb_cpp_args, + cpp_args: cpp_args + extra_hb_cpp_args, soversion: hb_so_version, version: version, install: true, diff --git a/source/libs/harfbuzz/harfbuzz-src/src/test-buffer-serialize.cc b/source/libs/harfbuzz/harfbuzz-src/src/test-buffer-serialize.cc index aced1c8d1b4beb2b4791d05e4fac396aee70e14f..421e5da6847d8a61dab98b3d3e49365b03a2e28b 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/test-buffer-serialize.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/test-buffer-serialize.cc @@ -43,6 +43,23 @@ main (int argc, char **argv) #ifndef HB_NO_BUFFER_SERIALIZE + hb_buffer_serialize_format_t format = HB_BUFFER_SERIALIZE_FORMAT_TEXT; + if (argc > 1) + { + if (!strcmp (argv[1], "--json")) + { + format = HB_BUFFER_SERIALIZE_FORMAT_JSON; + argc--; + argv++; + } + else if (!strcmp (argv[1], "--text")) + { + format = HB_BUFFER_SERIALIZE_FORMAT_TEXT; + argc--; + argv++; + } + } + if (argc < 2) argv[1] = (char *) "/dev/null"; @@ -68,10 +85,13 @@ main (int argc, char **argv) while (true) { const char *p = line; + const char *end = p + strlen (p); + if (p < end && *(end - 1) == '\n') + end--; if (!hb_buffer_deserialize_glyphs (buf, - p, -1, &p, + p, end - p, &p, font, - HB_BUFFER_SERIALIZE_FORMAT_TEXT)) + format)) { ret = false; break; @@ -97,7 +117,8 @@ main (int argc, char **argv) unsigned len; offset += hb_buffer_serialize_glyphs (buf, offset, count, out, sizeof (out), &len, - font, HB_BUFFER_SERIALIZE_FORMAT_TEXT, + font, + format, HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS); fwrite (out, 1, len, stdout); } diff --git a/source/libs/harfbuzz/include/Makefile.am b/source/libs/harfbuzz/include/Makefile.am index c208f1627891579113df7a8e468da7f42ab5322d..21d8da54f62f7810dd674a2b421473af43abccb2 100644 --- a/source/libs/harfbuzz/include/Makefile.am +++ b/source/libs/harfbuzz/include/Makefile.am @@ -1,4 +1,4 @@ -## $Id: Makefile.am 73427 2025-01-11 23:22:13Z kakuto $ +## $Id: Makefile.am 74729 2025-03-24 00:38:36Z kakuto $ ## Proxy Makefile.am to install harfbuzz headers for TeX Live. ## ## Copyright 2015-2016 Karl Berry <tex-live@tug.org> @@ -23,6 +23,7 @@ hdr_links = \ $(HARFBUZZ_SRC)/hb-draw.h \ $(HARFBUZZ_SRC)/hb-face.h \ $(HARFBUZZ_SRC)/hb-font.h \ + $(HARFBUZZ_SRC)/hb-fontations.h \ $(HARFBUZZ_SRC)/hb-map.h \ $(HARFBUZZ_SRC)/hb-ot-deprecated.h \ $(HARFBUZZ_SRC)/hb-paint.h \ diff --git a/source/libs/harfbuzz/include/Makefile.in b/source/libs/harfbuzz/include/Makefile.in index e6cf30dfe7a0cc645f300afcc0cbb96c3b4cb160..03b7908e86f12fd899aa9b5a9e5f0281c8015e06 100644 --- a/source/libs/harfbuzz/include/Makefile.in +++ b/source/libs/harfbuzz/include/Makefile.in @@ -255,10 +255,10 @@ hdr_links = $(HARFBUZZ_SRC)/hb.h $(HARFBUZZ_SRC)/hb-aat-layout.h \ $(HARFBUZZ_SRC)/hb-buffer.h $(HARFBUZZ_SRC)/hb-common.h \ $(HARFBUZZ_SRC)/hb-deprecated.h $(HARFBUZZ_SRC)/hb-draw.h \ $(HARFBUZZ_SRC)/hb-face.h $(HARFBUZZ_SRC)/hb-font.h \ - $(HARFBUZZ_SRC)/hb-map.h $(HARFBUZZ_SRC)/hb-ot-deprecated.h \ - $(HARFBUZZ_SRC)/hb-paint.h $(HARFBUZZ_SRC)/hb-set.h \ - $(HARFBUZZ_SRC)/hb-shape.h $(HARFBUZZ_SRC)/hb-shape-plan.h \ - $(HARFBUZZ_SRC)/hb-style.h \ + $(HARFBUZZ_SRC)/hb-fontations.h $(HARFBUZZ_SRC)/hb-map.h \ + $(HARFBUZZ_SRC)/hb-ot-deprecated.h $(HARFBUZZ_SRC)/hb-paint.h \ + $(HARFBUZZ_SRC)/hb-set.h $(HARFBUZZ_SRC)/hb-shape.h \ + $(HARFBUZZ_SRC)/hb-shape-plan.h $(HARFBUZZ_SRC)/hb-style.h \ $(HARFBUZZ_SRC)/hb-subset-serialize.h \ $(HARFBUZZ_SRC)/hb-unicode.h $(HARFBUZZ_BLD)/hb-version.h \ $(HARFBUZZ_SRC)/hb-ot.h $(HARFBUZZ_SRC)/hb-ot-color.h \ diff --git a/source/libs/harfbuzz/version.ac b/source/libs/harfbuzz/version.ac index c52799ab6d209b6aa16064da0c7e0b1e46f5808e..e71c57a1bccd4d8168f1bfe4b1ab8c0bc68cc788 100644 --- a/source/libs/harfbuzz/version.ac +++ b/source/libs/harfbuzz/version.ac @@ -8,4 +8,4 @@ dnl dnl -------------------------------------------------------- dnl dnl m4-include this file to define the current harfbuzz version -m4_define([harfbuzz_version], [10.4.0]) +m4_define([harfbuzz_version], [11.0.0]) diff --git a/source/texk/texlive/windows_wrapper/runscript.tlu b/source/texk/texlive/windows_wrapper/runscript.tlu index d6f5ef23c953d736942f489f1559f8bf1127cf4e..ca790556f4ff250b59523f32f890501727c570c6 100644 --- a/source/texk/texlive/windows_wrapper/runscript.tlu +++ b/source/texk/texlive/windows_wrapper/runscript.tlu @@ -1,7 +1,7 @@ -local svnrevision = string.match("$Revision: 71447 $", "%d+") or "0" -local svndate = string.match("$Date: 2024-06-06 09:46:11 +0200 (Thu, 06 Jun 2024) $", "[-%d]+") or "2009-12-04" +local svnrevision = string.match("$Revision: 74666 $", "%d+") or "0" +local svndate = string.match("$Date: 2025-03-17 04:44:40 +0100 (Mon, 17 Mar 2025) $", "[-%d]+") or "2009-12-04" local bannerstr = "runscript wrapper utility (rev. " .. svnrevision .. ", " .. svndate .. ")\n" .. "usage: runscript script-name [arguments]\n" .. @@ -843,11 +843,22 @@ elseif progname == 'latexdef' then progname = 'texdef' argline = ' --tex latex ' .. argline elseif progname == 'cllualatex' then +-- Originally argline was changed to add '--engine=...'. +-- However cllualatex and clxelatex did not work due to Engine +-- not specified error. This is because changed argline is not +-- used by dofile() for a lua script. +-- Here we rewrite arguments directly. (2025/03/17) progname = 'cluttex' - argline = ' --engine=lualatex ' .. argline + for k = #arg, 1, -1 do + arg[k+1] = arg[k] + end + arg[1] = '--engine=lualatex' elseif progname == 'clxelatex' then progname = 'cluttex' - argline = ' --engine=xelatex ' .. argline + for k = #arg, 1, -1 do + arg[k+1] = arg[k] + end + arg[1] = '--engine=xelatex' end -- general case diff --git a/source/texk/web2c/ChangeLog b/source/texk/web2c/ChangeLog index 992baa5086fa091ea2b90ed8cb2a47656f6ca10b..61ffcd29496b84d45085e0a181286b8cb3424e09 100644 --- a/source/texk/web2c/ChangeLog +++ b/source/texk/web2c/ChangeLog @@ -1,14 +1,33 @@ +2025-03-12 Andreas Scherer <https://ascherer.github.io> + + * weave.ch: Prevent get_line() when parsing module name. + Report and patch from Benjamin Gray + (https://tug.org/pipermail/tex-k/2025-March/004166.html). + +2025-03-12 Andreas Scherer <https://ascherer.github.io> + + * weave.ch: Parse and reject verbatim in TeX part. + Report and patch from Benjamin Gray + (https://tug.org/pipermail/tex-k/2025-March/004169.html). + +2025-03-11 Andreas Scherer <https://ascherer.github.io> + + * tangle.ch, + * tangleboot.pin: Prevent integer overflow in scan_numeric(). + Report and initial patch from Benjamin Gray + (https://tug.org/pipermail/tex-k/2025-March/004165.html). + 2025-03-10 Andreas Scherer <https://ascherer.github.io> - * texk/web2c/tangle.ch, - * texk/web2c/tangleboot.pin: Reject strings as macro names. + * tangle.ch, + * tangleboot.pin: Reject strings as macro names. Report and initial patch from Benjamin Gray (https://tug.org/pipermail/tex-k/2025-March/004163.html). 2025-03-10 Andreas Scherer <https://ascherer.github.io> - * texk/web2c/tangle.ch, - * texk/web2c/tangleboot.pin: Change case for letters only. + * tangle.ch, + * tangleboot.pin: Change case for letters only. Report and initial patch from Benjamin Gray (https://tug.org/pipermail/tex-k/2025-March/004161.html). diff --git a/source/texk/web2c/DIFF b/source/texk/web2c/DIFF new file mode 100644 index 0000000000000000000000000000000000000000..1b8ae50c3803ca3edbddd344696c4e5af84ab732 --- /dev/null +++ b/source/texk/web2c/DIFF @@ -0,0 +1,11 @@ +Files luatexdir/ChangeLog and /home/luigisvn/projects/texlive/trunk/Build/source/texk/web2c/luatexdir/ChangeLog differ +Files luatexdir/lua/ltexlib.c and /home/luigisvn/projects/texlive/trunk/Build/source/texk/web2c/luatexdir/lua/ltexlib.c differ +Only in luatexdir/luaffi: ffi.c.orig +Files luatexdir/luatex.c and /home/luigisvn/projects/texlive/trunk/Build/source/texk/web2c/luatexdir/luatex.c differ +Files luatexdir/luatex_svnversion.h and /home/luigisvn/projects/texlive/trunk/Build/source/texk/web2c/luatexdir/luatex_svnversion.h differ +Files luatexdir/tex/commands.c and /home/luigisvn/projects/texlive/trunk/Build/source/texk/web2c/luatexdir/tex/commands.c differ +Files luatexdir/tex/equivalents.h and /home/luigisvn/projects/texlive/trunk/Build/source/texk/web2c/luatexdir/tex/equivalents.h differ +Files luatexdir/tex/maincontrol.c and /home/luigisvn/projects/texlive/trunk/Build/source/texk/web2c/luatexdir/tex/maincontrol.c differ +Files luatexdir/tex/mlist.c and /home/luigisvn/projects/texlive/trunk/Build/source/texk/web2c/luatexdir/tex/mlist.c differ +Files luatexdir/tex/mlist.h and /home/luigisvn/projects/texlive/trunk/Build/source/texk/web2c/luatexdir/tex/mlist.h differ +Files luatexdir/tex/texmath.c and /home/luigisvn/projects/texlive/trunk/Build/source/texk/web2c/luatexdir/tex/texmath.c differ diff --git a/source/texk/web2c/cwebdir/ChangeLog b/source/texk/web2c/cwebdir/ChangeLog index 1ed6c99a679ba221605520a45e06b7fb0555aa52..b650e2b94d97047abf513b4a0bf74b00cfa29a59 100644 --- a/source/texk/web2c/cwebdir/ChangeLog +++ b/source/texk/web2c/cwebdir/ChangeLog @@ -1,3 +1,12 @@ +2025-03-12 Andreas Scherer <https://ascherer.github.io> + + * ctwill-w2c.ch, + * cweav-w2c.ch, + * cweave.w, + * po/cweb.pot, + * po/de/cweb.po, + * po/it/cweb.po: Handle verbatim strings in TeX part. + 2025-02-26 Andreas Scherer <https://ascherer.github.io> * tests/ham-sorted.tex, diff --git a/source/texk/web2c/cwebdir/cweav-w2c.ch b/source/texk/web2c/cwebdir/cweav-w2c.ch index 5838e0045d93f3e776f28d2cd9e4dcef8e847477..105e48ee139dd6c9d79ed012091b465b0f98034a 100644 --- a/source/texk/web2c/cwebdir/cweav-w2c.ch +++ b/source/texk/web2c/cwebdir/cweav-w2c.ch @@ -471,24 +471,30 @@ if (show_progress) printf("%s",_("\nWriting the output file...")); @z @x [12.232] l.4268 - err_print("! TeX string should be in C text only"); break; + err_print("! TeX string should be in C text only"); @y - err_print(_("! TeX string should be in C text only")); break; + err_print(_("! TeX string should be in C text only")); @z -@x [12.232] l.4274 +@x [12.232] l.4271 + err_print("! Verbatim string should be in C text only"); break; +@y + err_print(_("! Verbatim string should be in C text only")); break; +@z + +@x [12.232] l.4277 err_print("! You can't do that in TeX text"); break; @y err_print(_("! You can't do that in TeX text")); break; @z -@x [12.236] l.4346 +@x [12.236] l.4349 err_print("! Improper macro definition"); @y err_print(_("! Improper macro definition")); @z -@x [12.236] l.4359 +@x [12.236] l.4362 } @=/* otherwise fall through */@>@; default: err_print("! Improper macro definition"); break; @y @@ -496,62 +502,62 @@ if (show_progress) printf("%s",_("\nWriting the output file...")); default: err_print(_("! Improper macro definition")); break; @z -@x [12.237] l.4386 +@x [12.237] l.4389 if (scrap_ptr!=scrap_info+2) err_print("! Improper format definition"); @y if (scrap_ptr!=scrap_info+2) err_print(_("! Improper format definition")); @z -@x [12.240] l.4421 +@x [12.240] l.4424 err_print("! You need an = sign after the section name"); @y err_print(_("! You need an = sign after the section name")); @z -@x [12.241] l.4443 +@x [12.241] l.4446 err_print("! You can't do that in C text"); @y err_print(_("! You can't do that in C text")); @z -@x [13.247] l.4534 +@x [13.247] l.4537 if (show_progress) printf("%s","\nWriting the index..."); @y if (show_progress) printf("%s",_("\nWriting the index...")); @z -@x [13.247] l.4545 +@x [13.247] l.4548 fatal("! Cannot open index file ",idx_file_name); @y fatal(_("! Cannot open index file "),idx_file_name); @z -@x [13.247] l.4557 +@x [13.247] l.4560 fatal("! Cannot open section file ",scn_file_name); @y fatal(_("! Cannot open section file "),scn_file_name); @z -@x [13.247] l.4569 +@x [13.247] l.4572 fclose(active_file); @y fclose(active_file); active_file=tex_file=NULL; if (check_for_change) @<Update the result when it has changed@>@; @z -@x [13.247] l.4572 +@x [13.247] l.4575 printf("%s","Done."); @y printf("%s",_("Done.")); @z -@x [13.257] l.4724 +@x [13.257] l.4727 if (sort_ptr>=scrap_info_end) overflow("sorting"); @y if (sort_ptr>=scrap_info_end) overflow(_("sorting")); @z -@x [13.269] l.4861 +@x [13.269] l.4864 puts("\nMemory usage statistics:"); @.Memory usage statistics:@> printf("%td names (out of %ld)\n",@^system dependencies@> @@ -595,7 +601,7 @@ if (check_for_change) @<Update the result when it has changed@>@; (ptrdiff_t)(max_sort_ptr-scrap_info),(long)max_scraps); @z -@x [14.270] l.4883 +@x [14.270] l.4886 @** Index. @y @** Extensions to {\tentex CWEB}. The following sections introduce new or diff --git a/source/texk/web2c/cwebdir/cweave.w b/source/texk/web2c/cwebdir/cweave.w index 39de8a432be9298ab1e0fd359479b29de973e7ec..87095b1e00fe4efdc90fa8ccb62fee47c4ea0cc4 100644 --- a/source/texk/web2c/cwebdir/cweave.w +++ b/source/texk/web2c/cwebdir/cweave.w @@ -4261,12 +4261,15 @@ index entries are not copied and \CEE/ text within \pb\ is translated. switch (next_control=copy_TeX()) { case '|': init_stack(); output_C(); break; case '@@': out('@@'); break; - case TeX_string: case noop: + case TeX_string: case verbatim: case noop: case xref_roman: case xref_wildcard: case xref_typewriter: case section_name: loc-=2; next_control=get_next(); /* skip to \.{@@>} */ if (next_control==TeX_string) - err_print("! TeX string should be in C text only"); break; + err_print("! TeX string should be in C text only"); @.TeX string should be...@> + if (next_control==verbatim) + err_print("! Verbatim string should be in C text only"); break; +@.Verbatim string should be...@> case thin_space: case math_break: case ord: case line_break: case big_line_break: case no_line_break: case join: case pseudo_semi: case macro_arg_open: case macro_arg_close: diff --git a/source/texk/web2c/luatexdir/luatex_svnversion.h b/source/texk/web2c/luatexdir/luatex_svnversion.h index 147375209acbc19f24e922523a1b101c4cc8ef6e..89ac42960e9887430b559a9c6d21a9553491336d 100644 --- a/source/texk/web2c/luatexdir/luatex_svnversion.h +++ b/source/texk/web2c/luatexdir/luatex_svnversion.h @@ -1,4 +1,4 @@ #ifndef luatex_svn_revision_h #define luatex_svn_revision_h -#define luatex_svn_revision 7676 +#define luatex_svn_revision 7677 #endif diff --git a/source/texk/web2c/tangle.ch b/source/texk/web2c/tangle.ch index 8ce847bb3fbea7b6e2e11934fe33607e188fc458..1343ded43255cd7ccd61c8c222e79d9c3e87ead9 100644 --- a/source/texk/web2c/tangle.ch +++ b/source/texk/web2c/tangle.ch @@ -497,15 +497,10 @@ identifier: begin k:=0; j:=byte_start[cur_val]; w:=cur_val mod ww; end; @z -@x [11.119] l.2199 - Stretch limits of constants to match what we set for expressions. - if n>=@'2000000000 then err_print('! Constant too big') +@x [11.119] l.2185 - Calculate with decimal limit value INT_MAX/10. + if n>=@'1463146314 then err_print('! Constant too big') @y - if n>=@'10000000000 then err_print('! Constant too big') -@z -@x [11.119] l.2208 - if n>=@"8000000 then err_print('! Constant too big') -@y - if n>=@"40000000 then err_print('! Constant too big') + if n>=214748364 then err_print('! Constant too big') @z @x [14.157] l.2862 - Larger numerics. @@ -526,6 +521,31 @@ equiv[p]:=accumulator+@'10000000000; {name |p| now is defined to equal |accumula add_in(equiv[q]-@'10000000000); @z +@x [14.160] l.2915 - Avoid numeric overflow; see also section 119. +repeat val:=10*val+next_control-"0"; next_control:=get_next; +@y +repeat if val>=214748364 then err_print('! Constant too big') +@.Constant too big@> + else val:=10*val+next_control-"0"; + next_control:=get_next; +@z +@x [14.161] l.2920 - Avoid numeric overflow; see also section 119. +repeat val:=8*val+next_control-"0"; next_control:=get_next; +@y +repeat if val>=@'2000000000 then err_print('! Constant too big') +@.Constant too big@> + else val:=8*val+next_control-"0"; + next_control:=get_next; +@z +@x [14.162] l.2926 - Avoid numeric overflow; see also section 119. +val:=16*val+next_control-"0"; next_control:=get_next; +@y + if val>=@"8000000 then err_print('! Constant too big') +@.Constant too big@> + else val:=16*val+next_control-"0"; + next_control:=get_next; +@z + @x [15.165] l.2964 - Add parametric2 macros (macros that use [] to delimit arguments). "(": incr(bal); ")": if bal=0 then err_print('! Extra )') diff --git a/source/texk/web2c/tangleboot.pin b/source/texk/web2c/tangleboot.pin index a829f257d5f4df78d7c81dc1e60e66d343bb9b32..fac3b1b8e9c7c79206cde199fcf9e36c0e0073b2 100644 --- a/source/texk/web2c/tangleboot.pin +++ b/source/texk/web2c/tangleboot.pin @@ -479,12 +479,12 @@ write(stdout,'! Constant too big');error;end else n:=10*n+curchar; curchar:=getoutput;until(curchar>57)or(curchar<48);sendval(n);k:=0; if curchar=101 then curchar:=69;if curchar=69 then goto 2 else goto 21; end;125:sendval(poolchecksum);12:begin n:=0;curchar:=48; -repeat curchar:=curchar-48;if n>=1073741824 then begin writeln(stdout); +repeat curchar:=curchar-48;if n>=268435456 then begin writeln(stdout); write(stdout,'! Constant too big');error;end else n:=8*n+curchar; curchar:=getoutput;until(curchar>55)or(curchar<48);sendval(n);goto 21; end;13:begin n:=0;curchar:=48; repeat if curchar>=65 then curchar:=curchar-55 else curchar:=curchar-48; -if n>=1073741824 then begin writeln(stdout); +if n>=134217728 then begin writeln(stdout); write(stdout,'! Constant too big');error;end else n:=16*n+curchar; curchar:=getoutput; until(curchar>70)or(curchar<48)or((curchar>57)and(curchar<65)); @@ -699,16 +699,22 @@ var accumulator:integer;nextsign:-1..+1;q:namepointer;val:integer; begin{158:}accumulator:=0;nextsign:=+1; while true do begin nextcontrol:=getnext; 21:case nextcontrol of 48,49,50,51,52,53,54,55,56,57:begin{160:}val:=0; -repeat val:=10*val+nextcontrol-48;nextcontrol:=getnext; +repeat if val>=214748364 then begin writeln(stdout); +write(stdout,'! Constant too big');error; +end else val:=10*val+nextcontrol-48;nextcontrol:=getnext; until(nextcontrol>57)or(nextcontrol<48){:160}; begin accumulator:=accumulator+nextsign*(val);nextsign:=+1;end;goto 21; end;12:begin{161:}val:=0;nextcontrol:=48; -repeat val:=8*val+nextcontrol-48;nextcontrol:=getnext; +repeat if val>=268435456 then begin writeln(stdout); +write(stdout,'! Constant too big');error; +end else val:=8*val+nextcontrol-48;nextcontrol:=getnext; until(nextcontrol>55)or(nextcontrol<48){:161}; begin accumulator:=accumulator+nextsign*(val);nextsign:=+1;end;goto 21; end;13:begin{162:}val:=0;nextcontrol:=48; repeat if nextcontrol>=65 then nextcontrol:=nextcontrol-7; -val:=16*val+nextcontrol-48;nextcontrol:=getnext; +if val>=134217728 then begin writeln(stdout); +write(stdout,'! Constant too big');error; +end else val:=16*val+nextcontrol-48;nextcontrol:=getnext; until(nextcontrol>70)or(nextcontrol<48)or((nextcontrol>57)and( nextcontrol<65)){:162};begin accumulator:=accumulator+nextsign*(val); nextsign:=+1;end;goto 21;end;130:begin q:=idlookup(0);