Html: OpenType Features and Variable Fonts for Canvas

Created on 15 Mar 2018  路  10Comments  路  Source: whatwg/html

Font styling for the 2D Context of Canvas is currently limited to the font state of the context object.

I would like to start a discussion on extending Canvas' capabilities for font styling and OpenType feature activation. The reason being that a number of advancements in typographic quality on the web are not accessible through the font property of 2D context.

In regular CSS activating OpenType features such as ligatures, small caps, contextual alternates, additional number/fraction/ordinal forms is performed through using font-variant-* properties, and font-feature-settings.

The second limitation is the usage of Variable Fonts (Introducing Variable Fonts, Introduction to Variable Fonts on the Web, Variable Fonts Exploration).

In regular CSS, controlling parameters for the rendering of variable fonts is done through the font-weight, font-stretch, and font-style properties, which can be specified as part of the font property/shorthand form on canvas. However, activating variation axes outside these three canonical axes is not possible, preventing a whole set of more artistic and creative fonts to be used on canvas. Control of the additional axes is done through the font-optical-sizing property as well as the low level font-variation-settings.

I believe it would be beneficial to to find a way for all of the tools and control that the CSS Fonts Specification offers to be applicable to the 2D context of Canvas.

additioproposal needs implementer interest canvas

Most helpful comment

Note that there are two very distinct possibilities for a font-related interface (the confusion of which resulted in a very mixed-up TypedOM section that I eventually had to remove):

  1. Explicitly providing font faces to something for use - these should use FontFace. (CSSFontFaceRule is roughly equivalent, but it's tied more to the stylesheet and its loading behavior; it shouldn't be used directly by APIs.)
  2. Activating the system's font-selection capability - this is what canvas currently does with its font attribute.

The latter is currently only exposed thru CSS properties; at some point in a future level of TypedOM there will be an object representing a font-selection query (for 'font' to reify to), but that doesn't exist yet.

You probably want to continue canvas's current approach, and continue just doing font queries, rather than explicitly providing faces.

All 10 comments

Perhaps one approach would be to expose a style-like object on the 2D context and define a subset of style properties relevant for font-styling to be permitted, such as font-family, font-(stretch|style|weight), font-variant-*, font-feature-settings, font-variation-settings etc.

Could we use https://drafts.csswg.org/css-font-loading/#fontface-interface somehow? Abstracting fonts into a reusable/mutable object rather than exposing various properties to poke at it seems more reasonable.

cc @tabatkins

While the FontFace interface is getting close, I find it confusing to use FontFace in a dual purpose: In one sense as a representation of a @font-face rule that style rules are being matched against, and in a second sense as a collection of style attributes covering font styling, meaning one concrete particular instance of a font.

Especially so for variable fonts, where a @font-face can mean a spectrum of available font instances, e.g. weight ranging from 100 to 700, stretch ranging from 100% to 150%, slant ranging from 0 deg to 20 deg.

Also, @litherum commented in a separate thread that accessing/assigning only one such instance to the 2D context does not provide a means of specifying a cascade for fallback, as we would usually find it in the font-family stack of fonts.

We could make it a sequence of FontFace objects, but we could also support a CSSFontFaceRule object, if that matches things better. It just seems that at some point we should have an underlying primitive here rather than keep adding properties to the 2D context.

/cc @jfkthame @FremyCompany

We could make it a sequence of FontFace objects, but we could also support a CSSFontFaceRule object, if that matches things better. It just seems that at some point we should have an underlying primitive here rather than keep adding properties to the 2D context.

The underlying primitive for font selection is CSS properties.

  1. In the past, canvas's interaction with fonts has maintained the invariant that drawing text in a canvas has the same visual result as the browser drawing native text. Matching native rendering is desirable for sites like Flipboard which implemented their entire site using canvas.
  2. Keep in mind that this has to be implementable - all browsers already have code to select fonts using CSS properties and draw the result. Requiring an entirely new font selection mechanism would likely limit implementor's interest in implementing (it would certainly limit our interest).

Perhaps one approach would be to expose a style-like object on the 2D context and define a subset of style properties relevant for font-styling to be permitted

I think @drott's suggestion is a good one. Making the canvas API match the existing font selection facilities is best for developers, users, and implementors. Indeed, this is already how the existing canvas API was designed, and we should not deviate from that design.

Oh, a point I missed before - this issue is bringing up a valuable request. The ability to use great fonts should be ubiquitous, and included in every subsystem that interacts with text.

Note that there are two very distinct possibilities for a font-related interface (the confusion of which resulted in a very mixed-up TypedOM section that I eventually had to remove):

  1. Explicitly providing font faces to something for use - these should use FontFace. (CSSFontFaceRule is roughly equivalent, but it's tied more to the stylesheet and its loading behavior; it shouldn't be used directly by APIs.)
  2. Activating the system's font-selection capability - this is what canvas currently does with its font attribute.

The latter is currently only exposed thru CSS properties; at some point in a future level of TypedOM there will be an object representing a font-selection query (for 'font' to reify to), but that doesn't exist yet.

You probably want to continue canvas's current approach, and continue just doing font queries, rather than explicitly providing faces.

+1 to what @tabatkins said

Yes, @tabatkins is right.

Was this page helpful?
0 / 5 - 0 ratings