Brooooooklyn / canvas

High performance skia binding to Node.js. Zero system dependencies and pure npm packages without any postinstall scripts nor node-gyp.
https://vercel.skia.rs
MIT License
1.66k stars 71 forks source link

Variable fonts #495

Open controversial opened 1 year ago

controversial commented 1 year ago

How can I register and use a variable font?

If I register

GlobalFonts.registerFromPath(path.join(fontsDir, 'RobotoMono-VariableFont.woff2'), 'Roboto Mono');

and try to render different font weights (100–900) by something like:

for (let i = 1; i <= 9; i++) {
  ctx.font = `${i * 100} 45px Roboto Mono`;
  ctx.fillText(`${i * 100}: Jackdaws love my big sphinx of quartz`, 30, i * 65);
}

I get the following result:

result

Weights 100–500 are rendered at 400, and 600–900 are rendered at 700.

I would expect to see an even gradient from 100–700 as the weight specified in ctx.font changes.

yisibl commented 1 year ago

In CSS you need to register a new variable font with @font-face, and adjusting the variable axis directly with font-weight doesn't work either.

However, the variable axis can be controlled directly through the low-level property font-variation-setting.

As far as I know, skr-canvas does not currently support variable fonts. The primary goal in skr-canvas should be to find an implementation that corresponds to font-variation-setting in order to control the variable axis.

Here is some information for reference.

yisibl commented 4 months ago

As far as I know, there is no other canvas library in Node.js that supports variable fonts except canvaskit(fontVariations). If skr-canvas supports variable fonts, it will be very competitive.

@Brooooooklyn Can this be our goal for 2024?

canvaskit-wasm/types/index.d.ts

export interface TextStyle {
  backgroundColor?: InputColor
  color?: InputColor
  decoration?: number
  decorationColor?: InputColor
  decorationThickness?: number
  decorationStyle?: DecorationStyle
  fontFamilies?: string[]
  fontFeatures?: TextFontFeatures[]
  fontSize?: number
  fontStyle?: FontStyle
  fontVariations?: TextFontVariations[]
  foregroundColor?: InputColor
  heightMultiplier?: number
  halfLeading?: boolean
  letterSpacing?: number
  locale?: string
  shadows?: TextShadow[]
  textBaseline?: TextBaseline
  wordSpacing?: number
}

export interface TextFontFeatures {
  name: string
  value: number
}

export interface TextFontVariations {
  axis: string
  value: number
}