[Pkg-javascript-commits] [pdf.js] 10/115: Allow subpixel anti-aliasing for most of the content.
David Prévot
taffit at moszumanska.debian.org
Wed Dec 16 20:03:09 UTC 2015
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository pdf.js.
commit 1d8800370a94b8e1dfc054f5ae2b964035b5c5e0
Author: Yury Delendik <ydelendik at mozilla.com>
Date: Mon Nov 16 10:50:02 2015 -0600
Allow subpixel anti-aliasing for most of the content.
---
src/display/api.js | 4 +-
src/display/canvas.js | 85 ++++++++++++++++++++++++++++---------------
src/display/pattern_helper.js | 12 +++---
test/driver.js | 18 +++++++--
web/pdf_page_view.js | 26 +++++++------
web/pdf_thumbnail_view.js | 10 ++++-
web/text_layer_builder.js | 5 ++-
7 files changed, 108 insertions(+), 52 deletions(-)
diff --git a/src/display/api.js b/src/display/api.js
index 655582a..bee60e6 100644
--- a/src/display/api.js
+++ b/src/display/api.js
@@ -660,6 +660,8 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() {
* calling of PDFPage.getViewport method.
* @property {string} intent - Rendering intent, can be 'display' or 'print'
* (default value is 'display').
+ * @property {Array} transform - (optional) Additional transform, applied
+ * just before viewport transform.
* @property {Object} imageLayer - (optional) An object that has beginLayout,
* endLayout and appendImage functions.
* @property {function} continueCallback - (deprecated) A function that will be
@@ -1732,7 +1734,7 @@ var InternalRenderTask = (function InternalRenderTaskClosure() {
this.gfx = new CanvasGraphics(params.canvasContext, this.commonObjs,
this.objs, params.imageLayer);
- this.gfx.beginDrawing(params.viewport, transparency);
+ this.gfx.beginDrawing(params.transform, params.viewport, transparency);
this.operatorListIdx = 0;
this.graphicsReady = true;
if (this.graphicsReadyCallback) {
diff --git a/src/display/canvas.js b/src/display/canvas.js
index 679359f..c8533b6 100644
--- a/src/display/canvas.js
+++ b/src/display/canvas.js
@@ -162,13 +162,15 @@ function addContextCurrentTransform(ctx) {
}
var CachedCanvases = (function CachedCanvasesClosure() {
- var cache = {};
- return {
+ function CachedCanvases() {
+ this.cache = Object.create(null);
+ }
+ CachedCanvases.prototype = {
getCanvas: function CachedCanvases_getCanvas(id, width, height,
trackTransform) {
var canvasEntry;
- if (cache[id] !== undefined) {
- canvasEntry = cache[id];
+ if (this.cache[id] !== undefined) {
+ canvasEntry = this.cache[id];
canvasEntry.canvas.width = width;
canvasEntry.canvas.height = height;
// reset canvas transform for emulated mozCurrentTransform, if needed
@@ -179,21 +181,22 @@ var CachedCanvases = (function CachedCanvasesClosure() {
if (trackTransform) {
addContextCurrentTransform(ctx);
}
- cache[id] = canvasEntry = {canvas: canvas, context: ctx};
+ this.cache[id] = canvasEntry = {canvas: canvas, context: ctx};
}
return canvasEntry;
},
clear: function () {
- for (var id in cache) {
- var canvasEntry = cache[id];
+ for (var id in this.cache) {
+ var canvasEntry = this.cache[id];
// Zeroing the width and height causes Firefox to release graphics
// resources immediately, which can greatly reduce memory consumption.
canvasEntry.canvas.width = 0;
canvasEntry.canvas.height = 0;
- delete cache[id];
+ delete this.cache[id];
}
}
};
+ return CachedCanvases;
})();
function compileType3Glyph(imgData) {
@@ -431,6 +434,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
this.smaskStack = [];
this.smaskCounter = 0;
this.tempSMask = null;
+ this.cachedCanvases = new CachedCanvases();
if (canvasCtx) {
// NOTE: if mozCurrentTransform is polyfilled, then the current state of
// the transformation must already be set in canvasCtx._transformMatrix.
@@ -707,28 +711,39 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
CanvasGraphics.prototype = {
- beginDrawing: function CanvasGraphics_beginDrawing(viewport, transparency) {
+ beginDrawing: function CanvasGraphics_beginDrawing(transform, viewport,
+ transparency) {
// For pdfs that use blend modes we have to clear the canvas else certain
// blend modes can look wrong since we'd be blending with a white
// backdrop. The problem with a transparent backdrop though is we then
- // don't get sub pixel anti aliasing on text, so we fill with white if
- // we can.
+ // don't get sub pixel anti aliasing on text, creating temporary
+ // transparent canvas when we have blend modes.
var width = this.ctx.canvas.width;
var height = this.ctx.canvas.height;
+
+ this.ctx.save();
+ this.ctx.fillStyle = 'rgb(255, 255, 255)';
+ this.ctx.fillRect(0, 0, width, height);
+ this.ctx.restore();
+
if (transparency) {
- this.ctx.clearRect(0, 0, width, height);
- } else {
- this.ctx.mozOpaque = true;
+ var transparentCanvas = this.cachedCanvases.getCanvas(
+ 'transparent', width, height, true);
+ this.compositeCtx = this.ctx;
+ this.transparentCanvas = transparentCanvas.canvas;
+ this.ctx = transparentCanvas.context;
this.ctx.save();
- this.ctx.fillStyle = 'rgb(255, 255, 255)';
- this.ctx.fillRect(0, 0, width, height);
- this.ctx.restore();
+ // The transform can be applied before rendering, transferring it to
+ // the new canvas.
+ this.ctx.transform.apply(this.ctx,
+ this.compositeCtx.mozCurrentTransform);
}
- var transform = viewport.transform;
-
this.ctx.save();
- this.ctx.transform.apply(this.ctx, transform);
+ if (transform) {
+ this.ctx.transform.apply(this.ctx, transform);
+ }
+ this.ctx.transform.apply(this.ctx, viewport.transform);
this.baseTransform = this.ctx.mozCurrentTransform.slice();
@@ -810,7 +825,14 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
endDrawing: function CanvasGraphics_endDrawing() {
this.ctx.restore();
- CachedCanvases.clear();
+
+ if (this.transparentCanvas) {
+ this.ctx = this.compositeCtx;
+ this.ctx.drawImage(this.transparentCanvas, 0, 0);
+ this.transparentCanvas = null;
+ }
+
+ this.cachedCanvases.clear();
WebGLUtils.clear();
if (this.imageLayer) {
@@ -924,7 +946,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
var drawnWidth = activeSMask.canvas.width;
var drawnHeight = activeSMask.canvas.height;
var cacheId = 'smaskGroupAt' + this.groupLevel;
- var scratchCanvas = CachedCanvases.getCanvas(
+ var scratchCanvas = this.cachedCanvases.getCanvas(
cacheId, drawnWidth, drawnHeight, true);
var currentCtx = this.ctx;
@@ -1708,7 +1730,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
// Using two cache entries is case if masks are used one after another.
cacheId += '_smask_' + ((this.smaskCounter++) % 2);
}
- var scratchCanvas = CachedCanvases.getCanvas(
+ var scratchCanvas = this.cachedCanvases.getCanvas(
cacheId, drawnWidth, drawnHeight, true);
var groupCtx = scratchCanvas.context;
@@ -1849,7 +1871,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
return;
}
- var maskCanvas = CachedCanvases.getCanvas('maskCanvas', width, height);
+ var maskCanvas = this.cachedCanvases.getCanvas('maskCanvas',
+ width, height);
var maskCtx = maskCanvas.context;
maskCtx.save();
@@ -1874,7 +1897,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
var fillColor = this.current.fillColor;
var isPatternFill = this.current.patternFill;
- var maskCanvas = CachedCanvases.getCanvas('maskCanvas', width, height);
+ var maskCanvas = this.cachedCanvases.getCanvas('maskCanvas',
+ width, height);
var maskCtx = maskCanvas.context;
maskCtx.save();
@@ -1909,7 +1933,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
var image = images[i];
var width = image.width, height = image.height;
- var maskCanvas = CachedCanvases.getCanvas('maskCanvas', width, height);
+ var maskCanvas = this.cachedCanvases.getCanvas('maskCanvas',
+ width, height);
var maskCtx = maskCanvas.context;
maskCtx.save();
@@ -1982,7 +2007,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
if (imgData instanceof HTMLElement || !imgData.data) {
imgToPaint = imgData;
} else {
- tmpCanvas = CachedCanvases.getCanvas('inlineImage', width, height);
+ tmpCanvas = this.cachedCanvases.getCanvas('inlineImage',
+ width, height);
var tmpCtx = tmpCanvas.context;
putBinaryImageData(tmpCtx, imgData);
imgToPaint = tmpCanvas.canvas;
@@ -2004,7 +2030,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
newHeight = Math.ceil(paintHeight / 2);
heightScale /= paintHeight / newHeight;
}
- tmpCanvas = CachedCanvases.getCanvas(tmpCanvasId, newWidth, newHeight);
+ tmpCanvas = this.cachedCanvases.getCanvas(tmpCanvasId,
+ newWidth, newHeight);
tmpCtx = tmpCanvas.context;
tmpCtx.clearRect(0, 0, newWidth, newHeight);
tmpCtx.drawImage(imgToPaint, 0, 0, paintWidth, paintHeight,
@@ -2036,7 +2063,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
var w = imgData.width;
var h = imgData.height;
- var tmpCanvas = CachedCanvases.getCanvas('inlineImage', w, h);
+ var tmpCanvas = this.cachedCanvases.getCanvas('inlineImage', w, h);
var tmpCtx = tmpCanvas.context;
putBinaryImageData(tmpCtx, imgData);
diff --git a/src/display/pattern_helper.js b/src/display/pattern_helper.js
index e23dc0a..c0251c3 100644
--- a/src/display/pattern_helper.js
+++ b/src/display/pattern_helper.js
@@ -149,7 +149,7 @@ var createMeshCanvas = (function createMeshCanvasClosure() {
}
function createMeshCanvas(bounds, combinesScale, coords, colors, figures,
- backgroundColor) {
+ backgroundColor, cachedCanvases) {
// we will increase scale on some weird factor to let antialiasing take
// care of "rough" edges
var EXPECTED_SCALE = 1.1;
@@ -183,11 +183,11 @@ var createMeshCanvas = (function createMeshCanvasClosure() {
figures, context);
// https://bugzilla.mozilla.org/show_bug.cgi?id=972126
- tmpCanvas = CachedCanvases.getCanvas('mesh', width, height, false);
+ tmpCanvas = cachedCanvases.getCanvas('mesh', width, height, false);
tmpCanvas.context.drawImage(canvas, 0, 0);
canvas = tmpCanvas.canvas;
} else {
- tmpCanvas = CachedCanvases.getCanvas('mesh', width, height, false);
+ tmpCanvas = cachedCanvases.getCanvas('mesh', width, height, false);
var tmpCtx = tmpCanvas.context;
var data = tmpCtx.createImageData(width, height);
@@ -243,7 +243,8 @@ ShadingIRs.Mesh = {
// Rasterizing on the main thread since sending/queue large canvases
// might cause OOM.
var temporaryPatternCanvas = createMeshCanvas(bounds, scale, coords,
- colors, figures, shadingFill ? null : background);
+ colors, figures, shadingFill ? null : background,
+ owner.cachedCanvases);
if (!shadingFill) {
ctx.setTransform.apply(ctx, owner.baseTransform);
@@ -346,7 +347,8 @@ var TilingPattern = (function TilingPatternClosure() {
height = Math.min(Math.ceil(Math.abs(height * combinedScale[1])),
MAX_PATTERN_SIZE);
- var tmpCanvas = CachedCanvases.getCanvas('pattern', width, height, true);
+ var tmpCanvas = owner.cachedCanvases.getCanvas('pattern',
+ width, height, true);
var tmpCtx = tmpCanvas.context;
var graphics = new CanvasGraphics(tmpCtx, commonObjs, objs);
graphics.groupLevel = owner.groupLevel;
diff --git a/test/driver.js b/test/driver.js
index aed80e3..6855861 100644
--- a/test/driver.js
+++ b/test/driver.js
@@ -50,6 +50,12 @@ var SimpleTextLayerBuilder = (function SimpleTextLayerBuilderClosure() {
this.ctx = ctx;
this.viewport = viewport;
this.textCounter = 0;
+
+ // clear canvas
+ ctx.save();
+ ctx.fillStyle = 'rgb(255,255,255)';
+ ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
+ ctx.restore();
}
SimpleTextLayerBuilder.prototype = {
@@ -271,6 +277,7 @@ var Driver = (function DriverClosure() {
_nextPage: function Driver_nextPage(task, loadError) {
var self = this;
var failure = loadError || '';
+ var ctx;
if (!task.pdfDoc) {
var dataUrl = this.canvas.toDataURL('image/png');
@@ -301,7 +308,11 @@ var Driver = (function DriverClosure() {
// Empty the canvas
this.canvas.width = 1;
this.canvas.height = 1;
- this._clearCanvas();
+ ctx = this.canvas.getContext('2d', {alpha: false});
+ ctx.save();
+ ctx.fillStyle = 'white';
+ ctx.fillRect(0, 0, 1, 1);
+ ctx.restore();
this._snapshot(task, '');
return;
@@ -311,7 +322,8 @@ var Driver = (function DriverClosure() {
try {
this._log(' Loading page ' + task.pageNum + '/' +
task.pdfDoc.numPages + '... ');
- var ctx = this.canvas.getContext('2d');
+ this.canvas.mozOpaque = true;
+ ctx = this.canvas.getContext('2d', {alpha: false});
task.pdfDoc.getPage(task.pageNum).then(function(page) {
var viewport = page.getViewport(PDF_TO_CSS_UNITS);
self.canvas.width = viewport.width;
@@ -371,7 +383,7 @@ var Driver = (function DriverClosure() {
},
_clearCanvas: function Driver_clearCanvas() {
- var ctx = this.canvas.getContext('2d');
+ var ctx = this.canvas.getContext('2d', {alpha: false});
ctx.beginPath();
ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
},
diff --git a/web/pdf_page_view.js b/web/pdf_page_view.js
index f882311..b4f36f4 100644
--- a/web/pdf_page_view.js
+++ b/web/pdf_page_view.js
@@ -166,8 +166,7 @@ var PDFPageView = (function PDFPageViewClosure() {
var isScalingRestricted = false;
if (this.canvas && PDFJS.maxCanvasPixels > 0) {
- var ctx = this.canvas.getContext('2d');
- var outputScale = getOutputScale(ctx);
+ var outputScale = this.outputScale;
var pixelsInViewport = this.viewport.width * this.viewport.height;
var maxScale = Math.sqrt(PDFJS.maxCanvasPixels / pixelsInViewport);
if (((Math.floor(this.viewport.width) * outputScale.sx) | 0) *
@@ -311,6 +310,7 @@ var PDFPageView = (function PDFPageViewClosure() {
var canvas = document.createElement('canvas');
canvas.id = 'page' + this.id;
+ canvas.setAttribute('hidden', 'hidden');
canvasWrapper.appendChild(canvas);
if (this.annotationLayer && this.annotationLayer.div) {
// annotationLayer needs to stay on top
@@ -318,10 +318,15 @@ var PDFPageView = (function PDFPageViewClosure() {
} else {
div.appendChild(canvasWrapper);
}
+ var isCanvasHidden = true;
this.canvas = canvas;
- var ctx = canvas.getContext('2d');
+//#if MOZCENTRAL || FIREFOX || GENERIC
+ canvas.mozOpaque = true;
+//#endif
+ var ctx = canvas.getContext('2d', {alpha: false});
var outputScale = getOutputScale(ctx);
+ this.outputScale = outputScale;
if (PDFJS.useOnlyCssZoom) {
var actualSizeViewport = viewport.clone({scale: CSS_UNITS});
@@ -374,14 +379,6 @@ var PDFPageView = (function PDFPageViewClosure() {
}
this.textLayer = textLayer;
- if (outputScale.scaled) {
-//#if !(MOZCENTRAL || FIREFOX)
- // Used by the mozCurrentTransform polyfill in src/display/canvas.js.
- ctx._transformMatrix = [outputScale.sx, 0, 0, outputScale.sy, 0, 0];
-//#endif
- ctx.scale(outputScale.sx, outputScale.sy);
- }
-
var resolveRenderPromise, rejectRenderPromise;
var promise = new Promise(function (resolve, reject) {
resolveRenderPromise = resolve;
@@ -461,12 +458,19 @@ var PDFPageView = (function PDFPageViewClosure() {
};
return;
}
+ if (isCanvasHidden) {
+ self.canvas.removeAttribute('hidden');
+ isCanvasHidden = false;
+ }
cont();
};
}
+ var transform = !outputScale.scaled ? null :
+ [outputScale.sx, 0, 0, outputScale.sy, 0, 0];
var renderContext = {
canvasContext: ctx,
+ transform: transform,
viewport: this.viewport,
// intent: 'default', // === 'display'
};
diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js
index 24e4cf5..50f7719 100644
--- a/web/pdf_thumbnail_view.js
+++ b/web/pdf_thumbnail_view.js
@@ -46,7 +46,10 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
// Since this is a temporary canvas, we need to fill the canvas with a white
// background ourselves. |_getPageDrawContext| uses CSS rules for this.
- var ctx = tempCanvas.getContext('2d');
+//#if MOZCENTRAL || FIREFOX || GENERIC
+ tempCanvas.mozOpaque = true;
+//#endif
+ var ctx = tempCanvas.getContext('2d', {alpha: false});
ctx.save();
ctx.fillStyle = 'rgb(255, 255, 255)';
ctx.fillRect(0, 0, width, height);
@@ -186,7 +189,10 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
var canvas = document.createElement('canvas');
this.canvas = canvas;
- var ctx = canvas.getContext('2d');
+//#if MOZCENTRAL || FIREFOX || GENERIC
+ canvas.mozOpaque = true;
+//#endif
+ var ctx = canvas.getContext('2d', {alpha: false});
var outputScale = getOutputScale(ctx);
canvas.width = (this.canvasWidth * outputScale.sx) | 0;
diff --git a/web/text_layer_builder.js b/web/text_layer_builder.js
index 1986e7c..bea1469 100644
--- a/web/text_layer_builder.js
+++ b/web/text_layer_builder.js
@@ -74,7 +74,10 @@ var TextLayerBuilder = (function TextLayerBuilderClosure() {
var textDivs = this.textDivs;
var textDivsLength = textDivs.length;
var canvas = document.createElement('canvas');
- var ctx = canvas.getContext('2d');
+//#if MOZCENTRAL || FIREFOX || GENERIC
+ canvas.mozOpaque = true;
+//#endif
+ var ctx = canvas.getContext('2d', {alpha: false});
// No point in rendering many divs as it would make the browser
// unusable even after the divs are rendered.
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/pdf.js.git
More information about the Pkg-javascript-commits
mailing list