Merge branch 'master' of https://github.com/mozilla/pdf.js into xrefdict

This commit is contained in:
Brendan Dahl 2012-04-04 11:45:04 -07:00
commit 82a95d8bde
8 changed files with 175 additions and 61 deletions

View File

@ -752,28 +752,30 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
continue;
}
var char = glyph.fontChar;
var character = glyph.fontChar;
var charWidth = glyph.width * fontSize * 0.001 +
Util.sign(current.fontMatrix[0]) * charSpacing;
var scaledX = x / fontSizeScale;
switch (textRenderingMode) {
default: // other unsupported rendering modes
case TextRenderingMode.FILL:
case TextRenderingMode.FILL_ADD_TO_PATH:
ctx.fillText(char, scaledX, 0);
break;
case TextRenderingMode.STROKE:
case TextRenderingMode.STROKE_ADD_TO_PATH:
ctx.strokeText(char, scaledX, 0);
break;
case TextRenderingMode.FILL_STROKE:
case TextRenderingMode.FILL_STROKE_ADD_TO_PATH:
ctx.fillText(char, scaledX, 0);
ctx.strokeText(char, scaledX, 0);
break;
case TextRenderingMode.INVISIBLE:
break;
if (!glyph.disabled) {
var scaledX = x / fontSizeScale;
switch (textRenderingMode) {
default: // other unsupported rendering modes
case TextRenderingMode.FILL:
case TextRenderingMode.FILL_ADD_TO_PATH:
ctx.fillText(character, scaledX, 0);
break;
case TextRenderingMode.STROKE:
case TextRenderingMode.STROKE_ADD_TO_PATH:
ctx.strokeText(character, scaledX, 0);
break;
case TextRenderingMode.FILL_STROKE:
case TextRenderingMode.FILL_STROKE_ADD_TO_PATH:
ctx.fillText(character, scaledX, 0);
ctx.strokeText(character, scaledX, 0);
break;
case TextRenderingMode.INVISIBLE:
break;
}
}
x += charWidth;

View File

@ -533,9 +533,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
var cmap = cmapObj.getBytes(cmapObj.length);
for (var i = 0, ii = cmap.length; i < ii; i++) {
var byte = cmap[i];
if (byte == 0x20 || byte == 0x0D || byte == 0x0A ||
byte == 0x3C || byte == 0x5B || byte == 0x5D) {
var octet = cmap[i];
if (octet == 0x20 || octet == 0x0D || octet == 0x0A ||
octet == 0x3C || octet == 0x5B || octet == 0x5D) {
switch (token) {
case 'usecmap':
error('usecmap is not implemented');
@ -592,7 +592,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
tokens.push(token);
token = '';
}
switch (byte) {
switch (octet) {
case 0x5B:
// begin list parsing
tokens.push(beginArrayToken);
@ -606,7 +606,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
tokens.push(items);
break;
}
} else if (byte == 0x3E) {
} else if (octet == 0x3E) {
if (token.length) {
if (token.length <= 4) {
// parsing hex number
@ -632,7 +632,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
}
}
} else {
token += String.fromCharCode(byte);
token += String.fromCharCode(octet);
}
}
}

View File

@ -1828,8 +1828,9 @@ var Font = (function FontClosure() {
readGlyphNameMap(post, properties);
}
// Replace the old CMAP table with a shiny new one
var glyphs, ids;
if (properties.type == 'CIDFontType2') {
// Replace the old CMAP table with a shiny new one
// Type2 composite fonts map characters directly to glyphs so the cmap
// table must be replaced.
// canvas fillText will reencode some characters even if the font has a
@ -1861,7 +1862,9 @@ var Font = (function FontClosure() {
}
}
var glyphs = [], ids = [];
glyphs = [];
ids = [];
var usedUnicodes = [];
var unassignedUnicodeItems = [];
for (var i = 1; i < numGlyphs; i++) {
@ -1892,11 +1895,12 @@ var Font = (function FontClosure() {
glyphs.push({ unicode: unicode, code: cid });
ids.push(i);
}
cmap.data = createCMapTable(glyphs, ids);
} else {
var cmapTable = readCMapTable(cmap, font);
var glyphs = cmapTable.glyphs;
var ids = cmapTable.ids;
glyphs = cmapTable.glyphs;
ids = cmapTable.ids;
var hasShortCmap = !!cmapTable.hasShortCmap;
var toFontChar = this.toFontChar;
@ -2062,10 +2066,16 @@ var Font = (function FontClosure() {
createGlyphNameMap(glyphs, ids, properties);
this.glyphNameMap = properties.glyphNameMap;
cmap.data = createCMapTable(glyphs, ids);
}
// Converting glyphs and ids into font's cmap table
cmap.data = createCMapTable(glyphs, ids);
var unicodeIsEnabled = [];
for (var i = 0, ii = glyphs.length; i < ii; i++) {
unicodeIsEnabled[glyphs[i].unicode] = true;
}
this.unicodeIsEnabled = unicodeIsEnabled;
// Rewrite the 'post' table if needed
if (requiredTables.indexOf('post') != -1) {
tables.push({
@ -2391,7 +2401,7 @@ var Font = (function FontClosure() {
},
charToGlyph: function fonts_charToGlyph(charcode) {
var fontCharCode, width, operatorList;
var fontCharCode, width, operatorList, disabled;
var width = this.widths[charcode];
@ -2464,11 +2474,14 @@ var Font = (function FontClosure() {
unicodeChars = String.fromCharCode(unicodeChars);
width = (isNum(width) ? width : this.defaultWidth) * this.widthMultiplier;
disabled = this.unicodeIsEnabled ?
!this.unicodeIsEnabled[fontCharCode] : false;
return {
fontChar: String.fromCharCode(fontCharCode),
unicode: unicodeChars,
width: width,
disabled: disabled,
operatorList: operatorList
};
},
@ -2848,7 +2861,7 @@ var Type1Parser = function type1Parser() {
subrs: [],
charstrings: [],
properties: {
'private': {
'privateData': {
'lenIV': 4
}
}
@ -2877,7 +2890,7 @@ var Type1Parser = function type1Parser() {
(token == 'RD' || token == '-|')) {
i++;
var data = eexec.slice(i, i + length);
var lenIV = program.properties.private['lenIV'];
var lenIV = program.properties.privateData['lenIV'];
var encoded = decrypt(data, kCharStringsEncryptionKey, lenIV);
var str = decodeCharString(encoded);
@ -2917,7 +2930,7 @@ var Type1Parser = function type1Parser() {
var length = parseInt(getToken(), 10);
getToken(); // read in 'RD'
var data = eexec.slice(i + 1, i + 1 + length);
var lenIV = program.properties.private['lenIV'];
var lenIV = program.properties.privateData['lenIV'];
var encoded = decrypt(data, kCharStringsEncryptionKey, lenIV);
var str = decodeCharString(encoded);
i = i + 1 + length;
@ -2933,12 +2946,12 @@ var Type1Parser = function type1Parser() {
case '/FamilyOtherBlues':
case '/StemSnapH':
case '/StemSnapV':
program.properties.private[token.substring(1)] =
program.properties.privateData[token.substring(1)] =
readNumberArray(eexecStr, i + 1);
break;
case '/StdHW':
case '/StdVW':
program.properties.private[token.substring(1)] =
program.properties.privateData[token.substring(1)] =
readNumberArray(eexecStr, i + 2)[0];
break;
case '/BlueShift':
@ -2947,7 +2960,7 @@ var Type1Parser = function type1Parser() {
case '/BlueScale':
case '/LanguageGroup':
case '/ExpansionFactor':
program.properties.private[token.substring(1)] =
program.properties.privateData[token.substring(1)] =
readNumber(eexecStr, i + 1);
break;
}
@ -2971,14 +2984,14 @@ var Type1Parser = function type1Parser() {
var count = headerString.length;
for (var i = 0; i < count; i++) {
var getToken = function getToken() {
var char = headerString[i];
while (i < count && (isSeparator(char) || char == '/'))
char = headerString[++i];
var character = headerString[i];
while (i < count && (isSeparator(character) || character == '/'))
character = headerString[++i];
var token = '';
while (i < count && !(isSeparator(char) || char == '/')) {
token += char;
char = headerString[++i];
while (i < count && !(isSeparator(character) || character == '/')) {
token += character;
character = headerString[++i];
}
return token;
@ -3344,7 +3357,7 @@ Type1Font.prototype = {
dict += self.encodeNumber(offset) + '\x11'; // Charstrings
offset = offset + fields.charstrings.length;
dict += self.encodeNumber(fields.private.length);
dict += self.encodeNumber(fields.privateData.length);
dict += self.encodeNumber(offset) + '\x12'; // Private
return header + String.fromCharCode(dict.length + 1) + dict;
@ -3385,7 +3398,7 @@ Type1Font.prototype = {
'charstrings': this.createCFFIndexHeader([[0x8B, 0x0E]].concat(glyphs),
true),
'private': (function cffWrapPrivate(self) {
'privateData': (function cffWrapPrivate(self) {
var data =
'\x8b\x14' + // defaultWidth
'\x8b\x15'; // nominalWidth
@ -3403,9 +3416,9 @@ Type1Font.prototype = {
ExpansionFactor: '\x0c\x18'
};
for (var field in fieldMap) {
if (!properties.private.hasOwnProperty(field))
if (!properties.privateData.hasOwnProperty(field))
continue;
var value = properties.private[field];
var value = properties.privateData[field];
if (isArray(value)) {
data += self.encodeNumber(value[0]);
@ -4362,16 +4375,18 @@ var CFFCompiler = (function CFFCompilerClosure() {
output.add(charStrings);
if (cff.isCIDFont) {
// For some reason FDSelect must be in front of FDArray on windows. OSX
// and linux don't seem to care.
topDictTracker.setEntryLocation('FDSelect', [output.length], output);
var fdSelect = this.compileFDSelect(cff.fdSelect.raw);
output.add(fdSelect);
var compiled = this.compileTopDicts(cff.fdArray, output.length);
topDictTracker.setEntryLocation('FDArray', [output.length], output);
output.add(compiled.output);
var fontDictTrackers = compiled.trackers;
this.compilePrivateDicts(cff.fdArray, fontDictTrackers, output);
topDictTracker.setEntryLocation('FDSelect', [output.length], output);
var fdSelect = this.compileFDSelect(cff.fdSelect.raw);
output.add(fdSelect);
}
this.compilePrivateDicts([cff.topDict], [topDictTracker], output);

View File

@ -122,9 +122,9 @@ function readFontDictData(aString, aMap) {
token = '';
var parsed = false;
while (!parsed) {
var byte = aString[i++];
var octet = aString[i++];
var nibbles = [parseInt(byte / 16, 10), parseInt(byte % 16, 10)];
var nibbles = [parseInt(octet / 16, 10), parseInt(octet % 16, 10)];
for (var j = 0; j < nibbles.length; j++) {
var nibble = nibbles[j];
switch (nibble) {
@ -336,7 +336,7 @@ var Type2Parser = function type2Parser(aFilePath) {
var privateDict = [];
for (var i = 0; i < priv.size; i++)
privateDict.push(aStream.getByte());
dump('private:' + privateDict);
dump('privateData:' + privateDict);
parseAsToken(privateDict, CFFDictPrivateDataMap);
for (var p in font.map)

View File

@ -266,6 +266,9 @@ function sendTaskResult(snapshot, task, failure) {
r.onreadystatechange = function sendTaskResultOnreadystatechange(e) {
if (r.readyState == 4) {
inFlightRequests--;
// Retry until successful
if (r.status !== 200)
sendTaskResult(snapshot, task, failure);
}
};
document.getElementById('inFlightCount').innerHTML = inFlightRequests++;

View File

@ -391,11 +391,43 @@ canvas {
}
}
#loading {
#loadingBox {
margin: 100px 0;
text-align: center;
}
#loadingBar {
background-color: #333;
display: inline-block;
border: 1px solid black;
clear: both;
margin:0px;
line-height: 0;
border-radius: 4px;
width: 15em;
height: 1.5em;
}
#loadingBar .progress {
background-color: green;
display: inline-block;
float: left;
background: #b4e391;
background: -moz-linear-gradient(top, #b4e391 0%, #61c419 50%, #b4e391 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b4e391), color-stop(50%,#61c419), color-stop(100%,#b4e391));
background: -webkit-linear-gradient(top, #b4e391 0%,#61c419 50%,#b4e391 100%);
background: -o-linear-gradient(top, #b4e391 0%,#61c419 50%,#b4e391 100%);
background: -ms-linear-gradient(top, #b4e391 0%,#61c419 50%,#b4e391 100%);
background: linear-gradient(top, #b4e391 0%,#61c419 50%,#b4e391 100%);
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
width: 0%;
height: 100%;
}
#PDFBug {
font-size: 10px;
position: fixed;

View File

@ -143,7 +143,10 @@
</div>
</div>
<div id="loading">Loading... 0%</div>
<div id="loadingBox">
<div id="loading">Loading... 0%</div>
<div id="loadingBar"><div class="progress"></div></div>
</div>
<div id="viewer"></div>
</body>
</html>

View File

@ -15,6 +15,15 @@ var kMaxScale = 4.0;
var kImageDirectory = './images/';
var kSettingsMemory = 20;
function getFileName(url) {
var anchor = url.indexOf('#');
var query = url.indexOf('?');
var end = Math.min(
anchor > 0 ? anchor : url.length,
query > 0 ? query : url.length);
return url.substring(url.lastIndexOf('/', end) + 1, end);
}
var Cache = function cacheCache(size) {
var data = [];
this.push = function cachePush(view) {
@ -27,6 +36,48 @@ var Cache = function cacheCache(size) {
};
};
var ProgressBar = (function ProgressBarClosure() {
function clamp(v, min, max) {
return Math.min(Math.max(v, min), max);
}
function ProgressBar(id, opts) {
// Fetch the sub-elements for later
this.div = document.querySelector(id + ' .progress');
// Get options, with sensible defaults
this.height = opts.height || 100;
this.width = opts.width || 100;
this.units = opts.units || '%';
this.percent = opts.percent || 0;
// Initialize heights
this.div.style.height = this.height + this.units;
}
ProgressBar.prototype = {
updateBar: function ProgressBar_updateBar() {
var progressSize = this.width * this._percent / 100;
this.div.style.width = progressSize + this.units;
},
get percent() {
return this._percent;
},
set percent(val) {
this._percent = clamp(val, 0, 100);
this.updateBar();
}
};
return ProgressBar;
})();
var RenderingQueue = (function RenderingQueueClosure() {
function RenderingQueue() {
this.items = [];
@ -258,7 +309,13 @@ var PDFView = {
},
open: function pdfViewOpen(url, scale) {
document.title = this.url = url;
this.url = url;
document.title = decodeURIComponent(getFileName(url)) || url;
if (!PDFView.loadingBar) {
PDFView.loadingBar = new ProgressBar('#loadingBar', {});
}
var self = this;
PDFJS.getPdf(
@ -400,6 +457,8 @@ var PDFView = {
var percent = Math.round(level * 100);
var loadingIndicator = document.getElementById('loading');
loadingIndicator.textContent = 'Loading... ' + percent + '%';
PDFView.loadingBar.percent = percent;
},
load: function pdfViewLoad(data, scale) {
@ -414,8 +473,8 @@ var PDFView = {
var errorWrapper = document.getElementById('errorWrapper');
errorWrapper.setAttribute('hidden', 'true');
var loadingIndicator = document.getElementById('loading');
loadingIndicator.setAttribute('hidden', 'true');
var loadingBox = document.getElementById('loadingBox');
loadingBox.setAttribute('hidden', 'true');
var sidebar = document.getElementById('sidebarView');
sidebar.parentNode.scrollTop = 0;