bestlong 怕失憶論壇's Archiver

bestlong 發表於 2006-6-29 23:07

FastReport 2 中文換行及亂碼問題

主要改 fr_class.pas 中的 WrapLine 函數,其中有一段:
[code]
else if s[last] = ' ' then
  OutLine(Copy(s, beg, last - beg)) else
  OutLine(Copy(s, beg, last - beg + 1)); //造成亂碼的根本原因
[/code]
改為
[code]
else if s[last] = ' ' then
  OutLine(Copy(s, beg, last - beg)) else
  if ByteType(s,last) =  mbLeadByte then //判斷是否是中文字
    OutLine(Copy(s, beg, last - beg ))  
  else
    OutLine(Copy(s, beg, last - beg + 1));
[/code]
後面的
[code]
LoopPos := cur;
beg := last + 1; last := beg;
[/code]
要改為:
[code]
LoopPos := cur;
if ByteType(s,last) =  mbLeadByte then  
begin
  beg := last ; last := beg;
end
else
begin
  beg := last + 1; last := beg;
end;
[/code]

資料來源:http://www.delphibbs.com

bestlong 發表於 2006-6-29 23:30

我試過,fr245中中文折行仍有問題,我是這樣解決的。
1、在 WrapMemo 方法中的 WrapLine 程序中加入子程序(在變數宣告之後)
[code]
procedure WrapLine(const s:String);
var
  i, cur, beg, last, LoopPos: Integer;
  WasBreak, CRLF: Boolean;
  //以下為加入部分
  procedure AdjustLast;
  var
    ls: string;
    ci,ni: Integer;
  begin
    ls := Copy(s, beg, last - beg + 1);
    ci := 0;
    for ni := 1 to Length(ls) do
      if (ls[ni] >= #$A0) then Inc(ci);
    ni := ci mod 2;
    if (ni <> 0) and (ls[Length(ls)] >= #$A0) then
      Dec(last);
  end;
[/code]
2.在最後一次調用OutLine的地方作如下修改:
[code]
if WasBreak then
  OutLine(Copy(s, beg, last - beg + 1) + '-')
else if s[last] = ' ' then
  OutLine(Copy(s, beg, last - beg))
else begin
  AdjustLast;  //此為新加的程序
  OutLine(Copy(s, beg, last - beg + 1)); //在fr242中該行就是這樣,在fr245中原來沒有 + 1,但輸出後last卻減1,不知為何
end;
[/code]

bestlong 發表於 2006-6-29 23:36

[code]
procedure WrapLine(const s: wideString);  //解決中文換行亂碼
  var
    i, cur, beg, last, LoopPos: Integer;
    WasBreak, CRLF: Boolean;
  begin
    CRLF := False;
    LoopPos := 0;
    for i := 1 to Length(s) do
      if (s[i] = #10) or (s[i] = #13) then
//    if s[i] in [#10, #13] then
      begin
        CRLF := True;
        break;
      end;
    last := 1; beg := 1;
    if not CRLF and ((Length(s) <= 1) or (WCanvas.TextWidth(s) <= maxwidth)) then
      OutLine(s + #1)
    else
    begin
      cur := 1;
      while cur <= Length(s) do
      begin
      if (s[cur] = #10) or (s[cur] = #13) then
//      if s[cur] in [#10, #13] then
        begin
          OutLine(Copy(s, beg, cur - beg) + #1);
          while (cur < Length(s)) and
         ((s[cur] = #10) or (s[cur] = #13))
        //  (s[cur] in [#10, #13])
          do Inc(cur);
          beg := cur; last := beg;
      if (s[cur] = #10) or (s[cur] = #13) then
//      if s[cur] in [#13, #10] then
            Exit else
            continue;
        end;
        if s[cur] <> ' ' then
        if WCanvas.TextWidth(Copy(s, beg, cur - beg + 1)) > maxwidth then
        begin
          WasBreak := False;
          if (Flags and flWordBreak) <> 0 then
          begin
            i := cur;
            while (i <= Length(s)) and
            not ((s[i] = ' ') or (s[i] = ' ') or (s[i] = '.') or (s[i] = ',') or(s[i] = '-')) do
            //not (s[i] in spaces) do
              Inc(i);
            b := BreakWord(Copy(s, last + 1, i - last - 1));
            if Length(b) > 0 then
            begin
              i := 1;
              cur := last;
              while (i <= Length(b)) and
                (WCanvas.TextWidth(Copy(s, beg, last - beg + 1 + Ord(b[i])) + '-') <= maxwidth) do
              begin
                WasBreak := True;
                cur := last + Ord(b[i]);
                Inc(i);
              end;
              last := cur;
            end;
          end
          else
            if last = beg then last := cur;
          if WasBreak then
            OutLine(Copy(s, beg, last - beg + 1) + '-')
          else if s[last] = ' ' then
            OutLine(Copy(s, beg, last - beg)) else
          begin
            OutLine(Copy(s, beg, last - beg));
            Dec(last);
          end;
          if ((Flags and flWordBreak) <> 0) and not WasBreak and (last = cur - 1) then
            if LoopPos = cur then
            begin
              beg := cur + 1;
              cur := Length(s);
              break;
            end
            else
              LoopPos := cur;
          beg := last + 1; last := beg;
        end;
//      if s[cur] in spaces then last := cur;
        if s[cur] = ' ' then last := cur;
        Inc(cur);
      end;
      if beg <> cur then OutLine(Copy(s, beg, cur - beg + 1) + #1);
    end;
  end;
[/code]
頁: [1]

Powered by Discuz! X1.5 Archiver   © 2001-2010 Comsenz Inc.