Skip to content

[p5.js 2.0+ Bug Report]: loadFont() loses all glyph data for variable fonts with short gvar offsets #9208

Description

@nexus-hash

Most appropriate sub-area of p5.js?

  • Accessibility
  • Color
  • Core/Environment/Rendering
  • Data
  • DOM
  • Events
  • Image
  • IO
  • Math
  • Typography
  • Utilities
  • WebGL
  • WebGPU
  • p5.strands
  • Build process
  • Unit testing
  • Internationalization
  • Friendly errors
  • Other (specify if possible)

p5.js version

2.3.3

Web browser and version

Chrome: 153.0.8010.53

Operating system

Windows

Steps to reproduce this

Steps

  1. Save the snippet below as repro.html and open it in a browser. No server is needed.
  2. Open DevTools (F12) and go to the Console tab.
  3. Note the warning and the NO glyph data line.
  4. Replace the URL with each font below, reload, and confirm both log glyph data present with no warning:
    • Bricolage Grotesque (variable, long gvar offsets):
      https://raw.githubusercontent.com/google/fonts/main/ofl/bricolagegrotesque/BricolageGrotesque%5Bopsz%2Cwdth%2Cwght%5D.ttf
    • Jersey 10 (static):
      https://fonts.gstatic.com/s/jersey10/v4/GftH7vZKsggXMf9n_J5X-A.ttf

Snippet

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>p5 variable font repro</title>
  <script src="https://cdn.jsdelivr.net/npm/p5@2.3.3/lib/p5.min.js"></script>
</head>
<body>
<script>
async function setup() {
  createCanvas(400, 200);
  const font = await loadFont(
    'https://raw.githubusercontent.com/google/fonts/main/ofl/outfit/Outfit%5Bwght%5D.ttf'
  );
  console.log(font.data?.glyf ? 'glyph data present' : 'NO glyph data');
}
</script>
</body>
</html>

Actual result

Console output:

WARN: No glyph data for 'Outfit%5Bwght%5D', retrying as FontFace
NO glyph data

font.data is undefined, so loadFont falls back to a plain FontFace. Text still renders, but glyph-outline features such as textToPoints() have no glyph data to work with.

Expected result

Glyph data is parsed (glyph data present), as it is for static fonts and for variable fonts that use long gvar offsets.

Why

Typr's gvar parser always reads glyphVariationDataOffsets as 4-byte Offset32 values:
https://github.com/processing/p5.js/blob/main/src/type/lib/Typr.js#L2211-L2214

Per the OpenType spec, the offsets are 4-byte only when flags bit 0 is set. Otherwise they are 2-byte uint16 values, and the real offset is the value × 2. Outfit's gvar has flags = 0, so every offset after the first is misaligned and parsing fails.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions