latex3 / fontspec

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

Support a range of font weights #170

Open wspr opened 10 years ago

wspr commented 10 years ago

From TeX.sx, Ulrike:

It would be very fine if one could add more series/shapes. I just did go to some length to add a semibold series in one document. Naturally it would be even better if one could add more NFSS-axes to handle e.g. variants like different number types or ligatures without ending with another family name.

I wonder what would be the best interface for this sort of feature. Regardless of the fontspec interface to load them in the first place, I'd like to provide, say, \fontweight{+1} or \fontbolder to move between them.

Interface 1

Perhaps having just five in-built weights would be enough — "extra light", "light", "medium", "bold", "extra bold",

\setmainfont[ LightFont=... , ExtraBoldFont = ... ]

Interface 2

Alternatively, it might be possible to have

\setmainfont[ BoldFont = ... , BolderFont = ... , BolderFeatures = ... , BolderFont = ... , BolderFeatures = ... ]

and increment the series as b1 -> b2 -> b3 and so on, with matching LighterFont style commands as well.

Interface 3

This is probably my least favourite so far:

\setmainfont
 [
  BoldFont = { Bold Font , Extra Bold Font, Black Font, ... } ,
  BoldFontFeatures = { {BF features} , {XB features} , {BK features}, ... }
 ]

But actually would work out quite well to program.

Interface 4

Perverting keyval:

\setmainfont[ Weight = {<series>}{<features>}{<font name>} ]

I think this would be ugly.

Interface 5

Even more keyval nesting:

[ WeightFont = { Series=..., Font=..., <features> } ]

This would need some care in interacting with SizeFeatures.

Interface 6

I'm not entirely opposed to the idea of adding some more fontspec commands to write things like:

\setmainfont[]{} % as usual
\addweight{ <series> } [ <features> ] { <fontname> }

But I'm not super happy about this at the same time. Perhaps this would be better as an environment-style definition:

\begin{definefont}{<family>}[ <features> ]
\starname{foo}
\normal [<features>] {*-regular}
\italic [<features>] {*-italic}
\bold [<features>] {*-bold}
\weight {sb} [<features>] {*-semibold}
\end{definefont}

This wouldn't end up being quite so neat as all this I guess but maybe it's a better idea to move along these lines for an "advanced" interface.


Lots of possibilities, none of them great. What do people think?

phi-gamma commented 10 years ago

···<date: 2014-05-13, Tuesday>······

I wonder what would be the best interface for this sort of feature. Regardless of the fontspec interface to load them in the first place, I'd like to provide, say, \fontweight{+1} or \fontbolder to move between them.

Lots of possibilities, none of them great. What do people think?

I like the proposal.

Perhaps having just five in-built weights would be enough — "extra light", "light", "medium", "bold", "extra bold",

OT fonts come in nine weight classes: http://www.microsoft.com/typography/otspec/os2.htm#wtc. Luaotfload already has some heuristic to assign the “bold” slot of families that lack a dedicated bold face (or of families with a borked naming scheme …) with the “next best thing”. It might make sense to extend that mechanism so that the user can request a family at a specific weight. Of course this comes at the price of some extra overhead in Luaotfload’s “families” table.

We could introduce a modifier for font definitions analogous to the existing /S=<val>; what about /W? At the TeX end you’d say:

\font \somefont = "name:Some Family/W=800"

To request extra bold weight. Likewise

\font \somefont = "name:Some Family/I/W=500"

will get you the italics of medium weight,

\font \somefont = "name:Some Family/I/W=700"

should be synonymous with the bold italic face in most cases (except for when above mentioned heuristic kicks in -- we wouldn’t want that for explicit weights).

I can’t contribute to your thoughts about the Fontspec interface since I’m not too familiar with it. Perhaps one remark:

Perhaps having just five in-built weights would be enough — "extra light", "light", "medium", "bold", "extra bold",

\setmainfont[ LightFont=... , ExtraBoldFont = ... ]

What about

\setmainfont [ BoldWeight = 900, BoldFont = Some Family, … ]

to remap all /b lookups to the black/heavy font of the “Some Family”? We could accept the official weight identifiers too, e.g. BoldWeight=heavy.

u-fischer commented 10 years ago

It is not enough to think about how to define font series, one need also commands to use them. Unless you want to predefine a lot of \XXseries commands this means that the user needs access to real series name (and will need it anyway if something unusual is wanted) so that they can write commands containing \fontseries{XX}\selectfont. Also it should imho be possible to extend the new interface to add new shapes - e.g. a contour shape - and if ever nfss is extended and get more axes it should be possible to extend the interface to this axes too.

So in my opinion an interface that invents a lot of single options like "ExtraBoldFont" is not sensible. I also don't think that it is needed: Setting up extra series and shapes is advanced stuff. I would suggest an interface similar to \DeclareFontShape like

 \addtocurrentfontfamily{series=l, shape=..., features=...}{...}

fontspec should try to always fill up the m/\bfdefault series and the n/it shape if they hasn't been declared earlier.

If there exist a way to identify weights in a font then perhaps fontspec could also be told to look for more than two weights by default. E.g. \setupweights{l,m,b,bx,ex} \setmainfont{...}.

Also it would be also nice to be able to get a "copy" of such a family but with e.g. another number style. But I think that is not easy as it is not enough to add features to a font, one often must first remove features that clash.

khaledhosny commented 10 years ago

OT fonts come in nine weight classes: http://www.microsoft.com/typography/otspec/os2.htm#wtc.

usWeightClass can actually be any arbitrary value between 0–1000, and the names assigned to them can be as arbitrary. There are already fonts with more than nine weights: http://typophile.com/node/84518

wspr commented 10 years ago

Since we're talking about both XeTeX and LuaTeX for now, let's restrict our discussion to only the fontspec side of things -- unfortunately automatically finding or using varieties of bold font can't happen on my end. In XeTeX the only possibility we have at present is /B to detect a possible bold font. (Definitely not ruling out using more information if/when luaotfload can provide it to us, however.)

I think my current plan is to use phi-gamma's suggestion with an initial interface of something like this:

\setmainfont
 [
  BoldSeries = bf ,
  BoldFont = somefont-bold ,
  BoldFeatures = ... ,
  BoldSeries = xb ,
  BoldFont = somefont-extrabold ,
  BoldFeatures = ... ,
 ] {somefont-regular}

I hope I'm not opening a can of worms. I also like Ulrike's suggestion for a more advanced interface such as

\addfontshape{series}{shape}{font name}[additional features on top of the default]

but I want to think about that a bit more beforehand. I'll no doubt explore a few ideas before releasing the package, so can't promise a short time frame.

Additional NFSS axes won't happen until someone (me?) re-writes the font selection scheme in LaTeX3, which I started work on long ago and then stalled. In any case, we'll probably only add one axis because of combinatorial issues — you can always argue for just one more axis :)

u-fischer commented 10 years ago

phi-gamma's suggestion is fine for me as it is extensible to and I can see the names "xb" and "bx" etc. But I would like it if one could extend a family after the \setmainfont in an extra command (and in more then one step). I do find long optional arguments difficult to handle.

And regarding the axes: One additional axis to separate itshape and scshape is naturally a must. But imho one additional "free" axis for fancy stuff like number styles or variants would be useful too. The fontaxes package adds a least three axis ;-)

wspr commented 10 years ago

Sorry to think out loud here. Here're my current thoughts.

buildersim21 commented 3 years ago

I know this is an old thread but it seemed like my brain was on a similar thread with this open issue, and in light of the changes to LaTeX2e in the font selection adding in the spaced small caps (ssc) and swashed (sw) where they are both specific font shapes, as well as being able to set different weights and widths as well, it would be nice (wishlist issue) for fontspec to do something like:

--startsnippet--

\setmainfont{<fontname>}[
    SpacedSmallCapsFont=<fontname>,
    SpacedSmallCapsFeatures={<features>},
    SwashedFont=<fontname>,
    SwashedFontFeatures={<features>},
]

--endsnippet--

In regards to the different weights/series and widths, maybe just separate them out into two different axes for sure:

Weights/Series:

Width family:

Is there possibly a way to add an optional argument such as [<width>]to the overall \setmainfont, \setsansfont, \setmonofont, such that it will allow you to declare the font family of the specified width in a similar manner without needing way too many user keys?

--startsnippet--

\setmainfont[<c|sc|n(default)|ec|x|sx>]{fontname}[fontfeatures]

--endsnippet--

Then behind the scenes it would do something like set the weight/series, the width, and the shape, but the user just has to specify optionally that they want to declare the width and have an alternate width available should the need arise. With this, could set up a way to declare which width is desired should more than one width be declared using the new setup, using something like \renewcommand\fontwidthdefault{\condensedwidthfamily}?

There are font families such as the Noto fonts, a font family called NK 57 Monospace, and several others that could benefit from this. Simulating small caps is a scaling to height of "x" using the uppercase letters, which wouldn't look particularly good (see the "textfit" package for a good view of this issue), but it would be an option, particularly for display fonts at least, where if one calls small caps, they might get some semblance of them. Something like FakedSmallCaps as an option to set Bold, Italic, BoldItalic, Regular, etc., with a small caps declared additionally that relies on the base declaration and then sets to lower-case to scaled-down upper-case letters to simulate small caps. Petite caps might be easier to implement in this. However something like:

--startsnippet--

\iffirstuppercase
    <leave regular cap>
\else
    <fake small cap the first letter too>
\fi
<rest of letters of word>

--endsnippet--

might be a rough estimation of what could be attempted here with it.

I would help with this, but reading the code is outside my skill at the moment. I am just getting into better creating usable macros and environments in LaTeX2e syntax. Though if I had to, which I probably will at some point, would be able to get into the new LaTeX3 syntax style. But trying to keep things mentally pseudocode in my head.