17 changed files with 475 additions and 127 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,164 @@ |
|||||||
|
/* 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. |
||||||
|
*/ |
||||||
|
'use strict'; |
||||||
|
|
||||||
|
function xmlEncode(s) { |
||||||
|
var i = 0, |
||||||
|
ch; |
||||||
|
s = String(s); |
||||||
|
while (i < s.length && (ch = s[i]) !== '&' && ch !== '<' && ch !== '\"' && ch !== '\n' && ch !== '\r' && ch !== '\t') { |
||||||
|
i++; |
||||||
|
} |
||||||
|
if (i >= s.length) { |
||||||
|
return s; |
||||||
|
} |
||||||
|
var buf = s.substring(0, i); |
||||||
|
while (i < s.length) { |
||||||
|
ch = s[i++]; |
||||||
|
switch (ch) { |
||||||
|
case '&': |
||||||
|
buf += '&'; |
||||||
|
break; |
||||||
|
case '<': |
||||||
|
buf += '<'; |
||||||
|
break; |
||||||
|
case '\"': |
||||||
|
buf += '"'; |
||||||
|
break; |
||||||
|
case '\n': |
||||||
|
buf += '
'; |
||||||
|
break; |
||||||
|
case '\r': |
||||||
|
buf += '
'; |
||||||
|
break; |
||||||
|
case '\t': |
||||||
|
buf += '	'; |
||||||
|
break; |
||||||
|
default: |
||||||
|
buf += ch; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
return buf; |
||||||
|
} |
||||||
|
function DOMElement(name) { |
||||||
|
this.nodeName = name; |
||||||
|
this.childNodes = []; |
||||||
|
this.attributes = {}; |
||||||
|
this.textContent = ''; |
||||||
|
if (name === 'style') { |
||||||
|
this.sheet = { |
||||||
|
cssRules: [], |
||||||
|
insertRule: function insertRule(rule) { |
||||||
|
this.cssRules.push(rule); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
||||||
|
DOMElement.prototype = { |
||||||
|
getAttributeNS: function DOMElement_getAttributeNS(NS, name) { |
||||||
|
return name in this.attributes ? this.attributes[name] : null; |
||||||
|
}, |
||||||
|
setAttributeNS: function DOMElement_setAttributeNS(NS, name, value) { |
||||||
|
value = value || ''; |
||||||
|
value = xmlEncode(value); |
||||||
|
this.attributes[name] = value; |
||||||
|
}, |
||||||
|
appendChild: function DOMElement_appendChild(element) { |
||||||
|
var childNodes = this.childNodes; |
||||||
|
if (childNodes.indexOf(element) === -1) { |
||||||
|
childNodes.push(element); |
||||||
|
} |
||||||
|
}, |
||||||
|
toString: function DOMElement_toString() { |
||||||
|
var buf = []; |
||||||
|
buf.push('<' + this.nodeName); |
||||||
|
if (this.nodeName === 'svg:svg') { |
||||||
|
buf.push(' xmlns:xlink="http://www.w3.org/1999/xlink"' + ' xmlns:svg="http://www.w3.org/2000/svg"'); |
||||||
|
} |
||||||
|
for (var i in this.attributes) { |
||||||
|
buf.push(' ' + i + '="' + xmlEncode(this.attributes[i]) + '"'); |
||||||
|
} |
||||||
|
buf.push('>'); |
||||||
|
if (this.nodeName === 'svg:tspan' || this.nodeName === 'svg:style') { |
||||||
|
buf.push(xmlEncode(this.textContent)); |
||||||
|
} else { |
||||||
|
this.childNodes.forEach(function (childNode) { |
||||||
|
buf.push(childNode.toString()); |
||||||
|
}); |
||||||
|
} |
||||||
|
buf.push('</' + this.nodeName + '>'); |
||||||
|
return buf.join(''); |
||||||
|
}, |
||||||
|
cloneNode: function DOMElement_cloneNode() { |
||||||
|
var newNode = new DOMElement(this.nodeName); |
||||||
|
newNode.childNodes = this.childNodes; |
||||||
|
newNode.attributes = this.attributes; |
||||||
|
newNode.textContent = this.textContent; |
||||||
|
return newNode; |
||||||
|
} |
||||||
|
}; |
||||||
|
var document = { |
||||||
|
childNodes: [], |
||||||
|
get currentScript() { |
||||||
|
return { src: '' }; |
||||||
|
}, |
||||||
|
get documentElement() { |
||||||
|
return this; |
||||||
|
}, |
||||||
|
createElementNS: function createElementNS(NS, element) { |
||||||
|
var elObject = new DOMElement(element); |
||||||
|
return elObject; |
||||||
|
}, |
||||||
|
createElement: function createElement(element) { |
||||||
|
return this.createElementNS('', element); |
||||||
|
}, |
||||||
|
getElementsByTagName: function getElementsByTagName(element) { |
||||||
|
if (element === 'head') { |
||||||
|
return [this.head || (this.head = new DOMElement('head'))]; |
||||||
|
} |
||||||
|
return []; |
||||||
|
} |
||||||
|
}; |
||||||
|
function Image() { |
||||||
|
this._src = null; |
||||||
|
this.onload = null; |
||||||
|
} |
||||||
|
Image.prototype = { |
||||||
|
get src() { |
||||||
|
return this._src; |
||||||
|
}, |
||||||
|
set src(value) { |
||||||
|
this._src = value; |
||||||
|
if (this.onload) { |
||||||
|
this.onload(); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
exports.document = document; |
||||||
|
exports.Image = Image; |
||||||
|
var exported_symbols = Object.keys(exports); |
||||||
|
exports.setStubs = function (namespace) { |
||||||
|
exported_symbols.forEach(function (key) { |
||||||
|
console.assert(!(key in namespace), 'property should not be set: ' + key); |
||||||
|
namespace[key] = exports[key]; |
||||||
|
}); |
||||||
|
}; |
||||||
|
exports.unsetStubs = function (namespace) { |
||||||
|
exported_symbols.forEach(function (key) { |
||||||
|
console.assert(key in namespace, 'property should be set: ' + key); |
||||||
|
delete namespace[key]; |
||||||
|
}); |
||||||
|
}; |
@ -0,0 +1,118 @@ |
|||||||
|
/* 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. |
||||||
|
*/ |
||||||
|
'use strict'; |
||||||
|
|
||||||
|
var _util = require('../../shared/util'); |
||||||
|
|
||||||
|
var _domstubs = require('../../examples/node/domstubs'); |
||||||
|
|
||||||
|
var _test_utils = require('./test_utils'); |
||||||
|
|
||||||
|
var _api = require('../../display/api'); |
||||||
|
|
||||||
|
var _svg = require('../../display/svg'); |
||||||
|
|
||||||
|
function withZlib(isZlibRequired, callback) { |
||||||
|
if (isZlibRequired) { |
||||||
|
if (!(0, _util.isNodeJS)()) { |
||||||
|
throw new Error('zlib test can only be run in Node.js'); |
||||||
|
} |
||||||
|
return callback(); |
||||||
|
} |
||||||
|
if (!(0, _util.isNodeJS)()) { |
||||||
|
return callback(); |
||||||
|
} |
||||||
|
var zlib = require('zlib'); |
||||||
|
var deflateSync = zlib.deflateSync; |
||||||
|
zlib.deflateSync = function () { |
||||||
|
throw new Error('zlib.deflateSync is explicitly disabled for testing.'); |
||||||
|
}; |
||||||
|
try { |
||||||
|
return callback(); |
||||||
|
} finally { |
||||||
|
zlib.deflateSync = deflateSync; |
||||||
|
} |
||||||
|
} |
||||||
|
describe('SVGGraphics', function () { |
||||||
|
var loadingTask; |
||||||
|
var page; |
||||||
|
beforeAll(function (done) { |
||||||
|
loadingTask = (0, _api.getDocument)((0, _test_utils.buildGetDocumentParams)('xobject-image.pdf', { nativeImageDecoderSupport: _util.NativeImageDecoding.DISPLAY })); |
||||||
|
loadingTask.promise.then(function (doc) { |
||||||
|
doc.getPage(1).then(function (firstPage) { |
||||||
|
page = firstPage; |
||||||
|
done(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
afterAll(function (done) { |
||||||
|
loadingTask.destroy().then(done); |
||||||
|
}); |
||||||
|
describe('paintImageXObject', function () { |
||||||
|
function getSVGImage() { |
||||||
|
var svgGfx; |
||||||
|
return page.getOperatorList().then(function (opList) { |
||||||
|
var forceDataSchema = true; |
||||||
|
svgGfx = new _svg.SVGGraphics(page.commonObjs, page.objs, forceDataSchema); |
||||||
|
return svgGfx.loadDependencies(opList); |
||||||
|
}).then(function () { |
||||||
|
var svgImg; |
||||||
|
var elementContainer = { |
||||||
|
appendChild: function appendChild(element) { |
||||||
|
svgImg = element; |
||||||
|
} |
||||||
|
}; |
||||||
|
var xobjectObjId = { |
||||||
|
ref: 4, |
||||||
|
gen: 0 |
||||||
|
}; |
||||||
|
if ((0, _util.isNodeJS)()) { |
||||||
|
(0, _domstubs.setStubs)(global); |
||||||
|
} |
||||||
|
try { |
||||||
|
svgGfx.paintImageXObject(xobjectObjId, elementContainer); |
||||||
|
} finally { |
||||||
|
if ((0, _util.isNodeJS)()) { |
||||||
|
(0, _domstubs.unsetStubs)(global); |
||||||
|
} |
||||||
|
} |
||||||
|
return svgImg; |
||||||
|
}); |
||||||
|
} |
||||||
|
it('should produce a reasonably small svg:image', function () { |
||||||
|
if (!(0, _util.isNodeJS)()) { |
||||||
|
pending('zlib.deflateSync is not supported in non-Node environments.'); |
||||||
|
} |
||||||
|
withZlib(true, getSVGImage).then(function (svgImg) { |
||||||
|
expect(svgImg.nodeName).toBe('svg:image'); |
||||||
|
expect(svgImg.getAttribute('width')).toBe('200px'); |
||||||
|
expect(svgImg.getAttribute('height')).toBe('100px'); |
||||||
|
var imgUrl = svgImg.getAttribute('xlink:href'); |
||||||
|
expect(imgUrl).toMatch(/^data:image\/png;base64,/); |
||||||
|
expect(imgUrl.length).toBeLessThan(367); |
||||||
|
}); |
||||||
|
}); |
||||||
|
it('should produce a svg:image even if zlib is unavailable', function () { |
||||||
|
withZlib(false, getSVGImage).then(function (svgImg) { |
||||||
|
expect(svgImg.nodeName).toBe('svg:image'); |
||||||
|
expect(svgImg.getAttribute('width')).toBe('200px'); |
||||||
|
expect(svgImg.getAttribute('height')).toBe('100px'); |
||||||
|
var imgUrl = svgImg.getAttribute('xlink:href'); |
||||||
|
expect(imgUrl).toMatch(/^data:image\/png;base64,/); |
||||||
|
expect(imgUrl.length).toBe(80247); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
Loading…
Reference in new issue