fonteditor-core icon indicating copy to clipboard operation
fonteditor-core copied to clipboard

Support for remapping code points

Open rektdeckard opened this issue 1 year ago • 2 comments
trafficstars

Thanks for this excellent library!

I am currently using it to programmatically merge and minify icon fonts, and I am wondering if there is an idiomatic way to remap the code points of certain glyphs. For example, I want to merge two fonts that both have a glyph at the unicode point 0xe900. It would be great if I could:

  1. Move the glyph in one of those fonts to another code point of my choosing, or
  2. Have it moved automatically when merging, and find out where it was moved to

I tried mutating one of the Glyphs directly, but it seems to corrupt the font. Pseudocode:

fontA: FontEditor.Font;
fontB: FontEditor.Font;
const duplicateCodePoint = 0xe900;

// Find the glyph in the second font
const [glyph] = fontB.find({ unicode: [duplicateCodePoint] });
// Move it to the next code point
glyph.unicode = [duplicateCodePoint + 1];

// Generate a merged font file
const mergedFontBuffer = fontA
  .merge(fontB, { adjustGlyf: false })
  .write({ type: "ttf", hinting: false, toBuffer: true });

This produces the following warnings in the browser when I attempt to use the font:

Failed to decode downloaded font: file:///<path-to>/Font.ttf
OTS parsing error:    OS: misaligned table

I assume this functionality already exists, since glyphs can be reassigned to different code points via your graphical font editor, but I couldn't quite grasp from the source how it is done.

Any help would be appreciated!

rektdeckard avatar Dec 01 '23 01:12 rektdeckard

I got this to work by passing { scale: 1 } instead of { adjustGlyf: false } merge options, for some reason. This is odd, since both of these should be the default behavior, and should be allowed to be omitted or included without making any difference.

rektdeckard avatar Dec 01 '23 05:12 rektdeckard

font merge option(scale or adjust) will set to fit the merged em box, so that merged font display not too big or small.

when we merge two font, we should follow these steps:

  1. fontA is the base font, fontB should convert all glyph to simple glyph fontB. compound2simple()
  2. chang fontB glyph codepoint to merged codepoint, should not same to fontA glyph's codepoint.
  3. adjust fontB glyph to fit fontA em box, merge function only need to provide glyf and head:
const gyphs = fontB.find({ unicode: [duplicateCodePoint] });
// ...
fontA.merge({
  glyf: gyphs,
  head: fontB.head
}, {scale: 1})

here's the merge function, only copy and adjust glyphs: https://github.com/kekee000/fonteditor-core/blob/master/src/ttf/ttf.js#L126

kekee000 avatar Dec 05 '23 02:12 kekee000