Skip to content

Commit

Permalink
Better CSS scaling for deviceRixelRatio != 1.
Browse files Browse the repository at this point in the history
  • Loading branch information
yurydelendik committed Oct 23, 2015
1 parent 2a15695 commit 0d8fcd3
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 6 deletions.
15 changes: 9 additions & 6 deletions web/pdf_page_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
* limitations under the License.
*/
/* globals RenderingStates, PDFJS, CustomStyle, CSS_UNITS, getOutputScale,
TextLayerBuilder, AnnotationsLayerBuilder, Promise */
TextLayerBuilder, AnnotationsLayerBuilder, Promise,
approximateFraction, roundToDivide */

'use strict';

Expand Down Expand Up @@ -315,7 +316,7 @@ var PDFPageView = (function PDFPageViewClosure() {
var outputScale = getOutputScale(ctx);

if (PDFJS.useOnlyCssZoom) {
var actualSizeViewport = viewport.clone({ scale: CSS_UNITS });
var actualSizeViewport = viewport.clone({scale: CSS_UNITS});
// Use a scale that will make the canvas be the original intended size
// of the page.
outputScale.sx *= actualSizeViewport.width / viewport.width;
Expand All @@ -336,10 +337,12 @@ var PDFPageView = (function PDFPageViewClosure() {
}
}

canvas.width = (Math.floor(viewport.width) * outputScale.sx) | 0;
canvas.height = (Math.floor(viewport.height) * outputScale.sy) | 0;
canvas.style.width = Math.floor(viewport.width) + 'px';
canvas.style.height = Math.floor(viewport.height) + 'px';
var sfx = approximateFraction(outputScale.sx);
var sfy = approximateFraction(outputScale.sy);
canvas.width = roundToDivide(viewport.width * outputScale.sx, sfx[0]);
canvas.height = roundToDivide(viewport.height * outputScale.sy, sfy[0]);
canvas.style.width = roundToDivide(viewport.width, sfx[1]) + 'px';
canvas.style.height = roundToDivide(viewport.height, sfy[1]) + 'px';
// Add the viewport so it's known what it was originally drawn with.
canvas._viewport = viewport;

Expand Down
49 changes: 49 additions & 0 deletions web/ui_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,55 @@ function binarySearchFirstItem(items, condition) {
return minIndex; /* === maxIndex */
}

/**
* Approximates float number as a fraction using Farley sequence (max order
* of 8).
* @param {number} x - Positive float number.
* @returns {Array} Estimated fraction: the first array item is a numerator,
* the second one is a denominator.
*/
function approximateFraction(x) {
// Fast paths for int numbers or their inversions.
if (Math.floor(x) === x) {
return [x, 1];
}
var xinv = 1 / x;
var limit = 8;
if (xinv > limit) {
return [1, limit];
} else if (Math.floor(xinv) === xinv) {
return [1, xinv];
}

var x_ = x > 1 ? xinv : x;
// a/b and c/d are neighbours in Farley sequence.
var a = 0, b = 1, c = 1, d = 1;
// Limiting search to order 8.
while (true) {
// Generating next term in sequence (order of q).
var p = a + c, q = b + d;
if (q > limit) {
break;
}
if (x_ <= p / q) {
c = p; d = q;
} else {
a = p; b = q;
}
}
// Select closest of the neighbours to x.
if (x_ - a / b < c / d - x_) {
return x_ === x ? [a, b] : [b, a];
} else {
return x_ === x ? [c, d] : [d, c];
}
}

function roundToDivide(x, div) {
var r = x % div;
return r === 0 ? x : Math.round(x - r + div);
}

/**
* Generic helper to find out what elements are visible within a scroll pane.
*/
Expand Down

0 comments on commit 0d8fcd3

Please sign in to comment.