function sinkFeet(glyph, gLeftFeet, gRightFeet, gLeftFeetLen, gRightFeetLen,
{ maxStroke = 10, sinkRatio = 0.25 } = {}) {
  /** @type { [ number, number ][] } */
  const toSink = [];
  /** @type { number[] } Corresponding lenghts of the feet to sink */
  const feetLengths = [];
  gLeftFeet.forEach((lf, i) => {
    const [ cid, pid ] = lf;
    const lpt = glyph[cid][pid];
    const rpt = glyph[cid][mod(pid+1, glyph[cid].length)];
    if (Math.abs(lpt.y - rpt.y) <= 1) {
      toSink.push(lf);
      feetLengths.push(gLeftFeetLen[i]);
    }
  });
  gRightFeet.forEach((rf, i) => {
    const [ cid, pid ] = rf;
    const lpt = glyph[cid][mod(pid-1, glyph[cid].length)];
    const rpt = glyph[cid][pid];
    if (Math.abs(lpt.y - rpt.y) > 1) return;
    // Test if lpt is already in toSink
    for (const lf of toSink) {
      if (lf[0] === cid && lf[1] === mod(pid-1, glyph[cid].length)) {
        return;
      }
    }
    toSink.push([ cid, mod(pid-1, glyph[cid].length) ]);
    feetLengths.push(gRightFeetLen[i]);
  });

  /** @type { GlyphData } */
  const result = JSON.parse(JSON.stringify(glyph));
  toSink.forEach((lf, i) => {
    const [ cid, pid ] = lf;
    const lpt = result[cid][pid];
    const rpt = result[cid][mod(pid+1, result[cid].length)];
    let found = searchInGlyph(result, lpt.x, rpt.x, lpt.y+2, lpt.y + maxStroke);
    const minFoundY = Math.min(...found.map(([ ci, pi ]) => result[ci][pi].y));
    found = found.filter(([ ci, pi ]) => 
      Math.abs(result[ci][pi].y - minFoundY) <= 1);

    found.forEach(([ ci, pi ]) => 
      result[ci][pi].y -= feetLengths[i] * sinkRatio);
    lpt.y -= feetLengths[i] * sinkRatio;
    rpt.y -= feetLengths[i] * sinkRatio;
  });
  return result;
}
Sink the removed feets
@param { GlyphData } glyph 
@param { [ number, number ][] } gLeftFeet 
@param { [ number, number ][] } gRightFeet 
@param { number[] } gLeftFeetLen 
@param { number[] } gRightFeetLen 
@param { maxStroke: number, sinkRatio: number } config 
@returns { GlyphData }