From 0f6291c7b9361fc8c9b6eb2223034b17b78f3df2 Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Sun, 18 Dec 2011 12:53:30 -0600 Subject: [PATCH 1/3] Move text layer UI to viewer.js; fixes adding div with single char; replaces innerHTML to textContent --- src/canvas.js | 50 +++++++------------------------------------------- web/viewer.js | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 44 deletions(-) diff --git a/src/canvas.js b/src/canvas.js index cd49c88b1..75165855c 100644 --- a/src/canvas.js +++ b/src/canvas.js @@ -255,8 +255,9 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { } // Scale so that canvas units are the same as PDF user space units this.ctx.scale(cw / mediaBox.width, ch / mediaBox.height); - this.textDivs = []; - this.textLayerQueue = []; + + if (this.textLayer) + this.textLayer.beginLayout(); }, executeIRQueue: function canvasGraphicsExecuteIRQueue(codeIR, @@ -320,27 +321,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { endDrawing: function canvasGraphicsEndDrawing() { this.ctx.restore(); - var textLayer = this.textLayer; - if (!textLayer) - return; - - var self = this; - var textDivs = this.textDivs; - this.textLayerTimer = setInterval(function renderTextLayer() { - if (textDivs.length === 0) { - clearInterval(self.textLayerTimer); - return; - } - var textDiv = textDivs.shift(); - if (textDiv.dataset.textLength > 1) { // avoid div by zero - textLayer.appendChild(textDiv); - // Adjust div width (via letterSpacing) to match canvas text - // Due to the .offsetWidth calls, this is slow - textDiv.style.letterSpacing = - ((textDiv.dataset.canvasWidth - textDiv.offsetWidth) / - (textDiv.dataset.textLength - 1)) + 'px'; - } - }, 0); + if (this.textLayer) + this.textLayer.endLayout(); }, // Graphics state @@ -630,24 +612,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { return geometry; }, - pushTextDivs: function canvasGraphicsPushTextDivs(text) { - var div = document.createElement('div'); - var fontSize = this.current.fontSize; - - // vScale and hScale already contain the scaling to pixel units - // as mozCurrentTransform reflects ctx.scale() changes - // (see beginDrawing()) - var fontHeight = fontSize * text.geom.vScale; - div.dataset.canvasWidth = text.canvasWidth * text.geom.hScale; - - div.style.fontSize = fontHeight + 'px'; - div.style.fontFamily = this.current.font.loadedName || 'sans-serif'; - div.style.left = text.geom.x + 'px'; - div.style.top = (text.geom.y - fontHeight) + 'px'; - div.innerHTML = text.str; - div.dataset.textLength = text.length; - this.textDivs.push(div); - }, showText: function canvasGraphicsShowText(str, skipTextSelection) { var ctx = this.ctx; var current = this.current; @@ -753,7 +717,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { } if (textSelection) - this.pushTextDivs(text); + this.textLayer.appendText(text, font.loadedName, fontSize); return text; }, @@ -819,7 +783,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { } if (textSelection) - this.pushTextDivs(text); + this.textLayer.appendText(text, font.loadedName, fontSize); }, nextLineShowText: function canvasGraphicsNextLineShowText(text) { this.nextLine(); diff --git a/web/viewer.js b/web/viewer.js index daf0174ab..afaf03e04 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -595,7 +595,7 @@ var PageView = function pageView(container, content, id, pageWidth, pageHeight, this.updateStats(); if (this.onAfterDraw) this.onAfterDraw(); - }).bind(this), textLayer + }).bind(this), new TextLayerBuilder(textLayer) ); setupLinks(this.content, this.scale); @@ -726,6 +726,53 @@ var DocumentOutlineView = function documentOutlineView(outline) { } }; +var TextLayerBuilder = function textLayerBuilder(textLayerDiv) { + this.textLayerDiv = textLayerDiv; + + this.beginLayout = function textLayerBuilderBeginLayout() { + this.textDivs = []; + this.textLayerQueue = []; + }; + + this.endLayout = function textLayerBuilderEndLayout() { + var self = this; + var textDivs = this.textDivs; + var textLayerDiv = this.textLayerDiv; + this.textLayerTimer = setInterval(function renderTextLayer() { + if (textDivs.length === 0) { + clearInterval(self.textLayerTimer); + return; + } + var textDiv = textDivs.shift(); + if (textDiv.dataset.textLength >= 1) { // avoid div by zero + textLayerDiv.appendChild(textDiv); + // Adjust div width (via letterSpacing) to match canvas text + // Due to the .offsetWidth calls, this is slow + textDiv.style.letterSpacing = + ((textDiv.dataset.canvasWidth - textDiv.offsetWidth) / + (textDiv.dataset.textLength - 1)) + 'px'; + } + }, 0); + }; + + this.appendText = function textLayerBuilderAppendText(text, + fontName, fontSize) { + var textDiv = document.createElement('div'); + + // vScale and hScale already contain the scaling to pixel units + var fontHeight = fontSize * text.geom.vScale; + textDiv.dataset.canvasWidth = text.canvasWidth * text.geom.hScale; + + textDiv.style.fontSize = fontHeight + 'px'; + textDiv.style.fontFamily = fontName || 'sans-serif'; + textDiv.style.left = text.geom.x + 'px'; + textDiv.style.top = (text.geom.y - fontHeight) + 'px'; + textDiv.textContent = text.str; + textDiv.dataset.textLength = text.length; + this.textDivs.push(textDiv); + }; +}; + window.addEventListener('load', function webViewerLoad(evt) { var params = document.location.search.substring(1).split('&'); for (var i = 0; i < params.length; i++) { From a52aacab5a8925350e3208a575080f243ff48ccf Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Sun, 18 Dec 2011 16:15:53 -0600 Subject: [PATCH 2/3] Fix the text layer testing --- test/driver.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/test/driver.js b/test/driver.js index 64fceee90..85d25658a 100644 --- a/test/driver.js +++ b/test/driver.js @@ -165,9 +165,14 @@ function nextPage(task, loadError) { canvas.height = pageHeight * pdfToCssUnitsCoef; clear(ctx); - // using non-attached to the document div to test + // using the text layer builder that does nothing to test // text layer creation operations - var textLayer = document.createElement('div'); + var textLayerBuilder = { + beginLayout: function nullTextLayerBuilderBeginLayout() {}, + endLayout: function nullTextLayerBuilderEndLayout() {}, + appendText: function nullTextLayerBuilderAppendText(text, fontName, + fontSize) {} + }; page.startRendering( ctx, @@ -177,7 +182,7 @@ function nextPage(task, loadError) { failureMessage = 'render : ' + error.message; snapshotCurrentPage(task, failureMessage); }, - textLayer + textLayerBuilder ); } catch (e) { failure = 'page setup : ' + e.toString(); From cbf4c0393f4296cf24b1898b7f795ee8033f5b11 Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Fri, 30 Dec 2011 19:32:35 -0600 Subject: [PATCH 3/3] Replace nbsp entity with character code --- src/canvas.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/canvas.js b/src/canvas.js index 0f7abdddf..a1c4fb40c 100644 --- a/src/canvas.js +++ b/src/canvas.js @@ -711,7 +711,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { width += charWidth; - text.str += glyph.unicode === ' ' ? ' ' : glyph.unicode; + text.str += glyph.unicode === ' ' ? '\u00A0' : glyph.unicode; text.length++; text.canvasWidth += charWidth; } @@ -763,7 +763,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { if (e < 0 && text.geom.spaceWidth > 0) { // avoid div by zero var numFakeSpaces = Math.round(-e / text.geom.spaceWidth); if (numFakeSpaces > 0) { - text.str += ' '; + text.str += '\u00A0'; text.length++; } } @@ -773,7 +773,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { if (textSelection) { if (shownText.str === ' ') { - text.str += ' '; + text.str += '\u00A0'; } else { text.str += shownText.str; }