Adds additional parameter so background color of canvas can be set

This commit is contained in:
chris.greening 2017-05-16 12:01:03 +01:00
parent 08f8b68f12
commit cfc2f36f5c
8 changed files with 429 additions and 27 deletions

View File

@ -717,6 +717,11 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() {
* @property {Object} canvasFactory - (optional) The factory that will be used
* when creating canvases. The default value is
* {DOMCanvasFactory}.
* @property {Object} background - (optional) Background to use for the canvas.
* Can use any valid canvas.fillStyle: A DOMString parsed as
* CSS <color> value, a CanvasGradient object (a linear or
* radial gradient) or a CanvasPattern object (a repetitive
* image). The default value is 'rgb(255,255,255)'.
*/
/**
@ -2128,7 +2133,12 @@ var InternalRenderTask = (function InternalRenderTaskClosure() {
this.objs, this.canvasFactory,
params.imageLayer);
this.gfx.beginDrawing(params.transform, params.viewport, transparency);
this.gfx.beginDrawing({
transform: params.transform,
viewport: params.viewport,
transparency,
background: params.background,
});
this.operatorListIdx = 0;
this.graphicsReady = true;
if (this.graphicsReadyCallback) {

View File

@ -705,8 +705,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
CanvasGraphics.prototype = {
beginDrawing: function CanvasGraphics_beginDrawing(transform, viewport,
transparency) {
beginDrawing({ transform, viewport, transparency,
background = null, }) {
// 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
@ -716,7 +716,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
var height = this.ctx.canvas.height;
this.ctx.save();
this.ctx.fillStyle = 'rgb(255, 255, 255)';
this.ctx.fillStyle = background || 'rgb(255, 255, 255)';
this.ctx.fillRect(0, 0, width, height);
this.ctx.restore();

View File

@ -280,3 +280,4 @@
!issue7878.pdf
!font_ascent_descent.pdf
!issue8097_reduced.pdf
!transparent.pdf

276
test/pdfs/transparent.pdf Normal file

File diff suppressed because one or more lines are too long

View File

@ -13,6 +13,9 @@
* limitations under the License.
*/
import {
buildGetDocumentParams, NodeFileReaderFactory, TEST_PDFS_PATH
} from './test_utils';
import {
createPromiseCapability, FontType, InvalidPDFException, isNodeJS,
MissingPDFException, PasswordException, PasswordResponses, StreamType,
@ -24,29 +27,8 @@ import {
import {
getDocument, PDFDocumentProxy, PDFPageProxy
} from '../../src/display/api';
import { NodeFileReaderFactory } from './test_utils';
import { PDFJS } from '../../src/display/global';
const TEST_PDFS_PATH = {
dom: '../pdfs/',
node: './test/pdfs/',
};
function buildGetDocumentParams(filename, options) {
let params = Object.create(null);
if (isNodeJS()) {
params.data = NodeFileReaderFactory.fetch({
path: TEST_PDFS_PATH.node + filename,
});
} else {
params.url = new URL(TEST_PDFS_PATH.dom + filename, window.location).href;
}
for (let option in options) {
params[option] = options[option];
}
return params;
}
describe('api', function() {
let basicApiFileName = 'basicapi.pdf';
let basicApiFileLength = 105779; // bytes

110
test/unit/custom_spec.js Normal file
View File

@ -0,0 +1,110 @@
/* Copyright 2017 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { buildGetDocumentParams } from './test_utils';
import { DOMCanvasFactory } from '../../src/display/dom_utils';
import { getDocument } from '../../src/display/api';
import { isNodeJS } from '../../src/shared/util';
import { PDFJS } from '../../src/display/global';
function getTopLeftPixel(canvasContext) {
let imgData = canvasContext.getImageData(0, 0, 1, 1);
return {
r: imgData.data[0],
g: imgData.data[1],
b: imgData.data[2],
a: imgData.data[3],
};
}
describe('custom canvas rendering', function() {
let transparentGetDocumentParams = buildGetDocumentParams('transparent.pdf');
let CanvasFactory;
let loadingTask;
let page;
beforeAll(function(done) {
if (isNodeJS()) {
PDFJS.pdfjsNext = true;
// NOTE: To support running the canvas-related tests in Node.js,
// a `NodeCanvasFactory` would need to be added (in test_utils.js).
} else {
CanvasFactory = new DOMCanvasFactory();
}
loadingTask = getDocument(transparentGetDocumentParams);
loadingTask.promise.then(function(doc) {
return doc.getPage(1);
}).then(function(data) {
page = data;
done();
}).catch(function (reason) {
done.fail(reason);
});
});
afterAll(function(done) {
CanvasFactory = null;
page = null;
loadingTask.destroy().then(done);
});
it('renders to canvas with a default white background', function(done) {
if (isNodeJS()) {
pending('TODO: Support Canvas testing in Node.js.');
}
var viewport = page.getViewport(1);
var canvasAndCtx = CanvasFactory.create(viewport.width, viewport.height);
page.render({
canvasContext: canvasAndCtx.context,
viewport,
}).then(function() {
var { r, g, b, a } = getTopLeftPixel(canvasAndCtx.context);
CanvasFactory.destroy(canvasAndCtx);
expect(r).toEqual(255);
expect(g).toEqual(255);
expect(b).toEqual(255);
expect(a).toEqual(255);
done();
}).catch(function (reason) {
done(reason);
});
});
it('renders to canvas with a custom background', function(done) {
if (isNodeJS()) {
pending('TODO: Support Canvas testing in Node.js.');
}
var viewport = page.getViewport(1);
var canvasAndCtx = CanvasFactory.create(viewport.width, viewport.height);
page.render({
canvasContext: canvasAndCtx.context,
viewport,
background: 'rgba(255,0,0,1.0)'
}).then(function() {
var { r, g, b, a } = getTopLeftPixel(canvasAndCtx.context);
CanvasFactory.destroy(canvasAndCtx);
expect(r).toEqual(255);
expect(g).toEqual(0);
expect(b).toEqual(0);
expect(a).toEqual(255);
done();
}).catch(function (reason) {
done(reason);
});
});
});

View File

@ -52,7 +52,8 @@ function initializePDFJS(callback) {
'pdfjs-test/unit/network_spec', 'pdfjs-test/unit/parser_spec',
'pdfjs-test/unit/primitives_spec', 'pdfjs-test/unit/stream_spec',
'pdfjs-test/unit/type1_parser_spec', 'pdfjs-test/unit/ui_utils_spec',
'pdfjs-test/unit/unicode_spec', 'pdfjs-test/unit/util_spec'
'pdfjs-test/unit/unicode_spec', 'pdfjs-test/unit/util_spec',
'pdfjs-test/unit/custom_spec'
].map(function (moduleName) {
return SystemJS.import(moduleName);
})).then(function (modules) {

View File

@ -13,7 +13,7 @@
* limitations under the License.
*/
import { CMapCompressionType } from '../../src/shared/util';
import { CMapCompressionType, isNodeJS } from '../../src/shared/util';
class NodeFileReaderFactory {
static fetch(params) {
@ -23,6 +23,26 @@ class NodeFileReaderFactory {
}
}
const TEST_PDFS_PATH = {
dom: '../pdfs/',
node: './test/pdfs/',
};
function buildGetDocumentParams(filename, options) {
let params = Object.create(null);
if (isNodeJS()) {
params.data = NodeFileReaderFactory.fetch({
path: TEST_PDFS_PATH.node + filename,
});
} else {
params.url = new URL(TEST_PDFS_PATH.dom + filename, window.location).href;
}
for (let option in options) {
params[option] = options[option];
}
return params;
}
class NodeCMapReaderFactory {
constructor({ baseUrl = null, isCompressed = false, }) {
this.baseUrl = baseUrl;
@ -57,4 +77,6 @@ class NodeCMapReaderFactory {
export {
NodeFileReaderFactory,
NodeCMapReaderFactory,
buildGetDocumentParams,
TEST_PDFS_PATH,
};