Page 1 of 1

Watermark

Posted: Tue Jun 06, 2017 9:41 am
by Yury
Hello, I found some operations which are placing the watermark on to the document. But how can I setup watermark in such a way that it'd be visible for the end user in process of his work over document, and user could not remove it?
Same way as I can see Tracker-Soft's Watermark image. ( See attach )

Regards,
Yury

Re: Watermark

Posted: Tue Jun 06, 2017 11:54 am
by Sasha - Tracker Dev Team
Hello Yury,

Basically what you have to do is draw on the Pages View directly. For that, check out this post:
https://forum.pdf-xchange.com/ ... ck#p103111

Cheers,
Alex

Re: Watermark

Posted: Wed Jun 07, 2017 1:42 pm
by Yury
Thanks, Sasha. I did the following:
1. I took the code from the sample, you've pointed me to.
2. I changed the m_aInst.MathHelper.Matrix_TransformRect(ref p2v, ref rc); to m_aInst.MathHelper.Rect_Transform(ref p2v, ref rc); as compiler failed to find method.
3. I tried to register/unregister call back at event monitor... ( not sure I did this correctly )

Code: Select all

        public partial class UIEventMon : PDFXEdit.IUIX_EventMonitor
        {
            MainEditorForm _form;
            bool _registered = false;
            public  UIEventMon(MainEditorForm form)
            {
                _form = form;
            }
            public void OnEventMonitor(PDFXEdit.IUIX_Obj pTarget, PDFXEdit.IUIX_Event pEvent)
            {
                
                {
                    if (_form.pdfCtl.Doc != null && !_registered)
                    {
                        _form.pdfCtl.Doc.ActiveView.PagesView.RegisterDrawCallback(PDFXEdit.PXV_PagesViewDrawStage.PXV_PagesViewDraw_Foreground, _form._dPClbk);
                        _registered = true;
                    }
                }
                
                if( pEvent.Code == (int)PDFXEdit.UIX_EventCodes.e_BeforeDestroy )
                {
                    if(_form.pdfCtl.Doc != null && _registered )
                    {
                        _form.pdfCtl.Doc.ActiveView.PagesView.UnregisterDrawCallback(PDFXEdit.PXV_PagesViewDrawStage.PXV_PagesViewDraw_Foreground, _form._dPClbk);
                        _registered = false;
                    }
                }
                
            }
        }
I'm able to break debugger at painting code ( DrawRectangle ), however I see nothing in editor view.
Sometimes, ( in case I have document with 1 page, I see the blue rectangle at the left bottom of the page. If open doc with several pages, I don't see it.

So,
1. How can I properly register/unregister callback?
2. How to draw on each page?

Best regards, and thanks for your help!

Re: Watermark

Posted: Wed Jun 07, 2017 2:06 pm
by Sasha - Tracker Dev Team
Hello Yury,

In this case you should use the pdfCtl_OnEvent method to monitor the events. As for the registering\unregistering of the callback, you can use the e.activeDocChanged event to unregister the callback first and then register it to another document. Also the unregistering should be done in the e.document.beforeClose event. The callback itself should probably hold a reference to the IPXV_Document that should be cleared when unregistering.
To draw on all of the pages do this:

Code: Select all

//Drawing rectangle on the foreground
if (nStage == PDFXEdit.PXV_PagesViewDrawStage.PXV_PagesViewDraw_Foreground)
{
	for (uint i = 0; i < pPageRegions.Count; i++)
	{
		DrawRectangle(pView, pRC, pPageRegions[i].nPage);
	}
}
Cheers,
Alex

Re: Watermark

Posted: Wed Jun 07, 2017 3:36 pm
by Yury
Thanks, sorry, can't find where these e.activeDocChanged , e.document.beforeClose are defined?

Re: Watermark

Posted: Wed Jun 07, 2017 4:20 pm
by Tracker Supp-Stefan
Hello Yuri,

This is a list of the events in the Editor:
https://sdkhelp.pdf-xchange.com/view/PXV:PXV_Events

And you can handle them with the OnEvent method:
https://sdkhelp.pdf-xchange.com/vie ... er_OnEvent

Regards,
Stefan

Re: Watermark

Posted: Wed Jun 07, 2017 5:10 pm
by Yury
Could you please give some code example? Not sure I understand.....
I have this in my code

Code: Select all

private void pdfCtl_OnEvent(object sender, AxPDFXEdit._IPXV_ControlEvents_OnEventEvent e)
        {
            
            
        }
And this:

Code: Select all

 this.pdfCtl.OnEvent += new AxPDFXEdit._IPXV_ControlEvents_OnEventEventHandler(this.pdfCtl_OnEvent);
Until now everything is clear for me.
But inside the pdfCtl_OnEvent, how I can detect that e is "e.document.beforeClose"
Sorry, looks I missing something

Re: Watermark

Posted: Wed Jun 07, 2017 8:19 pm
by Sasha - Tracker Dev Team
Please check the FullDemo application - there is a sample on that matter.

Cheers,
Alex

Re: Watermark

Posted: Thu Jun 08, 2017 9:40 am
by Yury
int id = pdfCtl.Inst.Str2ID("e.document.beforeClose");

Correct?

Re: Watermark

Posted: Thu Jun 08, 2017 10:03 am
by Sasha - Tracker Dev Team
Correct, and then compare it to the e.nEventID.

Cheers,
Alex

Re: Watermark

Posted: Thu Jun 08, 2017 3:31 pm
by Yury
Does not work....

Code: Select all

 private void pdfCtl_OnEvent(object sender, AxPDFXEdit._IPXV_ControlEvents_OnEventEvent e)
        {
            try
            {
                if (e.nEventID == _editorIDS.nIDS[(int)IDS.e_activeDocChanged])
                {

                    if (_doc != null)
                        _doc.ActiveView.PagesView.UnregisterDrawCallback(PDFXEdit.PXV_PagesViewDrawStage.PXV_PagesViewDraw_Foreground, _dPClbk);
                   
                    if(this.pdfCtl.Doc!=null )
                         this.pdfCtl.Doc.ActiveView.PagesView.RegisterDrawCallback(PDFXEdit.PXV_PagesViewDrawStage.PXV_PagesViewDraw_Foreground, _dPClbk);
                    
                    _doc = this.pdfCtl.Doc;
                }
                int id = pdfCtl.Inst.Str2ID("e.document.beforeClose");

                if (e.nEventID == id)
                {
                    this.pdfCtl.Doc.ActiveView.PagesView.UnregisterDrawCallback(PDFXEdit.PXV_PagesViewDrawStage.PXV_PagesViewDraw_Foreground, _dPClbk);
                }
            }
            catch (Exception ex)
            {
                return;
            }
1. I can break at

Code: Select all

public void DrawRectangle(PDFXEdit.IPXV_PagesView pView, PDFXEdit.IUIX_RenderContext pRC_, uint nPage)
        {
            PDFXEdit.IPXV_PagesLayoutManager plm = pView.Layout;
            if (plm == null)
                return;

            PDFXEdit.PXC_Matrix p2v = plm.GetPageToDeviceMatrix(nPage, true);
            PDFXEdit.PXC_Rect rc = m_rcDraw;
            m_aInst.MathHelper.Rect_Transform(ref p2v, ref rc);

            //Flipping rectangle top and bottom coordinates and converting it's type
            PDFXEdit.tagRECT rcDR;
            rcDR.left = (int)rc.left;
            rcDR.right = (int)rc.right;
            rcDR.top = (int)rc.bottom;
            rcDR.bottom = (int)rc.top;

            pRC_.DrawRect(rcDR, m_Brush, m_Pen, ref rcDR, 1);
        }
So, call back is set. But I don't see any rectangles on pages. See attachment.
Next, this code produces exception when I'm closing window..

Code: Select all

if (_doc != null)
                        _doc.ActiveView.PagesView.UnregisterDrawCallback(PDFXEdit.PXV_PagesViewDrawStage.PXV_PagesViewDraw_Foreground, _dPClbk);
May be I should not save doc?
And finally, I never come to inside the if:

Code: Select all

if (e.nEventID == id)
                {
                    this.pdfCtl.Doc.ActiveView.PagesView.UnregisterDrawCallback(PDFXEdit.PXV_PagesViewDrawStage.PXV_PagesViewDraw_Foreground, _dPClbk);
                }
Any thoughts? I'm using x64 version of the control.

Re: Watermark

Posted: Thu Jun 08, 2017 3:54 pm
by Yury
Seems I got rid of exceptions and callback registrations issues. (

Code: Select all

int id = pdfCtl.Inst.Str2ID("e.document.beforeClose");
             pdfCtl.EnableEventListening2(id, bRegister);
But I still do not see the rectangles... Ideas?

Re: Watermark

Posted: Fri Jun 09, 2017 9:07 am
by Sasha - Tracker Dev Team
Hello Yury,

For starters just make a button with this code:

Code: Select all

DrawPagesCallback m_DPClbk = null;

private void drawRectangleOnPageToolStripMenuItem_Click(object sender, EventArgs e)
{
	if (m_DPClbk == null)
	{
		m_DPClbk = new DrawPagesCallback(auxInst, uiInst);
		//Registering callback at the needed document's pages view
		pdfCtl.Doc.ActiveView.PagesView.RegisterDrawCallback(PDFXEdit.PXV_PagesViewDrawStage.PXV_PagesViewDraw_Foreground, m_DPClbk);
	}
}
Then use this code here for a callback class:

Code: Select all

public class DrawPagesCallback : PDFXEdit.IPXV_PagesViewDrawCallback
{
	public PDFXEdit.IAUX_Inst m_aInst;
	public PDFXEdit.IUIX_Inst m_uiInst;
	private PDFXEdit.IColor m_clrFill;
	private PDFXEdit.IColor m_clrBorder;
	private PDFXEdit.PXC_Rect m_rcDraw;
	PDFXEdit.IUIX_Brush m_Brush;
	PDFXEdit.IUIX_Pen m_Pen;
	public DrawPagesCallback(PDFXEdit.IAUX_Inst aInst, PDFXEdit.IUIX_Inst uiInst)
	{
		m_aInst = aInst;
		m_uiInst = uiInst;
		m_clrFill = m_aInst.CreateColor(PDFXEdit.ColorType.ColorType_RGB);
		m_clrFill.SetRGB(0.0f, 1.0f, 1.0f);
		m_clrBorder = m_aInst.CreateColor(PDFXEdit.ColorType.ColorType_RGB);
		m_clrBorder.SetRGB(0.0f, 1.0f, 0.0f);
		m_rcDraw.left = -100;
		m_rcDraw.right = 100;
		m_rcDraw.top = 100;
		m_rcDraw.bottom = 0;
		m_Brush = m_uiInst.CreateNewBrush();
		m_Pen = m_uiInst.CreateNewPen();
		m_Brush.Color0 = m_clrFill.RGB;
		m_Brush.Color1 = m_clrFill.RGB;
		m_Pen.Brush.Color0 = m_clrBorder.RGB;
		m_Pen.Brush.Color1 = m_clrBorder.RGB;
		m_Pen.Width = 10;
		m_Pen.Inside = true;

	}
	public void OnDrawPagesView(PDFXEdit.IPXV_PagesView pView, PDFXEdit.PXV_PagesViewDrawStage nStage, PDFXEdit.IUIX_RenderContext pRC, PDFXEdit.IPXV_PagesLayoutRegions pPageRegions)
	{
		if (pView == null)
			return;
		//Drawing rectangle on the foreground
		if (nStage == PDFXEdit.PXV_PagesViewDrawStage.PXV_PagesViewDraw_Foreground)
		{
			for (uint i = 0; i < pPageRegions.Count; i++)
			{
				DrawRectangle(pView, pRC, pPageRegions[i].nPage);
			}
		}
	}

	public void DrawRectangle(PDFXEdit.IPXV_PagesView pView, PDFXEdit.IUIX_RenderContext pRC_, uint nPage)
	{
		PDFXEdit.IPXV_PagesLayoutManager plm = pView.Layout;
		if (plm == null)
			return;

		PDFXEdit.PXC_Matrix p2v = plm.GetPageToDeviceMatrix(nPage, true);
		PDFXEdit.PXC_Rect rc = m_rcDraw;
		m_aInst.MathHelper.Rect_Transform(ref p2v, ref rc);

		//Flipping rectangle top and bottom coordinates and converting it's type
		PDFXEdit.tagRECT rcDR;
		rcDR.left = (int)rc.left;
		rcDR.right = (int)rc.right;
		rcDR.top = (int)rc.bottom;
		rcDR.bottom = (int)rc.top;

		pRC_.DrawRect(rcDR, m_Brush, m_Pen, ref rcDR, 1);
	}
}
Do not forget about unregistering the callback:

Code: Select all

if (e.nEventID == nIDS[(int)IDS.e_document_beforeClose])
{
	if (m_DPClbk != null)
		pdfCtl.Doc.ActiveView.PagesView.UnregisterDrawCallback(PDFXEdit.PXV_PagesViewDrawStage.PXV_PagesViewDraw_Foreground, m_DPClbk);
}
All of this code should draw a rectangle on the visual left bottom side of the page.

Cheers,
Alex

Re: Watermark

Posted: Fri Jun 09, 2017 10:43 am
by Yury
Not working.... project attached

Thank you.

Re: Watermark

Posted: Fri Jun 09, 2017 11:13 am
by Sasha - Tracker Dev Team
Hello Yury,

As I see you haven't tried resizing the page or scrolling it. You will have to invalidate the page(s) for the first time manually:

Code: Select all

pdfCtl.Doc.ActiveView.PagesView.RegisterDrawCallback(PDFXEdit.PXV_PagesViewDrawStage.PXV_PagesViewDraw_Foreground, _dPClbk);
pdfCtl.Doc.ActiveView.PagesView.InvalidatePage(pdfCtl.CurrentPage);
Cheers,
Alex

Re: Watermark

Posted: Fri Jun 09, 2017 11:34 am
by Yury
No, this didn't help . Have you tried to build/run my project?

Re: Watermark

Posted: Fri Jun 09, 2017 11:43 am
by Sasha - Tracker Dev Team
Works for me:
WS.gif
Cheers,
Alex

Re: Watermark

Posted: Fri Jun 09, 2017 12:00 pm
by Yury
Just checked again.... If I start under VS2013 - it works. If I start under VS2010 - it does not.... any thoughts?

Re: Watermark

Posted: Fri Jun 09, 2017 12:12 pm
by Sasha - Tracker Dev Team
Hello Yury,

What came to mind is a .Net platform that the different VS are using - check that out.

Cheers,
Alex

Re: Watermark

Posted: Fri Jun 09, 2017 12:43 pm
by Yury
No, this is in project settings. Both use .Net Framework 4 Client Profile

Re: Watermark

Posted: Fri Jun 09, 2017 12:48 pm
by Sasha - Tracker Dev Team
Well then it's not a SDK problem then.

Cheers,
Alex

Re: Watermark

Posted: Fri Jun 09, 2017 2:36 pm
by Yury
Alex, I think that issue is in some object marshaling....look at the code below:

Code: Select all

public void OnDrawPagesView(PDFXEdit.IPXV_PagesView pView, PDFXEdit.PXV_PagesViewDrawStage nStage, PDFXEdit.IUIX_RenderContext pRC, PDFXEdit.IPXV_PagesLayoutRegions pPageRegions)
   {
      if (pView == null)
         return;
      //Drawing rectangle on the foreground
      if (nStage == PDFXEdit.PXV_PagesViewDrawStage.PXV_PagesViewDraw_Foreground)
      {
         for (uint i = 0; i < pPageRegions.Count; i++)
         {
            DrawRectangle(pView, pRC, pPageRegions[i].nPage, pPageRegions[i].rcPageRect);
         }
      }
   }
public void DrawRectangle(PDFXEdit.IPXV_PagesView pView, PDFXEdit.IUIX_RenderContext pRC_, uint nPage, PDFXEdit.tagRECT rcPage)
   {
      PDFXEdit.IPXV_PagesLayoutManager plm = pView.Layout;
      if (plm == null)
         return;

      PDFXEdit.PXC_Matrix p2v = plm.GetPageToDeviceMatrix(nPage, true);
      PDFXEdit.PXC_Rect rc = m_rcDraw;
      PDFXEdit.PXC_Rect rcPageRect; rcPageRect.bottom = rcPage.bottom; rcPageRect.left = rcPage.left; rcPageRect.top = rcPage.top; rcPageRect.right = rcPage.right;        
      m_aInst.MathHelper.Rect_Transform(ref p2v, ref rc);
      m_aInst.MathHelper.Rect_Transform(ref p2v, ref rcPageRect);  

      //Flipping rectangle top and bottom coordinates and converting it's type
      PDFXEdit.tagRECT rcDR;
      rcDR.left = (int)rc.left;
      rcDR.right = (int)rc.right;
      rcDR.top = (int)rc.bottom;
      rcDR.bottom = (int)rc.top;

      PDFXEdit.tagRECT rcDRPage;
      rcDRPage.left = (int)rcPageRect.left;
      rcDRPage.right = (int)rcPageRect.right;
      rcDRPage.top = (int)rcPageRect.bottom;
      rcDRPage.bottom = (int)rcPageRect.top;

      pRC_.DrawRect(rcDR, m_Brush, m_Pen, ref rcDRPage, 1.0);   

      pRC_.DrawRect(rcDR, m_Brush, m_Pen, ref rcDR, 1.0);
   }
Having this, I got a small rectangle at the bottom left of the page.
Note that 1.0 is used instead of 1
I checked the interop wrapers and both are the same.
[DispId(1610743821)]

Code: Select all

void DrawRect(ref tagRECT stRect, IUIX_Brush pBrush, IUIX_Pen pPen, ref tagRECT stClipRect, double nOpacity = 1);
I think you'd know about this. default parameters in DevStudio 10 will not work. they will be transferred as 0 instead of 1

But please, tell me how to draw rect over the Page bound? My code above not working to draw rec on entire page.

Re: Watermark

Posted: Fri Jun 09, 2017 2:55 pm
by Sasha - Tracker Dev Team
That's because you have not taken the needed page's rectangle:

Code: Select all

public void DrawRectangle(PDFXEdit.IPXV_PagesView pView, PDFXEdit.IUIX_RenderContext pRC_, uint nPage)
{
	PDFXEdit.IPXV_PagesLayoutManager plm = pView.Layout;
	if (plm == null)
		return;

	PDFXEdit.PXC_Matrix p2v = plm.GetPageToDeviceMatrix(nPage, true);
	PDFXEdit.IPXC_Page page = pView.DocView.Doc.CoreDoc.Pages[nPage];
	PDFXEdit.PXC_Rect rc = page.get_Box(PXC_BoxType.PBox_PageBox); ;// = m_rcDraw;
	m_aInst.MathHelper.Rect_Transform(ref p2v, ref rc);

	//Flipping rectangle top and bottom coordinates and converting it's type
	PDFXEdit.tagRECT rcDR;
	rcDR.left = (int)rc.left;
	rcDR.right = (int)rc.right;
	rcDR.top = (int)rc.bottom;
	rcDR.bottom = (int)rc.top;

	pRC_.DrawRect(rcDR, m_Brush, m_Pen, ref rcDR, 1);
}
Cheers,
Alex

Re: Watermark

Posted: Fri Jun 09, 2017 3:14 pm
by Yury
Ok. Thank you. works.
But What is the

Code: Select all

 pPageRegions[i].rcPageRect
?
I thought this is also page rectangle.....

Re: Watermark

Posted: Mon Jun 12, 2017 9:50 am
by Sasha - Tracker Dev Team
Hello Yury,

I've updated the description of this structure:
https://sdkhelp.pdf-xchange.com/vie ... youtRegion

Cheers,
Alex

Re: Watermark

Posted: Tue Jun 13, 2017 11:43 am
by Yury
Thanks Alex.
Could you please also point me to some description or sample on how to use pRC_.DrawString(
What I really need is draw Watermark string through the each page of the document. ( opacity is needed )

Thanks again!

Re: Watermark

Posted: Tue Jun 13, 2017 11:50 am
by Sasha - Tracker Dev Team
Hello Yury,

Check out this sample:
https://github.com/tracker-software/PDFCoreSDKExamples

Cheers,
Alex

Re: Watermark

Posted: Tue Jun 13, 2017 1:23 pm
by Yury
Alex, I'm unable to build this sample. It seems uses VS2105.
Also, it is CoreAPI sample and uses different interfaces than IUIX_RenderContext.

I've spent a lot of time trying to implement simple things with your SDK. This is because it is not documented. This is not my fault.
Could you please give me example on how to do what I need.

I need draw watermark text through the pages. I'm using the RenderContext interface, as you've suggested in your previous posts.

Thanks.

Re: Watermark

Posted: Tue Jun 13, 2017 2:25 pm
by Sasha - Tracker Dev Team
Hello Yury,

Well that method is majorly self-explanatory, though I've updated it's description:
https://sdkhelp.pdf-xchange.com/vie ... DrawString
Basically one problem that you could struggle with is how to obtain the IUIX_Font - though there are the samples for that in the FullDemo application:

Code: Select all

PDFXEdit.IUIX_Theme th = uiInst.Theme;
PDFXEdit.IUIX_Font fnt = th.StdFont[PDFXEdit.UIX_StdFont.UIX_StdFont_Default];
Cheers,
Alex

Re: Watermark

Posted: Wed Jun 14, 2017 1:20 pm
by Yury
Hello, thank you. I could draw text.

How can I draw image? I tried to use

Code: Select all

IStreamWrapper
class, which is described in some of your posts, but failed.
What I have is .Net Bitmap ( Image ) object.
I need to convert it to PDFXEdit.IUIX_ImageData, so I could use it in pRC_.DrawImage(.
How can I do this?

Code: Select all

System.IO.MemoryStream memStream = new System.IO.MemoryStream();
       watermark.Save( memStream, System.Drawing.Imaging.ImageFormat.Png );
       PDFXEditor.IStreamWrapper sw = new PDFXEditor.IStreamWrapper(memStream);
       _imgWatermark = m_uiInst.CreateImageFromIStream((IStream)sw);
This code produced type cast exception in last row.

Re: Watermark

Posted: Wed Jun 14, 2017 2:57 pm
by Sasha - Tracker Dev Team
Hello Yury,

Here's a code sample for you to experiment with:

Code: Select all

public void DrawImage(PDFXEdit.IPXV_PagesView pView, PDFXEdit.IUIX_RenderContext pRC_, uint nPage)
{
	PDFXEdit.IPXV_PagesLayoutManager plm = pView.Layout;
	PDFXEdit.PXC_Matrix p2v = plm.GetPageToDeviceMatrix(nPage, true);
	PDFXEdit.IPXC_Page page = pView.DocView.Doc.CoreDoc.Pages[nPage];
	PDFXEdit.PXC_Rect rcPage = page.get_Box(PXC_BoxType.PBox_PageBox); ;// = m_rcDraw;
	m_aInst.MathHelper.Rect_Transform(ref p2v, ref rcPage);
	PDFXEdit.tagRECT rcTagPage;
	rcTagPage.left = (int)rcPage.left;
	rcTagPage.top = (int)rcPage.bottom;
	rcTagPage.bottom = (int)rcPage.top;
	rcTagPage.right = (int)rcPage.right;


	//image = (Bitmap)Bitmap.FromFile(@"D:\PageImage.bmp");
	Rectangle rect = new Rectangle(0, 0, image.Width, image.Height);
	System.Drawing.Imaging.BitmapData bmpData = image.LockBits(rect, ImageLockMode.ReadWrite, image.PixelFormat);
	IUIX_ImageData iData = m_uiInst.CreateNewImage(image.Width, image.Height);
	// Get the address of the first line.
	IntPtr ptr = bmpData.Scan0;
	// Declare an array to hold the bytes of the bitmap.
	int bytes = Math.Abs(bmpData.Stride) * image.Height;
	byte[] rgbValues = new byte[bytes];

	IntPtr outPtr = new IntPtr(iData.Scan0);
	// Copy the RGB values into the array.
	System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
	// Copy the RGB values back to the bitmap
	System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, outPtr, bytes);
	// Unlock the bits.
	image.UnlockBits(bmpData);
	PDFXEdit.tagRECT rcImage;
	rcImage.left = 0;
	rcImage.right = image.Width;
	rcImage.bottom = image.Height;
	rcImage.top = 0;
	pRC_.DrawImage(iData, rcTagPage, rcImage, rcTagPage, (int)UIX_ImageScaleTypes.UIX_ImageScale_Stretch, (int)UIX_ImageScaleTypes.UIX_ImageScale_Stretch);
}
Cheers,
Alex