[Pkg-javascript-commits] [pdf.js] 31/115: Better "text" testing.
David Prévot
taffit at moszumanska.debian.org
Wed Dec 16 20:03:11 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 bd7f121c8300b75aba4a21d5ef6022baa00b4eac
Author: Yury Delendik <ydelendik at mozilla.com>
Date: Thu Nov 19 11:03:52 2015 -0600
Better "text" testing.
---
test/driver.js | 176 +++++++++++++++++++++++------------------------
test/test_manifest.json | 6 --
test/text_layer_test.css | 38 ++++++++++
web/viewer.css | 22 +++++-
4 files changed, 147 insertions(+), 95 deletions(-)
diff --git a/test/driver.js b/test/driver.js
index c6c295f..c41ec70 100644
--- a/test/driver.js
+++ b/test/driver.js
@@ -22,80 +22,71 @@ var PDF_TO_CSS_UNITS = 96.0 / 72.0;
/**
* @class
*/
-var NullTextLayerBuilder = (function NullTextLayerBuilderClosure() {
- /**
- * @constructs NullTextLayerBuilder
- */
- function NullTextLayerBuilder() {}
-
- NullTextLayerBuilder.prototype = {
- beginLayout: function NullTextLayerBuilder_BeginLayout() {},
- endLayout: function NullTextLayerBuilder_EndLayout() {},
- appendText: function NullTextLayerBuilder_AppendText() {}
- };
+var rasterizeTextLayer = (function rasterizeTextLayerClosure() {
+ var SVG_NS = 'http://www.w3.org/2000/svg';
- return NullTextLayerBuilder;
-})();
-
-/**
- * @class
- */
-var SimpleTextLayerBuilder = (function SimpleTextLayerBuilderClosure() {
- /**
- * @constructs SimpleTextLayerBuilder
- */
- function SimpleTextLayerBuilder(ctx, viewport) {
- 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();
+ var textLayerStylePromise = null;
+ function getTextLayerStyle() {
+ if (textLayerStylePromise) {
+ return textLayerStylePromise;
+ }
+ textLayerStylePromise = new Promise(function (resolve) {
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', './text_layer_test.css');
+ xhr.onload = function () {
+ resolve(xhr.responseText);
+ };
+ xhr.send(null);
+ });
+ return textLayerStylePromise;
}
- SimpleTextLayerBuilder.prototype = {
- appendText: function SimpleTextLayerBuilder_AppendText(geom, styles) {
- var style = styles[geom.fontName];
- var ctx = this.ctx, viewport = this.viewport;
- var tx = PDFJS.Util.transform(this.viewport.transform, geom.transform);
- var angle = Math.atan2(tx[1], tx[0]);
- var fontHeight = Math.sqrt((tx[2] * tx[2]) + (tx[3] * tx[3]));
- var fontAscent = (style.ascent ? style.ascent * fontHeight :
- (style.descent ? (1 + style.descent) * fontHeight : fontHeight));
-
- ctx.save();
- ctx.beginPath();
- ctx.strokeStyle = 'red';
- ctx.fillStyle = 'yellow';
- ctx.translate(tx[4] + (fontAscent * Math.sin(angle)),
- tx[5] - (fontAscent * Math.cos(angle)));
- ctx.rotate(angle);
- ctx.rect(0, 0, geom.width * viewport.scale, geom.height * viewport.scale);
- ctx.stroke();
- ctx.fill();
- ctx.restore();
- ctx.font = fontHeight + 'px ' + style.fontFamily;
- ctx.fillStyle = 'black';
- ctx.fillText(geom.str, tx[4], tx[5]);
-
- this.textCounter++;
- },
-
- setTextContent:
- function SimpleTextLayerBuilder_SetTextContent(textContent) {
- this.ctx.save();
- var textItems = textContent.items;
- for (var i = 0, ii = textItems.length; i < ii; i++) {
- this.appendText(textItems[i], textContent.styles);
- }
- this.ctx.restore();
- }
- };
+ function rasterizeTextLayer(ctx, viewport, textContent) {
+ 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');
+ // items are transformed to have 1px font size
+ svg.setAttribute('font-size', 1);
+
+ // Adding element to host our HTML (style + text 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 = getTextLayerStyle();
+ foreignObject.appendChild(style);
+ var div = document.createElement('div');
+ div.className = 'textLayer';
+ foreignObject.appendChild(div);
+
+ // Rendering text layer as HTML.
+ var task = PDFJS.renderTextLayer({
+ textContent: textContent,
+ container: div,
+ viewport: viewport
+ });
+ Promise.all([stylePromise, task.promise]).then(function (results) {
+ style.textContent = results[0];
+ svg.appendChild(foreignObject);
+
+ // We need to have UTF-8 encoded XML.
+ 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 SimpleTextLayerBuilder;
+ return rasterizeTextLayer;
})();
/**
@@ -328,35 +319,44 @@ var Driver = (function DriverClosure() {
self.canvas.height = viewport.height;
self._clearCanvas();
- var drawContext, textLayerBuilder;
- var resolveInitPromise;
- var initPromise = new Promise(function (resolve) {
- resolveInitPromise = resolve;
- });
+ var textLayerCanvas;
+ var initPromise;
if (task.type === 'text') {
// Using a dummy canvas for PDF context drawing operations
- if (!self.dummyCanvas) {
- self.dummyCanvas = document.createElement('canvas');
+ textLayerCanvas = self.textLayerCanvas;
+ if (!textLayerCanvas) {
+ textLayerCanvas = document.createElement('canvas');
+ self.textLayerCanvas = textLayerCanvas;
}
- drawContext = self.dummyCanvas.getContext('2d');
+ textLayerCanvas.width = viewport.width;
+ textLayerCanvas.height = viewport.height;
+ var textLayerContext = textLayerCanvas.getContext('2d');
+ textLayerContext.clearRect(0, 0,
+ textLayerCanvas.width, textLayerCanvas.height);
// The text builder will draw its content on the test canvas
- textLayerBuilder = new SimpleTextLayerBuilder(ctx, viewport);
-
- page.getTextContent().then(function(textContent) {
- textLayerBuilder.setTextContent(textContent);
- resolveInitPromise();
+ initPromise = page.getTextContent().then(function(textContent) {
+ return rasterizeTextLayer(textLayerContext, viewport,
+ textContent);
});
} else {
- drawContext = ctx;
- textLayerBuilder = new NullTextLayerBuilder();
- resolveInitPromise();
+ textLayerCanvas = null;
+ initPromise = Promise.resolve();
}
var renderContext = {
- canvasContext: drawContext,
+ canvasContext: ctx,
viewport: viewport
};
var completeRender = (function(error) {
- page.destroy();
+ // if text layer is present, compose it on top of the page
+ if (textLayerCanvas) {
+ ctx.save();
+ ctx.globalCompositeOperation = 'screen';
+ ctx.fillStyle = 'rgb(128, 255, 128)'; // making it green
+ ctx.fillRect(0, 0, viewport.width, viewport.height);
+ ctx.restore();
+ ctx.drawImage(textLayerCanvas, 0, 0);
+ }
+ page.cleanup();
task.stats = page.stats;
page.stats = new StatTimer();
self._snapshot(task, error);
diff --git a/test/test_manifest.json b/test/test_manifest.json
index d478031..1bb299c 100644
--- a/test/test_manifest.json
+++ b/test/test_manifest.json
@@ -323,12 +323,6 @@
"lastPage": 1,
"about": "The same file as issue2337."
},
- { "id": "thuluthfont-text",
- "file": "pdfs/ThuluthFeatures.pdf",
- "md5": "b7e18bf7a3d6a9c82aefa12d721072fc",
- "rounds": 1,
- "type": "text"
- },
{ "id": "freeculture",
"file": "pdfs/freeculture.pdf",
"md5": "dcdf3a8268e6a18938a42d5149efcfca",
diff --git a/test/text_layer_test.css b/test/text_layer_test.css
new file mode 100644
index 0000000..ed62e6c
--- /dev/null
+++ b/test/text_layer_test.css
@@ -0,0 +1,38 @@
+/* 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 in 'text' tests */
+
+.textLayer {
+ position: absolute;
+ left: 0;
+ top: 0;
+ right: 0;
+ bottom: 0;
+}
+.textLayer > div {
+ position: absolute;
+ white-space: pre;
+ -webkit-transform-origin: 0% 0%;
+ -moz-transform-origin: 0% 0%;
+ -o-transform-origin: 0% 0%;
+ -ms-transform-origin: 0% 0%;
+ transform-origin: 0% 0%;
+ border: solid 1px rgba(255, 0, 0, 0.5);
+ background-color: rgba(255, 255, 32, 0.1);
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
diff --git a/web/viewer.css b/web/viewer.css
index b012631..b782684 100644
--- a/web/viewer.css
+++ b/web/viewer.css
@@ -1515,7 +1515,27 @@ html[dir='rtl'] #documentPropertiesOverlay .row > * {
font-size: 10px;
}
-#viewer.textLayer-visible .textLayer > div,
+#viewer.textLayer-visible .textLayer {
+ opacity: 1.0;
+}
+
+#viewer.textLayer-visible .canvasWrapper {
+ background-color: rgb(128,255,128);
+}
+
+#viewer.textLayer-visible .canvasWrapper canvas {
+ mix-blend-mode: screen;
+}
+
+#viewer.textLayer-visible .textLayer > div {
+ background-color: rgba(255, 255, 0, 0.1);
+ color: black;
+ border: solid 1px rgba(255, 0, 0, 0.5);
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
#viewer.textLayer-hover .textLayer > div:hover {
background-color: white;
color: black;
--
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