diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/fontspec/fontspec-internal.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/fontspec/fontspec-internal.dtx | 949 |
1 files changed, 405 insertions, 544 deletions
diff --git a/Master/texmf-dist/source/latex/fontspec/fontspec-internal.dtx b/Master/texmf-dist/source/latex/fontspec/fontspec-internal.dtx index 467ccb77f71..85c16e3cadf 100644 --- a/Master/texmf-dist/source/latex/fontspec/fontspec-internal.dtx +++ b/Master/texmf-dist/source/latex/fontspec/fontspec-internal.dtx @@ -6,16 +6,10 @@ % \end{macrocode} % \fi % -% \subsection{Internal macros} +% \subsection{The main function for setting fonts} % \label{sec:codeinternal} % -% The macros from here in are used internally by all those defined above. -% They are not designed to remain consistent between versions. -% -% -% -% -% \begin{macro}{\fontspec_select:nn} +% \begin{macro}{\@@_select_font_family:nn} % This is the command that defines font families for use, the underlying % procedure of all \cmd\fontspec-like commands. Given a % list of font features (|#1|) for a requested font (|#2|), @@ -30,58 +24,122 @@ % \begin{itemize} % \item \cmd{\l_fontspec_fontname_tl} is used as the generic name of the font being defined. % \item \cmd{\l_@@_fontid_tl} is the unique identifier of the font with all its features. -% \item \cmd{\l_fontspec_fontname_up_tl} is the font specifically to be used as the upright font. +% \item \cmd{\l_@@_fontname_up_tl} is the font specifically to be used as the upright font. % \item \cmd{\l_@@_basename_tl} is the (immutable) original argument used for |*|-replacing. % \item \cmd{\l_fontspec_font} is the plain \TeX{} font of the upright font requested. % \end{itemize} % \begin{macrocode} -\cs_set:Nn \fontspec_select:nn +\cs_new_protected:Nn \@@_select_font_family:nn { +%<debug>\typeout{^^J^^J::::::::::::::::::::::::::::::^^J:: fontspec_select:nn~ {#1}~ {#2} } \group_begin: \@@_font_suppress_not_found_error: \@@_init: - \tl_set:Nx \l_fontspec_fontname_tl {#2} - \tl_set:Nx \l_fontspec_fontname_up_tl {#2} - \tl_set:Nx \l_@@_basename_tl {#2} + \@@_sanitise_fontname:Nn \l_fontspec_fontname_tl {#2} + \@@_sanitise_fontname:Nn \l_@@_fontname_up_tl {#2} + \@@_sanitise_fontname:Nn \l_@@_basename_tl {#2} + + \@@_if_detect_external:nT {#2} + { \keys_set:nn {fontspec-preparse-external} {Path} } + \@@_init_ttc:n {#2} \@@_load_external_fontoptions:Nn \l_fontspec_fontname_tl {#2} + \@@_extract_all_features:n {#1} - \@@_preparse_features: + \tl_set:Nx \l_@@_fontid_tl { \tl_to_str:N \l_fontspec_fontname_tl-:-\tl_to_str:N \l_@@_all_features_clist } + +%<debug>\typeout{fontid: \l_@@_fontid_tl} + \@@_preparse_features: \@@_load_font: \@@_set_scriptlang: \@@_get_features:Nn \l_@@_rawfeatures_sclist {} \bool_set_false:N \l_@@_firsttime_bool - \@@_save_family:nTF {#2} + \@@_save_family_needed:nTF {#2} { - \@@_save_fontinfo: - \@@_find_autofonts: - \DeclareFontFamily{\l_@@_nfss_enc_tl}{\l_fontspec_family_tl}{} - \@@_set_faces: - \@@_info:nxx {defining-font} {#1} {#2} -%<*debug> - \typeout{"\l_@@_fontid_tl"~ defined.} - \@@_warning:nxx {defining-font} {#1} {#2} -%</debug> + \@@_save_family:nn {#1} {#2} +%<debug> \@@_warning:nxx {defining-font} {#1} {#2} } { -%<*debug> - \typeout{"\l_@@_fontid_tl"~ already~ defined~ apparently.} -%</debug> +%<debug> \typeout{Font~ family~ already~ defined.} } \group_end: } % \end{macrocode} % \end{macro} % +% \begin{macro}{\fontspec_select:nn} +% This old name has been used by 3rd party packages so for compatibility: +% \begin{macrocode} +\cs_set_eq:NN \fontspec_select:nn \@@_select_font_family:nn +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_sanitise_fontname:Nn} +% Assigns font name |#2| to token list variable |#1| and strips extension(s) from it in the case of an external font. +% We strip spaces for luatex for consistency with luaotfload, although I'm not sure this is necessary any more. +% At one stage this also lowercased the name, but this step has been removed unless someone can remind me why it was necessary. +% \begin{macrocode} +\cs_new:Nn \@@_sanitise_fontname:Nn + { + \tl_set:Nx #1 {#2} +%<luatex> \tl_remove_all:Nn #1 {~} + \clist_map_inline:Nn \l_@@_extensions_clist + { + \tl_if_in:NnT #1 {##1} + { + \tl_remove_once:Nn #1 {##1} + \tl_set:Nn \l_@@_extension_tl {##1} + \clist_map_break: + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_if_detect_external:nT} +% Check if either the fontname ends with a known font extension. +% \begin{macrocode} +\prg_new_conditional:Nnn \@@_if_detect_external:n {T} + { +%<debug> \typeout{:: @@_if_detect_external:n { \exp_not:n {#1} } } + \clist_map_inline:Nn \l_@@_extensions_clist + { + \bool_set_false:N \l_@@_tmpa_bool + \exp_args:Nx % <- this should be handled earlier + \tl_if_in:nnT {#1 <= end_of_string} {##1 <= end_of_string} + { \bool_set_true:N \l_@@_tmpa_bool \clist_map_break: } + } + \bool_if:NTF \l_@@_tmpa_bool \prg_return_true: \prg_return_false: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_init_ttc:n} +% For TTC fonts we assume they will be loading the italic/bold fonts from the same file, +% so prepopulate the fontnames to avoid needing to do it manually. +% \begin{macrocode} +\cs_new:Nn \@@_init_ttc:n + { + \str_if_eq_x:nnT { \str_lower_case:f {\l_@@_extension_tl} } {.ttc} + { + \@@_sanitise_fontname:Nn \l_@@_fontname_it_tl {#1} + \@@_sanitise_fontname:Nn \l_@@_fontname_bf_tl {#1} + \@@_sanitise_fontname:Nn \l_@@_fontname_bfit_tl {#1} + } + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\@@_load_external_fontoptions:Nn} % Load a possible \texttt{.fontspec} font configuration file. % This file could set font-specific options for the font about to be loaded. % \begin{macrocode} \cs_new:Nn \@@_load_external_fontoptions:Nn { +%<debug> \typeout{:: @@_load_external_fontoptions:Nn \exp_not:N #1 {#2} } \@@_sanitise_fontname:Nn #1 {#2} \tl_set:Nx \l_@@_ext_filename_tl {#1.fontspec} \tl_remove_all:Nn \l_@@_ext_filename_tl {~} @@ -94,10 +152,11 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_extract_features:} +% \begin{macro}{\@@_extract_all_features:} % \begin{macrocode} \cs_new:Nn \@@_extract_all_features:n { +%<debug> \typeout{:: @@_extract_all_features:n { \unexpanded {#1} } } \bool_if:NTF \l_@@_disable_defaults_bool { \clist_set:Nx \l_@@_all_features_clist {#1} @@ -118,10 +177,6 @@ #1 } } - \tl_set:Nx \l_@@_fontid_tl { \tl_to_str:N \l_fontspec_fontname_tl-:-\tl_to_str:N \l_@@_all_features_clist } -%<*debug> - \typeout{fontid: \l_@@_fontid_tl} -%</debug> } % \end{macrocode} % \end{macro} @@ -138,25 +193,25 @@ % \begin{macrocode} \cs_new:Nn \@@_preparse_features: { +%<debug> \typeout{:: @@_preparse_features:} % \end{macrocode} % Detect if external fonts are to be used, possibly automatically, and % parse fontspec features for bold/italic fonts and their features. % \begin{macrocode} - \@@_if_detect_external:VT \l_@@_basename_tl - { \keys_set:nn {fontspec-preparse-external} {ExternalLocation} } - \keys_set_known:nxN {fontspec-preparse-external} + \@@_keys_set_known:nxN {fontspec-preparse-external} { \l_@@_all_features_clist } \l_@@_keys_leftover_clist + % \end{macrocode} % When \cmd{\l_fontspec_fontname_tl} is augmented with a prefix or whatever to create -% the name of the upright font (\cmd{\l_fontspec_fontname_up_tl}), this latter is the new `general +% the name of the upright font (\cmd{\l_@@_fontname_up_tl}), this latter is the new `general % font name' to use. % \begin{macrocode} - \tl_set_eq:NN \l_fontspec_fontname_tl \l_fontspec_fontname_up_tl - \keys_set_known:nxN {fontspec-renderer} {\l_@@_keys_leftover_clist} + \tl_set_eq:NN \l_fontspec_fontname_tl \l_@@_fontname_up_tl + \@@_keys_set_known:nxN {fontspec-renderer} {\l_@@_keys_leftover_clist} \l_@@_keys_leftover_clist - \keys_set_known:nxN {fontspec-preparse} {\l_@@_keys_leftover_clist} + \@@_keys_set_known:nxN {fontspec-preparse} {\l_@@_keys_leftover_clist} \l_@@_fontfeat_clist } % \end{macrocode} @@ -166,46 +221,67 @@ % \begin{macrocode} \cs_new:Nn \@@_load_font: { - \@@_font_set:Nnn \l_fontspec_font - { \@@_fullname:n {\l_fontspec_fontname_up_tl} } {\f@size pt} - \@@_font_if_null:NT \l_fontspec_font { \@@_error:nx {font-not-found} {\l_fontspec_fontname_up_tl} } +%<debug>\typeout{:: @@_load_font} +%<debug>\typeout{Set~ base~ font~ for~ preliminary~ analysis: \@@_construct_font_call:nn { \l_@@_fontname_up_tl } {} } + \@@_primitive_font_set:Nnn \l_fontspec_font + { \@@_construct_font_call:nn { \l_@@_fontname_up_tl } {} } {\f@size pt} + \@@_primitive_font_if_null:NT \l_fontspec_font { \@@_error:nx {font-not-found} {\l_@@_fontname_up_tl} } \@@_set_font_type: - \@@_font_gset:Nnn \l_fontspec_font - { \@@_fullname:n {\l_fontspec_fontname_up_tl} } {\f@size pt} +%<debug>\typeout{Set~ base~ font~ properly: \@@_construct_font_call:nn { \l_@@_fontname_up_tl } {} } + \@@_primitive_font_gset:Nnn \l_fontspec_font + { \@@_construct_font_call:nn { \l_@@_fontname_up_tl } {} } {\f@size pt} \l_fontspec_font % this is necessary for LuaLaTeX to check the scripts properly } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_if_detect_external:nnT} -% Check if either the fontname ends with a known font extension. +% \begin{macro}{\@@_construct_font_call:nn} +% Constructs the complete font invocation. +% \darg{Base name} +% \darg{Extension} +% \darg{TTC Index} +% \darg{Renderer} +% \darg{Optical size} +% \darg{Font features} +% We check if \meta{Font features} are empty and if so don't add in the separator colon. % \begin{macrocode} -\prg_new_conditional:Nnn \@@_if_detect_external:n {T} +\cs_set:Nn \@@_construct_font_call:nnnnnn { - \clist_map_inline:Nn \l_@@_extensions_clist - { - \bool_set_false:N \l_@@_tmpa_bool - \tl_if_in:nnT {#1 <= end_of_string} {##1 <= end_of_string} - { \bool_set_true:N \l_@@_tmpa_bool \clist_map_break: } - } - \bool_if:NTF \l_@@_tmpa_bool \prg_return_true: \prg_return_false: + " \@@_fontname_wrap:n { #1 #2 #3 } #4 #5 + \str_if_eq_x:nnF {#6}{} {:#6} " } -\cs_generate_variant:Nn \@@_if_detect_external:nT {V} % \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_fullname:n} -% Constructs the complete font name based on a common piece of info. +% In practice, we don't use the six-argument version, since most arguments are constructed on-the-fly: % \begin{macrocode} -\cs_set:Nn \@@_fullname:n +\cs_set:Nn \@@_construct_font_call:nn { - \@@_namewrap:n { #1 \l_@@_extension_tl } - \l_fontspec_renderer_tl - \l_@@_optical_size_tl + \@@_construct_font_call:nnnnnn + {#1} + \l_@@_extension_tl + \l_@@_ttc_index_tl + \l_fontspec_renderer_tl + \l_@@_optical_size_tl + {#2} } % \end{macrocode} % \end{macro} % +% \begin{macro}{\@@_font_is_file:,\@@_font_is_name:} +% The \cs{@@_fontname_wrap:n} command takes the font name and either passes it through unchanged or wraps it in the syntax for loading a font `by filename'. +% \XeTeX's syntax is followed since \pkg{luaotfload} provides compatibility. +% \begin{macrocode} +\cs_new:Nn \@@_font_is_name: + { + \cs_set_eq:NN \@@_fontname_wrap:n \use:n + } +\cs_new:Nn \@@_font_is_file: + { +%<xetexx> \cs_set:Npn \@@_fontname_wrap:n ##1 { [ \l_@@_font_path_tl ##1 ] } +%<luatex> \cs_set:Npn \@@_fontname_wrap:n ##1 { file:\l_@@_font_path_tl ##1 } + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\@@_set_scriptlang:} % Only necessary for OpenType fonts. % First check if the font supports scripts, then apply defaults if @@ -217,15 +293,15 @@ { \tl_if_empty:NTF \l_@@_script_name_tl { - \fontspec_check_script:nTF {latn} + \@@_check_script:nTF {latn} { \tl_set:Nn \l_@@_script_name_tl {Latin} \tl_if_empty:NT \l_@@_lang_name_tl { \tl_set:Nn \l_@@_lang_name_tl {Default} } - \keys_set:nx {fontspec} {Script=\l_@@_script_name_tl} - \keys_set:nx {fontspec} {Language=\l_@@_lang_name_tl} + \keys_set:nx {fontspec-opentype} {Script=\l_@@_script_name_tl} + \keys_set:nx {fontspec-opentype} {Language=\l_@@_lang_name_tl} } { \@@_info:n {no-scripts} @@ -236,16 +312,58 @@ { \tl_set:Nn \l_@@_lang_name_tl {Default} } - \keys_set:nx {fontspec} {Script=\l_@@_script_name_tl} - \keys_set:nx {fontspec} {Language=\l_@@_lang_name_tl} + \keys_set:nx {fontspec-opentype} {Script=\l_@@_script_name_tl} + \keys_set:nx {fontspec-opentype} {Language=\l_@@_lang_name_tl} } } } % \end{macrocode} % \end{macro} % +% \begin{macro}{\@@_get_features:Nn} +% This macro is a wrapper for |\keys_set:nn| which expands and adds a +% default specification to the original passed options. It begins by +% initialising the commands used to hold font-feature specific +% strings. +% Its argument is any additional features to prepend to the default. +% +% Do not set the colour if not explicitly spec'd else \verb|\color| (using +% specials) will not work. +% \begin{macrocode} +\cs_set:Nn \@@_get_features:Nn + { +%<debug> \typeout{:: @@_get_features:Nn \exp_not:N #1 { \exp_not:n {#2} } } + \@@_init_fontface: + \@@_keys_set_known:nxN {fontspec-renderer} {\l_@@_fontfeat_clist,#2} + \l_@@_keys_leftover_clist + \@@_keys_set_known:nxN {fontspec} {\l_@@_keys_leftover_clist} \l_@@_keys_leftover_clist +%<*xetexx> + \bool_if:NTF \l_@@_ot_bool + { +%<debug> \typeout{::: Setting~ keys~ for~ OpenType~ font~ features:~"\l_@@_keys_leftover_clist"} + \keys_set:nx {fontspec-opentype} {\l_@@_keys_leftover_clist} + } + { +%<debug> \typeout{::: Setting~ keys~ for~ AAT~ font~ features:~"\l_@@_keys_leftover_clist"} + \bool_if:NT \l_@@_atsui_bool + { \keys_set:nx {fontspec-aat} {\l_@@_keys_leftover_clist} } + } +%</xetexx> +%<*luatex> +%<debug> \typeout{::: Setting~ keys~ for~ OpenType~ font~ features:~"\l_@@_keys_leftover_clist"} + \keys_set:nx {fontspec-opentype} {\l_@@_keys_leftover_clist} +%</luatex> + + \str_if_eq_x:nnF { \l_@@_hexcol_tl \l_@@_opacity_tl } + { \g_@@_hexcol_tl \g_@@_opacity_tl } + { \@@_update_featstr:n { color = \l_@@_hexcol_tl\l_@@_opacity_tl } } + + \tl_set_eq:NN #1 \l_@@_rawfeatures_sclist + } +% \end{macrocode} +% \end{macro} % -% \begin{macro}{\@@_save_family:nTF} +% \begin{macro}{\@@_save_family_needed:nTF} % Check if the family is unique and, if so, save its information. % (\cs{addfontfeature} and other macros use this data.) % Then the font family and its shapes are defined in the NFSS. @@ -256,9 +374,12 @@ % selecting. % % \begin{macrocode} -\prg_new_conditional:Nnn \@@_save_family:n {TF} +\prg_new_conditional:Nnn \@@_save_family_needed:n {TF} { -%<debug>\typeout{save~ family:~ #1} + +%<debug> \typeout{save~ family:~ #1} +%<debug> \typeout{== fontid_tl: "\l_@@_fontid_tl".} + \cs_if_exist:NT \l_@@_nfss_fam_tl { \cs_set_eq:cN {g_@@_UID_\l_@@_fontid_tl} \l_@@_nfss_fam_tl @@ -285,30 +406,42 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\@@_save_family:nn} +% Saves the relevant font information for future processing. +% \begin{macrocode} +\cs_new:Nn \@@_save_family:nn + { + \@@_save_fontinfo:n {#2} + \@@_find_autofonts: + \DeclareFontFamily{\l_@@_nfss_enc_tl}{\l_fontspec_family_tl}{} + \@@_set_faces: + \@@_info:nxx {defining-font} {#1} {#2} + } +% \end{macrocode} +% \end{macro} % -% \begin{macro}{\@@_save_fontinfo:nn} +% \begin{macro}{\@@_save_fontinfo:n} % Saves the relevant font information for future processing. % \begin{macrocode} -\cs_new:Nn \@@_save_fontinfo: +\cs_new:Nn \@@_save_fontinfo:n { \prop_new:c {g_@@_ \l_fontspec_family_tl _prop} - \prop_gput:cnx {g_@@_ \l_fontspec_family_tl _prop} {fontname} { \l_@@_basename_tl } + \prop_gput:cnx {g_@@_ \l_fontspec_family_tl _prop} {fontname} { #1 } \prop_gput:cnx {g_@@_ \l_fontspec_family_tl _prop} {options} { \l_@@_all_features_clist } \prop_gput:cnx {g_@@_ \l_fontspec_family_tl _prop} {fontdef} { - \@@_fullname:n {\l_fontspec_fontname_tl} : - \l_@@_pre_feat_sclist \l_@@_rawfeatures_sclist + \@@_construct_font_call:nn {\l_fontspec_fontname_tl} + { \l_@@_pre_feat_sclist \l_@@_rawfeatures_sclist } } - \prop_gput:cnV {g_@@_ \l_fontspec_family_tl _prop} {script-num} \l_fontspec_script_int - \prop_gput:cnV {g_@@_ \l_fontspec_family_tl _prop} {lang-num} \l_fontspec_language_int + \prop_gput:cnV {g_@@_ \l_fontspec_family_tl _prop} {script-num} \l_@@_script_int + \prop_gput:cnV {g_@@_ \l_fontspec_family_tl _prop} {lang-num} \l_@@_language_int \prop_gput:cnV {g_@@_ \l_fontspec_family_tl _prop} {script-tag} \l_fontspec_script_tl \prop_gput:cnV {g_@@_ \l_fontspec_family_tl _prop} {lang-tag} \l_fontspec_lang_tl - } % \end{macrocode} % \end{macro} % -% \subsubsection{Setting font shapes in a family} +% \subsection{Setting font shapes in a family} % % All NFSS specifications take their default values, so if any of them % are redefined, the shapes will be selected to fit in with the @@ -325,22 +458,22 @@ { \bool_if:nF {\l_@@_noit_bool || \l_@@_nobf_bool} { - \@@_set_autofont:Nnn \l_fontspec_fontname_bfit_tl {\l_fontspec_fontname_it_tl} {/B} - \@@_set_autofont:Nnn \l_fontspec_fontname_bfit_tl {\l_fontspec_fontname_bf_tl} {/I} - \@@_set_autofont:Nnn \l_fontspec_fontname_bfit_tl {\l_fontspec_fontname_tl} {/BI} + \@@_set_autofont:Nnn \l_@@_fontname_bfit_tl {\l_@@_fontname_it_tl} {/B} + \@@_set_autofont:Nnn \l_@@_fontname_bfit_tl {\l_@@_fontname_bf_tl} {/I} + \@@_set_autofont:Nnn \l_@@_fontname_bfit_tl {\l_fontspec_fontname_tl} {/BI} } \bool_if:NF \l_@@_nobf_bool { - \@@_set_autofont:Nnn \l_fontspec_fontname_bf_tl {\l_fontspec_fontname_tl} {/B} + \@@_set_autofont:Nnn \l_@@_fontname_bf_tl {\l_fontspec_fontname_tl} {/B} } \bool_if:NF \l_@@_noit_bool { - \@@_set_autofont:Nnn \l_fontspec_fontname_it_tl {\l_fontspec_fontname_tl} {/I} + \@@_set_autofont:Nnn \l_@@_fontname_it_tl {\l_fontspec_fontname_tl} {/I} } - \@@_set_autofont:Nnn \l_fontspec_fontname_bfsl_tl {\l_fontspec_fontname_sl_tl} {/B} + \@@_set_autofont:Nnn \l_@@_fontname_bfsl_tl {\l_@@_fontname_sl_tl} {/B} } % \end{macrocode} % \end{macro} @@ -350,11 +483,11 @@ \cs_new:Nn \@@_set_faces: { \@@_add_nfssfont:nnnn \mddefault \updefault \l_fontspec_fontname_tl \l_@@_fontfeat_up_clist - \@@_add_nfssfont:nnnn \bfdefault \updefault \l_fontspec_fontname_bf_tl \l_@@_fontfeat_bf_clist - \@@_add_nfssfont:nnnn \mddefault \itdefault \l_fontspec_fontname_it_tl \l_@@_fontfeat_it_clist - \@@_add_nfssfont:nnnn \mddefault \sldefault \l_fontspec_fontname_sl_tl \l_@@_fontfeat_sl_clist - \@@_add_nfssfont:nnnn \bfdefault \itdefault \l_fontspec_fontname_bfit_tl \l_@@_fontfeat_bfit_clist - \@@_add_nfssfont:nnnn \bfdefault \sldefault \l_fontspec_fontname_bfsl_tl \l_@@_fontfeat_bfsl_clist + \@@_add_nfssfont:nnnn \bfdefault \updefault \l_@@_fontname_bf_tl \l_@@_fontfeat_bf_clist + \@@_add_nfssfont:nnnn \mddefault \itdefault \l_@@_fontname_it_tl \l_@@_fontfeat_it_clist + \@@_add_nfssfont:nnnn \mddefault \sldefault \l_@@_fontname_sl_tl \l_@@_fontfeat_sl_clist + \@@_add_nfssfont:nnnn \bfdefault \itdefault \l_@@_fontname_bfit_tl \l_@@_fontfeat_bfit_clist + \@@_add_nfssfont:nnnn \bfdefault \sldefault \l_@@_fontname_bfsl_tl \l_@@_fontfeat_bfsl_clist \prop_map_inline:Nn \l_@@_nfssfont_prop { \@@_set_faces_aux:nnnnn ##2 } } @@ -366,6 +499,42 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\fontspec_complete_fontname:Nn} +% This macro defines |#1| as the input with any |*| tokens of its input +% replaced by the font name. This lets us define supplementary fonts in full +% (``\texttt{Baskerville Semibold}'') or in abbreviation (``\texttt{* Semibold}''). +% \begin{macrocode} +\cs_set:Nn \fontspec_complete_fontname:Nn + { + \tl_set:Nx #1 {#2} + \tl_replace_all:Nnx #1 {*} {\l_@@_basename_tl} +%<luatex> \tl_remove_all:Nn #1 {~} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_add_nfssfont:nnnn} +% \darg{series} +% \darg{shape} +% \darg{fontname} +% \darg{fontspec features} +% \begin{macrocode} +\cs_new:Nn \@@_add_nfssfont:nnnn + { + \tl_set:Nx \l_@@_this_font_tl {#3} + + \tl_if_empty:xTF {#4} + { \clist_set:Nn \l_@@_sizefeat_clist {Size={-}} } + { \@@_keys_set_known:nxN {fontspec-preparse-nested} {#4} \l_@@_tmp_tl } + + \tl_if_empty:NF \l_@@_this_font_tl + { + \prop_put:Nxx \l_@@_nfssfont_prop {#1/#2} + { {#1}{#2}{\l_@@_this_font_tl}{#4}{\l_@@_sizefeat_clist} } + } + } +% \end{macrocode} +% \end{macro} % % % \subsubsection{Fonts} @@ -380,8 +549,9 @@ % Multiple Master), respectively. % \begin{macrocode} \cs_new:Nn \@@_set_font_type: -%<*xetexx> { +%<debug> \typeout{:: @@_set_font_type:} +%<*xetexx> \bool_set_false:N \l_@@_tfm_bool \bool_set_false:N \l_@@_atsui_bool \bool_set_false:N \l_@@_ot_bool @@ -412,17 +582,14 @@ { \tl_set:Nn \l_fontspec_renderer_tl {/OT} } } } - } %</xetexx> %<*luatex> - { \bool_set_true:N \l_@@_ot_bool - } %</luatex> + } % \end{macrocode} % \end{macro} % -% % \begin{macro}{\@@_set_autofont:Nnn} % \darg{Font name tl} % \darg{Base font name} @@ -438,7 +605,6 @@ % If not found, \meta{font name tl} remains empty. % Otherwise, we have a match. % \begin{macrocode} -\cs_generate_variant:Nn \tl_if_empty:nF {x} \cs_new:Nn \@@_set_autofont:Nnn { \bool_if:NF \l_@@_external_bool @@ -457,8 +623,8 @@ \prg_new_conditional:Nnn \@@_if_autofont:nn {T,TF} { - \@@_font_set:Nnn \l_tmpa_font { \@@_fullname:n {#1} } {\f@size pt} - \@@_font_set:Nnn \l_tmpb_font { \@@_fullname:n {#1#2} } {\f@size pt} + \@@_primitive_font_set:Nnn \l_tmpa_font { \@@_construct_font_call:nn {#1} {} } {\f@size pt} + \@@_primitive_font_set:Nnn \l_tmpb_font { \@@_construct_font_call:nn {#1#2} {} } {\f@size pt} \str_if_eq_x:nnTF { \fontname \l_tmpa_font } { \fontname \l_tmpb_font } { \prg_return_false: } { \prg_return_true: } @@ -478,7 +644,7 @@ \cs_new:Nn \@@_make_font_shapes:Nnnnn { \group_begin: - \keys_set_known:nxN {fontspec-preparse-external} { #4 } \l_@@_leftover_clist + \@@_keys_set_known:nxN {fontspec-preparse-external} { #4 } \l_@@_leftover_clist \@@_load_fontname:n {#1} \@@_declare_shape:nnxx {#2} {#3} { \l_@@_fontopts_clist, \l_@@_leftover_clist } {#5} \group_end: @@ -486,11 +652,12 @@ \cs_new:Nn \@@_load_fontname:n { +%<debug> \typeout{:: @@_load_fontname:n {#1} } \@@_load_external_fontoptions:Nn \l_fontspec_fontname_tl {#1} \prop_get:NVNF \g_@@_fontopts_prop \l_fontspec_fontname_tl \l_@@_fontopts_clist { \clist_clear:N \l_@@_fontopts_clist } - \@@_font_set:Nnn \l_fontspec_font {\@@_fullname:n {\l_fontspec_fontname_tl}} {\f@size pt} - \@@_font_if_null:NT \l_fontspec_font { \@@_error:nx {font-not-found} {#1} } + \@@_primitive_font_set:Nnn \l_fontspec_font { \@@_construct_font_call:nn {\l_fontspec_fontname_tl} {} } {\f@size pt} + \@@_primitive_font_if_null:NT \l_fontspec_font { \@@_error:nx {font-not-found} {#1} } } % \end{macrocode} % \end{macro} @@ -510,97 +677,122 @@ % \begin{macrocode} \cs_new:Nn \@@_declare_shape:nnnn { +%<debug>\typeout{=~ declare_shape:~{\l_fontspec_fontname_tl}~{#1}~{#2}} \tl_clear:N \l_@@_nfss_tl \tl_clear:N \l_@@_nfss_sc_tl \tl_set_eq:NN \l_@@_saved_fontname_tl \l_fontspec_fontname_tl - \exp_args:Nx \clist_map_inline:nn {#4} - { + \exp_args:Nx \clist_map_inline:nn {#4} { \@@_setup_single_size:nn {#3} {##1} } + + \@@_declare_shapes_normal:nn {#1} {#2} + \@@_declare_shapes_smcaps:nn {#1} {#2} + \@@_declare_shape_slanted:nn {#1} {#2} + \@@_declare_shape_loginfo:nn {#1} {#2} + } +\cs_generate_variant:Nn \@@_declare_shape:nnnn {nnxx} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_setup_single_size:nn} +% \begin{macrocode} +\cs_new:Nn \@@_setup_single_size:nn + { \tl_clear:N \l_@@_size_tl \tl_set_eq:NN \l_@@_sizedfont_tl \l_@@_saved_fontname_tl % in case not spec'ed - \keys_set_known:nxN {fontspec-sizing} { \exp_after:wN \use:n ##1 } + \keys_set_known:nxN {fontspec-sizing} { \exp_after:wN \use:n #2 } \l_@@_sizing_leftover_clist \tl_if_empty:NT \l_@@_size_tl { \@@_error:n {no-size-info} } +%<debug>\typeout{==~ size:~\l_@@_size_tl} % "normal" \@@_load_fontname:n {\l_@@_sizedfont_tl} - \@@_setup_nfss:Nnn \l_@@_nfss_tl {#3} {} + \@@_setup_nfss:Nnnn \l_@@_nfss_tl {#1} {\l_@@_sizing_leftover_clist} {} +%<debug> \typeout{===~ sized~ font:~ \l_@@_sizedfont_tl} % small caps \clist_set_eq:NN \l_@@_fontfeat_curr_clist \l_@@_fontfeat_sc_clist \bool_if:NF \l_@@_nosc_bool { - \tl_if_empty:NTF \l_fontspec_fontname_sc_tl + \tl_if_empty:NTF \l_@@_fontname_sc_tl { -%<debug> \typeout{Attempting~ small~ caps?} \@@_make_smallcaps:TF { -%<debug> \typeout{Small~ caps~ found.} +%<debug>\typeout{====~Small~ caps~ found.} \clist_put_left:Nn \l_@@_fontfeat_curr_clist {Letters=SmallCaps} } { -%<debug> \typeout{Small~ caps~ not~ found.} +%<debug>\typeout{====~Small~ caps~ not~ found.} \bool_set_true:N \l_@@_nosc_bool } } - { \@@_load_fontname:n {\l_fontspec_fontname_sc_tl} }% local for each size + { \@@_load_fontname:n {\l_@@_fontname_sc_tl} }% local for each size } \bool_if:NF \l_@@_nosc_bool { - \@@_setup_nfss:Nnn \l_@@_nfss_sc_tl {#3} {\l_@@_fontfeat_curr_clist} + \@@_setup_nfss:Nnnn \l_@@_nfss_sc_tl + {#1} {\l_@@_sizing_leftover_clist} {\l_@@_fontfeat_curr_clist} } - - } - - \@@_declare_shapes_normal:nn {#1} {#2} - \@@_declare_shapes_smcaps:nn {#1} {#2} - \@@_declare_shape_slanted:nn {#1} {#2} - \@@_declare_shape_loginfo:nn {#1} {#2} - } -\cs_generate_variant:Nn \@@_declare_shape:nnnn {nnxx} - -\cs_new:Nn \@@_setup_nfss:Nnn + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_setup_nfss:Nnnn} +% \begin{macrocode} +\cs_new:Nn \@@_setup_nfss:Nnnn { - \@@_get_features:Nn \l_@@_rawfeatures_sclist - { #2 , \l_@@_sizing_leftover_clist , #3 } +%<debug>\typeout{====~Setup~NFSS~shape:~<\l_@@_size_tl>~\l_fontspec_fontname_tl} + + \@@_get_features:Nn \l_@@_rawfeatures_sclist { #2 , #3 , #4 } +%<debug>\typeout{====~Gathered~features:~\l_@@_rawfeatures_sclist} \tl_put_right:Nx #1 { <\l_@@_size_tl> \l_@@_scale_tl - \@@_fontwrap:n - { - \@@_fullname:n { \l_fontspec_fontname_tl } - : \l_@@_pre_feat_sclist \l_@@_rawfeatures_sclist - } + \@@_construct_font_call:nn { \l_fontspec_fontname_tl } + { \l_@@_pre_feat_sclist \l_@@_rawfeatures_sclist } } } - +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_declare_shapes_normal:nn} +% \begin{macrocode} \cs_new:Nn \@@_declare_shapes_normal:nn { \@@_DeclareFontShape:xxxxxx {\l_@@_nfss_enc_tl} {\l_fontspec_family_tl} {#1} {#2} {\l_@@_nfss_tl}{\l_@@_postadjust_tl} } - +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_declare_shapes_smcaps:nn} +% \begin{macrocode} \cs_new:Nn \@@_declare_shapes_smcaps:nn { - \bool_if:NF \l_@@_nosc_bool + \tl_if_empty:NF \l_@@_nfss_sc_tl { \@@_DeclareFontShape:xxxxxx {\l_@@_nfss_enc_tl} {\l_fontspec_family_tl} {#1} { \@@_combo_sc_shape:n {#2} } {\l_@@_nfss_sc_tl} {\l_@@_postadjust_tl} } } + \cs_new:Nn \@@_combo_sc_shape:n { \tl_if_exist:cTF { \@@_shape_merge:nn {#1} {\scdefault} } { \tl_use:c { \@@_shape_merge:nn {#1} {\scdefault} } } { \scdefault } } - +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_DeclareFontShape:nnnnnn} +% \begin{macrocode} \cs_new:Nn \@@_DeclareFontShape:nnnnnn { +%<debug>\typeout{DeclareFontShape:~{#1}{#2}{#3}{#4}...} \group_begin: \normalsize \cs_undefine:c {#1/#2/#3/#4/\f@size} @@ -609,6 +801,8 @@ } \cs_generate_variant:Nn \@@_DeclareFontShape:nnnnnn {xxxxxx} % \end{macrocode} +% +% \begin{macro}{\@@_declare_shape_slanted:nn} % This extra stuff for the slanted shape substitution is a little bit awkward. % We define the slanted shape to be a synonym for it when (a)~we're defining an italic font, but also (b)~when the default slanted shape isn't `it'. % (Presumably this turned up once in a test and I realised it caused problems. I doubt this would happen much.) @@ -628,12 +822,16 @@ } } % \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_declare_shape_loginfo:nn} % Lastly some informative messaging. % \begin{macrocode} \cs_new:Nn \@@_declare_shape_loginfo:nn { \tl_gput_right:Nx \l_fontspec_defined_shapes_tl { + \exp_not:n { \\ } -~ \exp_not:N \str_case:nn {#1/#2} { {\mddefault/\updefault} {'normal'~} @@ -663,11 +861,13 @@ } } } -\cs_generate_variant:Nn \tl_if_empty:nF {f} % \end{macrocode} % Maybe |\str_if_eq_x:nnF| would be better? % \end{macro} % +% +% \subsubsection{Features} +% % \begin{macro}{\l_@@_pre_feat_sclist} % These are the features always applied to a font selection before other % features. @@ -699,157 +899,29 @@ % \end{macro} % % -% -% -% -% \subsubsection{Features} -% -% \begin{macro}{\@@_get_features:Nn} -% -% This macro is a wrapper for |\keys_set:nn| which expands and adds a -% default specification to the original passed options. It begins by -% initialising the commands used to hold font-feature specific -% strings. -% Its argument is any additional features to prepend to the default. -% \begin{macrocode} -\cs_set:Nn \@@_get_features:Nn - { - \sclist_clear:N \l_@@_rawfeatures_sclist - \tl_clear:N \l_@@_scale_tl - \tl_set_eq:NN \l_@@_opacity_tl \g_@@_opacity_tl - \tl_set_eq:NN \l_@@_hexcol_tl \g_@@_hexcol_tl - \tl_set_eq:NN \l_@@_postadjust_tl \g_@@_postadjust_tl - \tl_clear:N \l_@@_wordspace_adjust_tl - \tl_clear:N \l_@@_punctspace_adjust_tl - - \keys_set_known:nxN {fontspec-renderer} {\l_@@_fontfeat_clist,#2} - \l_@@_keys_leftover_clist - \keys_set:nx {fontspec} {\l_@@_keys_leftover_clist} -% \end{macrocode} -% Finish the colour specification. -% Do not set the colour if not explicitly spec'd else \verb|\color| (using -% specials) will not work. -% \begin{macrocode} - \str_if_eq_x:nnF { \l_@@_hexcol_tl \l_@@_opacity_tl } - { \g_@@_hexcol_tl \g_@@_opacity_tl } - { - \@@_update_featstr:n { color = \l_@@_hexcol_tl\l_@@_opacity_tl } - } - - \tl_set_eq:NN #1 \l_@@_rawfeatures_sclist - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_init:} -% Initialisations that either need to occur globally: -% (all setting of these variables is done locally inside a group) -% \begin{macrocode} -\tl_clear:N \l_@@_family_label_tl -\tl_clear:N \l_fontspec_fontname_bf_tl -\tl_clear:N \l_fontspec_fontname_it_tl -\tl_clear:N \l_fontspec_fake_slant_tl -\tl_clear:N \l_fontspec_fake_embolden_tl -\tl_clear:N \l_fontspec_fontname_bfit_tl -\tl_clear:N \l_fontspec_fontname_sl_tl -\tl_clear:N \l_fontspec_fontname_bfsl_tl -\tl_clear:N \l_fontspec_fontname_sc_tl -\tl_clear:N \l_@@_fontfeat_up_clist -\tl_clear:N \l_@@_fontfeat_bf_clist -\tl_clear:N \l_@@_fontfeat_it_clist -\tl_clear:N \l_@@_fontfeat_bfit_clist -\tl_clear:N \l_@@_fontfeat_sl_clist -\tl_clear:N \l_@@_fontfeat_bfsl_clist -\tl_clear:N \l_@@_fontfeat_sc_clist -\tl_clear:N \l_@@_script_name_tl -\tl_clear:N \l_fontspec_script_tl -\tl_clear:N \l_@@_lang_name_tl -\tl_clear:N \l_fontspec_lang_tl -\tl_set:Nn \g_@@_postadjust_tl { \l_@@_wordspace_adjust_tl \l_@@_punctspace_adjust_tl } - -\clist_set:Nn \l_@@_sizefeat_clist {Size={-}} -\tl_new:N \g_@@_hexcol_tl -\tl_new:N \g_@@_opacity_tl -\tl_set:Nn \g_@@_hexcol_tl {000000} -\tl_set:Nn \g_@@_opacity_tl {FF~} -% \end{macrocode} -% Or once per fontspec font invocation: -% (Some of these may be redundant. -% Check whether they're assigned to globally or not.) -% \begin{macrocode} -\cs_set:Npn \@@_init: - { - \bool_set_false:N \l_@@_ot_bool - \bool_set_true:N \l_@@_firsttime_bool - \cs_set:Npn \@@_namewrap:n ##1 { ##1 } - \tl_clear:N \l_@@_optical_size_tl - \tl_clear:N \l_fontspec_renderer_tl - \tl_clear:N \l_fontspec_defined_shapes_tl - \tl_clear:N \g_@@_curr_series_tl - \tl_gset_eq:NN \l_@@_nfss_enc_tl \g_fontspec_encoding_tl - - % This is for detecting font families when assigning default features. - % Replace defaults for the standard families because they're not set in the usual way: - \exp_args:NV \str_case:nnF {\l_@@_family_label_tl} - { - {\rmdefault} { \tl_set:Nn \l_@@_family_label_tl {\g_@@_rmfamily_family} } - {\sfdefault} { \tl_set:Nn \l_@@_family_label_tl {\g_@@_sffamily_family} } - {\ttdefault} { \tl_set:Nn \l_@@_family_label_tl {\g_@@_ttfamily_family} } - }{} - -%<*luatex> - \tl_set:Nn \l_fontspec_mode_tl {node} - \int_set:Nn \luatex_prehyphenchar:D { `\- } % fixme - \int_zero:N \luatex_posthyphenchar:D % fixme - \int_zero:N \luatex_preexhyphenchar:D % fixme - \int_zero:N \luatex_postexhyphenchar:D % fixme -%</luatex> - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_make_smallcaps:TF} +% \begin{macro}{\@@_make_ot_smallcaps:TF} % \label{mac:makesmallcaps} % This macro checks if the font contains small caps. % \begin{macrocode} -\cs_set:Nn \fontspec_make_ot_smallcaps:TF +%<luatex>\cs_set:Nn \@@_make_smallcaps:TF +%<xetexx>\cs_set:Nn \@@_make_ot_smallcaps:TF { - \fontspec_check_ot_feat:nTF {+smcp} {#1} {#2} + \@@_check_ot_feat:nTF {smcp} {#1} {#2} } %<*xetexx> \cs_set:Nn \@@_make_smallcaps:TF { \bool_if:NTF \l_@@_ot_bool - { \fontspec_make_ot_smallcaps:TF {#1} {#2} } + { \@@_make_ot_smallcaps:TF {#1} {#2} } { \bool_if:NT \l_@@_atsui_bool - { \fontspec_make_AAT_feature_string:nnTF {3}{3} {#1} {#2} } + { \@@_make_AAT_feature_string:nnTF {3}{3} {#1} {#2} } } } %</xetexx> -%<*luatex> -\cs_set_eq:NN \@@_make_smallcaps:TF \fontspec_make_ot_smallcaps:TF -%</luatex> % \end{macrocode} % \end{macro} % -% -% -% \begin{macro}{\sclist_put_right:Nn} -% I'm hardly going to write an `sclist' module but a couple of functions are -% useful. Here, items in semi-colon lists are always followed by a semi-colon -% (as opposed to the s.-c's being placed between elements) so we can append -% sclists without worrying about it. -% \begin{macrocode} -\cs_set_eq:NN \sclist_clear:N \tl_clear:N -\cs_new:Nn \sclist_gput_right:Nn - { \tl_gput_right:Nn #1 {#2;} } -\cs_generate_variant:Nn \sclist_gput_right:Nn {Nx} -% \end{macrocode} -% \end{macro} -% -% -% % \begin{macro}{\@@_update_featstr:n} % \cmd{\l_@@_rawfeatures_sclist} is the string used to define the list of specific % font features. Each time another font feature is requested, this @@ -857,161 +929,87 @@ % separated by semicolons. % \begin{macrocode} \cs_new:Nn \@@_update_featstr:n - { - \bool_if:NF \l_@@_firsttime_bool - { - \sclist_gput_right:Nx \l_@@_rawfeatures_sclist {#1} - } - } + { +%<debug> \typeout{:::: @@_update_featstr:n {#1}} + \bool_if:NF \l_@@_firsttime_bool + { + \tl_gset:Nx \g_@@_single_feat_tl { #1 } +%<debug> \typeout{::::~ Adding~ feature.} + \tl_gput_right:Nx \l_@@_rawfeatures_sclist {#1;} + } + } % \end{macrocode} % \end{macro} % -% -% -% \begin{macro}{\fontspec_make_feature:nnn} -% This macro is called by each feature key selected, and runs -% according to which type of font is selected. +% \begin{macro}{\@@_remove_clashing_featstr:n} % \begin{macrocode} -\cs_new:Nn \fontspec_make_feature:nnn -%<*xetexx> - { - \bool_if:NTF \l_@@_ot_bool - { \fontspec_make_OT_feature:n {#3} } - { - \bool_if:NT \l_@@_atsui_bool - { \fontspec_make_AAT_feature:nn {#1}{#2} } - } - } -%</xetexx> -%<*luatex> - { \fontspec_make_OT_feature:n {#3} } -%</luatex> -\cs_generate_variant:Nn \fontspec_make_feature:nnn {nnx} -% \end{macrocode} -% -% \begin{macrocode} -\cs_new:Nn \fontspec_make_AAT_feature:nn - { - \tl_if_empty:nTF {#1} - { \@@_warning:n {aat-feature-not-exist} } - { - \fontspec_make_AAT_feature_string:nnTF {#1}{#2} - { - \@@_update_featstr:n {\l_fontspec_feature_string_tl} - } - { \@@_warning:nx {aat-feature-not-exist-in-font} {#1,#2} } - } - } -\cs_new:Nn \fontspec_make_OT_feature:n - { - \tl_if_empty:nTF {#1} - { \@@_warning:n {icu-feature-not-exist} } - { - \fontspec_check_ot_feat:nTF {#1} +\cs_new:Nn \@@_remove_clashing_featstr:n + { +%<debug> \typeout{:::: @@_remove_clashing_featstr:n {#1}} + \clist_map_inline:nn {#1} { - \@@_update_featstr:n {#1} +%<debug> \typeout{::::~ Removing~ feature~ "##1;"} + \tl_gremove_all:Nn \l_@@_rawfeatures_sclist {##1;} } - { \@@_warning:nx {icu-feature-not-exist-in-font} {#1} } - } - } -\cs_new_protected:Nn \fontspec_make_numbered_feature:nn - { - \fontspec_check_ot_feat:nTF {#1} - { - \@@_update_featstr:n { #1 = #2 } - } - { \@@_warning:nx {icu-feature-not-exist-in-font} {#1} } - } -\cs_generate_variant:Nn \fontspec_make_numbered_feature:nn {xn} + } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_define_font_feature:n} -% \begin{macro}{\@@_define_feature_option:nnnnn} -% \begin{macro}{\fontspec_define_numbered_feat:nnnn} -% These macros are used in order to simplify font feature definition later on. +% \subsection{Initialisation} +% +% \begin{macro}{\@@_init:} +% Initialisations that need to occur once per fontspec font invocation. +% (Some of these may be redundant. +% Check whether they're assigned to globally or not.) % \begin{macrocode} -\cs_new:Nn \@@_define_font_feature:n - { - \keys_define:nn {fontspec} { #1 .multichoice: } - } -\cs_new:Nn \@@_define_feature_option:nnnnn - { - \keys_define:nn {fontspec} - { - #1/#2 .code:n = { \fontspec_make_feature:nnn{#3}{#4}{#5} } - } - } -\cs_new:Nn \fontspec_define_numbered_feat:nnnn +\cs_set:Npn \@@_init: { - \keys_define:nn {fontspec} - { - #1/#2 .code:n = - { \fontspec_make_numbered_feature:nn {#3}{#4} } - } +%<debug> \typeout{:: @@_init:} + \bool_set_false:N \l_@@_ot_bool + \bool_set_true:N \l_@@_firsttime_bool + \@@_font_is_name: + \tl_clear:N \l_@@_font_path_tl + \tl_clear:N \l_@@_optical_size_tl + \tl_clear:N \l_@@_ttc_index_tl + \tl_clear:N \l_fontspec_renderer_tl + \tl_clear:N \l_fontspec_defined_shapes_tl + \tl_clear:N \g_@@_curr_series_tl + \tl_gset_eq:NN \l_@@_nfss_enc_tl \g_fontspec_encoding_tl + +%<*luatex> + \tl_set:Nn \l_fontspec_mode_tl {node} + \int_set:Nn \luatex_prehyphenchar:D { `\- } % fixme + \int_zero:N \luatex_posthyphenchar:D % fixme + \int_zero:N \luatex_preexhyphenchar:D % fixme + \int_zero:N \luatex_postexhyphenchar:D % fixme +%</luatex> } % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\fontspec_make_AAT_feature_string:nnTF} -% This macro takes the numerical codes for a font feature and -% creates a specified macro containing the string required in the -% font definition to turn that feature on or off. Used primarily in -% [...], but also used to check if small caps -% exists in the requested font (see page~\pageref{mac:makesmallcaps}). -% -% For exclusive selectors, it's easy; just grab the string: -% For \emph{non}-exclusive selectors, it's a little more complex. -% If the selector is even, it corresponds to switching the feature on. -% If the selector is \emph{odd}, it corresponds to switching the feature off. -% But \XeTeX\ doesn't return a selector string for this number, since the -% feature is defined for the `switching on' value. So we need to check the -% selector of the previous number, and then prefix the feature string with |!| -% to denote the switch. -% -% Finally, save out the complete feature string in \cmd\l_fontspec_feature_string_tl. +% \begin{macro}{\@@_init_fontface:} +% Executed in \cs{@@_get_features:Nn}. % \begin{macrocode} -\prg_new_conditional:Nnn \fontspec_make_AAT_feature_string:nn {TF,T,F} - { - \tl_set:Nx \l_tmpa_tl { \XeTeXfeaturename \l_fontspec_font #1 } - \tl_if_empty:NTF \l_tmpa_tl - { \prg_return_false: } - { - \int_compare:nTF { \XeTeXisexclusivefeature\l_fontspec_font #1 > 0 } - { - \tl_set:Nx \l_tmpb_tl {\XeTeXselectorname\l_fontspec_font #1\space #2} - } - { - \int_if_even:nTF {#2} - { - \tl_set:Nx \l_tmpb_tl {\XeTeXselectorname\l_fontspec_font #1\space #2} - } - { - \tl_set:Nx \l_tmpb_tl - { - \XeTeXselectorname\l_fontspec_font #1\space \numexpr#2-1\relax - } - \tl_if_empty:NF \l_tmpb_tl { \tl_put_left:Nn \l_tmpb_tl {!} } - } - } - \tl_if_empty:NTF \l_tmpb_tl - { \prg_return_false: } - { - \tl_set:Nx \l_fontspec_feature_string_tl { \l_tmpa_tl = \l_tmpb_tl } - \prg_return_true: - } - } - } +\cs_new:Nn \@@_init_fontface: + { + \tl_clear:N \l_@@_rawfeatures_sclist + \tl_clear:N \l_@@_scale_tl + \tl_set_eq:NN \l_@@_opacity_tl \g_@@_opacity_tl + \tl_set_eq:NN \l_@@_hexcol_tl \g_@@_hexcol_tl + \tl_set_eq:NN \l_@@_postadjust_tl \g_@@_postadjust_tl + \tl_clear:N \l_@@_wordspace_adjust_tl + \tl_clear:N \l_@@_punctspace_adjust_tl + } % \end{macrocode} % \end{macro} % -% \begin{macro}{\fontspec_iv_str_to_num:Nn} -% \begin{macro}{\fontspec_v_str_to_num:Nn} +% +% \subsection{Miscellaneous} +% +% \begin{macro}{\@@_iv_str_to_num:Nn} % This macro takes a four character string and converts it to the % numerical representation required for \XeTeX\ OpenType script/language/feature -% purposes. The output is stored in \cmd\l_fontspec_strnum_int. +% purposes. The output is stored in |#1|. % % The reason it's ugly is because the input can be of the form of any of these: % `|abcd|', `|abc|', `|abc |', `|ab|', `|ab |', \etc. @@ -1019,16 +1017,12 @@ % reads in the string, delimited by a space; this input is padded with \cmd\@empty s % and anything beyond four chars is snipped. The \cmd\@empty s then are used to reconstruct % the spaces in the string to number calculation. -% -% The variant \cmd\fontspec_v_str_to_num:n\ is used when looking at features, which are passed around -% with prepended plus and minus signs (\eg, \texttt{+liga}, \texttt{-dlig}); it -% simply strips off the first char of the input before calling the normal \cmd\fontspec_iv_str_to_num:n. % \begin{macrocode} -\cs_set:Nn \fontspec_iv_str_to_num:Nn +\cs_set:Nn \@@_iv_str_to_num:Nn { - \fontspec_iv_str_to_num:w #1 \q_nil #2 \c_empty_tl \c_empty_tl \q_nil + \@@_iv_str_to_num:w #1 \q_nil #2 \c_empty_tl \c_empty_tl \q_nil } -\cs_set:Npn \fontspec_iv_str_to_num:w #1 \q_nil #2#3#4#5#6 \q_nil +\cs_set:Npn \@@_iv_str_to_num:w #1 \q_nil #2#3#4#5#6 \q_nil { \int_set:Nn #1 { @@ -1038,143 +1032,10 @@ + \ifx \c_empty_tl #5 32 \else `#5 \fi } } -\cs_generate_variant:Nn \fontspec_iv_str_to_num:Nn {No} -\cs_set:Nn \fontspec_v_str_to_num:Nn - { - \bool_if:nTF - { - \tl_if_head_eq_charcode_p:nN {#2} {+} || - \tl_if_head_eq_charcode_p:nN {#2} {-} - } - { \fontspec_iv_str_to_num:No #1 { \use_none:n #2 } } - { \fontspec_iv_str_to_num:Nn #1 {#2} } - } +\cs_generate_variant:Nn \@@_iv_str_to_num:Nn {No} % \end{macrocode} % \end{macro} -% \end{macro} -% % -% \begin{macro}{\fontspec_check_script:nTF} -% This macro takes an OpenType script tag and checks if it exists in the current -% font. The output boolean is \cmd\@tempswatrue. \cmd\l_fontspec_strnum_int\ is used to store -% the number corresponding to the script tag string. -% \begin{macrocode} -\prg_new_conditional:Nnn \fontspec_check_script:n {TF} -%<*xetexx> - { - \fontspec_iv_str_to_num:Nn \l_fontspec_strnum_int {#1} - \int_set:Nn \l_tmpb_int { \XeTeXOTcountscripts \l_fontspec_font } - \int_zero:N \l_tmpa_int - \bool_set_false:N \l__fontspec_check_bool - \bool_until_do:nn { \int_compare_p:nNn \l_tmpa_int = \l_tmpb_int } - { - \ifnum \XeTeXOTscripttag\l_fontspec_font \l_tmpa_int = \l_fontspec_strnum_int - \bool_set_true:N \l__fontspec_check_bool - \int_set:Nn \l_tmpa_int {\l_tmpb_int} - \else - \int_incr:N \l_tmpa_int - \fi - } - \bool_if:NTF \l__fontspec_check_bool \prg_return_true: \prg_return_false: - } -%</xetexx> -%<*luatex> - { - \directlua{fontspec.check_ot_script("l_fontspec_font", "#1")} - \bool_if:NTF \l__fontspec_check_bool \prg_return_true: \prg_return_false: - } -%</luatex> -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\fontspec_check_lang:nTF} -% This macro takes an OpenType language tag and checks if it exists in the current -% font/script. The output boolean is \cmd\@tempswatrue. \cmd\l_fontspec_strnum_int\ is used to store -% the number corresponding to the language tag string. -% The script used is whatever's held in \cmd\l_fontspec_script_int. By default, that's the -% number corresponding to `|latn|'. -% \begin{macrocode} -\prg_new_conditional:Nnn \fontspec_check_lang:n {TF} -%<*xetexx> - { - \fontspec_iv_str_to_num:Nn \l_fontspec_strnum_int {#1} - \int_set:Nn \l_tmpb_int - { \XeTeXOTcountlanguages \l_fontspec_font \l_fontspec_script_int } - \int_zero:N \l_tmpa_int - \bool_set_false:N \l__fontspec_check_bool - \bool_until_do:nn { \int_compare_p:nNn \l_tmpa_int = \l_tmpb_int } - { - \ifnum\XeTeXOTlanguagetag\l_fontspec_font\l_fontspec_script_int \l_tmpa_int =\l_fontspec_strnum_int - \bool_set_true:N \l__fontspec_check_bool - \int_set:Nn \l_tmpa_int {\l_tmpb_int} - \else - \int_incr:N \l_tmpa_int - \fi - } - \bool_if:NTF \l__fontspec_check_bool \prg_return_true: \prg_return_false: - } -%</xetexx> -%<*luatex> - { - \directlua - { - fontspec.check_ot_lang( "l_fontspec_font", "#1", "\l_fontspec_script_tl" ) - } - \bool_if:NTF \l__fontspec_check_bool \prg_return_true: \prg_return_false: - } -%</luatex> -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\fontspec_check_ot_feat:nTF} -% \begin{macro}{\fontspec_check_ot_feat:nT} -% This macro takes an OpenType feature tag and checks if it exists in the current -% font/script/language. -% \cmd\l_fontspec_strnum_int\ is used to store the number corresponding to the feature tag string. -% The script used is whatever's held in \cmd\l_fontspec_script_int. By default, that's the -% number corresponding to `|latn|'. The language used is \cmd\l_fontspec_language_int, -% by default |0|, the `default language'. -% \begin{macrocode} -\prg_new_conditional:Nnn \fontspec_check_ot_feat:n {TF,T} -%<*xetexx> - { - \int_set:Nn \l_tmpb_int - { - \XeTeXOTcountfeatures \l_fontspec_font - \l_fontspec_script_int - \l_fontspec_language_int - } - \fontspec_v_str_to_num:Nn \l_fontspec_strnum_int {#1} - \int_zero:N \l_tmpa_int - \bool_set_false:N \l__fontspec_check_bool - \bool_until_do:nn { \int_compare_p:nNn \l_tmpa_int = \l_tmpb_int } - { - \ifnum\XeTeXOTfeaturetag\l_fontspec_font\l_fontspec_script_int\l_fontspec_language_int - \l_tmpa_int =\l_fontspec_strnum_int - \bool_set_true:N \l__fontspec_check_bool - \int_set:Nn \l_tmpa_int {\l_tmpb_int} - \else - \int_incr:N \l_tmpa_int - \fi - } - \bool_if:NTF \l__fontspec_check_bool \prg_return_true: \prg_return_false: - } -%</xetexx> -%<*luatex> - { - \directlua - { - fontspec.check_ot_feat( - "l_fontspec_font", "#1", - "\l_fontspec_lang_tl", "\l_fontspec_script_tl" - ) - } - \bool_if:NTF \l__fontspec_check_bool \prg_return_true: \prg_return_false: - } -%</luatex> -% \end{macrocode} -% \end{macro} -% \end{macro} % % \iffalse % \begin{macrocode} |