[Pkg-javascript-commits] [pdf.js] 29/414: Implement annotation layer regression testing
David Prévot
taffit at moszumanska.debian.org
Tue Jun 28 17:12:02 UTC 2016
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository pdf.js.
commit b7217a22745473c186da794729c9584576bf1c1c
Author: Tim van der Meij <timvandermeij at gmail.com>
Date: Fri Dec 18 22:29:22 2015 +0100
Implement annotation layer regression testing
---
test/annotation_layer_test.css | 73 ++++++++++++++++++
test/driver.js | 169 ++++++++++++++++++++++++++++++++++++++++-
test/test_manifest.json | 7 +-
3 files changed, 245 insertions(+), 4 deletions(-)
diff --git a/test/annotation_layer_test.css b/test/annotation_layer_test.css
new file mode 100644
index 0000000..3101be4
--- /dev/null
+++ b/test/annotation_layer_test.css
@@ -0,0 +1,73 @@
+/* Copyright 2015 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.
+ */
+
+/* Used for annotation layer tests */
+
+.annotationLayer {
+ position: absolute;
+ left: 0;
+ top: 0;
+ right: 0;
+ bottom: 0;
+}
+
+.annotationLayer > section {
+ position: absolute;
+}
+
+.annotationLayer .annotLink > a {
+ position: absolute;
+ font-size: 1em;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ opacity: 0.2;
+ background: #ff0;
+ box-shadow: 0px 2px 10px #ff0;
+}
+
+.annotationLayer .annotText > img {
+ position: absolute;
+}
+
+.annotationLayer .annotTextContentWrapper {
+ position: absolute;
+ width: 20em;
+}
+
+.annotationLayer .annotTextContent {
+ z-index: 200;
+ float: left;
+ max-width: 20em;
+ background-color: #FFFF99;
+ box-shadow: 0px 2px 5px #333;
+ border-radius: 2px;
+ padding: 0.6em;
+ display: block !important;
+ font: message-box;
+}
+
+.annotationLayer .annotTextContent > h1 {
+ font-size: 1em;
+ border-bottom: 1px solid #000000;
+ margin: 0;
+ padding: 0 0 0.2em 0;
+}
+
+.annotationLayer .annotTextContent > p {
+ margin: 0;
+ padding: 0.2em 0 0 0;
+}
diff --git a/test/driver.js b/test/driver.js
index fa9c77a..148a8c4 100644
--- a/test/driver.js
+++ b/test/driver.js
@@ -22,6 +22,29 @@ var PDF_TO_CSS_UNITS = 96.0 / 72.0;
/**
* @class
*/
+var LinkServiceMock = (function LinkServiceMockClosure() {
+ function LinkServiceMock() {}
+
+ LinkServiceMock.prototype = {
+ navigateTo: function (dest) {},
+
+ getDestinationHash: function (dest) {
+ return '#';
+ },
+
+ getAnchorUrl: function (hash) {
+ return '#';
+ },
+
+ executeNamedAction: function (action) {}
+ };
+
+ return LinkServiceMock;
+})();
+
+/**
+ * @class
+ */
var rasterizeTextLayer = (function rasterizeTextLayerClosure() {
var SVG_NS = 'http://www.w3.org/2000/svg';
@@ -90,6 +113,115 @@ var rasterizeTextLayer = (function rasterizeTextLayerClosure() {
})();
/**
+ * @class
+ */
+var rasterizeAnnotationLayer = (function rasterizeAnnotationLayerClosure() {
+ var SVG_NS = 'http://www.w3.org/2000/svg';
+
+ var annotationLayerStylePromise = null;
+ function getAnnotationLayerStyle() {
+ if (annotationLayerStylePromise) {
+ return annotationLayerStylePromise;
+ }
+ annotationLayerStylePromise = new Promise(function (resolve) {
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', './annotation_layer_test.css');
+ xhr.onload = function () {
+ resolve(xhr.responseText);
+ };
+ xhr.send(null);
+ });
+ return annotationLayerStylePromise;
+ }
+
+ function inlineAnnotationImages(images) {
+ var imagePromises = [];
+ for (var i = 0, ii = images.length; i < ii; i++) {
+ var imagePromise = new Promise(function(resolve) {
+ var xhr = new XMLHttpRequest();
+ xhr.responseType = 'blob';
+ xhr.onload = function() {
+ var reader = new FileReader();
+ reader.onloadend = function() {
+ resolve(reader.result);
+ };
+ reader.readAsDataURL(xhr.response);
+ };
+ xhr.onerror = function() {
+ resolve('');
+ };
+ xhr.open('GET', images[i].src);
+ xhr.send();
+ });
+ imagePromises.push(imagePromise);
+ }
+ return imagePromises;
+ }
+
+ function rasterizeAnnotationLayer(ctx, viewport, annotations, page) {
+ return new Promise(function (resolve) {
+ // Building SVG with size of the viewport.
+ var svg = document.createElementNS(SVG_NS, 'svg:svg');
+ svg.setAttribute('width', viewport.width + 'px');
+ svg.setAttribute('height', viewport.height + 'px');
+
+ // Adding element to host our HTML (style + annotation layer div).
+ var foreignObject = document.createElementNS(SVG_NS, 'svg:foreignObject');
+ foreignObject.setAttribute('x', '0');
+ foreignObject.setAttribute('y', '0');
+ foreignObject.setAttribute('width', viewport.width + 'px');
+ foreignObject.setAttribute('height', viewport.height + 'px');
+ var style = document.createElement('style');
+ var stylePromise = getAnnotationLayerStyle();
+ foreignObject.appendChild(style);
+ var div = document.createElement('div');
+ div.className = 'annotationLayer';
+
+ // Rendering annotation layer as HTML.
+ stylePromise.then(function (styles) {
+ style.textContent = styles;
+
+ var annotation_viewport = viewport.clone({ dontFlip: true });
+ var parameters = {
+ viewport: annotation_viewport,
+ div: div,
+ annotations: annotations,
+ page: page,
+ linkService: new LinkServiceMock()
+ };
+ PDFJS.AnnotationLayer.render(parameters);
+
+ // Inline SVG images from text annotations.
+ var images = div.getElementsByTagName('img');
+ var imagePromises = inlineAnnotationImages(images);
+ var converted = Promise.all(imagePromises).then(function(data) {
+ for (var i = 0, ii = data.length; i < ii; i++) {
+ images[i].src = data[i];
+ }
+ });
+
+ foreignObject.appendChild(div);
+ svg.appendChild(foreignObject);
+
+ // We need to have UTF-8 encoded XML.
+ converted.then(function() {
+ var svg_xml = unescape(encodeURIComponent(
+ (new XMLSerializer()).serializeToString(svg)));
+ var img = new Image();
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg_xml);
+ img.onload = function () {
+ ctx.drawImage(img, 0, 0);
+ resolve();
+ };
+ });
+ });
+ });
+ }
+
+ return rasterizeAnnotationLayer;
+})();
+
+/**
* @typedef {Object} DriverOptions
* @property {HTMLSpanElement} inflight - Field displaying the number of
* inflight requests.
@@ -113,6 +245,7 @@ var Driver = (function DriverClosure() {
PDFJS.cMapPacked = true;
PDFJS.cMapUrl = '../external/bcmaps/';
PDFJS.enableStats = true;
+ PDFJS.imageResourcesPath = '/web/images/';
// Set the passed options
this.inflight = options.inflight;
@@ -320,7 +453,7 @@ var Driver = (function DriverClosure() {
self.canvas.height = viewport.height;
self._clearCanvas();
- var textLayerCanvas;
+ var textLayerCanvas, annotationLayerCanvas;
var initPromise;
if (task.type === 'text') {
// Using a dummy canvas for PDF context drawing operations
@@ -343,8 +476,36 @@ var Driver = (function DriverClosure() {
});
} else {
textLayerCanvas = null;
- initPromise = Promise.resolve();
+
+ // Render the annotation layer if necessary.
+ if (task.annotations) {
+ // Create a dummy canvas for the drawing operations.
+ annotationLayerCanvas = self.annotationLayerCanvas;
+ if (!annotationLayerCanvas) {
+ annotationLayerCanvas = document.createElement('canvas');
+ self.annotationLayerCanvas = annotationLayerCanvas;
+ }
+ annotationLayerCanvas.width = viewport.width;
+ annotationLayerCanvas.height = viewport.height;
+ var annotationLayerContext =
+ annotationLayerCanvas.getContext('2d');
+ annotationLayerContext.clearRect(0, 0,
+ annotationLayerCanvas.width, annotationLayerCanvas.height);
+
+ // The annotation builder will draw its content on the canvas.
+ initPromise =
+ page.getAnnotations({ intent: 'display' }).then(
+ function(annotations) {
+ return rasterizeAnnotationLayer(annotationLayerContext,
+ viewport, annotations,
+ page);
+ });
+ } else {
+ annotationLayerCanvas = null;
+ initPromise = Promise.resolve();
+ }
}
+
var renderContext = {
canvasContext: ctx,
viewport: viewport
@@ -359,6 +520,10 @@ var Driver = (function DriverClosure() {
ctx.restore();
ctx.drawImage(textLayerCanvas, 0, 0);
}
+ // If we have annotation layer, compose it on top of the page.
+ if (annotationLayerCanvas) {
+ ctx.drawImage(annotationLayerCanvas, 0, 0);
+ }
page.cleanup();
task.stats = page.stats;
page.stats = new pdfjsSharedUtil.StatTimer();
diff --git a/test/test_manifest.json b/test/test_manifest.json
index 7095734..32b74c9 100644
--- a/test/test_manifest.json
+++ b/test/test_manifest.json
@@ -1600,7 +1600,8 @@
"rounds": 1,
"lastPage": 1,
"link": true,
- "type": "eq"
+ "type": "eq",
+ "annotations": true
},
{ "id": "issue1002",
"file": "pdfs/issue1002.pdf",
@@ -2052,6 +2053,7 @@
"md5": "56321ea830be9c4f8437ca17ac535b2d",
"rounds": 1,
"type": "eq",
+ "annotations": true,
"about": "Text widget annotation witout appearance streams."
},
{ "id": "gesamt",
@@ -2585,7 +2587,8 @@
"file": "pdfs/annotation-border-styles.pdf",
"md5": "22930fc09c7386e1131b14d936e554af",
"rounds": 1,
- "type": "eq"
+ "type": "eq",
+ "annotations": true
},
{ "id": "issue5481.pdf",
"file": "pdfs/issue5481.pdf",
--
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