修复lazarus lazreport中文换行乱码


lazreport 换行乱码是默认的编码引起的,只需打开LR_Class.pas,将procedure wrapline(const s:string)里的Length、copy替换为UTF8Length和UTF8Copy就可以修复中文换行乱码的bug。

  procedure WrapLine(const s: String);
  var
    i, cur, beg, last, len: Integer;
    WasBreak, CRLF, IsCR: Boolean;
    ch: char;
  begin

    CRLF := False;
    for i := 1 to UTF8Length(s) do     
begin if s[i] in [#10, #13] then begin CRLF := True; break; end; end; last := 1; beg := 1; if not CRLF and ((UTF8Length(s) <= 1) or (WCanvas.TextWidth(s) <= maxwidth)) then
begin OutLine(s + #1) end else begin cur := 1; Len := UTF8length(s); while cur <= Len do begin Ch := s[cur]; // check for items with soft-breaks IsCR := Ch=#13; if IsCR then begin //handle composite newline if (cur < UTF8length(s)) then begin ch := s[cur+1]; //dont increase char index if next char is LF (#10) if s[cur+1]<>#10 then Inc(Cur); end; end; if Ch=#10 then begin OutLine(UTF8Copy(s, beg, cur - beg) + #1); //increase the char index since it's pointing to CR (#13) if IsCR then Inc(cur); Inc(cur); beg := cur; last := beg; Continue; end; if ch <> ' ' then if WCanvas.TextWidth(UTF8Copy(s, beg, cur - beg + 1)) > maxwidth then begin WasBreak := False; if (Flags and flWordBreak) <> 0 then begin // in case of breaking in the middle, get the full word i := cur; while (i <= Len) and not (ch in [' ', '.', ',', '-']) do begin Inc(i); ch := s[i]; end; // find word's break points using some simple hyphenator algorithm // TODO: implement interface so users can use their own hyphenator // algorithm
aWord := UTF8Copy(s, last, i - last); if (FHyp<>nil) and (FHyp.Loaded) then begin try b := FHyp.BreakWord(UTF8Lowercase(aWord)); except b := ''; end; end else b := BreakWord(aWord); // if word can be broken in many segments, find the last segment that // fits within maxwidth
if UTF8Length(b) > 0 then begin i := 1; while (i <= UTF8Length(b)) and (WCanvas.TextWidth(UTF8Copy(s, beg, last - beg + Ord(b[i])) + '-') <= maxwidth) do begin WasBreak := True; cur := last + Ord(b[i]); // cur now points to next char after breaking word Inc(i); end; end; if (not WasBreak) and (FHyp<>nil) and FHyp.Loaded then // if hyphenator was specified and is valid don't break // words which hyphenator didn't break else // last now points to nex char to be processed last := cur; end else begin if last = beg then last := cur; end; if WasBreak then begin // if word has been broken, output the partial word plus an hyphen
OutLine(UTF8Copy(s, beg, last - beg) + '-'); end else begin // output the portion of word that fits maxwidth
OutLine(UTF8Copy(s, beg, last - beg)); // if space was found, advance to next no space char
while (s[last] = ' ') and (last < UTF8Length(s)) do Inc(last); end; beg := last; end; if Ch in [' ', '.', ',', '-'] then last := cur; Inc(cur); end; if beg <> cur then OutLine(UTF8Copy(s, beg, cur - beg + 1) + #1); end;