【问题标题】:Unicode characters not rendering properly in HTML5 canvasUnicode 字符无法在 HTML5 画布中正确呈现
【发布时间】:2015-06-10 08:38:14
【问题描述】:

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

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

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>

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

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

【问题讨论】:

  • 当您尝试使用超出 16 位可表示范围的 Unicode 字符时,JavaScript 会变得很奇怪。
  • 试试这个:“\uD834\uDD20”(解释来了)
  • 供以后参考:fileformat.info/info/unicode/char/1d120/index.htm,这个序列实际上就在里面。

标签: javascript html canvas unicode html5-canvas


【解决方案1】:

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

a blog post by somebody smarter than me偷来的是这个方便的功能:

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);
}

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

var treble = toUTF16(0x1D120);

你回来"\uD834\uDD20"

再次感谢 Axel Rauschmayer 博士提供上面的代码 - 阅读出色的链接博客文章以了解更多信息。

【讨论】:

  • 不是“因为它是一个3字节的UTF-8序列”,这实际上只是一个症状,而不是原因。
  • @Tomalak 是的,这是一个很好的观点 - 问题是它超出了可直接表示为单个 UTF-16 字符的代码页范围,但我不知道术语那:)
  • 基本多语言平面。 ;) -- 并且这两个 UTF-16 字符被称为 代理对
  • 它实际上是一个UTF-32表示(去掉了前导0),即:\u0001d120。
  • 仅供参考,ES6 允许使用\u{...},因此'\u{1D120}'String.fromCodePoint(...codepoints)(在 ES6 中也添加)将与给定函数执行相同的操作。 0xD8000xDFFF 之间的代码点由 Unicode 中的 UTF-16 保留(尽管 ECMAScript 6 不会为此抛出任何异常)。
【解决方案2】:

将十六进制值括在 {} 中,如下所示:

context.strokeText("\u{1D120}", 10, 50);

【讨论】:

    猜你喜欢
    • 2012-01-26
    • 2021-03-10
    • 2016-04-03
    • 2015-04-12
    • 2012-06-11
    • 1970-01-01
    • 2013-08-30
    • 2016-09-13
    • 1970-01-01
    相关资源
    最近更新 更多