How to PXC_Destination.dValues for a GoTo link annotation when the target page is rotated?  SOLVED

PDF-XChange Editor SDK for Developers

Moderators: TrackerSupp-Daniel, Tracker Support, Paul - Tracker Supp, Vasyl-Tracker Dev Team, Chris - Tracker Supp, Sean - Tracker, Ivan - Tracker Software, Tracker Supp-Stefan

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.
zarkogajic
User
Posts: 1372
Joined: Thu Sep 05, 2019 12:35 pm

How to PXC_Destination.dValues for a GoTo link annotation when the target page is rotated?

Post by zarkogajic »

Hi Support,

I'm adding a GoTo link annotation onto a page targeting a different page. Setting Dest_XYZ, nNullFlags == 12 (inherit all except x,y).

All works well if the target page is not rotated (IPXC_Page.GetRotation = 0)

Pseudo code used :

Code: Select all

IPXV_PagesLayoutManager lay.GetPageSize(42, pageWidth, pageHeight);
PXC_Destination annotDest.dValues[0] := 0;
PXC_Destination annotDest.dValues[1] := pageHeight;
The above works as expected if page 42 (actually 43, ofc) is not rotated.

BUT, if "42".Get_Rotation() != 0 -> the annotation does not point correctly.


I know I would need to take the target page rotation into calculation - just do not know how / what. I guess dValues need be "fixed" by rotation ...

p.s.
I know of IPXC_Page::GetMatrix and Matrix_Rotate but I'm not sure how to use that to have correct dValues for PXC_Destination ....

-žarko
zarkogajic
User
Posts: 1372
Joined: Thu Sep 05, 2019 12:35 pm

Re: How to PXC_Destination.dValues for a GoTo link annotation when the target page is rotated?

Post by zarkogajic »

Hi Support,

Upon further investigation: the rotation can be either 90, 180 or 270. So, to point to the "top" of the page I can "fix" dValues manually. For example if the page is rotated 270, dValues[0] should be set to page_height and dvalues[1] should be page_width - so to set the destination to the top of that page.

Such hard coding works as expected - I just thought there will be some ready made method in IMathHelper to help with page rotations...

Are there?

-žarko
Last edited by zarkogajic on Wed Jul 26, 2023 3:00 pm, edited 1 time in total.
User avatar
Tracker Supp-Stefan
Site Admin
Posts: 17960
Joined: Mon Jan 12, 2009 8:07 am
Location: London

Re: How to PXC_Destination.dValues for a GoTo link annotation when the target page is rotated?

Post by Tracker Supp-Stefan »

Hello zarkogajic,

Glad to hear you found a solution with "hard coding" things, and I will ask our devs to post some further info if there is an easier way to do it with the IMathHelper or any other method!

Kind regards,
Stefan
zarkogajic
User
Posts: 1372
Joined: Thu Sep 05, 2019 12:35 pm

Re: How to PXC_Destination.dValues for a GoTo link annotation when the target page is rotated?

Post by zarkogajic »

Hi,

Any more info from devs?

-žarko
User avatar
Tracker Supp-Stefan
Site Admin
Posts: 17960
Joined: Mon Jan 12, 2009 8:07 am
Location: London

Re: How to PXC_Destination.dValues for a GoTo link annotation when the target page is rotated?

Post by Tracker Supp-Stefan »

Hello zarkogajic,

I am asking my colleagues again - and I hope we will have some further info for you alter today.

Kind regards,
Stefan
User avatar
Vasyl-Tracker Dev Team
Site Admin
Posts: 2353
Joined: Thu Jun 30, 2005 4:11 pm
Location: Canada

Re: How to PXC_Destination.dValues for a GoTo link annotation when the target page is rotated?

Post by Vasyl-Tracker Dev Team »

Hi Zarko.

Seems this one may help you:

Code: Select all

PXC_Matrix pm = page.GetMatrix(PXC_BoxType.PBox_PageBox);

IPXC_Annotation annot = page.GetAnnot(0);
PXC_Rect rc = annot.get_Rect();

IMathHelper math = auxInst.MathHelper;
math.Rect_Transform(pm, ref rc); // rotates annot's rect according to page's rotation

PXC_Point pt;
pt.x = rc.left;
pt.y = rc.top;

PXC_Matrix ipm = math.Matrix_Invert(pm);
ipm.Point_Transform(ref pt); // translates 'visual' left/top to the corresponding point in the page's coord. space

PXC_Destination d = new PXC_Destination();
d.nType = PXC_DestType.Dest_XYZ;
d.nPageNum = page.Number;

d.dValues[0] = pt.x; // X
d.dValues[1] = pt.y; // Y
d.dValues[2] = 1; // Zoom
d.nNullFlags = 4; // inherit Zoom, 1 - inherit X, 2 - inherit Y; for example, you may specify 3 to inherit X and Y but no Zoom (3 == 1 | 2) 
Cheers.
Vasyl Yaremyn
Tracker Software Products
Project Developer

Please archive any files posted to a ZIP, 7z or RAR file or they will be removed and not posted.
zarkogajic
User
Posts: 1372
Joined: Thu Sep 05, 2019 12:35 pm

Re: How to PXC_Destination.dValues for a GoTo link annotation when the target page is rotated?

Post by zarkogajic »

Hi Vasyl,

Thanks, but not the problem I have here.

The problem is not the rectangle of the annotation (where the annotation is) but the destination location (X/Y). I'm creating a new link from a non-rotated page to a rotated page.

I'm using Dest_XYZ, setting target page number, X and Y and inherit all the rest (actually only zoom applies here to be inherited). When the link points to a non-rotated page, the values to use would be dValues[0] == X := 0; dValues[1] = Y := height_of_target_page. This points to the top of the targeted page (inheriting zoom).

This works well if the targeted page is not rotated.

If the targeted page is rotated 270, then X (dValues[0]) needs to be set to target_page-HEIGHT and Y (dValues[1]) needs to be target_page-WIDTH. That's what common math would give (when rotating the below rect rectangle)

For a non rotated A4 page, we can say that its rectangle is (where rect.left and rect.top can be used for X and Y in dValues) :

rect.left =0
rect.top = page_height /* 595,2 */
rect.bottom = 0
rect.right = page_width /* 841,92 */

I would want such a rectangle be translated / rotated taking into account the actual target page rotation.

For a 270 rotated page the page matrix looks like:

a = 0; b = 1; c = -1; d = 0; e = 595,2; f = -0

If I then do Rect_Transform applying that matrix to the rect. The resulting rect values look like:

rect.left = -246,72
rect.top = 595,2
rect.bottom = 0
rect.right = 595,2

The resulting Left and Top are not the ones I need for X==dValues[0] and Y==dValues[1]

I must be missing something or something is not working how (I think) it should.

p.s.
Using 9.4.363 version if that is relevant.

-žarko
User avatar
Vasyl-Tracker Dev Team
Site Admin
Posts: 2353
Joined: Thu Jun 30, 2005 4:11 pm
Location: Canada

Re: How to PXC_Destination.dValues for a GoTo link annotation when the target page is rotated?

Post by Vasyl-Tracker Dev Team »

Hi Zarko.

I corrected my code snippet above because it was incomplete. It had missed the important step about using the inverted page-matrix to translate the visual point back to the page's coord-space (the 'ipm' matrix usage in that code).

Also, for your case, when you need to navigate to the left/top of specified page - you need to use the whole page-rectangle you may get via simple:
PXC_Rect pageRect = targetPage.get_Box(PXC_BoxType.PBox_PageBox);

HTH.
Vasyl Yaremyn
Tracker Software Products
Project Developer

Please archive any files posted to a ZIP, 7z or RAR file or they will be removed and not posted.
zarkogajic
User
Posts: 1372
Joined: Thu Sep 05, 2019 12:35 pm

Re: How to PXC_Destination.dValues for a GoTo link annotation when the target page is rotated?

Post by zarkogajic »

Hi Vasyl,

Thanks, but it seems still something's missing or not working as expected.

Here's my (pseudo) code with real returned values :

Code: Select all

//page displays as A4 portrait
IPXC_Page targetPage = ... //the 270 rotated page  where the link needs to point to top/left -> top of the page, normally that would be 0, pageHeight

PXC_Rect pageBoxRect = targetPage.Get_Box(PBox_PageBox); 
// -> Left = 0, Bottom = 0, Right = 842, Top = 596 -> this already smells as rotated why is Right > Top ?!

PXC_Matrix pageMatrix = targetPage.GetMatrix(PBox_PageBox);
//-> a = 0; b = 1; c = -1; d = 0; e = 596; f = -0

PXC_Point 
  ptPage.x := pageBoxRect.left; //0
  ptPage.y := pageBoxRect.top; //596 ?! Expecting 842

PXC_Matrix invertedPageMatrix = MathHelper.Matrix_Invert(pageMatrix);
//-> a = 0; b = -1; c = 1; d = 0; e = 0; f = 596

MathHelper.Point_Transform(invertedPageMatrix, ptPage);
The Point_Transform result:

ptPage. x = 596
ptPage. Y = 596

So, not the values I should use for dValues[0] and dValues [1].

Expected values:

ptPage. x = 842
ptPage. Y = 596

p.s.
I have rounded the PT values here 595,2 = 596.

-žarko
User avatar
Vasyl-Tracker Dev Team
Site Admin
Posts: 2353
Joined: Thu Jun 30, 2005 4:11 pm
Location: Canada

Re: How to PXC_Destination.dValues for a GoTo link annotation when the target page is rotated?

Post by Vasyl-Tracker Dev Team »

In your pseudocode you missed one important step:

...
PXC_Matrix pageMatrix = targetPage.GetMatrix(PBox_PageBox);

MathHelper.Rect_Transform(pageMatrix, pageBoxRect); // this one is missed!

PXC_Point
ptPage.x := pageBoxRect.left;
ptPage.y := pageBoxRect.top;
...
Vasyl Yaremyn
Tracker Software Products
Project Developer

Please archive any files posted to a ZIP, 7z or RAR file or they will be removed and not posted.
zarkogajic
User
Posts: 1372
Joined: Thu Sep 05, 2019 12:35 pm

Re: How to PXC_Destination.dValues for a GoTo link annotation when the target page is rotated?  SOLVED

Post by zarkogajic »

Hi Vasyl,

Thanks, yes, missed that one ...

Anyhow, here's the full needed code (for future readers):

Code: Select all

//pseudo

IPXC_Page targetPage = ... //the rotated page  where the link needs to point to top/left -> top of the page, normally that would be 0, pageHeight

PXC_Rect pageBoxRect = targetPage.Get_Box(PBox_PageBox); 

PXC_Matrix pageMatrix = targetPage.GetMatrix(PBox_PageBox);

MathHelper.Rect_Transform(pageMatrix, pageBoxRect);

PXC_Point 
  ptPage.x := pageBoxRect.left; 
  ptPage.y := pageBoxRect.top; 
  
PXC_Matrix invertedPageMatrix = MathHelper.Matrix_Invert(pageMatrix);

MathHelper.Point_Transform(invertedPageMatrix, ptPage);

PXC_Destination annotDest;
annotDest.dValues[0] := ptPage.X;
annotDest.dValues[1] := ptPage.Y;

p.s.
Ofc, can be used even if the tartgetPage is NOT rotated...

User avatar
Dimitar - Tracker Supp
Site Admin
Posts: 1797
Joined: Mon Jan 15, 2018 9:01 am

How to PXC_Destination.dValues for a GoTo link annotation when the target page is rotated?

Post by Dimitar - Tracker Supp »

:)