latex3 / fontspec

Font selection in LaTeX for XeTeX and LuaTeX
http://latex3.github.io/fontspec/
LaTeX Project Public License v1.3c
276 stars 33 forks source link

BoldFeatures within \defaultfontfeatures #436

Closed Davislor closed 4 months ago

Davislor commented 3 years ago

Description

Using BoldFeatures = inside \defaultfontfeatures gives an error.

Check/indicate

Minimal example demonstrating the issue

\documentclass{article}
\usepackage{fontspec}

\defaultfontfeatures[FreeSerif]{
  BoldFont=*,
  BoldFeatures = {FakeBold = 1.2} }

\setmainfont{FreeSerif}

\begin{document}
\maketitle
\end{document}

Further details

On an up-to-date TeX Live 2020, this gives the error

! LaTeX3 Error: The key 'fontspec-opentype/BoldFeatures' is unknown and is
(LaTeX3)        being ignored.
chrullrich commented 2 years ago

I was able to get around that by changing fontspec-preparse to fontspec-opentype between lines 2308 and 2366 of fontspec-luatex.sty and lines 2416 and 2444 of fontspec-xetex.sty (built from current git). A very simple test document that exercises UprightFeatures, BoldFeatures, etc. combined with SizeFeatures for the optical sizes of Source Serif 4 as well as a 180-page doc that uses only a few different faces compiled with both lualatex and xelatex and looked OK to me.

No idea what may break from this change that I just have not seen yet. My guess (and it really is one) is that anything other than my exact circumstances (installed OpenType fonts on Windows) will not work anymore.

u-fischer commented 2 years ago

I don't think that this the right fix. The problem is that \__fontspec_make_font_shapes:Nnnnn calls

\__fontspec_declare_shape:nnxx {#2} {#3} { \l__fontspec_fontopts_clist, \l__fontspec_leftover_clist } {#5}

where \l__fontspec_fontopts_clist contains the font specific options. This list contains options that have been already processed (the options from the families preparsed and preparsed-external) which \__fontspec_declare_shape:nnxx should imho simply ignore. Instead it tries to set them as keys of the final family fontspec-opentype and then errors.

The problem seems to have hit someone earlier, as there are a number of dummy key definitions

\__fontspec_keys_define_code:nnn {fontspec-opentype} {UprightFont} {}
\__fontspec_keys_define_code:nnn {fontspec-opentype} {ItalicFont} {}

One could extend that list, but imho it would make more sense to set only known keys at the end:

\documentclass{article}
\usepackage{fontspec}

\ExplSyntaxOn
\cs_set:Nn \__fontspec_get_features:n
  {
    \__fontspec_init_fontface:
    \__fontspec_keys_set_known:nxN {fontspec-renderer} {\l__fontspec_fontfeat_clist,#1}
      \l__fontspec_keys_leftover_clist
    \__fontspec_keys_set_known:nxN {fontspec} {\l__fontspec_keys_leftover_clist} \l__fontspec_keys_leftover_clist
    \keys_set_known:nV {fontspec-opentype} \l__fontspec_keys_leftover_clist %changed, set only known keys

    \tl_if_empty:NF \l__fontspec_mapping_tl
      { \__fontspec_update_featstr:n { mapping = \l__fontspec_mapping_tl } }

    \str_if_eq:eeF { \l__fontspec_hexcol_tl \l__fontspec_opacity_tl }
                     { \c__fontspec_hexcol_tl \c__fontspec_opacity_tl }
       { \__fontspec_update_featstr:n { color = {\l__fontspec_hexcol_tl\l__fontspec_opacity_tl} } }
  }
\ExplSyntaxOff
\defaultfontfeatures[FreeSerif]{
  BoldFont=*,
  BoldFeatures = {FakeBold = 1.2} }

\setmainfont{FreeSerif}

\begin{document}
xx
\end{document}
chrullrich commented 2 years ago

This works perfectly with my two test documents, with both LuaTeX and XeTeX from MiKTeX and installed OpenType fonts. Guessing further, I would expect it to work in any OpenType situation. Would the same change be required for the Graphite/AAT case with XeTeX? I don't have a Mac handy to try.

wspr commented 4 months ago

This has now been resolved