Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limit the size of canvases to 5MP (iOS restriction) #4834

Merged
merged 1 commit into from Jun 13, 2014
Merged

Limit the size of canvases to 5MP (iOS restriction) #4834

merged 1 commit into from Jun 13, 2014

Conversation

ghost
Copy link

@ghost ghost commented May 24, 2014

This is an attempt to fix #2439 and maybe some other related issues.
It seems to work for me but more tests are definitely needed.

ctx.scale(outputScale.sx, outputScale.sy);
ctx._scaleX = outputScale.sx * correctiveScale.sx;
ctx._scaleY = outputScale.sy * correctiveScale.sy;
if (outputScale.scaled | correctiveScale.scaled) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it be || instead of |?

@Snuffleupagus
Copy link
Collaborator

Limiting the canvas size should generally be a good thing, but isn't there a risk that hard-coding one value that will apply to all platforms/devices could cause unnecessary restrictions (e.g. blurry canvases at higher zoom levels on desktop)?

Perhaps we could instead introduce e.g. PDFJS.maxCanvasPixels placed in src/display/api.js and letting it default to some reasonable value for most desktop computers? Then you could add an entry in web/compatibility.js that reduces this value for iOS (and other platforms as necessary).

@ghost
Copy link
Author

ghost commented May 24, 2014

Done.
I propose 67108864 (8192*8192) as a default value. It is possible to set it to -1 to deactivate this feature.

@Snuffleupagus
Copy link
Collaborator

/botio-linux preview

@pdfjsbot
Copy link

From: Bot.io (Linux)


Received

Command cmd_preview from @Snuffleupagus received. Current queue size: 0

Live output at: http://107.21.233.14:8877/bcf0b4658e5764b/output.txt

@@ -134,6 +134,14 @@ PDFJS.verbosity = (PDFJS.verbosity === undefined ?
PDFJS.VERBOSITY_LEVELS.warnings : PDFJS.verbosity);

/**
* The maximum supported canvas size in total pixels e.g. width * height.
* Use -1 for no limit.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps also add a comment about the default value, i.e. something like this:

* The default value is 8192 * 8192. Use -1 for no limit.

@ghost
Copy link
Author

ghost commented May 24, 2014

Done.

canvas.width = (Math.floor(viewport.width) * outputScale.sx) | 0;
canvas.height = (Math.floor(viewport.height) * outputScale.sy) | 0;
canvas.width = (
Math.floor(viewport.width) * outputScale.sx * correctiveScale.sy
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo at the end of the line, should be correctiveScale.sx.

@ghost
Copy link
Author

ghost commented May 24, 2014

Oops. Sorry.

@yurydelendik yurydelendik added this to the 2014 Q2 milestone May 26, 2014
@ghost
Copy link
Author

ghost commented May 27, 2014

Rebased.

correctiveScale.sy = maxScale / outputScale.sy;
correctiveScale.scaled = true;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the entire diff, I have feeling that this code (above and below) can be simplified to something like:

    var pixelsInViewport = viewport.width * viewport.height;
    if (PDFJS.maxCanvasPixels > 0 && pixelsInViewport > PDFJS.maxCanvasPixels) {
      var correction = Math.sqrt(PDFJS.maxCanvasPixels / pixelsInViewport);
      outputScale.sx *= correction;
      outputScale.sy *= correction;
      outputScale.scaled = true;
    }

@yurydelendik
Copy link
Contributor

At https://github.com/dferer/pdf.js/blob/canvas-max-size/web/page_view.js#L122, can we check if we are already showing corrected css scale and canvas size if still at max viewport pixel to update only transform?

@yurydelendik
Copy link
Contributor

Really nice. I think with this patch we can also increase MAX_SCALE value a little (e.g. up to 10?)

@Snuffleupagus
Copy link
Collaborator

I think with this patch we can also increase MAX_SCALE value a little (e.g. up to 10?)

That would mean that we'd also fix https://bugzilla.mozilla.org/show_bug.cgi?id=827496 at the same time.

@ghost
Copy link
Author

ghost commented May 30, 2014

I think I addressed all your remarks.
The new data-restricted-scaling attribute on the canvas is an attempt at limiting the amount of recalculations. I kept the code in comments in case you don't like the data attribute. Just tell me what you prefer.
The combination of MAX_SCALE=10 and maxCanvasPixels=67108864 brought my laptop (a recent MBPr with 16GB RAM) to its limits when zooming on even very simple pages. I left it, but I think one of those values should be lowered.

@Snuffleupagus
Copy link
Collaborator

/botio-windows preview

@pdfjsbot
Copy link

From: Bot.io (Windows)


Received

Command cmd_preview from @Snuffleupagus received. Current queue size: 0

Live output at: http://107.22.172.223:8877/9a06581fa49e880/output.txt

@Snuffleupagus
Copy link
Collaborator

The combination of MAX_SCALE=10 and maxCanvasPixels=67108864 brought my laptop (a recent MBPr with 16GB RAM) to its limits when zooming on even very simple pages.

Apart from huge memory consumption, I'm also seeing rendering issues similar to those of #605 at zoom levels around 800 % (on Windows). So we might indeed want to limit the maximum values somewhat.

Edit: Just wanted to point out that the rendering issues mentioned above are in no way caused by the PR.

@yurydelendik
Copy link
Contributor

Try 4096x4096 which will be max webgl texture size. (400dpi for 10x10inch printed material)

@ghost
Copy link
Author

ghost commented May 30, 2014

Done

@yurydelendik yurydelendik modified the milestone: 2014 Q2 Jun 10, 2014
@yurydelendik yurydelendik self-assigned this Jun 10, 2014
@CodingFabian
Copy link
Contributor

let me paste this info here for completeness. I was wondering why I can see in chrome profilings the drawImage for thumbnails, but not the ones for the main content.
It turns out that chrome has a problem here:
https://code.google.com/p/chromium/issues/detail?id=170021
The bug confirms the max texture size being 4096x4096.

The one intel guy says that it is not really a use case to copy from a large canvas to a small canvas. Maybe one of you guys want to comment there that pdfjs has this use case?

@yurydelendik
Copy link
Contributor

@dferer this looks really good. Can we use internal attributeproperty for the page object instead of canvas.setAttribute('data-restricted-scaling', true); ?

@ghost
Copy link
Author

ghost commented Jun 12, 2014

@yurydelendik Something like this?

@yurydelendik
Copy link
Contributor

yes, thank you

/botio-linux preview

@pdfjsbot
Copy link

From: Bot.io (Linux)


Received

Command cmd_preview from @yurydelendik received. Current queue size: 3

Live output at: http://107.21.233.14:8877/ed642fe4325a78a/output.txt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

iPad zoom doesn't work properly
4 participants