|
@@ -1,202 +0,0 @@
|
|
|
-/**
|
|
|
- * Code extracted from pdf.js' viewer.js file. This contains code that is relevant to building the text overlays. I
|
|
|
- * have removed dependencies on viewer.js and viewer.html.
|
|
|
- *
|
|
|
- * -- Vivin Suresh Paliath (http://vivin.net)
|
|
|
- */
|
|
|
-
|
|
|
-var CustomStyle = (function CustomStyleClosure() {
|
|
|
-
|
|
|
- // As noted on: http://www.zachstronaut.com/posts/2009/02/17/
|
|
|
- // animate-css-transforms-firefox-webkit.html
|
|
|
- // in some versions of IE9 it is critical that ms appear in this list
|
|
|
- // before Moz
|
|
|
- var prefixes = ['ms', 'Moz', 'Webkit', 'O'];
|
|
|
- var _cache = { };
|
|
|
-
|
|
|
- function CustomStyle() {
|
|
|
- }
|
|
|
-
|
|
|
- CustomStyle.getProp = function get(propName, element) {
|
|
|
- // check cache only when no element is given
|
|
|
- if (arguments.length == 1 && typeof _cache[propName] == 'string') {
|
|
|
- return _cache[propName];
|
|
|
- }
|
|
|
-
|
|
|
- element = element || document.documentElement;
|
|
|
- var style = element.style, prefixed, uPropName;
|
|
|
-
|
|
|
- // test standard property first
|
|
|
- if (typeof style[propName] == 'string') {
|
|
|
- return (_cache[propName] = propName);
|
|
|
- }
|
|
|
-
|
|
|
- // capitalize
|
|
|
- uPropName = propName.charAt(0).toUpperCase() + propName.slice(1);
|
|
|
-
|
|
|
- // test vendor specific properties
|
|
|
- for (var i = 0, l = prefixes.length; i < l; i++) {
|
|
|
- prefixed = prefixes[i] + uPropName;
|
|
|
- if (typeof style[prefixed] == 'string') {
|
|
|
- return (_cache[propName] = prefixed);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //if all fails then set to undefined
|
|
|
- return (_cache[propName] = 'undefined');
|
|
|
- };
|
|
|
-
|
|
|
- CustomStyle.setProp = function set(propName, element, str) {
|
|
|
- var prop = this.getProp(propName);
|
|
|
- if (prop != 'undefined')
|
|
|
- element.style[prop] = str;
|
|
|
- };
|
|
|
-
|
|
|
- return CustomStyle;
|
|
|
-})();
|
|
|
-
|
|
|
-var TextLayerBuilder = function textLayerBuilder(textLayerDiv, pageIdx) {
|
|
|
- var textLayerFrag = document.createDocumentFragment();
|
|
|
-
|
|
|
- this.textLayerDiv = textLayerDiv;
|
|
|
- this.layoutDone = false;
|
|
|
- this.divContentDone = false;
|
|
|
- this.pageIdx = pageIdx;
|
|
|
- this.matches = [];
|
|
|
-
|
|
|
- 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 bidiTexts = this.textContent.bidiTexts;
|
|
|
- var textLayerDiv = this.textLayerDiv;
|
|
|
- var canvas = document.createElement('canvas');
|
|
|
- var ctx = canvas.getContext('2d');
|
|
|
-
|
|
|
- // No point in rendering so many divs as it'd make the browser unusable
|
|
|
- // even after the divs are rendered
|
|
|
- var MAX_TEXT_DIVS_TO_RENDER = 100000;
|
|
|
- if (textDivs.length > MAX_TEXT_DIVS_TO_RENDER)
|
|
|
- return;
|
|
|
-
|
|
|
- for (var i = 0, ii = textDivs.length; i < ii; i++) {
|
|
|
- var textDiv = textDivs[i];
|
|
|
- if ('isWhitespace' in textDiv.dataset) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- textLayerFrag.appendChild(textDiv);
|
|
|
-
|
|
|
- ctx.font = textDiv.style.fontSize + ' ' + textDiv.style.fontFamily;
|
|
|
- var width = ctx.measureText(textDiv.textContent).width;
|
|
|
-
|
|
|
- if (width > 0) {
|
|
|
- var textScale = textDiv.dataset.canvasWidth / width;
|
|
|
-
|
|
|
- var transform = 'scale(' + textScale + ', 1)';
|
|
|
- if (bidiTexts[i].dir === 'ttb') {
|
|
|
- transform = 'rotate(90deg) ' + transform;
|
|
|
- }
|
|
|
- CustomStyle.setProp('transform', textDiv, transform);
|
|
|
- CustomStyle.setProp('transformOrigin', textDiv, '0% 0%');
|
|
|
-
|
|
|
- textLayerDiv.appendChild(textDiv);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- this.renderingDone = true;
|
|
|
-
|
|
|
- textLayerDiv.appendChild(textLayerFrag);
|
|
|
- };
|
|
|
-
|
|
|
- this.setupRenderLayoutTimer = function textLayerSetupRenderLayoutTimer() {
|
|
|
- // Schedule renderLayout() if user has been scrolling, otherwise
|
|
|
- // run it right away
|
|
|
- var RENDER_DELAY = 200; // in ms
|
|
|
- var self = this;
|
|
|
- //0 was originally PDFView.lastScroll
|
|
|
- if (Date.now() - 0 > RENDER_DELAY) {
|
|
|
- // Render right away
|
|
|
- this.renderLayer();
|
|
|
- } else {
|
|
|
- // Schedule
|
|
|
- if (this.renderTimer)
|
|
|
- clearTimeout(this.renderTimer);
|
|
|
- this.renderTimer = setTimeout(function () {
|
|
|
- self.setupRenderLayoutTimer();
|
|
|
- }, RENDER_DELAY);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- this.appendText = function textLayerBuilderAppendText(geom) {
|
|
|
- var textDiv = document.createElement('div');
|
|
|
-
|
|
|
- // vScale and hScale already contain the scaling to pixel units
|
|
|
- var fontHeight = geom.fontSize * Math.abs(geom.vScale);
|
|
|
- textDiv.dataset.canvasWidth = geom.canvasWidth * geom.hScale;
|
|
|
- textDiv.dataset.fontName = geom.fontName;
|
|
|
-
|
|
|
- textDiv.style.fontSize = fontHeight + 'px';
|
|
|
- textDiv.style.fontFamily = geom.fontFamily;
|
|
|
- textDiv.style.left = geom.x + 'px';
|
|
|
- textDiv.style.top = (geom.y - fontHeight) + 'px';
|
|
|
-
|
|
|
- // The content of the div is set in the `setTextContent` function.
|
|
|
-
|
|
|
- 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.bidiTexts;
|
|
|
-
|
|
|
- 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;
|
|
|
- // bidiText.dir may be 'ttb' for vertical texts.
|
|
|
- textDiv.dir = bidiText.dir === 'rtl' ? 'rtl' : 'ltr';
|
|
|
- }
|
|
|
-
|
|
|
- this.setupRenderLayoutTimer();
|
|
|
- };
|
|
|
-
|
|
|
- this.setTextContent = function textLayerBuilderSetTextContent(textContent) {
|
|
|
- this.textContent = textContent;
|
|
|
- this.insertDivContent();
|
|
|
- };
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * Returns scale factor for the canvas. It makes sense for the HiDPI displays.
|
|
|
- * @return {Object} The object with horizontal (sx) and vertical (sy)
|
|
|
- scales. The scaled property is set to false if scaling is
|
|
|
- not required, true otherwise.
|
|
|
- */
|
|
|
-function getOutputScale() {
|
|
|
- var pixelRatio = 'devicePixelRatio' in window ? window.devicePixelRatio : 1;
|
|
|
- return {
|
|
|
- sx: pixelRatio,
|
|
|
- sy: pixelRatio,
|
|
|
- scaled: pixelRatio != 1
|
|
|
- };
|
|
|
-}
|