Enable/disable image smoothing based on image interpolate value. (bug 1722191)

While some of the output looks worse to my eye, this behavior more
closely matches what I see when I open the PDFs in Adobe acrobat.

Fixes: #4706, #9713, #8245, #1344
This commit is contained in:
Brendan Dahl 2021-09-08 17:31:10 -07:00
parent 8a79f13e5a
commit f38fb42b42
13 changed files with 74 additions and 9 deletions

View file

@ -12,7 +12,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CSS_PIXELS_PER_INCH, PDF_PIXELS_PER_INCH } from "./display_utils.js";
import {
FONT_IDENTITY_MATRIX,
IDENTITY_MATRIX,
@ -871,6 +871,27 @@ function composeSMask(ctx, smask, layerCtx) {
ctx.drawImage(mask, 0, 0);
}
function getImageSmoothingEnabled(transform, interpolate) {
const scale = Util.singularValueDecompose2dScale(transform);
// Round to a 32bit float so that `<=` check below will pass for numbers that
// are very close, but not exactly the same 64bit floats.
scale[0] = Math.fround(scale[0]);
scale[1] = Math.fround(scale[1]);
const actualScale = Math.fround(
((globalThis.devicePixelRatio || 1) * CSS_PIXELS_PER_INCH) /
PDF_PIXELS_PER_INCH
);
if (interpolate !== undefined) {
// If the value is explicitly set use it.
return interpolate;
} else if (scale[0] <= actualScale || scale[1] <= actualScale) {
// Smooth when downscaling.
return true;
}
// Don't smooth when upscaling.
return false;
}
const LINE_CAP_STYLES = ["butt", "round", "square"];
const LINE_JOIN_STYLES = ["miter", "round", "bevel"];
const NORMAL_CLIP = {};
@ -1183,6 +1204,10 @@ class CanvasGraphics {
maskCanvas.canvas,
fillCtx.mozCurrentTransformInverse
);
fillCtx.imageSmoothingEnabled = getImageSmoothingEnabled(
fillCtx.mozCurrentTransform,
img.interpolate
);
fillCtx.drawImage(
scaled.img,
0,
@ -2663,6 +2688,10 @@ class CanvasGraphics {
}
const scaled = this._scaleImage(imgToPaint, ctx.mozCurrentTransformInverse);
ctx.imageSmoothingEnabled = getImageSmoothingEnabled(
ctx.mozCurrentTransform,
imgData.interpolate
);
ctx.drawImage(
scaled.img,
0,