UTF「サロゲートペア」を扱っています:
UTF-16 を使用すると、$D800-DBFF と $DC00-DCFF の範囲の値が、いわゆるサロゲート ペアを指定するために使用されます。
これらのサロゲート ペアを使用して、$10000 以上 ($10000 から $10FFFD の範囲) の Unicode コード ポイントをマップできます。
これは、値から $10000 を差し引いて、20 ビットで表現できる 0 から $FFFFD の範囲の値を残すことによって行われます。これらの 20 ビットは、それぞれ 10 ビットの 2 つのペアに分割され、$D800 resp に追加されます。$DC00 ペア。
したがって、Unicode コード ポイント $1D11E の場合、UTF-16 サロゲート ペアは次のように計算されます。最初に $10000 を減算すると、$D11E が残ります。これは、20 ビットの 00001101000100011110 であり、$34 と $11E に分割されます。$34 が $D800 に追加され、$11E が $DC00 に追加され、最上位のサロゲートは $D834、最下位のサロゲートは $DD1E になります。
[Unicode コード ポイント $D800 から $DFFD には、Unicode 標準では有効な文字が割り当てられないことに注意してください (UTF-16 の問題を回避するため)。ペアとして使用)]
http://en.wikipedia.org/wiki/UTF-16も参照してください。
サロゲート ペア文字を正しく表示するには、それらを含むフォントが必要です。たとえば、U+1D100 – U+1D1FF (119040–119295) の範囲の音楽記号は、Code2001、Euterpe、Free Serif、Musica、Quivira、Symbola (http://www.alanwood.net/unicode/) の Windows フォントでサポートされています。 fontsbyrange.html#u1d100)
この例を機能させるには、システムに Musica フォント (以前は Musical Symbols と呼ばれていました) をダウンロードしてインストールする必要があります。ダウンロード場所 例: http://users.teilar.gr/~g1951d/
[Win7 でのインストール: ttf ファイルを右クリックして [インストール] を選択]
[テスト ページ: http://www.alanwood.net/unicode/ music_symbols.html]
これは、上記を使用するサンプルの Delphi XE2 テスト コードです (D2007 を使用していますが、これで問題が解決する可能性があります)。
unit uSurrogatePairs;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TFrmSurrogatePairs = class(TForm)
MmoCharacter: TMemo;
Mmo: TMemo;
procedure FormShow(Sender: TObject);
private
procedure Log(S: String);
public
{ Public declarations }
end;
var
FrmSurrogatePairs: TFrmSurrogatePairs;
implementation
{$R *.dfm}
type
TDanishString = type ansistring(1252);
procedure TFrmSurrogatePairs.FormShow(Sender: TObject);
// Code adapted from http://compaspascal.blogspot.nl/2008/10/delphi-2009-strings-explained-by.html
var
UTF16Str : string;
UTF8Str : utf8string;
DanishStr: TDanishString;
L : Integer;
begin
{ TODO -oJan -cShouldHave : Test if Musica font is installed }
UTF16Str:=#$1D160;
MmoCharacter.Text := UTF16Str;
L := length(UTF16Str);
Assert (L=2);
Log('Assigned: UTF16Str := #$1D160');
Log(' This is a musical note (000011101000101100000),');
log(' see http://unicode.org/charts/PDF/U1D100.pdf');
Log('Length(UTF16Str)=2');
Log(' This character occupies 2 positions in UTF-16');
Assert (UTF16Str[1]=#$D834); // 110110 0000110100 First half of the symbol
Assert (UTF16Str[2]=#$DD60); // 110111 0101100000 Second half of the symbol
Log('UTF16Str[1]=#$D834');
Log('UTF16Str[2]=#$DD60');
UTF8Str := utf8string(UTF16Str);
MmoCharacter.Lines.Add(String(UTF8Str));
Log('');
Log('Assigned: UTF8Str := UTF16Str');
Log(' This is the second line (char) in the left memo');
L := Length(UTF8Str);
Assert (L=4);
Log('Length(UTF8Str)=4');
Log(' This character occupies 4 positions in UTF-8, each 1 byte');
Assert (UTF8Str[1]=#$F0); // 11110 000
Assert (UTF8Str[2]=#$9D); // 10 011101
Assert (UTF8Str[3]=#$85); // 10 000101
Assert (UTF8Str[4]=#$A0); // 10 100000
DanishStr:=UTF16Str;
Assert (DanishStr='??'); // Note how Windows incorrectly converts to two letters!
Assert (length(DanishStr)=2);
DanishStr:=UTF8Str;
Assert (DanishStr='??'); // Note how Windows incorrectly converts to two letters!
Assert (length(DanishStr)=2);
end;
procedure TFrmSurrogatePairs.Log(S: String);
begin
Mmo.Lines.Add(S);
end;
end.
そしてDFM:
object FrmSurrogatePairs: TFrmSurrogatePairs
Left = 0
Top = 0
Caption = 'Surrogate pairs'
ClientHeight = 273
ClientWidth = 600
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 13
object MmoCharacter: TMemo
AlignWithMargins = True
Left = 3
Top = 3
Width = 134
Height = 267
Align = alLeft
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -107
Font.Name = 'Musica'
Font.Style = []
ParentFont = False
ReadOnly = True
TabOrder = 0
end
object Mmo: TMemo
AlignWithMargins = True
Left = 143
Top = 3
Width = 454
Height = 267
Align = alClient
Lines.Strings = (
'')
ReadOnly = True
TabOrder = 1
end
end