[Example][ScaleRichView] How to draw line numbers

Demos, code samples. Only questions related to the existing topics are allowed here.
Post Reply
Sergey Tkachenko
Site Admin
Posts: 17602
Joined: Sat Aug 27, 2005 10:28 am
Contact:

[Example][ScaleRichView] How to draw line numbers

Post 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
Last edited by Sergey Tkachenko on Fri Oct 02, 2015 9:42 am, edited 1 time in total.
Jim Knopf
Posts: 241
Joined: Mon Dec 30, 2013 10:07 pm
Location: Austria
Contact:

Post by Jim Knopf »

Oh, I saw it only now - thank you!
Sergey Tkachenko
Site Admin
Posts: 17602
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

I think we will add line numbers as a built-in option in TSRichViewEdit.
Sergey Tkachenko
Site Admin
Posts: 17602
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Line numbers is a standard feature since ScaleRichView 6.5 (available for registered users)
Sergey Tkachenko
Site Admin
Posts: 17602
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Line numbers in TRichView FireMonkey

Post 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;
Post Reply