Add Overlay via code

PDF-XChange Editor SDK for Developers

Moderators: PDF-XChange Support, Daniel - PDF-XChange, Chris - PDF-XChange, Sean - PDF-XChange, Paul - PDF-XChange, Vasyl - PDF-XChange, Ivan - Tracker Software, Stefan - PDF-XChange

Forum rules
DO NOT post your license/serial key, or your activation code - these forums, and all posts within, are public and we will be forced to immediately deactivate your license.

When experiencing some errors, use the IAUX_Inst::FormatHRESULT method to see their description and include it in your post along with the error code.
lidds
User
Posts: 534
Joined: Sat May 16, 2009 1:55 pm

Add Overlay via code

Post by lidds »

Is there a way to do the following:
1. Add an overlay PDF document using code?
2. Change the overlay PDF content to a light grey, etc., so the user can differentiate between the two PDFs.

I have attached a screenshot with further explanation.
PDFXChangeOverlay.jpg
It seems that this can be achieved using a Background PDF file. However, I need the ability to toggle visibility of the second PDF and the Background option does not allow it to be added to a Layer to achieve this.
Background.jpg
Thanks

Simon
You do not have the required permissions to view the files attached to this post.
User avatar
MishaH
User
Posts: 29
Joined: Wed Sep 11, 2024 1:43 pm

Re: Add Overlay via code

Post by MishaH »

Hello Simon,

1. You can use the op.layers.importAsLayerOverlay operation to add an overlay PDF as a separate layer that can be toggled on and off.

2. The ‘Overlay Pages’ feature also lets you recolor both the base and overlay content (see the ‘Color’ options in the dialog). Here’s an example showing how to compare two PDFs by adjusting colors: viewtopic.php?p=193211#p193211

I hope this helps!

Kind regards,
Misha
lidds
User
Posts: 534
Joined: Sat May 16, 2009 1:55 pm

Re: Add Overlay via code

Post by lidds »

Hi Misha,

Thank you for your reply.

I think I did not clearly explain my scenario properly.

I do not want to compare the 2 PDF files as my solution mainly uses engineering drawings (limited text) and therefore PDFXChange is unable to compare the difference as this will be non-textural changes.

Therefore, what I want to achieve is the following:

1. The user loads the PDF drawing document. This will be black and white with the content being black.
2. I want to then load the previous version of the document, which is stored in my application, but this document needs to be loaded in greyscale. FYI the previous document is copied locally on the users machine, so does allow for pre-processing prior to loading.
3. As explained in my post, I would like this greyscale document to be loading as a layer so I can easily turn on and off visibility.

With this explained is this achievable via code?

Thanks

Simon
User avatar
MishaH
User
Posts: 29
Joined: Wed Sep 11, 2024 1:43 pm

Re: Add Overlay via code

Post by MishaH »

Hello Simon,

Thank you for providing a more detailed explanation of your scenario.

My apologies for the confusion caused by my use of the term compare. I mentioned it only as an example of a real and commonly used case of the color-change mechanism within the Overlay Pages feature, which is designed to visually highlight changes in a document (what was added, removed, or left unchanged).
I’d also like to clarify that the color modification applies to all document content, not only text. This is one possible way to achieve the grayscale appearance of your drawings. I think that would work well too.

Returning to your case — in your initial post you mentioned that you achieved the desired visual effect (making the content gray) by using the Add Background feature. From your settings, I can see that this was done by setting Opacity = 30%.

You can achieve the same effect with Overlay Pages by setting Opacity = 30% and enabling As Background. Additionally, this feature allows you to assign the overlay content to a new layer, which can then be easily managed (e.g., shown or hidden as needed).

Here’s a simple example:

Code: Select all

PDFXEdit.IOperation op = pdfCtl.Inst.CreateOp(pdfCtl.Inst.Str2ID("op.layers.importAsLayerOverlay"));
{
	PDFXEdit.CoAUX_Cab pr = op.Params.Root;
	pr["Input"].Add().v = pdfCtl.Doc;
	PDFXEdit.ICabNode opts = pr["Options"];

	// 1. Specify the source document
	opts["SrcSource"].v = "c:\\Test\\Test.pdf";

	// 2. Layer Options
	opts["LayerMode"].v = 0; //0 - add new; 2 - don`t create

	// 2.1 General layer property
	opts["NewLayerOpts"]["Name"].v = "New Layer";
	opts["NewLayerOpts"]["IsON"].v = true;	// is 'true' by default

	// 2.2 Additional layer property
	// opts["NewLayerOpts"]["IsLocked"].v = false; // is 'false' by default
	// opts["NewLayerOpts"]["VisibleOnView"].v = 1; // 0 - OFF, ON - 1, 2 - Undefined, is '1' by default
	// opts["NewLayerOpts"]["VisibleOnPrint"].v = 1; // same 
	// opts["NewLayerOpts"]["VisibleOnExport"].v = 1; // same
	// and many other options ...

	// 3. Specify which pages to use:
	// 3.1 from the source document
	opts["SourcePagesRange.Type"].v = "All";
	// 3.2 from the destination document
	opts["DestPagesRange.Type"].v = "All";

	// 4. Appearance & Placement
	opts["Opacity"].v = 30; // according to your example, to change to greyscale by reducing the transparency of the content
	opts["AsBackground"].v = true; // to place in the background

	// 5. Additional settings

	// 5.1 repeat of pages from the source document on the destination
	// opts["RepeatMode"].v = 0; // 0 - No, 1- last selected page, 2 - continuonus repeat pages; is '0' by default

	// 5.2 Actions with Objects
	// opts["CommentsAction"].v = 1; // 0 - copy, 1 - flatten, 2 - dont copy; is '1' by default
	// opts["FieldsAction"].v = 1; // 0 - copy, 1 - flatten, 2 - dont copy, 3 - copy with rename; is '1' by default

	// 5.3 Setting the color
	// opts["SourceColor"].v = "rgb(0.75,0.75,0.75)";	// is a light gray
								// (note that rgb notation is rgb(r,g,b) where r g b are float values from 0.0 to 1.0)
								// is 'A' (Auto - no changes) by default
}

op.Do();

Please let me know if this works for you.

Kind regards,
Misha
lidds
User
Posts: 534
Joined: Sat May 16, 2009 1:55 pm

Re: Add Overlay via code

Post by lidds »

Hi Misha,

Thank you very much for the code. This worked perfectly.

One last question, if I am using this code to add a layer using the below code:

options("NewLayerOpts")("Name").v = "PrevDocOverlay"

If I wanted to hide this layer by name using code, how would I do this?

Thanks

Simon
lidds
User
Posts: 534
Joined: Sat May 16, 2009 1:55 pm

Re: Add Overlay via code

Post by lidds »

I was wondering if someone is available to answer this question?

I would look at your documentation, but the HRESULT link is down.

Thank you in advance

Simon
User avatar
MishaH
User
Posts: 29
Joined: Wed Sep 11, 2024 1:43 pm

Re: Add Overlay via code

Post by MishaH »

Hi Simon,

Sorry for the delayed reply.

1. Regarding your question about hiding a layer by its name:
At the moment, we do provide layer manipulations for the end user, and only a very small part of that is available via the Core or Editor SDK.
However, the manipulations needed in your case are available through JavaScript.
Here is an example:

Code: Select all

var overlayLayer = this.getOCGs().filter(function(layer) {return layer.name === "PrevDocOverlay";})[0];
overlayLayer.state = false;
To execute this code, you should use the IPXV_Inst::ExecuteJS method.

I would also like to note that a layer’s name is not a unique identifier. The specification allows multiple layers in a document to share the same name.

2. You can check which HRESULT the exception returns using the IAUX_Inst::FormatHRESULT method.

I hope this helps.
Please let me know if this works for you.

Kind regards,
Misha
lidds
User
Posts: 534
Joined: Sat May 16, 2009 1:55 pm

Re: Add Overlay via code

Post by lidds »

Hi Misha,

Thank you for your response.

I have tried to implement the code, however, it does not seem to remove the layer overlay. I must be doing something wrong, would you mind reviewing the code.

The below code is how I am adding the overlay document

Code: Select all

    Public Function addPrevDocOverlay(ByVal docOID As Guid) As Boolean
        Try
            Dim nID As Integer = Me.docPreview.Inst.Str2ID("op.layers.importAsLayerOverlay", False)
            Dim Op As PDFXEdit.IOperation = Me.docPreview.Inst.CreateOp(nID)
            Dim input As PDFXEdit.ICabNode = Op.Params.Root("Input")
            input.v = Me.docPreview.Doc
            Dim options As PDFXEdit.ICabNode = Op.Params.Root("Options")

            options = Op.Params.Root("Options")
            options("SrcSource").v = MISData.Instance.LocalFileStorage & "\DocOverlay\" & docOID.ToString & ".pdf"
            options("LayerMode").v = 0
            options("NewLayerOpts")("Name").v = "PrevDocOverlay"
            options("NewLayerOpts")("IsON").v = True
            options("SourcePagesRange.Type").v = "All"
            options("DestPagesRange.Type").v = "All"
            options("Opacity").v = 30
            options("AsBackground").v = True
            Op.Do()

            Return True
        Catch ex As Exception
            MsgBox(ex.Message)

            Return False
        End Try
    End Function
The below code is what I am using to remove the overlay

Code: Select all

    Public Function remDocOverlay() As Boolean
        Try
            Dim sb As New StringBuilder()
            sb.AppendLine("var overlayLayer = this.getOCGs().filter(function(layer) {return layer.name === ""PrevDocOverlay"";})[0];")
            sb.AppendLine("overlayLayer.state = false;")

            Dim res As PDFXEdit.IString = Me.docPreview.Inst.CreateString()
            Me.docPreview.Inst.ExecuteJS(Me.docPreview.Doc, sb.ToString, Nothing, Nothing, Nothing, res)

            Return True
        Catch ex As Exception
            Debug.WriteLine("Error removing document overlay: " & convertErr(ex))

            Return False
        End Try
    End Function
Thanks

Simon
User avatar
MishaH
User
Posts: 29
Joined: Wed Sep 11, 2024 1:43 pm

Re: Add Overlay via code

Post by MishaH »

Hi Simon,

I’m not very experienced with VB, but it seems that this should work correctly according to the requirements you described.

However, one thing concerns me: in your original question you asked about hiding a layer, while in your latest message you refer to it being removed.
The provided code hides a layer by its name, which results in hiding the overlaid content, but does not remove it. Both the layer and the overlaid content remain in the document, and only visibility is changed to “hidden” within the current document session.

Please describe your workflow in more detail and clarify at which step the result does not match what you expect.

Kind regards,
Misha
lidds
User
Posts: 534
Joined: Sat May 16, 2009 1:55 pm

Re: Add Overlay via code

Post by lidds »

Hi Misha,

I think I have found the problem, the code to add the document as an overlay does not actually create a layer item on the document. Hence, the code does not hide the overlay layer because it does not exist.

Is there additional options I need to change on the addPrevDocOverlay function to achieve this?

Also, as mention previously, your http://sdkhelp.tracker-software.com/vie ... matHRESULT is not working.

Thanks

Simon
User avatar
MishaH
User
Posts: 29
Joined: Wed Sep 11, 2024 1:43 pm

Re: Add Overlay via code

Post by MishaH »

Hello again!

A quick update on this.

Thanks to your clarification that the layer is not being added, I noticed that I made a mistake in the previous description of the operation parameters.

Incorrect:
opts["LayerMode"].v = 0; //0 - add new; 2 - don't create

Correct version:
opts["LayerMode"].v = 1; //0 - don't create; 1 - add new

With this correction, the layer addition should work properly.
Please let me know if this works for you.

Kind regards,
Misha
lidds
User
Posts: 534
Joined: Sat May 16, 2009 1:55 pm

Re: Add Overlay via code

Post by lidds »

Hi Misha,

Thank you for such a quick response. This has resolved the issue of the overlap layer being hidden.

However, I now have another question.

The below code is what I have using to add the layer:

Code: Select all

Public Function addPrevDocOverlay(ByVal docOID As Guid) As Boolean
        Try
            Dim nID As Integer = Me.docPreview.Inst.Str2ID("op.layers.importAsLayerOverlay", False)
            Dim Op As PDFXEdit.IOperation = Me.docPreview.Inst.CreateOp(nID)
            Dim input As PDFXEdit.ICabNode = Op.Params.Root("Input")
            input.v = Me.docPreview.Doc
            Dim options As PDFXEdit.ICabNode = Op.Params.Root("Options")

            options = Op.Params.Root("Options")
            options("SrcSource").v = MISData.Instance.LocalFileStorage & "\DocOverlay\" & docOID.ToString & ".pdf"
            options("LayerMode").v = 0
            options("NewLayerOpts")("Name").v = "PrevDocOverlay"
            options("NewLayerOpts")("IsON").v = True
            options("SourcePagesRange.Type").v = "All"
            options("DestPagesRange.Type").v = "All"
            options("Opacity").v = 30
            options("AsBackground").v = True
            Op.Do()

            Return True
        Catch ex As Exception
            MsgBox(ex.Message)

            Return False
        End Try
    End Function
And the below code to hide the layer:

Code: Select all

    Public Function remDocOverlay() As Boolean
        Try
            Dim sb As New StringBuilder()
            sb.AppendLine("var overlayLayer = this.getOCGs().filter(function(layer) {return layer.name === ""PrevDocOverlay"";})[0];")
            sb.AppendLine("overlayLayer.state = false;")

            Dim res As PDFXEdit.IString = Me.docPreview.Inst.CreateString()
            Me.docPreview.Inst.ExecuteJS(Me.docPreview.Doc, sb.ToString, Nothing, Nothing, Nothing, res)

            Return True
        Catch ex As Exception
            Debug.WriteLine("Error removing document overlay: " & convertErr(ex))

            Return False
        End Try
    End Function
The problem I now have, is that if the user clicks on the toggle button the show the layer (which executes addPrevDocOverlay function) this adds a document as a layer. Then the user clicks the button to hide the layer(which executes remDocOverlay function), which hides the layer. If the user clicks the button again then the document is added again as another layer.

Is there a way that we can change the remDocOverlay function to DELETE the layer, therefore avoiding this? Or can I add some code to the addPrevDocOverlay function to see if the layer name exists and therefore not execute the code?

Thanks

Simon
lidds
User
Posts: 534
Joined: Sat May 16, 2009 1:55 pm

Re: Add Overlay via code

Post by lidds »

Hi Misha,

I resolved this using the following code.

Sharing with the community incase it is useful for others.

Code: Select all

Public Function addPrevDocOverlay(ByVal docOID As Guid) As Boolean
    Dim docModified As Boolean = MISData.Instance.frmDocDesigner.docPreview.Doc.Modified

    Try
        Dim sb As New StringBuilder()
        sb.AppendLine("var ocgs = this.getOCGs();")
        sb.AppendLine("res = ""NotFound"";")
        sb.AppendLine("if(ocgs) {")
        sb.AppendLine("  for(var i=0; i<ocgs.length; i++) {")
        sb.AppendLine("    if(ocgs[i].name === ""PrevDocOverlay"") {")
        sb.AppendLine("      res = ""Found"";")
        sb.AppendLine("    }")
        sb.AppendLine("  }")
        sb.AppendLine("}")

        Dim res As PDFXEdit.IString = Me.docPreview.Inst.CreateString()
        Me.docPreview.Inst.ExecuteJS(Me.docPreview.Doc, sb.ToString, Nothing, Nothing, Nothing, res)
        Dim tOutputJS As String = res.Value

        If tOutputJS = "NotFound" Then
            Dim nID As Integer = Me.docPreview.Inst.Str2ID("op.layers.importAsLayerOverlay", False)
            Dim Op As PDFXEdit.IOperation = Me.docPreview.Inst.CreateOp(nID)
            Dim input As PDFXEdit.ICabNode = Op.Params.Root("Input")
            input.v = Me.docPreview.Doc
            Dim options As PDFXEdit.ICabNode = Op.Params.Root("Options")

            options = Op.Params.Root("Options")
            options("SrcSource").v = MISData.Instance.LocalFileStorage & "\DocOverlay\" & docOID.ToString & ".pdf"
            options("LayerMode").v = 1
            options("NewLayerOpts")("Name").v = "PrevDocOverlay"
            options("NewLayerOpts")("IsON").v = True
            options("SourcePagesRange.Type").v = "All"
            options("DestPagesRange.Type").v = "All"
            options("Opacity").v = 30
            options("AsBackground").v = True
            Op.Do()
        Else
            sb = New StringBuilder()
            sb.AppendLine("var overlayLayer = this.getOCGs().filter(function(layer) {return layer.name === ""PrevDocOverlay"";})[0];")
            sb.AppendLine("overlayLayer.state = true;")

            res = Me.docPreview.Inst.CreateString()
            Me.docPreview.Inst.ExecuteJS(Me.docPreview.Doc, sb.ToString, Nothing, Nothing, Nothing, res)
        End If


        Return True
    Catch ex As Exception
        MsgBox(ex.Message)

        Return False
    Finally
        Me.docPreview.Doc.Modified = docModified
    End Try
Thank you, as always for the great support.

Thanks

Simon
User avatar
Daniel - PDF-XChange
Site Admin
Posts: 12524
Joined: Wed Jan 03, 2018 6:52 pm

Add Overlay via code

Post by Daniel - PDF-XChange »

:)
Dan McIntyre - Support Technician
PDF-XChange Co. LTD

+++++++++++++++++++++++++++++++++++
Our Web site domain and email address has changed as of 26/10/2023.
https://www.pdf-xchange.com
Support@pdf-xchange.com