How to check if specified char exists on Android ? (jss/css/whatever/…)

Viewed 62

I have problem with some unicode (utf-8) character on Android. It's displayer as non existing (crossed out rectangle). It's there some way how to check if char exists?

I was trying to check it by FontFaceSet.check() ( https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/check ) but it's not working :(

my code looks like:

document.fonts.check('700 24px / 36px Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif', '⮝');

where is my char and long string is computed style from window.getComputedStyle( myElement, null ).getPropertyValue( 'font' )

It returns true, like character exists, but still this char cannot be show. What am I doing wrong?

1 Answers

FontFaceSet.check does not check if a specific character exists in a font, only if any character in the range of that character exists. You can try rendering the text to a canvas and checking if the rendering is the same as a Unicode character that is known not to exist:

function isLetterRenderable(letter) {
  if (!document.fonts.check('700 24px / 36px Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif', letter)) return false;
  let can;
  if (window.OffscreenCanvas) {
    can = new OffscreenCanvas(50, 50);
  } else {
    can = document.createElement("canvas");
    can.height = 50;
    can.width = 50;
  }
  const ctx = can.getContext("2d");
  ctx.font = '700 10px Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif';
  ctx.fillText(letter, 10, 10);
  const imgData1 = ctx.getImageData(0, 0, 50, 50);
  ctx.clearRect(0, 0, 50, 50);
  ctx.fillText("῿", 10, 10);
  const imgData2 = ctx.getImageData(0, 0, 50, 50);
  // drawing of character must differ from drawing of known invalid character
  return !imgData1.data.every((x, i) => imgData2.data[i] === x);
}

console.log("a ->", isLetterRenderable("a"));
console.log("ꯃ ->", isLetterRenderable("ꯃ"));
console.log(" ->", isLetterRenderable(""));
console.log("⮝ ->", isLetterRenderable("⮝"));
console.log(" ->", isLetterRenderable(""));

Note that some browsers (Firefox does it on my system) will automatically generate "pseudo-letters" that look like 010EB0 in a square. These look like actual unique letters to isLetterRenderable above, so it first checks using document.fonts.check since while that function returning true is meaningless in this context, if it returns false we know for sure that the glyph can't be rendered. But if some letters in a range are renderable, and some are pseduo-letters, then it is very hard to detect which ones have associated glyphs.

Related