Merge branch 'master' of https://github.com/andreasgal/pdf.js.git into zoom-bookmark

Conflicts:
	web/viewer.js
This commit is contained in:
notmasteryet 2011-09-05 15:54:54 -05:00
commit 9eac2e1c95
6 changed files with 78 additions and 72 deletions

View File

@ -9,6 +9,10 @@ var isWorker = (typeof window == 'undefined');
*/ */
var kMaxWaitForFontFace = 1000; var kMaxWaitForFontFace = 1000;
// Unicode Private Use Area
var kCmapGlyphOffset = 0xE000;
/** /**
* Hold a map of decoded fonts and of the standard fourteen Type1 * Hold a map of decoded fonts and of the standard fourteen Type1
* fonts and their acronyms. * fonts and their acronyms.
@ -797,9 +801,6 @@ var Font = (function Font() {
encoding: null, encoding: null,
checkAndRepair: function font_checkAndRepair(name, font, properties) { checkAndRepair: function font_checkAndRepair(name, font, properties) {
// offset glyphs to the Unicode Private Use Area
var kCmapGlyphOffset = 0xE000;
function readTableEntry(file) { function readTableEntry(file) {
var tag = file.getBytes(4); var tag = file.getBytes(4);
tag = String.fromCharCode(tag[0]) + tag = String.fromCharCode(tag[0]) +
@ -879,16 +880,23 @@ var Font = (function Font() {
var index = font.getByte(); var index = font.getByte();
if (index) { if (index) {
deltas.push(index); deltas.push(index);
glyphs.push({ unicode: j });
var code = encoding[index];
for (var glyph in properties.glyphs) {
if (properties.glyphs[glyph] == code)
break;
}
glyphs.push({ glyph: glyph, unicode: j });
} }
} }
if (properties.firstChar < 0x20) { if (properties.firstChar < 0x20) {
var code = 0;
for (var j = 0; j < glyphs.length; j++) { for (var j = 0; j < glyphs.length; j++) {
var glyph = glyphs[j]; var glyph = glyphs[j];
glyphs[j].unicode += 0x1F; var code = glyph.unicode + kCmapGlyphOffset;
properties.glyphs[glyph.glyph] = encoding[++code] = glyph.unicode; properties.glyphs[glyph.glyph] = encoding[glyph.unicode] = code;
glyph.unicode = code;
} }
} }
@ -1406,7 +1414,7 @@ var Type1Parser = function() {
// Type1 only command with command not (yet) built-in ,throw an error // Type1 only command with command not (yet) built-in ,throw an error
'6': -1, // seac '6': -1, // seac
'7': -1, //sbw '7': -1, // sbw
'11': 'sub', '11': 'sub',
'12': 'div', '12': 'div',
@ -1422,8 +1430,8 @@ var Type1Parser = function() {
// moveto (this is a one shot positionning command). This is used only // moveto (this is a one shot positionning command). This is used only
// with the return of an OtherSubrs call. // with the return of an OtherSubrs call.
// TODO Implement the OtherSubrs charstring embedding and replace this // TODO Implement the OtherSubrs charstring embedding and replace this
// call by a no-op, like 2 'pop' commands for example. // call by a no-op, like 2 'pop' commands for example.
'33': null //setcurrentpoint '33': null // setcurrentpoint
}, },
'13': 'hsbw', '13': 'hsbw',
'14': 'endchar', '14': 'endchar',
@ -1458,7 +1466,7 @@ var Type1Parser = function() {
charstring.push('drop'); charstring.push('drop');
// If the flex mechanism is not used in a font program, Adobe // If the flex mechanism is not used in a font program, Adobe
// state that that entries 0, 1 and 2 can simply be replace by // states that entries 0, 1 and 2 can simply be replaced by
// {}, which means that we can simply ignore them. // {}, which means that we can simply ignore them.
if (index < 3) { if (index < 3) {
continue; continue;
@ -1477,7 +1485,7 @@ var Type1Parser = function() {
command = charStringDictionary['12'][escape]; command = charStringDictionary['12'][escape];
} else { } else {
// TODO Clean this code // TODO Clean this code
if (value == 13) { //hsbw if (value == 13) { // hsbw
if (charstring.length == 2) { if (charstring.length == 2) {
lsb = charstring[0]; lsb = charstring[0];
width = charstring[1]; width = charstring[1];
@ -1646,9 +1654,9 @@ var Type1Parser = function() {
var encoded = decrypt(data, kCharStringsEncryptionKey, lenIV); var encoded = decrypt(data, kCharStringsEncryptionKey, lenIV);
var str = decodeCharString(encoded); var str = decodeCharString(encoded);
i = i + 1 + length; i = i + 1 + length;
t = getToken(); //read in 'NP' t = getToken(); // read in 'NP'
if (t == 'noaccess') if (t == 'noaccess')
getToken(); //read in 'put' getToken(); // read in 'put'
program.subrs[index] = str.charstring; program.subrs[index] = str.charstring;
} }
break; break;
@ -2235,7 +2243,6 @@ var Type2CFF = (function() {
var nominalWidth = privDict['nominalWidthX']; var nominalWidth = privDict['nominalWidthX'];
var charstrings = []; var charstrings = [];
var kCmapGlyphOffset = 0xE000;
var differences = properties.differences; var differences = properties.differences;
var index = 0; var index = 0;
for (var i = 1; i < charsets.length; i++) { for (var i = 1; i < charsets.length; i++) {

85
pdf.js
View File

@ -276,11 +276,11 @@ var FakeStream = (function() {
}; };
constructor.prototype.getBytes = function(length) { constructor.prototype.getBytes = function(length) {
var pos = this.pos; var end, pos = this.pos;
if (length) { if (length) {
this.ensureBuffer(pos + length); this.ensureBuffer(pos + length);
var end = pos + length; end = pos + length;
while (!this.eof && this.bufferLength < end) while (!this.eof && this.bufferLength < end)
this.readBlock(); this.readBlock();
@ -290,7 +290,7 @@ var FakeStream = (function() {
end = bufEnd; end = bufEnd;
} else { } else {
this.eof = true; this.eof = true;
var end = this.bufferLength; end = this.bufferLength;
} }
this.pos = end; this.pos = end;
@ -2056,7 +2056,7 @@ var CCITTFaxStream = (function() {
constructor.prototype.eatBits = function(n) { constructor.prototype.eatBits = function(n) {
if ((this.inputBits -= n) < 0) if ((this.inputBits -= n) < 0)
this.inputBits = 0; this.inputBits = 0;
} };
return constructor; return constructor;
})(); })();
@ -2359,7 +2359,7 @@ var Lexer = (function() {
constructor.isSpace = function(ch) { constructor.isSpace = function(ch) {
return ch == ' ' || ch == '\t'; return ch == ' ' || ch == '\t';
} };
// A '1' in this array means the character is white space. A '1' or // A '1' in this array means the character is white space. A '1' or
// '2' means the character ends a name or command. // '2' means the character ends a name or command.
@ -2432,7 +2432,8 @@ var Lexer = (function() {
var stream = this.stream; var stream = this.stream;
var ch; var ch;
do { do {
switch (ch = stream.getChar()) { ch = stream.getChar();
switch (ch) {
case undefined: case undefined:
warn('Unterminated string'); warn('Unterminated string');
done = true; done = true;
@ -2449,7 +2450,8 @@ var Lexer = (function() {
} }
break; break;
case '\\': case '\\':
switch (ch = stream.getChar()) { ch = stream.getChar();
switch (ch) {
case undefined: case undefined:
warn('Unterminated string'); warn('Unterminated string');
done = true; done = true;
@ -2802,7 +2804,7 @@ var Parser = (function() {
if (xref) if (xref)
length = xref.fetchIfRef(length); length = xref.fetchIfRef(length);
if (!IsInt(length)) { if (!IsInt(length)) {
error('Bad ' + Length + ' attribute in stream'); error('Bad ' + length + ' attribute in stream');
length = 0; length = 0;
} }
@ -3160,7 +3162,7 @@ var XRef = (function() {
if (!IsCmd(obj3, 'obj')) { if (!IsCmd(obj3, 'obj')) {
// some bad pdfs use "obj1234" and really mean 1234 // some bad pdfs use "obj1234" and really mean 1234
if (obj3.cmd.indexOf('obj') == 0) { if (obj3.cmd.indexOf('obj') == 0) {
var num = parseInt(obj3.cmd.substring(3)); num = parseInt(obj3.cmd.substring(3));
if (!isNaN(num)) if (!isNaN(num))
return num; return num;
} }
@ -3190,7 +3192,7 @@ var XRef = (function() {
var i, entries = [], nums = []; var i, entries = [], nums = [];
// read the object numbers to populate cache // read the object numbers to populate cache
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
var num = parser.getObj(); num = parser.getObj();
if (!IsInt(num)) { if (!IsInt(num)) {
error('invalid object number in the ObjStm stream: ' + num); error('invalid object number in the ObjStm stream: ' + num);
} }
@ -4175,7 +4177,7 @@ var PartialEvaluator = (function() {
return function(gfx) { return function(gfx) {
for (var i = 0, length = argsArray.length; i < length; i++) for (var i = 0, length = argsArray.length; i < length; i++)
gfx[fnArray[i]].apply(gfx, argsArray[i]); gfx[fnArray[i]].apply(gfx, argsArray[i]);
} };
}, },
translateFont: function(fontDict, xref, resources) { translateFont: function(fontDict, xref, resources) {
@ -4302,7 +4304,6 @@ var PartialEvaluator = (function() {
var index = GlyphsUnicode[glyph] || i; var index = GlyphsUnicode[glyph] || i;
glyphsMap[glyph] = encodingMap[i] = index; glyphsMap[glyph] = encodingMap[i] = index;
var kCmapGlyphOffset = 0xE000;
if (index <= 0x1f || (index >= 127 && index <= 255)) if (index <= 0x1f || (index >= 127 && index <= 255))
glyphsMap[glyph] = encodingMap[i] += kCmapGlyphOffset; glyphsMap[glyph] = encodingMap[i] += kCmapGlyphOffset;
} }
@ -5221,7 +5222,7 @@ var CanvasGraphics = (function() {
})(); })();
var Util = (function() { var Util = (function() {
function constructor() {}; function constructor() {}
constructor.makeCssRgb = function makergb(r, g, b) { constructor.makeCssRgb = function makergb(r, g, b) {
var ri = (255 * r) | 0, gi = (255 * g) | 0, bi = (255 * b) | 0; var ri = (255 * r) | 0, gi = (255 * g) | 0, bi = (255 * b) | 0;
return 'rgb(' + ri + ',' + gi + ',' + bi + ')'; return 'rgb(' + ri + ',' + gi + ',' + bi + ')';
@ -5244,7 +5245,7 @@ var ColorSpace = (function() {
// Constructor should define this.numComps, this.defaultColor, this.name // Constructor should define this.numComps, this.defaultColor, this.name
function constructor() { function constructor() {
error('should not call ColorSpace constructor'); error('should not call ColorSpace constructor');
}; }
constructor.prototype = { constructor.prototype = {
// Input: array of size numComps representing color component values // Input: array of size numComps representing color component values
@ -5279,18 +5280,14 @@ var ColorSpace = (function() {
case 'DeviceGray': case 'DeviceGray':
case 'G': case 'G':
return new DeviceGrayCS(); return new DeviceGrayCS();
break;
case 'DeviceRGB': case 'DeviceRGB':
case 'RGB': case 'RGB':
return new DeviceRgbCS(); return new DeviceRgbCS();
break;
case 'DeviceCMYK': case 'DeviceCMYK':
case 'CMYK': case 'CMYK':
return new DeviceCmykCS(); return new DeviceCmykCS();
break;
case 'Pattern': case 'Pattern':
return new PatternCS(null); return new PatternCS(null);
break;
default: default:
error('unrecognized colorspace ' + mode); error('unrecognized colorspace ' + mode);
} }
@ -5302,30 +5299,25 @@ var ColorSpace = (function() {
case 'DeviceGray': case 'DeviceGray':
case 'G': case 'G':
return new DeviceGrayCS(); return new DeviceGrayCS();
break;
case 'DeviceRGB': case 'DeviceRGB':
case 'RGB': case 'RGB':
return new DeviceRgbCS(); return new DeviceRgbCS();
break;
case 'DeviceCMYK': case 'DeviceCMYK':
case 'CMYK': case 'CMYK':
return new DeviceCmykCS(); return new DeviceCmykCS();
break;
case 'CalGray': case 'CalGray':
return new DeviceGrayCS(); return new DeviceGrayCS();
break;
case 'CalRGB': case 'CalRGB':
return new DeviceRgbCS(); return new DeviceRgbCS();
break;
case 'ICCBased': case 'ICCBased':
var stream = xref.fetchIfRef(cs[1]); var stream = xref.fetchIfRef(cs[1]);
var dict = stream.dict; var dict = stream.dict;
var numComps = dict.get('N'); var numComps = dict.get('N');
if (numComps == 1) if (numComps == 1)
return new DeviceGrayCS(); return new DeviceGrayCS();
else if (numComps == 3) if (numComps == 3)
return new DeviceRgbCS(); return new DeviceRgbCS();
else if (numComps == 4) if (numComps == 4)
return new DeviceCmykCS(); return new DeviceCmykCS();
break; break;
case 'Pattern': case 'Pattern':
@ -5333,19 +5325,16 @@ var ColorSpace = (function() {
if (baseCS) if (baseCS)
baseCS = ColorSpace.parse(baseCS, xref, res); baseCS = ColorSpace.parse(baseCS, xref, res);
return new PatternCS(baseCS); return new PatternCS(baseCS);
break;
case 'Indexed': case 'Indexed':
var base = ColorSpace.parse(cs[1], xref, res); var base = ColorSpace.parse(cs[1], xref, res);
var hiVal = cs[2] + 1; var hiVal = cs[2] + 1;
var lookup = xref.fetchIfRef(cs[3]); var lookup = xref.fetchIfRef(cs[3]);
return new IndexedCS(base, hiVal, lookup); return new IndexedCS(base, hiVal, lookup);
break;
case 'Separation': case 'Separation':
var name = cs[1]; var name = cs[1];
var alt = ColorSpace.parse(cs[2], xref, res); var alt = ColorSpace.parse(cs[2], xref, res);
var tintFn = new PDFFunction(xref, xref.fetchIfRef(cs[3])); var tintFn = new PDFFunction(xref, xref.fetchIfRef(cs[3]));
return new SeparationCS(alt, tintFn); return new SeparationCS(alt, tintFn);
break;
case 'Lab': case 'Lab':
case 'DeviceN': case 'DeviceN':
default: default:
@ -5435,7 +5424,7 @@ var IndexedCS = (function() {
constructor.prototype = { constructor.prototype = {
getRgb: function indexcs_getRgb(color) { getRgb: function indexcs_getRgb(color) {
var numComps = base.numComps; var numComps = this.base.numComps;
var start = color[0] * numComps; var start = color[0] * numComps;
var c = []; var c = [];
@ -5471,7 +5460,7 @@ var DeviceGrayCS = (function() {
this.name = 'DeviceGray'; this.name = 'DeviceGray';
this.numComps = 1; this.numComps = 1;
this.defaultColor = [0]; this.defaultColor = [0];
}; }
constructor.prototype = { constructor.prototype = {
getRgb: function graycs_getRgb(color) { getRgb: function graycs_getRgb(color) {
@ -5606,7 +5595,7 @@ var Pattern = (function() {
// Constructor should define this.getPattern // Constructor should define this.getPattern
function constructor() { function constructor() {
error('should not call Pattern constructor'); error('should not call Pattern constructor');
}; }
constructor.prototype = { constructor.prototype = {
// Input: current Canvas context // Input: current Canvas context
@ -5670,14 +5659,14 @@ var Pattern = (function() {
default: default:
return new DummyShading(); return new DummyShading();
} }
} };
return constructor; return constructor;
})(); })();
var DummyShading = (function() { var DummyShading = (function() {
function constructor() { function constructor() {
this.type = 'Pattern'; this.type = 'Pattern';
}; }
constructor.prototype = { constructor.prototype = {
getPattern: function dummy_getpattern() { getPattern: function dummy_getpattern() {
return 'hotpink'; return 'hotpink';
@ -5707,13 +5696,15 @@ var RadialAxialShading = (function() {
var t0 = 0.0, t1 = 1.0; var t0 = 0.0, t1 = 1.0;
if (dict.has('Domain')) { if (dict.has('Domain')) {
var domainArr = dict.get('Domain'); var domainArr = dict.get('Domain');
t0 = domainArr[0], t1 = domainArr[1]; t0 = domainArr[0];
t1 = domainArr[1];
} }
var extendStart = false, extendEnd = false; var extendStart = false, extendEnd = false;
if (dict.has('Extend')) { if (dict.has('Extend')) {
var extendArr = dict.get('Extend'); var extendArr = dict.get('Extend');
extendStart = extendArr[0], extendEnd = extendArr[1]; extendStart = extendArr[0];
extendEnd = extendArr[1];
TODO('Support extend'); TODO('Support extend');
} }
@ -5742,7 +5733,7 @@ var RadialAxialShading = (function() {
} }
this.colorStops = colorStops; this.colorStops = colorStops;
}; }
constructor.prototype = { constructor.prototype = {
getPattern: function() { getPattern: function() {
@ -5807,7 +5798,7 @@ var TilingPattern = (function() {
var e = m[4] * tm[0] + m[5] * tm[2] + tm[4]; var e = m[4] * tm[0] + m[5] * tm[2] + tm[4];
var f = m[4] * tm[1] + m[5] * tm[3] + tm[5]; var f = m[4] * tm[1] + m[5] * tm[3] + tm[5];
return [a, b, c, d, e, f]; return [a, b, c, d, e, f];
}; }
TODO('TilingType'); TODO('TilingType');
@ -5879,7 +5870,7 @@ var TilingPattern = (function() {
graphics.execute(code, xref, res); graphics.execute(code, xref, res);
this.canvas = tmpCanvas; this.canvas = tmpCanvas;
}; }
constructor.prototype = { constructor.prototype = {
getPattern: function tiling_getPattern() { getPattern: function tiling_getPattern() {
@ -5958,7 +5949,7 @@ var PDFImage = (function() {
} else if (smask) { } else if (smask) {
this.smask = new PDFImage(xref, res, smask); this.smask = new PDFImage(xref, res, smask);
} }
}; }
constructor.prototype = { constructor.prototype = {
getComponents: function getComponents(buffer, decodeMap) { getComponents: function getComponents(buffer, decodeMap) {
@ -6133,7 +6124,7 @@ var PDFFunction = (function() {
error('Unknown type of function'); error('Unknown type of function');
typeFn.call(this, fn, dict, xref); typeFn.call(this, fn, dict, xref);
}; }
constructor.prototype = { constructor.prototype = {
constructSampled: function(str, dict) { constructSampled: function(str, dict) {
@ -6179,7 +6170,7 @@ var PDFFunction = (function() {
else if (v < min) else if (v < min)
v = min; v = min;
return v; return v;
} };
if (inputSize != args.length) if (inputSize != args.length)
error('Incorrect number of arguments: ' + inputSize + ' != ' + error('Incorrect number of arguments: ' + inputSize + ' != ' +
@ -6229,7 +6220,7 @@ var PDFFunction = (function() {
} }
return output; return output;
} };
}, },
getSampleArray: function(size, outputSize, bps, str) { getSampleArray: function(size, outputSize, bps, str) {
var length = 1; var length = 1;
@ -6277,7 +6268,7 @@ var PDFFunction = (function() {
out.push(c0[j] + (x^n * diff[i])); out.push(c0[j] + (x^n * diff[i]));
return out; return out;
} };
}, },
constructStiched: function(fn, dict, xref) { constructStiched: function(fn, dict, xref) {
var domain = dict.get('Domain'); var domain = dict.get('Domain');
@ -6305,7 +6296,7 @@ var PDFFunction = (function() {
else if (v < min) else if (v < min)
v = min; v = min;
return v; return v;
} };
// clip to domain // clip to domain
var v = clip(args[0], domain[0], domain[1]); var v = clip(args[0], domain[0], domain[1]);
@ -6330,11 +6321,13 @@ var PDFFunction = (function() {
// call the appropropriate function // call the appropropriate function
return fns[i].func([v2]); return fns[i].func([v2]);
} };
}, },
constructPostScript: function() { constructPostScript: function() {
TODO('unhandled type of function'); TODO('unhandled type of function');
this.func = function() { return [255, 105, 180]; } this.func = function() {
return [255, 105, 180];
};
} }
}; };

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -34,12 +34,14 @@
<div class="separator"></div> <div class="separator"></div>
<button id="next" title="Zoom Out" onclick="PDFView.zoomOut();"> <button id="next" title="Zoom Out" onclick="PDFView.zoomOut();">
<img src="images/list-remove.svg" align="top" height="32"/> <img src="images/zoom-out.svg" align="top" height="32"/>
</button> </button>
<button id="next" title="Zoom In" onclick="PDFView.zoomIn();"> <button id="next" title="Zoom In" onclick="PDFView.zoomIn();">
<img src="images/list-add.svg" align="top" height="32"/> <img src="images/zoom-in.svg" align="top" height="32"/>
</button> </button>
<div class="separator"></div>
<select id="scaleSelect" onchange="PDFView.parseScale(this.value);"> <select id="scaleSelect" onchange="PDFView.parseScale(this.value);">
<option id="customScaleOption" value="custom"></option> <option id="customScaleOption" value="custom"></option>
<option value="0.5">50%</option> <option value="0.5">50%</option>

View File

@ -47,13 +47,14 @@ var PDFView = {
}, },
parseScale: function(value, resetAutoSettings) { parseScale: function(value, resetAutoSettings) {
if ('custom' == value)
return;
var scale = parseFloat(value); var scale = parseFloat(value);
if (scale) { if (scale) {
this.setScale(scale, true); this.setScale(scale, true);
return; return;
} }
if ('custom' == value)
return;
var currentPage = this.pages[this.page - 1]; var currentPage = this.pages[this.page - 1];
var pageWidthScale = (window.innerWidth - kScrollbarPadding) / var pageWidthScale = (window.innerWidth - kScrollbarPadding) /
@ -567,7 +568,7 @@ window.addEventListener('scalechange', function scalechange(evt) {
var value = '' + evt.scale; var value = '' + evt.scale;
for (var i = 0; i < options.length; i++) { for (var i = 0; i < options.length; i++) {
var option = options[i]; var option = options[i];
if (option.value != evt.scale) { if (option.value != value) {
option.selected = false; option.selected = false;
continue; continue;
} }
@ -591,16 +592,19 @@ window.addEventListener('pagechange', function pagechange(evt) {
document.getElementById('next').disabled = (page == PDFView.pages.length); document.getElementById('next').disabled = (page == PDFView.pages.length);
}, true); }, true);
window.addEventListener('keydown', function (evt) { window.addEventListener('keydown', function keydown(evt) {
switch(evt.keyCode) { switch(evt.keyCode) {
case 61: // '+' and '=' keys case 61: // FF/Mac '='
case 107: case 107: // FF '+' and '='
case 187: case 187: // Chrome '+'
PDFView.zoomIn(); PDFView.zoomIn();
break; break;
case 109: // '-' keys case 109: // FF '-'
case 189: case 189: // Chrome '-'
PDFView.zoomOut(); PDFView.zoomOut();
break; break;
case 48: // '0'
PDFView.setScale(kDefaultScale, true);
break;
} }
}); });