%%^^A%% fontspec-keyval.dtx -- part of FONTSPEC % \section{Font loading (\pkg{keyval}) definitions} % % This is the tedious section where we correlate all possible % (eventually) font feature requests with their \XeTeX\ representations. % % \iffalse % \begin{macrocode} %<*fontspec> % \end{macrocode} % \fi % % % \begin{macrocode} \clist_set:Nn \g_@@_all_keyval_modules_clist { fontspec, fontspec-opentype, fontspec-aat, fontspec-preparse, fontspec-preparse-cfg, fontspec-preparse-external, fontspec-preparse-nested, fontspec-renderer } % \end{macrocode} % % \begin{macrocode} \cs_new:Nn \@@_keys_define_code:nnn { \keys_define:nn {#1} { #2 .code:n = {#3} } } % \end{macrocode} % % For catching features that cannot be used in |\addfontfeatures|: % \begin{macrocode} \cs_new:Nn \@@_aff_error:n { \@@_keys_define_code:nnn {fontspec-addfeatures} {#1} { \@@_error:nx {not-in-addfontfeatures} {#1} } } % \end{macrocode} % % \subsubsection{Pre-parsing naming information} % % These features are extracted from the font feature list before all others. % % \paragraph{Don't load font config file} % \begin{macrocode} \@@_keys_define_code:nnn {fontspec-preparse-cfg} {IgnoreFontspecFile} { \bool_set_false:N \l_@@_fontcfg_bool } \@@_keys_define_code:nnn {fontspec-preparse-external} {IgnoreFontspecFile} { \bool_set_false:N \l_@@_fontcfg_bool } % \end{macrocode} % % \begin{macro}{Path} % For fonts that aren't installed in the system. If no argument is given, the font is located % with |kpsewhich|; it's either in the current directory or the \TeX\ tree. Otherwise, the % argument given defines the file path of the font. % \begin{macrocode} \@@_keys_define_code:nnn {fontspec-preparse-external} {Path} { \bool_set_true:N \l_@@_nobf_bool \bool_set_true:N \l_@@_noit_bool \bool_set_true:N \l_@@_external_bool \tl_set:Nn \l_@@_font_path_tl {#1} \@@_font_is_file: %<*XE> \keys_set:nn {fontspec-renderer} {Renderer=OpenType} % } \aliasfontfeature{Path}{ExternalLocation} \@@_keys_define_code:nnn {fontspec} {Path} {} % \end{macrocode} % \end{macro} % % \paragraph{\feat{Extension}} % For fonts that aren't installed in the system. Specifies the font extension % to use. % \begin{macrocode} \@@_keys_define_code:nnn {fontspec-preparse-external} {Extension} { \tl_set:Nn \l_@@_extension_tl {#1} \bool_if:NF \l_@@_external_bool { \keys_set:nn {fontspec-preparse-external} {Path} } } \tl_clear:N \l_@@_extension_tl \@@_keys_define_code:nnn {fontspec} {Extension} {} % \end{macrocode} % % \subsubsection{Pre-parsed features} % % After the font name(s) have been sorted out, now need to extract any % renderer/font configuration features that need to be processed before % all other font features. % % \paragraph{\feat{Renderer}} % This feature must be processed before all others (the other font shape and features options are also pre-parsed for convenience) because the renderer determines the format of the features and even whether certain features are available. % \begin{macrocode} \keys_define:nn {fontspec-renderer} { Renderer .choices:nn = {AAT,ICU,OpenType,Graphite,Full,Basic} { \int_compare:nTF {\l_keys_choice_int <= 4} { %<*XE> \tl_set:Nx \l_fontspec_renderer_tl { \int_case:nn \l_keys_choice_int { 1 {/AAT} 2 {/OT} 3 {/OT} 4 {/GR} } } \tl_gset:Nx \g_@@_single_feat_tl { \l_fontspec_renderer_tl } % %<*LU> \@@_warning:nx {only-xetex-feature} {Renderer=AAT/OpenType/Graphite} % } { %<*XE> \@@_warning:nx {only-luatex-feature} {Renderer=Full/Basic} % %<*LU> \tl_set:Nx \l_fontspec_mode_tl { \int_case:nn \l_keys_choice_int { 5 {node} 6 {base} } } \tl_gset:Nx \g_@@_single_feat_tl { mode=\l_fontspec_mode_tl } % } } } % \end{macrocode} % % \paragraph{OpenType script/language} % See later for the resolutions from \pkg{fontspec} features to OpenType definitions. % \begin{macrocode} \@@_keys_define_code:nnn {fontspec-preparse} {Script} { % \keys_set:nn {fontspec-renderer} {Renderer=OpenType} \tl_set:Nn \l_@@_script_name_tl {#1} } % \end{macrocode} % Exactly the same: % \begin{macrocode} \@@_keys_define_code:nnn {fontspec-preparse} {Language} { % \keys_set:nn {fontspec-renderer} {Renderer=OpenType} \tl_set:Nn \l_@@_lang_name_tl {#1} } % \end{macrocode} % % \paragraph{TTC font index} % \begin{macrocode} \@@_keys_define_code:nnn {fontspec-preparse} {FontIndex} { \str_if_eq_x:nnF { \str_lower_case:f {\l_@@_extension_tl} } {.ttc} { \@@_warning:n {font-index-needs-ttc} } % \tl_set:Nn \l_@@_ttc_index_tl {:#1} % \tl_set:Nn \l_@@_ttc_index_tl {(#1)} } \@@_keys_define_code:nnn {fontspec} {FontIndex} { % \tl_set:Nn \l_@@_ttc_index_tl {:#1} % \tl_set:Nn \l_@@_ttc_index_tl {(#1)} } % \end{macrocode} % % \subsubsection{Bold/italic choosing options} % % The \feat{Bold}, \feat{Italic}, and \feat{BoldItalic} % features are for defining explicitly the bold and italic fonts used % in a font family. % % \paragraph{Bold (NFSS) Series} % By default, \pkg{fontspec} uses the default bold series, \cs{bfdefault}. % We want to be able to make this extensible. % \begin{macrocode} \@@_keys_define_code:nnn {fontspec-preparse-external} {BoldSeries} { \tl_gset:Nx \g_@@_curr_series_tl { #1 } \seq_gput_right:Nx \g_@@_bf_series_seq { #1 } } % \end{macrocode} % % \paragraph{Fonts} % Upright: % \begin{macrocode} \@@_keys_define_code:nnn {fontspec-preparse-external} {UprightFont} { \fontspec_complete_fontname:Nn \l_@@_fontname_up_tl {#1} } \@@_keys_define_code:nnn {fontspec-preparse-external} {FontName} { \fontspec_complete_fontname:Nn \l_@@_fontname_up_tl {#1} } % \end{macrocode} % Bold: % \begin{macrocode} \@@_keys_define_code:nnn {fontspec-preparse-external} {BoldFont} { \tl_if_empty:nTF {#1} { \bool_set_true:N \l_@@_nobf_bool } { \bool_set_false:N \l_@@_nobf_bool \fontspec_complete_fontname:Nn \l_@@_curr_bfname_tl {#1} \seq_if_empty:NT \g_@@_bf_series_seq { \tl_gset:Nx \g_@@_curr_series_tl {\bfdefault} \seq_put_right:Nx \g_@@_bf_series_seq {\bfdefault} } \tl_if_eq:oxT \g_@@_curr_series_tl {\bfdefault} { \tl_set_eq:NN \l_@@_fontname_bf_tl \l_@@_curr_bfname_tl } %\typeout{Setting~bold~font~"\l_@@_curr_bfname_tl"~with~series~"\g_@@_curr_series_tl"} \prop_put:NxV \l_@@_nfss_prop {BoldFont-\g_@@_curr_series_tl} \l_@@_curr_bfname_tl } } % \end{macrocode} % Same for italic: % \begin{macrocode} \@@_keys_define_code:nnn {fontspec-preparse-external} {ItalicFont} { \tl_if_empty:nTF {#1} { \bool_set_true:N \l_@@_noit_bool } { \bool_set_false:N \l_@@_noit_bool \fontspec_complete_fontname:Nn \l_@@_fontname_it_tl {#1} } } % \end{macrocode} % Simpler for bold+italic \& slanted: % \begin{macrocode} \@@_keys_define_code:nnn {fontspec-preparse-external} {BoldItalicFont} { \fontspec_complete_fontname:Nn \l_@@_fontname_bfit_tl {#1} } \@@_keys_define_code:nnn {fontspec-preparse-external} {SlantedFont} { \fontspec_complete_fontname:Nn \l_@@_fontname_sl_tl {#1} } \@@_keys_define_code:nnn {fontspec-preparse-external} {BoldSlantedFont} { \fontspec_complete_fontname:Nn \l_@@_fontname_bfsl_tl {#1} } % \end{macrocode} % Small caps isn't pre-parsed because it can vary with others above: % \begin{macrocode} \@@_keys_define_code:nnn {fontspec} {SmallCapsFont} { \tl_if_empty:nTF {#1} { \bool_set_true:N \l_@@_nosc_bool } { \bool_set_false:N \l_@@_nosc_bool \fontspec_complete_fontname:Nn \l_@@_fontname_sc_tl {#1} } } % \end{macrocode} % % % \paragraph{Features} % % \begin{macrocode} \@@_keys_define_code:nnn {fontspec-preparse} {UprightFeatures} { \clist_set:Nn \l_@@_fontfeat_up_clist {#1} } \@@_keys_define_code:nnn {fontspec-preparse} {BoldFeatures} { \clist_set:Nn \l_@@_fontfeat_bf_clist {#1} % \prop_put:NxV \l_@@_nfss_prop % {BoldFont-\g_@@_curr_series_tl} \l_@@_curr_bfname_tl } \@@_keys_define_code:nnn {fontspec-preparse} {ItalicFeatures} { \clist_set:Nn \l_@@_fontfeat_it_clist {#1} } \@@_keys_define_code:nnn {fontspec-preparse} {BoldItalicFeatures} { \clist_set:Nn \l_@@_fontfeat_bfit_clist {#1} } \@@_keys_define_code:nnn {fontspec-preparse} {SlantedFeatures} { \clist_set:Nn \l_@@_fontfeat_sl_clist {#1} } \@@_keys_define_code:nnn {fontspec-preparse} {BoldSlantedFeatures} { \clist_set:Nn \l_@@_fontfeat_bfsl_clist {#1} } % \end{macrocode} % Note that small caps features can vary by shape, so these in fact \emph{aren't} pre-parsed. % \begin{macrocode} \@@_keys_define_code:nnn {fontspec} {SmallCapsFeatures} { \bool_if:NF \l_@@_firsttime_bool { \clist_set:Nn \l_@@_fontfeat_sc_clist {#1} } } % \end{macrocode} % % paragraph{Features varying by size} % \begin{macrocode} \@@_keys_define_code:nnn {fontspec-preparse} {SizeFeatures} { \clist_set:Nn \l_@@_sizefeat_clist {#1} \clist_put_right:Nn \l_@@_fontfeat_up_clist { SizeFeatures = {#1} } } \@@_keys_define_code:nnn {fontspec-preparse-nested} {SizeFeatures} { \clist_set:Nn \l_@@_sizefeat_clist {#1} \tl_if_empty:NT \l_@@_this_font_tl { \tl_set:Nn \l_@@_this_font_tl { -- } } % needs to be non-empty as a flag } \@@_keys_define_code:nnn {fontspec-preparse-nested} {Font} { \tl_set:Nn \l_@@_this_font_tl {#1} } \@@_keys_define_code:nnn {fontspec} {SizeFeatures} { % dummy } \@@_keys_define_code:nnn {fontspec} {Font} { % dummy } % \end{macrocode} % % \begin{macrocode} \@@_keys_define_code:nnn {fontspec-sizing} {Size} { \tl_set:Nn \l_@@_size_tl {#1} } \@@_keys_define_code:nnn {fontspec-sizing} {Font} { \fontspec_complete_fontname:Nn \l_@@_sizedfont_tl {#1} } % \end{macrocode} % % \subsubsection{Font-independent features} % % These features can be applied to any font. % % \paragraph{NFSS encoding} % For the very brave. % \begin{macrocode} \@@_keys_define_code:nnn {fontspec-preparse} {NFSSEncoding} { \tl_gset:Nx \l_@@_nfss_enc_tl { #1 } } % \end{macrocode} % % \paragraph{NFSS family} % Interactions with other packages will sometimes require setting the NFSS family explicitly. % (By default \pkg{fontspec} auto-generates one based on the font name.) % \begin{macrocode} \@@_keys_define_code:nnn {fontspec-preparse} {NFSSFamily} { \tl_set:Nx \l_@@_nfss_fam_tl { #1 } \cs_undefine:c {g_@@_UID_\l_@@_fontid_tl} \tl_if_exist:NT \l_fontspec_family_tl { \cs_undefine:c {g_@@_fontinfo_ \l_fontspec_family_tl _prop} } } % \end{macrocode} % % \paragraph{NFSS series/shape} % This option looks similar in name but has a very different function. % \begin{macrocode} \@@_keys_define_code:nnn {fontspec} {FontFace} { \tl_set:No \l_@@_arg_tl { \use_iii:nnn #1 } \tl_set_eq:NN \l_@@_this_feat_tl \l_@@_arg_tl \tl_clear:N \l_@@_this_font_tl \int_compare:nT { \clist_count:N \l_@@_arg_tl = 1 } { %<*debug> \typeout{FontFace~ parsing:~ one~ clist~ item} % \tl_if_in:NnF \l_@@_arg_tl {=} { %<*debug> \typeout{FontFace~ parsing:~ no~ equals~ =>~ font~ name~ only} % \tl_set_eq:NN \l_@@_this_font_tl \l_@@_arg_tl \tl_clear:N \l_@@_this_feat_tl } } \@@_add_nfssfont:nnnn {\use_i:nnn #1}{\use_ii:nnn #1}{\l_@@_this_font_tl}{\l_@@_this_feat_tl} } % \end{macrocode} % % % % \paragraph{Scale} % If the input isn't one of the pre-defined string options, then % it's gotta be numerical. \cs{fontspec_calc_scale:n} does all the work in % the auto-scaling cases. % \begin{macrocode} \@@_keys_define_code:nnn {fontspec} {Scale} { \str_case:nnF {#1} { {MatchLowercase} { \@@_calc_scale:n {5} } {MatchUppercase} { \@@_calc_scale:n {8} } } { \tl_set:Nx \l_@@_scale_tl {#1} } \tl_set:Nx \l_@@_scale_tl { s*[\l_@@_scale_tl] } } % \end{macrocode} % % \begin{macro}{\@@_calc_scale:n} % This macro calculates the amount of scaling between the default % roman font and the (default shape of) the font being selected such % that the font dimension that is input is equal for both. The only % font dimensions that justify this are 5 (lowercase height) % and 8 (uppercase height in \XeTeX). % % This script is executed for every extra shape, which seems wasteful, % but allows alternate italic shapes from a separate font, say, to % be loaded and to be auto-scaled correctly. Even if this would be ugly. % % To begin, change to \cs{rmfamily} but use internal commands in case cs{rmfamily} % has been overwritten. % (Note that changing \cs{rmfamily} with fontspec resets \cs{encodingdefault} % appropriately.) % \begin{macrocode} \cs_new:Nn \@@_calc_scale:n { \group_begin: \fontencoding { \encodingdefault } \fontfamily { \rmdefault } \selectfont \@@_set_font_dimen:NnN \l_@@_tmpa_dim {#1} \font \@@_set_font_dimen:NnN \l_@@_tmpb_dim {#1} \l_fontspec_font \tl_gset:Nx \l_@@_scale_tl { \fp_eval:n { \dim_to_fp:n {\l_@@_tmpa_dim} / \dim_to_fp:n {\l_@@_tmpb_dim} } } \@@_info:n {set-scale} \group_end: } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_set_font_dimen:NnN} % This function sets the dimension |#1| (for font |#3|) to `fontdimen' |#2| % for either font dimension 5 (x-height) or 8 (cap-height). If, for some % reason, these return an incorrect `zero' value (as \cs{fontdimen8} might % for a \texttt{.tfm} font), then we cheat and measure the height of a glyph. % We assume in this case that the font contains either an `X' or an `x'. % \begin{macrocode} \cs_new:Nn \@@_set_font_dimen:NnN { \dim_set:Nn #1 { \fontdimen #2 #3 } \dim_compare:nNnT #1 = {0pt} { \settoheight #1 { \str_if_eq:nnTF {#3} {\font} \rmfamily #3 \int_case:nnF #2 { {5} {x} % x-height {8} {X} % cap-height } {?} % "else" clause; never reached. } } } % \end{macrocode} % \end{macro} % % % \paragraph{Inter-word space} % These options set the relevant \cmd\fontdimen s for the % font being loaded. % \begin{macrocode} \@@_keys_define_code:nnn {fontspec} {WordSpace} { \bool_if:NF \l_@@_firsttime_bool { \_fontspec_parse_wordspace:w #1,,,\q_stop } } \@@_aff_error:n {WordSpace} % \end{macrocode} % % \begin{macro}{\_fontspec_parse_wordspace:w} % This macro determines if the input to \feat{WordSpace} is % of the form |{X}| or |{X,Y,Z}| and executes the font scaling. % If the former input, it executes |{X,X,X}|. % \begin{macrocode} \cs_set:Npn \_fontspec_parse_wordspace:w #1,#2,#3,#4 \q_stop { \tl_if_empty:nTF {#4} { \tl_set:Nn \l_@@_wordspace_adjust_tl { \fontdimen 2 \font = #1 \fontdimen 2 \font \fontdimen 3 \font = #1 \fontdimen 3 \font \fontdimen 4 \font = #1 \fontdimen 4 \font } } { \tl_set:Nn \l_@@_wordspace_adjust_tl { \fontdimen 2 \font = #1 \fontdimen 2 \font \fontdimen 3 \font = #2 \fontdimen 3 \font \fontdimen 4 \font = #3 \fontdimen 4 \font } } } % \end{macrocode} % \end{macro} % % \paragraph{Punctuation space} % Scaling factor for the nominal \cmd\fontdimen \#7. % \begin{macrocode} \@@_keys_define_code:nnn {fontspec} {PunctuationSpace} { \str_case_x:nnF {#1} { {WordSpace} { \tl_set:Nn \l_@@_punctspace_adjust_tl { \fontdimen 7 \font = 0 \fontdimen 2 \font } } {TwiceWordSpace} { \tl_set:Nn \l_@@_punctspace_adjust_tl { \fontdimen 7 \font = 1 \fontdimen 2 \font } } } { \tl_set:Nn \l_@@_punctspace_adjust_tl { \fontdimen 7 \font = #1 \fontdimen 7 \font } } } \@@_aff_error:n {PunctuationSpace} % \end{macrocode} % % \paragraph{Secret hook into the font-adjustment code} % % \begin{macrocode} \@@_keys_define_code:nnn {fontspec} {FontAdjustment} { \tl_put_right:Nx \l_@@_postadjust_tl {#1} } % \end{macrocode} % % \paragraph{Letterspacing} % \begin{macrocode} \@@_keys_define_code:nnn {fontspec} {LetterSpace} { \@@_update_featstr:n {letterspace=#1} } % \end{macrocode} % % \paragraph{Hyphenation character} % This feature takes one of three arguments: `\opt{None}', % \meta{glyph}, or \meta{slot}. If the input isn't the first, % and it's one character, then it's the second; otherwise, it's % the third. % % LuaTeX decouples hyphenation from font settings, so only \verb|HyphenChar=None| works % for that engine. % \begin{macrocode} \@@_keys_define_code:nnn {fontspec} {HyphenChar} { \str_if_eq:nnTF {#1} {None} { \tl_put_right:Nn \l_@@_postadjust_tl { \@@_primitive_font_set_hyphenchar:Nn \font {-1} } } { \@@_warning:nx {only-xetex-feature} {HyphenChar} \tl_if_single:nTF {#1} { \tl_set:Nn \l_fontspec_hyphenchar_tl {`#1} } { \tl_set:Nn \l_fontspec_hyphenchar_tl { #1} } \@@_primitive_font_glyph_if_exist:NnTF \l_fontspec_font {\l_fontspec_hyphenchar_tl} { \tl_put_right:Nn \l_@@_postadjust_tl { \@@_primitive_font_set_hyphenchar:Nn \font { \l_fontspec_hyphenchar_tl } } } { \@@_error:nx {no-glyph}{#1} } } } \@@_aff_error:n {HyphenChar} % \end{macrocode} % % \paragraph{Color} % Hooks into pkg{xcolor}, which names its colours \texttt{\char`\\color@}. % \begin{macrocode} \@@_keys_define_code:nnn {fontspec} {Color} { \cs_if_exist:cTF { \token_to_str:N \color@ #1 } { \convertcolorspec{named}{#1}{HTML}\l_@@_hexcol_tl } { \int_compare:nTF { \tl_count:n {#1} == 6 } { \tl_set:Nn \l_@@_hexcol_tl {#1} } { \int_compare:nTF { \tl_count:n {#1} == 8 } { \fontspec_parse_colour:viii #1 } { \bool_if:NF \l_@@_firsttime_bool { \@@_warning:nx {bad-colour} {#1} } } } } } % \end{macrocode} % % \begin{macrocode} \cs_set:Npn \fontspec_parse_colour:viii #1#2#3#4#5#6#7#8 { \tl_set:Nn \l_@@_hexcol_tl {#1#2#3#4#5#6} \tl_if_eq:NNF \l_@@_opacity_tl \g_@@_opacity_tl { \bool_if:NF \l_@@_firsttime_bool { \@@_warning:nx {opa-twice-col} {#7#8} } } \tl_set:Nn \l_@@_opacity_tl {#7#8} } \aliasfontfeature{Color}{Colour} % \end{macrocode} % \begin{macrocode} \@@_keys_define_code:nnn {fontspec} {Opacity} { \int_set:Nn \l_@@_tmp_int {255} \@@_int_mult_truncate:Nn \l_@@_tmp_int { #1 } \tl_if_eq:NNF \l_@@_opacity_tl \g_@@_opacity_tl { \bool_if:NF \l_@@_firsttime_bool { \@@_warning:nx {opa-twice} {#1} } } \tl_set:Nx \l_@@_opacity_tl { \int_compare:nT { \l_@@_tmp_int <= "F } {0} % zero pad \int_to_hex:n { \l_@@_tmp_int } } } % \end{macrocode} % % % \paragraph{Mapping} % \begin{macrocode} %<*XE> \@@_keys_define_code:nnn {fontspec-aat} {Mapping} { \tl_set:Nn \l_@@_mapping_tl { #1 } } \@@_keys_define_code:nnn {fontspec-opentype} {Mapping} { \tl_set:Nn \l_@@_mapping_tl { #1 } } % %<*LU> \@@_keys_define_code:nnn {fontspec-opentype} {Mapping} { \str_if_eq:nnTF {#1} {tex-text} { \@@_warning:n {no-mapping-ligtex} \msg_redirect_name:nnn {fontspec} {no-mapping-ligtex} {none} \keys_set:nn {fontspec-opentype} { Ligatures=TeX } } { \@@_warning:n {no-mapping} } } % % \end{macrocode} % % % \subsubsection{Continuous font axes} % % \begin{macrocode} \@@_keys_define_code:nnn {fontspec} {Weight} { \@@_update_featstr:n{weight=#1} } \@@_keys_define_code:nnn {fontspec} {Width} { \@@_update_featstr:n{width=#1} } \@@_keys_define_code:nnn {fontspec} {OpticalSize} %<*XE> { \bool_if:NTF \l_@@_ot_bool { \tl_set:Nn \l_@@_optical_size_tl {/ S = #1} } { \bool_if:NT \l_@@_mm_bool { \@@_update_featstr:n { optical size = #1 } } } \bool_if:nT { !\l_@@_ot_bool && !\l_@@_mm_bool } { \bool_if:NT \l_@@_firsttime_bool { \@@_warning:n {no-opticals} } } } % %<*LU> { \tl_set:Nn \l_@@_optical_size_tl {/ S = #1} } % % \end{macrocode} % % \subsubsection{Font transformations} % These are to be specified to apply directly to a font shape: % \begin{macrocode} \keys_define:nn {fontspec} { FakeSlant .code:n = { \@@_update_featstr:n{slant=#1} }, FakeSlant .default:n = {0.2} } \keys_define:nn {fontspec} { FakeStretch .code:n = { \@@_update_featstr:n{extend=#1} }, FakeStretch .default:n = {1.2} } %<*XE> \keys_define:nn {fontspec} { FakeBold .code:n = { \@@_update_featstr:n {embolden=#1} }, FakeBold .default:n = {1.5} } % %<*LU> \keys_define:nn {fontspec} { FakeBold .code:n = { \@@_warning:n {fakebold-only-xetex} } } % % \end{macrocode} % These are to be given to a shape that has no real bold/italic % to signal that \pkg{fontspec} should automatically create `fake' shapes. % % The behaviour is currently that only if both \opt{AutoFakeSlant} \emph{and} % \opt{AutoFakeBold} are specified, the bold italic is also faked. % % These features presently \emph{override} real shapes found in the font; % in the future I'd like these features to be ignored in this case, instead. % (This is just a bit harder to program in the current design of % \pkg{fontspec}.) % \begin{macrocode} \keys_define:nn {fontspec} { AutoFakeSlant .code:n = { \bool_if:NT \l_@@_firsttime_bool { \tl_set:Nn \l_@@_fake_slant_tl {#1} \clist_put_right:Nn \l_@@_fontfeat_it_clist {FakeSlant=#1} \tl_set_eq:NN \l_@@_fontname_it_tl \l_fontspec_fontname_tl \bool_set_false:N \l_@@_noit_bool \tl_if_empty:NF \l_@@_fake_embolden_tl { \clist_put_right:Nx \l_@@_fontfeat_bfit_clist {FakeBold=\l_@@_fake_embolden_tl} \clist_put_right:Nx \l_@@_fontfeat_bfit_clist {FakeSlant=#1} \tl_set_eq:NN \l_@@_fontname_bfit_tl \l_fontspec_fontname_tl } } }, AutoFakeSlant .default:n = {0.2} } % \end{macrocode} % Same but reversed: % \begin{macrocode} \keys_define:nn {fontspec} { AutoFakeBold .code:n = { \bool_if:NT \l_@@_firsttime_bool { \tl_set:Nn \l_@@_fake_embolden_tl {#1} \clist_put_right:Nn \l_@@_fontfeat_bf_clist {FakeBold=#1} \tl_set_eq:NN \l_@@_fontname_bf_tl \l_fontspec_fontname_tl \bool_set_false:N \l_@@_nobf_bool \tl_if_empty:NF \l_@@_fake_slant_tl { \clist_put_right:Nx \l_@@_fontfeat_bfit_clist {FakeSlant=\l_@@_fake_slant_tl} \clist_put_right:Nx \l_@@_fontfeat_bfit_clist {FakeBold=#1} \tl_set_eq:NN \l_@@_fontname_bfit_tl \l_fontspec_fontname_tl } } }, AutoFakeBold .default:n = {1.5} } % \end{macrocode} % % % \subsubsection{Raw feature string} % This allows savvy \XeTeX-ers to input font features manually if they have % already memorised the OpenType abbreviations and don't mind not having error checking. % \begin{macrocode} \@@_keys_define_code:nnn {fontspec-opentype} {RawFeature} { \@@_update_featstr:n {#1} } \@@_keys_define_code:nnn {fontspec-aat} {RawFeature} { \@@_update_featstr:n {#1} } % \end{macrocode} % % % % % \iffalse % \begin{macrocode} % % \end{macrocode} % \fi \endinput % /© % ------------------------------------------------ % The FONTSPEC package % ------------------------------------------------ % Copyright 2004-2017 Will Robertson, LPPL "maintainer" % Copyright 2009-2015 Khaled Hosny % Copyright 2013 Philipp Gesang % Copyright 2013-2016 Joseph Wright % ------------------------------------------------ % This package is free software and may be redistributed and/or modified under % the conditions of the LaTeX Project Public License, version 1.3c or higher % (your choice): . % ------------------------------------------------ % ©/