Problem with bookmark navigation on rotated pages

145 views
Skip to first unread message

Give Us A Freaking Break

unread,
May 2, 2017, 12:50:55 PM5/2/17
to PDFTron WebViewer
Hello.

We were having a tiny problem going to the correct page when the user clicked on a bookmark that pointed to a page with rotation. We have temp-fixed it with some hack, but it would be nice if you could do something about it. :)
We are using PdfTron WebViewer v.2.2.0.
This was our fix:

var pn = bookmark.getPageNumber(),
    viewer = me.docViewer,
    rot = viewer.getCompleteRotation(pn);
 
if (rot % 4 === 2) {
    var nameVPos = getBookmarkVPosPropName(bookmark); // Get minified property name.
    if (nameVPos !== null) bookmark[nameVPos] = viewer.getDocument().getPageInfo(pn - 1).height;
} else if (rot % 4 === 3) {
    var nameHPos = getBookmarkHPosPropName(bookmark); // Get minified property name.
    if (nameHPos !== null) bookmark[nameHPos] = viewer.getDocument().getPageInfo(pn - 1).height;
}
I am not sure if you have fixed that already.

Thanks,
Kostas

Justin Jung

unread,
May 2, 2017, 7:07:48 PM5/2/17
to PDFTron WebViewer
Hello,

WebViewer has the same behaviour as Acrobat when jumping to bookmarks when the page is rotated. You are welcome to use custom methods to adjust this behaviour if you like!

Justin Jung
Software Developer
PDFTron Systems Inc.

Give Us A Freaking Break

unread,
May 5, 2017, 12:21:42 PM5/5/17
to PDFTron WebViewer
OK.
Thanks.

Just another notice, for your information:

I have a -90 degrees (rotation = 3) document with annotations (I cannot share it unfortunately - but I think all similar docs will do that).
When printing it in a Chromium browser I see that the annotations are not in the right place and orientation.
I have tested that in your online showcase and it has the same issue.

Cheers! :)

Justin Jung

unread,
May 5, 2017, 6:44:00 PM5/5/17
to PDFTron WebViewer
Hello,

We are having trouble reproducing in the showcase. What are the exact steps to reproduce the issue? Which type of annotations have you tested with?

Give Us A Freaking Break

unread,
May 9, 2017, 12:01:05 PM5/9/17
to PDFTron WebViewer
Hello.

I have tried with the free hand annotation on the showcase, after uploading the document.

In our solution we have version 2.2.0 of the WebViewer and we have patched it with the latest code of function `loadPageLoop()` (inside BaseReaderControl.js) :


var pageNumber = pages[index];
var doc = me.docViewer.getDocument();
 
var originalDocumentRotation = (me.docViewer.getCompleteRotation(pageNumber) - me.docViewer.getRotation(pageNumber));
var pageInfo = doc.getPageInfo(pageNumber - 1);
var annotationRotationOffset = 0;
var rotation = 0;
if (orientation === me.pageOrientations.Portrait) {
    annotationRotationOffset = originalDocumentRotation;
    pageInfo = {
        width: pageInfo.height,
        height: pageInfo.width
    };
} else if (orientation === me.pageOrientations.Landscape) {
    rotation = 1;
    annotationRotationOffset = (originalDocumentRotation + 1) % 4;
    if (originalDocumentRotation !== 0) {
        pageInfo = {
            width: pageInfo.height,
            height: pageInfo.width
        };
    }
} else if (orientation === me.pageOrientations.Auto) {
    if (pageInfo.width > pageInfo.height) {
        if (originalDocumentRotation === 0) {
            rotation = 1;
            annotationRotationOffset = 1;
        } else {
            rotation = 4 - originalDocumentRotation;
        }
    }
}
var zoom = me.printFactor;
 
doc.loadCanvasAsync(pageNumber - 1, zoom, rotation, function(canvas) {
    // scale the canvas context so that annotations are drawn in the correct location
    var ctx = canvas.getContext('2d');
    ctx.scale(me.printFactor, me.printFactor);
 
    // transform the canvas context so that annotations are drawn in the correct location
    var t = window.GetPageMatrix(zoom, annotationRotationOffset, pageInfo);
    ctx.setTransform(t.m_a, t.m_b, t.m_c, t.m_d, t.m_h, t.m_v);
 
    me.docViewer.getAnnotationManager().drawAnnotations(pageNumber, canvas);
 
    dataurl = canvas.toDataURL();
 
    img = $('<img>')
        .attr('src', dataurl)
        .css({
            'max-height''100%',
            'max-width''100%'
        })
        .load(function() {
            if (!me.preparingForPrint) {
                return;
            }
            printDisplay.append(img);
            me.fireEvent('printProgressChanged', [index + 1, pages.length]);
            index++;
            if (index < pages.length) {
                loadPageLoop();
            } else {
                completeCallback(printDisplay);
                window.utils.unsetCanvasMultiplier();
                me.preparingForPrint = false;
            }
        });
 
    if (isInline) {
        img.css('display''block');
 
        if (index > 0) {
            img.css('page-break-after''always');
        }
    }
 
}, function() {}, 1);


And we still get the same behavior as in the showcase.
Here are some console tests I did:

var pg = 1;[readerControl.docViewer.getCompleteRotation(pg), readerControl.docViewer.getRotation(pg)]
  1. [30]

(All the document pages have this orientation)
Everything seems OK before printing, but when you select to print from the toolbar, the preview generated has all the annotations rotated and in the wrong place (we have some custom watermarks and page numbers, plus some user free-hand annotations).

I hope this helps.

Hm... I have now tested on another document with the same rotation and this problem does not appear to happen.
I am not 100% sure what is so special with this document.
I will let you know if I find something out...


Give Us A Freaking Break

unread,
May 9, 2017, 12:01:05 PM5/9/17
to PDFTron WebViewer

Here are the properties of the PDF document, if they help.

I have asked for permission to share the PDF file itself, but we will see if that's possible.

It seems to be a PDF with images of scanned documents.


Give Us A Freaking Break

unread,
May 16, 2017, 11:38:26 AM5/16/17
to PDFTron WebViewer
OK.
I am gonna send you the file. :)
Keep it private if possible, despite the fact that I got permission for sharing it.
Can you tell me in which private email to send it?

Justin Jung

unread,
May 16, 2017, 7:58:22 PM5/16/17
to PDFTron WebViewer
Hello,

You can send the document to sup...@pdftron.com.

Justin Jung

unread,
May 18, 2017, 1:53:04 PM5/18/17
to PDFTron WebViewer
Hello,

Thank you for sending us the document. To resolve the issue, you can replace prepareDocument function in BaseReaderControl.js with the following:

prepareDocument: function(pages, orientation, isInline, completeCallback) {
    var me = this;
    var printDisplay = isInline ? $('<div style="height: 100%; display: block"></div>') : $('#print-display');
    CoreControls.SetCanvasMode(CoreControls.CanvasMode.PageCanvas);
    printDisplay.empty();

    // draw all pages at 100% regardless of devicePixelRatio or other modifiers
    window.utils.setCanvasMultiplier(1);

    var index = 0;
    var dataurl, img;

    me.fireEvent('printProgressChanged', [0, pages.length]);
    loadPageLoop();
    function loadPageLoop() {
        var pageNumber = pages[index];
        var doc = me.docViewer.getDocument();
        var zoom = me.printFactor;
        var completeRotation =  me.docViewer.getCompleteRotation(pageNumber);
        var viewerRotation =  me.docViewer.getRotation(pageNumber);
        var width = doc.getPageInfo(pageNumber - 1).width;
        var height = doc.getPageInfo(pageNumber - 1).height;

        doc.loadCanvasAsync(pageNumber - 1, zoom, viewerRotation, function(canvas) {
            var ctx = canvas.getContext('2d');

            // transform the canvas context so that annotations are drawn in the correct location
            var rotation = completeRotation - viewerRotation;
            if (rotation < 0) {
                rotation += 4;
            }
            switch(rotation) {
                case 1:
                    ctx.translate(width, 0);
                    ctx.rotate(90 * Math.PI / 180);
                    break;
                case 2:
                    ctx.translate(width, height);
                    ctx.rotate(180 * Math.PI / 180);
                    break;
                case 3:
                    ctx.translate(0, height);
                    ctx.rotate(270 * Math.PI / 180);
                    break;
            }

            me.docViewer.getAnnotationManager().drawAnnotations(pageNumber, canvas);

            dataurl = canvas.toDataURL();

            img = $('<img>')
                .attr('src', dataurl)
                .css({
                    'max-height': '100%',
                    'max-width': '100%'
                })
                .on('load', function() {
                    if (!me.preparingForPrint) {
                        return;
                    }
                    printDisplay.append(img);
                    me.fireEvent('printProgressChanged', [index + 1, pages.length]);
                    index++;
                    if (index < pages.length) {
                        loadPageLoop();
                    } else {
                        completeCallback(printDisplay);
                        window.utils.unsetCanvasMultiplier();
                        me.preparingForPrint = false;
                    }
                });

            if (isInline) {
                img.css('display', 'block');

                if (index > 0) {
                    img.css('page-break-after', 'always');
                }
            }

        }, function() {}, 1);
    }
},

This change would be included in the next release as well.

Give Us A Freaking Break

unread,
May 24, 2017, 11:33:14 AM5/24/17
to PDFTron WebViewer
Thanks for the fix! :)

I have added something to it, taken form your previous fix, so that the printing occupies most of the page area when you print a document with pages rotated with various angles.
Let me know if you like it enough to make it part of the release (it seems working quite fine to me so far):


function loadPageLoop() {
    var pageNumber = pages[index];
    var doc = me.docViewer.getDocument();
    var zoom = me.printFactor;
    var completeRotation = me.docViewer.getCompleteRotation(pageNumber);
    var viewerRotation = me.docViewer.getRotation(pageNumber);
    var width = doc.getPageInfo(pageNumber - 1).width;
    var
 height = doc.getPageInfo(pageNumber - 1).height;
 
 
    var originalDocumentRotation = (me.docViewer.getCompleteRotation(pageNumber) - me.docViewer.getRotation(pageNumber));
    var pageInfo = doc.getPageInfo(pageNumber - 1);
    var viewerRotation2 = viewerRotation;
    // Assume browser uses portrait orientation and render with mode : orientation === me.pageOrientations.Auto.
    if (pageInfo.width > pageInfo.height) {
        if (originalDocumentRotation === 0) {
            viewerRotation2 = 1;
        } else {
            viewerRotation2 = 4 -originalDocumentRotation;
        }
    }
 
 
    var fixRotation = function (ctx, rotation) {
        rotation = (rotation + 4 * 4) % 4;
        switch (rotation) {
        case 1:
            ctx.translate(width, 0);
            ctx.rotate(90 * Math.PI / 180);
            break;
        case 2:
            ctx.translate(width, height);
            ctx.rotate(180 * Math.PI / 180);
            break;
        case 3:
            ctx.translate(0, height);
            ctx.rotate(270 * Math.PI / 180);
            break;
            }
    };
 
 
    doc.loadCanvasAsync(pageNumber - 1, zoom, viewerRotation2, function(canvas) {
        var ctx = canvas.getContext('2d');
        var t = window.GetPageMatrix(zoom, 1, pageInfo);
 
        // transform the canvas context so that annotations are drawn in the correct location
        var rotation = completeRotation - viewerRotation;
        if
 (rotation < 0) {
            rotation += 4;
        }
        fixRotation(ctx, rotation);
 
        me.docViewer.getAnnotationManager().drawAnnotations(pageNumber, canvas);
 
        dataurl = canvas.toDataURL();
 
        img = $('<img>')
            .attr('src', dataurl)
            .css({
                'max-height''100%',
                'max-width''100%'

Justin Jung

unread,
May 25, 2017, 3:02:53 PM5/25/17
to PDFTron WebViewer
Thanks for the suggestion!
We will consider it for a future version :)
Reply all
Reply to author
Forward
0 new messages