在Windows下,您可以通过
UniScribe API来实现此功能。我曾经使用它将Unicode文本转换为一组字形,用于我们的
开源PDF作者。您可以在
SynPdf.pas单元中查看源代码样本。请参阅
TPdfWrite.AddUnicodeHexTextUniScribe
方法。
function TPdfWrite.AddUnicodeHexTextUniScribe(PW: PWideChar;
WinAnsiTTF: TPdfFontTrueType; NextLine: boolean; Canvas: TPdfCanvas): boolean;
var L, i,j: integer;
res: HRESULT;
max, count, numSp: integer;
Sp: PScriptPropertiesArray;
W: PWideChar;
items: array of TScriptItem;
level: array of byte;
VisualToLogical: array of integer;
psc: pointer;
complex,R2L: boolean;
complexs: array of byte;
glyphs: array of TScriptVisAttr;
glyphsCount: integer;
OutGlyphs, LogClust: array of word;
procedure Append(i: Integer);
var L: integer;
W: PWideChar;
procedure DefaultAppend;
var tmpU: array of WideChar;
begin
SetLength(tmpU,L+1);
move(W^,tmpU[0],L*2);
AddUnicodeHexTextNoUniScribe(pointer(tmpU),WinAnsiTTF,false,Canvas);
end;
begin
L := items[i+1].iCharPos-items[i].iCharPos;
if L=0 then
exit;
W := PW+items[i].iCharPos;
if not GetBit(complexs[0],i) then begin
DefaultAppend;
exit;
end;
res := ScriptShape(0,psc,W,L,max,@items[i].a,
pointer(OutGlyphs),pointer(LogClust),pointer(glyphs),glyphsCount);
case res of
E_OUTOFMEMORY: begin
DefaultAppend;
exit;
end;
E_PENDING, USP_E_SCRIPT_NOT_IN_FONT: begin
res := ScriptShape(Canvas.FDoc.GetDCWithFont(WinAnsiTTF),
psc,W,L,max,@items[i].a,
pointer(OutGlyphs),pointer(LogClust),pointer(glyphs),glyphsCount);
if res<>0 then begin
DefaultAppend;
exit;
end;
end;
0: ;
else exit;
end;
AddGlyphs(pointer(OutGlyphs),glyphsCount,Canvas);
end;
begin
result := false;
L := StrLenW(PW)+1;
max := L+2;
SetLength(items,max);
count := 0;
if ScriptItemize(PW,L,max,nil,nil,pointer(items),count)<>0 then
exit;
SetLength(complexs,(count shr 3)+1);
ScriptGetProperties(sP,numSp);
complex := false;
R2L := false;
for i := 0 to Count-2 do
if fComplex in sP^[items[i].a.eScript and (1 shl 10-1)]^.fFlags then begin
complex := true;
SetBit(complexs[0],i);
end else
if fRTL in items[i].a.fFlags then
R2L := true;
if not complex then begin
if R2L then begin
W := pointer(items);
W[L] := #0;
dec(L);
for i := 0 to L do
W[i] := PW[L-i];
AddUnicodeHexTextNoUniScribe(W,WinAnsiTTF,NextLine,Canvas);
result := true;
end;
exit;
end;
SetLength(level,count);
for i := 0 to Count-1 do
level[i] := items[i].a.s.uBidiLevel;
SetLength(VisualToLogical,count);
if ScriptLayout(Count,pointer(level),pointer(VisualToLogical),nil)<>0 then
exit;
result := true;
if NextLine then
Canvas.MoveToNextLine;
max := (L*3)shr 1+32;
SetLength(glyphs,max);
SetLength(OutGlyphs,max);
SetLength(LogClust,max);
psc := nil;
if Canvas.RightToLeftText then
for j := Count-2 downto 0 do
Append(VisualToLogical[j]) else
for j := 0 to Count-2 do
Append(VisualToLogical[j]);
end;
当然,这只适用于Windows系统。因此,在Mac OS X下无法使用。您需要在Mac OS X下使用另一个库...