字体使用Android自带库NotoSansCJK-Regular.ttf,这需要使用FontCreate工具把otf格式转换为ttf
var
pdf : THPDF_Doc;
font, font1, font2 : THPDF_Font;
page : THPDF_Page;
fontname : PAnsiChar;
s : RawByteString;
vText: string;
codepage : Word;
pdf := HPDF_New (@error_handler, nil);
{ add a new page object. }
page := HPDF_AddPage (pdf);
//HPDF_UseCNSFonts(pdf);
//HPDF_UseCNSEncodings(pdf);
HPDF_UseUTFEncodings(pdf);
HPDF_SetCurrentEncoder(pdf, 'UTF-8');
(* Embend Font *)
fontname := HPDF_LoadTTFontFromFile(pdf, '..\..\fonts\NotoSansCJK-Regular.ttf',HPDF_TRUE);
font := HPDF_GetFont(pdf, fontname, 'UTF-8');//'GBK-EUC-H');
HPDF_Page_BeginText (page);
HPDF_Page_SetFontAndSize (page, font, 24);
vText := '山川异域,风月同天,岂曰无衣,与子同裳';
s := UTF8Encode(vText);
codepage := StringCodePage(s);
HPDF_Page_TextOut(page, 50.00, 460.00, PHPDF_BYTE(s));
vText := '山川異域,風月同天,豈曰無衣,與子同裳';
s := MBCSString(vText, 65001);
HPDF_Page_TextOut(page, 50.00, 490.00, PHPDF_BYTE(s));
这里有个挺特别地方,就是要用UTF8Encode函数把中文转为UTF8编码,可以用StringCodePage(s)检验下codepage,应该=65001。假如直接在函数里放中文:
HPDF_Page_TextOut(page, 50.00, 460.00, '山川异域,风月同天,岂曰无衣,与子同裳'),不是不可以,但最后生成的pdf是乱码,因为编译器默认的codepage和操作系统相关,是936, 即GB2312。
字符串传入后,下一步的处理是UTF8转为UTF16,delphi XE自带了强大的处理函数,直接使用就可
encoder.encode_text_fn(encoder, Atext, len, @_length);
var s : RawByteString;
str16 : string;
codepage : Word;
enc : TEncoding;
bytes: TBytes;
_length : HPDF_UINT;
s := UTF8Decode(Atext);
//codepage=1200 utf-16 Unicode
str16 := UTF8ToUnicodeString(s);
codepage := StringCodePage(str16);
enc := TEncoding.GetEncoding(codepage);
bytes := enc.GetBytes(s);
_length := Length(bytes);
Alength^ := _length;
Result := AllocMem(_length);
Move(Pointer(bytes)^, Pointer(Result)^, _Length);
enc.Free;
以上代码将UTF8编码转为UTF16字节码,然后调用函数写入文件
ret := HPDF_Stream_WriteBinary(Aattr.stream, encoded, _length, nil);
最后打开pdf,效果不错,字体已经无误内嵌到文件中。