unoplatform/uno · error · Exception

cmap table not found

Error message

cmap table not found

What it means

FontFallbackPreprocessor is a build-time console tool that parses TrueType/OpenType fonts from the notofonts repo to extract their Unicode coverage (cmap). It reads the font's table directory; if no table tagged 'cmap' (0x636D6170) is present, cmapOffset stays 0 and it throws a bare Exception. Every valid TrueType/OpenType font must contain a cmap, so its absence means the input is not a usable font (corrupt, a collection, an OTF stub, or a non-font file).

Source

Thrown at src/FontFallbackPreprocessor/Program.cs:280

		// 2. Find 'cmap' table
		uint cmapOffset = 0;
		for (int i = 0; i < numTables; i++)
		{
			uint tag = ReadUInt32Be(reader);
			_ = ReadUInt32Be(reader); // checkSum
			uint offset = ReadUInt32Be(reader);
			_ = ReadUInt32Be(reader); // length

			if (tag == 0x636D6170) // 'cmap'
			{
				cmapOffset = offset;
				break;
			}
		}

		if (cmapOffset == 0)
			throw new Exception("cmap table not found");

		// 3. Read cmap table header
		fs.Seek(cmapOffset, SeekOrigin.Begin);
		_ = ReadUInt16Be(reader); // version
		ushort numSubtables = ReadUInt16Be(reader);

		uint selectedSubtableOffset = 0;
		int selectedPlatformId = -1;
		int selectedEncodingId = -1;

		// We want Platform 3 (Windows) and Encoding 1 (Unicode BMP) or 10 (Unicode Full)
		// Or Platform 0 (Unicode)
		for (int i = 0; i < numSubtables; i++)
		{
			ushort platformId = ReadUInt16Be(reader);
			ushort encodingId = ReadUInt16Be(reader);
			uint offset = ReadUInt32Be(reader);

View on GitHub (pinned to 0418340488)

Solutions

  1. Validate the input is a real font (check the sfVersion magic 0x00010000 / 'OTTO' / 'true') before parsing.
  2. Re-download/regenerate the offending font file from notofonts and confirm it opens in a font tool.
  3. Skip non-font files in the directory scan before calling the cmap parser.

Example fix

// before
if (cmapOffset == 0) throw new Exception("cmap table not found");

// after
if (cmapOffset == 0)
{
	this.Log().Warning($"{path} has no cmap table; skipping.");
	return null; // skip this font in the build tool
Defensive patterns

Strategy: validation

Validate before calling

uint magic = ReadUInt32Be(reader);
bool isFont = magic == 0x00010000 || magic == 0x4F54544F /*OTTO*/ || magic == 0x74727565 /*true*/;
if (!isFont) { /* skip non-font file */ }

Type guard

static bool LooksLikeFontHeader(uint magic) => magic == 0x00010000u || magic == 0x4F54544Fu || magic == 0x74727565u;

Try / catch

try { ParseCmap(path); }
catch (Exception ex) when (ex.Message.Contains("cmap table not found")) { Log.Warn($"{path} not a valid font; skipping."); }

Prevention

When it happens

Trigger: Feeding the preprocessor a file that is not a well-formed font (no cmap table): a corrupt TTF, a bare text/JSON file mislabeled .ttf, an OTF with an unusual table layout, or an empty download.

Common situations: A notofonts checkout with a partial/incomplete font file; a network blip leaving a truncated font download; pointing the tool at a directory containing non-font artifacts; an OTF/CFF font whose tables are ordered so the cmap scan overruns.

Related errors


AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13). Data as JSON: /api/errors/1cc79abfdd20d53a. Report an issue: GitHub.