2015-04-05 3 views
4

Я пытаюсь отобразить скрипичный ключ unicode с помощью элемента canvas HTML5. При использовании правильного кода символа (в частности, 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

JavaScript становится странным, когда вы пытаетесь использовать символы Unicode за пределами диапазона, представляемого с 16 бит. – Pointy

+1

Попробуйте следующее: «\ uD834 \ uDD20» (объяснение приходит) – Pointy

+1

Для справок: http://www.fileformat.info/info/unicode/char/1d120/index.htm, эта последовательность на самом деле там. – Tomalak

ответ

9

Строки JavaScript используют кодировку UTF-16. Ваш персонаж нуждается в двухчастном побеге, потому что это 3-байтовый код UTF-8 , который требует 2 символа UTF-16.

Похищенные из 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".

Еще раз спасибо доктору Акселу Раушмайеру за код выше — прочитайте превосходное связанное сообщение в блоге для получения дополнительной информации.

+0

Не «потому что это 3-байтная последовательность UTF-8», это на самом деле только симптом, а не причина. – Tomalak

+0

@Tomalak да, это хороший момент - проблема в том, что это вне диапазона кодовых страниц, непосредственно представляемых как один символ UTF-16, но я не знаю терминологию для этого :) – Pointy

+0

Базовая многоязычная плоскость , ;) - И два символа UTF-16 называются * суррогатной парой *. – Tomalak