1

I managed to rotate individual pages in a document, but I can't get any means of refreshing the page to work. I have to re-navigate to the page to see the effect of the rotation. Not the ideal scenario for our users.

MyPDFView code:

    public void RotatePage(int page)
    {
        Page.Rotate originalRotation = m_PdfDocument.GetPage(page).GetRotation();
        Page.Rotate rotation;

        switch (originalRotation)
        {
            case Page.Rotate.e_0: rotation = Page.Rotate.e_90; break;
            case Page.Rotate.e_90: rotation = Page.Rotate.e_180; break;
            case Page.Rotate.e_180: rotation = Page.Rotate.e_270; break;
            case Page.Rotate.e_270: rotation = Page.Rotate.e_0; break;
            default: rotation = Page.Rotate.e_0; break;
        }

        m_PdfDocument.GetPage(page).SetRotation(rotation);
    }

frmMain code:

    private void btnTurnView_ItemClick(object sender, ItemClickEventArgs e)
    {
        if (CurrentForm != null)
        {
            CurrentForm.p_m_oPDFViewCtrl.RotatePage(CurrentForm.p_m_oPDFViewCtrl.p_PageInfo.p_PageNumber);
        }
    }

Things I have tried so far: Invalidate(), Refresh(), Update() on different parts of the document/view. I could run a page analysis (similar to what happens on a page change) which probably fixes the issue, but brings unnecessary overhead, if there's a more efficient means, I would prefer relying on that instead.

Silvio Langereis
  • 487
  • 1
  • 11
  • 20

2 Answers2

1

Already found it, there's a method UpdatePageLayout() which does exactly that.

Silvio Langereis
  • 487
  • 1
  • 11
  • 20
1

There are actually two errors with the original code.

The first being the missing UpdatePageLayout.

The second, is missing concurrency locking, as you are modifying the document on one thread, while background threads are reading the document. Finally, there are now, in the latest versions, helper functions for adjusting rotations, so the whole switch block can be avoided.

So, the safer way to permanently rotate an individual page, while also viewing it in PDFViewCtrl, would be the following.

public void RotatePage(int page_number)
{
    mPDFView.DocLock(true); // lock the document for editing, and stop rendering
    try
    {
        Page page = mPDFView.GetDocument().GetPage(page_number);
        page.SetRotation(Page.AddRotations(Page.Rotate.e_90, page.GetRotation()));
    }
    finally
    {
        mPDFView.DocUnlock(); resume background threads
    }
    mPDFView.UpdatePageLayout();
}

Note, the document locking. Since you are accessing the document directly, you need to lock it (either read or write lock) so that background threads pause. Any calls on PDFViewCtrl itself already handle this. This document goes into more details.

Ryan
  • 2,473
  • 1
  • 11
  • 14
  • Thanks Ryan. I will add the additional lock tomorrow. Since we're still on an older SDK version, I won't be able to implement the helper function, but I will keep it as a reminder when we do update to the latest version (which should be very soon). – Silvio Langereis Apr 20 '17 at 19:28
  • I was able to fully implement the whole thing, helper functions included. Thanks again ! :) – Silvio Langereis Apr 21 '17 at 08:23