网上文摘 最近更新 下载排行 资源分类 下载指南
经典编程资源 精彩不容错过
设为首页
加入收藏
联系我们
当前位置:Delphi园地技巧文章编程心得 → FastReport 3.X 在 Win9X 下的中文折行乱码问题
FastReport 3.X 在 Win9X 下的中文折行乱码问题
日期:2006-03-22 作者:狂迷 人气: 查看:[大字体 中字体 小字体]

花了不少时间去装虚拟机和 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;

(出处:http://www.delphibbs.com/keylife/iblog_show.asp?xid=16261)

相关文章:
·FastReport技巧
·FastReport问题集
·让Fastreport3.x支持中文PDF的输出
·Fastreport 3.07 专业版的安装及中文化
·Fastreport3.14的中文PDF输出
·StringGrid打印报表(FastReport)
·FastReport 3.23.12 创建"人民币大小写转换"自定义函数
·FastReport 3.18版For Delphi7安装笔记
·FastReport 程序员手册
·Delphi7中手动安装FastReport v4的方法
 → 特别推荐
 → 热点TOP10
关于我们 | 广告服务 | 发布资源 | 联系站长 Copyright 2001-2012 Delphi园地 All Rights Reserved