2010-04-14 55 views
1

我是新来的unicode,所以我希望任何人都可以帮助我。我希望将unicode编写为PDF,现在我需要文本格式的unicode文本的宽度和高度。对于AnsiString我有这个功能在PDF类:使用unicode文本的PDF和TextWidth/TextHeight

function PDFClass.TextWidth(Text: AnsiString): Single; 
var 
    i: integer; 
    ch: AnsiChar; 
    tmpWidth: Single; 
    chv: Integer; 
begin 
    Result := 0; 
    for I := 1 to Length(Text) do 
    begin 
    ch := Text[i]; 
    chv := CurrentFontObj.GetCharWidth(Text, I); 
    tmpWidth := chv * CurrentFontObj.Size/1000; 
    if FHorizontalScaling <> 100 then 
     tmpWidth := tmpWidth * FHorizontalScaling/100; 
    if tmpWidth > 0 then 
     tmpWidth := tmpWidth + FCharSpace 
    else 
     tmpWidth := 0; 
    if (ch = ' ') and (FWordSpace > 0) and (i <> Length(Text)) then 
     tmpWidth := tmpWidth + FWordSpace; 
    Result := Result + tmpWidth; 
    end; 
    Result := (Result/DocScale); 
end; 


function PDFClass.TextHeight(Text: AnsiString): Real; 
begin 
    Result := CurrentFontObj.Size * CurrentFontObj.Ascent/1000; 
end; 

任何人都可以帮我使用此功能的Unicode文本?我在带有UnicodeString的C++ Builder 2009中使用这个组件。

CurrentFontObj是从类PDFFontObj

PDFFontObj = class(TObject) 
    private 
    Name: AnsiString; 
    Size: Single; 
    ArrIndex: Integer; 
    Saved: boolean; 
    OldName: AnsiString; 
    Ascent: Integer; 
    FActive: boolean; 
    IsUsed: boolean; 
    UniLen: Integer; 
    FontLen: Integer; 
    IsUnicode: boolean; 
    IsVertical: boolean; 
    OrdinalName: AnsiString; 
    IsStandard: boolean; 
    FontStyle: TFontStyles; 
    FontCharset: TFontCharset; 
    IsMonospaced: boolean; 
    OutTextM: OUTLINETEXTMETRIC; 
    ABCArray: array[0..255] of ABC; 
    Symbols: array of CDescript; 
    UnicodeTable: array of IndexedChar; 
    SymbolTable: array[32..255] of boolean; 
    function GetCharWidth(AText: AnsiString; APos: integer): integer; 
    function GetCodeByID(ID: Word): Word; 
    procedure CopyFontFetures(InFnt: PDFFontObj); 
    procedure GetFontFeatures; 
    procedure ParseFontName; 
    procedure ClearTables; 
    end; 

function PDFFontObj.GetCharWidth(AText: AnsiString; APos: integer): integer; 
var 
    ChCode: Byte; 
begin 
    ChCode := Ord(AText[APos]); 
    if not IsMonospaced then 
    Result := ABCArray[ChCode].abcA + Integer(ABCArray[ChCode].abcB) + ABCArray[ChCode].abcC 
    else 
    Result := ABCArray[0].abcA + Integer(ABCArray[0].abcB) + ABCArray[0].abcC; 
end; 
+0

你的问题是很难理解的,请注明哪些帮助,你需要用这个代码。它不会编译?你想支持字体包含的所有Unicode字形吗?还是其他什么东西? – mghie 2010-04-15 06:38:59

+0

我想连续写3个文本,每个文本的颜色都不一样。为此,我需要每个字符串(文本)的像素宽度。对于AnsiString: int width = PDF-> CurrentPage-> TextWidth(_ansi_text_); 但我需要一个unicode文本的TextWidth,如: int width = PDF-> CurrentPage-> TextWidthUnicode(_unicode_text_with_chinese_signs_); TextWidthUnicode()(和高度)是我需要的。 我的问题是,“如何获得unicode文本的像素宽度?” :) – Katsumi 2010-04-15 07:16:44

回答

0

在评论你写

我还想写一排3个文本,以不同的颜色每个文本。为此,我需要每个文本的像素宽度。对于AnsiString是:

int width = PDF->CurrentPage->TextWidth(ansi_text); 

,但我需要一个Unicode文本的宽度,如:

int width = PDF->CurrentPage->TextWidthUnicode(unicode_text_with_chinese_signs); 

简短的回答:
如果你有代码,不会的对于Ansi字符串来说是正确的事情,那么它应该可以在没有改变的情况下正确使用Unicode。

较长的答案:
PDFClass.TextWidth()方法确实遍历字符串中的所有字符,调用当前字体对象的功能,以获得单个字符的宽度,应用缩放,并增加了人物之间的额外空间话。这或多或少可以在PDF 1.7 specification的第9章中阅读。

您发布的代码不完整,但我怀疑它对Ansi字符串已经不能正常工作。有Ansi编码可以使用多个字符来编码一个可见的字符字形,CJK多字节编码。在Ansi字符串中循环单个字节并总结返回的宽度在那里不会正常工作。该代码可能以某种方式解释了这一点,但您的代码段不显示它。

该代码也可能有不同的单字节Ansi编码的问题,但很难从您发布的代码段中分辨出来。如果您使用非ASCII字符的Ansi程序(如'ä'或'á')并运行它(例如俄语Windows版本),创建的PDF文件是否将包含西里尔字形?如果不是,那么代码不会将必要的编码信息放入PDF中。如果是这样的话,它也不会用于Unicode字符串。有关编码问题的更多信息,请参阅PDF规范。

还要注意的是,代码可能并不适用于所有用户的工作,即使它编译:

  • 您将需要一个包含所有必要的字形字体(中国人在你的例子)。如果没有,则会显示后备标志符号。如果系统没有完全相同的字体,则可以使用类似但不同的字体,而对于某些或全部字形可能会有不同的宽度,在这种情况下,计算出的宽度将是错误的。出于这个原因,最好在PDF文档中嵌入TrueType字体(甚至更好,即使只使用字体的字形)。TTF字体可能嵌入也可能不嵌入,并且您可能无权嵌入并分发文档。

  • 有些语言会从右向左放置字形,甚至垂直放置它们。

  • 有些语言会使用其他代码点来分隔单词,问题中的代码只能识别空格作为单词分隔符。这将再次导致计算产生不同的结果,如果FWordSpace不等于0