Print Watermarks

Top  Previous  Next

Watermarks are drawings which are printed before the actual contents of a page is printed.

 

In WPTools 5 Watermarks have to be printed inside the event handler for OnPaintWatermark.

 

This event gets this parameters:

 

Sendera reference to the TWPRichText component which tiggered the event
RTFEngineis the RTF Engine (= TWPRichText.Memo)
toCanvasthe drawing canvas for the output. During printtime this is the printer canvas.
PageRectthe bounding rectangle of the page. During printime the Top,Left coordinate is set to the negative physical offset to make it easy to print at exact positions.
PaintPageNrthe number of the page, 0 based
RTFPageNr0 or the number of the text page which is printed later over the watermark. You can access the definition object (class TWPVirtPage) of this page by reading

       RTFEngine.DisplayedText.Pages[RTFPageNr - 1].

WaterMarkRefreserved
XRes and YResdefine the current resolution. This is very important to convert real coordinates into coordinates on the virtual paper. You can use this functions to convert CM into pixles. The result value has to be added to PageRect.Left or PageRect.Top.

 

function XP(cm: Double): Integer;

begin

   Result := MulDiv(WPCentimeterToTwips(cm), Xres, 1440);

end;

function YP(cm: Double): Integer;

begin

   Result := MulDiv(WPCentimeterToTwips(cm), Yres, 1440);

end;

 

CurrentZoomspecifies the zooming the editor uses, at printtime it is 1
PaintModethe paint mode which is currently used. By checking for 'wppInPaintDesktop' you can write code which is not active at print time.

 

 

Example:

 

You can print the contents of one editor to the background of a different editor: (demo WaterM3)

 

procedure TWPLetterHeadEdit.WPRichText1PaintWatermark(Sender: TObject;

RTFEngine: TWPRTFEnginePaint; toCanvas: TCanvas; PageRect: TRect;

PaintPageNr, RTFPageNr: Integer; WaterMarkRef: TObject; XRes,

YRes: Integer; CurrentZoom: Single; PaintMode: TWPPaintModes);

begin

// We are painting on a RTF-Engine surface so use the

// PaintPageMode wpNoViewPortAPI since everything has been

// set up already

WPLetterhead.PaintPageOnCanvas(0,

    0, 0, 0, 0, toCanvas, [],

    XRes, YRes, -1, -1, [wpNoViewPortAPI]);

end;

 

 

Other examples how Watermarks can be used (Project: Demos\Tasks\Watermark)

 

a) show a background pattern on the virtual paper - but do not print this pattern:

 

var x,y : Integer;

   bit : TBitmap;

begin

if wppInPaintDesktop in PaintMode then

begin

   x := PageRect.Left;

   bit := Image1.Picture.Bitmap;

   while x<PageRect.Right do

   begin

    y := PageRect.Top;

    while y<PageRect.Bottom do

    begin

      toCanvas.Draw(x,y,bit);

      inc(y, bit.Height);

    end;

    inc(x, bit.Width);

   end

end;

end;

 

 

b) Draw a 0.5 cm grid using light blue color, this grid is also printed

 

var i,j : Integer;

begin

   toCanvas.Pen.Width := 0;

   toCanvas.Pen.Color := $00FAD5AF;

   toCanvas.Pen.Style := psSolid;

   for i:=1 to 1000 do

   begin

     j := PageRect.Left + MulDiv(WPCentimeterToTwips(0.5 * i), Xres, 1440);

     if j>= PageRect.Right then break;

     toCanvas.MoveTo(j, PageRect.Top);

     toCanvas.LineTo(j, PageRect.Bottom);

   end;

 

   for i:=1 to 1000 do

   begin

     j := PageRect.Top + MulDiv(WPCentimeterToTwips(0.5 * i), Yres, 1440);

     if j>= PageRect.Bottom then break;

     toCanvas.MoveTo(PageRect.Left, j);

     toCanvas.LineTo(PageRect.Right, j);

   end;

end;

 

 

c) Print a frame line around the text area

 

(1) We are using the main page layout information:

 

procedure TWaterM.WPRichText1PaintWatermark(Sender: TObject;

  RTFEngine: TWPRTFEnginePaint; toCanvas: TCanvas;

  PageRect: TRect; PaintPageNr, RTFPageNr: Integer; WaterMarkRef: TObject;

  XRes, YRes: Integer;

  FCurrentZoom : Single;

  PaintMode: TWPPaintModes);

var r: TRect;

begin

r.Left := PageRect.Left + MulDiv( RTFEngine.RTFData.Header.LeftMargin, XRes, 1440);

r.Top := PageRect.Top + MulDiv( RTFEngine.RTFData.Header.TopMargin, YRes, 1440);

r.Right := PageRect.Right - MulDiv( RTFEngine.RTFData.Header.RightMargin, XRes, 1440); 

r.Bottom := PageRect.Bottom - MulDiv( RTFEngine.RTFData.Header.BottomMargin, YRes, 1440);

toCanvas.Pen.Color := clBtnShadow;

toCanvas.Pen.Width := 0;

toCanvas.Brush.Style := bsClear;

toCanvas.Rectangle(r);

end;

 

(2) Now we are using the page layout information for the current page.

 

if RTFPageNr > 0 then

begin

   r.Left := PageRect.Left + MulDiv(

        RTFEngine.DisplayedText.Pages[RTFPageNr - 1].PageMarginLeft, XRes, 1440);

   r.Top := PageRect.Top + MulDiv(

        RTFEngine.DisplayedText.Pages[RTFPageNr - 1].PageMarginTop, YRes, 1440);

   r.Right := PageRect.Right - MulDiv(

        RTFEngine.DisplayedText.Pages[RTFPageNr - 1].PageMarginRight, XRes, 1440);

   r.Bottom := PageRect.Bottom - MulDiv(

        RTFEngine.DisplayedText.Pages[RTFPageNr - 1].PageMarginBottom, YRes, 1440);

   toCanvas.Pen.Color := clBtnShadow;

   toCanvas.Pen.Width := 0;

   toCanvas.Brush.Style := bsClear;

   toCanvas.Rectangle(r);

end;

 

Please note that the parameter RTFPageNr can be 0 if the page was inserted as "external page".

 

d) Display a pre-printed form (such as a money transfer form) as part of the page.

 

WaterM2Demo

 

This example requires to use the event OnMeasurePage as well. In this event we reserve space at the bottom of the first page:

 

const PR_Form_Height = 10.5; // Form Height in CM

     PR_Form_Width  = 15.0;

 

procedure TForm1.WPRichText1MeasureTextPage(Sender: TObject;

PageInfo: TWPMeasurePageParam);

begin

// We want to make sure the first page has a bottom margin which is

// large enough for our form

if PageInfo.pagenr = 1 then

begin

   PageInfo.marginbottom := WPCentimeterToTwips(PR_Form_Height);

   PageInfo.changed := TRUE;

end;

end;

 

The PaintWatermark code only draws on the first page:

 

procedure TForm1.WPRichText1PaintWatermark(Sender: TObject;

RTFEngine: TWPRTFEnginePaint; toCanvas: TCanvas; PageRect: TRect;

PaintPageNr, RTFPageNr: Integer; WaterMarkRef: TObject; XRes,

YRes: Integer; CurrentZoom: Single; PaintMode: TWPPaintModes);

// ~~~~~~~~~~~~~~~~~~~~~ Convert CM values into pixel ~~~~~~~~~~~~~

function XP(cm: Double): Integer;

begin

   Result := MulDiv(WPCentimeterToTwips(cm), Xres, 1440);

end;

function YP(cm: Double): Integer;

begin

   Result := MulDiv(WPCentimeterToTwips(cm), Yres, 1440);

end;

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

var r, r2: TRect;

off, w: Integer;

begin

if PaintPageNr = 0 then

begin

   r := PageRect;

   r.Top := r.Bottom - YP(PR_Form_Height);

   toCanvas.Pen.Color := clBlack;

   toCanvas.Pen.Style := psDash;

   toCanvas.MoveTo(r.Left, r.Top);

   toCanvas.LineTo(r.Right, r.Top);

 

   // Draw the form at the right bottom border

   r.Left := r.Right - XP(PR_Form_Width);

 

   // Draw line

   toCanvas.MoveTo(r.Left, r.Top);

   toCanvas.LineTo(r.Left, r.Bottom);

 

   // Draw the sizzors

   toCanvas.Font.Name := 'WingDings';

   toCanvas.Font.Height := -YP(0.5);

   toCanvas.TextOut( PageRect.Left + XP(0.7), r.Top-

      toCanvas.TextHeight(#$22) div 2 , #$22 );

 

    // This is background of the form, we do not draw this when

    // we are printing!

   if wppInPaintDesktop in PaintMode then

   begin

     r2 := r;

     inc(r2.Left,XP(0.1));

     inc(r2.Top,YP(0.1));

     toCanvas.Brush.Color := clYellow;

     toCanvas.FillRect(r2);

   end;

 

    // This are the form text

   toCanvas.Brush.Color := clWhite;

   toCanvas.Font.Name := 'Courier New';

   toCanvas.Font.Height := -YP(0.5);

   toCanvas.Font.Style := [fsBold];

   off := YP(0.1);

 

    // NAME

   r2.Left := r.Left + XP(1.0);

   r2.Top := r.Top + YP(2);

   r2.Right := r2.Left + XP(10);

   r2.Bottom := r2.Top + YP(0.7);

   toCanvas.FillRect(r2);

   toCanvas.TextOut(r2.Left + off, r2.Top + off, NameE.Text);

 

    // ADR

   r2.Left := r.Left + XP(1.0);

   r2.Top := r.Top + YP(5.5);

   r2.Right := r2.Left + XP(10);

   r2.Bottom := r2.Top + YP(0.7);

   toCanvas.FillRect(r2);

   toCanvas.TextOut(r2.Left + off, r2.Top + off, AdrE.Text);

 

    // COST, right aligned

   r2.Left := r.Left + XP(8.5);

   r2.Top := r.Top + YP(4.5);

   r2.Right := r2.Left + XP(5);

   r2.Bottom := r2.Top + YP(0.7);

   toCanvas.FillRect(r2);

   w := toCanvas.TextWidth(CostE.Text);

   toCanvas.TextOut(r2.Right - off - w, r2.Top + off, CostE.Text);

 

   // For Debugging

   // Draw a Line at 10,10 CM

   if DrawDebugCross.Checked then

   begin

     toCanvas.TextOut( PageRect.Left+XP(10), PageRect.Top, '10');

     toCanvas.TextOut( PageRect.Left, PageRect.Top+YP(10), '10');

     toCanvas.MoveTo( PageRect.Left, PageRect.Top + YP(10));

     toCanvas.LineTo( PageRect.Right, PageRect.Top + YP(10));

     toCanvas.MoveTo( PageRect.Left+XP(10), PageRect.Top);

     toCanvas.LineTo( PageRect.Left+XP(10), r.Top);

   end;

end;

end;