|
|
@ -1,6 +1,5 @@ |
|
|
|
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- / |
|
|
|
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- / |
|
|
|
/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ |
|
|
|
/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ |
|
|
|
|
|
|
|
|
|
|
|
function warn(msg) { |
|
|
|
function warn(msg) { |
|
|
|
if (console && console.log) |
|
|
|
if (console && console.log) |
|
|
|
console.log(msg); |
|
|
|
console.log(msg); |
|
|
@ -18,10 +17,11 @@ function shadow(obj, prop, value) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var Stream = (function() { |
|
|
|
var Stream = (function() { |
|
|
|
function constructor(arrayBuffer) { |
|
|
|
function constructor(arrayBuffer, dict) { |
|
|
|
this.bytes = new Uint8Array(arrayBuffer); |
|
|
|
this.bytes = new Uint8Array(arrayBuffer); |
|
|
|
this.pos = 0; |
|
|
|
this.pos = 0; |
|
|
|
this.start = 0; |
|
|
|
this.start = 0; |
|
|
|
|
|
|
|
this.dict = dict; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
constructor.prototype = { |
|
|
|
constructor.prototype = { |
|
|
@ -58,11 +58,11 @@ var Stream = (function() { |
|
|
|
moveStart: function() { |
|
|
|
moveStart: function() { |
|
|
|
this.start = this.pos; |
|
|
|
this.start = this.pos; |
|
|
|
}, |
|
|
|
}, |
|
|
|
makeSubStream: function(pos, length) { |
|
|
|
makeSubStream: function(pos, length, dict) { |
|
|
|
var buffer = this.bytes.buffer; |
|
|
|
var buffer = this.bytes.buffer; |
|
|
|
if (length) |
|
|
|
if (length) |
|
|
|
return new Stream(new Uint8Array(buffer, pos, length)); |
|
|
|
return new Stream(new Uint8Array(buffer, pos, length), dict); |
|
|
|
return new Stream(new Uint8Array(buffer, pos)); |
|
|
|
return new Stream(new Uint8Array(buffer, pos), dict); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
@ -1196,7 +1196,7 @@ var Lexer = (function() { |
|
|
|
case '\\': |
|
|
|
case '\\': |
|
|
|
case '(': |
|
|
|
case '(': |
|
|
|
case ')': |
|
|
|
case ')': |
|
|
|
str += c; |
|
|
|
str += ch; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case '0': case '1': case '2': case '3': |
|
|
|
case '0': case '1': case '2': case '3': |
|
|
|
case '4': case '5': case '6': case '7': |
|
|
|
case '4': case '5': case '6': case '7': |
|
|
@ -1500,7 +1500,7 @@ var Parser = (function() { |
|
|
|
error("Missing 'endstream'"); |
|
|
|
error("Missing 'endstream'"); |
|
|
|
this.shift(); |
|
|
|
this.shift(); |
|
|
|
|
|
|
|
|
|
|
|
stream = stream.makeSubStream(pos, length); |
|
|
|
stream = stream.makeSubStream(pos, length, dict); |
|
|
|
if (this.fileKey) { |
|
|
|
if (this.fileKey) { |
|
|
|
stream = new DecryptStream(stream, |
|
|
|
stream = new DecryptStream(stream, |
|
|
|
this.fileKey, |
|
|
|
this.fileKey, |
|
|
@ -1813,30 +1813,11 @@ var Page = (function() { |
|
|
|
var mediaBox = xref.fetchIfRef(this.mediaBox); |
|
|
|
var mediaBox = xref.fetchIfRef(this.mediaBox); |
|
|
|
if (!IsStream(contents) || !IsDict(resources)) |
|
|
|
if (!IsStream(contents) || !IsDict(resources)) |
|
|
|
error("invalid page contents or resources"); |
|
|
|
error("invalid page contents or resources"); |
|
|
|
gfx.resources = resources; |
|
|
|
|
|
|
|
gfx.beginDrawing({ x: mediaBox[0], y: mediaBox[1], |
|
|
|
gfx.beginDrawing({ x: mediaBox[0], y: mediaBox[1], |
|
|
|
width: mediaBox[2] - mediaBox[0], |
|
|
|
width: mediaBox[2] - mediaBox[0], |
|
|
|
height: mediaBox[3] - mediaBox[1] }); |
|
|
|
height: mediaBox[3] - mediaBox[1] }); |
|
|
|
var args = []; |
|
|
|
gfx.interpret(new Parser(new Lexer(contents), false), |
|
|
|
var map = gfx.map; |
|
|
|
xref, resources); |
|
|
|
var parser = new Parser(new Lexer(contents), false); |
|
|
|
|
|
|
|
var obj; |
|
|
|
|
|
|
|
while (!IsEOF(obj = parser.getObj())) { |
|
|
|
|
|
|
|
if (IsCmd(obj)) { |
|
|
|
|
|
|
|
var cmd = obj.cmd; |
|
|
|
|
|
|
|
var fn = map[cmd]; |
|
|
|
|
|
|
|
if (fn) |
|
|
|
|
|
|
|
// TODO figure out how to type-check vararg functions
|
|
|
|
|
|
|
|
fn.apply(gfx, args); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
error("Unknown command '" + cmd + "'"); |
|
|
|
|
|
|
|
args.length = 0; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
if (args.length > 33) |
|
|
|
|
|
|
|
error("Too many arguments '" + cmd + "'"); |
|
|
|
|
|
|
|
args.push(obj); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
gfx.endDrawing(); |
|
|
|
gfx.endDrawing(); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
@ -2040,6 +2021,8 @@ var CanvasGraphics = (function() { |
|
|
|
this.current = new CanvasExtraState(); |
|
|
|
this.current = new CanvasExtraState(); |
|
|
|
this.stateStack = [ ]; |
|
|
|
this.stateStack = [ ]; |
|
|
|
this.pendingClip = null; |
|
|
|
this.pendingClip = null; |
|
|
|
|
|
|
|
this.res = null; |
|
|
|
|
|
|
|
this.xobjs = null; |
|
|
|
this.map = { |
|
|
|
this.map = { |
|
|
|
// Graphics state
|
|
|
|
// Graphics state
|
|
|
|
w: this.setLineWidth, |
|
|
|
w: this.setLineWidth, |
|
|
@ -2115,6 +2098,38 @@ var CanvasGraphics = (function() { |
|
|
|
this.ctx.scale(cw / mediaBox.width, -ch / mediaBox.height); |
|
|
|
this.ctx.scale(cw / mediaBox.width, -ch / mediaBox.height); |
|
|
|
this.ctx.translate(0, -mediaBox.height); |
|
|
|
this.ctx.translate(0, -mediaBox.height); |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
interpret: function(parser, xref, resources) { |
|
|
|
|
|
|
|
var savedXref = this.xref, savedRes = this.res, savedXobjs = this.xobjs; |
|
|
|
|
|
|
|
this.xref = xref; |
|
|
|
|
|
|
|
this.res = resources || new Dict(); |
|
|
|
|
|
|
|
this.xobjs = this.res.get("XObject") || new Dict(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var args = []; |
|
|
|
|
|
|
|
var map = this.map; |
|
|
|
|
|
|
|
var obj; |
|
|
|
|
|
|
|
while (!IsEOF(obj = parser.getObj())) { |
|
|
|
|
|
|
|
if (IsCmd(obj)) { |
|
|
|
|
|
|
|
var cmd = obj.cmd; |
|
|
|
|
|
|
|
var fn = map[cmd]; |
|
|
|
|
|
|
|
if (fn) |
|
|
|
|
|
|
|
// TODO figure out how to type-check vararg functions
|
|
|
|
|
|
|
|
fn.apply(this, args); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
error("Unknown command '" + cmd + "'"); |
|
|
|
|
|
|
|
args.length = 0; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
if (args.length > 33) |
|
|
|
|
|
|
|
error("Too many arguments '" + cmd + "'"); |
|
|
|
|
|
|
|
args.push(obj); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.xobjs = savedXobjs; |
|
|
|
|
|
|
|
this.res = savedRes; |
|
|
|
|
|
|
|
this.xref = savedXref; |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
endDrawing: function() { |
|
|
|
endDrawing: function() { |
|
|
|
this.ctx.restore(); |
|
|
|
this.ctx.restore(); |
|
|
|
}, |
|
|
|
}, |
|
|
@ -2144,8 +2159,11 @@ var CanvasGraphics = (function() { |
|
|
|
this.current = new CanvasExtraState(); |
|
|
|
this.current = new CanvasExtraState(); |
|
|
|
}, |
|
|
|
}, |
|
|
|
restore: function() { |
|
|
|
restore: function() { |
|
|
|
this.current = this.stateStack.pop(); |
|
|
|
var prev = this.stateStack.pop(); |
|
|
|
|
|
|
|
if (prev) { |
|
|
|
|
|
|
|
this.current = prev; |
|
|
|
this.ctx.restore(); |
|
|
|
this.ctx.restore(); |
|
|
|
|
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
transform: function(a, b, c, d, e, f) { |
|
|
|
transform: function(a, b, c, d, e, f) { |
|
|
|
this.ctx.transform(a, b, c, d, e, f); |
|
|
|
this.ctx.transform(a, b, c, d, e, f); |
|
|
@ -2207,7 +2225,9 @@ var CanvasGraphics = (function() { |
|
|
|
// TODO
|
|
|
|
// TODO
|
|
|
|
}, |
|
|
|
}, |
|
|
|
setFont: function(fontRef, size) { |
|
|
|
setFont: function(fontRef, size) { |
|
|
|
var font = this.resources.get("Font").get(fontRef.name); |
|
|
|
var font = this.res.get("Font").get(fontRef.name); |
|
|
|
|
|
|
|
if (!font) |
|
|
|
|
|
|
|
return; |
|
|
|
this.current.fontSize = size; |
|
|
|
this.current.fontSize = size; |
|
|
|
this.ctx.font = this.current.fontSize +'px '+ font.BaseFont; |
|
|
|
this.ctx.font = this.current.fontSize +'px '+ font.BaseFont; |
|
|
|
}, |
|
|
|
}, |
|
|
@ -2282,7 +2302,15 @@ var CanvasGraphics = (function() { |
|
|
|
|
|
|
|
|
|
|
|
// XObjects
|
|
|
|
// XObjects
|
|
|
|
paintXObject: function(obj) { |
|
|
|
paintXObject: function(obj) { |
|
|
|
// TODO
|
|
|
|
var xobj = this.xobjs.get(obj.name); |
|
|
|
|
|
|
|
if (!xobj) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
xobj = this.xref.fetchIfRef(xobj); |
|
|
|
|
|
|
|
if (!IsStream(xobj)) |
|
|
|
|
|
|
|
error("XObject should be a stream"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.interpret(new Parser(new Lexer(xobj), false), |
|
|
|
|
|
|
|
this.xref, xobj.dict.get("Resources")); |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
// Helper functions
|
|
|
|
// Helper functions
|
|
|
|