2015-04-05 85 views
4

我正嘗試使用HTML5 canvas元素呈現unicode高音譜號。當使用正確的字符代碼(特別是1D120)時,它在HTML中渲染得很好,但是當我嘗試在畫布內部使用它時,會出現一個奇怪的字符Unicode字符在HTML5畫布中無法正確呈現

以下代碼在我的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>

可惜我不能把人物的照片,因爲我的代表處是過低的呢。

瞭解可能會導致此問題的任何洞察。提前致謝!

+0

當您嘗試使用超出16位可表示範圍的Unicode字符時,JavaScript會變得很奇怪。 – Pointy 2015-04-05 22:37:51

+1

試試這個:「\ uD834 \ uDD20」(解釋即將到來) – Pointy 2015-04-05 22:40:24

+1

爲了將來的參考:http://www.fileformat.info/info/unicode/char/1d120/index.htm,這個序列實際上就在那裏。 – Tomalak 2015-04-05 22:47:07

回答

9

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"

再次感謝Dr. Axel Rauschmayer對—以上的代碼閱讀優秀的鏈接博客文章以獲取更多信息。

+0

不是「因爲它是一個3字節的UTF-8序列」,這實際上只是一個症狀,而不是原因。 – Tomalak 2015-04-05 22:46:07

+0

@Tomalak是的,這是一個很好的觀點 - 問題在於它超出了可直接表示爲單個UTF-16字符的代碼頁的範圍,但我不知道該術語:) – Pointy 2015-04-05 22:47:58

+0

基礎多語言平面。 ;) - 兩個UTF-16字符被稱爲*代理對*。 – Tomalak 2015-04-05 22:49:53