FastReport 3.X 在 Win9X 下的中文折行乱码问题解决方法 |
|
One2Free
一般會員 ![]() ![]() 發表:26 回覆:28 積分:20 註冊:2004-05-12 發送簡訊給我 |
花了不少时间去装虚拟机和 WIN98 来实验. 修改 frxGraphicUtils.pas
procedure TfrxDrawText.WrapTextLine(s: string; Width, FirstLineWidth,
CharSpacing: Integer);
var
n, i, Offset, LineBegin, LastSpace, BreakPos: Integer;
sz: TSize;
TheWord: string;
WasBreak: Boolean; //俄文换行
function BreakWord(const s: string; LineBegin, CurPos, LineEnd: Integer):
string;
var
i, BreakPos: Integer;
TheWord, Breaks: string;
begin
// get the whole word
i := CurPos;
while (i <= LineEnd) and (Pos(s[i], ' .,-;') = 0) do
Inc(i); TheWord := Copy(s, LineBegin, i - LineBegin);
// get available break positions
Breaks := BreakRussianWord(AnsiUpperCase(TheWord));
// find the closest position
BreakPos := CurPos - LineBegin;
for i := Length(Breaks) downto 1 do
if Ord(Breaks[i]) < BreakPos then
begin
BreakPos := Ord(Breaks[i]);
break;
end;
if BreakPos <> CurPos - LineBegin then
Result := Copy(TheWord, 1, BreakPos) else
Result := '';
end; begin
// remove all HTML tags and build the tag list
FHTMLTags.NewLine;
FHTMLTags.ExpandHTMLTags(s);
FHTMLTags.FPosition := FHTMLTags.FPosition 2; n := Length(s);
if (n < 2) or not FWordWrap then // no need to wrap a string with 0 or 1 symbol
begin
FText.Add(s);
Exit;
end;
// 字符间空隙和计算宽度
// get the intercharacter spacing table and calculate the width
sz.cx := FHTMLTags.FillCharSpacingArray(FTempArray, s, FCanvas,
FHTMLTags.Count - 1, CharSpacing, True); // 不需换行
// text fits, no need to wrap it
if sz.cx < FirstLineWidth then
begin
FText.Add(s);
Exit;
end; Offset := 0; //偏移量
i := 1;
LineBegin := 1; // index of the first symbol in the current line
LastSpace := 1; // index of the last space symbol in the current line while i <= n do
begin
if s[i] = ' ' then
LastSpace := i; if FTempArray[i] - Offset > FirstLineWidth then // need wrap
begin
if LastSpace = LineBegin then // there is only one word without spaces...
begin
if i <> LineBegin then // ... and it has more than 1 symbol
begin
if FWordBreak then // 俄文换行
begin
TheWord := BreakWord(s, LineBegin, i, n); //俄文换行
WasBreak := TheWord <> '';
if not WasBreak then
TheWord := Copy(s, LineBegin, i - LineBegin);
if WasBreak then
FText.Add(TheWord '-') else
FText.Add(TheWord);
BreakPos := Length(TheWord);
FHTMLTags.Wrap(BreakPos, WasBreak);
LastSpace := LineBegin BreakPos - 1;
end
else
begin
// mbSingleByte 表示了一个完整的字符时,
// mbLeadByte 表示一个双字节字符的头一个字节
// mbTrailByte 表示一个双字节字符的第二个字节 //todo: [2005-07-29] 狂迷修改中文换行
if ByteType(s, i - 1) = mbLeadByte then //判断是否是汉字字节
begin
FText.Add(Copy(s, LineBegin, i - LineBegin -1));
FHTMLTags.Wrap(i - LineBegin -1, False);
LastSpace := i - 2;
end
else
begin
FText.Add(Copy(s, LineBegin, i - LineBegin));
FHTMLTags.Wrap(i - LineBegin, False);
LastSpace := i - 1;
end;
end;
end
else
begin
FText.Add(s[LineBegin]);
// can't wrap 1 symbol, just add it to the new line
FHTMLTags.Wrap(1, False);
end;
end
else // we have a space symbol inside
begin
if FWordBreak then
begin
TheWord := BreakWord(s, LastSpace 1, i, n);
WasBreak := TheWord <> '';
if WasBreak then
FText.Add(Copy(s, LineBegin, LastSpace - LineBegin 1) TheWord
'-') else
FText.Add(Copy(s, LineBegin, LastSpace - LineBegin));
BreakPos := LastSpace - LineBegin Length(TheWord) 1;
FHTMLTags.Wrap(BreakPos, WasBreak);
if WasBreak then
LastSpace := LineBegin BreakPos - 1;
end
else
begin
FText.Add(Copy(s, LineBegin, LastSpace - LineBegin));
FHTMLTags.Wrap(LastSpace - LineBegin 1, False);
end;
end; Offset := FTempArray[LastSpace]; // starting a new line
Inc(LastSpace);
LineBegin := LastSpace;
FirstLineWidth := Width; // this line is not first, so use Width
end; Inc(i);
end; if n - LineBegin 1 > 0 then // put the rest of line to FText
FText.Add(Copy(s, LineBegin, n - LineBegin 1));
end;
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |