[英]How to turn an Indy UTF-8 response into a native Delphi (Unicode)String?
[英]delphi 2007 display unicode U+1F48B in UTF-8 string or any other way
我有一個sqlite數據庫(UTF-8編碼)。 在數據庫里面我有這樣的記錄(十六進制字節):
D0 9E D0 BA 29 F0 9F 92 8B F0 9F 92 8B
因此,字節不是對齊的,即:
$D09E = O
$D0BA = к
$29 = )
$F09F928B = U+1F48b (KISS MARK)
$F09F928B = U+1F48b (KISS MARK)
這就是它在SQLite管理器中的樣子:
但無論我做什么(UTF8Decode和一些自定義轉換)我都無法在我啟用Unicode的TNTStringGrid中顯示它。
是的,我可以得到OK)? 顯示,但然后去Ок)рџ'<џџ'<或這就是它看起來像真實的(UTF8Encoded):РћРє)рџ'<рџ'<
我知道這是一個很難的問題,但必須有一個解決方案,因為SQLite管理器顯示它絕對正確。
那么如何顯示那些U +字符和普通文字呢?
請幫忙! 3個晝夜與這項任務作斗爭。
您正在處理UTF“代理對”:
使用UTF-16,$ D800-DBFF和$ DC00-DCFF的值范圍用於指定所謂的代理對。
使用這些代理對,我們可以映射10000美元或更高的Unicode代碼點(在$ 10000到$ 10FFFD范圍內)。
這是通過從值中減去$ 10000來完成的,保留0到$ FFFFD范圍內的值,可以用20位表示。 這20位分為兩對,每對10位,加到$ D800或。 $ DC00對。
因此,對於Unicode代碼點$ 1D11E,UTF-16代理對計算如下:首先減去$ 10000,留下$ D11E,即20位的00001101000100011110,分為$ 34和$ 11E。 $ 40增加到D800,$ 11E增加到$ DC00,最重要的替代品為$ D834,最不重要的代理為$ DD1E。
[請注意,Unicode代碼點$ D800到$ DFFD將不會被Unicode標准指定為有效字符(以避免UTF-16出現問題),因此各個代理字符永遠不會映射到實際字符本身(但應始終為用作一對)。]
另見http://en.wikipedia.org/wiki/UTF-16
要正確顯示代理項對字符,您需要一個包含它們的字體。 例如,Windows字體Code2001,Euterpe,Free Serif,Musica,Quivira,Symbola(http://www.alanwood.net/unicode/)支持U + 1D100 - U + 1D1FF(119040-119295)范圍內的音樂符號。 fontsbyrange.html#u1d100)
您需要在系統上下載並安裝Musica字體(以前稱為Musical Symbols)才能使此示例正常工作。 下載位置,例如http://users.teilar.gr/~g1951d/
[在Win7下安裝:右鍵單擊ttf文件並選擇“安裝”]
[測試頁:http://www.alanwood.net/unicode/musical_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
Ok)??
表示UTF-8數據已正確解碼為UTF-16,但UTF-16數據已轉換為不支持這些Unicode字符的Ansi代碼頁。
Ок)рџ'‹рџ'‹
表示原始8位UTF-8八位字節按原樣存儲,擴展為16位值,根本不從UTF-8解碼為UTF-16。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.