% Font declaration interface and routing logic. % This layer owns the declaration entry points and public builders. \ExplSyntaxOn \tl_new:N \l__font_name_tl \tl_new:N \l__font_path_tl \tl_new:N \l__font_bold_path_tl \tl_new:N \l__font_italic_path_tl \tl_new:N \l__font_bolditalic_path_tl \tl_new:N \l__font_sans_path_tl \tl_new:N \l__font_sans_bold_path_tl \tl_new:N \l__font_sans_italic_path_tl \tl_new:N \l__font_sans_bolditalic_path_tl \tl_new:N \l__font_mono_path_tl \tl_new:N \l__font_mono_bold_path_tl \tl_new:N \l__font_regular_tl \tl_new:N \l__font_bold_tl \tl_new:N \l__font_italic_tl \tl_new:N \l__font_bolditalic_tl \tl_new:N \l__font_sans_tl \tl_new:N \l__font_sans_bold_tl \tl_new:N \l__font_sans_italic_tl \tl_new:N \l__font_sans_bolditalic_tl \tl_new:N \l__font_mono_tl \tl_new:N \l__font_mono_bold_tl \tl_new:N \l__font_script_tl \tl_new:N \l__font_language_tl \tl_new:N \l__font_features_tl \tl_new:N \l__font_cjk_fallback_tl \tl_new:N \l__font_command_tl \tl_new:N \l__font_layout_tl \tl_new:N \l__font_special_module_tl \tl_new:N \l__font_missing_face_tl \tl_new:N \l__font_resolved_bold_path_tl \tl_new:N \l__font_resolved_italic_path_tl \tl_new:N \l__font_resolved_bolditalic_path_tl \tl_new:N \l__font_resolved_sans_path_tl \tl_new:N \l__font_resolved_sans_bold_path_tl \tl_new:N \l__font_resolved_sans_italic_path_tl \tl_new:N \l__font_resolved_sans_bolditalic_path_tl \tl_new:N \l__font_resolved_mono_path_tl \tl_new:N \l__font_resolved_mono_bold_path_tl \tl_new:N \l__font_main_options_tl \tl_new:N \l__font_sans_options_tl \tl_new:N \l__font_mono_options_tl \tl_new:N \l__font_feature_options_tl \tl_new:N \l__font_special_entry_tl \tl_new:N \l__font_decl_family_id_tl \tl_new:N \l__font_external_command_tl \tl_new:N \l__font_external_engine_tl \tl_new:N \l__font_external_render_command_tl \tl_new:N \l__font_external_clusterwise_tl \clist_new:N \l__font_unicode_blocks_clist \bool_new:N \l__font_use_latex_fallback_bool \bool_new:N \l__font_nextsystem_installed_bool \bool_new:N \l__font_reapply_style_bool \bool_new:N \l__font_local_override_bool \bool_new:N \g__font_cjk_main_declared_bool \seq_new:N \g__font_loaded_special_modules_seq \seq_new:N \g__font_range_global_blocks_seq \prop_new:N \g__font_range_global_name_prop \prop_new:N \g__font_unicode_block_range_prop \prop_new:N \g__font_cjk_fallback_applied_prop \tl_new:N \g__font_devanagari_akshara_name_tl \int_new:N \g__font_range_known_class_max_int \cs_generate_variant:Nn \prop_if_in:NnF { NVF } \cs_generate_variant:Nn \prop_gput:Nnn { NVn } \cs_generate_variant:Nn \tl_to_str:n { V } \cs_new_protected:Npn \__font_declare_unicode_block:nnn #1#2#3 { \prop_gput:Nnn \g__font_unicode_block_range_prop {#1} { {#2} {#3} } } \__font_declare_unicode_block:nnn { DevanagariPreMarks } { "0900 } { "0950 } \__font_declare_unicode_block:nnn { DevanagariMarks } { "0951 } { "0954 } \__font_declare_unicode_block:nnn { DevanagariPostMarks } { "0955 } { "0963 } \__font_declare_unicode_block:nnn { DevanagariDanDa } { "0964 } { "0965 } \__font_declare_unicode_block:nnn { DevanagariPostDanDa } { "0966 } { "097F } \__font_declare_unicode_block:nnn { DevanagariExtended } { "A8E0 } { "A8FF } \__font_declare_unicode_block:nnn { DevanagariExtendedA } { "11B00 } { "11B5F } \__font_declare_unicode_block:nnn { VedicExtensions } { "1CD0 } { "1CFF } \__font_declare_unicode_block:nnn { Tibetan } { "0F00 } { "0FFF } \cs_new_protected:Npn \__font_devanagari_akshara_break: { \penalty 300 \hskip 0pt \relax } \cs_new_protected:Npn \__font_devanagari_danda_break: { \penalty 50 \hskip 0pt \relax } \cs_if_exist:NTF \ifNextSystemInstalled { \ifNextSystemInstalled \bool_gset_true:N \l__font_nextsystem_installed_bool \else \bool_gset_false:N \l__font_nextsystem_installed_bool \fi } { \bool_gset_false:N \l__font_nextsystem_installed_bool } \cs_new_protected:Npn \__font_reset_state: { \tl_clear:N \l__font_name_tl \tl_clear:N \l__font_path_tl \tl_clear:N \l__font_bold_path_tl \tl_clear:N \l__font_italic_path_tl \tl_clear:N \l__font_bolditalic_path_tl \tl_clear:N \l__font_sans_path_tl \tl_clear:N \l__font_sans_bold_path_tl \tl_clear:N \l__font_sans_italic_path_tl \tl_clear:N \l__font_sans_bolditalic_path_tl \tl_clear:N \l__font_mono_path_tl \tl_clear:N \l__font_mono_bold_path_tl \tl_clear:N \l__font_regular_tl \tl_clear:N \l__font_bold_tl \tl_clear:N \l__font_italic_tl \tl_clear:N \l__font_bolditalic_tl \tl_clear:N \l__font_sans_tl \tl_clear:N \l__font_sans_bold_tl \tl_clear:N \l__font_sans_italic_tl \tl_clear:N \l__font_sans_bolditalic_tl \tl_clear:N \l__font_mono_tl \tl_clear:N \l__font_mono_bold_tl \tl_clear:N \l__font_script_tl \tl_clear:N \l__font_language_tl \tl_clear:N \l__font_features_tl \tl_clear:N \l__font_cjk_fallback_tl \tl_clear:N \l__font_command_tl \tl_clear:N \l__font_layout_tl \tl_clear:N \l__font_special_module_tl \tl_clear:N \l__font_missing_face_tl \tl_clear:N \l__font_decl_family_id_tl \tl_clear:N \l__font_external_command_tl \tl_clear:N \l__font_external_engine_tl \tl_clear:N \l__font_external_render_command_tl \tl_clear:N \l__font_external_clusterwise_tl \clist_clear:N \l__font_unicode_blocks_clist \tl_clear:N \l__font_backend_tl \tl_clear:N \l__font_script_class_tl \tl_clear:N \l__font_scope_tl \tl_clear:N \l__font_inline_axis_tl \tl_clear:N \l__font_inline_direction_tl \tl_clear:N \l__font_block_progression_tl \tl_clear:N \l__font_preserve_spaces_tl \tl_clear:N \l__font_inline_behavior_tl \tl_clear:N \l__font_vertical_strategy_tl \bool_set_false:N \l__font_use_latex_fallback_bool } \keys_define:nn { font/declare } { scope .tl_set:N = \l__font_scope_tl, name .tl_set:N = \l__font_name_tl, path .tl_set:N = \l__font_path_tl, boldpath .tl_set:N = \l__font_bold_path_tl, italicpath .tl_set:N = \l__font_italic_path_tl, bolditalicpath .tl_set:N = \l__font_bolditalic_path_tl, sanspath .tl_set:N = \l__font_sans_path_tl, sansboldpath .tl_set:N = \l__font_sans_bold_path_tl, sansitalicpath .tl_set:N = \l__font_sans_italic_path_tl, sansbolditalicpath .tl_set:N = \l__font_sans_bolditalic_path_tl, monopath .tl_set:N = \l__font_mono_path_tl, monoboldpath .tl_set:N = \l__font_mono_bold_path_tl, regular .tl_set:N = \l__font_regular_tl, bold .tl_set:N = \l__font_bold_tl, italic .tl_set:N = \l__font_italic_tl, bolditalic .tl_set:N = \l__font_bolditalic_tl, sans .tl_set:N = \l__font_sans_tl, sansbold .tl_set:N = \l__font_sans_bold_tl, sansitalic .tl_set:N = \l__font_sans_italic_tl, sansbolditalic .tl_set:N = \l__font_sans_bolditalic_tl, mono .tl_set:N = \l__font_mono_tl, monobold .tl_set:N = \l__font_mono_bold_tl, script .tl_set:N = \l__font_script_tl, language .tl_set:N = \l__font_language_tl, scriptclass .tl_set:N = \l__font_script_class_tl, inlineaxis .tl_set:N = \l__font_inline_axis_tl, inlinedirection .tl_set:N = \l__font_inline_direction_tl, blockprogression .tl_set:N = \l__font_block_progression_tl, preservespaces .tl_set:N = \l__font_preserve_spaces_tl, inlinebehavior .tl_set:N = \l__font_inline_behavior_tl, verticalstrategy .tl_set:N = \l__font_vertical_strategy_tl, verticalrotation .tl_set:N = \l__font_vertical_rotation_override_tl, verticalorigin .tl_set:N = \l__font_vertical_origin_override_tl, verticaltopcorrection .tl_set:N = \l__font_vertical_top_correction_override_tl, features .tl_set:N = \l__font_features_tl, cjkfallback .tl_set:N = \l__font_cjk_fallback_tl, cjkfallbacks .tl_set:N = \l__font_cjk_fallback_tl, command .tl_set:N = \l__font_command_tl, layout .tl_set:N = \l__font_layout_tl, familyid .tl_set:N = \l__font_decl_family_id_tl, backend .tl_set:N = \l__font_backend_tl, fallbackmode .tl_set:N = \l__font_fallback_mode_tl, specialmodule .tl_set:N = \l__font_special_module_tl, specialbuilder .tl_set:N = \l__font_special_module_tl, externalcommand .tl_set:N = \l__font_external_command_tl, externalengine .tl_set:N = \l__font_external_engine_tl, externalrendercommand .tl_set:N = \l__font_external_render_command_tl, externalclusterwise .tl_set:N = \l__font_external_clusterwise_tl, unicodeblocks .clist_set:N = \l__font_unicode_blocks_clist, unicodeblock .clist_set:N = \l__font_unicode_blocks_clist, } \cs_new_protected:Npn \__font_special_use_generic: { \__font_define_local_families_generic: } \prg_new_conditional:Npnn \__font_special_is_builtin:n #1 { TF } { \str_case:nnF {#1} { } { \prg_return_false: } } \cs_new_protected:Npn \__font_import_special_module: { \exp_args:NV \__font_special_is_builtin:nTF \l__font_special_module_tl { } { \seq_if_in:NVF \g__font_loaded_special_modules_seq \l__font_special_module_tl { \bool_if:NTF \l__font_nextsystem_installed_bool { \use:x { \exp_not:N \subimport { modules/fonts/ } { impe-font-\l__font_special_module_tl .tex } } } { \use:x { \exp_not:N \subimport { ../../modules/fonts/ } { impe-font-\l__font_special_module_tl .tex } } } \seq_gput_right:NV \g__font_loaded_special_modules_seq \l__font_special_module_tl } } } \cs_new_protected:Npn \__font_apply_layout_compat: { \str_if_eq:VnT \l__font_special_module_tl { vertical } { \PackageWarning{font-defaults} {specialmodule=vertical~is~deprecated.~Use~layout=vertical~instead} \tl_set:Nn \l__font_layout_tl { vertical } \tl_clear:N \l__font_special_module_tl } } \cs_new_protected:Npn \__font_note_missing_face:nn #1#2 { \tl_if_blank:VTF \l__font_missing_face_tl { \tl_set:Nn \l__font_missing_face_tl { #1 = #2 } } { } } \cs_new_protected:Npn \__font_check_face:nnVV #1#2#3#4 { \tl_if_blank:VTF #4 { \exp_args:NV \IfFontExistsTF #3 { } { \__font_note_missing_face:nn {#1} {#2} } } { \exp_args:Nx \file_if_exist:nTF { \tl_use:N #4 \tl_use:N #3 } { } { \__font_note_missing_face:nn {#1} {#2} } } } \prg_new_conditional:Npnn \__font_all_faces_exist: { TF } { \tl_clear:N \l__font_missing_face_tl \__font_check_face:nnVV {regular} { \l__font_regular_tl } \l__font_regular_tl \l__font_path_tl \__font_check_face:nnVV {bold} { \l__font_resolved_bold_tl } \l__font_resolved_bold_tl \l__font_resolved_bold_path_tl \__font_check_face:nnVV {italic} { \l__font_resolved_italic_tl } \l__font_resolved_italic_tl \l__font_resolved_italic_path_tl \__font_check_face:nnVV {bolditalic} { \l__font_resolved_bolditalic_tl } \l__font_resolved_bolditalic_tl \l__font_resolved_bolditalic_path_tl \__font_check_face:nnVV {sans} { \l__font_resolved_sans_tl } \l__font_resolved_sans_tl \l__font_resolved_sans_path_tl \__font_check_face:nnVV {sansbold} { \l__font_resolved_sans_bold_tl } \l__font_resolved_sans_bold_tl \l__font_resolved_sans_bold_path_tl \__font_check_face:nnVV {sansitalic} { \l__font_resolved_sans_italic_tl } \l__font_resolved_sans_italic_tl \l__font_resolved_sans_italic_path_tl \__font_check_face:nnVV {sansbolditalic} { \l__font_resolved_sans_bolditalic_tl } \l__font_resolved_sans_bolditalic_tl \l__font_resolved_sans_bolditalic_path_tl \__font_check_face:nnVV {mono} { \l__font_resolved_mono_tl } \l__font_resolved_mono_tl \l__font_resolved_mono_path_tl \__font_check_face:nnVV {monobold} { \l__font_resolved_mono_bold_tl } \l__font_resolved_mono_bold_tl \l__font_resolved_mono_bold_path_tl \tl_if_blank:VTF \l__font_missing_face_tl { \prg_return_true: } { \prg_return_false: } } \cs_new_protected:Npn \__font_warn_soft_fallback: { \PackageWarning{font-defaults} {Font~declaration~`\tl_use:N \l__font_name_tl`~could~not~be~resolved~(\tl_use:N \l__font_missing_face_tl).~Falling~back~to~LaTeX~default~families} } \cs_new_protected:Npn \__font_error_missing_faces: { \PackageError{font-defaults} {Font~declaration~`\tl_use:N \l__font_name_tl`~could~not~be~resolved~(\tl_use:N \l__font_missing_face_tl)} {Check~the~font~name~or~font~file~path,~or~set~fallbackmode=soft.} } \cs_new_protected:Npn \__font_define_local_families_fallback: { \cs_set_protected:cpn { __fontrm_\l__font_name_tl } { \rmfamily } \cs_set_protected:cpn { __fontsf_\l__font_name_tl } { \sffamily } \cs_set_protected:cpn { __fonttt_\l__font_name_tl } { \ttfamily } \exp_args:NV \__font_define_behavior_hooks:n \l__font_name_tl \exp_args:NVV \__font_define_public_command:nn \l__font_command_tl \l__font_name_tl \tl_if_blank:VF \l__font_external_command_tl { \use:x { \exp_not:N \__font_define_externalized_command:nnnnn { \tl_use:N \l__font_external_command_tl } { \tl_use:N \l__font_external_engine_tl } { \tl_use:N \l__font_decl_family_id_tl } { \tl_use:N \l__font_external_render_command_tl } { \tl_use:N \l__font_external_clusterwise_tl } } } } \cs_new_protected:Npn \__font_define_special_local: { \__font_import_special_module: \tl_set:Nx \l__font_special_entry_tl { __font_define_special_\l__font_special_module_tl : } \exp_args:NV \cs_if_exist:cTF \l__font_special_entry_tl { \exp_args:NV \use:c \l__font_special_entry_tl } { \PackageWarning{font-defaults} {Special~module~`\tl_use:N \l__font_special_module_tl`~has~no~entry~point.~Using~generic~local~font~definition} \__font_define_local_families_generic: } } \cs_new_protected:Npn \__font_append_script_language_feature_options:N #1 { \tl_if_blank:VF \l__font_script_tl { \tl_put_right:Nx #1 { Script = \exp_not:V \l__font_script_tl , } } \tl_if_blank:VF \l__font_language_tl { \tl_put_right:Nx #1 { Language = \exp_not:V \l__font_language_tl , } } \tl_if_blank:VF \l__font_effective_features_tl { \tl_put_right:Nx #1 { \l__font_effective_features_tl, } } } \cs_new_protected:Npn \__font_append_path_option:NV #1#2 { \tl_if_blank:VTF #2 { } { \tl_put_right:Nx #1 { Path = { \exp_not:V #2 } , } } } \cs_new_protected:Npn \__font_append_backend_options:N #1 { \str_case:VnF \l__font_backend_tl { { generic } { } { native } { } { harfbuzz } { \sys_if_engine_luatex:T { \tl_put_right:Nn #1 { Renderer = HarfBuzz, } } } { graphite } { \sys_if_engine_xetex:T { \tl_put_right:Nn #1 { Renderer = Graphite, } } } } { } } \cs_new_protected:Npn \__font_set_feature_path_option:NV #1#2 { \tl_clear:N #1 \tl_if_blank:VTF #2 { } { \tl_put_right:Nx #1 { Path = { \exp_not:V #2 } , } } } \cs_new_protected:Npn \__font_build_main_options: { \tl_clear:N \l__font_main_options_tl \__font_append_backend_options:N \l__font_main_options_tl \__font_append_path_option:NV \l__font_main_options_tl \l__font_path_tl \tl_put_right:Nx \l__font_main_options_tl { BoldFont = { \l__font_resolved_bold_tl }, } \__font_set_feature_path_option:NV \l__font_feature_options_tl \l__font_resolved_bold_path_tl \tl_put_right:Nx \l__font_main_options_tl { BoldFeatures = { \tl_use:N \l__font_feature_options_tl }, } \tl_put_right:Nx \l__font_main_options_tl { ItalicFont = { \l__font_resolved_italic_tl }, } \__font_set_feature_path_option:NV \l__font_feature_options_tl \l__font_resolved_italic_path_tl \tl_put_right:Nx \l__font_main_options_tl { ItalicFeatures = { \tl_use:N \l__font_feature_options_tl }, } \tl_put_right:Nx \l__font_main_options_tl { BoldItalicFont = { \l__font_resolved_bolditalic_tl }, } \__font_set_feature_path_option:NV \l__font_feature_options_tl \l__font_resolved_bolditalic_path_tl \tl_put_right:Nx \l__font_main_options_tl { BoldItalicFeatures = { \tl_use:N \l__font_feature_options_tl }, } \__font_append_script_language_feature_options:N \l__font_main_options_tl } \cs_new_protected:Npn \__font_build_sans_options: { \tl_clear:N \l__font_sans_options_tl \__font_append_backend_options:N \l__font_sans_options_tl \__font_append_path_option:NV \l__font_sans_options_tl \l__font_resolved_sans_path_tl \tl_put_right:Nx \l__font_sans_options_tl { BoldFont = { \l__font_resolved_sans_bold_tl }, } \__font_set_feature_path_option:NV \l__font_feature_options_tl \l__font_resolved_sans_bold_path_tl \tl_put_right:Nx \l__font_sans_options_tl { BoldFeatures = { \tl_use:N \l__font_feature_options_tl }, } \tl_put_right:Nx \l__font_sans_options_tl { ItalicFont = { \l__font_resolved_sans_italic_tl }, } \__font_set_feature_path_option:NV \l__font_feature_options_tl \l__font_resolved_sans_italic_path_tl \tl_put_right:Nx \l__font_sans_options_tl { ItalicFeatures = { \tl_use:N \l__font_feature_options_tl }, } \tl_put_right:Nx \l__font_sans_options_tl { BoldItalicFont = { \l__font_resolved_sans_bolditalic_tl }, } \__font_set_feature_path_option:NV \l__font_feature_options_tl \l__font_resolved_sans_bolditalic_path_tl \tl_put_right:Nx \l__font_sans_options_tl { BoldItalicFeatures = { \tl_use:N \l__font_feature_options_tl }, } \__font_append_script_language_feature_options:N \l__font_sans_options_tl } \cs_new_protected:Npn \__font_build_mono_options: { \tl_clear:N \l__font_mono_options_tl \__font_append_backend_options:N \l__font_mono_options_tl \__font_append_path_option:NV \l__font_mono_options_tl \l__font_resolved_mono_path_tl \tl_put_right:Nx \l__font_mono_options_tl { BoldFont = { \l__font_resolved_mono_bold_tl }, } \__font_set_feature_path_option:NV \l__font_feature_options_tl \l__font_resolved_mono_bold_path_tl \tl_put_right:Nx \l__font_mono_options_tl { BoldFeatures = { \tl_use:N \l__font_feature_options_tl }, } \tl_put_right:Nx \l__font_mono_options_tl { ItalicFont = { \l__font_resolved_italic_tl }, } \__font_set_feature_path_option:NV \l__font_feature_options_tl \l__font_resolved_italic_path_tl \tl_put_right:Nx \l__font_mono_options_tl { ItalicFeatures = { \tl_use:N \l__font_feature_options_tl }, } \tl_put_right:Nx \l__font_mono_options_tl { BoldItalicFont = { \l__font_resolved_bolditalic_tl }, } \__font_set_feature_path_option:NV \l__font_feature_options_tl \l__font_resolved_bolditalic_path_tl \tl_put_right:Nx \l__font_mono_options_tl { BoldItalicFeatures = { \tl_use:N \l__font_feature_options_tl }, } \__font_append_script_language_feature_options:N \l__font_mono_options_tl } \cs_new_protected:Npn \__font_define_public_command:nn #1#2 { \str_if_eq:VnTF \l__font_script_class_tl { cjk } { \str_if_eq:VnTF \l__font_preserve_spaces_tl { true } { \cs_set_protected:cpn { __font_space_policy_#2: } { \cs_if_exist:NT \xeCJKsetup { \xeCJKsetup { CJKspace = true } } } } { \cs_set_protected:cpn { __font_space_policy_#2: } { \cs_if_exist:NT \xeCJKsetup { \xeCJKsetup { CJKspace = false } } } } } { \cs_set_protected:cpn { __font_space_policy_#2: } { } } \cs_set_protected:cpn { __font_map_sf_#2: } { \cs_set_protected:Npn \sffamily { \use:c { __fontsf_#2 } } } \tl_if_blank:VTF \l__font_mono_tl { \cs_set_protected:cpn { __font_map_tt_#2: } { } } { \cs_set_protected:cpn { __font_map_tt_#2: } { \cs_set_protected:Npn \ttfamily { \use:c { __fonttt_#2 } } } } \cs_set_protected:cpn { __font_prepare_local_#2: } { \use:c { __font_space_policy_#2: } \use:c { __font_map_sf_#2: } \use:c { __font_map_tt_#2: } \use:c { __fontrm_#2 } \bool_set_false:N \l__font_reapply_style_bool \str_if_eq:eeF { \use:c { f@series } } { \mddefault } { \exp_args:Nx \fontseries { \use:c { f@series } } \bool_set_true:N \l__font_reapply_style_bool } \str_if_eq:eeF { \use:c { f@shape } } { \updefault } { \exp_args:Nx \fontshape { \use:c { f@shape } } \bool_set_true:N \l__font_reapply_style_bool } \bool_if:NT \l__font_reapply_style_bool { \selectfont } } \exp_args:Nc \DeclareDocumentCommand {#1} {+m} { { \bool_set_true:N \l__font_local_override_bool \use:c { __font_prepare_local_#2: } \__font_apply_behavior:nn {#2} {##1} } } } \cs_new_protected:Npn \__font_apply_cjk_fallback_family:n #1 { \tl_if_blank:VF \l__font_cjk_fallback_tl { \tl_set:Nx \l_tmpa_tl { \tl_to_str:n {#1} / \tl_to_str:V \l__font_cjk_fallback_tl } \prop_if_in:NVF \g__font_cjk_fallback_applied_prop \l_tmpa_tl { \cs_if_exist:NF \setCJKfallbackfamilyfont { \RequirePackage{xeCJK} } \cs_if_exist:NT \xeCJKsetup { \xeCJKsetup { AutoFallBack = true } } \cs_if_exist:NT \xeCJKDeclareCharClass { \xeCJKDeclareCharClass { CJK } { "2EBF0 -> "2EE5F , "31350 -> "323AF , "323B0 -> "3347F } } \use:x { \exp_not:N \setCJKfallbackfamilyfont { \exp_not:n {#1} } { \exp_not:V \l__font_cjk_fallback_tl } } \prop_gput:NVn \g__font_cjk_fallback_applied_prop \l_tmpa_tl { applied } } } } \tl_new:N \l__font_vertical_embed_gap_tl \tl_new:N \l__font_vertical_base_command_tl \tl_new:N \l__font_vertical_base_name_tl \tl_new:N \l__font_vertical_flow_tl \tl_new:N \l__font_vertical_rotation_angle_tl \tl_new:N \l__font_vertical_rotation_origin_tl \tl_clear_new:N \l__font_vertical_rotation_override_tl \tl_clear_new:N \l__font_vertical_origin_override_tl \tl_clear_new:N \l__font_vertical_top_correction_override_tl \tl_new:N \l__font_vertical_content_tl \tl_new:N \l__font_vertical_style_family_tl \tl_new:N \l__font_vertical_style_series_tl \tl_new:N \l__font_vertical_style_shape_tl \tl_new:N \l__font_vertical_style_setup_tl \bool_new:N \l__font_vertical_first_word_bool \dim_new:N \l__font_vertical_embed_top_correction_dim \dim_new:N \l__font_vertical_embed_bottom_padding_dim \dim_new:N \l__font_vertical_embed_height_dim \dim_new:N \l__font_vertical_embed_depth_dim \box_new:N \l__font_vertical_embed_box \box_new:N \l__font_vertical_source_box \cs_new_protected:Npn \__font_vertical_use_base:n #1 { \use:c { __font_space_policy_\l__font_vertical_base_name_tl : } \use:c { __font_map_sf_\l__font_vertical_base_name_tl : } \use:c { __font_map_tt_\l__font_vertical_base_name_tl : } \str_case:VnF \l__font_vertical_style_family_tl { { sans } { \use:c { __fontsf_\l__font_vertical_base_name_tl } } { mono } { \use:c { __fonttt_\l__font_vertical_base_name_tl } } } { \use:c { __fontrm_\l__font_vertical_base_name_tl } } \bool_set_false:N \l__font_reapply_style_bool \str_if_eq:eeF { \use:c { f@series } } { \mddefault } { \exp_args:Nx \fontseries { \use:c { f@series } } \bool_set_true:N \l__font_reapply_style_bool } \str_if_eq:eeF { \use:c { f@shape } } { \updefault } { \exp_args:Nx \fontshape { \use:c { f@shape } } \bool_set_true:N \l__font_reapply_style_bool } \bool_if:NT \l__font_reapply_style_bool { \selectfont } #1 } \cs_new_protected:Npn \__font_vertical_emit_word:n #1 { \tl_if_blank:nF {#1} { \bool_if:NF \l__font_vertical_first_word_bool { \nobreak \hskip \l__font_vertical_embed_gap_tl \relax \allowbreak } \bool_set_false:N \l__font_vertical_first_word_bool \__font_vertical_embed_word:nn { 0pt } {#1} } } \cs_new_protected:Npn \__font_vertical_emit_words_forward:n #1 { \bool_set_true:N \l__font_vertical_first_word_bool \regex_split:nnN { \s+ } {#1} \l_tmpa_seq \seq_map_inline:Nn \l_tmpa_seq { \__font_vertical_emit_word:n {##1} } } \cs_new_protected:Npn \__font_vertical_emit_words_reverse:n #1 { \bool_set_true:N \l__font_vertical_first_word_bool \regex_split:nnN { \s+ } {#1} \l_tmpa_seq \seq_map_inline_reverse:Nn \l_tmpa_seq { \__font_vertical_emit_word:n {##1} } } \cs_new_protected:Npn \__font_vertical_style_reset: { \tl_clear:N \l__font_vertical_style_family_tl \tl_clear:N \l__font_vertical_style_series_tl \tl_clear:N \l__font_vertical_style_shape_tl \tl_clear:N \l__font_vertical_style_setup_tl } \cs_new_protected:Npn \__font_vertical_finalize_argument: { \tl_clear:N \l__font_vertical_style_setup_tl \tl_if_blank:VF \l__font_vertical_style_series_tl { \tl_put_right:NV \l__font_vertical_style_setup_tl \l__font_vertical_style_series_tl } \tl_if_blank:VF \l__font_vertical_style_shape_tl { \tl_put_right:NV \l__font_vertical_style_setup_tl \l__font_vertical_style_shape_tl } } \cs_new_protected:Npn \__font_vertical_prepare_argument:n #1 { \__font_vertical_style_reset: \tl_set:Nn \l__font_vertical_content_tl {#1} \__font_vertical_unwrap_loop: } \cs_new_protected:Npn \__font_vertical_unwrap_loop: { \tl_if_head_eq_meaning:VNTF \l__font_vertical_content_tl \textsf { \__font_vertical_unwrap_textsf: } { \tl_if_head_eq_meaning:VNTF \l__font_vertical_content_tl \texttt { \__font_vertical_unwrap_texttt: } { \tl_if_head_eq_meaning:VNTF \l__font_vertical_content_tl \textbf { \__font_vertical_unwrap_textbf: } { \tl_if_head_eq_meaning:VNTF \l__font_vertical_content_tl \textit { \__font_vertical_unwrap_textit: } { \__font_vertical_finalize_argument: } } } } } \cs_new_protected:Npn \__font_vertical_unwrap_textsf: { \exp_after:wN \__font_vertical_unwrap_textsf_aux:w \l__font_vertical_content_tl \q_stop } \cs_new_protected:Npn \__font_vertical_unwrap_textsf_aux:w \textsf #1#2 \q_stop { \tl_if_blank:nTF {#2} { \tl_set:Nn \l__font_vertical_style_family_tl { sans } \tl_set:Nn \l__font_vertical_content_tl {#1} \__font_vertical_unwrap_loop: } { \__font_vertical_finalize_argument: } } \cs_new_protected:Npn \__font_vertical_unwrap_texttt: { \exp_after:wN \__font_vertical_unwrap_texttt_aux:w \l__font_vertical_content_tl \q_stop } \cs_new_protected:Npn \__font_vertical_unwrap_texttt_aux:w \texttt #1#2 \q_stop { \tl_if_blank:nTF {#2} { \tl_set:Nn \l__font_vertical_style_family_tl { mono } \tl_set:Nn \l__font_vertical_content_tl {#1} \__font_vertical_unwrap_loop: } { \__font_vertical_finalize_argument: } } \cs_new_protected:Npn \__font_vertical_unwrap_textbf: { \exp_after:wN \__font_vertical_unwrap_textbf_aux:w \l__font_vertical_content_tl \q_stop } \cs_new_protected:Npn \__font_vertical_unwrap_textbf_aux:w \textbf #1#2 \q_stop { \tl_if_blank:nTF {#2} { \tl_set:Nn \l__font_vertical_style_series_tl { \bfseries } \tl_set:Nn \l__font_vertical_content_tl {#1} \__font_vertical_unwrap_loop: } { \__font_vertical_finalize_argument: } } \cs_new_protected:Npn \__font_vertical_unwrap_textit: { \exp_after:wN \__font_vertical_unwrap_textit_aux:w \l__font_vertical_content_tl \q_stop } \cs_new_protected:Npn \__font_vertical_unwrap_textit_aux:w \textit #1#2 \q_stop { \tl_if_blank:nTF {#2} { \tl_set:Nn \l__font_vertical_style_shape_tl { \itshape } \tl_set:Nn \l__font_vertical_content_tl {#1} \__font_vertical_unwrap_loop: } { \__font_vertical_finalize_argument: } } \cs_new_protected:Npn \__font_define_vertical_public_command:nnnnn #1#2#3#4#5 { \exp_args:Nc \DeclareDocumentCommand {#1} { O{0pt} m } { { \tl_set:Nn \l__font_vertical_base_name_tl {#2} \tl_set:Nn \l__font_vertical_flow_tl {#3} \tl_set:Nn \l__font_vertical_rotation_angle_tl {#4} \tl_set:Nn \l__font_vertical_rotation_origin_tl {#5} \__font_vertical_prepare_argument:n {##2} \leavevmode { \tl_use:N \l__font_vertical_style_setup_tl \str_if_eq:VnTF \l__font_vertical_flow_tl { rtl } { \exp_args:NV \__font_vertical_emit_words_reverse:n \l__font_vertical_content_tl } { \exp_args:NV \__font_vertical_emit_words_forward:n \l__font_vertical_content_tl } } } } } \cs_new_protected:Npn \__font_vertical_embed_word:nn #1#2 { \hbox_set:Nn \l__font_vertical_source_box { { \__font_vertical_use_base:n {#2} } } \use:x { \exp_not:N \hbox_set:Nn \exp_not:N \l__font_vertical_embed_box { \exp_not:N \rotatebox [ origin=\tl_use:N \l__font_vertical_rotation_origin_tl ] { \tl_use:N \l__font_vertical_rotation_angle_tl } { \exp_not:N \box_use:N \exp_not:N \l__font_vertical_source_box } } } \dim_set:Nn \l__font_vertical_embed_height_dim { \box_ht:N \l__font_vertical_embed_box + \l__font_vertical_embed_top_correction_dim } \dim_set:Nn \l__font_vertical_embed_depth_dim { \box_dp:N \l__font_vertical_embed_box + \l__font_vertical_embed_bottom_padding_dim - \l__font_vertical_embed_top_correction_dim } \dim_compare:nNnT { \l__font_vertical_embed_depth_dim } < { 0pt } { \dim_zero:N \l__font_vertical_embed_depth_dim } \leavevmode \raisebox{\l__font_vertical_embed_top_correction_dim} [\l__font_vertical_embed_height_dim] [\l__font_vertical_embed_depth_dim] { \box_use:N \l__font_vertical_embed_box } } \cs_new_protected:Npn \__font_define_special_vertical: { \__font_special_use_generic: \tl_set:Nn \l__font_vertical_embed_gap_tl { 0.35em } \dim_set:Nn \l__font_vertical_embed_top_correction_dim { 1em } \dim_set:Nn \l__font_vertical_embed_bottom_padding_dim { 0.28em } \tl_if_blank:VF \l__font_vertical_top_correction_override_tl { \dim_set:Nn \l__font_vertical_embed_top_correction_dim { \l__font_vertical_top_correction_override_tl } } \tl_if_blank:VTF \l__font_vertical_strategy_tl { \str_if_eq:VnTF \l__font_inline_direction_tl { rtl } { \tl_set:Nn \l__font_vertical_flow_tl { ltr } } { \tl_set:Nn \l__font_vertical_flow_tl { rtl } } } { \tl_set_eq:NN \l__font_vertical_flow_tl \l__font_vertical_strategy_tl } \tl_if_blank:VTF \l__font_vertical_rotation_override_tl { \tl_set:Nn \l__font_vertical_rotation_angle_tl { -90 } } { \tl_set_eq:NN \l__font_vertical_rotation_angle_tl \l__font_vertical_rotation_override_tl } \tl_if_blank:VTF \l__font_vertical_origin_override_tl { \tl_set:Nn \l__font_vertical_rotation_origin_tl { lB } } { \tl_set_eq:NN \l__font_vertical_rotation_origin_tl \l__font_vertical_origin_override_tl } \tl_set:Nx \l_tmpa_tl { \tl_use:N \l__font_command_tl v } \use:x { \exp_not:N \__font_define_vertical_public_command:nnnnn { \tl_use:N \l_tmpa_tl } { \tl_use:N \l__font_name_tl } { \tl_use:N \l__font_vertical_flow_tl } { \tl_use:N \l__font_vertical_rotation_angle_tl } { \tl_use:N \l__font_vertical_rotation_origin_tl } } } \cs_new_protected:Npn \__font_define_local_families_generic: { \__font_build_main_options: \__font_build_sans_options: \__font_build_mono_options: \str_if_eq:VnTF \l__font_script_class_tl { cjk } { \cs_if_exist:NF \newCJKfontfamily { \RequirePackage{xeCJK} } \bool_if:NF \g__font_cjk_main_declared_bool { \use:x { \exp_not:N \setCJKmainfont [ \tl_use:N \l__font_main_options_tl ] { \l__font_regular_tl } } \__font_apply_cjk_fallback_family:n { \CJKrmdefault } \bool_gset_true:N \g__font_cjk_main_declared_bool } \use:x { \exp_not:N \newCJKfontfamily [ { __fontrm_\l__font_name_tl } ] \exp_not:c { __fontrm_\l__font_name_tl } [ \tl_use:N \l__font_main_options_tl ] { \l__font_regular_tl } } \__font_apply_cjk_fallback_family:n { __fontrm_\l__font_name_tl } \use:x { \exp_not:N \newCJKfontfamily [ { __fontsf_\l__font_name_tl } ] \exp_not:c { __fontsf_\l__font_name_tl } [ \tl_use:N \l__font_sans_options_tl ] { \l__font_resolved_sans_tl } } \use:x { \exp_not:N \newCJKfontfamily [ { __fonttt_\l__font_name_tl } ] \exp_not:c { __fonttt_\l__font_name_tl } [ \tl_use:N \l__font_mono_options_tl ] { \l__font_resolved_mono_tl } } } { \use:x { \exp_not:N \newfontfamily \exp_not:c { __fontrm_\l__font_name_tl } [ \tl_use:N \l__font_main_options_tl ] { \l__font_regular_tl } } \use:x { \exp_not:N \newfontfamily \exp_not:c { __fontsf_\l__font_name_tl } [ \tl_use:N \l__font_sans_options_tl ] { \l__font_resolved_sans_tl } } \use:x { \exp_not:N \newfontfamily \exp_not:c { __fonttt_\l__font_name_tl } [ \tl_use:N \l__font_mono_options_tl ] { \l__font_resolved_mono_tl } } } \exp_args:NV \__font_define_behavior_hooks:n \l__font_name_tl \exp_args:NVV \__font_define_public_command:nn \l__font_command_tl \l__font_name_tl \tl_if_blank:VF \l__font_external_command_tl { \use:x { \exp_not:N \__font_define_externalized_command:nnnnn { \tl_use:N \l__font_external_command_tl } { \tl_use:N \l__font_external_engine_tl } { \tl_use:N \l__font_decl_family_id_tl } { \tl_use:N \l__font_external_render_command_tl } { \tl_use:N \l__font_external_clusterwise_tl } } } } \cs_new_protected:Npn \__font_define_global_binding: { \__font_build_main_options: \__font_build_sans_options: \__font_build_mono_options: \str_if_eq:VnTF \l__font_script_class_tl { cjk } { \cs_if_exist:NF \setCJKmainfont { \RequirePackage{xeCJK} } \use:x { \exp_not:N \setCJKmainfont [ \tl_use:N \l__font_main_options_tl ] { \l__font_regular_tl } } \__font_apply_cjk_fallback_family:n { \CJKrmdefault } \use:x { \exp_not:N \setCJKsansfont [ \tl_use:N \l__font_sans_options_tl ] { \l__font_resolved_sans_tl } } \use:x { \exp_not:N \setCJKmonofont [ \tl_use:N \l__font_mono_options_tl ] { \l__font_resolved_mono_tl } } \bool_gset_true:N \g__font_cjk_main_declared_bool } { \use:x { \exp_not:N \setmainfont [ \tl_use:N \l__font_main_options_tl ] { \l__font_regular_tl } } \use:x { \exp_not:N \setsansfont [ \tl_use:N \l__font_sans_options_tl ] { \l__font_resolved_sans_tl } } \use:x { \exp_not:N \setmonofont [ \tl_use:N \l__font_mono_options_tl ] { \l__font_resolved_mono_tl } } } } \cs_new_protected:Npn \__font_define_range_enter_command: { \use:x { \exp_not:N \cs_set_protected:cpn { __font_enter_range_\l__font_name_tl : } { \exp_not:N \bool_if:NF \exp_not:N \l__font_local_override_bool { \exp_not:N \begingroup \exp_not:c { __fontglobal_\l__font_name_tl } } } } } \cs_new_protected:Npn \__font_leave_range: { \bool_if:NF \l__font_local_override_bool { \endgroup } } \cs_new:Npn \__font_interchar_class_max: { \int_eval:n { \use:c { xe@alloc@intercharclass } } } \cs_new:Npn \__font_interchar_boundary_class: { \int_eval:n { \use:c { e@alloc@intercharclass@top } } } \cs_new_protected:Npn \__font_assign_unicode_block_class:nnn #1#2#3 { \cs_if_exist:cF { __font_unicode_block_#1_class } { \exp_args:Nc \newXeTeXintercharclass { __font_unicode_block_#1_class } \int_step_inline:nnn {#2} {#3} { \XeTeXcharclass ##1 = \use:c { __font_unicode_block_#1_class } } } } \cs_new_protected:Npn \__font_ensure_unicode_block_class:n #1 { \prop_get:NnNTF \g__font_unicode_block_range_prop {#1} \l_tmpa_tl { \use:x { \exp_not:N \__font_assign_unicode_block_class:nnn {#1} \exp_not:V \l_tmpa_tl } } { \PackageWarning{font-defaults} {Unicode~block~`#1'~is~not~registered;~skipping~range~global~binding} } } \cs_new_protected:Npn \__font_set_range_transition:nnn #1#2#3 { \use:x { \exp_not:N \XeTeXinterchartoks #1 \exp_not:c { __font_unicode_block_#2_class } = { \exp_not:c { __font_enter_range_#3: } } \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_unicode_block_#2_class } #1 = { \exp_not:N \__font_leave_range: } } } \cs_new_protected:Npn \__font_set_transition_for_range_block:nn #1#2 { \int_step_inline:nnn { 0 } { \__font_interchar_class_max: } { \int_compare:nNnF {##1} = { \use:c { __font_unicode_block_#1_class } } { \__font_set_range_transition:nnn {##1} {#1} {#2} } } \__font_set_range_transition:nnn { \__font_interchar_boundary_class: } {#1} {#2} } \cs_new_protected:Npn \__font_devanagari_class_map_inline:n #1 { \clist_map_inline:nn { Start, Mark, Virama, EndMark, Danda } {#1} } \cs_new_protected:Npn \__font_assign_devanagari_range:nnn #1#2#3 { \int_step_inline:nnn {#1} {#2} { \XeTeXcharclass ##1 = \use:c { __font_devanagari_#3_class } } } \cs_new_protected:Npn \__font_ensure_devanagari_akshara_classes: { \cs_if_exist:cF { __font_devanagari_Start_class } { \__font_devanagari_class_map_inline:n { \exp_args:Nc \newXeTeXintercharclass { __font_devanagari_##1_class } } \__font_assign_devanagari_range:nnn { "0904 } { "0914 } { Start } \__font_assign_devanagari_range:nnn { "0915 } { "0939 } { Start } \__font_assign_devanagari_range:nnn { "0958 } { "095F } { Start } \XeTeXcharclass "0950 = \use:c { __font_devanagari_Start_class } \__font_assign_devanagari_range:nnn { "093E } { "094C } { Mark } \XeTeXcharclass "093C = \use:c { __font_devanagari_Mark_class } \XeTeXcharclass "094E = \use:c { __font_devanagari_Mark_class } \XeTeXcharclass "094F = \use:c { __font_devanagari_Mark_class } \__font_assign_devanagari_range:nnn { "0962 } { "0963 } { Mark } \XeTeXcharclass "094D = \use:c { __font_devanagari_Virama_class } \__font_assign_devanagari_range:nnn { "0900 } { "0903 } { EndMark } \XeTeXcharclass "093D = \use:c { __font_devanagari_EndMark_class } \__font_assign_devanagari_range:nnn { "0951 } { "0957 } { EndMark } \XeTeXcharclass "0964 = \use:c { __font_devanagari_Danda_class } \XeTeXcharclass "0965 = \use:c { __font_devanagari_Danda_class } } } \cs_new_protected:Npn \__font_set_devanagari_transition:nnn #1#2#3 { \use:x { \exp_not:N \XeTeXinterchartoks #1 \exp_not:c { __font_devanagari_#2_class } = { \exp_not:c { __font_enter_range_#3: } } \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_devanagari_#2_class } #1 = { \exp_not:N \__font_leave_range: } } } \cs_new_protected:Npn \__font_set_devanagari_intra_transition:nnn #1#2#3 { \use:x { \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_devanagari_#1_class } \exp_not:c { __font_devanagari_#2_class } = { #3 } } } \cs_new_protected:Npn \__font_set_devanagari_akshara_transitions:n #1 { \int_step_inline:nnn { 0 } { \__font_interchar_class_max: } { \__font_devanagari_class_map_inline:n { \int_compare:nNnF {##1} = { \use:c { __font_devanagari_####1_class } } { \__font_set_devanagari_transition:nnn {##1} {####1} {#1} } } } \__font_devanagari_class_map_inline:n { \__font_set_devanagari_transition:nnn { \__font_interchar_boundary_class: } {##1} {#1} } \__font_devanagari_class_map_inline:n { \__font_devanagari_class_map_inline:n { \__font_set_devanagari_intra_transition:nnn {##1} {####1} { } } } \__font_set_devanagari_intra_transition:nnn { Start } { Start } { \exp_not:N \__font_devanagari_akshara_break: } \__font_set_devanagari_intra_transition:nnn { Mark } { Start } { \exp_not:N \__font_devanagari_akshara_break: } \__font_set_devanagari_intra_transition:nnn { EndMark } { Start } { \exp_not:N \__font_devanagari_akshara_break: } \__font_set_devanagari_intra_transition:nnn { Danda } { Start } { \exp_not:N \__font_devanagari_danda_break: } } \cs_new_protected:Npn \__font_set_devanagari_akshara_cross_for_block:nn #1#2 { \tl_if_blank:VF \g__font_devanagari_akshara_name_tl { \__font_devanagari_class_map_inline:n { \use:x { \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_unicode_block_#1_class } \exp_not:c { __font_devanagari_##1_class } = { \exp_not:N \__font_leave_range: \exp_not:c { __font_enter_range_\g__font_devanagari_akshara_name_tl : } } \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_devanagari_##1_class } \exp_not:c { __font_unicode_block_#1_class } = { \exp_not:N \__font_leave_range: \exp_not:c { __font_enter_range_#2: } } } } } } \cs_new_protected:Npn \__font_apply_sanskrit_akshara_breaks: { \str_if_eq:VnT \l__font_decl_family_id_tl { sanskrit } { \tl_gset:NV \g__font_devanagari_akshara_name_tl \l__font_name_tl \__font_ensure_devanagari_akshara_classes: \exp_args:NV \__font_set_devanagari_akshara_transitions:n \l__font_name_tl \seq_map_inline:Nn \g__font_range_global_blocks_seq { \prop_get:NnN \g__font_range_global_name_prop {##1} \l_tmpa_tl \use:x { \exp_not:N \__font_set_devanagari_akshara_cross_for_block:nn {##1} { \exp_not:V \l_tmpa_tl } } } } } \cs_new_protected:Npn \__font_ensure_tibetan_tsheg_class: { \cs_if_exist:cF { __font_tibetan_tsheg_class } { \exp_args:Nc \newXeTeXintercharclass { __font_tibetan_tsheg_class } \XeTeXcharclass "0F0B = \use:c { __font_tibetan_tsheg_class } \XeTeXcharclass "0F0C = \use:c { __font_tibetan_tsheg_class } } } \cs_new_protected:Npn \__font_ensure_tibetan_punctuation_class: { \cs_if_exist:cF { __font_tibetan_punctuation_class } { \exp_args:Nc \newXeTeXintercharclass { __font_tibetan_punctuation_class } \clist_map_inline:Nn \c__font_tibetan_non_tsheg_punctuation_codepoints_clist { \XeTeXcharclass ##1 = \use:c { __font_tibetan_punctuation_class } } } } \cs_new_protected:Npn \__font_set_tibetan_tsheg_transition:nn #1#2 { \use:x { \exp_not:N \XeTeXinterchartoks #1 \exp_not:c { __font_tibetan_tsheg_class } = { \exp_not:c { __font_enter_range_#2: } } \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_tibetan_tsheg_class } #1 = { \exp_not:N \__font_leave_range: } } } \cs_new_protected:Npn \__font_set_tibetan_punctuation_transition:nn #1#2 { \use:x { \exp_not:N \XeTeXinterchartoks #1 \exp_not:c { __font_tibetan_punctuation_class } = { \exp_not:N \nobreak \exp_not:c { __font_enter_range_#2: } } \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_tibetan_punctuation_class } #1 = { \exp_not:N \__font_leave_range: } } } \cs_new_protected:Npn \__font_set_tibetan_tsheg_cross_transition:nnn #1#2#3 { \use:x { \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_unicode_block_#1_class } \exp_not:c { __font_tibetan_tsheg_class } = { \exp_not:N \__font_leave_range: \exp_not:c { __font_enter_range_#3: } } \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_tibetan_tsheg_class } \exp_not:c { __font_unicode_block_#1_class } = { \exp_not:N \__font_leave_range: \exp_not:c { __font_enter_range_#2: } } } } \cs_new_protected:Npn \__font_set_tibetan_punctuation_cross_transition:nnn #1#2#3 { \use:x { \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_unicode_block_#1_class } \exp_not:c { __font_tibetan_punctuation_class } = { \exp_not:N \__font_leave_range: \exp_not:N \nobreak \exp_not:c { __font_enter_range_#3: } } \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_tibetan_punctuation_class } \exp_not:c { __font_unicode_block_#1_class } = { \exp_not:N \__font_leave_range: \exp_not:c { __font_enter_range_#2: } } } } \cs_new_protected:Npn \__font_set_tibetan_tsheg_transitions:n #1 { \__font_ensure_tibetan_tsheg_class: \__font_ensure_tibetan_punctuation_class: \int_step_inline:nnn { 0 } { \__font_interchar_class_max: } { \bool_lazy_and:nnT { ! \int_compare_p:nNn {##1} = { \use:c { __font_tibetan_tsheg_class } } } { ! \int_compare_p:nNn {##1} = { \use:c { __font_tibetan_punctuation_class } } } { \__font_set_tibetan_tsheg_transition:nn {##1} {#1} \__font_set_tibetan_punctuation_transition:nn {##1} {#1} } } \__font_set_tibetan_tsheg_transition:nn { \__font_interchar_boundary_class: } {#1} \__font_set_tibetan_punctuation_transition:nn { \__font_interchar_boundary_class: } {#1} \use:x { \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_unicode_block_Tibetan_class } \exp_not:c { __font_tibetan_tsheg_class } = { } \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_tibetan_tsheg_class } \exp_not:c { __font_unicode_block_Tibetan_class } = { \exp_not:N \allowbreak } \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_unicode_block_Tibetan_class } \exp_not:c { __font_tibetan_punctuation_class } = { \exp_not:N \nobreak } \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_tibetan_punctuation_class } \exp_not:c { __font_unicode_block_Tibetan_class } = { } \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_tibetan_tsheg_class } \exp_not:c { __font_tibetan_punctuation_class } = { \exp_not:N \nobreak } \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_tibetan_punctuation_class } \exp_not:c { __font_tibetan_tsheg_class } = { \exp_not:N \nobreak } \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_tibetan_punctuation_class } \exp_not:c { __font_tibetan_punctuation_class } = { } } \seq_map_inline:Nn \g__font_range_global_blocks_seq { \str_if_eq:nnF {##1} { Tibetan } { \prop_get:NnN \g__font_range_global_name_prop {##1} \l_tmpa_tl \__font_set_tibetan_tsheg_cross_transition:nnn {##1} { \l_tmpa_tl } {#1} \__font_set_tibetan_punctuation_cross_transition:nnn {##1} { \l_tmpa_tl } {#1} } } } \cs_new_protected:Npn \__font_set_range_cross_transition:nnnn #1#2#3#4 { \str_if_eq:eeTF {#3} {#4} { % Keep a shaping run intact when adjacent Unicode blocks are owned by % the same range family. This is essential for clusters such as Old % Hangul, whose jamo can span Hangul Jamo and Extended-A/B. \use:x { \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_unicode_block_#1_class } \exp_not:c { __font_unicode_block_#2_class } = { } \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_unicode_block_#2_class } \exp_not:c { __font_unicode_block_#1_class } = { } } } { \use:x { \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_unicode_block_#1_class } \exp_not:c { __font_unicode_block_#2_class } = { \exp_not:N \__font_leave_range: \exp_not:c { __font_enter_range_#4: } } \exp_not:N \XeTeXinterchartoks \exp_not:c { __font_unicode_block_#2_class } \exp_not:c { __font_unicode_block_#1_class } = { \exp_not:N \__font_leave_range: \exp_not:c { __font_enter_range_#3: } } } } } \cs_new_protected:Npn \__font_register_range_global_block:n #1 { \tl_if_blank:nF {#1} { \__font_ensure_unicode_block_class:n {#1} \cs_if_exist:cTF { __font_unicode_block_#1_class } { \__font_set_transition_for_range_block:nn {#1} { \l__font_name_tl } \str_if_eq:nnT {#1} { Tibetan } { \__font_set_tibetan_tsheg_transitions:n { \l__font_name_tl } } \seq_map_inline:Nn \g__font_range_global_blocks_seq { \prop_get:NnN \g__font_range_global_name_prop {##1} \l_tmpa_tl \__font_set_range_cross_transition:nnnn {##1} {#1} { \l_tmpa_tl } { \l__font_name_tl } } \__font_set_devanagari_akshara_cross_for_block:nn {#1} { \l__font_name_tl } \prop_put:Nnx \g__font_range_global_name_prop {#1} { \l__font_name_tl } \seq_gput_right:Nn \g__font_range_global_blocks_seq {#1} } { } } } \cs_new_protected:Npn \__font_define_range_global_binding: { \sys_if_engine_xetex:TF { \XeTeXinterchartokenstate = 1 \__font_build_main_options: \tl_if_blank:VTF \l__font_name_tl { \tl_set_eq:NN \l__font_name_tl \l__font_decl_family_id_tl } { } \str_if_eq:VnTF \l__font_script_class_tl { cjk } { \tl_if_blank:VTF \l__font_cjk_fallback_tl { \use:x { \exp_not:N \newfontfamily \exp_not:c { __fontglobal_\l__font_name_tl } [ \tl_use:N \l__font_main_options_tl ] { \l__font_regular_tl } } } { \cs_if_exist:NF \setCJKmainfont { \RequirePackage{xeCJK} } \bool_if:NF \g__font_cjk_main_declared_bool { \use:x { \exp_not:N \setCJKmainfont [ \tl_use:N \l__font_main_options_tl ] { \l__font_regular_tl } } \bool_gset_true:N \g__font_cjk_main_declared_bool } \__font_apply_cjk_fallback_family:n { \CJKrmdefault } \clist_clear:N \l__font_unicode_blocks_clist } } { \use:x { \exp_not:N \newfontfamily \exp_not:c { __fontglobal_\l__font_name_tl } [ \tl_use:N \l__font_main_options_tl ] { \l__font_regular_tl } } } \__font_define_range_enter_command: \clist_map_inline:Nn \l__font_unicode_blocks_clist { \__font_register_range_global_block:n {##1} } \__font_apply_sanskrit_akshara_breaks: \int_gset:Nn \g__font_range_known_class_max_int { \__font_interchar_class_max: } } { \PackageError{font-defaults} {Unicode-range~global~fonts~require~XeLaTeX} {Compile~with~xelatex,~or~use~this~family~in~local~mode.} } } \cs_new_protected:Npn \__font_apply_declaration: { \tl_if_blank:VTF \l__font_regular_tl { \PackageError{font-defaults}{Missing~regular~field}{Set~regular~=...} } { } \__font_apply_core_defaults: \__font_validate_core_state: \__font_apply_script_hooks: \__font_apply_behavior_defaults: \__font_validate_behavior_state: \__font_apply_script_line_breaking: \__font_resolve_style_fallbacks: \bool_set_false:N \l__font_use_latex_fallback_bool \__font_all_faces_exist:TF { } { \str_if_eq:VnTF \l__font_fallback_mode_tl { soft } { \tl_if_blank:VTF \l__font_name_tl { \tl_set_eq:NN \l__font_name_tl \l__font_command_tl } { } \str_if_eq:VnTF \l__font_scope_tl { global } { \__font_warn_soft_fallback: \bool_set_true:N \l__font_use_latex_fallback_bool } { \tl_if_blank:VTF \l__font_command_tl { \PackageError{font-defaults}{Missing~command~field}{Set~command~=...~for~local~scope.} } { } \__font_warn_soft_fallback: \__font_define_local_families_fallback: \bool_set_true:N \l__font_use_latex_fallback_bool } } { \__font_error_missing_faces: } } \str_if_eq:VnTF \l__font_scope_tl { global } { \bool_if:NF \l__font_use_latex_fallback_bool { \clist_if_empty:NTF \l__font_unicode_blocks_clist { \__font_define_global_binding: } { \__font_define_range_global_binding: } } } { \bool_if:NF \l__font_use_latex_fallback_bool { \tl_if_blank:VTF \l__font_command_tl { \PackageError{font-defaults}{Missing~command~field}{Set~command~=...~for~local~scope.} } { } \tl_if_blank:VTF \l__font_name_tl { \tl_set_eq:NN \l__font_name_tl \l__font_command_tl } { } \__font_apply_layout_compat: \tl_if_blank:VF \l__font_special_module_tl { \__font_import_special_module: } \str_if_eq:VnTF \l__font_layout_tl { vertical } { \__font_define_special_vertical: } { \tl_if_blank:VTF \l__font_special_module_tl { \__font_define_local_families_generic: } { \__font_define_special_local: } } } } } \NewDocumentCommand{\FontDeclare}{m} { \__font_reset_state: \keys_set:nn { font/declare } {#1} \__font_apply_declaration: } \NewDocumentCommand{\FontDeclareLocalDefault}{m} { \FontDeclare{scope=local,#1} } \cs_new_protected:Npn \__font_backfill_external_class:n #1 { \seq_map_inline:Nn \g__font_range_global_blocks_seq { \prop_get:NnN \g__font_range_global_name_prop {##1} \l_tmpa_tl \__font_set_range_transition:nnn {#1} {##1} { \l_tmpa_tl } } } \cs_new_protected:Npn \__font_refresh_late_interchar_classes: { \sys_if_engine_xetex:T { \int_set:Nn \l_tmpa_int { \__font_interchar_class_max: } \int_compare:nNnT { \l_tmpa_int } > { \g__font_range_known_class_max_int } { \int_step_inline:nnn { \g__font_range_known_class_max_int + 1 } { \l_tmpa_int } { \__font_backfill_external_class:n {##1} } \int_gset_eq:NN \g__font_range_known_class_max_int \l_tmpa_int } } } \AtBeginDocument{\__font_refresh_late_interchar_classes:} \ExplSyntaxOff