Unicode 字符无法在 HTML5 画布中正确呈现

2022-01-17 00:00:00 unicode canvas javascript html html5-canvas

我正在尝试使用 HTML5 画布元素呈现 unicode 高音谱号.使用正确的字符代码(特别是 1D120)时,它在 HTML 中呈现良好,但是当我尝试在画布内使用它时,会出现一个奇怪的字符

I am trying to render a unicode treble clef using the HTML5 canvas element. When using the correct character code (specifically 1D120), it renders fine in HTML, but when I try to use it inside of a canvas a weird character appears

以下代码在我的 javascript 文件中,它在画布上发挥了它的魔力...

The following code is in my javascript file which works its magic on the canvas...

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');

context.font = "48px serif";
context.strokeText("u1D120", 10, 50);

<h1>&#x1D120;</h1>

<canvas id="canvas" width="100" height="100">
</canvas>

很遗憾,我不能放角色的照片,因为我的声望还太低.

Unfortunately I can't put a picture of the character because my rep is too low as of yet.

感谢您深入了解可能导致此问题的原因.提前致谢!

Any insight into what might be causing this problem is appreciated. Thanks in advance!

推荐答案

JavaScript 字符串使用 UTF-16 编码.您的字符需要两部分转义,因为它是一个需要 2 个 UTF-16 字符的 3 字节 UTF-8 序列 代码点.

JavaScript strings use UTF-16 encoding. Your character requires a two-part escape because it's a 3-byte UTF-8 sequence codepoint that requires 2 UTF-16 characters.

从比我聪明的人的博客文章中盗取方便的功能:

function toUTF16(codePoint) {
    var TEN_BITS = parseInt('1111111111', 2);
    function u(codeUnit) {
        return '\u'+codeUnit.toString(16).toUpperCase();
    }

    if (codePoint <= 0xFFFF) {
        return u(codePoint);
    }
    codePoint -= 0x10000;

    // Shift right to get to most significant 10 bits
    var leadSurrogate = 0xD800 + (codePoint >> 10);

    // Mask to get least significant 10 bits
    var tailSurrogate = 0xDC00 + (codePoint & TEN_BITS);

    return u(leadSurrogate) + u(tailSurrogate);
}

当你用你的代码调用它时:

When you invoke that with your code:

var treble = toUTF16(0x1D120);

你回来了 "uD834uDD20".

再次感谢 Axel Rauschmayer 博士提供上述代码 —阅读优秀的链接博客文章了解更多信息.

Thanks again to Dr. Axel Rauschmayer for the code above — read the excellent linked blog post for more information.

相关文章