How to synchronize the content of PDFViewCtrl on two devices

Q:

Hi PDFNet Mobile support team,
I have a problem with the convClientPtToPagePt & convPagePtToClientPt methods.
My problem is the following:
I have two Android devices

  • Samsung Galaxy S (480x800)
  • Samsung Galaxy Nexus (720x1280)

and two applications: ServerApp and ClientApp. ServerApp runs on GalaxyNexus and ClientApp runs on Galaxy S.
Both applications show the same PDF, and when I scroll the pdf into the ClientApp, the ServerApp should be scroll the PDF in the same position of the upper left corner. ClientApp and ServerApp are connected with a socket.

In the ClientApp I perform:

double[] pdfP = mPDFView.convClientPtToPagePt(mPDFView.getScrollX(), mPDFView.getScrollY(), mPDFView.getCurrentPage());

PdfViewBean bean = new PdfViewBean(pdfP[0], pdfP[1], zoom, mPDFView.getCurrentPage());

In the ServerApp I receive the bean and I perform:

double [] scrolls = mPDFView.convPagePtToClientPt(bean.getPdfX(), bean.getPdfY(), bean.getPage());

if(mPDFView.getCurrentPage() != bean.getPage())mPDFView.setCurrentPage(bean.getPage());

double diffZoom = mPDFView.getZoom() / bean.getZoom();

mPDFView.scrollTo((int)(scrolls[0]/diffZoom), (int)(scrolls[1]/diffZoom));

But the upper left corner in the ServerApp isn’t in the same position of the ClientApp.

Basically I convert my upper left corner of the ClientApp into absolute coordinates (PagePt), and when I use the reverse method (convPagePtToClientPt) I would like to have the correct local coordinates into ServerApp (in ClientPt).

What is wrong?

A:

I think the problem here is that you got the zoom factor involved here incorrectly. First of all, it is helpful to understand the spaces used by PDFViewCtrl “conv” functions. It is detailed in the documentation and I am just copying it here for easy reference:

  • Client Space is the virtual area occupied by PDFViewCtrl on a device,
  • originated at its upper-left corner. Note that this space can extend
  • beyond the visible region. Client Space is in the same scale with the
  • dimensions of android.view.View;
  • Page Space is defined by a PDF page itself, originated at the
  • lower-left corner. Unlike Client Space, it is independent of how the page
  • is viewed; Namely, it does’t change with the zoom factor, the scroll
  • position, and etc.
  • (PDF) Canvas Space is defined as the smallest axis-aligned rectangle
  • surrounding all the pages in continuous page presentation mode, or the
  • current page(s) in non-continuous page presentation mode. For example,
  • PAGE_PRESENTATION_FACING_CONT will make a wider but shorter Canvas Space
  • than what PAGE_PRESENTATION_SINGLE_CONT will do. Note that PDF Canvas
  • Space is in the same scale of Page Space and also independent of zoom
  • factor, scroll position, etc. For simplicity, PDF Canvas Space is
  • referenced to as Canvas Space.
  • Zoomed PDF Canvas Space is similar to PDF Canvas space, but after it
  • is scaled by the current zoom factor, and page gaps are added between
  • pages.
  • View Canvas Space is the virtual region occupied by the its
  • android.graphics.Canvas object, the one passed in through the
  • onDraw(Canvas c) method. Note that View Canvas Space is in general
  • different from Canvas Space. For example, when PDFViewCtrl is zoomed out
  • so that all the pages are visible, View Canvas Space will be
  • larger than Canvas Space.
  • For example, if you want to know the coordinates of the upper-left corner
  • of the Canvas Space in the client space, you can simply use
  • convCanvasPtToClientPt(0,0). If you want to calculate the coordinates of
  • the lower-left corner of page 1 in the client space, you can use
  • convPagePtToClientPt(0, 0, 1). Or if you just want to know the
  • coordinates of the upper left corner of the Client Space in View
  • Canvas Space, it is simply (getScrollX(), getScrollY()).
  • You are right by using the page coordinates as the “absolute” position. The following is the sample code for the server side:

    if(mPDFView.getCurrentPage() != bean.getPage())mPDFView.setCurrentPage(bean.getPage());

    double x = bean.getPdfX();

    double y = bean.getPdfY();

    double [] pts = this.convPagePtToCanvasPt(x, y, bean.getPage()); //pts are in (PDF) Canvas Space

    double zoom = getZoom();

    x = pts[0] * zoom;

    y = pts[1] * zoom; //(x, y) is now in View Canvas Space

    this.scrollTo((int)x, (int)y);

    Note that the above code only shows how to synchronize the scroll positions, but not the zoom factor. If you want to do that, you should do that before synchronizing the scroll positions. Since the two devices have different screen size, the zoom factors on two devices should be synchronized in a relative sense.

    After zooming on client side, it should be:
    double old_zoom = getZoom();
    //now you change zoom
    double relative_zoom = getZoom() / old_zoom;
    //then put relative_zoom in bean

    Then on the server side, it should be:
    double relative_zoom = bean.getZoom();
    double new_zoom = relative_zoom * getZoom();
    PDFViewCtrl.this.setZoom(new_zoom):

    After this is done, you can apply the above code to adjust the scroll positions.