Page 1 of 1

[Example][ScaleRichView] How to draw line numbers

Posted: Sun Feb 01, 2015 9:28 pm
by Sergey Tkachenko
Update: this code is not needed in new version of ScaleRichView, because this is a standard feature, see TSRichViewEdit.LineNumberProperty

Assign this code to TSRichViewEdit's OnPaintPage event.

The code draws line numbers at the left margin.
Numbering is restarted on each page.

Code: Select all

procedure TForm1.SRichViewEdit1PaintPage(Sender: TObject; PageNo: Integer;
  PageRect, R: TRect; Canvas: TCanvas; Prepaint, Printing: Boolean);
const
  PageNumberDX = 5; // distance between line numbers and text
var
  i: Integer;
  FirstItemNo, LastItemNo, Offs, ItemPart: Integer;
  FirstPageNo, LastPageNo : Integer;
  ItemRect: TRect;
  srv: TSRichViewEdit;
  TextHeight, LineNumber, Left, Top, LeftMargin: Integer;
begin

  // line number font
  Canvas.Font.Name := 'Tahoma';
  Canvas.Font.Size := 6;
  Canvas.Font.Style := [];
  Canvas.Font.Color := clBtnShadow;
  Canvas.Brush.Style := bsClear;
  
  TextHeight := Canvas.TextHeight('0');
  srv := Sender as TSRichViewEdit;
  srv.GetPageStartItemNo(PageNo, FirstItemNo, Offs);
  srv.GetPageLastItemNo(PageNo, LastItemNo, Offs);
  LineNumber := 1;
  LeftMargin := srv.GetLeftMargin100Pix(PageNo);

  for i := FirstItemNo to LastItemNo do begin
    if srv.RichViewEdit.GetItemStyle(i)=rvsTable then
      continue;
    ItemPart := 0;
    while srv.GetItemBounds100(
      srv.RichViewEdit.RVData, i, ItemRect,
      FirstPageNo, LastPageNo, ItemPart) do begin
      if (FirstPageNo = PageNo) and
         ((ItemPart>0) or srv.RichViewEdit.IsFromNewLine(i)) then begin
          Left := PageRect.Left + LeftMargin - PageNumberDX -
            Canvas.TextWidth(IntToStr(LineNumber));
          Top := PageRect.Top + (ItemRect.Top+ItemRect.Bottom - TextHeight) div 2;
          Canvas.TextOut(Left, Top, IntToStr(LineNumber));
        inc(LineNumber);
      end;
      inc(ItemPart);
    end;
  end;
end;
Screenshot:
Image

Posted: Sat Feb 21, 2015 6:59 pm
by Jim Knopf
Oh, I saw it only now - thank you!

Posted: Sun Feb 22, 2015 2:02 pm
by Sergey Tkachenko
I think we will add line numbers as a built-in option in TSRichViewEdit.

Posted: Sat Aug 01, 2015 5:06 pm
by Sergey Tkachenko
Line numbers is a standard feature since ScaleRichView 6.5 (available for registered users)

Line numbers in TRichView FireMonkey

Posted: Wed Aug 28, 2024 11:40 am
by Sergey Tkachenko
This code for OnPaint event draws line numbers in FireMonkey version of TRichView.
Line numbers are drawn on the left margin, so the value of LeftMargin property must be large enough.

The following values can be customized:
- distance from the right side of numbers to the right side of the left margin (PageNumberDX constant)
- font name, size and color of line numbers (this example uses 'Arial', 8, Blueviolet)

Code: Select all

uses fmxCRVData, fmxDLines;

procedure TfrmMain.rvePaint(Sender: TCustomRichView; ACanvas: TCanvas;
  Prepaint: Boolean);
const
  PageNumberDX = 5; // distance between line numbers and text
var
  i: Integer;
  TextHeight: Single;
  LineNumber: Integer;
  rv: TCustomRichView;
  R: TRectF;
  DItem: TRVDrawLineInfo;
  MinY, MaxY, ZoomRatio: Single;
begin
  if Prepaint then
    exit;
  rv := Sender as TCustomRichView;
  if not (rvflRoot in rv.Flags) then
    exit;
  ZoomRatio := rv.ZoomPercent / 100;

  Canvas.Font.Family := 'Arial';
  Canvas.Font.Size := 8 * ZoomRatio;
  Canvas.Font.Style := [];
  Canvas.Fill.Color := TAlphaColorRec.Blueviolet;

  TextHeight := Canvas.TextHeight('0');
  LineNumber := 1;

  MinY := rv.ClientToDocument(TPointF.Create(0, 0)).Y;
  MaxY := MinY + rv.Height;

  for i := 0 to rv.RVData.DrawItems.Count - 1 do
  begin
    DItem := rv.RVData.DrawItems[i];
    if DItem.FromNewLine then
    begin
      R := TRectF.Create(0, DItem.Top - TextHeight,
        (rv.LeftMargin - PageNumberDX) * ZoomRatio,
        DItem.Top + DItem.Height + TextHeight);
      if R.Top > MaxY then
        exit;
      if R.Bottom >= MinY then
        Canvas.FillText(R, IntToStr(LineNumber), False, 1, [],
           TTextAlign.Trailing, TTextAlign.Center);
      inc(LineNumber);
    end;
  end;

end;