|
|
|
@ -249,6 +249,55 @@ function binarySearchFirstItem(items, condition) {
@@ -249,6 +249,55 @@ function binarySearchFirstItem(items, condition) {
|
|
|
|
|
return minIndex; /* === maxIndex */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Approximates float number as a fraction using Farey 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 Farey 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. |
|
|
|
|
*/ |
|
|
|
@ -1207,10 +1256,12 @@ var PDFPageView = (function PDFPageViewClosure() {
@@ -1207,10 +1256,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; |
|
|
|
|
|
|
|
|
|