简体   繁体   中英

How to detect if a unicode character has been rendered?

I'm trying to write some javascript that detects if a unicode character has been rendered in the browser or not.

Note — this question or similar questions have been asked before, but none of them have had an answer that actually answers the question. Either, the chosen answer doesn't work for every unicode character, or the chosen answer solves the questioner's problem in a different way. eg install a font that has the unicode character you want to use.

There are a couple of approaches to this problem I have come accross. Neither of them i think cover every possible situation, or are particularly elegant solutions.

  1. HTMLCanvas

Render the unicode character in a canvas element and compare it to all existing fallback glyphs eg or ▯ etc...

if it matches any of those characters then you know that it hasn't rendered correctly.

The problem with this solution is it requires knowing what all those fallback characters are, which is basically not possible. It also would show a false negative result if you test a character like "▯"

  1. Use a fallback font with blank, zero-width characters for every code point

Render the unicode character with the following css, if the character has no width, then you know it has failed to render correctly.

@font-face {
  font-family: 'Blank';
  src:url('~assets/fonts/blankfont.ttf') format('truetype');
}

.testfont {
    font-family:
                -apple-system,
                system-ui,
                BlinkMacSystemFont,
                "Segoe UI",
                Roboto,
                "Helvetica Neue",
                Arial,
                sans-serif,
                serif...
                ... every possible font that it could render in by default...

                "Blank"
}

The main problem with this approach is knowing all the possible fonts the character could render in. I've given this approach a try. I'd render the same unicode character twice, once with the above css, and again without the css.

I found that the unicode character would sometimes render with correctly without the css and render as blank with the css. This suggests that there are more fallback fonts on my system that aren't covered by serif, sans-serif and other generic css font families.

So, you would have to add all the possible fonts before falling back to the "blank" font.

Both these approaches might work most of the time with a lot of tinkering. But I'm looking for an approach that will work all of the time.

Any help would be much appreciated. If I find a solution I'll make sure to post it here.

The only way to do this is to have all the fonts in the font stack available for inspection, and then testing each font in that stack to see whether it supports the character(s) you care about.

The canvas won't work because (a) there is no universal "not supported" glyph, each font gets to define its own, so a list of "not supported" glyphs is something you'd have to build for each set of fonts yo use. But then also (b) the canvas is an imaging bitmap, and so trying to match pixels to a known picture becomes horrendously complex due to point sizes, subpixel offsets, and text rendering optimizations like ClearType.

Also, wanting "missing glyphs" to take up zero space is generally a really bad idea: instead, use a font that very clearly shows that you have missing glyphs, and fix those before pushing updates with missing characters live. This is one of the things you write integration tests for.

The only reliable way would be to only use webfonts, not built-ins (so no "Times New Roman" or "Hiragino") and no "serif" or "sans" as final generic category keyword, but something like Adobe Blank, and then for each of those fonts check whether at the OpenType cmap level those fonts support the character(s) you're trying to render.

(and you could do that server-side, or you could do that in-browser with something like fontkit or font.js )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM