merge with remote

This commit is contained in:
Chris Jones 2011-06-30 02:14:47 -07:00
commit 49058c9174
9 changed files with 151 additions and 99 deletions

145
fonts.js
View File

@ -34,65 +34,89 @@ var kDisableFonts = false;
* http://cgit.freedesktop.org/poppler/poppler/tree/poppler/GfxFont.cc#n65 * http://cgit.freedesktop.org/poppler/poppler/tree/poppler/GfxFont.cc#n65
*/ */
var kScalePrecision = 40; var Fonts = (function () {
var Fonts = { var kScalePrecision = 40;
_active: null, var fonts = Object.create(null);
var ctx = document.createElement("canvas").getContext("2d");
ctx.scale(1 / kScalePrecision, 1);
get active() { function Font(name, data, properties) {
return this._active; this.name = name;
}, this.data = data;
this.properties = properties;
this.loading = true;
this.charsCache = Object.create(null);
this.sizes = [];
}
setActive: function fonts_setActive(name, size) { var current;
this._active = this[name]; var charsCache;
this.ctx.font = (size * kScalePrecision) + 'px "' + name + '"'; var measureCache;
},
charsToUnicode: function fonts_chars2Unicode(chars) { return {
var active = this._active; registerFont: function fonts_registerFont(fontName, data, properties) {
if (!active) fonts[fontName] = new Font(fontName, data, properties);
return chars; },
blacklistFont: function fonts_blacklistFont(fontName) {
registerFont(fontName, null, {});
markLoaded(fontName);
},
lookup: function fonts_lookup(fontName) {
return fonts[fontName];
},
setActive: function fonts_setActive(fontName, size) {
current = fonts[fontName];
charsCache = current.charsCache;
var sizes = current.sizes;
if (!(measureCache = sizes[size]))
measureCache = sizes[size] = Object.create(null);
ctx.font = (size * kScalePrecision) + 'px "' + fontName + '"';
},
charsToUnicode: function fonts_chars2Unicode(chars) {
if (!charsCache)
return chars;
// if we translated this string before, just grab it from the cache // if we translated this string before, just grab it from the cache
var str = active.cache[chars]; var str = charsCache[chars];
if (str) if (str)
return str; return str;
// translate the string using the font's encoding // translate the string using the font's encoding
var encoding = active.properties.encoding; var encoding = current.properties.encoding;
if (!encoding) if (!encoding)
return chars; return chars;
str = ""; str = "";
for (var i = 0; i < chars.length; ++i) { for (var i = 0; i < chars.length; ++i) {
var charcode = chars.charCodeAt(i); var charcode = chars.charCodeAt(i);
var unicode = encoding[charcode]; var unicode = encoding[charcode];
// Check if the glyph has already been converted // Check if the glyph has already been converted
if (!IsNum(unicode)) if (!IsNum(unicode))
unicode = encoding[unicode] = GlyphsUnicode[unicode.name]; unicode = encoding[unicode] = GlyphsUnicode[unicode.name];
// Handle surrogate pairs // Handle surrogate pairs
if (unicode > 0xFFFF) { if (unicode > 0xFFFF) {
str += String.fromCharCode(unicode & 0xFFFF); str += String.fromCharCode(unicode & 0xFFFF);
unicode >>= 16; unicode >>= 16;
}
str += String.fromCharCode(unicode);
} }
str += String.fromCharCode(unicode);
// Enter the translated string into the cache
return charsCache[chars] = str;
},
measureText: function fonts_measureText(text) {
var width;
if (measureCache && (width = measureCache[text]))
return width;
width = ctx.measureText(text).width / kScalePrecision;
if (measureCache)
measureCache[text] = width;
return width;
} }
// Enter the translated string into the cache
return active.cache[chars] = str;
},
get ctx() {
var ctx = document.createElement("canvas").getContext("2d");
ctx.scale(1 / kScalePrecision, 1);
return shadow(this, "ctx", ctx);
},
measureText: function fonts_measureText(text) {
return this.ctx.measureText(text).width / kScalePrecision;
} }
}; })();
var FontLoader = { var FontLoader = {
bind: function(fonts, callback) { bind: function(fonts, callback) {
@ -101,7 +125,7 @@ var FontLoader = {
function checkFontsLoaded() { function checkFontsLoaded() {
for (var i = 0; i < fonts.length; i++) { for (var i = 0; i < fonts.length; i++) {
var font = fonts[i]; var font = fonts[i];
if (Fonts[font.name].loading) { if (Fonts.lookup(font.name).loading) {
return false; return false;
} }
} }
@ -115,11 +139,11 @@ var FontLoader = {
for (var i = 0; i < fonts.length; i++) { for (var i = 0; i < fonts.length; i++) {
var font = fonts[i]; var font = fonts[i];
if (!Fonts[font.name]) { if (!Fonts.lookup(font.name)) {
var obj = new Font(font.name, font.file, font.properties); var obj = new Font(font.name, font.file, font.properties);
var str = ""; var str = "";
var data = Fonts[font.name].data; var data = Fonts.lookup(font.name).data;
var length = data.length; var length = data.length;
for (var j = 0; j < length; j++) for (var j = 0; j < length; j++)
str += String.fromCharCode(data[j]); str += String.fromCharCode(data[j]);
@ -152,8 +176,8 @@ var Font = (function () {
this.encoding = properties.encoding; this.encoding = properties.encoding;
// If the font has already been decoded simply return it // If the font has already been decoded simply return it
if (Fonts[name]) { if (Fonts.lookup(name)) {
this.font = Fonts[name].data; this.font = Fonts.lookup(name).data;
return; return;
} }
fontCount++; fontCount++;
@ -162,12 +186,7 @@ var Font = (function () {
// If the font is to be ignored, register it like an already loaded font // If the font is to be ignored, register it like an already loaded font
// to avoid the cost of waiting for it be be loaded by the platform. // to avoid the cost of waiting for it be be loaded by the platform.
if (properties.ignore || kDisableFonts) { if (properties.ignore || kDisableFonts) {
Fonts[name] = { Fonts.blacklistFont(name);
data: file,
loading: false,
properties: {},
cache: Object.create(null)
}
return; return;
} }
@ -194,13 +213,7 @@ var Font = (function () {
break; break;
} }
this.data = data; this.data = data;
Fonts.registerFont(name, data, properties);
Fonts[name] = {
data: data,
properties: properties,
loading: true,
cache: Object.create(null)
};
}; };
function stringToArray(str) { function stringToArray(str) {
@ -854,7 +867,7 @@ var Font = (function () {
src += ' var fontName="'+ fontName +'";\n'; src += ' var fontName="'+ fontName +'";\n';
src += ' window.onload = function () {\n' src += ' window.onload = function () {\n'
src += ' var Fonts = top.document.defaultView.Fonts;\n'; src += ' var Fonts = top.document.defaultView.Fonts;\n';
src += ' var font = Fonts[fontName];\n'; src += ' var font = Fonts.lookup(fontName);\n';
src += ' font.loading = false;\n'; src += ' font.loading = false;\n';
src += ' var doc = top.document;\n'; src += ' var doc = top.document;\n';
src += ' var evt = doc.createEvent("Events");\n'; src += ' var evt = doc.createEvent("Events");\n';

View File

@ -29,11 +29,15 @@ var PDFViewer = {
scale: 1.0, scale: 1.0,
pageWidth: function(page) { pageWidth: function(page) {
return page.mediaBox[2] * PDFViewer.scale; var pdfToCssUnitsCoef = 96.0 / 72.0;
var width = (page.mediaBox[2] - page.mediaBox[0]);
return width * PDFViewer.scale * pdfToCssUnitsCoef;
}, },
pageHeight: function(page) { pageHeight: function(page) {
return page.mediaBox[3] * PDFViewer.scale; var pdfToCssUnitsCoef = 96.0 / 72.0;
var height = (page.mediaBox[3] - page.mediaBox[1]);
return height * PDFViewer.scale * pdfToCssUnitsCoef;
}, },
lastPagesDrawn: [], lastPagesDrawn: [],
@ -106,10 +110,11 @@ var PDFViewer = {
canvas.id = 'thumbnail' + num; canvas.id = 'thumbnail' + num;
canvas.mozOpaque = true; canvas.mozOpaque = true;
// Canvas dimensions must be specified in CSS pixels. CSS pixels var pageWidth = PDFViewer.pageWidth(page);
// are always 96 dpi. These dimensions are 8.5in x 11in at 96dpi. var pageHeight = PDFViewer.pageHeight(page);
canvas.width = 104; var thumbScale = Math.min(104 / pageWidth, 134 / pageHeight);
canvas.height = 134; canvas.width = pageWidth * thumbScale;
canvas.height = pageHeight * thumbScale;
div.appendChild(canvas); div.appendChild(canvas);
var ctx = canvas.getContext('2d'); var ctx = canvas.getContext('2d');
@ -168,8 +173,6 @@ var PDFViewer = {
canvas.id = 'page' + num; canvas.id = 'page' + num;
canvas.mozOpaque = true; canvas.mozOpaque = true;
// Canvas dimensions must be specified in CSS pixels. CSS pixels
// are always 96 dpi. These dimensions are 8.5in x 11in at 96dpi.
canvas.width = PDFViewer.pageWidth(page); canvas.width = PDFViewer.pageWidth(page);
canvas.height = PDFViewer.pageHeight(page); canvas.height = PDFViewer.pageHeight(page);
div.appendChild(canvas); div.appendChild(canvas);
@ -260,6 +263,12 @@ var PDFViewer = {
openURL: function(url) { openURL: function(url) {
PDFViewer.url = url; PDFViewer.url = url;
document.title = url; document.title = url;
if (this.thumbsLoadingInterval) {
// cancel thumbs loading operations
clearInterval(this.thumbsLoadingInterval);
this.thumbsLoadingInterval = null;
}
var req = new XMLHttpRequest(); var req = new XMLHttpRequest();
req.open('GET', url); req.open('GET', url);
@ -276,7 +285,9 @@ var PDFViewer = {
req.send(null); req.send(null);
}, },
thumbsLoadingInterval: null,
readPDF: function(data) { readPDF: function(data) {
while (PDFViewer.element.hasChildNodes()) { while (PDFViewer.element.hasChildNodes()) {
PDFViewer.element.removeChild(PDFViewer.element.firstChild); PDFViewer.element.removeChild(PDFViewer.element.firstChild);
@ -298,12 +309,22 @@ var PDFViewer = {
PDFViewer.drawPage(1); PDFViewer.drawPage(1);
document.location.hash = 1; document.location.hash = 1;
setTimeout(function() { // slowly loading the thumbs (few per second)
for (var i = 1; i <= PDFViewer.numberOfPages; i++) { // first time we are loading more images than subsequent
PDFViewer.createThumbnail(i); var currentPageIndex = 1, imagesToLoad = 15;
PDFViewer.drawThumbnail(i); this.thumbsLoadingInterval = setInterval((function() {
while (imagesToLoad-- > 0) {
if (currentPageIndex > PDFViewer.numberOfPages) {
clearInterval(this.thumbsLoadingInterval);
this.thumbsLoadingInterval = null;
return;
}
PDFViewer.createThumbnail(currentPageIndex);
PDFViewer.drawThumbnail(currentPageIndex);
++currentPageIndex;
} }
}, 500); imagesToLoad = 3; // next time loading less images
}).bind(this), 500);
} }
PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? 'disabled' : ''; PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? 'disabled' : '';

View File

@ -4,6 +4,7 @@
<style type="text/css"></style> <style type="text/css"></style>
<script type="text/javascript" src="/pdf.js"></script> <script type="text/javascript" src="/pdf.js"></script>
<script type="text/javascript" src="/fonts.js"></script> <script type="text/javascript" src="/fonts.js"></script>
<script type="text/javascript" src="/crypto.js"></script>
<script type="text/javascript" src="/glyphlist.js"></script> <script type="text/javascript" src="/glyphlist.js"></script>
<script type="application/javascript"> <script type="application/javascript">
var appPath, browser, canvas, currentTask, currentTaskIdx, failure, manifest, numPages, pdfDoc, stdout; var appPath, browser, canvas, currentTask, currentTaskIdx, failure, manifest, numPages, pdfDoc, stdout;
@ -103,11 +104,12 @@ function nextPage() {
} }
try { try {
var pdfToCssUnitsCoef = 96.0 / 72.0;
// using mediaBox for the canvas size // using mediaBox for the canvas size
var wTwips = (currentPage.mediaBox[2] - currentPage.mediaBox[0]); var pageWidth = (currentPage.mediaBox[2] - currentPage.mediaBox[0]);
var hTwips = (currentPage.mediaBox[3] - currentPage.mediaBox[1]); var pageHeight = (currentPage.mediaBox[3] - currentPage.mediaBox[1]);
canvas.width = wTwips * 96.0 / 72.0; canvas.width = pageWidth * pdfToCssUnitsCoef;
canvas.height = hTwips * 96.0 / 72.0; canvas.height = pageHeight * pdfToCssUnitsCoef;
clear(ctx); clear(ctx);
} catch(e) { } catch(e) {
failure = 'page setup: '+ e.toString(); failure = 'page setup: '+ e.toString();

View File

@ -24,10 +24,11 @@ span#info {
} }
#viewer { #viewer {
}
#canvas {
margin: auto; margin: auto;
border: 1px solid black; display: block;
width: 12.75in;
height: 16.5in;
} }
#pageNumber { #pageNumber {

View File

@ -25,9 +25,7 @@
</div> </div>
<div id="viewer"> <div id="viewer">
<!-- Canvas dimensions must be specified in CSS pixels. CSS pixels <canvas id="canvas"></canvas>
are always 96 dpi. 816x1056 is 8.5x11in at 96dpi. -->
<canvas id="canvas" width="816" height="1056" defaultwidth="816" defaultheight="1056"></canvas>
</div> </div>
</body> </body>
</html> </html>

View File

@ -58,12 +58,12 @@ function displayPage(num) {
var t0 = Date.now(); var t0 = Date.now();
var page = pdfDocument.getPage(pageNum = num); var page = pdfDocument.getPage(pageNum = num);
canvas.width = parseInt(canvas.getAttribute("defaultwidth")) * pageScale;
canvas.height = parseInt(canvas.getAttribute("defaultheight")) * pageScale;
// scale canvas by 2 var pdfToCssUnitsCoef = 96.0 / 72.0;
canvas.width = 2 * page.mediaBox[2]; var pageWidth = (page.mediaBox[2] - page.mediaBox[0]);
canvas.hieght = 2 * page.mediaBox[3]; var pageHeight = (page.mediaBox[3] - page.mediaBox[1]);
canvas.width = pageScale * pageWidth * pdfToCssUnitsCoef;
canvas.height = pageScale * pageHeight * pdfToCssUnitsCoef;
var t1 = Date.now(); var t1 = Date.now();
var ctx = canvas.getContext("2d"); var ctx = canvas.getContext("2d");

View File

@ -39,10 +39,7 @@ window.onload = function() {
</div> </div>
<div id="viewer"> <div id="viewer">
<!-- Canvas dimensions must be specified in CSS pixels. CSS pixels <canvas id="canvas"></canvas>
are always 96 dpi. 816x1056 is 8.5x11in at 96dpi. -->
<!-- We're rendering here at 1.5x scale. -->
<canvas id="canvas" width="1224" height="1584"></canvas>
</div> </div>
</body> </body>
</html> </html>

View File

@ -306,6 +306,13 @@ function WorkerPDFDoc(canvas) {
document.body.appendChild(div); document.body.appendChild(div);
}, },
"setup_page": function(data) {
var size = data.split(",");
var canvas = this.canvas, ctx = this.ctx;
canvas.width = parseInt(size[0]);
canvas.height = parseInt(size[1]);
},
"fonts": function(data) { "fonts": function(data) {
this.waitingForFonts = true; this.waitingForFonts = true;
this.fontWorker.ensureFonts(data, function() { this.fontWorker.ensureFonts(data, function() {

View File

@ -31,6 +31,7 @@ importScripts("console.js")
importScripts("canvas.js"); importScripts("canvas.js");
importScripts("../pdf.js"); importScripts("../pdf.js");
importScripts("../fonts.js"); importScripts("../fonts.js");
importScripts("../crypto.js");
importScripts("../glyphlist.js") importScripts("../glyphlist.js")
// Use the JpegStreamProxy proxy. // Use the JpegStreamProxy proxy.
@ -59,6 +60,18 @@ onmessage = function(event) {
// Let's try to render the first page... // Let's try to render the first page...
var page = pdfDocument.getPage(parseInt(data)); var page = pdfDocument.getPage(parseInt(data));
var pdfToCssUnitsCoef = 96.0 / 72.0;
var pageWidth = (page.mediaBox[2] - page.mediaBox[0]) * pdfToCssUnitsCoef;
var pageHeight = (page.mediaBox[3] - page.mediaBox[1]) * pdfToCssUnitsCoef;
postMessage({
action: "setup_page",
data: pageWidth + "," + pageHeight
});
// Set canvas size.
canvas.width = pageWidth;
canvas.height = pageHeight;
// page.compile will collect all fonts for us, once we have loaded them // page.compile will collect all fonts for us, once we have loaded them
// we can trigger the actual page rendering with page.display // we can trigger the actual page rendering with page.display
var fonts = []; var fonts = [];