|
|
|
@ -162,13 +162,15 @@ function addContextCurrentTransform(ctx) {
@@ -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() {
@@ -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() {
@@ -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() {
@@ -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() {
@@ -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() {
@@ -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() {
@@ -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() {
@@ -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() {
@@ -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() {
@@ -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() {
@@ -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() {
@@ -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() {
@@ -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); |
|
|
|
|
|
|
|
|
|