7,585 pdf.js

This file was deleted.

Large diffs are not rendered by default.

File renamed without changes.
File renamed without changes.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

File renamed without changes.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -0,0 +1,306 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */

'use strict';

var PDFFunction = (function() {
var CONSTRUCT_SAMPLED = 0;
var CONSTRUCT_INTERPOLATED = 2;
var CONSTRUCT_STICHED = 3;
var CONSTRUCT_POSTSCRIPT = 4;

return {
getSampleArray: function(size, outputSize, bps, str) {
var length = 1;
for (var i = 0; i < size.length; i++)
length *= size[i];
length *= outputSize;

var array = [];
var codeSize = 0;
var codeBuf = 0;

var strBytes = str.getBytes((length * bps + 7) / 8);
var strIdx = 0;
for (var i = 0; i < length; i++) {
while (codeSize < bps) {
codeBuf <<= 8;
codeBuf |= strBytes[strIdx++];
codeSize += 8;
}
codeSize -= bps;
array.push(codeBuf >> codeSize);
codeBuf &= (1 << codeSize) - 1;
}
return array;
},

getIR: function(xref, fn) {
var dict = fn.dict;
if (!dict)
dict = fn;

var types = [this.constructSampled,
null,
this.constructInterpolated,
this.constructStiched,
this.constructPostScript];

var typeNum = dict.get('FunctionType');
var typeFn = types[typeNum];
if (!typeFn)
error('Unknown type of function');

return typeFn.call(this, fn, dict, xref);
},

fromIR: function(IR) {
var type = IR[0];
switch (type) {
case CONSTRUCT_SAMPLED:
return this.constructSampledFromIR(IR);
case CONSTRUCT_INTERPOLATED:
return this.constructInterpolatedFromIR(IR);
case CONSTRUCT_STICHED:
return this.constructStichedFromIR(IR);
case CONSTRUCT_POSTSCRIPT:
default:
return this.constructPostScriptFromIR(IR);
}
},

parse: function(xref, fn) {
var IR = this.getIR(xref, fn);
return this.fromIR(IR);
},

constructSampled: function(str, dict) {
var domain = dict.get('Domain');
var range = dict.get('Range');

if (!domain || !range)
error('No domain or range');

var inputSize = domain.length / 2;
var outputSize = range.length / 2;

if (inputSize != 1)
error('No support for multi-variable inputs to functions: ' +
inputSize);

var size = dict.get('Size');
var bps = dict.get('BitsPerSample');
var order = dict.get('Order');
if (!order)
order = 1;
if (order !== 1)
error('No support for cubic spline interpolation: ' + order);

var encode = dict.get('Encode');
if (!encode) {
encode = [];
for (var i = 0; i < inputSize; ++i) {
encode.push(0);
encode.push(size[i] - 1);
}
}
var decode = dict.get('Decode');
if (!decode)
decode = range;

var samples = this.getSampleArray(size, outputSize, bps, str);

return [
CONSTRUCT_SAMPLED, inputSize, domain, encode, decode, samples, size,
outputSize, bps, range
];
},

constructSampledFromIR: function(IR) {
var inputSize = IR[1];
var domain = IR[2];
var encode = IR[3];
var decode = IR[4];
var samples = IR[5];
var size = IR[6];
var outputSize = IR[7];
var bps = IR[8];
var range = IR[9];

return function(args) {
var clip = function(v, min, max) {
if (v > max)
v = max;
else if (v < min)
v = min;
return v;
};

if (inputSize != args.length)
error('Incorrect number of arguments: ' + inputSize + ' != ' +
args.length);

for (var i = 0; i < inputSize; i++) {
var i2 = i * 2;

// clip to the domain
var v = clip(args[i], domain[i2], domain[i2 + 1]);

// encode
v = encode[i2] + ((v - domain[i2]) *
(encode[i2 + 1] - encode[i2]) /
(domain[i2 + 1] - domain[i2]));

// clip to the size
args[i] = clip(v, 0, size[i] - 1);
}

// interpolate to table
TODO('Multi-dimensional interpolation');
var floor = Math.floor(args[0]);
var ceil = Math.ceil(args[0]);
var scale = args[0] - floor;

floor *= outputSize;
ceil *= outputSize;

var output = [], v = 0;
for (var i = 0; i < outputSize; ++i) {
if (ceil == floor) {
v = samples[ceil + i];
} else {
var low = samples[floor + i];
var high = samples[ceil + i];
v = low * scale + high * (1 - scale);
}

var i2 = i * 2;
// decode
v = decode[i2] + (v * (decode[i2 + 1] - decode[i2]) /
((1 << bps) - 1));

// clip to the domain
output.push(clip(v, range[i2], range[i2 + 1]));
}

return output;
}
},

constructInterpolated:
function pdfFunctionConstructInterpolated(str, dict) {
var c0 = dict.get('C0') || [0];
var c1 = dict.get('C1') || [1];
var n = dict.get('N');

if (!isArray(c0) || !isArray(c1))
error('Illegal dictionary for interpolated function');

var length = c0.length;
var diff = [];
for (var i = 0; i < length; ++i)
diff.push(c1[i] - c0[i]);

return [CONSTRUCT_INTERPOLATED, c0, diff, n];
},

constructInterpolatedFromIR:
function pdfFunctionconstructInterpolatedFromIR(IR) {
var c0 = IR[1];
var diff = IR[2];
var n = IR[3];

var length = diff.length;

return function(args) {
var x = n == 1 ? args[0] : Math.pow(args[0], n);

var out = [];
for (var j = 0; j < length; ++j)
out.push(c0[j] + (x * diff[j]));

return out;

}
},

constructStiched: function pdfFunctionConstructStiched(fn, dict, xref) {
var domain = dict.get('Domain');
var range = dict.get('Range');

if (!domain)
error('No domain');

var inputSize = domain.length / 2;
if (inputSize != 1)
error('Bad domain for stiched function');

var fnRefs = dict.get('Functions');
var fns = [];
for (var i = 0, ii = fnRefs.length; i < ii; ++i)
fns.push(PDFFunction.getIR(xref, xref.fetchIfRef(fnRefs[i])));

var bounds = dict.get('Bounds');
var encode = dict.get('Encode');

return [CONSTRUCT_STICHED, domain, bounds, encode, fns];
},

constructStichedFromIR: function pdfFunctionConstructStichedFromIR(IR) {
var domain = IR[1];
var bounds = IR[2];
var encode = IR[3];
var fnsIR = IR[4];
var fns = [];

for (var i = 0; i < fnsIR.length; i++) {
fns.push(PDFFunction.fromIR(fnsIR[i]));
}

return function(args) {
var clip = function(v, min, max) {
if (v > max)
v = max;
else if (v < min)
v = min;
return v;
};

// clip to domain
var v = clip(args[0], domain[0], domain[1]);
// calulate which bound the value is in
for (var i = 0, ii = bounds.length; i < ii; ++i) {
if (v < bounds[i])
break;
}

// encode value into domain of function
var dmin = domain[0];
if (i > 0)
dmin = bounds[i - 1];
var dmax = domain[1];
if (i < bounds.length)
dmax = bounds[i];

var rmin = encode[2 * i];
var rmax = encode[2 * i + 1];

var v2 = rmin + (v - dmin) * (rmax - rmin) / (dmax - dmin);

// call the appropropriate function
return fns[i]([v2]);
};
},

constructPostScript: function pdfFunctionConstructPostScript() {
return [CONSTRUCT_POSTSCRIPT];
},

constructPostScriptFromIR: function pdfFunctionConstructPostScriptFromIR() {
TODO('unhandled type of function');
return function() {
return [255, 105, 180];
};
}
};
})();
File renamed without changes.
@@ -0,0 +1,256 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */

'use strict';

var PDFImage = (function pdfImage() {
function constructor(xref, res, image, inline) {
this.image = image;
if (image.getParams) {
// JPX/JPEG2000 streams directly contain bits per component
// and color space mode information.
TODO('get params from actual stream');
// var bits = ...
// var colorspace = ...
}
// TODO cache rendered images?

var dict = image.dict;
this.width = dict.get('Width', 'W');
this.height = dict.get('Height', 'H');

if (this.width < 1 || this.height < 1)
error('Invalid image width: ' + this.width + ' or height: ' +
this.height);

this.interpolate = dict.get('Interpolate', 'I') || false;
this.imageMask = dict.get('ImageMask', 'IM') || false;

var bitsPerComponent = image.bitsPerComponent;
if (!bitsPerComponent) {
bitsPerComponent = dict.get('BitsPerComponent', 'BPC');
if (!bitsPerComponent) {
if (this.imageMask)
bitsPerComponent = 1;
else
error('Bits per component missing in image: ' + this.imageMask);
}
}
this.bpc = bitsPerComponent;

if (!this.imageMask) {
var colorSpace = dict.get('ColorSpace', 'CS');
if (!colorSpace) {
TODO('JPX images (which don"t require color spaces');
colorSpace = new Name('DeviceRGB');
}
this.colorSpace = ColorSpace.parse(colorSpace, xref, res);
this.numComps = this.colorSpace.numComps;
}

this.decode = dict.get('Decode', 'D');

var mask = xref.fetchIfRef(dict.get('Mask'));
var smask = xref.fetchIfRef(dict.get('SMask'));

if (mask) {
TODO('masked images');
} else if (smask) {
this.smask = new PDFImage(xref, res, smask);
}
}

constructor.prototype = {
getComponents: function getComponents(buffer, decodeMap) {
var bpc = this.bpc;
if (bpc == 8)
return buffer;

var width = this.width;
var height = this.height;
var numComps = this.numComps;

var length = width * height;
var bufferPos = 0;
var output = bpc <= 8 ? new Uint8Array(length) :
bpc <= 16 ? new Uint16Array(length) : new Uint32Array(length);
var rowComps = width * numComps;

if (bpc == 1) {
var valueZero = 0, valueOne = 1;
if (decodeMap) {
valueZero = decodeMap[0] ? 1 : 0;
valueOne = decodeMap[1] ? 1 : 0;
}
var mask = 0;
var buf = 0;

for (var i = 0, ii = length; i < ii; ++i) {
if (i % rowComps == 0) {
mask = 0;
buf = 0;
} else {
mask >>= 1;
}

if (mask <= 0) {
buf = buffer[bufferPos++];
mask = 128;
}

output[i] = !(buf & mask) ? valueZero : valueOne;
}
} else {
if (decodeMap != null)
TODO('interpolate component values');
var bits = 0, buf = 0;
for (var i = 0, ii = length; i < ii; ++i) {
if (i % rowComps == 0) {
buf = 0;
bits = 0;
}

while (bits < bpc) {
buf = (buf << 8) | buffer[bufferPos++];
bits += 8;
}

var remainingBits = bits - bpc;
output[i] = buf >> remainingBits;
buf = buf & ((1 << remainingBits) - 1);
bits = remainingBits;
}
}
return output;
},
getOpacity: function getOpacity() {
var smask = this.smask;
var width = this.width;
var height = this.height;
var buf = new Uint8Array(width * height);

if (smask) {
if (smask.image.getImage) {
// smask is a DOM image
var tempCanvas = new ScratchCanvas(width, height);
var tempCtx = tempCanvas.getContext('2d');
var domImage = smask.image.getImage();
tempCtx.drawImage(domImage, 0, 0, domImage.width, domImage.height,
0, 0, width, height);
var data = tempCtx.getImageData(0, 0, width, height).data;
for (var i = 0, j = 0, ii = width * height; i < ii; ++i, j += 4)
buf[i] = data[j]; // getting first component value
return buf;
}
var sw = smask.width;
var sh = smask.height;
if (sw != this.width || sh != this.height)
error('smask dimensions do not match image dimensions: ' + sw +
' != ' + this.width + ', ' + sh + ' != ' + this.height);

smask.fillGrayBuffer(buf);
return buf;
} else {
for (var i = 0, ii = width * height; i < ii; ++i)
buf[i] = 255;
}
return buf;
},
applyStencilMask: function applyStencilMask(buffer, inverseDecode) {
var width = this.width, height = this.height;
var bitStrideLength = (width + 7) >> 3;
this.image.reset();
var imgArray = this.image.getBytes(bitStrideLength * height);
var imgArrayPos = 0;
var i, j, mask, buf;
// removing making non-masked pixels transparent
var bufferPos = 3; // alpha component offset
for (i = 0; i < height; i++) {
mask = 0;
for (j = 0; j < width; j++) {
if (!mask) {
buf = imgArray[imgArrayPos++];
mask = 128;
}
if (!(buf & mask) == inverseDecode) {
buffer[bufferPos] = 0;
}
bufferPos += 4;
mask >>= 1;
}
}
},
fillRgbaBuffer: function fillRgbaBuffer(buffer, decodeMap) {
var numComps = this.numComps;
var width = this.width;
var height = this.height;
var bpc = this.bpc;

// rows start at byte boundary;
var rowBytes = (width * numComps * bpc + 7) >> 3;
this.image.reset();
var imgArray = this.image.getBytes(height * rowBytes);

var comps = this.colorSpace.getRgbBuffer(
this.getComponents(imgArray, decodeMap), bpc);
var compsPos = 0;
var opacity = this.getOpacity();
var opacityPos = 0;
var length = width * height * 4;

for (var i = 0; i < length; i += 4) {
buffer[i] = comps[compsPos++];
buffer[i + 1] = comps[compsPos++];
buffer[i + 2] = comps[compsPos++];
buffer[i + 3] = opacity[opacityPos++];
}
},
fillGrayBuffer: function fillGrayBuffer(buffer) {
var numComps = this.numComps;
if (numComps != 1)
error('Reading gray scale from a color image: ' + numComps);

var width = this.width;
var height = this.height;
var bpc = this.bpc;

// rows start at byte boundary;
var rowBytes = (width * numComps * bpc + 7) >> 3;
this.image.reset();
var imgArray = this.image.getBytes(height * rowBytes);

var comps = this.getComponents(imgArray);
var length = width * height;

for (var i = 0; i < length; ++i)
buffer[i] = comps[i];
}
};
return constructor;
})();

var JpegImage = (function() {
function JpegImage(objId, imageData, objs) {
var src = 'data:image/jpeg;base64,' + window.btoa(imageData);

var img = new Image();
img.onload = (function() {
this.loaded = true;

objs.resolve(objId, this);

if (this.onLoad)
this.onLoad();
}).bind(this);
img.src = src;
this.domImage = img;
}

JpegImage.prototype = {
getImage: function() {
return this.domImage;
}
};

return JpegImage;
})();
File renamed without changes.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -0,0 +1,289 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */

'use strict';

var Pattern = (function patternPattern() {
// Constructor should define this.getPattern
function constructor() {
error('should not call Pattern constructor');
}

constructor.prototype = {
// Input: current Canvas context
// Output: the appropriate fillStyle or strokeStyle
getPattern: function pattern_getStyle(ctx) {
error('Should not call Pattern.getStyle: ' + ctx);
}
};

constructor.shadingFromIR = function pattern_shadingFromIR(ctx, raw) {
return Shadings[raw[0]].fromIR(ctx, raw);
}

constructor.parseShading = function pattern_shading(shading, matrix,
xref, res, ctx) {

var dict = isStream(shading) ? shading.dict : shading;
var type = dict.get('ShadingType');

switch (type) {
case 2:
case 3:
// both radial and axial shadings are handled by RadialAxial shading
return new Shadings.RadialAxial(dict, matrix, xref, res, ctx);
default:
return new Shadings.Dummy();
}
};
return constructor;
})();

var Shadings = {};

// Radial and axial shading have very similar implementations
// If needed, the implementations can be broken into two classes
Shadings.RadialAxial = (function radialAxialShading() {
function constructor(dict, matrix, xref, res, ctx) {
this.matrix = matrix;
this.coordsArr = dict.get('Coords');
this.shadingType = dict.get('ShadingType');
this.type = 'Pattern';

this.ctx = ctx;
var cs = dict.get('ColorSpace', 'CS');
cs = ColorSpace.parse(cs, xref, res);
this.cs = cs;

var t0 = 0.0, t1 = 1.0;
if (dict.has('Domain')) {
var domainArr = dict.get('Domain');
t0 = domainArr[0];
t1 = domainArr[1];
}

var extendStart = false, extendEnd = false;
if (dict.has('Extend')) {
var extendArr = dict.get('Extend');
extendStart = extendArr[0];
extendEnd = extendArr[1];
TODO('Support extend');
}

this.extendStart = extendStart;
this.extendEnd = extendEnd;

var fnObj = dict.get('Function');
fnObj = xref.fetchIfRef(fnObj);
if (isArray(fnObj))
error('No support for array of functions');
else if (!isPDFFunction(fnObj))
error('Invalid function');
var fn = PDFFunction.parse(xref, fnObj);

// 10 samples seems good enough for now, but probably won't work
// if there are sharp color changes. Ideally, we would implement
// the spec faithfully and add lossless optimizations.
var step = (t1 - t0) / 10;
var diff = t1 - t0;

var colorStops = [];
for (var i = t0; i <= t1; i += step) {
var color = fn([i]);
var rgbColor = Util.makeCssRgb.apply(this, cs.getRgb(color));
colorStops.push([(i - t0) / diff, rgbColor]);
}

this.colorStops = colorStops;
}

constructor.fromIR = function(ctx, raw) {
var type = raw[1];
var colorStops = raw[2];
var p0 = raw[3];
var p1 = raw[4];
var r0 = raw[5];
var r1 = raw[6];

var curMatrix = ctx.mozCurrentTransform;
if (curMatrix) {
var userMatrix = ctx.mozCurrentTransformInverse;

p0 = Util.applyTransform(p0, curMatrix);
p0 = Util.applyTransform(p0, userMatrix);

p1 = Util.applyTransform(p1, curMatrix);
p1 = Util.applyTransform(p1, userMatrix);
}

if (type == 2)
var grad = ctx.createLinearGradient(p0[0], p0[1], p1[0], p1[1]);
else if (type == 3)
var grad = ctx.createRadialGradient(p0[0], p0[1], r0, p1[0], p1[1], r1);

for (var i = 0, ii = colorStops.length; i < ii; ++i) {
var c = colorStops[i];
grad.addColorStop(c[0], c[1]);
}
return grad;
}

constructor.prototype = {
getIR: function RadialAxialShading_getIR() {
var coordsArr = this.coordsArr;
var type = this.shadingType;
if (type == 2) {
var p0 = [coordsArr[0], coordsArr[1]];
var p1 = [coordsArr[2], coordsArr[3]];
var r0 = null;
var r1 = null;
} else if (type == 3) {
var p0 = [coordsArr[0], coordsArr[1]];
var p1 = [coordsArr[3], coordsArr[4]];
var r0 = coordsArr[2];
var r1 = coordsArr[5];
} else {
error('getPattern type unknown: ' + type);
}

var matrix = this.matrix;
if (matrix) {
p0 = Util.applyTransform(p0, matrix);
p1 = Util.applyTransform(p1, matrix);
}

return ['RadialAxial', type, this.colorStops, p0, p1, r0, r1];
}
};

return constructor;
})();

Shadings.Dummy = (function dummyShading() {
function constructor() {
this.type = 'Pattern';
}

constructor.fromIR = function() {
return 'hotpink';
}

constructor.prototype = {
getIR: function dummpy_getir() {
return ['Dummy'];
}
};
return constructor;
})();

var TilingPattern = (function tilingPattern() {
var PAINT_TYPE_COLORED = 1, PAINT_TYPE_UNCOLORED = 2;

function TilingPattern(IR, color, ctx, objs) {
var IRQueue = IR[2];
this.matrix = IR[3];
var bbox = IR[4];
var xstep = IR[5];
var ystep = IR[6];
var paintType = IR[7];

TODO('TilingType');

this.curMatrix = ctx.mozCurrentTransform;
this.invMatrix = ctx.mozCurrentTransformInverse;
this.ctx = ctx;
this.type = 'Pattern';

var x0 = bbox[0], y0 = bbox[1], x1 = bbox[2], y1 = bbox[3];

var topLeft = [x0, y0];
// we want the canvas to be as large as the step size
var botRight = [x0 + xstep, y0 + ystep];

var width = botRight[0] - topLeft[0];
var height = botRight[1] - topLeft[1];

// TODO: hack to avoid OOM, we would idealy compute the tiling
// pattern to be only as large as the acual size in device space
// This could be computed with .mozCurrentTransform, but still
// needs to be implemented
while (Math.abs(width) > 512 || Math.abs(height) > 512) {
width = 512;
height = 512;
}

var tmpCanvas = new ScratchCanvas(width, height);

// set the new canvas element context as the graphics context
var tmpCtx = tmpCanvas.getContext('2d');
var graphics = new CanvasGraphics(tmpCtx, objs);

switch (paintType) {
case PAINT_TYPE_COLORED:
tmpCtx.fillStyle = ctx.fillStyle;
tmpCtx.strokeStyle = ctx.strokeStyle;
break;
case PAINT_TYPE_UNCOLORED:
color = Util.makeCssRgb.apply(this, color);
tmpCtx.fillStyle = color;
tmpCtx.strokeStyle = color;
break;
default:
error('Unsupported paint type: ' + paintType);
}

var scale = [width / xstep, height / ystep];
this.scale = scale;

// transform coordinates to pattern space
var tmpTranslate = [1, 0, 0, 1, -topLeft[0], -topLeft[1]];
var tmpScale = [scale[0], 0, 0, scale[1], 0, 0];
graphics.transform.apply(graphics, tmpScale);
graphics.transform.apply(graphics, tmpTranslate);

if (bbox && isArray(bbox) && 4 == bbox.length) {
var bboxWidth = bbox[2] - bbox[0];
var bboxHeight = bbox[3] - bbox[1];
graphics.rectangle(bbox[0], bbox[1], bboxWidth, bboxHeight);
graphics.clip();
graphics.endPath();
}

graphics.executeIRQueue(IRQueue);

this.canvas = tmpCanvas;
}

TilingPattern.getIR = function tiling_getIR(codeIR, dict, args) {
var matrix = dict.get('Matrix');
var bbox = dict.get('BBox');
var xstep = dict.get('XStep');
var ystep = dict.get('YStep');
var paintType = dict.get('PaintType');

return [
'TilingPattern', args, codeIR, matrix, bbox, xstep, ystep, paintType
];
}

TilingPattern.prototype = {
getPattern: function tiling_getPattern() {
var matrix = this.matrix;
var curMatrix = this.curMatrix;
var ctx = this.ctx;

if (curMatrix)
ctx.setTransform.apply(ctx, curMatrix);

if (matrix)
ctx.transform.apply(ctx, matrix);

var scale = this.scale;
ctx.scale(1 / scale[0], 1 / scale[1]);

return ctx.createPattern(this.canvas, 'repeat');
}
};

return TilingPattern;
})();
@@ -0,0 +1,14 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */

var PDFJS = {};

(function pdfjsWrapper() {

// Use strict in our context only - users might not want it
'use strict';

// Files are inserted below - see Makefile
/* PDFJSSCRIPT_INCLUDE_ALL */

})();

Large diffs are not rendered by default.

@@ -0,0 +1,285 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */

'use strict';

function log(msg) {
if (console && console.log)
console.log(msg);
else if (print)
print(msg);
}

function warn(msg) {
if (verbosity >= WARNINGS)
log('Warning: ' + msg);
}

function backtrace() {
var stackStr;
try {
throw new Error();
} catch (e) {
stackStr = e.stack;
}
return stackStr.split('\n').slice(1).join('\n');
}

function error(msg) {
log(backtrace());
throw new Error(msg);
}

function TODO(what) {
if (verbosity >= TODOS)
log('TODO: ' + what);
}

function malformed(msg) {
error('Malformed PDF: ' + msg);
}

function assert(cond, msg) {
if (!cond)
error(msg);
}

// In a well-formed PDF, |cond| holds. If it doesn't, subsequent
// behavior is undefined.
function assertWellFormed(cond, msg) {
if (!cond)
malformed(msg);
}

function shadow(obj, prop, value) {
Object.defineProperty(obj, prop, { value: value,
enumerable: true,
configurable: true,
writable: false });
return value;
}

function bytesToString(bytes) {
var str = '';
var length = bytes.length;
for (var n = 0; n < length; ++n)
str += String.fromCharCode(bytes[n]);
return str;
}

function stringToBytes(str) {
var length = str.length;
var bytes = new Uint8Array(length);
for (var n = 0; n < length; ++n)
bytes[n] = str.charCodeAt(n) & 0xFF;
return bytes;
}

var IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];

var Util = (function utilUtil() {
function constructor() {}
constructor.makeCssRgb = function makergb(r, g, b) {
var ri = (255 * r) | 0, gi = (255 * g) | 0, bi = (255 * b) | 0;
return 'rgb(' + ri + ',' + gi + ',' + bi + ')';
};
constructor.makeCssCmyk = function makecmyk(c, m, y, k) {
c = (new DeviceCmykCS()).getRgb([c, m, y, k]);
var ri = (255 * c[0]) | 0, gi = (255 * c[1]) | 0, bi = (255 * c[2]) | 0;
return 'rgb(' + ri + ',' + gi + ',' + bi + ')';
};
constructor.applyTransform = function apply(p, m) {
var xt = p[0] * m[0] + p[1] * m[2] + m[4];
var yt = p[0] * m[1] + p[1] * m[3] + m[5];
return [xt, yt];
};

return constructor;
})();

var PDFStringTranslateTable = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0x2D8, 0x2C7, 0x2C6, 0x2D9, 0x2DD, 0x2DB, 0x2DA, 0x2DC, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014,
0x2013, 0x192, 0x2044, 0x2039, 0x203A, 0x2212, 0x2030, 0x201E, 0x201C,
0x201D, 0x2018, 0x2019, 0x201A, 0x2122, 0xFB01, 0xFB02, 0x141, 0x152, 0x160,
0x178, 0x17D, 0x131, 0x142, 0x153, 0x161, 0x17E, 0, 0x20AC
];

function stringToPDFString(str) {
var i, n = str.length, str2 = '';
if (str[0] === '\xFE' && str[1] === '\xFF') {
// UTF16BE BOM
for (i = 2; i < n; i += 2)
str2 += String.fromCharCode(
(str.charCodeAt(i) << 8) | str.charCodeAt(i + 1));
} else {
for (i = 0; i < n; ++i) {
var code = PDFStringTranslateTable[str.charCodeAt(i)];
str2 += code ? String.fromCharCode(code) : str.charAt(i);
}
}
return str2;
}

function isBool(v) {
return typeof v == 'boolean';
}

function isInt(v) {
return typeof v == 'number' && ((v | 0) == v);
}

function isNum(v) {
return typeof v == 'number';
}

function isString(v) {
return typeof v == 'string';
}

function isNull(v) {
return v === null;
}

function isName(v) {
return v instanceof Name;
}

function isCmd(v, cmd) {
return v instanceof Cmd && (!cmd || v.cmd == cmd);
}

function isDict(v, type) {
return v instanceof Dict && (!type || v.get('Type').name == type);
}

function isArray(v) {
return v instanceof Array;
}

function isStream(v) {
return typeof v == 'object' && v != null && ('getChar' in v);
}

function isArrayBuffer(v) {
return typeof v == 'object' && v != null && ('byteLength' in v);
}

function isRef(v) {
return v instanceof Ref;
}

function isPDFFunction(v) {
var fnDict;
if (typeof v != 'object')
return false;
else if (isDict(v))
fnDict = v;
else if (isStream(v))
fnDict = v.dict;
else
return false;
return fnDict.has('FunctionType');
}

/**
* 'Promise' object.
* Each object that is stored in PDFObjects is based on a Promise object that
* contains the status of the object and the data. There migth be situations,
* where a function want to use the value of an object, but it isn't ready at
* that time. To get a notification, once the object is ready to be used, s.o.
* can add a callback using the `then` method on the promise that then calls
* the callback once the object gets resolved.
* A promise can get resolved only once and only once the data of the promise
* can be set. If any of these happens twice or the data is required before
* it was set, an exception is throw.
*/
var Promise = (function() {
var EMPTY_PROMISE = {};

/**
* If `data` is passed in this constructor, the promise is created resolved.
* If there isn't data, it isn't resolved at the beginning.
*/
function Promise(name, data) {
this.name = name;
// If you build a promise and pass in some data it's already resolved.
if (data != null) {
this.isResolved = true;
this._data = data;
this.hasData = true;
} else {
this.isResolved = false;
this._data = EMPTY_PROMISE;
}
this.callbacks = [];
};

Promise.prototype = {
hasData: false,

set data(data) {
if (data === undefined) {
return;
}
if (this._data !== EMPTY_PROMISE) {
throw 'Promise ' + this.name +
': Cannot set the data of a promise twice';
}
this._data = data;
this.hasData = true;

if (this.onDataCallback) {
this.onDataCallback(data);
}
},

get data() {
if (this._data === EMPTY_PROMISE) {
throw 'Promise ' + this.name + ': Cannot get data that isn\'t set';
}
return this._data;
},

onData: function(callback) {
if (this._data !== EMPTY_PROMISE) {
callback(this._data);
} else {
this.onDataCallback = callback;
}
},

resolve: function(data) {
if (this.isResolved) {
throw 'A Promise can be resolved only once ' + this.name;
}

this.isResolved = true;
this.data = data;
var callbacks = this.callbacks;

for (var i = 0; i < callbacks.length; i++) {
callbacks[i].call(null, data);
}
},

then: function(callback) {
if (!callback) {
throw 'Requiring callback' + this.name;
}

// If the promise is already resolved, call the callback directly.
if (this.isResolved) {
var data = this.data;
callback.call(null, data);
} else {
this.callbacks.push(callback);
}
}
};
return Promise;
})();
@@ -1,8 +1,6 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */

'use strict';

var CFFEncodingMap = {
'0': '-reserved-',
'1': 'hstem',
@@ -1,8 +1,6 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */

'use strict';

/*
* The Type2 reader code below is only used for debugging purpose since Type2
* is only a CharString format and is never used directly as a Font file.
@@ -1,8 +1,48 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */

'use strict';

function MessageHandler(name, comObj) {
this.name = name;
this.comObj = comObj;
var ah = this.actionHandler = {};

ah['console_log'] = [function(data) {
console.log.apply(console, data);
}];
ah['console_error'] = [function(data) {
console.error.apply(console, data);
}];

comObj.onmessage = function(event) {
var data = event.data;
if (data.action in ah) {
var action = ah[data.action];
action[0].call(action[1], data.data);
} else {
throw 'Unkown action from worker: ' + data.action;
}
};
}

MessageHandler.prototype = {
on: function(actionName, handler, scope) {
var ah = this.actionHandler;
if (ah[actionName]) {
throw "There is already an actionName called '" + actionName + "'";
}
ah[actionName] = [handler, scope];
},

send: function(actionName, data) {
this.comObj.postMessage({
action: actionName,
data: data
});
}
};

var WorkerProcessorHandler = {
setup: function(handler) {
var pdfDoc = null;
@@ -99,3 +139,44 @@ var WorkerProcessorHandler = {
});
}
};

var consoleTimer = {};

var workerConsole = {
log: function log() {
var args = Array.prototype.slice.call(arguments);
postMessage({
action: 'console_log',
data: args
});
},

error: function error() {
var args = Array.prototype.slice.call(arguments);
postMessage({
action: 'console_error',
data: args
});
},

time: function(name) {
consoleTimer[name] = Date.now();
},

timeEnd: function(name) {
var time = consoleTimer[name];
if (time == null) {
throw 'Unkown timer name ' + name;
}
this.log('Timer:', name, Date.now() - time);
}
};

// Worker thread?
if (typeof window === 'undefined') {
globalScope.console = workerConsole;

// Listen for messages from the main thread.
var handler = new MessageHandler('worker_processor', globalScope);
WorkerProcessorHandler.setup(handler);
}
@@ -0,0 +1,23 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */

'use strict';

importScripts('../src/core.js');
importScripts('../src/util.js');
importScripts('../src/canvas.js');
importScripts('../src/obj.js');
importScripts('../src/function.js');
importScripts('../src/charsets.js');
importScripts('../src/cidmaps.js');
importScripts('../src/colorspace.js');
importScripts('../src/crypto.js');
importScripts('../src/evaluator.js');
importScripts('../src/fonts.js');
importScripts('../src/glyphlist.js');
importScripts('../src/image.js');
importScripts('../src/metrics.js');
importScripts('../src/parser.js');
importScripts('../src/pattern.js');
importScripts('../src/stream.js');
importScripts('../src/worker.js');
@@ -82,7 +82,7 @@ function nextTask() {
getPdf(task.file, function nextTaskGetPdf(data) {
var failure;
try {
task.pdfDoc = new PDFDoc(data);
task.pdfDoc = new PDFJS.PDFDoc(data);
} catch (e) {
failure = 'load PDF doc : ' + e.toString();
}
@@ -318,7 +318,7 @@ def downloadLinkedPDFs(manifestList):

def setUp(options):
# Only serve files from a pdf.js clone
assert not ANAL or os.path.isfile('../pdf.js') and os.path.isdir('../.git')
assert not ANAL or os.path.isfile('../src/pdf.js') and os.path.isdir('../.git')

if options.masterMode and os.path.isdir(TMPDIR):
print 'Temporary snapshot dir tmp/ is still around.'
@@ -3,16 +3,25 @@
<head>
<title>pdf.js test slave</title>
<style type="text/css"></style>
<script type="text/javascript" src="/pdf.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="/metrics.js"></script>
<script type="text/javascript" src="/charsets.js"></script>
<script type="text/javascript" src="/cidmaps.js"></script>
<script type="text/javascript" src="/src/core.js"></script>
<script type="text/javascript" src="/src/util.js"></script>
<script type="text/javascript" src="/src/canvas.js"></script>
<script type="text/javascript" src="/src/obj.js"></script>
<script type="text/javascript" src="/src/function.js"></script>
<script type="text/javascript" src="/src/charsets.js"></script>
<script type="text/javascript" src="/src/cidmaps.js"></script>
<script type="text/javascript" src="/src/colorspace.js"></script>
<script type="text/javascript" src="/src/crypto.js"></script>
<script type="text/javascript" src="/src/evaluator.js"></script>
<script type="text/javascript" src="/src/fonts.js"></script>
<script type="text/javascript" src="/src/glyphlist.js"></script>
<script type="text/javascript" src="/src/image.js"></script>
<script type="text/javascript" src="/src/metrics.js"></script>
<script type="text/javascript" src="/src/parser.js"></script>
<script type="text/javascript" src="/src/pattern.js"></script>
<script type="text/javascript" src="/src/stream.js"></script>
<script type="text/javascript" src="/src/worker.js"></script>
<script type="text/javascript" src="driver.js"></script>
<script type="text/javascript" src="../worker/message_handler.js"></script>
<script type="text/javascript" src="../worker/processor_handler.js"></script>
</head>

<body>
@@ -0,0 +1 @@
viewer-production.html
@@ -0,0 +1,2 @@
<!-- This snippet is used in production, see Makefile -->
<script type="text/javascript" src="../build/pdf.js"></script>
@@ -3,18 +3,30 @@
<head>
<title>Simple pdf.js page viewer</title>
<link rel="stylesheet" href="viewer.css"/>

<!-- PDFJSSCRIPT_INCLUDE_BUILD -->

<script type="text/javascript" src="../src/core.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
<script type="text/javascript" src="../src/util.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
<script type="text/javascript" src="../src/canvas.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
<script type="text/javascript" src="../src/obj.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
<script type="text/javascript" src="../src/function.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
<script type="text/javascript" src="../src/charsets.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
<script type="text/javascript" src="../src/cidmaps.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
<script type="text/javascript" src="../src/colorspace.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
<script type="text/javascript" src="../src/crypto.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
<script type="text/javascript" src="../src/evaluator.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
<script type="text/javascript" src="../src/fonts.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
<script type="text/javascript" src="../src/glyphlist.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
<script type="text/javascript" src="../src/image.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
<script type="text/javascript" src="../src/metrics.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
<script type="text/javascript" src="../src/parser.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
<script type="text/javascript" src="../src/pattern.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
<script type="text/javascript" src="../src/stream.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
<script type="text/javascript" src="../src/worker.js"></script> <!-- PDFJSSCRIPT_REMOVE -->

<script type="text/javascript" src="compatibility.js"></script>
<script type="text/javascript" src="viewer.js"></script>
<script type="text/javascript" src="../pdf.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="../metrics.js"></script>
<script type="text/javascript" src="../charsets.js"></script>
<script type="text/javascript" src="../cidmaps.js"></script>
<script type="text/javascript" src="../worker/message_handler.js"></script>
<script type="text/javascript" src="../worker/processor_handler.js"></script>
</head>

<body>
@@ -122,7 +122,7 @@ var PDFView = {
document.title = this.url = url;

var self = this;
getPdf(
PDFJS.getPdf(
{
url: url,
progress: function getPdfProgress(evt) {
@@ -209,7 +209,7 @@ var PDFView = {
while (container.hasChildNodes())
container.removeChild(container.lastChild);

var pdf = new PDFDoc(data);
var pdf = new PDFJS.PDFDoc(data);
var pagesCount = pdf.numPages;
document.getElementById('numPages').innerHTML = pagesCount;
document.getElementById('pageNumber').max = pagesCount;

This file was deleted.

This file was deleted.

This file was deleted.