mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-20 15:18:08 +02:00
Build the text layer geometry on the worker.
This commit is contained in:
parent
af536353d5
commit
5bd8a83c9b
10 changed files with 404 additions and 416 deletions
|
@ -485,8 +485,8 @@ var PageView = function pageView(container, id, scale,
|
|||
if (!PDFJS.disableTextLayer) {
|
||||
textLayerDiv = document.createElement('div');
|
||||
textLayerDiv.className = 'textLayer';
|
||||
textLayerDiv.style.width = canvas.width + 'px';
|
||||
textLayerDiv.style.height = canvas.height + 'px';
|
||||
textLayerDiv.style.width = canvas.style.width;
|
||||
textLayerDiv.style.height = canvas.style.height;
|
||||
div.appendChild(textLayerDiv);
|
||||
}
|
||||
var textLayer = this.textLayer =
|
||||
|
@ -503,14 +503,6 @@ var PageView = function pageView(container, id, scale,
|
|||
if (outputScale.scaled) {
|
||||
ctx.scale(outputScale.sx, outputScale.sy);
|
||||
}
|
||||
if (outputScale.scaled && textLayerDiv) {
|
||||
var cssScale = 'scale(' + (1 / outputScale.sx) + ', ' +
|
||||
(1 / outputScale.sy) + ')';
|
||||
CustomStyle.setProp('transform' , textLayerDiv, cssScale);
|
||||
CustomStyle.setProp('transformOrigin' , textLayerDiv, '0% 0%');
|
||||
textLayerDiv.dataset._scaleX = outputScale.sx;
|
||||
textLayerDiv.dataset._scaleY = outputScale.sy;
|
||||
}
|
||||
|
||||
// Rendering area
|
||||
|
||||
|
@ -600,20 +592,19 @@ var PageView = function pageView(container, id, scale,
|
|||
this.renderTask.promise.then(
|
||||
function pdfPageRenderCallback() {
|
||||
pageViewDrawCallback(null);
|
||||
if (textLayer) {
|
||||
self.getTextContent().then(
|
||||
function textContentResolved(textContent) {
|
||||
textLayer.setTextContent(textContent);
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
function pdfPageRenderError(error) {
|
||||
pageViewDrawCallback(error);
|
||||
}
|
||||
);
|
||||
|
||||
if (textLayer) {
|
||||
this.getTextContent().then(
|
||||
function textContentResolved(textContent) {
|
||||
textLayer.setTextContent(textContent);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
setupAnnotations(div, pdfPage, this.viewport);
|
||||
div.setAttribute('data-loaded', true);
|
||||
};
|
||||
|
|
|
@ -145,11 +145,12 @@ var PDFFindController = {
|
|||
var self = this;
|
||||
function extractPageText(pageIndex) {
|
||||
self.pdfPageSource.pages[pageIndex].getTextContent().then(
|
||||
function textContentResolved(bidiTexts) {
|
||||
function textContentResolved(textContent) {
|
||||
var textItems = textContent.items;
|
||||
var str = '';
|
||||
|
||||
for (var i = 0; i < bidiTexts.length; i++) {
|
||||
str += bidiTexts[i].str;
|
||||
for (var i = 0; i < textItems.length; i++) {
|
||||
str += textItems[i].str;
|
||||
}
|
||||
|
||||
// Store the pageContent as a string.
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/* globals CustomStyle, PDFFindController, scrollIntoView */
|
||||
/* globals CustomStyle, PDFFindController, scrollIntoView, PDFJS */
|
||||
|
||||
'use strict';
|
||||
|
||||
|
@ -40,6 +40,7 @@ var TextLayerBuilder = function textLayerBuilder(options) {
|
|||
this.lastScrollSource = options.lastScrollSource;
|
||||
this.viewport = options.viewport;
|
||||
this.isViewerInPresentationMode = options.isViewerInPresentationMode;
|
||||
this.textDivs = [];
|
||||
|
||||
if (typeof PDFFindController === 'undefined') {
|
||||
window.PDFFindController = null;
|
||||
|
@ -49,16 +50,6 @@ var TextLayerBuilder = function textLayerBuilder(options) {
|
|||
this.lastScrollSource = null;
|
||||
}
|
||||
|
||||
this.beginLayout = function textLayerBuilderBeginLayout() {
|
||||
this.textDivs = [];
|
||||
this.renderingDone = false;
|
||||
};
|
||||
|
||||
this.endLayout = function textLayerBuilderEndLayout() {
|
||||
this.layoutDone = true;
|
||||
this.insertDivContent();
|
||||
};
|
||||
|
||||
this.renderLayer = function textLayerBuilderRenderLayer() {
|
||||
var textDivs = this.textDivs;
|
||||
var canvas = document.createElement('canvas');
|
||||
|
@ -118,70 +109,56 @@ var TextLayerBuilder = function textLayerBuilder(options) {
|
|||
}
|
||||
};
|
||||
|
||||
this.appendText = function textLayerBuilderAppendText(geom) {
|
||||
this.appendText = function textLayerBuilderAppendText(geom, styles) {
|
||||
var style = styles[geom.fontName];
|
||||
var textDiv = document.createElement('div');
|
||||
if (!/\S/.test(geom.str)) {
|
||||
textDiv.dataset.isWhitespace = true;
|
||||
return;
|
||||
}
|
||||
var tx = PDFJS.Util.transform(this.viewport.transform, geom.transform);
|
||||
var angle = Math.atan2(tx[1], tx[0]);
|
||||
if (style.vertical) {
|
||||
angle += Math.PI / 2;
|
||||
}
|
||||
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));
|
||||
|
||||
// vScale and hScale already contain the scaling to pixel units
|
||||
var fontHeight = geom.fontSize * Math.abs(geom.vScale);
|
||||
textDiv.dataset.canvasWidth = geom.canvasWidth * Math.abs(geom.hScale);
|
||||
textDiv.dataset.fontName = geom.fontName;
|
||||
textDiv.dataset.angle = geom.angle * (180 / Math.PI);
|
||||
|
||||
textDiv.style.position = 'absolute';
|
||||
textDiv.style.left = (tx[4] + (fontAscent * Math.sin(angle))) + 'px';
|
||||
textDiv.style.top = (tx[5] - (fontAscent * Math.cos(angle))) + 'px';
|
||||
textDiv.style.fontSize = fontHeight + 'px';
|
||||
textDiv.style.fontFamily = geom.fontFamily;
|
||||
var fontAscent = (geom.ascent ? geom.ascent * fontHeight :
|
||||
(geom.descent ? (1 + geom.descent) * fontHeight : fontHeight));
|
||||
textDiv.style.left = (geom.x + (fontAscent * Math.sin(geom.angle))) + 'px';
|
||||
textDiv.style.top = (geom.y - (fontAscent * Math.cos(geom.angle))) + 'px';
|
||||
textDiv.style.fontFamily = style.fontFamily;
|
||||
|
||||
// The content of the div is set in the `setTextContent` function.
|
||||
textDiv.textContent = geom.str;
|
||||
textDiv.dataset.fontName = geom.fontName;
|
||||
textDiv.dataset.angle = angle * (180 / Math.PI);
|
||||
if (style.vertical) {
|
||||
textDiv.dataset.canvasWidth = geom.height * this.viewport.scale;
|
||||
} else {
|
||||
textDiv.dataset.canvasWidth = geom.width * this.viewport.scale;
|
||||
}
|
||||
|
||||
this.textDivs.push(textDiv);
|
||||
};
|
||||
|
||||
this.insertDivContent = function textLayerUpdateTextContent() {
|
||||
// Only set the content of the divs once layout has finished, the content
|
||||
// for the divs is available and content is not yet set on the divs.
|
||||
if (!this.layoutDone || this.divContentDone || !this.textContent) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.divContentDone = true;
|
||||
|
||||
var textDivs = this.textDivs;
|
||||
var bidiTexts = this.textContent;
|
||||
|
||||
for (var i = 0; i < bidiTexts.length; i++) {
|
||||
var bidiText = bidiTexts[i];
|
||||
var textDiv = textDivs[i];
|
||||
if (!/\S/.test(bidiText.str)) {
|
||||
textDiv.dataset.isWhitespace = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
textDiv.textContent = bidiText.str;
|
||||
// TODO refactor text layer to use text content position
|
||||
/**
|
||||
* var arr = this.viewport.convertToViewportPoint(bidiText.x, bidiText.y);
|
||||
* textDiv.style.left = arr[0] + 'px';
|
||||
* textDiv.style.top = arr[1] + 'px';
|
||||
*/
|
||||
// bidiText.dir may be 'ttb' for vertical texts.
|
||||
textDiv.dir = bidiText.dir;
|
||||
}
|
||||
|
||||
this.setupRenderLayoutTimer();
|
||||
};
|
||||
|
||||
this.setTextContent = function textLayerBuilderSetTextContent(textContent) {
|
||||
this.textContent = textContent;
|
||||
this.insertDivContent();
|
||||
|
||||
var textItems = textContent.items;
|
||||
for (var i = 0; i < textItems.length; i++) {
|
||||
this.appendText(textItems[i], textContent.styles);
|
||||
}
|
||||
this.divContentDone = true;
|
||||
|
||||
this.setupRenderLayoutTimer();
|
||||
};
|
||||
|
||||
this.convertMatches = function textLayerBuilderConvertMatches(matches) {
|
||||
var i = 0;
|
||||
var iIndex = 0;
|
||||
var bidiTexts = this.textContent;
|
||||
var bidiTexts = this.textContent.items;
|
||||
var end = bidiTexts.length - 1;
|
||||
var queryLen = (PDFFindController === null ?
|
||||
0 : PDFFindController.state.query.length);
|
||||
|
@ -240,7 +217,7 @@ var TextLayerBuilder = function textLayerBuilder(options) {
|
|||
return;
|
||||
}
|
||||
|
||||
var bidiTexts = this.textContent;
|
||||
var bidiTexts = this.textContent.items;
|
||||
var textDivs = this.textDivs;
|
||||
var prevEnd = null;
|
||||
var isSelectedPage = (PDFFindController === null ?
|
||||
|
@ -356,7 +333,7 @@ var TextLayerBuilder = function textLayerBuilder(options) {
|
|||
// Clear out all matches.
|
||||
var matches = this.matches;
|
||||
var textDivs = this.textDivs;
|
||||
var bidiTexts = this.textContent;
|
||||
var bidiTexts = this.textContent.items;
|
||||
var clearedUntilDivIdx = -1;
|
||||
|
||||
// Clear out all current matches.
|
||||
|
|
|
@ -1286,7 +1286,6 @@ canvas {
|
|||
.textLayer > div {
|
||||
color: transparent;
|
||||
position: absolute;
|
||||
line-height: 1;
|
||||
white-space: pre;
|
||||
cursor: text;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue