function generateUnicodeSupportMap()

in src/behaviors/emoji/support/unicode_support_map.js [72:141]


function generateUnicodeSupportMap(testMap) {
  const testMapKeys = Object.keys(testMap);
  const numTestEntries = testMapKeys.reduce(
    (list, testKey) => list.concat(testMap[testKey]),
    [],
  ).length;

  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  canvas.width = 2 * fontSize;
  canvas.height = numTestEntries * fontSize;
  ctx.fillStyle = '#000000';
  ctx.textBaseline = 'middle';
  ctx.font = `${fontSize}px "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"`;
  // Write each emoji to the canvas vertically
  let writeIndex = 0;
  testMapKeys.forEach((testKey) => {
    const testEntry = testMap[testKey];
    [].concat(testEntry).forEach((emojiUnicode) => {
      ctx.fillText(emojiUnicode, 0, writeIndex * fontSize + fontSize / 2);
      writeIndex += 1;
    });
  });

  // Read from the canvas
  const resultMap = {};
  let readIndex = 0;
  testMapKeys.forEach((testKey) => {
    const testEntry = testMap[testKey];
    // This needs to be a `reduce` instead of `every` because we need to
    // keep the `readIndex` in sync from the writes by running all entries
    const isTestSatisfied = [].concat(testEntry).reduce((isSatisfied) => {
      // Sample along the vertical-middle for a couple of characters
      const imageData = ctx.getImageData(
        0,
        readIndex * fontSize + fontSize / 2,
        2 * fontSize,
        1,
      ).data;

      let isValidEmoji = false;
      for (let currentPixel = 0; currentPixel < 64; currentPixel += 1) {
        const isLookingAtFirstChar = currentPixel < fontSize;
        const isLookingAtSecondChar = currentPixel >= fontSize + fontSize / 2;
        // Check for the emoji somewhere along the row
        if (isLookingAtFirstChar && checkPixelInImageDataArray(currentPixel, imageData)) {
          isValidEmoji = true;

          // Check to see that nothing is rendered next to the first character
          // to ensure that the ZWJ sequence rendered as one piece
        } else if (isLookingAtSecondChar && checkPixelInImageDataArray(currentPixel, imageData)) {
          isValidEmoji = false;
          break;
        }
      }

      readIndex += 1;
      return isSatisfied && isValidEmoji;
    }, true);

    resultMap[testKey] = isTestSatisfied;
  });

  resultMap.meta = {
    isChrome,
    chromeVersion,
  };

  return resultMap;
}