Merge branch 'master' of gitorious.org:owncloud/owncloud
|
@ -3,7 +3,7 @@ var bookmarks_loading = false;
|
|||
|
||||
var bookmarks_sorting = 'bookmarks_sorting_recent';
|
||||
|
||||
$(document).ready(function() {
|
||||
$(document).ready(function() {
|
||||
$('#bookmark_add_submit').click(addOrEditBookmark);
|
||||
$(window).resize(function () {
|
||||
fillWindow($('.bookmarks_list'));
|
||||
|
@ -18,10 +18,10 @@ function getBookmarks() {
|
|||
//have patience :)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$.ajax({
|
||||
url: 'ajax/updateList.php',
|
||||
data: 'tag=' + encodeURI($('#bookmarkFilterTag').val()) + '&page=' + bookmarks_page + '&sort=' + bookmarks_sorting,
|
||||
data: 'tag=' + encodeURIComponent($('#bookmarkFilterTag').val()) + '&page=' + bookmarks_page + '&sort=' + bookmarks_sorting,
|
||||
success: function(bookmarks){
|
||||
if (bookmarks.data.length) {
|
||||
bookmarks_page += 1;
|
||||
|
@ -29,7 +29,7 @@ function getBookmarks() {
|
|||
$('.bookmark_link').unbind('click', recordClick);
|
||||
$('.bookmark_delete').unbind('click', delBookmark);
|
||||
$('.bookmark_edit').unbind('click', showBookmark);
|
||||
|
||||
|
||||
for(var i in bookmarks.data) {
|
||||
updateBookmarksList(bookmarks.data[i]);
|
||||
$("#firstrun").hide();
|
||||
|
@ -41,13 +41,13 @@ function getBookmarks() {
|
|||
$('.bookmark_link').click(recordClick);
|
||||
$('.bookmark_delete').click(delBookmark);
|
||||
$('.bookmark_edit').click(showBookmark);
|
||||
|
||||
|
||||
bookmarks_loading = false;
|
||||
if (bookmarks.data.length) {
|
||||
updateOnBottom()
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// function addBookmark() {
|
||||
|
@ -60,13 +60,13 @@ function addOrEditBookmark(event) {
|
|||
var title = encodeEntities($('#bookmark_add_title').val());
|
||||
var tags = encodeEntities($('#bookmark_add_tags').val());
|
||||
$("#firstrun").hide();
|
||||
|
||||
|
||||
if (id == 0) {
|
||||
$.ajax({
|
||||
url: 'ajax/addBookmark.php',
|
||||
data: 'url=' + encodeURI(url) + '&title=' + encodeURI(title) + '&tags=' + encodeURI(tags),
|
||||
success: function(response){
|
||||
$('.bookmarks_input').val('');
|
||||
data: 'url=' + encodeURIComponent(url) + '&title=' + encodeURIComponent(title) + '&tags=' + encodeURIComponent(tags),
|
||||
success: function(response){
|
||||
$('.bookmarks_input').val('');
|
||||
$('.bookmarks_list').empty();
|
||||
bookmarks_page = 0;
|
||||
getBookmarks();
|
||||
|
@ -76,8 +76,8 @@ function addOrEditBookmark(event) {
|
|||
else {
|
||||
$.ajax({
|
||||
url: 'ajax/editBookmark.php',
|
||||
data: 'id=' + id + '&url=' + encodeURI(url) + '&title=' + encodeURI(title) + '&tags=' + encodeURI(tags),
|
||||
success: function(){
|
||||
data: 'id=' + id + '&url=' + encodeURIComponent(url) + '&title=' + encodeURIComponent(title) + '&tags=' + encodeURIComponent(tags),
|
||||
success: function(){
|
||||
$('.bookmarks_input').val('');
|
||||
$('#bookmark_add_id').val('0');
|
||||
$('.bookmarks_list').empty();
|
||||
|
@ -86,14 +86,14 @@ function addOrEditBookmark(event) {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function delBookmark(event) {
|
||||
var record = $(this).parent().parent();
|
||||
$.ajax({
|
||||
url: 'ajax/delBookmark.php',
|
||||
data: 'url=' + encodeURI($(this).parent().parent().children('.bookmark_url:first').text()),
|
||||
data: 'url=' + encodeURIComponent($(this).parent().parent().children('.bookmark_url:first').text()),
|
||||
success: function(data){
|
||||
record.remove();
|
||||
if($('.bookmarks_list').is(':empty')) {
|
||||
|
@ -109,7 +109,7 @@ function showBookmark(event) {
|
|||
$('#bookmark_add_url').val(record.children('.bookmark_url:first').text());
|
||||
$('#bookmark_add_title').val(record.children('.bookmark_title:first').text());
|
||||
$('#bookmark_add_tags').val(record.children('.bookmark_tags:first').text());
|
||||
|
||||
|
||||
if ($('.bookmarks_add').css('display') == 'none') {
|
||||
$('.bookmarks_add').slideToggle();
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ function updateBookmarksList(bookmark) {
|
|||
var taglist = '';
|
||||
for ( var i=0, len=tags.length; i<len; ++i ){
|
||||
if(tags[i] != '')
|
||||
taglist = taglist + '<a class="bookmark_tag" href="?tag=' + encodeURI(tags[i]) + '">' + tags[i] + '</a> ';
|
||||
taglist = taglist + '<a class="bookmark_tag" href="?tag=' + encodeURIComponent(tags[i]) + '">' + tags[i] + '</a> ';
|
||||
}
|
||||
if(!hasProtocol(bookmark.url)) {
|
||||
bookmark.url = 'http://' + bookmark.url;
|
||||
|
@ -165,8 +165,8 @@ function updateOnBottom() {
|
|||
function recordClick(event) {
|
||||
$.ajax({
|
||||
url: 'ajax/recordClick.php',
|
||||
data: 'url=' + encodeURI($(this).attr('href')),
|
||||
});
|
||||
data: 'url=' + encodeURIComponent($(this).attr('href')),
|
||||
});
|
||||
}
|
||||
|
||||
function encodeEntities(s){
|
||||
|
|
10044
apps/files_pdfviewer/js/pdfjs/build/pdf.js
Executable file → Normal file
432
apps/files_pdfviewer/js/pdfjs/src/bidi.js
Normal file
|
@ -0,0 +1,432 @@
|
|||
/* -*- 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 bidi = PDFJS.bidi = (function bidiClosure() {
|
||||
// Character types for symbols from 0000 to 00FF.
|
||||
var baseTypes = [
|
||||
'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'S', 'B', 'S', 'WS',
|
||||
'B', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN',
|
||||
'BN', 'BN', 'B', 'B', 'B', 'S', 'WS', 'ON', 'ON', 'ET', 'ET', 'ET', 'ON',
|
||||
'ON', 'ON', 'ON', 'ON', 'ON', 'CS', 'ON', 'CS', 'ON', 'EN', 'EN', 'EN',
|
||||
'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'ON', 'ON', 'ON', 'ON', 'ON',
|
||||
'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
|
||||
'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'ON', 'ON',
|
||||
'ON', 'ON', 'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
|
||||
'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
|
||||
'L', 'ON', 'ON', 'ON', 'ON', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'B', 'BN',
|
||||
'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN',
|
||||
'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN',
|
||||
'BN', 'CS', 'ON', 'ET', 'ET', 'ET', 'ET', 'ON', 'ON', 'ON', 'ON', 'L', 'ON',
|
||||
'ON', 'ON', 'ON', 'ON', 'ET', 'ET', 'EN', 'EN', 'ON', 'L', 'ON', 'ON', 'ON',
|
||||
'EN', 'L', 'ON', 'ON', 'ON', 'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
|
||||
'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
|
||||
'L', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
|
||||
'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
|
||||
'L', 'L', 'L', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L'
|
||||
];
|
||||
|
||||
// Character types for symbols from 0600 to 06FF
|
||||
var arabicTypes = [
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'CS', 'AL', 'ON', 'ON', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM',
|
||||
'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN',
|
||||
'AN', 'ET', 'AN', 'AN', 'AL', 'AL', 'AL', 'NSM', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM',
|
||||
'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'ON', 'NSM',
|
||||
'NSM', 'NSM', 'NSM', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL'
|
||||
];
|
||||
|
||||
function isOdd(i) {
|
||||
return (i & 1) != 0;
|
||||
}
|
||||
|
||||
function isEven(i) {
|
||||
return (i & 1) == 0;
|
||||
}
|
||||
|
||||
function findUnequal(arr, start, value) {
|
||||
var j;
|
||||
for (var j = start, jj = arr.length; j < jj; ++j) {
|
||||
if (arr[j] != value)
|
||||
return j;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
function setValues(arr, start, end, value) {
|
||||
for (var j = start; j < end; ++j) {
|
||||
arr[j] = value;
|
||||
}
|
||||
}
|
||||
|
||||
function reverseValues(arr, start, end) {
|
||||
for (var i = start, j = end - 1; i < j; ++i, --j) {
|
||||
var temp = arr[i];
|
||||
arr[i] = arr[j];
|
||||
arr[j] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
function mirrorGlyphs(c) {
|
||||
/*
|
||||
# BidiMirroring-1.txt
|
||||
0028; 0029 # LEFT PARENTHESIS
|
||||
0029; 0028 # RIGHT PARENTHESIS
|
||||
003C; 003E # LESS-THAN SIGN
|
||||
003E; 003C # GREATER-THAN SIGN
|
||||
005B; 005D # LEFT SQUARE BRACKET
|
||||
005D; 005B # RIGHT SQUARE BRACKET
|
||||
007B; 007D # LEFT CURLY BRACKET
|
||||
007D; 007B # RIGHT CURLY BRACKET
|
||||
00AB; 00BB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
00BB; 00AB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
*/
|
||||
switch (c) {
|
||||
case '(':
|
||||
return ')';
|
||||
case ')':
|
||||
return '(';
|
||||
case '<':
|
||||
return '>';
|
||||
case '>':
|
||||
return '<';
|
||||
case ']':
|
||||
return '[';
|
||||
case '[':
|
||||
return ']';
|
||||
case '}':
|
||||
return '{';
|
||||
case '{':
|
||||
return '}';
|
||||
case '\u00AB':
|
||||
return '\u00BB';
|
||||
case '\u00BB':
|
||||
return '\u00AB';
|
||||
default:
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
function bidi(text, startLevel) {
|
||||
var str = text.str;
|
||||
var strLength = str.length;
|
||||
if (strLength == 0)
|
||||
return str;
|
||||
|
||||
// get types, fill arrays
|
||||
|
||||
var chars = [];
|
||||
var types = [];
|
||||
var oldtypes = [];
|
||||
var numBidi = 0;
|
||||
|
||||
for (var i = 0; i < strLength; ++i) {
|
||||
chars[i] = str.charAt(i);
|
||||
|
||||
var charCode = str.charCodeAt(i);
|
||||
var charType = 'L';
|
||||
if (charCode <= 0x00ff)
|
||||
charType = baseTypes[charCode];
|
||||
else if (0x0590 <= charCode && charCode <= 0x05f4)
|
||||
charType = 'R';
|
||||
else if (0x0600 <= charCode && charCode <= 0x06ff)
|
||||
charType = arabicTypes[charCode & 0xff];
|
||||
else if (0x0700 <= charCode && charCode <= 0x08AC)
|
||||
charType = 'AL';
|
||||
|
||||
if (charType == 'R' || charType == 'AL' || charType == 'AN')
|
||||
numBidi++;
|
||||
|
||||
oldtypes[i] = types[i] = charType;
|
||||
}
|
||||
|
||||
// detect the bidi method
|
||||
// if there are no rtl characters then no bidi needed
|
||||
// if less than 30% chars are rtl then string is primarily ltr
|
||||
// if more than 30% chars are rtl then string is primarily rtl
|
||||
if (numBidi == 0) {
|
||||
text.direction = 'ltr';
|
||||
return str;
|
||||
}
|
||||
|
||||
if (startLevel == -1) {
|
||||
if ((strLength / numBidi) < 0.3) {
|
||||
text.direction = 'ltr';
|
||||
startLevel = 0;
|
||||
} else {
|
||||
text.direction = 'rtl';
|
||||
startLevel = 1;
|
||||
}
|
||||
}
|
||||
|
||||
var levels = [];
|
||||
|
||||
for (var i = 0; i < strLength; ++i) {
|
||||
levels[i] = startLevel;
|
||||
}
|
||||
|
||||
/*
|
||||
X1-X10: skip most of this, since we are NOT doing the embeddings.
|
||||
*/
|
||||
|
||||
var e = isOdd(startLevel) ? 'R' : 'L';
|
||||
var sor = e;
|
||||
var eor = sor;
|
||||
|
||||
/*
|
||||
W1. Examine each non-spacing mark (NSM) in the level run, and change the
|
||||
type of the NSM to the type of the previous character. If the NSM is at the
|
||||
start of the level run, it will get the type of sor.
|
||||
*/
|
||||
|
||||
var lastType = sor;
|
||||
for (var i = 0; i < strLength; ++i) {
|
||||
if (types[i] == 'NSM')
|
||||
types[i] = lastType;
|
||||
else
|
||||
lastType = types[i];
|
||||
}
|
||||
|
||||
/*
|
||||
W2. Search backwards from each instance of a European number until the
|
||||
first strong type (R, L, AL, or sor) is found. If an AL is found, change
|
||||
the type of the European number to Arabic number.
|
||||
*/
|
||||
|
||||
var lastType = sor;
|
||||
for (var i = 0; i < strLength; ++i) {
|
||||
var t = types[i];
|
||||
if (t == 'EN')
|
||||
types[i] = (lastType == 'AL') ? 'AN' : 'EN';
|
||||
else if (t == 'R' || t == 'L' || t == 'AL')
|
||||
lastType = t;
|
||||
}
|
||||
|
||||
/*
|
||||
W3. Change all ALs to R.
|
||||
*/
|
||||
|
||||
for (var i = 0; i < strLength; ++i) {
|
||||
var t = types[i];
|
||||
if (t == 'AL')
|
||||
types[i] = 'R';
|
||||
}
|
||||
|
||||
/*
|
||||
W4. A single European separator between two European numbers changes to a
|
||||
European number. A single common separator between two numbers of the same
|
||||
type changes to that type:
|
||||
*/
|
||||
|
||||
for (var i = 1; i < strLength - 1; ++i) {
|
||||
if (types[i] == 'ES' && types[i - 1] == 'EN' && types[i + 1] == 'EN')
|
||||
types[i] = 'EN';
|
||||
if (types[i] == 'CS' && (types[i - 1] == 'EN' || types[i - 1] == 'AN') &&
|
||||
types[i + 1] == types[i - 1])
|
||||
types[i] = types[i - 1];
|
||||
}
|
||||
|
||||
/*
|
||||
W5. A sequence of European terminators adjacent to European numbers changes
|
||||
to all European numbers:
|
||||
*/
|
||||
|
||||
for (var i = 0; i < strLength; ++i) {
|
||||
if (types[i] == 'EN') {
|
||||
// do before
|
||||
for (var j = i - 1; j >= 0; --j) {
|
||||
if (types[j] != 'ET')
|
||||
break;
|
||||
types[j] = 'EN';
|
||||
}
|
||||
// do after
|
||||
for (var j = i + 1; j < strLength; --j) {
|
||||
if (types[j] != 'ET')
|
||||
break;
|
||||
types[j] = 'EN';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
W6. Otherwise, separators and terminators change to Other Neutral:
|
||||
*/
|
||||
|
||||
for (var i = 0; i < strLength; ++i) {
|
||||
var t = types[i];
|
||||
if (t == 'WS' || t == 'ES' || t == 'ET' || t == 'CS')
|
||||
types[i] = 'ON';
|
||||
}
|
||||
|
||||
/*
|
||||
W7. Search backwards from each instance of a European number until the
|
||||
first strong type (R, L, or sor) is found. If an L is found, then change
|
||||
the type of the European number to L.
|
||||
*/
|
||||
|
||||
var lastType = sor;
|
||||
for (var i = 0; i < strLength; ++i) {
|
||||
var t = types[i];
|
||||
if (t == 'EN')
|
||||
types[i] = (lastType == 'L') ? 'L' : 'EN';
|
||||
else if (t == 'R' || t == 'L')
|
||||
lastType = t;
|
||||
}
|
||||
|
||||
/*
|
||||
N1. A sequence of neutrals takes the direction of the surrounding strong
|
||||
text if the text on both sides has the same direction. European and Arabic
|
||||
numbers are treated as though they were R. Start-of-level-run (sor) and
|
||||
end-of-level-run (eor) are used at level run boundaries.
|
||||
*/
|
||||
|
||||
for (var i = 0; i < strLength; ++i) {
|
||||
if (types[i] == 'ON') {
|
||||
var end = findUnequal(types, i + 1, 'ON');
|
||||
var before = sor;
|
||||
if (i > 0)
|
||||
before = types[i - 1];
|
||||
var after = eor;
|
||||
if (end + 1 < strLength)
|
||||
after = types[end + 1];
|
||||
if (before != 'L')
|
||||
before = 'R';
|
||||
if (after != 'L')
|
||||
after = 'R';
|
||||
if (before == after)
|
||||
setValues(types, i, end, before);
|
||||
i = end - 1; // reset to end (-1 so next iteration is ok)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
N2. Any remaining neutrals take the embedding direction.
|
||||
*/
|
||||
|
||||
for (var i = 0; i < strLength; ++i) {
|
||||
if (types[i] == 'ON')
|
||||
types[i] = e;
|
||||
}
|
||||
|
||||
/*
|
||||
I1. For all characters with an even (left-to-right) embedding direction,
|
||||
those of type R go up one level and those of type AN or EN go up two
|
||||
levels.
|
||||
I2. For all characters with an odd (right-to-left) embedding direction,
|
||||
those of type L, EN or AN go up one level.
|
||||
*/
|
||||
|
||||
for (var i = 0; i < strLength; ++i) {
|
||||
var t = types[i];
|
||||
if (isEven(levels[i])) {
|
||||
if (t == 'R') {
|
||||
levels[i] += 1;
|
||||
} else if (t == 'AN' || t == 'EN') {
|
||||
levels[i] += 2;
|
||||
}
|
||||
} else { // isOdd, so
|
||||
if (t == 'L' || t == 'AN' || t == 'EN') {
|
||||
levels[i] += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
L1. On each line, reset the embedding level of the following characters to
|
||||
the paragraph embedding level:
|
||||
|
||||
segment separators,
|
||||
paragraph separators,
|
||||
any sequence of whitespace characters preceding a segment separator or
|
||||
paragraph separator, and any sequence of white space characters at the end
|
||||
of the line.
|
||||
*/
|
||||
|
||||
// don't bother as text is only single line
|
||||
|
||||
/*
|
||||
L2. From the highest level found in the text to the lowest odd level on
|
||||
each line, reverse any contiguous sequence of characters that are at that
|
||||
level or higher.
|
||||
*/
|
||||
|
||||
// find highest level & lowest odd level
|
||||
|
||||
var highestLevel = -1;
|
||||
var lowestOddLevel = 99;
|
||||
for (var i = 0, ii = levels.length; i < ii; ++i) {
|
||||
var level = levels[i];
|
||||
if (highestLevel < level)
|
||||
highestLevel = level;
|
||||
if (lowestOddLevel > level && isOdd(level))
|
||||
lowestOddLevel = level;
|
||||
}
|
||||
|
||||
// now reverse between those limits
|
||||
|
||||
for (var level = highestLevel; level >= lowestOddLevel; --level) {
|
||||
// find segments to reverse
|
||||
var start = -1;
|
||||
for (var i = 0, ii = levels.length; i < ii; ++i) {
|
||||
if (levels[i] < level) {
|
||||
if (start >= 0) {
|
||||
reverseValues(chars, start, i);
|
||||
start = -1;
|
||||
}
|
||||
} else if (start < 0) {
|
||||
start = i;
|
||||
}
|
||||
}
|
||||
if (start >= 0) {
|
||||
reverseValues(chars, start, levels.length);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
L3. Combining marks applied to a right-to-left base character will at this
|
||||
point precede their base character. If the rendering engine expects them to
|
||||
follow the base characters in the final display process, then the ordering
|
||||
of the marks and the base character must be reversed.
|
||||
*/
|
||||
|
||||
// don't bother for now
|
||||
|
||||
/*
|
||||
L4. A character that possesses the mirrored property as specified by
|
||||
Section 4.7, Mirrored, must be depicted by a mirrored glyph if the resolved
|
||||
directionality of that character is R.
|
||||
*/
|
||||
|
||||
// don't mirror as characters are already mirrored in the pdf
|
||||
|
||||
// Finally, return string
|
||||
|
||||
var result = '';
|
||||
for (var i = 0, ii = chars.length; i < ii; ++i) {
|
||||
var ch = chars[i];
|
||||
if (ch != '<' && ch != '>')
|
||||
result += ch;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return bidi;
|
||||
})();
|
||||
|
784
apps/files_pdfviewer/js/pdfjs/src/canvas.js
Executable file → Normal file
0
apps/files_pdfviewer/js/pdfjs/src/charsets.js
Executable file → Normal file
0
apps/files_pdfviewer/js/pdfjs/src/cidmaps.js
Executable file → Normal file
311
apps/files_pdfviewer/js/pdfjs/src/colorspace.js
Executable file → Normal file
|
@ -3,34 +3,34 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var ColorSpace = (function colorSpaceColorSpace() {
|
||||
var ColorSpace = (function ColorSpaceClosure() {
|
||||
// Constructor should define this.numComps, this.defaultColor, this.name
|
||||
function constructor() {
|
||||
function ColorSpace() {
|
||||
error('should not call ColorSpace constructor');
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
ColorSpace.prototype = {
|
||||
// Input: array of size numComps representing color component values
|
||||
// Output: array of rgb values, each value ranging from [0.1]
|
||||
getRgb: function colorSpaceGetRgb(color) {
|
||||
getRgb: function ColorSpace_getRgb(color) {
|
||||
error('Should not call ColorSpace.getRgb: ' + color);
|
||||
},
|
||||
// Input: Uint8Array of component values, each value scaled to [0,255]
|
||||
// Output: Uint8Array of rgb values, each value scaled to [0,255]
|
||||
getRgbBuffer: function colorSpaceGetRgbBuffer(input) {
|
||||
getRgbBuffer: function ColorSpace_getRgbBuffer(input) {
|
||||
error('Should not call ColorSpace.getRgbBuffer: ' + input);
|
||||
}
|
||||
};
|
||||
|
||||
constructor.parse = function colorSpaceParse(cs, xref, res) {
|
||||
var IR = constructor.parseToIR(cs, xref, res);
|
||||
ColorSpace.parse = function ColorSpace_parse(cs, xref, res) {
|
||||
var IR = ColorSpace.parseToIR(cs, xref, res);
|
||||
if (IR instanceof AlternateCS)
|
||||
return IR;
|
||||
|
||||
return constructor.fromIR(IR);
|
||||
return ColorSpace.fromIR(IR);
|
||||
};
|
||||
|
||||
constructor.fromIR = function colorSpaceFromIR(IR) {
|
||||
ColorSpace.fromIR = function ColorSpace_fromIR(IR) {
|
||||
var name = isArray(IR) ? IR[0] : IR;
|
||||
|
||||
switch (name) {
|
||||
|
@ -57,15 +57,20 @@ var ColorSpace = (function colorSpaceColorSpace() {
|
|||
|
||||
return new AlternateCS(numComps, ColorSpace.fromIR(alt),
|
||||
PDFFunction.fromIR(tintFnIR));
|
||||
case 'LabCS':
|
||||
var whitePoint = IR[1].WhitePoint;
|
||||
var blackPoint = IR[1].BlackPoint;
|
||||
var range = IR[1].Range;
|
||||
return new LabCS(whitePoint, blackPoint, range);
|
||||
default:
|
||||
error('Unkown name ' + name);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
constructor.parseToIR = function colorSpaceParseToIR(cs, xref, res) {
|
||||
ColorSpace.parseToIR = function ColorSpace_parseToIR(cs, xref, res) {
|
||||
if (isName(cs)) {
|
||||
var colorSpaces = xref.fetchIfRef(res.get('ColorSpace'));
|
||||
var colorSpaces = res.get('ColorSpace');
|
||||
if (isDict(colorSpaces)) {
|
||||
var refcs = colorSpaces.get(cs.name);
|
||||
if (refcs)
|
||||
|
@ -130,6 +135,7 @@ var ColorSpace = (function colorSpaceColorSpace() {
|
|||
basePatternCS = ColorSpace.parseToIR(basePatternCS, xref, res);
|
||||
return ['PatternCS', basePatternCS];
|
||||
case 'Indexed':
|
||||
case 'I':
|
||||
var baseIndexedCS = ColorSpace.parseToIR(cs[1], xref, res);
|
||||
var hiVal = cs[2] + 1;
|
||||
var lookup = xref.fetchIfRef(cs[3]);
|
||||
|
@ -146,6 +152,8 @@ var ColorSpace = (function colorSpaceColorSpace() {
|
|||
var tintFnIR = PDFFunction.getIR(xref, xref.fetchIfRef(cs[3]));
|
||||
return ['AlternateCS', numComps, alt, tintFnIR];
|
||||
case 'Lab':
|
||||
var params = cs[1].getAll();
|
||||
return ['LabCS', params];
|
||||
default:
|
||||
error('unimplemented color space object "' + mode + '"');
|
||||
}
|
||||
|
@ -154,8 +162,31 @@ var ColorSpace = (function colorSpaceColorSpace() {
|
|||
}
|
||||
return null;
|
||||
};
|
||||
/**
|
||||
* Checks if a decode map matches the default decode map for a color space.
|
||||
* This handles the general decode maps where there are two values per
|
||||
* component. e.g. [0, 1, 0, 1, 0, 1] for a RGB color.
|
||||
* This does not handle Lab, Indexed, or Pattern decode maps since they are
|
||||
* slightly different.
|
||||
* @param {Array} decode Decode map (usually from an image).
|
||||
* @param {Number} n Number of components the color space has.
|
||||
*/
|
||||
ColorSpace.isDefaultDecode = function ColorSpace_isDefaultDecode(decode, n) {
|
||||
if (!decode)
|
||||
return true;
|
||||
|
||||
return constructor;
|
||||
if (n * 2 !== decode.length) {
|
||||
warning('The decode map is not the correct length');
|
||||
return true;
|
||||
}
|
||||
for (var i = 0, ii = decode.length; i < ii; i += 2) {
|
||||
if (decode[i] != 0 || decode[i + 1] != 1)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
return ColorSpace;
|
||||
})();
|
||||
|
||||
/**
|
||||
|
@ -164,8 +195,8 @@ var ColorSpace = (function colorSpaceColorSpace() {
|
|||
* Both color spaces use a tinting function to convert colors to a base color
|
||||
* space.
|
||||
*/
|
||||
var AlternateCS = (function alternateCS() {
|
||||
function constructor(numComps, base, tintFn) {
|
||||
var AlternateCS = (function AlternateCSClosure() {
|
||||
function AlternateCS(numComps, base, tintFn) {
|
||||
this.name = 'Alternate';
|
||||
this.numComps = numComps;
|
||||
this.defaultColor = [];
|
||||
|
@ -175,12 +206,12 @@ var AlternateCS = (function alternateCS() {
|
|||
this.tintFn = tintFn;
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
getRgb: function altcs_getRgb(color) {
|
||||
AlternateCS.prototype = {
|
||||
getRgb: function AlternateCS_getRgb(color) {
|
||||
var tinted = this.tintFn(color);
|
||||
return this.base.getRgb(tinted);
|
||||
},
|
||||
getRgbBuffer: function altcs_getRgbBuffer(input, bits) {
|
||||
getRgbBuffer: function AlternateCS_getRgbBuffer(input, bits) {
|
||||
var tintFn = this.tintFn;
|
||||
var base = this.base;
|
||||
var scale = 1 / ((1 << bits) - 1);
|
||||
|
@ -189,7 +220,7 @@ var AlternateCS = (function alternateCS() {
|
|||
var baseNumComps = base.numComps;
|
||||
var baseBuf = new Uint8Array(baseNumComps * length);
|
||||
var numComps = this.numComps;
|
||||
var scaled = new Array(numComps);
|
||||
var scaled = [];
|
||||
|
||||
for (var i = 0; i < length; i += numComps) {
|
||||
for (var z = 0; z < numComps; ++z)
|
||||
|
@ -200,24 +231,27 @@ var AlternateCS = (function alternateCS() {
|
|||
baseBuf[pos++] = 255 * tinted[j];
|
||||
}
|
||||
return base.getRgbBuffer(baseBuf, 8);
|
||||
},
|
||||
isDefaultDecode: function AlternateCS_isDefaultDecode(decodeMap) {
|
||||
return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
|
||||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return AlternateCS;
|
||||
})();
|
||||
|
||||
var PatternCS = (function patternCS() {
|
||||
function constructor(baseCS) {
|
||||
var PatternCS = (function PatternCSClosure() {
|
||||
function PatternCS(baseCS) {
|
||||
this.name = 'Pattern';
|
||||
this.base = baseCS;
|
||||
}
|
||||
constructor.prototype = {};
|
||||
PatternCS.prototype = {};
|
||||
|
||||
return constructor;
|
||||
return PatternCS;
|
||||
})();
|
||||
|
||||
var IndexedCS = (function indexedCS() {
|
||||
function constructor(base, highVal, lookup) {
|
||||
var IndexedCS = (function IndexedCSClosure() {
|
||||
function IndexedCS(base, highVal, lookup) {
|
||||
this.name = 'Indexed';
|
||||
this.numComps = 1;
|
||||
this.defaultColor = [0];
|
||||
|
@ -240,8 +274,8 @@ var IndexedCS = (function indexedCS() {
|
|||
this.lookup = lookupArray;
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
getRgb: function indexcs_getRgb(color) {
|
||||
IndexedCS.prototype = {
|
||||
getRgb: function IndexedCS_getRgb(color) {
|
||||
var numComps = this.base.numComps;
|
||||
var start = color[0] * numComps;
|
||||
var c = [];
|
||||
|
@ -251,7 +285,7 @@ var IndexedCS = (function indexedCS() {
|
|||
|
||||
return this.base.getRgb(c);
|
||||
},
|
||||
getRgbBuffer: function indexcs_getRgbBuffer(input) {
|
||||
getRgbBuffer: function IndexedCS_getRgbBuffer(input) {
|
||||
var base = this.base;
|
||||
var numComps = base.numComps;
|
||||
var lookup = this.lookup;
|
||||
|
@ -267,24 +301,28 @@ var IndexedCS = (function indexedCS() {
|
|||
}
|
||||
|
||||
return base.getRgbBuffer(baseBuf, 8);
|
||||
},
|
||||
isDefaultDecode: function IndexedCS_isDefaultDecode(decodeMap) {
|
||||
// indexed color maps shouldn't be changed
|
||||
return true;
|
||||
}
|
||||
};
|
||||
return constructor;
|
||||
return IndexedCS;
|
||||
})();
|
||||
|
||||
var DeviceGrayCS = (function deviceGrayCS() {
|
||||
function constructor() {
|
||||
var DeviceGrayCS = (function DeviceGrayCSClosure() {
|
||||
function DeviceGrayCS() {
|
||||
this.name = 'DeviceGray';
|
||||
this.numComps = 1;
|
||||
this.defaultColor = [0];
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
getRgb: function graycs_getRgb(color) {
|
||||
DeviceGrayCS.prototype = {
|
||||
getRgb: function DeviceGrayCS_getRgb(color) {
|
||||
var c = color[0];
|
||||
return [c, c, c];
|
||||
},
|
||||
getRgbBuffer: function graycs_getRgbBuffer(input, bits) {
|
||||
getRgbBuffer: function DeviceGrayCS_getRgbBuffer(input, bits) {
|
||||
var scale = 255 / ((1 << bits) - 1);
|
||||
var length = input.length;
|
||||
var rgbBuf = new Uint8Array(length * 3);
|
||||
|
@ -295,22 +333,25 @@ var DeviceGrayCS = (function deviceGrayCS() {
|
|||
rgbBuf[j++] = c;
|
||||
}
|
||||
return rgbBuf;
|
||||
},
|
||||
isDefaultDecode: function DeviceGrayCS_isDefaultDecode(decodeMap) {
|
||||
return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
|
||||
}
|
||||
};
|
||||
return constructor;
|
||||
return DeviceGrayCS;
|
||||
})();
|
||||
|
||||
var DeviceRgbCS = (function deviceRgbCS() {
|
||||
function constructor() {
|
||||
var DeviceRgbCS = (function DeviceRgbCSClosure() {
|
||||
function DeviceRgbCS() {
|
||||
this.name = 'DeviceRGB';
|
||||
this.numComps = 3;
|
||||
this.defaultColor = [0, 0, 0];
|
||||
}
|
||||
constructor.prototype = {
|
||||
getRgb: function rgbcs_getRgb(color) {
|
||||
DeviceRgbCS.prototype = {
|
||||
getRgb: function DeviceRgbCS_getRgb(color) {
|
||||
return color;
|
||||
},
|
||||
getRgbBuffer: function rgbcs_getRgbBuffer(input, bits) {
|
||||
getRgbBuffer: function DeviceRgbCS_getRgbBuffer(input, bits) {
|
||||
if (bits == 8)
|
||||
return input;
|
||||
var scale = 255 / ((1 << bits) - 1);
|
||||
|
@ -319,73 +360,37 @@ var DeviceRgbCS = (function deviceRgbCS() {
|
|||
for (i = 0; i < length; ++i)
|
||||
rgbBuf[i] = (scale * input[i]) | 0;
|
||||
return rgbBuf;
|
||||
},
|
||||
isDefaultDecode: function DeviceRgbCS_isDefaultDecode(decodeMap) {
|
||||
return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
|
||||
}
|
||||
};
|
||||
return constructor;
|
||||
return DeviceRgbCS;
|
||||
})();
|
||||
|
||||
var DeviceCmykCS = (function deviceCmykCS() {
|
||||
function constructor() {
|
||||
var DeviceCmykCS = (function DeviceCmykCSClosure() {
|
||||
function DeviceCmykCS() {
|
||||
this.name = 'DeviceCMYK';
|
||||
this.numComps = 4;
|
||||
this.defaultColor = [0, 0, 0, 1];
|
||||
}
|
||||
constructor.prototype = {
|
||||
getRgb: function cmykcs_getRgb(color) {
|
||||
DeviceCmykCS.prototype = {
|
||||
getRgb: function DeviceCmykCS_getRgb(color) {
|
||||
var c = color[0], m = color[1], y = color[2], k = color[3];
|
||||
var c1 = 1 - c, m1 = 1 - m, y1 = 1 - y, k1 = 1 - k;
|
||||
|
||||
var x, r, g, b;
|
||||
// this is a matrix multiplication, unrolled for performance
|
||||
// code is taken from the poppler implementation
|
||||
x = c1 * m1 * y1 * k1; // 0 0 0 0
|
||||
r = g = b = x;
|
||||
x = c1 * m1 * y1 * k; // 0 0 0 1
|
||||
r += 0.1373 * x;
|
||||
g += 0.1216 * x;
|
||||
b += 0.1255 * x;
|
||||
x = c1 * m1 * y * k1; // 0 0 1 0
|
||||
r += x;
|
||||
g += 0.9490 * x;
|
||||
x = c1 * m1 * y * k; // 0 0 1 1
|
||||
r += 0.1098 * x;
|
||||
g += 0.1020 * x;
|
||||
x = c1 * m * y1 * k1; // 0 1 0 0
|
||||
r += 0.9255 * x;
|
||||
b += 0.5490 * x;
|
||||
x = c1 * m * y1 * k; // 0 1 0 1
|
||||
r += 0.1412 * x;
|
||||
x = c1 * m * y * k1; // 0 1 1 0
|
||||
r += 0.9294 * x;
|
||||
g += 0.1098 * x;
|
||||
b += 0.1412 * x;
|
||||
x = c1 * m * y * k; // 0 1 1 1
|
||||
r += 0.1333 * x;
|
||||
x = c * m1 * y1 * k1; // 1 0 0 0
|
||||
g += 0.6784 * x;
|
||||
b += 0.9373 * x;
|
||||
x = c * m1 * y1 * k; // 1 0 0 1
|
||||
g += 0.0588 * x;
|
||||
b += 0.1412 * x;
|
||||
x = c * m1 * y * k1; // 1 0 1 0
|
||||
g += 0.6510 * x;
|
||||
b += 0.3137 * x;
|
||||
x = c * m1 * y * k; // 1 0 1 1
|
||||
g += 0.0745 * x;
|
||||
x = c * m * y1 * k1; // 1 1 0 0
|
||||
r += 0.1804 * x;
|
||||
g += 0.1922 * x;
|
||||
b += 0.5725 * x;
|
||||
x = c * m * y1 * k; // 1 1 0 1
|
||||
b += 0.0078 * x;
|
||||
x = c * m * y * k1; // 1 1 1 0
|
||||
r += 0.2118 * x;
|
||||
g += 0.2119 * x;
|
||||
b += 0.2235 * x;
|
||||
// CMYK -> CMY: http://www.easyrgb.com/index.php?X=MATH&H=14#text14
|
||||
c = (c * (1 - k) + k);
|
||||
m = (m * (1 - k) + k);
|
||||
y = (y * (1 - k) + k);
|
||||
|
||||
// CMY -> RGB: http://www.easyrgb.com/index.php?X=MATH&H=12#text12
|
||||
var r = (1 - c);
|
||||
var g = (1 - m);
|
||||
var b = (1 - y);
|
||||
|
||||
return [r, g, b];
|
||||
},
|
||||
getRgbBuffer: function cmykcs_getRgbBuffer(colorBuf, bits) {
|
||||
getRgbBuffer: function DeviceCmykCS_getRgbBuffer(colorBuf, bits) {
|
||||
var scale = 1 / ((1 << bits) - 1);
|
||||
var length = colorBuf.length / 4;
|
||||
var rgbBuf = new Uint8Array(length * 3);
|
||||
|
@ -403,9 +408,125 @@ var DeviceCmykCS = (function deviceCmykCS() {
|
|||
}
|
||||
|
||||
return rgbBuf;
|
||||
},
|
||||
isDefaultDecode: function DeviceCmykCS_isDefaultDecode(decodeMap) {
|
||||
return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
|
||||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return DeviceCmykCS;
|
||||
})();
|
||||
|
||||
//
|
||||
// LabCS: Based on "PDF Reference, Sixth Ed", p.250
|
||||
//
|
||||
var LabCS = (function LabCSClosure() {
|
||||
function LabCS(whitePoint, blackPoint, range) {
|
||||
this.name = 'Lab';
|
||||
this.numComps = 3;
|
||||
this.defaultColor = [0, 0, 0];
|
||||
|
||||
if (!whitePoint)
|
||||
error('WhitePoint missing - required for color space Lab');
|
||||
blackPoint = blackPoint || [0, 0, 0];
|
||||
range = range || [-100, 100, -100, 100];
|
||||
|
||||
// Translate args to spec variables
|
||||
this.XW = whitePoint[0];
|
||||
this.YW = whitePoint[1];
|
||||
this.ZW = whitePoint[2];
|
||||
this.amin = range[0];
|
||||
this.amax = range[1];
|
||||
this.bmin = range[2];
|
||||
this.bmax = range[3];
|
||||
|
||||
// These are here just for completeness - the spec doesn't offer any
|
||||
// formulas that use BlackPoint in Lab
|
||||
this.XB = blackPoint[0];
|
||||
this.YB = blackPoint[1];
|
||||
this.ZB = blackPoint[2];
|
||||
|
||||
// Validate vars as per spec
|
||||
if (this.XW < 0 || this.ZW < 0 || this.YW !== 1)
|
||||
error('Invalid WhitePoint components, no fallback available');
|
||||
|
||||
if (this.XB < 0 || this.YB < 0 || this.ZB < 0) {
|
||||
warn('Invalid BlackPoint, falling back to default');
|
||||
this.XB = this.YB = this.ZB = 0;
|
||||
}
|
||||
|
||||
if (this.amin > this.amax || this.bmin > this.bmax) {
|
||||
warn('Invalid Range, falling back to defaults');
|
||||
this.amin = -100;
|
||||
this.amax = 100;
|
||||
this.bmin = -100;
|
||||
this.bmax = 100;
|
||||
}
|
||||
};
|
||||
|
||||
// Function g(x) from spec
|
||||
function g(x) {
|
||||
if (x >= 6 / 29)
|
||||
return x * x * x;
|
||||
else
|
||||
return (108 / 841) * (x - 4 / 29);
|
||||
}
|
||||
|
||||
LabCS.prototype = {
|
||||
getRgb: function LabCS_getRgb(color) {
|
||||
// Ls,as,bs <---> L*,a*,b* in the spec
|
||||
var Ls = color[0], as = color[1], bs = color[2];
|
||||
|
||||
// Adjust limits of 'as' and 'bs'
|
||||
as = as > this.amax ? this.amax : as;
|
||||
as = as < this.amin ? this.amin : as;
|
||||
bs = bs > this.bmax ? this.bmax : bs;
|
||||
bs = bs < this.bmin ? this.bmin : bs;
|
||||
|
||||
// Computes intermediate variables X,Y,Z as per spec
|
||||
var M = (Ls + 16) / 116;
|
||||
var L = M + (as / 500);
|
||||
var N = M - (bs / 200);
|
||||
var X = this.XW * g(L);
|
||||
var Y = this.YW * g(M);
|
||||
var Z = this.ZW * g(N);
|
||||
|
||||
// XYZ to RGB 3x3 matrix, from:
|
||||
// http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC18
|
||||
var XYZtoRGB = [3.240479, -1.537150, -0.498535,
|
||||
-0.969256, 1.875992, 0.041556,
|
||||
0.055648, -0.204043, 1.057311];
|
||||
|
||||
return Util.apply3dTransform(XYZtoRGB, [X, Y, Z]);
|
||||
},
|
||||
getRgbBuffer: function LabCS_getRgbBuffer(input, bits) {
|
||||
if (bits == 8)
|
||||
return input;
|
||||
var scale = 255 / ((1 << bits) - 1);
|
||||
var i, length = input.length / 3;
|
||||
var rgbBuf = new Uint8Array(length);
|
||||
|
||||
var j = 0;
|
||||
for (i = 0; i < length; ++i) {
|
||||
// Convert L*, a*, s* into RGB
|
||||
var rgb = this.getRgb([input[i], input[i + 1], input[i + 2]]);
|
||||
rgbBuf[j++] = rgb[0];
|
||||
rgbBuf[j++] = rgb[1];
|
||||
rgbBuf[j++] = rgb[2];
|
||||
}
|
||||
|
||||
return rgbBuf;
|
||||
},
|
||||
isDefaultDecode: function LabCS_isDefaultDecode(decodeMap) {
|
||||
// From Table 90 in Adobe's:
|
||||
// "Document management - Portable document format", 1st ed, 2008
|
||||
if (decodeMap[0] === 0 && decodeMap[1] === 100 &&
|
||||
decodeMap[2] === this.amin && decodeMap[3] === this.amax &&
|
||||
decodeMap[4] === this.bmin && decodeMap[5] === this.bmax)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
};
|
||||
return LabCS;
|
||||
})();
|
||||
|
|
616
apps/files_pdfviewer/js/pdfjs/src/core.js
Executable file → Normal file
|
@ -5,6 +5,8 @@
|
|||
|
||||
var globalScope = (typeof window === 'undefined') ? this : window;
|
||||
|
||||
var isWorker = (typeof window == 'undefined');
|
||||
|
||||
var ERRORS = 0, WARNINGS = 1, TODOS = 5;
|
||||
var verbosity = WARNINGS;
|
||||
|
||||
|
@ -31,7 +33,9 @@ function getPdf(arg, callback) {
|
|||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', params.url);
|
||||
xhr.mozResponseType = xhr.responseType = 'arraybuffer';
|
||||
xhr.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200;
|
||||
var protocol = params.url.indexOf(':') < 0 ? window.location.protocol :
|
||||
params.url.substring(0, params.url.indexOf(':') + 1);
|
||||
xhr.expected = (protocol === 'http:' || protocol === 'https:') ? 200 : 0;
|
||||
|
||||
if ('progress' in params)
|
||||
xhr.onprogress = params.progress || undefined;
|
||||
|
@ -39,41 +43,43 @@ function getPdf(arg, callback) {
|
|||
if ('error' in params)
|
||||
xhr.onerror = params.error || undefined;
|
||||
|
||||
xhr.onreadystatechange = function getPdfOnreadystatechange() {
|
||||
if (xhr.readyState === 4 && xhr.status === xhr.expected) {
|
||||
var data = (xhr.mozResponseArrayBuffer || xhr.mozResponse ||
|
||||
xhr.responseArrayBuffer || xhr.response);
|
||||
callback(data);
|
||||
xhr.onreadystatechange = function getPdfOnreadystatechange(e) {
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status === xhr.expected) {
|
||||
var data = (xhr.mozResponseArrayBuffer || xhr.mozResponse ||
|
||||
xhr.responseArrayBuffer || xhr.response);
|
||||
callback(data);
|
||||
} else if (params.error) {
|
||||
params.error(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.send(null);
|
||||
}
|
||||
globalScope.PDFJS.getPdf = getPdf;
|
||||
globalScope.PDFJS.pdfBug = false;
|
||||
|
||||
var Page = (function pagePage() {
|
||||
function constructor(xref, pageNumber, pageDict, ref) {
|
||||
var Page = (function PageClosure() {
|
||||
function Page(xref, pageNumber, pageDict, ref) {
|
||||
this.pageNumber = pageNumber;
|
||||
this.pageDict = pageDict;
|
||||
this.stats = {
|
||||
create: Date.now(),
|
||||
compile: 0.0,
|
||||
fonts: 0.0,
|
||||
images: 0.0,
|
||||
render: 0.0
|
||||
};
|
||||
this.stats = new StatTimer();
|
||||
this.stats.enabled = !!globalScope.PDFJS.enableStats;
|
||||
this.xref = xref;
|
||||
this.ref = ref;
|
||||
|
||||
this.displayReadyPromise = null;
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
getPageProp: function pageGetPageProp(key) {
|
||||
return this.xref.fetchIfRef(this.pageDict.get(key));
|
||||
Page.prototype = {
|
||||
getPageProp: function Page_getPageProp(key) {
|
||||
return this.pageDict.get(key);
|
||||
},
|
||||
inheritPageProp: function pageInheritPageProp(key) {
|
||||
inheritPageProp: function Page_inheritPageProp(key) {
|
||||
var dict = this.pageDict;
|
||||
var obj = dict.get(key);
|
||||
while (obj === undefined) {
|
||||
dict = this.xref.fetchIfRef(dict.get('Parent'));
|
||||
dict = dict.get('Parent');
|
||||
if (!dict)
|
||||
break;
|
||||
obj = dict.get(key);
|
||||
|
@ -94,23 +100,35 @@ var Page = (function pagePage() {
|
|||
return shadow(this, 'mediaBox', obj);
|
||||
},
|
||||
get view() {
|
||||
var obj = this.inheritPageProp('CropBox');
|
||||
var cropBox = this.inheritPageProp('CropBox');
|
||||
var view = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: this.width,
|
||||
height: this.height
|
||||
};
|
||||
if (isArray(obj) && obj.length == 4) {
|
||||
var tl = this.rotatePoint(obj[0], obj[1]);
|
||||
var br = this.rotatePoint(obj[2], obj[3]);
|
||||
view.x = Math.min(tl.x, br.x);
|
||||
view.y = Math.min(tl.y, br.y);
|
||||
view.width = Math.abs(tl.x - br.x);
|
||||
view.height = Math.abs(tl.y - br.y);
|
||||
}
|
||||
if (!isArray(cropBox) || cropBox.length !== 4)
|
||||
return shadow(this, 'view', view);
|
||||
|
||||
return shadow(this, 'cropBox', view);
|
||||
var mediaBox = this.mediaBox;
|
||||
var offsetX = mediaBox[0], offsetY = mediaBox[1];
|
||||
|
||||
// From the spec, 6th ed., p.963:
|
||||
// "The crop, bleed, trim, and art boxes should not ordinarily
|
||||
// extend beyond the boundaries of the media box. If they do, they are
|
||||
// effectively reduced to their intersection with the media box."
|
||||
cropBox = Util.intersect(cropBox, mediaBox);
|
||||
if (!cropBox)
|
||||
return shadow(this, 'view', view);
|
||||
|
||||
var tl = this.rotatePoint(cropBox[0] - offsetX, cropBox[1] - offsetY);
|
||||
var br = this.rotatePoint(cropBox[2] - offsetX, cropBox[3] - offsetY);
|
||||
view.x = Math.min(tl.x, br.x);
|
||||
view.y = Math.min(tl.y, br.y);
|
||||
view.width = Math.abs(tl.x - br.x);
|
||||
view.height = Math.abs(tl.y - br.y);
|
||||
|
||||
return shadow(this, 'view', view);
|
||||
},
|
||||
get annotations() {
|
||||
return shadow(this, 'annotations', this.inheritPageProp('Annots'));
|
||||
|
@ -152,77 +170,80 @@ var Page = (function pagePage() {
|
|||
return shadow(this, 'rotate', rotate);
|
||||
},
|
||||
|
||||
startRenderingFromIRQueue: function pageStartRenderingFromIRQueue(
|
||||
IRQueue, fonts) {
|
||||
startRenderingFromOperatorList:
|
||||
function Page_startRenderingFromOperatorList(operatorList, fonts) {
|
||||
var self = this;
|
||||
this.IRQueue = IRQueue;
|
||||
var gfx = new CanvasGraphics(this.ctx, this.objs);
|
||||
this.operatorList = operatorList;
|
||||
|
||||
var displayContinuation = function pageDisplayContinuation() {
|
||||
// Always defer call to display() to work around bug in
|
||||
// Firefox error reporting from XHR callbacks.
|
||||
setTimeout(function pageSetTimeout() {
|
||||
try {
|
||||
self.display(gfx, self.callback);
|
||||
} catch (e) {
|
||||
if (self.callback) self.callback(e.toString());
|
||||
throw e;
|
||||
}
|
||||
self.displayReadyPromise.resolve();
|
||||
});
|
||||
};
|
||||
|
||||
this.ensureFonts(fonts,
|
||||
function pageStartRenderingFromIRQueueEnsureFonts() {
|
||||
displayContinuation();
|
||||
});
|
||||
function pageStartRenderingFromOperatorListEnsureFonts() {
|
||||
displayContinuation();
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
getIRQueue: function pageGetIRQueue(handler, dependency) {
|
||||
if (this.IRQueue) {
|
||||
getOperatorList: function Page_getOperatorList(handler, dependency) {
|
||||
if (this.operatorList) {
|
||||
// content was compiled
|
||||
return this.IRQueue;
|
||||
return this.operatorList;
|
||||
}
|
||||
|
||||
this.stats.time('Build IR Queue');
|
||||
|
||||
var xref = this.xref;
|
||||
var content = xref.fetchIfRef(this.content);
|
||||
var resources = xref.fetchIfRef(this.resources);
|
||||
var content = this.content;
|
||||
var resources = this.resources;
|
||||
if (isArray(content)) {
|
||||
// fetching items
|
||||
var i, n = content.length;
|
||||
for (i = 0; i < n; ++i)
|
||||
content[i] = xref.fetchIfRef(content[i]);
|
||||
content = new StreamsSequenceStream(content);
|
||||
} else if (!content) {
|
||||
// replacing non-existent page content with empty one
|
||||
content = new Stream(new Uint8Array(0));
|
||||
}
|
||||
|
||||
var pe = this.pe = new PartialEvaluator(
|
||||
xref, handler, 'p' + this.pageNumber + '_');
|
||||
var IRQueue = {};
|
||||
return (this.IRQueue = pe.getIRQueue(content, resources, IRQueue,
|
||||
dependency));
|
||||
|
||||
this.operatorList = pe.getOperatorList(content, resources, dependency);
|
||||
this.stats.timeEnd('Build IR Queue');
|
||||
return this.operatorList;
|
||||
},
|
||||
|
||||
ensureFonts: function pageEnsureFonts(fonts, callback) {
|
||||
ensureFonts: function Page_ensureFonts(fonts, callback) {
|
||||
this.stats.time('Font Loading');
|
||||
// Convert the font names to the corresponding font obj.
|
||||
for (var i = 0, ii = fonts.length; i < ii; i++) {
|
||||
fonts[i] = this.objs.objs[fonts[i]].data;
|
||||
}
|
||||
|
||||
// Load all the fonts
|
||||
var fontObjs = FontLoader.bind(
|
||||
FontLoader.bind(
|
||||
fonts,
|
||||
function pageEnsureFontsFontObjs(fontObjs) {
|
||||
this.stats.fonts = Date.now();
|
||||
this.stats.timeEnd('Font Loading');
|
||||
|
||||
callback.call(this);
|
||||
}.bind(this),
|
||||
this.objs
|
||||
}.bind(this)
|
||||
);
|
||||
},
|
||||
|
||||
display: function pageDisplay(gfx, callback) {
|
||||
display: function Page_display(gfx, callback) {
|
||||
var stats = this.stats;
|
||||
stats.time('Rendering');
|
||||
var xref = this.xref;
|
||||
var resources = xref.fetchIfRef(this.resources);
|
||||
var mediaBox = xref.fetchIfRef(this.mediaBox);
|
||||
var resources = this.resources;
|
||||
var mediaBox = this.mediaBox;
|
||||
assertWellFormed(isDict(resources), 'invalid page resources');
|
||||
|
||||
gfx.xref = xref;
|
||||
|
@ -233,20 +254,29 @@ var Page = (function pagePage() {
|
|||
rotate: this.rotate });
|
||||
|
||||
var startIdx = 0;
|
||||
var length = this.IRQueue.fnArray.length;
|
||||
var IRQueue = this.IRQueue;
|
||||
var length = this.operatorList.fnArray.length;
|
||||
var operatorList = this.operatorList;
|
||||
var stepper = null;
|
||||
if (PDFJS.pdfBug && StepperManager.enabled) {
|
||||
stepper = StepperManager.create(this.pageNumber);
|
||||
stepper.init(operatorList);
|
||||
stepper.nextBreakPoint = stepper.getNextBreakPoint();
|
||||
}
|
||||
|
||||
var self = this;
|
||||
function next() {
|
||||
startIdx = gfx.executeIRQueue(IRQueue, startIdx, next);
|
||||
startIdx =
|
||||
gfx.executeOperatorList(operatorList, startIdx, next, stepper);
|
||||
if (startIdx == length) {
|
||||
self.stats.render = Date.now();
|
||||
gfx.endDrawing();
|
||||
stats.timeEnd('Rendering');
|
||||
stats.timeEnd('Overall');
|
||||
if (callback) callback();
|
||||
}
|
||||
}
|
||||
next();
|
||||
},
|
||||
rotatePoint: function pageRotatePoint(x, y, reverse) {
|
||||
rotatePoint: function Page_rotatePoint(x, y, reverse) {
|
||||
var rotate = reverse ? (360 - this.rotate) : this.rotate;
|
||||
switch (rotate) {
|
||||
case 180:
|
||||
|
@ -261,58 +291,183 @@ var Page = (function pagePage() {
|
|||
return {x: x, y: this.height - y};
|
||||
}
|
||||
},
|
||||
getLinks: function pageGetLinks() {
|
||||
var xref = this.xref;
|
||||
var annotations = xref.fetchIfRef(this.annotations) || [];
|
||||
var i, n = annotations.length;
|
||||
getLinks: function Page_getLinks() {
|
||||
var links = [];
|
||||
var annotations = pageGetAnnotations();
|
||||
var i, n = annotations.length;
|
||||
for (i = 0; i < n; ++i) {
|
||||
var annotation = xref.fetch(annotations[i]);
|
||||
if (annotations[i].type != 'Link')
|
||||
continue;
|
||||
links.push(annotations[i]);
|
||||
}
|
||||
return links;
|
||||
},
|
||||
getAnnotations: function Page_getAnnotations() {
|
||||
var xref = this.xref;
|
||||
function getInheritableProperty(annotation, name) {
|
||||
var item = annotation;
|
||||
while (item && !item.has(name)) {
|
||||
item = item.get('Parent');
|
||||
}
|
||||
if (!item)
|
||||
return null;
|
||||
return item.get(name);
|
||||
}
|
||||
function isValidUrl(url) {
|
||||
if (!url)
|
||||
return false;
|
||||
var colon = url.indexOf(':');
|
||||
if (colon < 0)
|
||||
return false;
|
||||
var protocol = url.substr(0, colon);
|
||||
switch (protocol) {
|
||||
case 'http':
|
||||
case 'https':
|
||||
case 'ftp':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var annotations = this.annotations || [];
|
||||
var i, n = annotations.length;
|
||||
var items = [];
|
||||
for (i = 0; i < n; ++i) {
|
||||
var annotationRef = annotations[i];
|
||||
var annotation = xref.fetch(annotationRef);
|
||||
if (!isDict(annotation))
|
||||
continue;
|
||||
var subtype = annotation.get('Subtype');
|
||||
if (!isName(subtype) || subtype.name != 'Link')
|
||||
if (!isName(subtype))
|
||||
continue;
|
||||
var rect = annotation.get('Rect');
|
||||
var topLeftCorner = this.rotatePoint(rect[0], rect[1]);
|
||||
var bottomRightCorner = this.rotatePoint(rect[2], rect[3]);
|
||||
|
||||
var link = {};
|
||||
link.x = Math.min(topLeftCorner.x, bottomRightCorner.x);
|
||||
link.y = Math.min(topLeftCorner.y, bottomRightCorner.y);
|
||||
link.width = Math.abs(topLeftCorner.x - bottomRightCorner.x);
|
||||
link.height = Math.abs(topLeftCorner.y - bottomRightCorner.y);
|
||||
var a = this.xref.fetchIfRef(annotation.get('A'));
|
||||
if (a) {
|
||||
switch (a.get('S').name) {
|
||||
case 'URI':
|
||||
link.url = a.get('URI');
|
||||
var item = {};
|
||||
item.type = subtype.name;
|
||||
item.x = Math.min(topLeftCorner.x, bottomRightCorner.x);
|
||||
item.y = Math.min(topLeftCorner.y, bottomRightCorner.y);
|
||||
item.width = Math.abs(topLeftCorner.x - bottomRightCorner.x);
|
||||
item.height = Math.abs(topLeftCorner.y - bottomRightCorner.y);
|
||||
switch (subtype.name) {
|
||||
case 'Link':
|
||||
var a = annotation.get('A');
|
||||
if (a) {
|
||||
switch (a.get('S').name) {
|
||||
case 'URI':
|
||||
var url = a.get('URI');
|
||||
// TODO: pdf spec mentions urls can be relative to a Base
|
||||
// entry in the dictionary.
|
||||
if (!isValidUrl(url))
|
||||
url = '';
|
||||
item.url = url;
|
||||
break;
|
||||
case 'GoTo':
|
||||
item.dest = a.get('D');
|
||||
break;
|
||||
default:
|
||||
TODO('other link types');
|
||||
}
|
||||
} else if (annotation.has('Dest')) {
|
||||
// simple destination link
|
||||
var dest = annotation.get('Dest');
|
||||
item.dest = isName(dest) ? dest.name : dest;
|
||||
}
|
||||
break;
|
||||
case 'Widget':
|
||||
var fieldType = getInheritableProperty(annotation, 'FT');
|
||||
if (!isName(fieldType))
|
||||
break;
|
||||
case 'GoTo':
|
||||
link.dest = a.get('D');
|
||||
break;
|
||||
default:
|
||||
TODO('other link types');
|
||||
}
|
||||
} else if (annotation.has('Dest')) {
|
||||
// simple destination link
|
||||
var dest = annotation.get('Dest');
|
||||
link.dest = isName(dest) ? dest.name : dest;
|
||||
item.fieldType = fieldType.name;
|
||||
// Building the full field name by collecting the field and
|
||||
// its ancestors 'T' properties and joining them using '.'.
|
||||
var fieldName = [];
|
||||
var namedItem = annotation, ref = annotationRef;
|
||||
while (namedItem) {
|
||||
var parent = namedItem.get('Parent');
|
||||
var parentRef = namedItem.getRaw('Parent');
|
||||
var name = namedItem.get('T');
|
||||
if (name) {
|
||||
fieldName.unshift(stringToPDFString(name));
|
||||
} else {
|
||||
// The field name is absent, that means more than one field
|
||||
// with the same name may exist. Replacing the empty name
|
||||
// with the '`' plus index in the parent's 'Kids' array.
|
||||
// This is not in the PDF spec but necessary to id the
|
||||
// the input controls.
|
||||
var kids = parent.get('Kids');
|
||||
var j, jj;
|
||||
for (j = 0, jj = kids.length; j < jj; j++) {
|
||||
var kidRef = kids[j];
|
||||
if (kidRef.num == ref.num && kidRef.gen == ref.gen)
|
||||
break;
|
||||
}
|
||||
fieldName.unshift('`' + j);
|
||||
}
|
||||
namedItem = parent;
|
||||
ref = parentRef;
|
||||
}
|
||||
item.fullName = fieldName.join('.');
|
||||
var alternativeText = stringToPDFString(annotation.get('TU') || '');
|
||||
item.alternativeText = alternativeText;
|
||||
var da = getInheritableProperty(annotation, 'DA') || '';
|
||||
var m = /([\d\.]+)\sTf/.exec(da);
|
||||
if (m)
|
||||
item.fontSize = parseFloat(m[1]);
|
||||
item.textAlignment = getInheritableProperty(annotation, 'Q');
|
||||
item.flags = getInheritableProperty(annotation, 'Ff') || 0;
|
||||
break;
|
||||
case 'Text':
|
||||
var content = annotation.get('Contents');
|
||||
var title = annotation.get('T');
|
||||
item.content = stringToPDFString(content || '');
|
||||
item.title = stringToPDFString(title || '');
|
||||
item.name = annotation.get('Name').name;
|
||||
break;
|
||||
default:
|
||||
TODO('unimplemented annotation type: ' + subtype.name);
|
||||
break;
|
||||
}
|
||||
links.push(link);
|
||||
items.push(item);
|
||||
}
|
||||
return links;
|
||||
return items;
|
||||
},
|
||||
startRendering: function pageStartRendering(ctx, callback) {
|
||||
this.ctx = ctx;
|
||||
this.callback = callback;
|
||||
startRendering: function Page_startRendering(ctx, callback, textLayer) {
|
||||
var stats = this.stats;
|
||||
stats.time('Overall');
|
||||
// If there is no displayReadyPromise yet, then the operatorList was never
|
||||
// requested before. Make the request and create the promise.
|
||||
if (!this.displayReadyPromise) {
|
||||
this.pdf.startRendering(this);
|
||||
this.displayReadyPromise = new Promise();
|
||||
}
|
||||
|
||||
this.startRenderingTime = Date.now();
|
||||
this.pdf.startRendering(this);
|
||||
// Once the operatorList and fonts are loaded, do the actual rendering.
|
||||
this.displayReadyPromise.then(
|
||||
function pageDisplayReadyPromise() {
|
||||
var gfx = new CanvasGraphics(ctx, this.objs, textLayer);
|
||||
try {
|
||||
this.display(gfx, callback);
|
||||
} catch (e) {
|
||||
if (callback)
|
||||
callback(e);
|
||||
else
|
||||
error(e);
|
||||
}
|
||||
}.bind(this),
|
||||
function pageDisplayReadPromiseError(reason) {
|
||||
if (callback)
|
||||
callback(reason);
|
||||
else
|
||||
error(reason);
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return Page;
|
||||
})();
|
||||
|
||||
/**
|
||||
|
@ -321,12 +476,9 @@ var Page = (function pagePage() {
|
|||
* Right now there exists one PDFDocModel on the main thread + one object
|
||||
* for each worker. If there is no worker support enabled, there are two
|
||||
* `PDFDocModel` objects on the main thread created.
|
||||
* TODO: Refactor the internal object structure, such that there is no
|
||||
* need for the `PDFDocModel` anymore and there is only one object on the
|
||||
* main thread and not one entire copy on each worker instance.
|
||||
*/
|
||||
var PDFDocModel = (function pdfDoc() {
|
||||
function constructor(arg, callback) {
|
||||
var PDFDocModel = (function PDFDocModelClosure() {
|
||||
function PDFDocModel(arg, callback) {
|
||||
if (isStream(arg))
|
||||
init.call(this, arg);
|
||||
else if (isArrayBuffer(arg))
|
||||
|
@ -339,6 +491,7 @@ var PDFDocModel = (function pdfDoc() {
|
|||
assertWellFormed(stream.length > 0, 'stream must have data');
|
||||
this.stream = stream;
|
||||
this.setup();
|
||||
this.acroForm = this.catalog.catDict.get('AcroForm');
|
||||
}
|
||||
|
||||
function find(stream, needle, limit, backwards) {
|
||||
|
@ -357,7 +510,7 @@ var PDFDocModel = (function pdfDoc() {
|
|||
return true; /* found */
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
PDFDocModel.prototype = {
|
||||
get linearization() {
|
||||
var length = this.stream.length;
|
||||
var linearization = false;
|
||||
|
@ -379,12 +532,17 @@ var PDFDocModel = (function pdfDoc() {
|
|||
if (find(stream, 'endobj', 1024))
|
||||
startXRef = stream.pos + 6;
|
||||
} else {
|
||||
// Find startxref at the end of the file.
|
||||
var start = stream.end - 1024;
|
||||
if (start < 0)
|
||||
start = 0;
|
||||
stream.pos = start;
|
||||
if (find(stream, 'startxref', 1024, true)) {
|
||||
// Find startxref by jumping backward from the end of the file.
|
||||
var step = 1024;
|
||||
var found = false, pos = stream.end;
|
||||
while (!found && pos > 0) {
|
||||
pos -= step - 'startxref'.length;
|
||||
if (pos < 0)
|
||||
pos = 0;
|
||||
stream.pos = pos;
|
||||
found = find(stream, 'startxref', step, true);
|
||||
}
|
||||
if (found) {
|
||||
stream.skip(9);
|
||||
var ch;
|
||||
do {
|
||||
|
@ -413,7 +571,7 @@ var PDFDocModel = (function pdfDoc() {
|
|||
},
|
||||
// Find the header, remove leading garbage and setup the stream
|
||||
// starting from the header.
|
||||
checkHeader: function pdfDocCheckHeader() {
|
||||
checkHeader: function PDFDocModel_checkHeader() {
|
||||
var stream = this.stream;
|
||||
stream.reset();
|
||||
if (find(stream, '%PDF-', 1024)) {
|
||||
|
@ -423,12 +581,13 @@ var PDFDocModel = (function pdfDoc() {
|
|||
}
|
||||
// May not be a PDF file, continue anyway.
|
||||
},
|
||||
setup: function pdfDocSetup(ownerPassword, userPassword) {
|
||||
setup: function PDFDocModel_setup(ownerPassword, userPassword) {
|
||||
this.checkHeader();
|
||||
this.xref = new XRef(this.stream,
|
||||
this.startXRef,
|
||||
this.mainXRefEntriesOffset);
|
||||
this.catalog = new Catalog(this.xref);
|
||||
var xref = new XRef(this.stream,
|
||||
this.startXRef,
|
||||
this.mainXRefEntriesOffset);
|
||||
this.xref = xref;
|
||||
this.catalog = new Catalog(xref);
|
||||
},
|
||||
get numPages() {
|
||||
var linearization = this.linearization;
|
||||
|
@ -436,16 +595,51 @@ var PDFDocModel = (function pdfDoc() {
|
|||
// shadow the prototype getter
|
||||
return shadow(this, 'numPages', num);
|
||||
},
|
||||
getPage: function pdfDocGetPage(n) {
|
||||
getDocumentInfo: function PDFDocModel_getDocumentInfo() {
|
||||
var info;
|
||||
if (this.xref.trailer.has('Info')) {
|
||||
var infoDict = this.xref.trailer.get('Info');
|
||||
|
||||
info = {};
|
||||
infoDict.forEach(function(key, value) {
|
||||
info[key] = typeof value !== 'string' ? value :
|
||||
stringToPDFString(value);
|
||||
});
|
||||
}
|
||||
|
||||
return shadow(this, 'getDocumentInfo', info);
|
||||
},
|
||||
getFingerprint: function PDFDocModel_getFingerprint() {
|
||||
var xref = this.xref, fileID;
|
||||
if (xref.trailer.has('ID')) {
|
||||
fileID = '';
|
||||
var id = xref.trailer.get('ID')[0];
|
||||
id.split('').forEach(function(el) {
|
||||
fileID += Number(el.charCodeAt(0)).toString(16);
|
||||
});
|
||||
} else {
|
||||
// If we got no fileID, then we generate one,
|
||||
// from the first 100 bytes of PDF
|
||||
var data = this.stream.bytes.subarray(0, 100);
|
||||
var hash = calculateMD5(data, 0, data.length);
|
||||
fileID = '';
|
||||
for (var i = 0, length = hash.length; i < length; i++) {
|
||||
fileID += Number(hash[i]).toString(16);
|
||||
}
|
||||
}
|
||||
|
||||
return shadow(this, 'getFingerprint', fileID);
|
||||
},
|
||||
getPage: function PDFDocModel_getPage(n) {
|
||||
return this.catalog.getPage(n);
|
||||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return PDFDocModel;
|
||||
})();
|
||||
|
||||
var PDFDoc = (function pdfDoc() {
|
||||
function constructor(arg, callback) {
|
||||
var PDFDoc = (function PDFDocClosure() {
|
||||
function PDFDoc(arg, callback) {
|
||||
var stream = null;
|
||||
var data = null;
|
||||
|
||||
|
@ -461,9 +655,10 @@ var PDFDoc = (function pdfDoc() {
|
|||
|
||||
this.data = data;
|
||||
this.stream = stream;
|
||||
this.pdf = new PDFDocModel(stream);
|
||||
|
||||
this.catalog = this.pdf.catalog;
|
||||
this.pdfModel = new PDFDocModel(stream);
|
||||
this.fingerprint = this.pdfModel.getFingerprint();
|
||||
this.info = this.pdfModel.getDocumentInfo();
|
||||
this.catalog = this.pdfModel.catalog;
|
||||
this.objs = new PDFObjects();
|
||||
|
||||
this.pageCache = [];
|
||||
|
@ -478,49 +673,59 @@ var PDFDoc = (function pdfDoc() {
|
|||
if (!globalScope.PDFJS.disableWorker && typeof Worker !== 'undefined') {
|
||||
var workerSrc = PDFJS.workerSrc;
|
||||
if (typeof workerSrc === 'undefined') {
|
||||
throw 'No PDFJS.workerSrc specified';
|
||||
error('No PDFJS.workerSrc specified');
|
||||
}
|
||||
|
||||
var worker;
|
||||
try {
|
||||
worker = new Worker(workerSrc);
|
||||
} catch (e) {
|
||||
// Some versions of FF can't create a worker on localhost, see:
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=683280
|
||||
globalScope.PDFJS.disableWorker = true;
|
||||
this.setupFakeWorker();
|
||||
return;
|
||||
}
|
||||
|
||||
var messageHandler = new MessageHandler('main', worker);
|
||||
|
||||
// Tell the worker the file it was created from.
|
||||
messageHandler.send('workerSrc', workerSrc);
|
||||
|
||||
messageHandler.on('test', function pdfDocTest(supportTypedArray) {
|
||||
if (supportTypedArray) {
|
||||
this.worker = worker;
|
||||
this.setupMessageHandler(messageHandler);
|
||||
var worker;
|
||||
if (PDFJS.isFirefoxExtension) {
|
||||
// The firefox extension can't load the worker from the resource://
|
||||
// url so we have to inline the script and then use the blob loader.
|
||||
var bb = new MozBlobBuilder();
|
||||
bb.append(document.querySelector('#PDFJS_SCRIPT_TAG').textContent);
|
||||
var blobUrl = window.URL.createObjectURL(bb.getBlob());
|
||||
worker = new Worker(blobUrl);
|
||||
} else {
|
||||
this.setupFakeWorker();
|
||||
// Some versions of FF can't create a worker on localhost, see:
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=683280
|
||||
worker = new Worker(workerSrc);
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
var testObj = new Uint8Array(1);
|
||||
messageHandler.send('test', testObj);
|
||||
} else {
|
||||
this.setupFakeWorker();
|
||||
var messageHandler = new MessageHandler('main', worker);
|
||||
|
||||
messageHandler.on('test', function pdfDocTest(supportTypedArray) {
|
||||
if (supportTypedArray) {
|
||||
this.worker = worker;
|
||||
this.setupMessageHandler(messageHandler);
|
||||
} else {
|
||||
globalScope.PDFJS.disableWorker = true;
|
||||
this.setupFakeWorker();
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
var testObj = new Uint8Array(1);
|
||||
// Some versions of Opera throw a DATA_CLONE_ERR on
|
||||
// serializing the typed array.
|
||||
messageHandler.send('test', testObj);
|
||||
return;
|
||||
} catch (e) {
|
||||
warn('The worker has been disabled.');
|
||||
}
|
||||
}
|
||||
// Either workers are disabled, not supported or have thrown an exception.
|
||||
// Thus, we fallback to a faked worker.
|
||||
globalScope.PDFJS.disableWorker = true;
|
||||
this.setupFakeWorker();
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
setupFakeWorker: function() {
|
||||
PDFDoc.prototype = {
|
||||
setupFakeWorker: function PDFDoc_setupFakeWorker() {
|
||||
// If we don't use a worker, just post/sendMessage to the main thread.
|
||||
var fakeWorker = {
|
||||
postMessage: function pdfDocPostMessage(obj) {
|
||||
postMessage: function PDFDoc_postMessage(obj) {
|
||||
fakeWorker.onmessage({data: obj});
|
||||
},
|
||||
terminate: function pdfDocTerminate() {}
|
||||
terminate: function PDFDoc_terminate() {}
|
||||
};
|
||||
|
||||
var messageHandler = new MessageHandler('main', fakeWorker);
|
||||
|
@ -532,7 +737,7 @@ var PDFDoc = (function pdfDoc() {
|
|||
},
|
||||
|
||||
|
||||
setupMessageHandler: function(messageHandler) {
|
||||
setupMessageHandler: function PDFDoc_setupMessageHandler(messageHandler) {
|
||||
this.messageHandler = messageHandler;
|
||||
|
||||
messageHandler.on('page', function pdfDocPage(data) {
|
||||
|
@ -540,7 +745,8 @@ var PDFDoc = (function pdfDoc() {
|
|||
var page = this.pageCache[pageNum];
|
||||
var depFonts = data.depFonts;
|
||||
|
||||
page.startRenderingFromIRQueue(data.IRQueue, depFonts);
|
||||
page.stats.timeEnd('Page Request');
|
||||
page.startRenderingFromOperatorList(data.operatorList, depFonts);
|
||||
}, this);
|
||||
|
||||
messageHandler.on('obj', function pdfDocObj(data) {
|
||||
|
@ -549,8 +755,12 @@ var PDFDoc = (function pdfDoc() {
|
|||
|
||||
switch (type) {
|
||||
case 'JpegStream':
|
||||
var IR = data[2];
|
||||
new JpegImageLoader(id, IR, this.objs);
|
||||
var imageData = data[2];
|
||||
loadJpegStream(id, imageData, this.objs);
|
||||
break;
|
||||
case 'Image':
|
||||
var imageData = data[2];
|
||||
this.objs.resolve(id, imageData);
|
||||
break;
|
||||
case 'Font':
|
||||
var name = data[2];
|
||||
|
@ -558,46 +768,63 @@ var PDFDoc = (function pdfDoc() {
|
|||
var properties = data[4];
|
||||
|
||||
if (file) {
|
||||
// Rewrap the ArrayBuffer in a stream.
|
||||
var fontFileDict = new Dict();
|
||||
fontFileDict.map = file.dict.map;
|
||||
|
||||
var fontFile = new Stream(file.bytes, file.start,
|
||||
file.end - file.start, fontFileDict);
|
||||
|
||||
// Check if this is a FlateStream. Otherwise just use the created
|
||||
// Stream one. This makes complex_ttf_font.pdf work.
|
||||
var cmf = file.bytes[0];
|
||||
if ((cmf & 0x0f) == 0x08) {
|
||||
file = new FlateStream(fontFile);
|
||||
} else {
|
||||
file = fontFile;
|
||||
}
|
||||
file = new Stream(file, 0, file.length, fontFileDict);
|
||||
}
|
||||
|
||||
// For now, resolve the font object here direclty. The real font
|
||||
// object is then created in FontLoader.bind().
|
||||
this.objs.resolve(id, {
|
||||
name: name,
|
||||
file: file,
|
||||
properties: properties
|
||||
});
|
||||
// At this point, only the font object is created but the font is
|
||||
// not yet attached to the DOM. This is done in `FontLoader.bind`.
|
||||
var font = new Font(name, file, properties);
|
||||
this.objs.resolve(id, font);
|
||||
break;
|
||||
default:
|
||||
throw 'Got unkown object type ' + type;
|
||||
error('Got unkown object type ' + type);
|
||||
}
|
||||
}, this);
|
||||
|
||||
messageHandler.on('font_ready', function pdfDocFontReady(data) {
|
||||
var id = data[0];
|
||||
var font = new FontShape(data[1]);
|
||||
messageHandler.on('page_error', function pdfDocError(data) {
|
||||
var page = this.pageCache[data.pageNum];
|
||||
if (page.displayReadyPromise)
|
||||
page.displayReadyPromise.reject(data.error);
|
||||
else
|
||||
error(data.error);
|
||||
}, this);
|
||||
|
||||
// If there is no string, then there is nothing to attach to the DOM.
|
||||
if (!font.str) {
|
||||
this.objs.resolve(id, font);
|
||||
} else {
|
||||
this.objs.setData(id, font);
|
||||
}
|
||||
}.bind(this));
|
||||
messageHandler.on('jpeg_decode', function(data, promise) {
|
||||
var imageData = data[0];
|
||||
var components = data[1];
|
||||
if (components != 3 && components != 1)
|
||||
error('Only 3 component or 1 component can be returned');
|
||||
|
||||
var img = new Image();
|
||||
img.onload = (function messageHandler_onloadClosure() {
|
||||
var width = img.width;
|
||||
var height = img.height;
|
||||
var size = width * height;
|
||||
var rgbaLength = size * 4;
|
||||
var buf = new Uint8Array(size * components);
|
||||
var tmpCanvas = createScratchCanvas(width, height);
|
||||
var tmpCtx = tmpCanvas.getContext('2d');
|
||||
tmpCtx.drawImage(img, 0, 0);
|
||||
var data = tmpCtx.getImageData(0, 0, width, height).data;
|
||||
|
||||
if (components == 3) {
|
||||
for (var i = 0, j = 0; i < rgbaLength; i += 4, j += 3) {
|
||||
buf[j] = data[i];
|
||||
buf[j + 1] = data[i + 1];
|
||||
buf[j + 2] = data[i + 2];
|
||||
}
|
||||
} else if (components == 1) {
|
||||
for (var i = 0, j = 0; i < rgbaLength; i += 4, j++) {
|
||||
buf[j] = data[i];
|
||||
}
|
||||
}
|
||||
promise.resolve({ data: buf, width: width, height: height});
|
||||
}).bind(this);
|
||||
var src = 'data:image/jpeg;base64,' + window.btoa(imageData);
|
||||
img.src = src;
|
||||
});
|
||||
|
||||
setTimeout(function pdfDocFontReadySetTimeout() {
|
||||
messageHandler.send('doc', this.data);
|
||||
|
@ -606,21 +833,22 @@ var PDFDoc = (function pdfDoc() {
|
|||
},
|
||||
|
||||
get numPages() {
|
||||
return this.pdf.numPages;
|
||||
return this.pdfModel.numPages;
|
||||
},
|
||||
|
||||
startRendering: function pdfDocStartRendering(page) {
|
||||
startRendering: function PDFDoc_startRendering(page) {
|
||||
// The worker might not be ready to receive the page request yet.
|
||||
this.workerReadyPromise.then(function pdfDocStartRenderingThen() {
|
||||
page.stats.time('Page Request');
|
||||
this.messageHandler.send('page_request', page.pageNumber + 1);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
getPage: function pdfDocGetPage(n) {
|
||||
getPage: function PDFDoc_getPage(n) {
|
||||
if (this.pageCache[n])
|
||||
return this.pageCache[n];
|
||||
|
||||
var page = this.pdf.getPage(n);
|
||||
var page = this.pdfModel.getPage(n);
|
||||
// Add a reference to the objects such that Page can forward the reference
|
||||
// to the CanvasGraphics and so on.
|
||||
page.objs = this.objs;
|
||||
|
@ -628,7 +856,7 @@ var PDFDoc = (function pdfDoc() {
|
|||
return (this.pageCache[n] = page);
|
||||
},
|
||||
|
||||
destroy: function pdfDocDestroy() {
|
||||
destroy: function PDFDoc_destroy() {
|
||||
if (this.worker)
|
||||
this.worker.terminate();
|
||||
|
||||
|
@ -645,7 +873,7 @@ var PDFDoc = (function pdfDoc() {
|
|||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return PDFDoc;
|
||||
})();
|
||||
|
||||
globalScope.PDFJS.PDFDoc = PDFDoc;
|
||||
|
|
59
apps/files_pdfviewer/js/pdfjs/src/crypto.js
Executable file → Normal file
|
@ -3,8 +3,8 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var ARCFourCipher = (function arcFourCipher() {
|
||||
function constructor(key) {
|
||||
var ARCFourCipher = (function ARCFourCipherClosure() {
|
||||
function ARCFourCipher(key) {
|
||||
this.a = 0;
|
||||
this.b = 0;
|
||||
var s = new Uint8Array(256);
|
||||
|
@ -20,8 +20,8 @@ var ARCFourCipher = (function arcFourCipher() {
|
|||
this.s = s;
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
encryptBlock: function arcFourCipherEncryptBlock(data) {
|
||||
ARCFourCipher.prototype = {
|
||||
encryptBlock: function ARCFourCipher_encryptBlock(data) {
|
||||
var i, n = data.length, tmp, tmp2;
|
||||
var a = this.a, b = this.b, s = this.s;
|
||||
var output = new Uint8Array(n);
|
||||
|
@ -39,12 +39,12 @@ var ARCFourCipher = (function arcFourCipher() {
|
|||
return output;
|
||||
}
|
||||
};
|
||||
constructor.prototype.decryptBlock = constructor.prototype.encryptBlock;
|
||||
ARCFourCipher.prototype.decryptBlock = ARCFourCipher.prototype.encryptBlock;
|
||||
|
||||
return constructor;
|
||||
return ARCFourCipher;
|
||||
})();
|
||||
|
||||
var calculateMD5 = (function calculateMD5() {
|
||||
var calculateMD5 = (function calculateMD5Closure() {
|
||||
var r = new Uint8Array([
|
||||
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
|
||||
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
|
||||
|
@ -128,20 +128,20 @@ var calculateMD5 = (function calculateMD5() {
|
|||
return hash;
|
||||
})();
|
||||
|
||||
var NullCipher = (function nullCipher() {
|
||||
function constructor() {
|
||||
var NullCipher = (function NullCipherClosure() {
|
||||
function NullCipher() {
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
decryptBlock: function nullCipherDecryptBlock(data) {
|
||||
NullCipher.prototype = {
|
||||
decryptBlock: function NullCipher_decryptBlock(data) {
|
||||
return data;
|
||||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return NullCipher;
|
||||
})();
|
||||
|
||||
var AES128Cipher = (function aes128Cipher() {
|
||||
var AES128Cipher = (function AES128CipherClosure() {
|
||||
var rcon = new Uint8Array([
|
||||
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c,
|
||||
0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a,
|
||||
|
@ -330,7 +330,7 @@ var AES128Cipher = (function aes128Cipher() {
|
|||
return state;
|
||||
}
|
||||
|
||||
function constructor(key) {
|
||||
function AES128Cipher(key) {
|
||||
this.key = expandKey128(key);
|
||||
this.buffer = new Uint8Array(16);
|
||||
this.bufferPosition = 0;
|
||||
|
@ -370,8 +370,8 @@ var AES128Cipher = (function aes128Cipher() {
|
|||
return output;
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
decryptBlock: function aes128CipherDecryptBlock(data) {
|
||||
AES128Cipher.prototype = {
|
||||
decryptBlock: function AES128Cipher_decryptBlock(data) {
|
||||
var i, sourceLength = data.length;
|
||||
var buffer = this.buffer, bufferLength = this.bufferPosition;
|
||||
// waiting for IV values -- they are at the start of the stream
|
||||
|
@ -391,16 +391,16 @@ var AES128Cipher = (function aes128Cipher() {
|
|||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return AES128Cipher;
|
||||
})();
|
||||
|
||||
var CipherTransform = (function cipherTransform() {
|
||||
function constructor(stringCipherConstructor, streamCipherConstructor) {
|
||||
var CipherTransform = (function CipherTransformClosure() {
|
||||
function CipherTransform(stringCipherConstructor, streamCipherConstructor) {
|
||||
this.stringCipherConstructor = stringCipherConstructor;
|
||||
this.streamCipherConstructor = streamCipherConstructor;
|
||||
}
|
||||
constructor.prototype = {
|
||||
createStream: function cipherTransformCreateStream(stream) {
|
||||
CipherTransform.prototype = {
|
||||
createStream: function CipherTransform_createStream(stream) {
|
||||
var cipher = new this.streamCipherConstructor();
|
||||
return new DecryptStream(stream,
|
||||
function cipherTransformDecryptStream(data) {
|
||||
|
@ -408,17 +408,17 @@ var CipherTransform = (function cipherTransform() {
|
|||
}
|
||||
);
|
||||
},
|
||||
decryptString: function cipherTransformDecryptString(s) {
|
||||
decryptString: function CipherTransform_decryptString(s) {
|
||||
var cipher = new this.stringCipherConstructor();
|
||||
var data = stringToBytes(s);
|
||||
data = cipher.decryptBlock(data);
|
||||
return bytesToString(data);
|
||||
}
|
||||
};
|
||||
return constructor;
|
||||
return CipherTransform;
|
||||
})();
|
||||
|
||||
var CipherTransformFactory = (function cipherTransformFactory() {
|
||||
var CipherTransformFactory = (function CipherTransformFactoryClosure() {
|
||||
function prepareKeyData(fileId, password, ownerPassword, userPassword,
|
||||
flags, revision, keyLength, encryptMetadata) {
|
||||
var defaultPasswordBytes = new Uint8Array([
|
||||
|
@ -490,7 +490,7 @@ var CipherTransformFactory = (function cipherTransformFactory() {
|
|||
|
||||
var identityName = new Name('Identity');
|
||||
|
||||
function constructor(dict, fileId, password) {
|
||||
function CipherTransformFactory(dict, fileId, password) {
|
||||
var filter = dict.get('Filter');
|
||||
if (!isName(filter) || filter.name != 'Standard')
|
||||
error('unknown encryption method');
|
||||
|
@ -570,12 +570,11 @@ var CipherTransformFactory = (function cipherTransformFactory() {
|
|||
};
|
||||
}
|
||||
error('Unknown crypto method');
|
||||
return null;
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
createCipherTransform: function buildCipherCreateCipherTransform(num,
|
||||
gen) {
|
||||
CipherTransformFactory.prototype = {
|
||||
createCipherTransform:
|
||||
function CipherTransformFactory_createCipherTransform(num, gen) {
|
||||
if (this.algorithm == 4) {
|
||||
return new CipherTransform(
|
||||
buildCipherConstructor(this.cf, this.stmf,
|
||||
|
@ -592,6 +591,6 @@ var CipherTransformFactory = (function cipherTransformFactory() {
|
|||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return CipherTransformFactory;
|
||||
})();
|
||||
|
||||
|
|
365
apps/files_pdfviewer/js/pdfjs/src/evaluator.js
Executable file → Normal file
|
@ -3,8 +3,8 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var PartialEvaluator = (function partialEvaluator() {
|
||||
function constructor(xref, handler, uniquePrefix) {
|
||||
var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
function PartialEvaluator(xref, handler, uniquePrefix) {
|
||||
this.state = new EvalState();
|
||||
this.stateStack = [];
|
||||
|
||||
|
@ -111,14 +111,27 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
EX: 'endCompat'
|
||||
};
|
||||
|
||||
constructor.prototype = {
|
||||
getIRQueue: function partialEvaluatorGetIRQueue(stream, resources,
|
||||
queue, dependency) {
|
||||
function splitCombinedOperations(operations) {
|
||||
// Two operations can be combined together, trying to find which two
|
||||
// operations were concatenated.
|
||||
for (var i = operations.length - 1; i > 0; i--) {
|
||||
var op1 = operations.substring(0, i), op2 = operations.substring(i);
|
||||
if (op1 in OP_MAP && op2 in OP_MAP)
|
||||
return [op1, op2]; // operations found
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
PartialEvaluator.prototype = {
|
||||
getOperatorList: function PartialEvaluator_getOperatorList(stream,
|
||||
resources,
|
||||
dependency,
|
||||
queue) {
|
||||
|
||||
var self = this;
|
||||
var xref = this.xref;
|
||||
var handler = this.handler;
|
||||
var uniquePrefix = this.uniquePrefix;
|
||||
var uniquePrefix = this.uniquePrefix || '';
|
||||
|
||||
function insertDependency(depList) {
|
||||
fnArray.push('dependency');
|
||||
|
@ -131,18 +144,14 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
}
|
||||
}
|
||||
|
||||
function handleSetFont(fontName, fontRef) {
|
||||
function handleSetFont(fontName, font) {
|
||||
var loadedName = null;
|
||||
|
||||
var fontRes = resources.get('Font');
|
||||
|
||||
// TODO: TOASK: Is it possible to get here? If so, what does
|
||||
// args[0].name should be like???
|
||||
assert(fontRes, 'fontRes not available');
|
||||
|
||||
fontRes = xref.fetchIfRef(fontRes);
|
||||
fontRef = fontRef || fontRes.get(fontName);
|
||||
var font = xref.fetchIfRef(fontRef);
|
||||
font = xref.fetchIfRef(font) || fontRes.get(fontName);
|
||||
assertWellFormed(isDict(font));
|
||||
if (!font.translated) {
|
||||
font.translated = self.translateFont(font, xref, resources,
|
||||
|
@ -155,6 +164,15 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
font.loadedName = loadedName;
|
||||
|
||||
var translated = font.translated;
|
||||
// Convert the file to an ArrayBuffer which will be turned back into
|
||||
// a Stream in the main thread.
|
||||
if (translated.file)
|
||||
translated.file = translated.file.getBytes();
|
||||
if (translated.properties.file) {
|
||||
translated.properties.file =
|
||||
translated.properties.file.getBytes();
|
||||
}
|
||||
|
||||
handler.send('obj', [
|
||||
loadedName,
|
||||
'Font',
|
||||
|
@ -168,7 +186,7 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
|
||||
// Ensure the font is ready before the font is set
|
||||
// and later on used for drawing.
|
||||
// TODO: This should get insert to the IRQueue only once per
|
||||
// OPTIMIZE: This should get insert to the operatorList only once per
|
||||
// page.
|
||||
insertDependency([loadedName]);
|
||||
return loadedName;
|
||||
|
@ -179,65 +197,60 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
var w = dict.get('Width', 'W');
|
||||
var h = dict.get('Height', 'H');
|
||||
|
||||
if (image instanceof JpegStream && image.isNative) {
|
||||
var objId = 'img_' + uniquePrefix + (++self.objIdCounter);
|
||||
handler.send('obj', [objId, 'JpegStream', image.getIR()]);
|
||||
var imageMask = dict.get('ImageMask', 'IM') || false;
|
||||
if (imageMask) {
|
||||
// This depends on a tmpCanvas beeing filled with the
|
||||
// current fillStyle, such that processing the pixel
|
||||
// data can't be done here. Instead of creating a
|
||||
// complete PDFImage, only read the information needed
|
||||
// for later.
|
||||
|
||||
// Add the dependency on the image object.
|
||||
insertDependency([objId]);
|
||||
|
||||
// The normal fn.
|
||||
fn = 'paintJpegXObject';
|
||||
args = [objId, w, h];
|
||||
var width = dict.get('Width', 'W');
|
||||
var height = dict.get('Height', 'H');
|
||||
var bitStrideLength = (width + 7) >> 3;
|
||||
var imgArray = image.getBytes(bitStrideLength * height);
|
||||
var decode = dict.get('Decode', 'D');
|
||||
var inverseDecode = !!decode && decode[0] > 0;
|
||||
|
||||
fn = 'paintImageMaskXObject';
|
||||
args = [imgArray, inverseDecode, width, height];
|
||||
return;
|
||||
}
|
||||
|
||||
// Needs to be rendered ourself.
|
||||
|
||||
// Figure out if the image has an imageMask.
|
||||
var imageMask = dict.get('ImageMask', 'IM') || false;
|
||||
|
||||
// If there is no imageMask, create the PDFImage and a lot
|
||||
// of image processing can be done here.
|
||||
if (!imageMask) {
|
||||
var imageObj = new PDFImage(xref, resources, image, inline);
|
||||
var objId = 'img_' + uniquePrefix + (++self.objIdCounter);
|
||||
insertDependency([objId]);
|
||||
args = [objId, w, h];
|
||||
|
||||
if (imageObj.imageMask) {
|
||||
throw 'Can\'t handle this in the web worker :/';
|
||||
}
|
||||
|
||||
var imgData = {
|
||||
width: w,
|
||||
height: h,
|
||||
data: new Uint8Array(w * h * 4)
|
||||
};
|
||||
var pixels = imgData.data;
|
||||
imageObj.fillRgbaBuffer(pixels, imageObj.decode);
|
||||
|
||||
fn = 'paintImageXObject';
|
||||
args = [imgData];
|
||||
var softMask = dict.get('SMask', 'IM') || false;
|
||||
if (!softMask && image instanceof JpegStream &&
|
||||
image.isNativelySupported(xref, resources)) {
|
||||
// These JPEGs don't need any more processing so we can just send it.
|
||||
fn = 'paintJpegXObject';
|
||||
handler.send('obj', [objId, 'JpegStream', image.getIR()]);
|
||||
return;
|
||||
}
|
||||
|
||||
// This depends on a tmpCanvas beeing filled with the
|
||||
// current fillStyle, such that processing the pixel
|
||||
// data can't be done here. Instead of creating a
|
||||
// complete PDFImage, only read the information needed
|
||||
// for later.
|
||||
fn = 'paintImageMaskXObject';
|
||||
fn = 'paintImageXObject';
|
||||
|
||||
var width = dict.get('Width', 'W');
|
||||
var height = dict.get('Height', 'H');
|
||||
var bitStrideLength = (width + 7) >> 3;
|
||||
var imgArray = image.getBytes(bitStrideLength * height);
|
||||
var decode = dict.get('Decode', 'D');
|
||||
var inverseDecode = !!decode && decode[0] > 0;
|
||||
|
||||
args = [imgArray, inverseDecode, width, height];
|
||||
PDFImage.buildImage(function(imageObj) {
|
||||
var drawWidth = imageObj.drawWidth;
|
||||
var drawHeight = imageObj.drawHeight;
|
||||
var imgData = {
|
||||
width: drawWidth,
|
||||
height: drawHeight,
|
||||
data: new Uint8Array(drawWidth * drawHeight * 4)
|
||||
};
|
||||
var pixels = imgData.data;
|
||||
imageObj.fillRgbaBuffer(pixels, drawWidth, drawHeight);
|
||||
handler.send('obj', [objId, 'Image', imgData]);
|
||||
}, handler, xref, resources, image, inline);
|
||||
}
|
||||
|
||||
uniquePrefix = uniquePrefix || '';
|
||||
if (!queue)
|
||||
queue = {};
|
||||
|
||||
if (!queue.argsArray) {
|
||||
queue.argsArray = [];
|
||||
}
|
||||
|
@ -248,45 +261,48 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
var fnArray = queue.fnArray, argsArray = queue.argsArray;
|
||||
var dependencyArray = dependency || [];
|
||||
|
||||
resources = xref.fetchIfRef(resources) || new Dict();
|
||||
var xobjs = xref.fetchIfRef(resources.get('XObject')) || new Dict();
|
||||
var patterns = xref.fetchIfRef(resources.get('Pattern')) || new Dict();
|
||||
var parser = new Parser(new Lexer(stream), false);
|
||||
resources = resources || new Dict();
|
||||
var xobjs = resources.get('XObject') || new Dict();
|
||||
var patterns = resources.get('Pattern') || new Dict();
|
||||
var parser = new Parser(new Lexer(stream), false, xref);
|
||||
var res = resources;
|
||||
var hasNextObj = false, nextObj;
|
||||
var args = [], obj;
|
||||
var getObjBt = function getObjBt() {
|
||||
parser = this.oldParser;
|
||||
return { name: 'BT' };
|
||||
};
|
||||
var TILING_PATTERN = 1, SHADING_PATTERN = 2;
|
||||
|
||||
while (!isEOF(obj = parser.getObj())) {
|
||||
while (true) {
|
||||
if (hasNextObj) {
|
||||
obj = nextObj;
|
||||
hasNextObj = false;
|
||||
} else {
|
||||
obj = parser.getObj();
|
||||
if (isEOF(obj))
|
||||
break;
|
||||
}
|
||||
|
||||
if (isCmd(obj)) {
|
||||
var cmd = obj.cmd;
|
||||
var fn = OP_MAP[cmd];
|
||||
if (!fn) {
|
||||
// invalid content command, trying to recover
|
||||
if (cmd.substr(-2) == 'BT') {
|
||||
fn = OP_MAP[cmd.substr(0, cmd.length - 2)];
|
||||
// feeding 'BT' on next interation
|
||||
parser = {
|
||||
getObj: getObjBt,
|
||||
oldParser: parser
|
||||
};
|
||||
var cmds = splitCombinedOperations(cmd);
|
||||
if (cmds) {
|
||||
cmd = cmds[0];
|
||||
fn = OP_MAP[cmd];
|
||||
// feeding other command on the next interation
|
||||
hasNextObj = true;
|
||||
nextObj = Cmd.get(cmds[1]);
|
||||
}
|
||||
}
|
||||
assertWellFormed(fn, 'Unknown command "' + cmd + '"');
|
||||
// TODO figure out how to type-check vararg functions
|
||||
|
||||
if ((cmd == 'SCN' || cmd == 'scn') && !args[args.length - 1].code) {
|
||||
// Use the IR version for setStroke/FillColorN.
|
||||
fn += '_IR';
|
||||
|
||||
// compile tiling patterns
|
||||
var patternName = args[args.length - 1];
|
||||
// SCN/scn applies patterns along with normal colors
|
||||
if (isName(patternName)) {
|
||||
var pattern = xref.fetchIfRef(patterns.get(patternName.name));
|
||||
var pattern = patterns.get(patternName.name);
|
||||
if (pattern) {
|
||||
var dict = isStream(pattern) ? pattern.dict : pattern;
|
||||
var typeNum = dict.get('PatternType');
|
||||
|
@ -294,21 +310,20 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
if (typeNum == TILING_PATTERN) {
|
||||
// Create an IR of the pattern code.
|
||||
var depIdx = dependencyArray.length;
|
||||
var queueObj = {};
|
||||
var codeIR = this.getIRQueue(pattern, dict.get('Resources'),
|
||||
queueObj, dependencyArray);
|
||||
var operatorList = this.getOperatorList(pattern,
|
||||
dict.get('Resources') || resources, dependencyArray);
|
||||
|
||||
// Add the dependencies that are required to execute the
|
||||
// codeIR.
|
||||
// operatorList.
|
||||
insertDependency(dependencyArray.slice(depIdx));
|
||||
|
||||
args = TilingPattern.getIR(codeIR, dict, args);
|
||||
args = TilingPattern.getIR(operatorList, dict, args);
|
||||
}
|
||||
else if (typeNum == SHADING_PATTERN) {
|
||||
var shading = xref.fetchIfRef(dict.get('Shading'));
|
||||
var shading = dict.get('Shading');
|
||||
var matrix = dict.get('Matrix');
|
||||
var pattern = Pattern.parseShading(shading, matrix, xref, res,
|
||||
null /*ctx*/);
|
||||
var pattern = Pattern.parseShading(shading, matrix, xref,
|
||||
res);
|
||||
args = pattern.getIR();
|
||||
} else {
|
||||
error('Unkown PatternType ' + typeNum);
|
||||
|
@ -320,7 +335,6 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
var name = args[0].name;
|
||||
var xobj = xobjs.get(name);
|
||||
if (xobj) {
|
||||
xobj = xref.fetchIfRef(xobj);
|
||||
assertWellFormed(isStream(xobj), 'XObject should be a stream');
|
||||
|
||||
var type = xobj.dict.get('Subtype');
|
||||
|
@ -336,14 +350,18 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
fnArray.push('paintFormXObjectBegin');
|
||||
argsArray.push([matrix, bbox]);
|
||||
|
||||
// This adds the IRQueue of the xObj to the current queue.
|
||||
// This adds the operatorList of the xObj to the current queue.
|
||||
var depIdx = dependencyArray.length;
|
||||
|
||||
this.getIRQueue(xobj, xobj.dict.get('Resources'), queue,
|
||||
dependencyArray);
|
||||
// Pass in the current `queue` object. That means the `fnArray`
|
||||
// and the `argsArray` in this scope is reused and new commands
|
||||
// are added to them.
|
||||
this.getOperatorList(xobj,
|
||||
xobj.dict.get('Resources') || resources,
|
||||
dependencyArray, queue);
|
||||
|
||||
// Add the dependencies that are required to execute the
|
||||
// codeIR.
|
||||
// operatorList.
|
||||
insertDependency(dependencyArray.slice(depIdx));
|
||||
|
||||
fn = 'paintFormXObjectEnd';
|
||||
|
@ -367,28 +385,27 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
args = [ColorSpace.parseToIR(args[0], xref, resources)];
|
||||
break;
|
||||
case 'shadingFill':
|
||||
var shadingRes = xref.fetchIfRef(res.get('Shading'));
|
||||
var shadingRes = res.get('Shading');
|
||||
if (!shadingRes)
|
||||
error('No shading resource found');
|
||||
|
||||
var shading = xref.fetchIfRef(shadingRes.get(args[0].name));
|
||||
var shading = shadingRes.get(args[0].name);
|
||||
if (!shading)
|
||||
error('No shading object found');
|
||||
|
||||
var shadingFill = Pattern.parseShading(shading, null, xref, res,
|
||||
null);
|
||||
var shadingFill = Pattern.parseShading(shading, null, xref, res);
|
||||
var patternIR = shadingFill.getIR();
|
||||
args = [patternIR];
|
||||
fn = 'shadingFill';
|
||||
break;
|
||||
case 'setGState':
|
||||
var dictName = args[0];
|
||||
var extGState = xref.fetchIfRef(resources.get('ExtGState'));
|
||||
var extGState = resources.get('ExtGState');
|
||||
|
||||
if (!isDict(extGState) || !extGState.has(dictName.name))
|
||||
break;
|
||||
|
||||
var gsState = xref.fetchIfRef(extGState.get(dictName.name));
|
||||
var gsState = extGState.get(dictName.name);
|
||||
|
||||
// This array holds the converted/processed state data.
|
||||
var gsStateObj = [];
|
||||
|
@ -453,10 +470,7 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
}
|
||||
}
|
||||
|
||||
return {
|
||||
fnArray: fnArray,
|
||||
argsArray: argsArray
|
||||
};
|
||||
return queue;
|
||||
},
|
||||
|
||||
extractDataStructures: function
|
||||
|
@ -470,7 +484,7 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
|
||||
if (properties.composite) {
|
||||
// CIDSystemInfo helps to match CID to glyphs
|
||||
var cidSystemInfo = xref.fetchIfRef(dict.get('CIDSystemInfo'));
|
||||
var cidSystemInfo = dict.get('CIDSystemInfo');
|
||||
if (isDict(cidSystemInfo)) {
|
||||
properties.cidSystemInfo = {
|
||||
registry: cidSystemInfo.get('Registry'),
|
||||
|
@ -479,20 +493,24 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
};
|
||||
}
|
||||
|
||||
var cidToGidMap = xref.fetchIfRef(dict.get('CIDToGIDMap'));
|
||||
var cidToGidMap = dict.get('CIDToGIDMap');
|
||||
if (isStream(cidToGidMap))
|
||||
properties.cidToGidMap = this.readCidToGidMap(cidToGidMap);
|
||||
}
|
||||
|
||||
var flags = properties.flags;
|
||||
var differences = [];
|
||||
var baseEncoding = Encodings.StandardEncoding;
|
||||
var baseEncoding = !!(flags & FontFlags.Symbolic) ?
|
||||
Encodings.symbolsEncoding : Encodings.StandardEncoding;
|
||||
var hasEncoding = dict.has('Encoding');
|
||||
if (hasEncoding) {
|
||||
var encoding = xref.fetchIfRef(dict.get('Encoding'));
|
||||
var encoding = dict.get('Encoding');
|
||||
if (isDict(encoding)) {
|
||||
var baseName = encoding.get('BaseEncoding');
|
||||
if (baseName)
|
||||
baseEncoding = Encodings[baseName.name];
|
||||
else
|
||||
hasEncoding = false; // base encoding was not provided
|
||||
|
||||
// Load the differences between the base and original
|
||||
if (encoding.has('Differences')) {
|
||||
|
@ -512,14 +530,14 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
error('Encoding is not a Name nor a Dict');
|
||||
}
|
||||
}
|
||||
|
||||
properties.differences = differences;
|
||||
properties.baseEncoding = baseEncoding;
|
||||
properties.hasEncoding = hasEncoding;
|
||||
},
|
||||
|
||||
readToUnicode:
|
||||
function partialEvaluatorReadToUnicode(toUnicode, xref) {
|
||||
var cmapObj = xref.fetchIfRef(toUnicode);
|
||||
readToUnicode: function PartialEvaluator_readToUnicode(toUnicode, xref) {
|
||||
var cmapObj = toUnicode;
|
||||
var charToUnicode = [];
|
||||
if (isName(cmapObj)) {
|
||||
var isIdentityMap = cmapObj.name.substr(0, 9) == 'Identity-';
|
||||
|
@ -532,9 +550,9 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
|
||||
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');
|
||||
|
@ -554,9 +572,21 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
var startRange = tokens[j];
|
||||
var endRange = tokens[j + 1];
|
||||
var code = tokens[j + 2];
|
||||
while (startRange <= endRange) {
|
||||
charToUnicode[startRange] = code++;
|
||||
++startRange;
|
||||
if (code == 0xFFFF) {
|
||||
// CMap is broken, assuming code == startRange
|
||||
code = startRange;
|
||||
}
|
||||
if (isArray(code)) {
|
||||
var codeindex = 0;
|
||||
while (startRange <= endRange) {
|
||||
charToUnicode[startRange] = code[codeindex++];
|
||||
++startRange;
|
||||
}
|
||||
} else {
|
||||
while (startRange <= endRange) {
|
||||
charToUnicode[startRange] = code++;
|
||||
++startRange;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -579,7 +609,7 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
tokens.push(token);
|
||||
token = '';
|
||||
}
|
||||
switch (byte) {
|
||||
switch (octet) {
|
||||
case 0x5B:
|
||||
// begin list parsing
|
||||
tokens.push(beginArrayToken);
|
||||
|
@ -593,21 +623,39 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
tokens.push(items);
|
||||
break;
|
||||
}
|
||||
} else if (byte == 0x3E) {
|
||||
} else if (octet == 0x3E) {
|
||||
if (token.length) {
|
||||
// parsing hex number
|
||||
tokens.push(parseInt(token, 16));
|
||||
token = '';
|
||||
if (token.length <= 4) {
|
||||
// parsing hex number
|
||||
tokens.push(parseInt(token, 16));
|
||||
token = '';
|
||||
} else {
|
||||
// parsing hex UTF-16BE numbers
|
||||
var str = [];
|
||||
for (var k = 0, kk = token.length; k < kk; k += 4) {
|
||||
var b = parseInt(token.substr(k, 4), 16);
|
||||
if (b <= 0x10) {
|
||||
k += 4;
|
||||
b = (b << 16) | parseInt(token.substr(k, 4), 16);
|
||||
b -= 0x10000;
|
||||
str.push(0xD800 | (b >> 10));
|
||||
str.push(0xDC00 | (b & 0x3FF));
|
||||
break;
|
||||
}
|
||||
str.push(b);
|
||||
}
|
||||
tokens.push(String.fromCharCode.apply(String, str));
|
||||
token = '';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
token += String.fromCharCode(byte);
|
||||
token += String.fromCharCode(octet);
|
||||
}
|
||||
}
|
||||
}
|
||||
return charToUnicode;
|
||||
},
|
||||
readCidToGidMap:
|
||||
function partialEvaluatorReadCidToGidMap(cidToGidStream) {
|
||||
readCidToGidMap: function PartialEvaluator_readCidToGidMap(cidToGidStream) {
|
||||
// Extract the encoding from the CIDToGIDMap
|
||||
var glyphsData = cidToGidStream.getBytes();
|
||||
|
||||
|
@ -624,16 +672,16 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
return result;
|
||||
},
|
||||
|
||||
extractWidths: function partialEvaluatorWidths(dict,
|
||||
extractWidths: function PartialEvaluator_extractWidths(dict,
|
||||
xref,
|
||||
descriptor,
|
||||
properties) {
|
||||
var glyphsWidths = [];
|
||||
var defaultWidth = 0;
|
||||
if (properties.composite) {
|
||||
defaultWidth = xref.fetchIfRef(dict.get('DW')) || 1000;
|
||||
defaultWidth = dict.get('DW') || 1000;
|
||||
|
||||
var widths = xref.fetchIfRef(dict.get('W'));
|
||||
var widths = dict.get('W');
|
||||
if (widths) {
|
||||
var start = 0, end = 0;
|
||||
for (var i = 0, ii = widths.length; i < ii; i++) {
|
||||
|
@ -654,7 +702,7 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
}
|
||||
} else {
|
||||
var firstChar = properties.firstChar;
|
||||
var widths = xref.fetchIfRef(dict.get('Widths'));
|
||||
var widths = dict.get('Widths');
|
||||
if (widths) {
|
||||
var j = firstChar;
|
||||
for (var i = 0, ii = widths.length; i < ii; i++)
|
||||
|
@ -676,7 +724,7 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
properties.widths = glyphsWidths;
|
||||
},
|
||||
|
||||
getBaseFontMetrics: function getBaseFontMetrics(name) {
|
||||
getBaseFontMetrics: function PartialEvaluator_getBaseFontMetrics(name) {
|
||||
var defaultWidth = 0, widths = [];
|
||||
var glyphWidths = Metrics[stdFontMap[name] || name];
|
||||
if (isNum(glyphWidths)) {
|
||||
|
@ -691,8 +739,10 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
};
|
||||
},
|
||||
|
||||
translateFont: function partialEvaluatorTranslateFont(dict, xref, resources,
|
||||
dependency) {
|
||||
translateFont: function PartialEvaluator_translateFont(dict,
|
||||
xref,
|
||||
resources,
|
||||
dependency) {
|
||||
var baseDict = dict;
|
||||
var type = dict.get('Subtype');
|
||||
assertWellFormed(isName(type), 'invalid font Subtype');
|
||||
|
@ -707,10 +757,7 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
if (!df)
|
||||
return null;
|
||||
|
||||
if (isRef(df))
|
||||
df = xref.fetch(df);
|
||||
|
||||
dict = xref.fetchIfRef(isRef(df) ? df : df[0]);
|
||||
dict = isArray(df) ? xref.fetchIfRef(df[0]) : df;
|
||||
|
||||
type = dict.get('Subtype');
|
||||
assertWellFormed(isName(type), 'invalid font Subtype');
|
||||
|
@ -718,7 +765,7 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
}
|
||||
var maxCharIndex = composite ? 0xFFFF : 0xFF;
|
||||
|
||||
var descriptor = xref.fetchIfRef(dict.get('FontDescriptor'));
|
||||
var descriptor = dict.get('FontDescriptor');
|
||||
if (!descriptor) {
|
||||
if (type.name == 'Type3') {
|
||||
// FontDescriptor is only required for Type3 fonts when the document
|
||||
|
@ -737,10 +784,18 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
baseFontName = baseFontName.name.replace(/[,_]/g, '-');
|
||||
var metrics = this.getBaseFontMetrics(baseFontName);
|
||||
|
||||
// Simulating descriptor flags attribute
|
||||
var fontNameWoStyle = baseFontName.split('-')[0];
|
||||
var flags = (serifFonts[fontNameWoStyle] ||
|
||||
(fontNameWoStyle.search(/serif/gi) != -1) ? FontFlags.Serif : 0) |
|
||||
(symbolsFonts[fontNameWoStyle] ? FontFlags.Symbolic :
|
||||
FontFlags.Nonsymbolic);
|
||||
|
||||
var properties = {
|
||||
type: type.name,
|
||||
widths: metrics.widths,
|
||||
defaultWidth: metrics.defaultWidth,
|
||||
flags: flags,
|
||||
firstChar: 0,
|
||||
lastChar: maxCharIndex
|
||||
};
|
||||
|
@ -752,34 +807,31 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
properties: properties
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// According to the spec if 'FontDescriptor' is declared, 'FirstChar',
|
||||
// 'LastChar' and 'Widths' should exists too, but some PDF encoders seems
|
||||
// 'LastChar' and 'Widths' should exist too, but some PDF encoders seem
|
||||
// to ignore this rule when a variant of a standart font is used.
|
||||
// TODO Fill the width array depending on which of the base font this is
|
||||
// a variant.
|
||||
var firstChar = xref.fetchIfRef(dict.get('FirstChar')) || 0;
|
||||
var lastChar = xref.fetchIfRef(dict.get('LastChar')) || maxCharIndex;
|
||||
var fontName = xref.fetchIfRef(descriptor.get('FontName'));
|
||||
var firstChar = dict.get('FirstChar') || 0;
|
||||
var lastChar = dict.get('LastChar') || maxCharIndex;
|
||||
var fontName = descriptor.get('FontName');
|
||||
// Some bad pdf's have a string as the font name.
|
||||
if (isString(fontName))
|
||||
fontName = new Name(fontName);
|
||||
assertWellFormed(isName(fontName), 'invalid font name');
|
||||
|
||||
var fontFile = descriptor.get('FontFile', 'FontFile2', 'FontFile3');
|
||||
if (fontFile) {
|
||||
fontFile = xref.fetchIfRef(fontFile);
|
||||
if (fontFile.dict) {
|
||||
var subtype = fontFile.dict.get('Subtype');
|
||||
if (subtype)
|
||||
subtype = subtype.name;
|
||||
|
||||
var length1 = fontFile.dict.get('Length1');
|
||||
if (!isInt(length1))
|
||||
length1 = xref.fetchIfRef(length1);
|
||||
|
||||
var length2 = fontFile.dict.get('Length2');
|
||||
if (!isInt(length2))
|
||||
length2 = xref.fetchIfRef(length2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -808,15 +860,14 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
|
||||
if (type.name === 'Type3') {
|
||||
properties.coded = true;
|
||||
var charProcs = xref.fetchIfRef(dict.get('CharProcs'));
|
||||
var fontResources = xref.fetchIfRef(dict.get('Resources')) || resources;
|
||||
var charProcs = dict.get('CharProcs').getAll();
|
||||
var fontResources = dict.get('Resources') || resources;
|
||||
properties.resources = fontResources;
|
||||
properties.charProcIRQueues = {};
|
||||
for (var key in charProcs.map) {
|
||||
var glyphStream = xref.fetchIfRef(charProcs.map[key]);
|
||||
var queueObj = {};
|
||||
properties.charProcIRQueues[key] =
|
||||
this.getIRQueue(glyphStream, fontResources, queueObj, dependency);
|
||||
properties.charProcOperatorList = {};
|
||||
for (var key in charProcs) {
|
||||
var glyphStream = charProcs[key];
|
||||
properties.charProcOperatorList[key] =
|
||||
this.getOperatorList(glyphStream, fontResources, dependency);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -829,11 +880,11 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return PartialEvaluator;
|
||||
})();
|
||||
|
||||
var EvalState = (function evalState() {
|
||||
function constructor() {
|
||||
var EvalState = (function EvalStateClosure() {
|
||||
function EvalState() {
|
||||
// Are soft masks and alpha values shapes or opacities?
|
||||
this.alphaIsShape = false;
|
||||
this.fontSize = 0;
|
||||
|
@ -850,8 +901,8 @@ var EvalState = (function evalState() {
|
|||
this.fillColorSpace = null;
|
||||
this.strokeColorSpace = null;
|
||||
}
|
||||
constructor.prototype = {
|
||||
EvalState.prototype = {
|
||||
};
|
||||
return constructor;
|
||||
return EvalState;
|
||||
})();
|
||||
|
||||
|
|
2859
apps/files_pdfviewer/js/pdfjs/src/fonts.js
Executable file → Normal file
729
apps/files_pdfviewer/js/pdfjs/src/function.js
Executable file → Normal file
|
@ -3,14 +3,14 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var PDFFunction = (function pdfFunction() {
|
||||
var PDFFunction = (function PDFFunctionClosure() {
|
||||
var CONSTRUCT_SAMPLED = 0;
|
||||
var CONSTRUCT_INTERPOLATED = 2;
|
||||
var CONSTRUCT_STICHED = 3;
|
||||
var CONSTRUCT_POSTSCRIPT = 4;
|
||||
|
||||
return {
|
||||
getSampleArray: function pdfFunctionGetSampleArray(size, outputSize, bps,
|
||||
getSampleArray: function PDFFunction_getSampleArray(size, outputSize, bps,
|
||||
str) {
|
||||
var length = 1;
|
||||
for (var i = 0, ii = size.length; i < ii; i++)
|
||||
|
@ -38,7 +38,7 @@ var PDFFunction = (function pdfFunction() {
|
|||
return array;
|
||||
},
|
||||
|
||||
getIR: function pdfFunctionGetIR(xref, fn) {
|
||||
getIR: function PDFFunction_getIR(xref, fn) {
|
||||
var dict = fn.dict;
|
||||
if (!dict)
|
||||
dict = fn;
|
||||
|
@ -57,7 +57,7 @@ var PDFFunction = (function pdfFunction() {
|
|||
return typeFn.call(this, fn, dict, xref);
|
||||
},
|
||||
|
||||
fromIR: function pdfFunctionFromIR(IR) {
|
||||
fromIR: function PDFFunction_fromIR(IR) {
|
||||
var type = IR[0];
|
||||
switch (type) {
|
||||
case CONSTRUCT_SAMPLED:
|
||||
|
@ -72,16 +72,16 @@ var PDFFunction = (function pdfFunction() {
|
|||
}
|
||||
},
|
||||
|
||||
parse: function pdfFunctionParse(xref, fn) {
|
||||
parse: function PDFFunction_parse(xref, fn) {
|
||||
var IR = this.getIR(xref, fn);
|
||||
return this.fromIR(IR);
|
||||
},
|
||||
|
||||
constructSampled: function pdfFunctionConstructSampled(str, dict) {
|
||||
constructSampled: function PDFFunction_constructSampled(str, dict) {
|
||||
function toMultiArray(arr) {
|
||||
var inputLength = arr.length;
|
||||
var outputLength = arr.length / 2;
|
||||
var out = new Array(outputLength);
|
||||
var out = [];
|
||||
var index = 0;
|
||||
for (var i = 0; i < inputLength; i += 2) {
|
||||
out[index] = [arr[i], arr[i + 1]];
|
||||
|
@ -125,114 +125,104 @@ var PDFFunction = (function pdfFunction() {
|
|||
else
|
||||
decode = toMultiArray(decode);
|
||||
|
||||
// Precalc the multipliers
|
||||
var inputMul = new Float64Array(inputSize);
|
||||
for (var i = 0; i < inputSize; ++i) {
|
||||
inputMul[i] = (encode[i][1] - encode[i][0]) /
|
||||
(domain[i][1] - domain[i][0]);
|
||||
}
|
||||
|
||||
var idxMul = new Int32Array(inputSize);
|
||||
idxMul[0] = outputSize;
|
||||
for (i = 1; i < inputSize; ++i) {
|
||||
idxMul[i] = idxMul[i - 1] * size[i - 1];
|
||||
}
|
||||
|
||||
var nSamples = outputSize;
|
||||
for (i = 0; i < inputSize; ++i)
|
||||
nSamples *= size[i];
|
||||
|
||||
var samples = this.getSampleArray(size, outputSize, bps, str);
|
||||
|
||||
return [
|
||||
CONSTRUCT_SAMPLED, inputSize, domain, encode, decode, samples, size,
|
||||
outputSize, bps, range, inputMul, idxMul, nSamples
|
||||
outputSize, Math.pow(2, bps) - 1, range
|
||||
];
|
||||
},
|
||||
|
||||
constructSampledFromIR: function pdfFunctionConstructSampledFromIR(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];
|
||||
var inputMul = IR[10];
|
||||
var idxMul = IR[11];
|
||||
var nSamples = IR[12];
|
||||
constructSampledFromIR: function PDFFunction_constructSampledFromIR(IR) {
|
||||
// See chapter 3, page 109 of the PDF reference
|
||||
function interpolate(x, xmin, xmax, ymin, ymax) {
|
||||
return ymin + ((x - xmin) * ((ymax - ymin) / (xmax - xmin)));
|
||||
}
|
||||
|
||||
return function constructSampledFromIRResult(args) {
|
||||
if (inputSize != args.length)
|
||||
// See chapter 3, page 110 of the PDF reference.
|
||||
var m = IR[1];
|
||||
var domain = IR[2];
|
||||
var encode = IR[3];
|
||||
var decode = IR[4];
|
||||
var samples = IR[5];
|
||||
var size = IR[6];
|
||||
var n = IR[7];
|
||||
var mask = IR[8];
|
||||
var range = IR[9];
|
||||
|
||||
if (m != args.length)
|
||||
error('Incorrect number of arguments: ' + inputSize + ' != ' +
|
||||
args.length);
|
||||
// Most of the below is a port of Poppler's implementation.
|
||||
// TODO: There's a few other ways to do multilinear interpolation such
|
||||
// as piecewise, which is much faster but an approximation.
|
||||
var out = new Float64Array(outputSize);
|
||||
var x;
|
||||
var e = new Array(inputSize);
|
||||
var efrac0 = new Float64Array(inputSize);
|
||||
var efrac1 = new Float64Array(inputSize);
|
||||
var sBuf = new Float64Array(1 << inputSize);
|
||||
var i, j, k, idx, t;
|
||||
|
||||
// map input values into sample array
|
||||
for (i = 0; i < inputSize; ++i) {
|
||||
x = (args[i] - domain[i][0]) * inputMul[i] + encode[i][0];
|
||||
if (x < 0) {
|
||||
x = 0;
|
||||
} else if (x > size[i] - 1) {
|
||||
x = size[i] - 1;
|
||||
}
|
||||
e[i] = [Math.floor(x), 0];
|
||||
if ((e[i][1] = e[i][0] + 1) >= size[i]) {
|
||||
// this happens if in[i] = domain[i][1]
|
||||
e[i][1] = e[i][0];
|
||||
}
|
||||
efrac1[i] = x - e[i][0];
|
||||
efrac0[i] = 1 - efrac1[i];
|
||||
}
|
||||
var x = args;
|
||||
|
||||
// for each output, do m-linear interpolation
|
||||
for (i = 0; i < outputSize; ++i) {
|
||||
// Building the cube vertices: its part and sample index
|
||||
// http://rjwagner49.com/Mathematics/Interpolation.pdf
|
||||
var cubeVertices = 1 << m;
|
||||
var cubeN = new Float64Array(cubeVertices);
|
||||
var cubeVertex = new Uint32Array(cubeVertices);
|
||||
for (var j = 0; j < cubeVertices; j++)
|
||||
cubeN[j] = 1;
|
||||
|
||||
// pull 2^m values out of the sample array
|
||||
for (j = 0; j < (1 << inputSize); ++j) {
|
||||
idx = i;
|
||||
for (k = 0, t = j; k < inputSize; ++k, t >>= 1) {
|
||||
idx += idxMul[k] * (e[k][t & 1]);
|
||||
}
|
||||
if (idx >= 0 && idx < nSamples) {
|
||||
sBuf[j] = samples[idx];
|
||||
var k = n, pos = 1;
|
||||
// Map x_i to y_j for 0 <= i < m using the sampled function.
|
||||
for (var i = 0; i < m; ++i) {
|
||||
// x_i' = min(max(x_i, Domain_2i), Domain_2i+1)
|
||||
var domain_2i = domain[i][0];
|
||||
var domain_2i_1 = domain[i][1];
|
||||
var xi = Math.min(Math.max(x[i], domain_2i), domain_2i_1);
|
||||
|
||||
// e_i = Interpolate(x_i', Domain_2i, Domain_2i+1,
|
||||
// Encode_2i, Encode_2i+1)
|
||||
var e = interpolate(xi, domain_2i, domain_2i_1,
|
||||
encode[i][0], encode[i][1]);
|
||||
|
||||
// e_i' = min(max(e_i, 0), Size_i - 1)
|
||||
var size_i = size[i];
|
||||
e = Math.min(Math.max(e, 0), size_i - 1);
|
||||
|
||||
// Adjusting the cube: N and vertex sample index
|
||||
var e0 = e < size_i - 1 ? Math.floor(e) : e - 1; // e1 = e0 + 1;
|
||||
var n0 = e0 + 1 - e; // (e1 - e) / (e1 - e0);
|
||||
var n1 = e - e0; // (e - e0) / (e1 - e0);
|
||||
var offset0 = e0 * k;
|
||||
var offset1 = offset0 + k; // e1 * k
|
||||
for (var j = 0; j < cubeVertices; j++) {
|
||||
if (j & pos) {
|
||||
cubeN[j] *= n1;
|
||||
cubeVertex[j] += offset1;
|
||||
} else {
|
||||
sBuf[j] = 0; // TODO Investigate if this is what Adobe does
|
||||
cubeN[j] *= n0;
|
||||
cubeVertex[j] += offset0;
|
||||
}
|
||||
}
|
||||
|
||||
// do m sets of interpolations
|
||||
for (j = 0, t = (1 << inputSize); j < inputSize; ++j, t >>= 1) {
|
||||
for (k = 0; k < t; k += 2) {
|
||||
sBuf[k >> 1] = efrac0[j] * sBuf[k] + efrac1[j] * sBuf[k + 1];
|
||||
}
|
||||
}
|
||||
|
||||
// map output value to range
|
||||
out[i] = (sBuf[0] * (decode[i][1] - decode[i][0]) + decode[i][0]);
|
||||
if (out[i] < range[i][0]) {
|
||||
out[i] = range[i][0];
|
||||
} else if (out[i] > range[i][1]) {
|
||||
out[i] = range[i][1];
|
||||
}
|
||||
k *= size_i;
|
||||
pos <<= 1;
|
||||
}
|
||||
return out;
|
||||
|
||||
var y = new Float64Array(n);
|
||||
for (var j = 0; j < n; ++j) {
|
||||
// Sum all cube vertices' samples portions
|
||||
var rj = 0;
|
||||
for (var i = 0; i < cubeVertices; i++)
|
||||
rj += samples[cubeVertex[i] + j] * cubeN[i];
|
||||
|
||||
// r_j' = Interpolate(r_j, 0, 2^BitsPerSample - 1,
|
||||
// Decode_2j, Decode_2j+1)
|
||||
rj = interpolate(rj, 0, 1, decode[j][0], decode[j][1]);
|
||||
|
||||
// y_j = min(max(r_j, range_2j), range_2j+1)
|
||||
y[j] = Math.min(Math.max(rj, range[j][0]), range[j][1]);
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
},
|
||||
|
||||
constructInterpolated:
|
||||
function pdfFunctionConstructInterpolated(str, dict) {
|
||||
constructInterpolated: function PDFFunction_constructInterpolated(str,
|
||||
dict) {
|
||||
var c0 = dict.get('C0') || [0];
|
||||
var c1 = dict.get('C1') || [1];
|
||||
var n = dict.get('N');
|
||||
|
@ -249,7 +239,7 @@ var PDFFunction = (function pdfFunction() {
|
|||
},
|
||||
|
||||
constructInterpolatedFromIR:
|
||||
function pdfFunctionconstructInterpolatedFromIR(IR) {
|
||||
function PDFFunction_constructInterpolatedFromIR(IR) {
|
||||
var c0 = IR[1];
|
||||
var diff = IR[2];
|
||||
var n = IR[3];
|
||||
|
@ -268,9 +258,8 @@ var PDFFunction = (function pdfFunction() {
|
|||
}
|
||||
},
|
||||
|
||||
constructStiched: function pdfFunctionConstructStiched(fn, dict, xref) {
|
||||
constructStiched: function PDFFunction_constructStiched(fn, dict, xref) {
|
||||
var domain = dict.get('Domain');
|
||||
var range = dict.get('Range');
|
||||
|
||||
if (!domain)
|
||||
error('No domain');
|
||||
|
@ -290,7 +279,7 @@ var PDFFunction = (function pdfFunction() {
|
|||
return [CONSTRUCT_STICHED, domain, bounds, encode, fns];
|
||||
},
|
||||
|
||||
constructStichedFromIR: function pdfFunctionConstructStichedFromIR(IR) {
|
||||
constructStichedFromIR: function PDFFunction_constructStichedFromIR(IR) {
|
||||
var domain = IR[1];
|
||||
var bounds = IR[2];
|
||||
var encode = IR[3];
|
||||
|
@ -336,16 +325,550 @@ var PDFFunction = (function pdfFunction() {
|
|||
};
|
||||
},
|
||||
|
||||
constructPostScript: function pdfFunctionConstructPostScript() {
|
||||
return [CONSTRUCT_POSTSCRIPT];
|
||||
constructPostScript: function PDFFunction_constructPostScript(fn, dict,
|
||||
xref) {
|
||||
var domain = dict.get('Domain');
|
||||
var range = dict.get('Range');
|
||||
|
||||
if (!domain)
|
||||
error('No domain.');
|
||||
|
||||
if (!range)
|
||||
error('No range.');
|
||||
|
||||
var lexer = new PostScriptLexer(fn);
|
||||
var parser = new PostScriptParser(lexer);
|
||||
var code = parser.parse();
|
||||
|
||||
return [CONSTRUCT_POSTSCRIPT, domain, range, code];
|
||||
},
|
||||
|
||||
constructPostScriptFromIR: function pdfFunctionConstructPostScriptFromIR() {
|
||||
TODO('unhandled type of function');
|
||||
return function constructPostScriptFromIRResult() {
|
||||
return [255, 105, 180];
|
||||
constructPostScriptFromIR: function PDFFunction_constructPostScriptFromIR(
|
||||
IR) {
|
||||
var domain = IR[1];
|
||||
var range = IR[2];
|
||||
var code = IR[3];
|
||||
var numOutputs = range.length / 2;
|
||||
var evaluator = new PostScriptEvaluator(code);
|
||||
// Cache the values for a big speed up, the cache size is limited though
|
||||
// since the number of possible values can be huge from a PS function.
|
||||
var cache = new FunctionCache();
|
||||
return function constructPostScriptFromIRResult(args) {
|
||||
var initialStack = [];
|
||||
for (var i = 0, ii = (domain.length / 2); i < ii; ++i) {
|
||||
initialStack.push(args[i]);
|
||||
}
|
||||
|
||||
var key = initialStack.join('_');
|
||||
if (cache.has(key))
|
||||
return cache.get(key);
|
||||
|
||||
var stack = evaluator.execute(initialStack);
|
||||
var transformed = [];
|
||||
for (i = numOutputs - 1; i >= 0; --i) {
|
||||
var out = stack.pop();
|
||||
var rangeIndex = 2 * i;
|
||||
if (out < range[rangeIndex])
|
||||
out = range[rangeIndex];
|
||||
else if (out > range[rangeIndex + 1])
|
||||
out = range[rangeIndex + 1];
|
||||
transformed[i] = out;
|
||||
}
|
||||
cache.set(key, transformed);
|
||||
return transformed;
|
||||
};
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
var FunctionCache = (function FunctionCacheClosure() {
|
||||
// Of 10 PDF's with type4 functions the maxium number of distinct values seen
|
||||
// was 256. This still may need some tweaking in the future though.
|
||||
var MAX_CACHE_SIZE = 1024;
|
||||
function FunctionCache() {
|
||||
this.cache = {};
|
||||
this.total = 0;
|
||||
}
|
||||
FunctionCache.prototype = {
|
||||
has: function FunctionCache_has(key) {
|
||||
return key in this.cache;
|
||||
},
|
||||
get: function FunctionCache_get(key) {
|
||||
return this.cache[key];
|
||||
},
|
||||
set: function FunctionCache_set(key, value) {
|
||||
if (this.total < MAX_CACHE_SIZE) {
|
||||
this.cache[key] = value;
|
||||
this.total++;
|
||||
}
|
||||
}
|
||||
};
|
||||
return FunctionCache;
|
||||
})();
|
||||
|
||||
var PostScriptStack = (function PostScriptStackClosure() {
|
||||
var MAX_STACK_SIZE = 100;
|
||||
function PostScriptStack(initialStack) {
|
||||
this.stack = initialStack || [];
|
||||
}
|
||||
|
||||
PostScriptStack.prototype = {
|
||||
push: function PostScriptStack_push(value) {
|
||||
if (this.stack.length >= MAX_STACK_SIZE)
|
||||
error('PostScript function stack overflow.');
|
||||
this.stack.push(value);
|
||||
},
|
||||
pop: function PostScriptStack_pop() {
|
||||
if (this.stack.length <= 0)
|
||||
error('PostScript function stack underflow.');
|
||||
return this.stack.pop();
|
||||
},
|
||||
copy: function PostScriptStack_copy(n) {
|
||||
if (this.stack.length + n >= MAX_STACK_SIZE)
|
||||
error('PostScript function stack overflow.');
|
||||
var stack = this.stack;
|
||||
for (var i = stack.length - n, j = n - 1; j >= 0; j--, i++)
|
||||
stack.push(stack[i]);
|
||||
},
|
||||
index: function PostScriptStack_index(n) {
|
||||
this.push(this.stack[this.stack.length - n - 1]);
|
||||
},
|
||||
// rotate the last n stack elements p times
|
||||
roll: function PostScriptStack_roll(n, p) {
|
||||
var stack = this.stack;
|
||||
var l = stack.length - n;
|
||||
var r = stack.length - 1, c = l + (p - Math.floor(p / n) * n), i, j, t;
|
||||
for (i = l, j = r; i < j; i++, j--) {
|
||||
t = stack[i]; stack[i] = stack[j]; stack[j] = t;
|
||||
}
|
||||
for (i = l, j = c - 1; i < j; i++, j--) {
|
||||
t = stack[i]; stack[i] = stack[j]; stack[j] = t;
|
||||
}
|
||||
for (i = c, j = r; i < j; i++, j--) {
|
||||
t = stack[i]; stack[i] = stack[j]; stack[j] = t;
|
||||
}
|
||||
}
|
||||
};
|
||||
return PostScriptStack;
|
||||
})();
|
||||
var PostScriptEvaluator = (function PostScriptEvaluatorClosure() {
|
||||
function PostScriptEvaluator(operators, operands) {
|
||||
this.operators = operators;
|
||||
this.operands = operands;
|
||||
}
|
||||
PostScriptEvaluator.prototype = {
|
||||
execute: function PostScriptEvaluator_execute(initialStack) {
|
||||
var stack = new PostScriptStack(initialStack);
|
||||
var counter = 0;
|
||||
var operators = this.operators;
|
||||
var length = operators.length;
|
||||
var operator, a, b;
|
||||
while (counter < length) {
|
||||
operator = operators[counter++];
|
||||
if (typeof operator == 'number') {
|
||||
// Operator is really an operand and should be pushed to the stack.
|
||||
stack.push(operator);
|
||||
continue;
|
||||
}
|
||||
switch (operator) {
|
||||
// non standard ps operators
|
||||
case 'jz': // jump if false
|
||||
b = stack.pop();
|
||||
a = stack.pop();
|
||||
if (!a)
|
||||
counter = b;
|
||||
break;
|
||||
case 'j': // jump
|
||||
a = stack.pop();
|
||||
counter = a;
|
||||
break;
|
||||
|
||||
// all ps operators in alphabetical order (excluding if/ifelse)
|
||||
case 'abs':
|
||||
a = stack.pop();
|
||||
stack.push(Math.abs(a));
|
||||
break;
|
||||
case 'add':
|
||||
b = stack.pop();
|
||||
a = stack.pop();
|
||||
stack.push(a + b);
|
||||
break;
|
||||
case 'and':
|
||||
b = stack.pop();
|
||||
a = stack.pop();
|
||||
if (isBool(a) && isBool(b))
|
||||
stack.push(a && b);
|
||||
else
|
||||
stack.push(a & b);
|
||||
break;
|
||||
case 'atan':
|
||||
a = stack.pop();
|
||||
stack.push(Math.atan(a));
|
||||
break;
|
||||
case 'bitshift':
|
||||
b = stack.pop();
|
||||
a = stack.pop();
|
||||
if (a > 0)
|
||||
stack.push(a << b);
|
||||
else
|
||||
stack.push(a >> b);
|
||||
break;
|
||||
case 'ceiling':
|
||||
a = stack.pop();
|
||||
stack.push(Math.ceil(a));
|
||||
break;
|
||||
case 'copy':
|
||||
a = stack.pop();
|
||||
stack.copy(a);
|
||||
break;
|
||||
case 'cos':
|
||||
a = stack.pop();
|
||||
stack.push(Math.cos(a));
|
||||
break;
|
||||
case 'cvi':
|
||||
a = stack.pop() | 0;
|
||||
stack.push(a);
|
||||
break;
|
||||
case 'cvr':
|
||||
// noop
|
||||
break;
|
||||
case 'div':
|
||||
b = stack.pop();
|
||||
a = stack.pop();
|
||||
stack.push(a / b);
|
||||
break;
|
||||
case 'dup':
|
||||
stack.copy(1);
|
||||
break;
|
||||
case 'eq':
|
||||
b = stack.pop();
|
||||
a = stack.pop();
|
||||
stack.push(a == b);
|
||||
break;
|
||||
case 'exch':
|
||||
stack.roll(2, 1);
|
||||
break;
|
||||
case 'exp':
|
||||
b = stack.pop();
|
||||
a = stack.pop();
|
||||
stack.push(Math.pow(a, b));
|
||||
break;
|
||||
case 'false':
|
||||
stack.push(false);
|
||||
break;
|
||||
case 'floor':
|
||||
a = stack.pop();
|
||||
stack.push(Math.floor(a));
|
||||
break;
|
||||
case 'ge':
|
||||
b = stack.pop();
|
||||
a = stack.pop();
|
||||
stack.push(a >= b);
|
||||
break;
|
||||
case 'gt':
|
||||
b = stack.pop();
|
||||
a = stack.pop();
|
||||
stack.push(a > b);
|
||||
break;
|
||||
case 'idiv':
|
||||
b = stack.pop();
|
||||
a = stack.pop();
|
||||
stack.push((a / b) | 0);
|
||||
break;
|
||||
case 'index':
|
||||
a = stack.pop();
|
||||
stack.index(a);
|
||||
break;
|
||||
case 'le':
|
||||
b = stack.pop();
|
||||
a = stack.pop();
|
||||
stack.push(a <= b);
|
||||
break;
|
||||
case 'ln':
|
||||
a = stack.pop();
|
||||
stack.push(Math.log(a));
|
||||
break;
|
||||
case 'log':
|
||||
a = stack.pop();
|
||||
stack.push(Math.log(a) / Math.LN10);
|
||||
break;
|
||||
case 'lt':
|
||||
b = stack.pop();
|
||||
a = stack.pop();
|
||||
stack.push(a < b);
|
||||
break;
|
||||
case 'mod':
|
||||
b = stack.pop();
|
||||
a = stack.pop();
|
||||
stack.push(a % b);
|
||||
break;
|
||||
case 'mul':
|
||||
b = stack.pop();
|
||||
a = stack.pop();
|
||||
stack.push(a * b);
|
||||
break;
|
||||
case 'ne':
|
||||
b = stack.pop();
|
||||
a = stack.pop();
|
||||
stack.push(a != b);
|
||||
break;
|
||||
case 'neg':
|
||||
a = stack.pop();
|
||||
stack.push(-b);
|
||||
break;
|
||||
case 'not':
|
||||
a = stack.pop();
|
||||
if (isBool(a) && isBool(b))
|
||||
stack.push(a && b);
|
||||
else
|
||||
stack.push(a & b);
|
||||
break;
|
||||
case 'or':
|
||||
b = stack.pop();
|
||||
a = stack.pop();
|
||||
if (isBool(a) && isBool(b))
|
||||
stack.push(a || b);
|
||||
else
|
||||
stack.push(a | b);
|
||||
break;
|
||||
case 'pop':
|
||||
stack.pop();
|
||||
break;
|
||||
case 'roll':
|
||||
b = stack.pop();
|
||||
a = stack.pop();
|
||||
stack.roll(a, b);
|
||||
break;
|
||||
case 'round':
|
||||
a = stack.pop();
|
||||
stack.push(Math.round(a));
|
||||
break;
|
||||
case 'sin':
|
||||
a = stack.pop();
|
||||
stack.push(Math.sin(a));
|
||||
break;
|
||||
case 'sqrt':
|
||||
a = stack.pop();
|
||||
stack.push(Math.sqrt(a));
|
||||
break;
|
||||
case 'sub':
|
||||
b = stack.pop();
|
||||
a = stack.pop();
|
||||
stack.push(a - b);
|
||||
break;
|
||||
case 'true':
|
||||
stack.push(true);
|
||||
break;
|
||||
case 'truncate':
|
||||
a = stack.pop();
|
||||
a = a < 0 ? Math.ceil(a) : Math.floor(a);
|
||||
stack.push(a);
|
||||
break;
|
||||
case 'xor':
|
||||
b = stack.pop();
|
||||
a = stack.pop();
|
||||
if (isBool(a) && isBool(b))
|
||||
stack.push(a != b);
|
||||
else
|
||||
stack.push(a ^ b);
|
||||
break;
|
||||
default:
|
||||
error('Unknown operator ' + operator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return stack.stack;
|
||||
}
|
||||
};
|
||||
return PostScriptEvaluator;
|
||||
})();
|
||||
|
||||
var PostScriptParser = (function PostScriptParserClosure() {
|
||||
function PostScriptParser(lexer) {
|
||||
this.lexer = lexer;
|
||||
this.operators = [];
|
||||
this.token;
|
||||
this.prev;
|
||||
}
|
||||
PostScriptParser.prototype = {
|
||||
nextToken: function PostScriptParser_nextToken() {
|
||||
this.prev = this.token;
|
||||
this.token = this.lexer.getToken();
|
||||
},
|
||||
accept: function PostScriptParser_accept(type) {
|
||||
if (this.token.type == type) {
|
||||
this.nextToken();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
expect: function PostScriptParser_expect(type) {
|
||||
if (this.accept(type))
|
||||
return true;
|
||||
error('Unexpected symbol: found ' + this.token.type + ' expected ' +
|
||||
type + '.');
|
||||
},
|
||||
parse: function PostScriptParser_parse() {
|
||||
this.nextToken();
|
||||
this.expect(PostScriptTokenTypes.LBRACE);
|
||||
this.parseBlock();
|
||||
this.expect(PostScriptTokenTypes.RBRACE);
|
||||
return this.operators;
|
||||
},
|
||||
parseBlock: function PostScriptParser_parseBlock() {
|
||||
while (true) {
|
||||
if (this.accept(PostScriptTokenTypes.NUMBER)) {
|
||||
this.operators.push(this.prev.value);
|
||||
} else if (this.accept(PostScriptTokenTypes.OPERATOR)) {
|
||||
this.operators.push(this.prev.value);
|
||||
} else if (this.accept(PostScriptTokenTypes.LBRACE)) {
|
||||
this.parseCondition();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
parseCondition: function PostScriptParser_parseCondition() {
|
||||
// Add two place holders that will be updated later
|
||||
var conditionLocation = this.operators.length;
|
||||
this.operators.push(null, null);
|
||||
|
||||
this.parseBlock();
|
||||
this.expect(PostScriptTokenTypes.RBRACE);
|
||||
if (this.accept(PostScriptTokenTypes.IF)) {
|
||||
// The true block is right after the 'if' so it just falls through on
|
||||
// true else it jumps and skips the true block.
|
||||
this.operators[conditionLocation] = this.operators.length;
|
||||
this.operators[conditionLocation + 1] = 'jz';
|
||||
} else if (this.accept(PostScriptTokenTypes.LBRACE)) {
|
||||
var jumpLocation = this.operators.length;
|
||||
this.operators.push(null, null);
|
||||
var endOfTrue = this.operators.length;
|
||||
this.parseBlock();
|
||||
this.expect(PostScriptTokenTypes.RBRACE);
|
||||
this.expect(PostScriptTokenTypes.IFELSE);
|
||||
// The jump is added at the end of the true block to skip the false
|
||||
// block.
|
||||
this.operators[jumpLocation] = this.operators.length;
|
||||
this.operators[jumpLocation + 1] = 'j';
|
||||
|
||||
this.operators[conditionLocation] = endOfTrue;
|
||||
this.operators[conditionLocation + 1] = 'jz';
|
||||
} else {
|
||||
error('PS Function: error parsing conditional.');
|
||||
}
|
||||
}
|
||||
};
|
||||
return PostScriptParser;
|
||||
})();
|
||||
|
||||
var PostScriptTokenTypes = {
|
||||
LBRACE: 0,
|
||||
RBRACE: 1,
|
||||
NUMBER: 2,
|
||||
OPERATOR: 3,
|
||||
IF: 4,
|
||||
IFELSE: 5
|
||||
};
|
||||
|
||||
var PostScriptToken = (function PostScriptTokenClosure() {
|
||||
function PostScriptToken(type, value) {
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
var opCache = {};
|
||||
|
||||
PostScriptToken.getOperator = function PostScriptToken_getOperator(op) {
|
||||
var opValue = opCache[op];
|
||||
if (opValue)
|
||||
return opValue;
|
||||
|
||||
return opCache[op] = new PostScriptToken(PostScriptTokenTypes.OPERATOR, op);
|
||||
};
|
||||
|
||||
PostScriptToken.LBRACE = new PostScriptToken(PostScriptTokenTypes.LBRACE,
|
||||
'{');
|
||||
PostScriptToken.RBRACE = new PostScriptToken(PostScriptTokenTypes.RBRACE,
|
||||
'}');
|
||||
PostScriptToken.IF = new PostScriptToken(PostScriptTokenTypes.IF, 'IF');
|
||||
PostScriptToken.IFELSE = new PostScriptToken(PostScriptTokenTypes.IFELSE,
|
||||
'IFELSE');
|
||||
return PostScriptToken;
|
||||
})();
|
||||
|
||||
var PostScriptLexer = (function PostScriptLexerClosure() {
|
||||
function PostScriptLexer(stream) {
|
||||
this.stream = stream;
|
||||
}
|
||||
PostScriptLexer.prototype = {
|
||||
getToken: function PostScriptLexer_getToken() {
|
||||
var s = '';
|
||||
var ch;
|
||||
var comment = false;
|
||||
var stream = this.stream;
|
||||
|
||||
// skip comments
|
||||
while (true) {
|
||||
if (!(ch = stream.getChar()))
|
||||
return EOF;
|
||||
|
||||
if (comment) {
|
||||
if (ch == '\x0a' || ch == '\x0d')
|
||||
comment = false;
|
||||
} else if (ch == '%') {
|
||||
comment = true;
|
||||
} else if (!Lexer.isSpace(ch)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (ch) {
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
case '+': case '-': case '.':
|
||||
return new PostScriptToken(PostScriptTokenTypes.NUMBER,
|
||||
this.getNumber(ch));
|
||||
case '{':
|
||||
return PostScriptToken.LBRACE;
|
||||
case '}':
|
||||
return PostScriptToken.RBRACE;
|
||||
}
|
||||
// operator
|
||||
var str = ch.toLowerCase();
|
||||
while (true) {
|
||||
ch = stream.lookChar().toLowerCase();
|
||||
if (ch >= 'a' && ch <= 'z')
|
||||
str += ch;
|
||||
else
|
||||
break;
|
||||
stream.skip();
|
||||
}
|
||||
switch (str) {
|
||||
case 'if':
|
||||
return PostScriptToken.IF;
|
||||
case 'ifelse':
|
||||
return PostScriptToken.IFELSE;
|
||||
default:
|
||||
return PostScriptToken.getOperator(str);
|
||||
}
|
||||
},
|
||||
getNumber: function PostScriptLexer_getNumber(ch) {
|
||||
var str = ch;
|
||||
var stream = this.stream;
|
||||
while (true) {
|
||||
ch = stream.lookChar();
|
||||
if ((ch >= '0' && ch <= '9') || ch == '-' || ch == '.')
|
||||
str += ch;
|
||||
else
|
||||
break;
|
||||
stream.skip();
|
||||
}
|
||||
var value = parseFloat(str);
|
||||
if (isNaN(value))
|
||||
error('Invalid floating point number: ' + value);
|
||||
return value;
|
||||
}
|
||||
};
|
||||
return PostScriptLexer;
|
||||
})();
|
||||
|
||||
|
|
84
apps/files_pdfviewer/js/pdfjs/src/glyphlist.js
Executable file → Normal file
|
@ -1508,27 +1508,7 @@ var GlyphsUnicode = {
|
|||
dalet: 0x05D3,
|
||||
daletdagesh: 0xFB33,
|
||||
daletdageshhebrew: 0xFB33,
|
||||
dalethatafpatah: 0x05D305B2,
|
||||
dalethatafpatahhebrew: 0x05D305B2,
|
||||
dalethatafsegol: 0x05D305B1,
|
||||
dalethatafsegolhebrew: 0x05D305B1,
|
||||
dalethebrew: 0x05D3,
|
||||
dalethiriq: 0x05D305B4,
|
||||
dalethiriqhebrew: 0x05D305B4,
|
||||
daletholam: 0x05D305B9,
|
||||
daletholamhebrew: 0x05D305B9,
|
||||
daletpatah: 0x05D305B7,
|
||||
daletpatahhebrew: 0x05D305B7,
|
||||
daletqamats: 0x05D305B8,
|
||||
daletqamatshebrew: 0x05D305B8,
|
||||
daletqubuts: 0x05D305BB,
|
||||
daletqubutshebrew: 0x05D305BB,
|
||||
daletsegol: 0x05D305B6,
|
||||
daletsegolhebrew: 0x05D305B6,
|
||||
daletsheva: 0x05D305B0,
|
||||
daletshevahebrew: 0x05D305B0,
|
||||
dalettsere: 0x05D305B5,
|
||||
dalettserehebrew: 0x05D305B5,
|
||||
dalfinalarabic: 0xFEAA,
|
||||
dammaarabic: 0x064F,
|
||||
dammalowarabic: 0x064F,
|
||||
|
@ -1845,10 +1825,6 @@ var GlyphsUnicode = {
|
|||
finalkafdagesh: 0xFB3A,
|
||||
finalkafdageshhebrew: 0xFB3A,
|
||||
finalkafhebrew: 0x05DA,
|
||||
finalkafqamats: 0x05DA05B8,
|
||||
finalkafqamatshebrew: 0x05DA05B8,
|
||||
finalkafsheva: 0x05DA05B0,
|
||||
finalkafshevahebrew: 0x05DA05B0,
|
||||
finalmem: 0x05DD,
|
||||
finalmemhebrew: 0x05DD,
|
||||
finalnun: 0x05DF,
|
||||
|
@ -2037,14 +2013,7 @@ var GlyphsUnicode = {
|
|||
hakatakanahalfwidth: 0xFF8A,
|
||||
halantgurmukhi: 0x0A4D,
|
||||
hamzaarabic: 0x0621,
|
||||
hamzadammaarabic: 0x0621064F,
|
||||
hamzadammatanarabic: 0x0621064C,
|
||||
hamzafathaarabic: 0x0621064E,
|
||||
hamzafathatanarabic: 0x0621064B,
|
||||
hamzalowarabic: 0x0621,
|
||||
hamzalowkasraarabic: 0x06210650,
|
||||
hamzalowkasratanarabic: 0x0621064D,
|
||||
hamzasukunarabic: 0x06210652,
|
||||
hangulfiller: 0x3164,
|
||||
hardsigncyrillic: 0x044A,
|
||||
harpoonleftbarbup: 0x21BC,
|
||||
|
@ -2476,10 +2445,6 @@ var GlyphsUnicode = {
|
|||
lameddagesh: 0xFB3C,
|
||||
lameddageshhebrew: 0xFB3C,
|
||||
lamedhebrew: 0x05DC,
|
||||
lamedholam: 0x05DC05B9,
|
||||
lamedholamdagesh: '05DC 05B9 05BC',
|
||||
lamedholamdageshhebrew: '05DC 05B9 05BC',
|
||||
lamedholamhebrew: 0x05DC05B9,
|
||||
lamfinalarabic: 0xFEDE,
|
||||
lamhahinitialarabic: 0xFCCA,
|
||||
laminitialarabic: 0xFEDF,
|
||||
|
@ -2489,8 +2454,6 @@ var GlyphsUnicode = {
|
|||
lammedialarabic: 0xFEE0,
|
||||
lammeemhahinitialarabic: 0xFD88,
|
||||
lammeeminitialarabic: 0xFCCC,
|
||||
lammeemjeeminitialarabic: 'FEDF FEE4 FEA0',
|
||||
lammeemkhahinitialarabic: 'FEDF FEE4 FEA8',
|
||||
largecircle: 0x25EF,
|
||||
lbar: 0x019A,
|
||||
lbelt: 0x026C,
|
||||
|
@ -2787,7 +2750,6 @@ var GlyphsUnicode = {
|
|||
noonfinalarabic: 0xFEE6,
|
||||
noonghunnaarabic: 0x06BA,
|
||||
noonghunnafinalarabic: 0xFB9F,
|
||||
noonhehinitialarabic: 0xFEE7FEEC,
|
||||
nooninitialarabic: 0xFEE7,
|
||||
noonjeeminitialarabic: 0xFCD2,
|
||||
noonjeemisolatedarabic: 0xFC4B,
|
||||
|
@ -3159,27 +3121,7 @@ var GlyphsUnicode = {
|
|||
qof: 0x05E7,
|
||||
qofdagesh: 0xFB47,
|
||||
qofdageshhebrew: 0xFB47,
|
||||
qofhatafpatah: 0x05E705B2,
|
||||
qofhatafpatahhebrew: 0x05E705B2,
|
||||
qofhatafsegol: 0x05E705B1,
|
||||
qofhatafsegolhebrew: 0x05E705B1,
|
||||
qofhebrew: 0x05E7,
|
||||
qofhiriq: 0x05E705B4,
|
||||
qofhiriqhebrew: 0x05E705B4,
|
||||
qofholam: 0x05E705B9,
|
||||
qofholamhebrew: 0x05E705B9,
|
||||
qofpatah: 0x05E705B7,
|
||||
qofpatahhebrew: 0x05E705B7,
|
||||
qofqamats: 0x05E705B8,
|
||||
qofqamatshebrew: 0x05E705B8,
|
||||
qofqubuts: 0x05E705BB,
|
||||
qofqubutshebrew: 0x05E705BB,
|
||||
qofsegol: 0x05E705B6,
|
||||
qofsegolhebrew: 0x05E705B6,
|
||||
qofsheva: 0x05E705B0,
|
||||
qofshevahebrew: 0x05E705B0,
|
||||
qoftsere: 0x05E705B5,
|
||||
qoftserehebrew: 0x05E705B5,
|
||||
qparen: 0x24AC,
|
||||
quarternote: 0x2669,
|
||||
qubuts: 0x05BB,
|
||||
|
@ -3253,32 +3195,11 @@ var GlyphsUnicode = {
|
|||
reharmenian: 0x0580,
|
||||
rehfinalarabic: 0xFEAE,
|
||||
rehiragana: 0x308C,
|
||||
rehyehaleflamarabic: '0631 FEF3 FE8E 0644',
|
||||
rekatakana: 0x30EC,
|
||||
rekatakanahalfwidth: 0xFF9A,
|
||||
resh: 0x05E8,
|
||||
reshdageshhebrew: 0xFB48,
|
||||
reshhatafpatah: 0x05E805B2,
|
||||
reshhatafpatahhebrew: 0x05E805B2,
|
||||
reshhatafsegol: 0x05E805B1,
|
||||
reshhatafsegolhebrew: 0x05E805B1,
|
||||
reshhebrew: 0x05E8,
|
||||
reshhiriq: 0x05E805B4,
|
||||
reshhiriqhebrew: 0x05E805B4,
|
||||
reshholam: 0x05E805B9,
|
||||
reshholamhebrew: 0x05E805B9,
|
||||
reshpatah: 0x05E805B7,
|
||||
reshpatahhebrew: 0x05E805B7,
|
||||
reshqamats: 0x05E805B8,
|
||||
reshqamatshebrew: 0x05E805B8,
|
||||
reshqubuts: 0x05E805BB,
|
||||
reshqubutshebrew: 0x05E805BB,
|
||||
reshsegol: 0x05E805B6,
|
||||
reshsegolhebrew: 0x05E805B6,
|
||||
reshsheva: 0x05E805B0,
|
||||
reshshevahebrew: 0x05E805B0,
|
||||
reshtsere: 0x05E805B5,
|
||||
reshtserehebrew: 0x05E805B5,
|
||||
reversedtilde: 0x223D,
|
||||
reviahebrew: 0x0597,
|
||||
reviamugrashhebrew: 0x0597,
|
||||
|
@ -3477,7 +3398,6 @@ var GlyphsUnicode = {
|
|||
shaddadammaarabic: 0xFC61,
|
||||
shaddadammatanarabic: 0xFC5E,
|
||||
shaddafathaarabic: 0xFC60,
|
||||
shaddafathatanarabic: 0x0651064B,
|
||||
shaddakasraarabic: 0xFC62,
|
||||
shaddakasratanarabic: 0xFC5F,
|
||||
shade: 0x2592,
|
||||
|
@ -3674,7 +3594,6 @@ var GlyphsUnicode = {
|
|||
tchehfinalarabic: 0xFB7B,
|
||||
tchehinitialarabic: 0xFB7C,
|
||||
tchehmedialarabic: 0xFB7D,
|
||||
tchehmeeminitialarabic: 0xFB7CFEE4,
|
||||
tcircle: 0x24E3,
|
||||
tcircumflexbelow: 0x1E71,
|
||||
tcommaaccent: 0x0163,
|
||||
|
@ -4287,6 +4206,7 @@ var GlyphsUnicode = {
|
|||
zretroflexhook: 0x0290,
|
||||
zstroke: 0x01B6,
|
||||
zuhiragana: 0x305A,
|
||||
zukatakana: 0x30BA
|
||||
zukatakana: 0x30BA,
|
||||
'.notdef': 0x0000
|
||||
};
|
||||
|
||||
|
|
270
apps/files_pdfviewer/js/pdfjs/src/image.js
Executable file → Normal file
|
@ -3,8 +3,37 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var PDFImage = (function pdfImage() {
|
||||
function constructor(xref, res, image, inline) {
|
||||
var PDFImage = (function PDFImageClosure() {
|
||||
/**
|
||||
* Decode the image in the main thread if it supported. Resovles the promise
|
||||
* when the image data is ready.
|
||||
*/
|
||||
function handleImageData(handler, xref, res, image, promise) {
|
||||
if (image instanceof JpegStream && image.isNativelyDecodable(xref, res)) {
|
||||
// For natively supported jpegs send them to the main thread for decoding.
|
||||
var dict = image.dict;
|
||||
var colorSpace = dict.get('ColorSpace', 'CS');
|
||||
colorSpace = ColorSpace.parse(colorSpace, xref, res);
|
||||
var numComps = colorSpace.numComps;
|
||||
handler.send('jpeg_decode', [image.getIR(), numComps], function(message) {
|
||||
var data = message.data;
|
||||
var stream = new Stream(data, 0, data.length, image.dict);
|
||||
promise.resolve(stream);
|
||||
});
|
||||
} else {
|
||||
promise.resolve(image);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Decode and clamp a value. The formula is different from the spec because we
|
||||
* don't decode to float range [0,1], we decode it in the [0,max] range.
|
||||
*/
|
||||
function decodeAndClamp(value, addend, coefficient, max) {
|
||||
value = addend + value * coefficient;
|
||||
// Clamp the value to the range
|
||||
return value < 0 ? 0 : value > max ? max : value;
|
||||
}
|
||||
function PDFImage(xref, res, image, inline, smask) {
|
||||
this.image = image;
|
||||
if (image.getParams) {
|
||||
// JPX/JPEG2000 streams directly contain bits per component
|
||||
|
@ -49,34 +78,143 @@ var PDFImage = (function pdfImage() {
|
|||
}
|
||||
|
||||
this.decode = dict.get('Decode', 'D');
|
||||
this.needsDecode = false;
|
||||
if (this.decode && this.colorSpace &&
|
||||
!this.colorSpace.isDefaultDecode(this.decode)) {
|
||||
this.needsDecode = true;
|
||||
// Do some preprocessing to avoid more math.
|
||||
var max = (1 << bitsPerComponent) - 1;
|
||||
this.decodeCoefficients = [];
|
||||
this.decodeAddends = [];
|
||||
for (var i = 0, j = 0; i < this.decode.length; i += 2, ++j) {
|
||||
var dmin = this.decode[i];
|
||||
var dmax = this.decode[i + 1];
|
||||
this.decodeCoefficients[j] = dmax - dmin;
|
||||
this.decodeAddends[j] = max * dmin;
|
||||
}
|
||||
}
|
||||
|
||||
var mask = xref.fetchIfRef(dict.get('Mask'));
|
||||
var smask = xref.fetchIfRef(dict.get('SMask'));
|
||||
var mask = dict.get('Mask');
|
||||
|
||||
if (mask) {
|
||||
TODO('masked images');
|
||||
} else if (smask) {
|
||||
this.smask = new PDFImage(xref, res, smask);
|
||||
this.smask = new PDFImage(xref, res, smask, false);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Handles processing of image data and calls the callback with an argument
|
||||
* of a PDFImage when the image is ready to be used.
|
||||
*/
|
||||
PDFImage.buildImage = function PDFImage_buildImage(callback, handler, xref,
|
||||
res, image, inline) {
|
||||
var imageDataPromise = new Promise();
|
||||
var smaskPromise = new Promise();
|
||||
// The image data and smask data may not be ready yet, wait till both are
|
||||
// resolved.
|
||||
Promise.all([imageDataPromise, smaskPromise]).then(function(results) {
|
||||
var imageData = results[0], smaskData = results[1];
|
||||
var image = new PDFImage(xref, res, imageData, inline, smaskData);
|
||||
callback(image);
|
||||
});
|
||||
|
||||
constructor.prototype = {
|
||||
getComponents: function getComponents(buffer, decodeMap) {
|
||||
handleImageData(handler, xref, res, image, imageDataPromise);
|
||||
|
||||
var smask = image.dict.get('SMask');
|
||||
if (smask)
|
||||
handleImageData(handler, xref, res, smask, smaskPromise);
|
||||
else
|
||||
smaskPromise.resolve(null);
|
||||
};
|
||||
|
||||
/**
|
||||
* Resize an image using the nearest neighbor algorithm. Currently only
|
||||
* supports one and three component images.
|
||||
* @param {TypedArray} pixels The original image with one component.
|
||||
* @param {Number} bpc Number of bits per component.
|
||||
* @param {Number} components Number of color components, 1 or 3 is supported.
|
||||
* @param {Number} w1 Original width.
|
||||
* @param {Number} h1 Original height.
|
||||
* @param {Number} w2 New width.
|
||||
* @param {Number} h2 New height.
|
||||
* @return {TypedArray} Resized image data.
|
||||
*/
|
||||
PDFImage.resize = function PDFImage_resize(pixels, bpc, components,
|
||||
w1, h1, w2, h2) {
|
||||
var length = w2 * h2 * components;
|
||||
var temp = bpc <= 8 ? new Uint8Array(length) :
|
||||
bpc <= 16 ? new Uint16Array(length) : new Uint32Array(length);
|
||||
var xRatio = w1 / w2;
|
||||
var yRatio = h1 / h2;
|
||||
var px, py, newIndex, oldIndex;
|
||||
for (var i = 0; i < h2; i++) {
|
||||
for (var j = 0; j < w2; j++) {
|
||||
px = Math.floor(j * xRatio);
|
||||
py = Math.floor(i * yRatio);
|
||||
newIndex = (i * w2) + j;
|
||||
oldIndex = ((py * w1) + px);
|
||||
if (components === 1) {
|
||||
temp[newIndex] = pixels[oldIndex];
|
||||
} else if (components === 3) {
|
||||
newIndex *= 3;
|
||||
oldIndex *= 3;
|
||||
temp[newIndex] = pixels[oldIndex];
|
||||
temp[newIndex + 1] = pixels[oldIndex + 1];
|
||||
temp[newIndex + 2] = pixels[oldIndex + 2];
|
||||
}
|
||||
}
|
||||
}
|
||||
return temp;
|
||||
};
|
||||
|
||||
PDFImage.prototype = {
|
||||
get drawWidth() {
|
||||
if (!this.smask)
|
||||
return this.width;
|
||||
return Math.max(this.width, this.smask.width);
|
||||
},
|
||||
get drawHeight() {
|
||||
if (!this.smask)
|
||||
return this.height;
|
||||
return Math.max(this.height, this.smask.height);
|
||||
},
|
||||
getComponents: function PDFImage_getComponents(buffer) {
|
||||
var bpc = this.bpc;
|
||||
if (bpc == 8)
|
||||
var needsDecode = this.needsDecode;
|
||||
var decodeMap = this.decode;
|
||||
|
||||
// This image doesn't require any extra work.
|
||||
if (bpc == 8 && !needsDecode)
|
||||
return buffer;
|
||||
|
||||
var bufferLength = buffer.length;
|
||||
var width = this.width;
|
||||
var height = this.height;
|
||||
var numComps = this.numComps;
|
||||
|
||||
var length = width * height;
|
||||
var length = width * height * numComps;
|
||||
var bufferPos = 0;
|
||||
var output = bpc <= 8 ? new Uint8Array(length) :
|
||||
bpc <= 16 ? new Uint16Array(length) : new Uint32Array(length);
|
||||
var rowComps = width * numComps;
|
||||
var decodeAddends, decodeCoefficients;
|
||||
if (needsDecode) {
|
||||
decodeAddends = this.decodeAddends;
|
||||
decodeCoefficients = this.decodeCoefficients;
|
||||
}
|
||||
var max = (1 << bpc) - 1;
|
||||
|
||||
if (bpc == 1) {
|
||||
if (bpc == 8) {
|
||||
// Optimization for reading 8 bpc images that have a decode.
|
||||
for (var i = 0, ii = length; i < ii; ++i) {
|
||||
var compIndex = i % numComps;
|
||||
var value = buffer[i];
|
||||
value = decodeAndClamp(value, decodeAddends[compIndex],
|
||||
decodeCoefficients[compIndex], max);
|
||||
output[i] = value;
|
||||
}
|
||||
} else if (bpc == 1) {
|
||||
// Optimization for reading 1 bpc images.
|
||||
var valueZero = 0, valueOne = 1;
|
||||
if (decodeMap) {
|
||||
valueZero = decodeMap[0] ? 1 : 0;
|
||||
|
@ -101,8 +239,7 @@ var PDFImage = (function pdfImage() {
|
|||
output[i] = !(buf & mask) ? valueZero : valueOne;
|
||||
}
|
||||
} else {
|
||||
if (decodeMap != null)
|
||||
TODO('interpolate component values');
|
||||
// The general case that handles all other bpc values.
|
||||
var bits = 0, buf = 0;
|
||||
for (var i = 0, ii = length; i < ii; ++i) {
|
||||
if (i % rowComps == 0) {
|
||||
|
@ -116,51 +253,44 @@ var PDFImage = (function pdfImage() {
|
|||
}
|
||||
|
||||
var remainingBits = bits - bpc;
|
||||
output[i] = buf >> remainingBits;
|
||||
var value = buf >> remainingBits;
|
||||
if (needsDecode) {
|
||||
var compIndex = i % numComps;
|
||||
value = decodeAndClamp(value, decodeAddends[compIndex],
|
||||
decodeCoefficients[compIndex], max);
|
||||
}
|
||||
output[i] = value;
|
||||
buf = buf & ((1 << remainingBits) - 1);
|
||||
bits = remainingBits;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
},
|
||||
getOpacity: function getOpacity() {
|
||||
getOpacity: function PDFImage_getOpacity(width, height) {
|
||||
var smask = this.smask;
|
||||
var width = this.width;
|
||||
var height = this.height;
|
||||
var buf = new Uint8Array(width * height);
|
||||
var originalWidth = this.width;
|
||||
var originalHeight = this.height;
|
||||
var buf;
|
||||
|
||||
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);
|
||||
|
||||
buf = new Uint8Array(sw * sh);
|
||||
smask.fillGrayBuffer(buf);
|
||||
return buf;
|
||||
if (sw != width || sh != height)
|
||||
buf = PDFImage.resize(buf, smask.bps, 1, sw, sh, width, height);
|
||||
} else {
|
||||
buf = new Uint8Array(width * height);
|
||||
for (var i = 0, ii = width * height; i < ii; ++i)
|
||||
buf[i] = 255;
|
||||
}
|
||||
return buf;
|
||||
},
|
||||
applyStencilMask: function applyStencilMask(buffer, inverseDecode) {
|
||||
applyStencilMask: function PDFImage_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 imgArray = this.getImageBytes(bitStrideLength * height);
|
||||
var imgArrayPos = 0;
|
||||
var i, j, mask, buf;
|
||||
// removing making non-masked pixels transparent
|
||||
|
@ -180,21 +310,23 @@ var PDFImage = (function pdfImage() {
|
|||
}
|
||||
}
|
||||
},
|
||||
fillRgbaBuffer: function fillRgbaBuffer(buffer, decodeMap) {
|
||||
fillRgbaBuffer: function PDFImage_fillRgbaBuffer(buffer, width, height) {
|
||||
var numComps = this.numComps;
|
||||
var width = this.width;
|
||||
var height = this.height;
|
||||
var originalWidth = this.width;
|
||||
var originalHeight = 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 rowBytes = (originalWidth * numComps * bpc + 7) >> 3;
|
||||
var imgArray = this.getImageBytes(originalHeight * rowBytes);
|
||||
|
||||
var comps = this.colorSpace.getRgbBuffer(
|
||||
this.getComponents(imgArray, decodeMap), bpc);
|
||||
this.getComponents(imgArray), bpc);
|
||||
if (originalWidth != width || originalHeight != height)
|
||||
comps = PDFImage.resize(comps, this.bpc, 3, originalWidth,
|
||||
originalHeight, width, height);
|
||||
var compsPos = 0;
|
||||
var opacity = this.getOpacity();
|
||||
var opacity = this.getOpacity(width, height);
|
||||
var opacityPos = 0;
|
||||
var length = width * height * 4;
|
||||
|
||||
|
@ -205,7 +337,7 @@ var PDFImage = (function pdfImage() {
|
|||
buffer[i + 3] = opacity[opacityPos++];
|
||||
}
|
||||
},
|
||||
fillGrayBuffer: function fillGrayBuffer(buffer) {
|
||||
fillGrayBuffer: function PDFImage_fillGrayBuffer(buffer) {
|
||||
var numComps = this.numComps;
|
||||
if (numComps != 1)
|
||||
error('Reading gray scale from a color image: ' + numComps);
|
||||
|
@ -216,42 +348,28 @@ var PDFImage = (function pdfImage() {
|
|||
|
||||
// rows start at byte boundary;
|
||||
var rowBytes = (width * numComps * bpc + 7) >> 3;
|
||||
this.image.reset();
|
||||
var imgArray = this.image.getBytes(height * rowBytes);
|
||||
var imgArray = this.getImageBytes(height * rowBytes);
|
||||
|
||||
var comps = this.getComponents(imgArray);
|
||||
var length = width * height;
|
||||
|
||||
// we aren't using a colorspace so we need to scale the value
|
||||
var scale = 255 / ((1 << bpc) - 1);
|
||||
for (var i = 0; i < length; ++i)
|
||||
buffer[i] = comps[i];
|
||||
buffer[i] = (scale * comps[i]) | 0;
|
||||
},
|
||||
getImageBytes: function PDFImage_getImageBytes(length) {
|
||||
this.image.reset();
|
||||
return this.image.getBytes(length);
|
||||
}
|
||||
};
|
||||
return constructor;
|
||||
return PDFImage;
|
||||
})();
|
||||
|
||||
var JpegImageLoader = (function jpegImage() {
|
||||
function JpegImageLoader(objId, imageData, objs) {
|
||||
var src = 'data:image/jpeg;base64,' + window.btoa(imageData);
|
||||
|
||||
var img = new Image();
|
||||
img.onload = (function jpegImageLoaderOnload() {
|
||||
this.loaded = true;
|
||||
|
||||
objs.resolve(objId, this);
|
||||
|
||||
if (this.onLoad)
|
||||
this.onLoad();
|
||||
}).bind(this);
|
||||
img.src = src;
|
||||
this.domImage = img;
|
||||
}
|
||||
|
||||
JpegImageLoader.prototype = {
|
||||
getImage: function jpegImageLoaderGetImage() {
|
||||
return this.domImage;
|
||||
}
|
||||
};
|
||||
|
||||
return JpegImageLoader;
|
||||
})();
|
||||
function loadJpegStream(id, imageData, objs) {
|
||||
var img = new Image();
|
||||
img.onload = (function loadJpegStream_onloadClosure() {
|
||||
objs.resolve(id, img);
|
||||
});
|
||||
img.src = 'data:image/jpeg;base64,' + window.btoa(imageData);
|
||||
}
|
||||
|
||||
|
|
1862
apps/files_pdfviewer/js/pdfjs/src/jpx.js
Normal file
66
apps/files_pdfviewer/js/pdfjs/src/metadata.js
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* -*- 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 Metadata = PDFJS.Metadata = (function MetadataClosure() {
|
||||
function Metadata(meta) {
|
||||
if (typeof meta === 'string') {
|
||||
var parser = new DOMParser();
|
||||
meta = parser.parseFromString(meta, 'application/xml');
|
||||
} else if (!(meta instanceof Document)) {
|
||||
error('Metadata: Invalid metadata object');
|
||||
}
|
||||
|
||||
this.metaDocument = meta;
|
||||
this.metadata = {};
|
||||
this.parse();
|
||||
}
|
||||
|
||||
Metadata.prototype = {
|
||||
parse: function Metadata_parse() {
|
||||
var doc = this.metaDocument;
|
||||
var rdf = doc.documentElement;
|
||||
|
||||
if (rdf.nodeName.toLowerCase() !== 'rdf:rdf') { // Wrapped in <xmpmeta>
|
||||
rdf = rdf.firstChild;
|
||||
while (rdf && rdf.nodeName.toLowerCase() !== 'rdf:rdf')
|
||||
rdf = rdf.nextSibling;
|
||||
}
|
||||
|
||||
var nodeName = (rdf) ? rdf.nodeName.toLowerCase() : null;
|
||||
if (!rdf || nodeName !== 'rdf:rdf' || !rdf.hasChildNodes())
|
||||
return;
|
||||
|
||||
var childNodes = rdf.childNodes, desc, namespace, entries, entry;
|
||||
|
||||
for (var i = 0, length = childNodes.length; i < length; i++) {
|
||||
desc = childNodes[i];
|
||||
if (desc.nodeName.toLowerCase() !== 'rdf:description')
|
||||
continue;
|
||||
|
||||
entries = [];
|
||||
for (var ii = 0, iLength = desc.childNodes.length; ii < iLength; ii++) {
|
||||
if (desc.childNodes[ii].nodeName.toLowerCase() !== '#text')
|
||||
entries.push(desc.childNodes[ii]);
|
||||
}
|
||||
|
||||
for (ii = 0, iLength = entries.length; ii < iLength; ii++) {
|
||||
var entry = entries[ii];
|
||||
var name = entry.nodeName.toLowerCase();
|
||||
this.metadata[name] = entry.textContent.trim();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
get: function Metadata_get(name) {
|
||||
return this.metadata[name] || null;
|
||||
},
|
||||
|
||||
has: function Metadata_has(name) {
|
||||
return typeof this.metadata[name] !== 'undefined';
|
||||
}
|
||||
};
|
||||
|
||||
return Metadata;
|
||||
})();
|
3
apps/files_pdfviewer/js/pdfjs/src/metrics.js
Executable file → Normal file
|
@ -3,6 +3,9 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
// The Metrics object contains glyph widths (in glyph space units).
|
||||
// As per PDF spec, for most fonts (Type 3 being an exception) a glyph
|
||||
// space unit corresponds to 1/1000th of text space unit.
|
||||
var Metrics = {
|
||||
'Courier': 600,
|
||||
'Courier-Bold': 600,
|
||||
|
|
416
apps/files_pdfviewer/js/pdfjs/src/obj.js
Executable file → Normal file
|
@ -3,121 +3,157 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var Name = (function nameName() {
|
||||
function constructor(name) {
|
||||
var Name = (function NameClosure() {
|
||||
function Name(name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
};
|
||||
Name.prototype = {};
|
||||
|
||||
return constructor;
|
||||
return Name;
|
||||
})();
|
||||
|
||||
var Cmd = (function cmdCmd() {
|
||||
function constructor(cmd) {
|
||||
var Cmd = (function CmdClosure() {
|
||||
function Cmd(cmd) {
|
||||
this.cmd = cmd;
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
Cmd.prototype = {};
|
||||
|
||||
var cmdCache = {};
|
||||
|
||||
Cmd.get = function Cmd_get(cmd) {
|
||||
var cmdValue = cmdCache[cmd];
|
||||
if (cmdValue)
|
||||
return cmdValue;
|
||||
|
||||
return cmdCache[cmd] = new Cmd(cmd);
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return Cmd;
|
||||
})();
|
||||
|
||||
var Dict = (function dictDict() {
|
||||
function constructor() {
|
||||
var Dict = (function DictClosure() {
|
||||
// xref is optional
|
||||
function Dict(xref) {
|
||||
// Map should only be used internally, use functions below to access.
|
||||
this.map = Object.create(null);
|
||||
this.xref = xref;
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
get: function dictGet(key1, key2, key3) {
|
||||
Dict.prototype = {
|
||||
// automatically dereferences Ref objects
|
||||
get: function Dict_get(key1, key2, key3) {
|
||||
var value;
|
||||
var xref = this.xref;
|
||||
if (typeof (value = this.map[key1]) != 'undefined' || key1 in this.map ||
|
||||
typeof key2 == 'undefined') {
|
||||
return value;
|
||||
return xref ? this.xref.fetchIfRef(value) : value;
|
||||
}
|
||||
if (typeof (value = this.map[key2]) != 'undefined' || key2 in this.map ||
|
||||
typeof key3 == 'undefined') {
|
||||
return value;
|
||||
return xref ? this.xref.fetchIfRef(value) : value;
|
||||
}
|
||||
|
||||
return this.map[key3] || null;
|
||||
value = this.map[key3] || null;
|
||||
return xref ? this.xref.fetchIfRef(value) : value;
|
||||
},
|
||||
// no dereferencing
|
||||
getRaw: function Dict_getRaw(key) {
|
||||
return this.map[key];
|
||||
},
|
||||
// creates new map and dereferences all Refs
|
||||
getAll: function Dict_getAll() {
|
||||
var all = {};
|
||||
for (var key in this.map)
|
||||
all[key] = this.get(key);
|
||||
return all;
|
||||
},
|
||||
|
||||
set: function dictSet(key, value) {
|
||||
set: function Dict_set(key, value) {
|
||||
this.map[key] = value;
|
||||
},
|
||||
|
||||
has: function dictHas(key) {
|
||||
has: function Dict_has(key) {
|
||||
return key in this.map;
|
||||
},
|
||||
|
||||
forEach: function dictForEach(callback) {
|
||||
forEach: function Dict_forEach(callback) {
|
||||
for (var key in this.map) {
|
||||
callback(key, this.map[key]);
|
||||
callback(key, this.get(key));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return Dict;
|
||||
})();
|
||||
|
||||
var Ref = (function refRef() {
|
||||
function constructor(num, gen) {
|
||||
var Ref = (function RefClosure() {
|
||||
function Ref(num, gen) {
|
||||
this.num = num;
|
||||
this.gen = gen;
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
};
|
||||
Ref.prototype = {};
|
||||
|
||||
return constructor;
|
||||
return Ref;
|
||||
})();
|
||||
|
||||
// The reference is identified by number and generation,
|
||||
// this structure stores only one instance of the reference.
|
||||
var RefSet = (function refSet() {
|
||||
function constructor() {
|
||||
var RefSet = (function RefSetClosure() {
|
||||
function RefSet() {
|
||||
this.dict = {};
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
has: function refSetHas(ref) {
|
||||
RefSet.prototype = {
|
||||
has: function RefSet_has(ref) {
|
||||
return !!this.dict['R' + ref.num + '.' + ref.gen];
|
||||
},
|
||||
|
||||
put: function refSetPut(ref) {
|
||||
put: function RefSet_put(ref) {
|
||||
this.dict['R' + ref.num + '.' + ref.gen] = ref;
|
||||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return RefSet;
|
||||
})();
|
||||
|
||||
var Catalog = (function catalogCatalog() {
|
||||
function constructor(xref) {
|
||||
var Catalog = (function CatalogClosure() {
|
||||
function Catalog(xref) {
|
||||
this.xref = xref;
|
||||
var obj = xref.getCatalogObj();
|
||||
assertWellFormed(isDict(obj), 'catalog object is not a dictionary');
|
||||
this.catDict = obj;
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
Catalog.prototype = {
|
||||
get metadata() {
|
||||
var stream = this.catDict.get('Metadata');
|
||||
var metadata;
|
||||
if (stream && isDict(stream.dict)) {
|
||||
var type = stream.dict.get('Type');
|
||||
var subtype = stream.dict.get('Subtype');
|
||||
|
||||
if (isName(type) && isName(subtype) &&
|
||||
type.name === 'Metadata' && subtype.name === 'XML') {
|
||||
metadata = stringToPDFString(bytesToString(stream.getBytes()));
|
||||
}
|
||||
}
|
||||
|
||||
return shadow(this, 'metadata', metadata);
|
||||
},
|
||||
get toplevelPagesDict() {
|
||||
var pagesObj = this.catDict.get('Pages');
|
||||
assertWellFormed(isRef(pagesObj), 'invalid top-level pages reference');
|
||||
var xrefObj = this.xref.fetch(pagesObj);
|
||||
assertWellFormed(isDict(xrefObj), 'invalid top-level pages dictionary');
|
||||
assertWellFormed(isDict(pagesObj), 'invalid top-level pages dictionary');
|
||||
// shadow the prototype getter
|
||||
return shadow(this, 'toplevelPagesDict', xrefObj);
|
||||
return shadow(this, 'toplevelPagesDict', pagesObj);
|
||||
},
|
||||
get documentOutline() {
|
||||
var obj = this.catDict.get('Outlines');
|
||||
var xref = this.xref;
|
||||
var obj = this.catDict.get('Outlines');
|
||||
var root = { items: [] };
|
||||
if (isRef(obj)) {
|
||||
obj = xref.fetch(obj).get('First');
|
||||
if (isDict(obj)) {
|
||||
obj = obj.getRaw('First');
|
||||
var processed = new RefSet();
|
||||
if (isRef(obj)) {
|
||||
var queue = [{obj: obj, parent: root}];
|
||||
|
@ -126,18 +162,20 @@ var Catalog = (function catalogCatalog() {
|
|||
processed.put(obj);
|
||||
while (queue.length > 0) {
|
||||
var i = queue.shift();
|
||||
var outlineDict = xref.fetch(i.obj);
|
||||
var outlineDict = xref.fetchIfRef(i.obj);
|
||||
if (outlineDict === null)
|
||||
continue;
|
||||
if (!outlineDict.has('Title'))
|
||||
error('Invalid outline item');
|
||||
var dest = outlineDict.get('A');
|
||||
if (dest)
|
||||
dest = xref.fetchIfRef(dest).get('D');
|
||||
dest = dest.get('D');
|
||||
else if (outlineDict.has('Dest')) {
|
||||
dest = outlineDict.get('Dest');
|
||||
dest = outlineDict.getRaw('Dest');
|
||||
if (isName(dest))
|
||||
dest = dest.name;
|
||||
}
|
||||
var title = xref.fetchIfRef(outlineDict.get('Title'));
|
||||
var title = outlineDict.get('Title');
|
||||
var outlineItem = {
|
||||
dest: dest,
|
||||
title: stringToPDFString(title),
|
||||
|
@ -148,12 +186,12 @@ var Catalog = (function catalogCatalog() {
|
|||
items: []
|
||||
};
|
||||
i.parent.items.push(outlineItem);
|
||||
obj = outlineDict.get('First');
|
||||
obj = outlineDict.getRaw('First');
|
||||
if (isRef(obj) && !processed.has(obj)) {
|
||||
queue.push({obj: obj, parent: outlineItem});
|
||||
processed.put(obj);
|
||||
}
|
||||
obj = outlineDict.get('Next');
|
||||
obj = outlineDict.getRaw('Next');
|
||||
if (isRef(obj) && !processed.has(obj)) {
|
||||
queue.push({obj: obj, parent: i.parent});
|
||||
processed.put(obj);
|
||||
|
@ -173,7 +211,7 @@ var Catalog = (function catalogCatalog() {
|
|||
// shadow the prototype getter
|
||||
return shadow(this, 'num', obj);
|
||||
},
|
||||
traverseKids: function catalogTraverseKids(pagesDict) {
|
||||
traverseKids: function Catalog_traverseKids(pagesDict) {
|
||||
var pageCache = this.pageCache;
|
||||
var kids = pagesDict.get('Kids');
|
||||
assertWellFormed(isArray(kids),
|
||||
|
@ -181,7 +219,7 @@ var Catalog = (function catalogCatalog() {
|
|||
for (var i = 0, ii = kids.length; i < ii; ++i) {
|
||||
var kid = kids[i];
|
||||
assertWellFormed(isRef(kid),
|
||||
'page dictionary kid is not a reference');
|
||||
'page dictionary kid is not a reference');
|
||||
var obj = this.xref.fetch(kid);
|
||||
if (isDict(obj, 'Page') || (isDict(obj) && !obj.has('Kids'))) {
|
||||
pageCache.push(new Page(this.xref, pageCache.length, obj, kid));
|
||||
|
@ -195,8 +233,7 @@ var Catalog = (function catalogCatalog() {
|
|||
}
|
||||
},
|
||||
get destinations() {
|
||||
function fetchDestination(xref, ref) {
|
||||
var dest = xref.fetchIfRef(ref);
|
||||
function fetchDestination(dest) {
|
||||
return isDict(dest) ? dest.get('D') : dest;
|
||||
}
|
||||
|
||||
|
@ -204,16 +241,16 @@ var Catalog = (function catalogCatalog() {
|
|||
var dests = {}, nameTreeRef, nameDictionaryRef;
|
||||
var obj = this.catDict.get('Names');
|
||||
if (obj)
|
||||
nameTreeRef = xref.fetchIfRef(obj).get('Dests');
|
||||
nameTreeRef = obj.getRaw('Dests');
|
||||
else if (this.catDict.has('Dests'))
|
||||
nameDictionaryRef = this.catDict.get('Dests');
|
||||
|
||||
if (nameDictionaryRef) {
|
||||
// reading simple destination dictionary
|
||||
obj = xref.fetchIfRef(nameDictionaryRef);
|
||||
obj = nameDictionaryRef;
|
||||
obj.forEach(function catalogForEach(key, value) {
|
||||
if (!value) return;
|
||||
dests[key] = fetchDestination(xref, value);
|
||||
dests[key] = fetchDestination(value);
|
||||
});
|
||||
}
|
||||
if (nameTreeRef) {
|
||||
|
@ -237,13 +274,13 @@ var Catalog = (function catalogCatalog() {
|
|||
}
|
||||
var names = obj.get('Names');
|
||||
for (i = 0, n = names.length; i < n; i += 2) {
|
||||
dests[names[i]] = fetchDestination(xref, names[i + 1]);
|
||||
dests[names[i]] = fetchDestination(xref.fetchIfRef(names[i + 1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
return shadow(this, 'destinations', dests);
|
||||
},
|
||||
getPage: function catalogGetPage(n) {
|
||||
getPage: function Catalog_getPage(n) {
|
||||
var pageCache = this.pageCache;
|
||||
if (!pageCache) {
|
||||
pageCache = this.pageCache = [];
|
||||
|
@ -253,105 +290,101 @@ var Catalog = (function catalogCatalog() {
|
|||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return Catalog;
|
||||
})();
|
||||
|
||||
var XRef = (function xRefXRef() {
|
||||
function constructor(stream, startXRef, mainXRefEntriesOffset) {
|
||||
var XRef = (function XRefClosure() {
|
||||
function XRef(stream, startXRef, mainXRefEntriesOffset) {
|
||||
this.stream = stream;
|
||||
this.entries = [];
|
||||
this.xrefstms = {};
|
||||
var trailerDict = this.readXRef(startXRef);
|
||||
|
||||
trailerDict.xref = this;
|
||||
this.trailer = trailerDict;
|
||||
// prepare the XRef cache
|
||||
this.cache = [];
|
||||
|
||||
var encrypt = trailerDict.get('Encrypt');
|
||||
if (encrypt) {
|
||||
var fileId = trailerDict.get('ID');
|
||||
this.encrypt = new CipherTransformFactory(this.fetch(encrypt),
|
||||
this.encrypt = new CipherTransformFactory(encrypt,
|
||||
fileId[0] /*, password */);
|
||||
}
|
||||
|
||||
// get the root dictionary (catalog) object
|
||||
if (!isRef(this.root = trailerDict.get('Root')))
|
||||
if (!(this.root = trailerDict.get('Root')))
|
||||
error('Invalid root reference');
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
readXRefTable: function readXRefTable(parser) {
|
||||
XRef.prototype = {
|
||||
readXRefTable: function XRef_readXRefTable(parser) {
|
||||
// Example of cross-reference table:
|
||||
// xref
|
||||
// 0 1 <-- subsection header (first obj #, obj count)
|
||||
// 0000000000 65535 f <-- actual object (offset, generation #, f/n)
|
||||
// 23 2 <-- subsection header ... and so on ...
|
||||
// 0000025518 00002 n
|
||||
// 0000025635 00000 n
|
||||
// trailer
|
||||
// ...
|
||||
|
||||
// Outer loop is over subsection headers
|
||||
var obj;
|
||||
while (true) {
|
||||
if (isCmd(obj = parser.getObj(), 'trailer'))
|
||||
break;
|
||||
if (!isInt(obj))
|
||||
error('Invalid XRef table');
|
||||
var first = obj;
|
||||
if (!isInt(obj = parser.getObj()))
|
||||
error('Invalid XRef table');
|
||||
var n = obj;
|
||||
if (first < 0 || n < 0 || (first + n) != ((first + n) | 0))
|
||||
error('Invalid XRef table: ' + first + ', ' + n);
|
||||
for (var i = first; i < first + n; ++i) {
|
||||
while (!isCmd(obj = parser.getObj(), 'trailer')) {
|
||||
var first = obj,
|
||||
count = parser.getObj();
|
||||
|
||||
if (!isInt(first) || !isInt(count))
|
||||
error('Invalid XRef table: wrong types in subsection header');
|
||||
|
||||
// Inner loop is over objects themselves
|
||||
for (var i = 0; i < count; i++) {
|
||||
var entry = {};
|
||||
if (!isInt(obj = parser.getObj()))
|
||||
error('Invalid XRef table: ' + first + ', ' + n);
|
||||
entry.offset = obj;
|
||||
if (!isInt(obj = parser.getObj()))
|
||||
error('Invalid XRef table: ' + first + ', ' + n);
|
||||
entry.gen = obj;
|
||||
obj = parser.getObj();
|
||||
if (isCmd(obj, 'n')) {
|
||||
entry.uncompressed = true;
|
||||
} else if (isCmd(obj, 'f')) {
|
||||
entry.offset = parser.getObj();
|
||||
entry.gen = parser.getObj();
|
||||
var type = parser.getObj();
|
||||
|
||||
if (isCmd(type, 'f'))
|
||||
entry.free = true;
|
||||
} else {
|
||||
error('Invalid XRef table: ' + first + ', ' + n);
|
||||
}
|
||||
if (!this.entries[i]) {
|
||||
// In some buggy PDF files the xref table claims to start at 1
|
||||
// instead of 0.
|
||||
if (i == 1 && first == 1 &&
|
||||
entry.offset == 0 && entry.gen == 65535 && entry.free) {
|
||||
i = first = 0;
|
||||
}
|
||||
this.entries[i] = entry;
|
||||
else if (isCmd(type, 'n'))
|
||||
entry.uncompressed = true;
|
||||
|
||||
// Validate entry obj
|
||||
if (!isInt(entry.offset) || !isInt(entry.gen) ||
|
||||
!(entry.free || entry.uncompressed)) {
|
||||
error('Invalid entry in XRef subsection: ' + first + ', ' + count);
|
||||
}
|
||||
|
||||
if (!this.entries[i + first])
|
||||
this.entries[i + first] = entry;
|
||||
}
|
||||
}
|
||||
|
||||
// read the trailer dictionary
|
||||
var dict;
|
||||
if (!isDict(dict = parser.getObj()))
|
||||
error('Invalid XRef table');
|
||||
// Sanity check: as per spec, first object must have these properties
|
||||
if (this.entries[0] &&
|
||||
!(this.entries[0].gen === 65535 && this.entries[0].free))
|
||||
error('Invalid XRef table: unexpected first object');
|
||||
|
||||
// get the 'Prev' pointer
|
||||
var prev;
|
||||
obj = dict.get('Prev');
|
||||
if (isInt(obj)) {
|
||||
prev = obj;
|
||||
} else if (isRef(obj)) {
|
||||
// certain buggy PDF generators generate "/Prev NNN 0 R" instead
|
||||
// of "/Prev NNN"
|
||||
prev = obj.num;
|
||||
}
|
||||
if (prev) {
|
||||
this.readXRef(prev);
|
||||
}
|
||||
// Sanity check
|
||||
if (!isCmd(obj, 'trailer'))
|
||||
error('Invalid XRef table: could not find trailer dictionary');
|
||||
|
||||
// check for 'XRefStm' key
|
||||
if (isInt(obj = dict.get('XRefStm'))) {
|
||||
var pos = obj;
|
||||
// ignore previously loaded xref streams (possible infinite recursion)
|
||||
if (!(pos in this.xrefstms)) {
|
||||
this.xrefstms[pos] = 1;
|
||||
this.readXRef(pos);
|
||||
}
|
||||
}
|
||||
// Read trailer dictionary, e.g.
|
||||
// trailer
|
||||
// << /Size 22
|
||||
// /Root 20R
|
||||
// /Info 10R
|
||||
// /ID [ <81b14aafa313db63dbd6f981e49f94f4> ]
|
||||
// >>
|
||||
// The parser goes through the entire stream << ... >> and provides
|
||||
// a getter interface for the key-value table
|
||||
var dict = parser.getObj();
|
||||
if (!isDict(dict))
|
||||
error('Invalid XRef table: could not parse trailer dictionary');
|
||||
|
||||
return dict;
|
||||
},
|
||||
readXRefStream: function readXRefStream(stream) {
|
||||
readXRefStream: function XRef_readXRefStream(stream) {
|
||||
var streamParameters = stream.parameters;
|
||||
var byteWidths = streamParameters.get('W');
|
||||
var range = streamParameters.get('Index');
|
||||
|
@ -400,12 +433,9 @@ var XRef = (function xRefXRef() {
|
|||
}
|
||||
range.splice(0, 2);
|
||||
}
|
||||
var prev = streamParameters.get('Prev');
|
||||
if (isInt(prev))
|
||||
this.readXRef(prev);
|
||||
return streamParameters;
|
||||
},
|
||||
indexObjects: function indexObjects() {
|
||||
indexObjects: function XRef_indexObjects() {
|
||||
// Simple scan through the PDF content to find objects,
|
||||
// trailers and XRef streams.
|
||||
function readToken(data, offset) {
|
||||
|
@ -497,7 +527,7 @@ var XRef = (function xRefXRef() {
|
|||
var dict;
|
||||
for (var i = 0, ii = trailers.length; i < ii; ++i) {
|
||||
stream.pos = trailers[i];
|
||||
var parser = new Parser(new Lexer(stream), true);
|
||||
var parser = new Parser(new Lexer(stream), true, null);
|
||||
var obj = parser.getObj();
|
||||
if (!isCmd(obj, 'trailer'))
|
||||
continue;
|
||||
|
@ -513,50 +543,88 @@ var XRef = (function xRefXRef() {
|
|||
return dict;
|
||||
// nothing helps
|
||||
error('Invalid PDF structure');
|
||||
return null;
|
||||
},
|
||||
readXRef: function readXref(startXRef) {
|
||||
readXRef: function XRef_readXRef(startXRef) {
|
||||
var stream = this.stream;
|
||||
stream.pos = startXRef;
|
||||
var parser = new Parser(new Lexer(stream), true);
|
||||
var obj = parser.getObj();
|
||||
// parse an old-style xref table
|
||||
if (isCmd(obj, 'xref'))
|
||||
return this.readXRefTable(parser);
|
||||
// parse an xref stream
|
||||
if (isInt(obj)) {
|
||||
if (!isInt(parser.getObj()) ||
|
||||
!isCmd(parser.getObj(), 'obj') ||
|
||||
!isStream(obj = parser.getObj())) {
|
||||
error('Invalid XRef stream');
|
||||
|
||||
try {
|
||||
var parser = new Parser(new Lexer(stream), true, null);
|
||||
var obj = parser.getObj();
|
||||
var dict;
|
||||
|
||||
// Get dictionary
|
||||
if (isCmd(obj, 'xref')) {
|
||||
// Parse end-of-file XRef
|
||||
dict = this.readXRefTable(parser);
|
||||
|
||||
// Recursively get other XRefs 'XRefStm', if any
|
||||
obj = dict.get('XRefStm');
|
||||
if (isInt(obj)) {
|
||||
var pos = obj;
|
||||
// ignore previously loaded xref streams
|
||||
// (possible infinite recursion)
|
||||
if (!(pos in this.xrefstms)) {
|
||||
this.xrefstms[pos] = 1;
|
||||
this.readXRef(pos);
|
||||
}
|
||||
}
|
||||
} else if (isInt(obj)) {
|
||||
// Parse in-stream XRef
|
||||
if (!isInt(parser.getObj()) ||
|
||||
!isCmd(parser.getObj(), 'obj') ||
|
||||
!isStream(obj = parser.getObj())) {
|
||||
error('Invalid XRef stream');
|
||||
}
|
||||
dict = this.readXRefStream(obj);
|
||||
}
|
||||
return this.readXRefStream(obj);
|
||||
|
||||
// Recursively get previous dictionary, if any
|
||||
obj = dict.get('Prev');
|
||||
if (isInt(obj))
|
||||
this.readXRef(obj);
|
||||
else if (isRef(obj)) {
|
||||
// The spec says Prev must not be a reference, i.e. "/Prev NNN"
|
||||
// This is a fallback for non-compliant PDFs, i.e. "/Prev NNN 0 R"
|
||||
this.readXRef(obj.num);
|
||||
}
|
||||
|
||||
return dict;
|
||||
} catch (e) {
|
||||
log('(while reading XRef): ' + e);
|
||||
}
|
||||
|
||||
warn('Indexing all PDF objects');
|
||||
return this.indexObjects();
|
||||
},
|
||||
getEntry: function xRefGetEntry(i) {
|
||||
getEntry: function XRef_getEntry(i) {
|
||||
var e = this.entries[i];
|
||||
if (e.free)
|
||||
error('reading an XRef stream not implemented yet');
|
||||
return e;
|
||||
if (e === null)
|
||||
return null;
|
||||
return e.free ? null : e; // returns null is the entry is free
|
||||
},
|
||||
fetchIfRef: function xRefFetchIfRef(obj) {
|
||||
fetchIfRef: function XRef_fetchIfRef(obj) {
|
||||
if (!isRef(obj))
|
||||
return obj;
|
||||
return this.fetch(obj);
|
||||
},
|
||||
fetch: function xRefFetch(ref, suppressEncryption) {
|
||||
fetch: function XRef_fetch(ref, suppressEncryption) {
|
||||
assertWellFormed(isRef(ref), 'ref object is not a reference');
|
||||
var num = ref.num;
|
||||
var e = this.cache[num];
|
||||
if (e)
|
||||
return e;
|
||||
if (num in this.cache)
|
||||
return this.cache[num];
|
||||
|
||||
var e = this.getEntry(num);
|
||||
|
||||
// the referenced entry can be free
|
||||
if (e === null)
|
||||
return (this.cache[num] = e);
|
||||
|
||||
e = this.getEntry(num);
|
||||
var gen = ref.gen;
|
||||
var stream, parser;
|
||||
if (e.uncompressed) {
|
||||
if (e.gen != gen)
|
||||
throw ('inconsistent generation in XRef');
|
||||
error('inconsistent generation in XRef');
|
||||
stream = this.stream.makeSubStream(e.offset);
|
||||
parser = new Parser(new Lexer(stream), true, this);
|
||||
var obj1 = parser.getObj();
|
||||
|
@ -589,7 +657,7 @@ var XRef = (function xRefXRef() {
|
|||
e = parser.getObj();
|
||||
}
|
||||
// Don't cache streams since they are mutable (except images).
|
||||
if (!isStream(e) || e.getImage)
|
||||
if (!isStream(e) || e instanceof JpegStream)
|
||||
this.cache[num] = e;
|
||||
return e;
|
||||
}
|
||||
|
@ -603,7 +671,7 @@ var XRef = (function xRefXRef() {
|
|||
if (!isInt(first) || !isInt(n)) {
|
||||
error('invalid first and n parameters for ObjStm stream');
|
||||
}
|
||||
parser = new Parser(new Lexer(stream), false);
|
||||
parser = new Parser(new Lexer(stream), false, this);
|
||||
var i, entries = [], nums = [];
|
||||
// read the object numbers to populate cache
|
||||
for (i = 0; i < n; ++i) {
|
||||
|
@ -628,12 +696,12 @@ var XRef = (function xRefXRef() {
|
|||
}
|
||||
return e;
|
||||
},
|
||||
getCatalogObj: function xRefGetCatalogObj() {
|
||||
return this.fetch(this.root);
|
||||
getCatalogObj: function XRef_getCatalogObj() {
|
||||
return this.root;
|
||||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return XRef;
|
||||
})();
|
||||
|
||||
/**
|
||||
|
@ -642,7 +710,7 @@ var XRef = (function xRefXRef() {
|
|||
* inside of a worker. The `PDFObjects` implements some basic functions to
|
||||
* manage these objects.
|
||||
*/
|
||||
var PDFObjects = (function pdfObjects() {
|
||||
var PDFObjects = (function PDFObjectsClosure() {
|
||||
function PDFObjects() {
|
||||
this.objs = {};
|
||||
}
|
||||
|
@ -655,7 +723,7 @@ var PDFObjects = (function pdfObjects() {
|
|||
* Ensures there is an object defined for `objId`. Stores `data` on the
|
||||
* object *if* it is created.
|
||||
*/
|
||||
ensureObj: function pdfObjectsEnsureObj(objId, data) {
|
||||
ensureObj: function PDFObjects_ensureObj(objId, data) {
|
||||
if (this.objs[objId])
|
||||
return this.objs[objId];
|
||||
return this.objs[objId] = new Promise(objId, data);
|
||||
|
@ -670,7 +738,7 @@ var PDFObjects = (function pdfObjects() {
|
|||
* function and the object is already resolved, the callback gets called
|
||||
* right away.
|
||||
*/
|
||||
get: function pdfObjectsGet(objId, callback) {
|
||||
get: function PDFObjects_get(objId, callback) {
|
||||
// If there is a callback, then the get can be async and the object is
|
||||
// not required to be resolved right now
|
||||
if (callback) {
|
||||
|
@ -684,18 +752,16 @@ var PDFObjects = (function pdfObjects() {
|
|||
|
||||
// If there isn't an object yet or the object isn't resolved, then the
|
||||
// data isn't ready yet!
|
||||
if (!obj || !obj.isResolved) {
|
||||
throw 'Requesting object that isn\'t resolved yet ' + objId;
|
||||
return null;
|
||||
} else {
|
||||
return obj.data;
|
||||
}
|
||||
if (!obj || !obj.isResolved)
|
||||
error('Requesting object that isn\'t resolved yet ' + objId);
|
||||
|
||||
return obj.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Resolves the object `objId` with optional `data`.
|
||||
*/
|
||||
resolve: function pdfObjectsResolve(objId, data) {
|
||||
resolve: function PDFObjects_resolve(objId, data) {
|
||||
var objs = this.objs;
|
||||
|
||||
// In case there is a promise already on this object, just resolve it.
|
||||
|
@ -706,11 +772,11 @@ var PDFObjects = (function pdfObjects() {
|
|||
}
|
||||
},
|
||||
|
||||
onData: function pdfObjectsOnData(objId, callback) {
|
||||
onData: function PDFObjects_onData(objId, callback) {
|
||||
this.ensureObj(objId).onData(callback);
|
||||
},
|
||||
|
||||
isResolved: function pdfObjectsIsResolved(objId) {
|
||||
isResolved: function PDFObjects_isResolved(objId) {
|
||||
var objs = this.objs;
|
||||
if (!objs[objId]) {
|
||||
return false;
|
||||
|
@ -719,7 +785,7 @@ var PDFObjects = (function pdfObjects() {
|
|||
}
|
||||
},
|
||||
|
||||
hasData: function pdfObjectsHasData(objId) {
|
||||
hasData: function PDFObjects_hasData(objId) {
|
||||
var objs = this.objs;
|
||||
if (!objs[objId]) {
|
||||
return false;
|
||||
|
@ -731,7 +797,7 @@ var PDFObjects = (function pdfObjects() {
|
|||
/**
|
||||
* Sets the data of an object but *doesn't* resolve it.
|
||||
*/
|
||||
setData: function pdfObjectsSetData(objId, data) {
|
||||
setData: function PDFObjects_setData(objId, data) {
|
||||
// Watchout! If you call `this.ensureObj(objId, data)` you're going to
|
||||
// create a *resolved* promise which shouldn't be the case!
|
||||
this.ensureObj(objId).data = data;
|
||||
|
|
181
apps/files_pdfviewer/js/pdfjs/src/parser.js
Executable file → Normal file
|
@ -9,8 +9,8 @@ function isEOF(v) {
|
|||
return v == EOF;
|
||||
}
|
||||
|
||||
var Parser = (function parserParser() {
|
||||
function constructor(lexer, allowStreams, xref) {
|
||||
var Parser = (function ParserClosure() {
|
||||
function Parser(lexer, allowStreams, xref) {
|
||||
this.lexer = lexer;
|
||||
this.allowStreams = allowStreams;
|
||||
this.xref = xref;
|
||||
|
@ -18,12 +18,12 @@ var Parser = (function parserParser() {
|
|||
this.refill();
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
refill: function parserRefill() {
|
||||
Parser.prototype = {
|
||||
refill: function Parser_refill() {
|
||||
this.buf1 = this.lexer.getObj();
|
||||
this.buf2 = this.lexer.getObj();
|
||||
},
|
||||
shift: function parserShift() {
|
||||
shift: function Parser_shift() {
|
||||
if (isCmd(this.buf2, 'ID')) {
|
||||
this.buf1 = this.buf2;
|
||||
this.buf2 = null;
|
||||
|
@ -34,7 +34,7 @@ var Parser = (function parserParser() {
|
|||
this.buf2 = this.lexer.getObj();
|
||||
}
|
||||
},
|
||||
getObj: function parserGetObj(cipherTransform) {
|
||||
getObj: function Parser_getObj(cipherTransform) {
|
||||
if (isCmd(this.buf1, 'BI')) { // inline image
|
||||
this.shift();
|
||||
return this.makeInlineImage(cipherTransform);
|
||||
|
@ -51,17 +51,16 @@ var Parser = (function parserParser() {
|
|||
}
|
||||
if (isCmd(this.buf1, '<<')) { // dictionary or stream
|
||||
this.shift();
|
||||
var dict = new Dict();
|
||||
var dict = new Dict(this.xref);
|
||||
while (!isCmd(this.buf1, '>>') && !isEOF(this.buf1)) {
|
||||
if (!isName(this.buf1)) {
|
||||
if (!isName(this.buf1))
|
||||
error('Dictionary key must be a name object');
|
||||
} else {
|
||||
var key = this.buf1.name;
|
||||
this.shift();
|
||||
if (isEOF(this.buf1))
|
||||
break;
|
||||
dict.set(key, this.getObj(cipherTransform));
|
||||
}
|
||||
|
||||
var key = this.buf1.name;
|
||||
this.shift();
|
||||
if (isEOF(this.buf1))
|
||||
break;
|
||||
dict.set(key, this.getObj(cipherTransform));
|
||||
}
|
||||
if (isEOF(this.buf1))
|
||||
error('End of file inside dictionary');
|
||||
|
@ -99,38 +98,37 @@ var Parser = (function parserParser() {
|
|||
this.shift();
|
||||
return obj;
|
||||
},
|
||||
makeInlineImage: function parserMakeInlineImage(cipherTransform) {
|
||||
makeInlineImage: function Parser_makeInlineImage(cipherTransform) {
|
||||
var lexer = this.lexer;
|
||||
var stream = lexer.stream;
|
||||
|
||||
// parse dictionary
|
||||
var dict = new Dict();
|
||||
while (!isCmd(this.buf1, 'ID') && !isEOF(this.buf1)) {
|
||||
if (!isName(this.buf1)) {
|
||||
if (!isName(this.buf1))
|
||||
error('Dictionary key must be a name object');
|
||||
} else {
|
||||
var key = this.buf1.name;
|
||||
this.shift();
|
||||
if (isEOF(this.buf1))
|
||||
break;
|
||||
dict.set(key, this.getObj(cipherTransform));
|
||||
}
|
||||
|
||||
var key = this.buf1.name;
|
||||
this.shift();
|
||||
if (isEOF(this.buf1))
|
||||
break;
|
||||
dict.set(key, this.getObj(cipherTransform));
|
||||
}
|
||||
|
||||
// parse image stream
|
||||
var startPos = stream.pos;
|
||||
|
||||
// searching for the /\sEI\s/
|
||||
// searching for the /EI\s/
|
||||
var state = 0, ch;
|
||||
while (state != 4 && (ch = stream.getByte()) != null) {
|
||||
switch (ch) {
|
||||
case 0x20:
|
||||
case 0x0D:
|
||||
case 0x0A:
|
||||
state = state === 3 ? 4 : 1;
|
||||
state = state === 3 ? 4 : 0;
|
||||
break;
|
||||
case 0x45:
|
||||
state = state === 1 ? 2 : 0;
|
||||
state = 2;
|
||||
break;
|
||||
case 0x49:
|
||||
state = state === 2 ? 3 : 0;
|
||||
|
@ -157,12 +155,16 @@ var Parser = (function parserParser() {
|
|||
imageStream = this.filter(imageStream, dict, length);
|
||||
imageStream.parameters = dict;
|
||||
|
||||
this.buf2 = new Cmd('EI');
|
||||
this.buf2 = Cmd.get('EI');
|
||||
this.shift();
|
||||
|
||||
return imageStream;
|
||||
},
|
||||
makeStream: function parserMakeStream(dict, cipherTransform) {
|
||||
fetchIfRef: function Parser_fetchIfRef(obj) {
|
||||
// not relying on the xref.fetchIfRef -- xref might not be set
|
||||
return isRef(obj) ? this.xref.fetch(obj) : obj;
|
||||
},
|
||||
makeStream: function Parser_makeStream(dict, cipherTransform) {
|
||||
var lexer = this.lexer;
|
||||
var stream = lexer.stream;
|
||||
|
||||
|
@ -171,14 +173,9 @@ var Parser = (function parserParser() {
|
|||
var pos = stream.pos;
|
||||
|
||||
// get length
|
||||
var length = dict.get('Length');
|
||||
var xref = this.xref;
|
||||
if (xref)
|
||||
length = xref.fetchIfRef(length);
|
||||
if (!isInt(length)) {
|
||||
var length = this.fetchIfRef(dict.get('Length'));
|
||||
if (!isInt(length))
|
||||
error('Bad ' + length + ' attribute in stream');
|
||||
length = 0;
|
||||
}
|
||||
|
||||
// skip over the stream data
|
||||
stream.pos = pos + length;
|
||||
|
@ -195,9 +192,9 @@ var Parser = (function parserParser() {
|
|||
stream.parameters = dict;
|
||||
return stream;
|
||||
},
|
||||
filter: function parserFilter(stream, dict, length) {
|
||||
var filter = dict.get('Filter', 'F');
|
||||
var params = dict.get('DecodeParms', 'DP');
|
||||
filter: function Parser_filter(stream, dict, length) {
|
||||
var filter = this.fetchIfRef(dict.get('Filter', 'F'));
|
||||
var params = this.fetchIfRef(dict.get('DecodeParms', 'DP'));
|
||||
if (isName(filter))
|
||||
return this.makeFilter(stream, filter.name, length, params);
|
||||
if (isArray(filter)) {
|
||||
|
@ -207,25 +204,25 @@ var Parser = (function parserParser() {
|
|||
filter = filterArray[i];
|
||||
if (!isName(filter))
|
||||
error('Bad filter name: ' + filter);
|
||||
else {
|
||||
params = null;
|
||||
if (isArray(paramsArray) && (i in paramsArray))
|
||||
params = paramsArray[i];
|
||||
stream = this.makeFilter(stream, filter.name, length, params);
|
||||
// after the first stream the length variable is invalid
|
||||
length = null;
|
||||
}
|
||||
|
||||
params = null;
|
||||
if (isArray(paramsArray) && (i in paramsArray))
|
||||
params = paramsArray[i];
|
||||
stream = this.makeFilter(stream, filter.name, length, params);
|
||||
// after the first stream the length variable is invalid
|
||||
length = null;
|
||||
}
|
||||
}
|
||||
return stream;
|
||||
},
|
||||
makeFilter: function parserMakeFilter(stream, name, length, params) {
|
||||
makeFilter: function Parser_makeFilter(stream, name, length, params) {
|
||||
if (name == 'FlateDecode' || name == 'Fl') {
|
||||
if (params) {
|
||||
return new PredictorStream(new FlateStream(stream), params);
|
||||
}
|
||||
return new FlateStream(stream);
|
||||
} else if (name == 'LZWDecode' || name == 'LZW') {
|
||||
}
|
||||
if (name == 'LZWDecode' || name == 'LZW') {
|
||||
var earlyChange = 1;
|
||||
if (params) {
|
||||
if (params.has('EarlyChange'))
|
||||
|
@ -234,31 +231,41 @@ var Parser = (function parserParser() {
|
|||
new LZWStream(stream, earlyChange), params);
|
||||
}
|
||||
return new LZWStream(stream, earlyChange);
|
||||
} else if (name == 'DCTDecode' || name == 'DCT') {
|
||||
}
|
||||
if (name == 'DCTDecode' || name == 'DCT') {
|
||||
var bytes = stream.getBytes(length);
|
||||
return new JpegStream(bytes, stream.dict, this.xref);
|
||||
} else if (name == 'ASCII85Decode' || name == 'A85') {
|
||||
return new Ascii85Stream(stream);
|
||||
} else if (name == 'ASCIIHexDecode' || name == 'AHx') {
|
||||
return new AsciiHexStream(stream);
|
||||
} else if (name == 'CCITTFaxDecode' || name == 'CCF') {
|
||||
return new CCITTFaxStream(stream, params);
|
||||
} else {
|
||||
TODO('filter "' + name + '" not supported yet');
|
||||
}
|
||||
if (name == 'JPXDecode' || name == 'JPX') {
|
||||
var bytes = stream.getBytes(length);
|
||||
return new JpxStream(bytes, stream.dict);
|
||||
}
|
||||
if (name == 'ASCII85Decode' || name == 'A85') {
|
||||
return new Ascii85Stream(stream);
|
||||
}
|
||||
if (name == 'ASCIIHexDecode' || name == 'AHx') {
|
||||
return new AsciiHexStream(stream);
|
||||
}
|
||||
if (name == 'CCITTFaxDecode' || name == 'CCF') {
|
||||
return new CCITTFaxStream(stream, params);
|
||||
}
|
||||
if (name == 'RunLengthDecode') {
|
||||
return new RunLengthStream(stream);
|
||||
}
|
||||
warn('filter "' + name + '" not supported yet');
|
||||
return stream;
|
||||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return Parser;
|
||||
})();
|
||||
|
||||
var Lexer = (function lexer() {
|
||||
function constructor(stream) {
|
||||
var Lexer = (function LexerClosure() {
|
||||
function Lexer(stream) {
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
constructor.isSpace = function lexerIsSpace(ch) {
|
||||
Lexer.isSpace = function Lexer_isSpace(ch) {
|
||||
return ch == ' ' || ch == '\t' || ch == '\x0d' || ch == '\x0a';
|
||||
};
|
||||
|
||||
|
@ -292,8 +299,8 @@ var Lexer = (function lexer() {
|
|||
return -1;
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
getNumber: function lexerGetNumber(ch) {
|
||||
Lexer.prototype = {
|
||||
getNumber: function Lexer_getNumber(ch) {
|
||||
var floating = false;
|
||||
var str = ch;
|
||||
var stream = this.stream;
|
||||
|
@ -321,7 +328,7 @@ var Lexer = (function lexer() {
|
|||
error('Invalid floating point number: ' + value);
|
||||
return value;
|
||||
},
|
||||
getString: function lexerGetString() {
|
||||
getString: function Lexer_getString() {
|
||||
var numParen = 1;
|
||||
var done = false;
|
||||
var str = '';
|
||||
|
@ -405,7 +412,7 @@ var Lexer = (function lexer() {
|
|||
} while (!done);
|
||||
return str;
|
||||
},
|
||||
getName: function lexerGetName(ch) {
|
||||
getName: function Lexer_getName(ch) {
|
||||
var str = '';
|
||||
var stream = this.stream;
|
||||
while (!!(ch = stream.lookChar()) && !specialChars[ch.charCodeAt(0)]) {
|
||||
|
@ -432,7 +439,7 @@ var Lexer = (function lexer() {
|
|||
str.length);
|
||||
return new Name(str);
|
||||
},
|
||||
getHexString: function lexerGetHexString(ch) {
|
||||
getHexString: function Lexer_getHexString(ch) {
|
||||
var str = '';
|
||||
var stream = this.stream;
|
||||
for (;;) {
|
||||
|
@ -461,7 +468,7 @@ var Lexer = (function lexer() {
|
|||
}
|
||||
return str;
|
||||
},
|
||||
getObj: function lexerGetObj() {
|
||||
getObj: function Lexer_getObj() {
|
||||
// skip whitespace and comments
|
||||
var comment = false;
|
||||
var stream = this.stream;
|
||||
|
@ -492,14 +499,14 @@ var Lexer = (function lexer() {
|
|||
// array punctuation
|
||||
case '[':
|
||||
case ']':
|
||||
return new Cmd(ch);
|
||||
return Cmd.get(ch);
|
||||
// hex string or dict punctuation
|
||||
case '<':
|
||||
ch = stream.lookChar();
|
||||
if (ch == '<') {
|
||||
// dict punctuation
|
||||
stream.skip();
|
||||
return new Cmd('<<');
|
||||
return Cmd.get('<<');
|
||||
}
|
||||
return this.getHexString(ch);
|
||||
// dict punctuation
|
||||
|
@ -507,25 +514,23 @@ var Lexer = (function lexer() {
|
|||
ch = stream.lookChar();
|
||||
if (ch == '>') {
|
||||
stream.skip();
|
||||
return new Cmd('>>');
|
||||
return Cmd.get('>>');
|
||||
}
|
||||
case '{':
|
||||
case '}':
|
||||
return new Cmd(ch);
|
||||
return Cmd.get(ch);
|
||||
// fall through
|
||||
case ')':
|
||||
error('Illegal character: ' + ch);
|
||||
return Error;
|
||||
}
|
||||
|
||||
// command
|
||||
var str = ch;
|
||||
while (!!(ch = stream.lookChar()) && !specialChars[ch.charCodeAt(0)]) {
|
||||
stream.skip();
|
||||
if (str.length == 128) {
|
||||
if (str.length == 128)
|
||||
error('Command token too long: ' + str.length);
|
||||
break;
|
||||
}
|
||||
|
||||
str += ch;
|
||||
}
|
||||
if (str == 'true')
|
||||
|
@ -534,9 +539,9 @@ var Lexer = (function lexer() {
|
|||
return false;
|
||||
if (str == 'null')
|
||||
return null;
|
||||
return new Cmd(str);
|
||||
return Cmd.get(str);
|
||||
},
|
||||
skipToNextLine: function lexerSkipToNextLine() {
|
||||
skipToNextLine: function Lexer_skipToNextLine() {
|
||||
var stream = this.stream;
|
||||
while (true) {
|
||||
var ch = stream.getChar();
|
||||
|
@ -549,17 +554,17 @@ var Lexer = (function lexer() {
|
|||
}
|
||||
}
|
||||
},
|
||||
skip: function lexerSkip() {
|
||||
skip: function Lexer_skip() {
|
||||
this.stream.skip();
|
||||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return Lexer;
|
||||
})();
|
||||
|
||||
var Linearization = (function linearizationLinearization() {
|
||||
function constructor(stream) {
|
||||
this.parser = new Parser(new Lexer(stream), false);
|
||||
var Linearization = (function LinearizationClosure() {
|
||||
function Linearization(stream) {
|
||||
this.parser = new Parser(new Lexer(stream), false, null);
|
||||
var obj1 = this.parser.getObj();
|
||||
var obj2 = this.parser.getObj();
|
||||
var obj3 = this.parser.getObj();
|
||||
|
@ -572,8 +577,8 @@ var Linearization = (function linearizationLinearization() {
|
|||
}
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
getInt: function linearizationGetInt(name) {
|
||||
Linearization.prototype = {
|
||||
getInt: function Linearization_getInt(name) {
|
||||
var linDict = this.linDict;
|
||||
var obj;
|
||||
if (isDict(linDict) &&
|
||||
|
@ -582,9 +587,8 @@ var Linearization = (function linearizationLinearization() {
|
|||
return obj;
|
||||
}
|
||||
error('"' + name + '" field in linearization table is invalid');
|
||||
return 0;
|
||||
},
|
||||
getHint: function linearizationGetHint(index) {
|
||||
getHint: function Linearization_getHint(index) {
|
||||
var linDict = this.linDict;
|
||||
var obj1, obj2;
|
||||
if (isDict(linDict) &&
|
||||
|
@ -595,7 +599,6 @@ var Linearization = (function linearizationLinearization() {
|
|||
return obj2;
|
||||
}
|
||||
error('Hints table in linearization table is invalid: ' + index);
|
||||
return 0;
|
||||
},
|
||||
get length() {
|
||||
if (!isDict(this.linDict))
|
||||
|
@ -631,6 +634,6 @@ var Linearization = (function linearizationLinearization() {
|
|||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return Linearization;
|
||||
})();
|
||||
|
||||
|
|
148
apps/files_pdfviewer/js/pdfjs/src/pattern.js
Executable file → Normal file
|
@ -3,48 +3,53 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var Pattern = (function patternPattern() {
|
||||
var PatternType = {
|
||||
AXIAL: 2,
|
||||
RADIAL: 3
|
||||
};
|
||||
|
||||
var Pattern = (function PatternClosure() {
|
||||
// Constructor should define this.getPattern
|
||||
function constructor() {
|
||||
function Pattern() {
|
||||
error('should not call Pattern constructor');
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
Pattern.prototype = {
|
||||
// Input: current Canvas context
|
||||
// Output: the appropriate fillStyle or strokeStyle
|
||||
getPattern: function pattern_getStyle(ctx) {
|
||||
getPattern: function Pattern_getPattern(ctx) {
|
||||
error('Should not call Pattern.getStyle: ' + ctx);
|
||||
}
|
||||
};
|
||||
|
||||
constructor.shadingFromIR = function pattern_shadingFromIR(ctx, raw) {
|
||||
return Shadings[raw[0]].fromIR(ctx, raw);
|
||||
Pattern.shadingFromIR = function Pattern_shadingFromIR(raw) {
|
||||
return Shadings[raw[0]].fromIR(raw);
|
||||
};
|
||||
|
||||
constructor.parseShading = function pattern_shading(shading, matrix, xref,
|
||||
res, ctx) {
|
||||
Pattern.parseShading = function Pattern_parseShading(shading, matrix, xref,
|
||||
res) {
|
||||
|
||||
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);
|
||||
case PatternType.AXIAL:
|
||||
case PatternType.RADIAL:
|
||||
// Both radial and axial shadings are handled by RadialAxial shading.
|
||||
return new Shadings.RadialAxial(dict, matrix, xref, res);
|
||||
default:
|
||||
return new Shadings.Dummy();
|
||||
}
|
||||
};
|
||||
return constructor;
|
||||
return Pattern;
|
||||
})();
|
||||
|
||||
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) {
|
||||
Shadings.RadialAxial = (function RadialAxialClosure() {
|
||||
function RadialAxial(dict, matrix, xref, res, ctx) {
|
||||
this.matrix = matrix;
|
||||
this.coordsArr = dict.get('Coords');
|
||||
this.shadingType = dict.get('ShadingType');
|
||||
|
@ -74,10 +79,9 @@ Shadings.RadialAxial = (function radialAxialShading() {
|
|||
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))
|
||||
if (!isPDFFunction(fnObj))
|
||||
error('Invalid function');
|
||||
var fn = PDFFunction.parse(xref, fnObj);
|
||||
|
||||
|
@ -89,56 +93,60 @@ Shadings.RadialAxial = (function radialAxialShading() {
|
|||
|
||||
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]);
|
||||
var rgbColor = cs.getRgb(fn([i]));
|
||||
var cssColor = Util.makeCssRgb(rgbColor[0], rgbColor[1], rgbColor[2]);
|
||||
colorStops.push([(i - t0) / diff, cssColor]);
|
||||
}
|
||||
|
||||
this.colorStops = colorStops;
|
||||
}
|
||||
|
||||
constructor.fromIR = function radialAxialShadingGetIR(ctx, raw) {
|
||||
RadialAxial.fromIR = function RadialAxial_fromIR(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];
|
||||
return {
|
||||
type: 'Pattern',
|
||||
getPattern: function(ctx) {
|
||||
var curMatrix = ctx.mozCurrentTransform;
|
||||
if (curMatrix) {
|
||||
var userMatrix = ctx.mozCurrentTransformInverse;
|
||||
|
||||
var curMatrix = ctx.mozCurrentTransform;
|
||||
if (curMatrix) {
|
||||
var userMatrix = ctx.mozCurrentTransformInverse;
|
||||
p0 = Util.applyTransform(p0, curMatrix);
|
||||
p0 = Util.applyTransform(p0, userMatrix);
|
||||
|
||||
p0 = Util.applyTransform(p0, curMatrix);
|
||||
p0 = Util.applyTransform(p0, userMatrix);
|
||||
p1 = Util.applyTransform(p1, curMatrix);
|
||||
p1 = Util.applyTransform(p1, userMatrix);
|
||||
}
|
||||
|
||||
p1 = Util.applyTransform(p1, curMatrix);
|
||||
p1 = Util.applyTransform(p1, userMatrix);
|
||||
}
|
||||
var grad;
|
||||
if (type == PatternType.AXIAL)
|
||||
grad = ctx.createLinearGradient(p0[0], p0[1], p1[0], p1[1]);
|
||||
else if (type == PatternType.RADIAL)
|
||||
grad = ctx.createRadialGradient(p0[0], p0[1], r0, p1[0], p1[1], r1);
|
||||
|
||||
var grad;
|
||||
if (type == 2)
|
||||
grad = ctx.createLinearGradient(p0[0], p0[1], p1[0], p1[1]);
|
||||
else if (type == 3)
|
||||
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;
|
||||
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 radialAxialShadingGetIR() {
|
||||
RadialAxial.prototype = {
|
||||
getIR: function RadialAxial_getIR() {
|
||||
var coordsArr = this.coordsArr;
|
||||
var type = this.shadingType;
|
||||
if (type == 2) {
|
||||
if (type == PatternType.AXIAL) {
|
||||
var p0 = [coordsArr[0], coordsArr[1]];
|
||||
var p1 = [coordsArr[2], coordsArr[3]];
|
||||
var r0 = null;
|
||||
var r1 = null;
|
||||
} else if (type == 3) {
|
||||
} else if (type == PatternType.RADIAL) {
|
||||
var p0 = [coordsArr[0], coordsArr[1]];
|
||||
var p1 = [coordsArr[3], coordsArr[4]];
|
||||
var r0 = coordsArr[2];
|
||||
|
@ -157,31 +165,35 @@ Shadings.RadialAxial = (function radialAxialShading() {
|
|||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return RadialAxial;
|
||||
})();
|
||||
|
||||
Shadings.Dummy = (function dummyShading() {
|
||||
function constructor() {
|
||||
Shadings.Dummy = (function DummyClosure() {
|
||||
function Dummy() {
|
||||
this.type = 'Pattern';
|
||||
}
|
||||
|
||||
constructor.fromIR = function dummyShadingFromIR() {
|
||||
Dummy.fromIR = function Dummy_fromIR() {
|
||||
return 'hotpink';
|
||||
};
|
||||
|
||||
constructor.prototype = {
|
||||
getIR: function dummyShadingGetIR() {
|
||||
Dummy.prototype = {
|
||||
getIR: function Dummy_getIR() {
|
||||
return ['Dummy'];
|
||||
}
|
||||
};
|
||||
return constructor;
|
||||
return Dummy;
|
||||
})();
|
||||
|
||||
var TilingPattern = (function tilingPattern() {
|
||||
var PAINT_TYPE_COLORED = 1, PAINT_TYPE_UNCOLORED = 2;
|
||||
var TilingPattern = (function TilingPatternClosure() {
|
||||
var PaintType = {
|
||||
COLORED: 1,
|
||||
UNCOLORED: 2
|
||||
};
|
||||
var MAX_PATTERN_SIZE = 512;
|
||||
|
||||
function TilingPattern(IR, color, ctx, objs) {
|
||||
var IRQueue = IR[2];
|
||||
var operatorList = IR[2];
|
||||
this.matrix = IR[3];
|
||||
var bbox = IR[4];
|
||||
var xstep = IR[5];
|
||||
|
@ -204,30 +216,30 @@ var TilingPattern = (function tilingPattern() {
|
|||
var width = botRight[0] - topLeft[0];
|
||||
var height = botRight[1] - topLeft[1];
|
||||
|
||||
// TODO: hack to avoid OOM, we would idealy compute the tiling
|
||||
// TODO: hack to avoid OOM, we would ideally 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;
|
||||
while (Math.abs(width) > MAX_PATTERN_SIZE ||
|
||||
Math.abs(height) > MAX_PATTERN_SIZE) {
|
||||
width = height = MAX_PATTERN_SIZE;
|
||||
}
|
||||
|
||||
var tmpCanvas = new ScratchCanvas(width, height);
|
||||
var tmpCanvas = createScratchCanvas(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:
|
||||
case PaintType.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;
|
||||
case PaintType.UNCOLORED:
|
||||
var cssColor = Util.makeCssRgb(this, color[0], color[1], color[2]);
|
||||
tmpCtx.fillStyle = cssColor;
|
||||
tmpCtx.strokeStyle = cssColor;
|
||||
break;
|
||||
default:
|
||||
error('Unsupported paint type: ' + paintType);
|
||||
|
@ -250,12 +262,12 @@ var TilingPattern = (function tilingPattern() {
|
|||
graphics.endPath();
|
||||
}
|
||||
|
||||
graphics.executeIRQueue(IRQueue);
|
||||
graphics.executeOperatorList(operatorList);
|
||||
|
||||
this.canvas = tmpCanvas;
|
||||
}
|
||||
|
||||
TilingPattern.getIR = function tiling_getIR(codeIR, dict, args) {
|
||||
TilingPattern.getIR = function TilingPattern_getIR(operatorList, dict, args) {
|
||||
var matrix = dict.get('Matrix');
|
||||
var bbox = dict.get('BBox');
|
||||
var xstep = dict.get('XStep');
|
||||
|
@ -263,12 +275,12 @@ var TilingPattern = (function tilingPattern() {
|
|||
var paintType = dict.get('PaintType');
|
||||
|
||||
return [
|
||||
'TilingPattern', args, codeIR, matrix, bbox, xstep, ystep, paintType
|
||||
'TilingPattern', args, operatorList, matrix, bbox, xstep, ystep, paintType
|
||||
];
|
||||
};
|
||||
|
||||
TilingPattern.prototype = {
|
||||
getPattern: function tiling_getPattern() {
|
||||
getPattern: function TilingPattern_getPattern() {
|
||||
var matrix = this.matrix;
|
||||
var curMatrix = this.curMatrix;
|
||||
var ctx = this.ctx;
|
||||
|
|
0
apps/files_pdfviewer/js/pdfjs/src/pdf.js
Executable file → Normal file
487
apps/files_pdfviewer/js/pdfjs/src/stream.js
Executable file → Normal file
|
@ -3,8 +3,8 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var Stream = (function streamStream() {
|
||||
function constructor(arrayBuffer, start, length, dict) {
|
||||
var Stream = (function StreamClosure() {
|
||||
function Stream(arrayBuffer, start, length, dict) {
|
||||
this.bytes = new Uint8Array(arrayBuffer);
|
||||
this.start = start || 0;
|
||||
this.pos = this.start;
|
||||
|
@ -14,18 +14,18 @@ var Stream = (function streamStream() {
|
|||
|
||||
// required methods for a stream. if a particular stream does not
|
||||
// implement these, an error should be thrown
|
||||
constructor.prototype = {
|
||||
Stream.prototype = {
|
||||
get length() {
|
||||
return this.end - this.start;
|
||||
},
|
||||
getByte: function stream_getByte() {
|
||||
getByte: function Stream_getByte() {
|
||||
if (this.pos >= this.end)
|
||||
return null;
|
||||
return this.bytes[this.pos++];
|
||||
},
|
||||
// returns subarray of original buffer
|
||||
// should only be read
|
||||
getBytes: function stream_getBytes(length) {
|
||||
getBytes: function Stream_getBytes(length) {
|
||||
var bytes = this.bytes;
|
||||
var pos = this.pos;
|
||||
var strEnd = this.end;
|
||||
|
@ -40,38 +40,38 @@ var Stream = (function streamStream() {
|
|||
this.pos = end;
|
||||
return bytes.subarray(pos, end);
|
||||
},
|
||||
lookChar: function stream_lookChar() {
|
||||
lookChar: function Stream_lookChar() {
|
||||
if (this.pos >= this.end)
|
||||
return null;
|
||||
return String.fromCharCode(this.bytes[this.pos]);
|
||||
},
|
||||
getChar: function stream_getChar() {
|
||||
getChar: function Stream_getChar() {
|
||||
if (this.pos >= this.end)
|
||||
return null;
|
||||
return String.fromCharCode(this.bytes[this.pos++]);
|
||||
},
|
||||
skip: function stream_skip(n) {
|
||||
skip: function Stream_skip(n) {
|
||||
if (!n)
|
||||
n = 1;
|
||||
this.pos += n;
|
||||
},
|
||||
reset: function stream_reset() {
|
||||
reset: function Stream_reset() {
|
||||
this.pos = this.start;
|
||||
},
|
||||
moveStart: function stream_moveStart() {
|
||||
moveStart: function Stream_moveStart() {
|
||||
this.start = this.pos;
|
||||
},
|
||||
makeSubStream: function stream_makeSubstream(start, length, dict) {
|
||||
makeSubStream: function Stream_makeSubStream(start, length, dict) {
|
||||
return new Stream(this.bytes.buffer, start, length, dict);
|
||||
},
|
||||
isStream: true
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return Stream;
|
||||
})();
|
||||
|
||||
var StringStream = (function stringStream() {
|
||||
function constructor(str) {
|
||||
var StringStream = (function StringStreamClosure() {
|
||||
function StringStream(str) {
|
||||
var length = str.length;
|
||||
var bytes = new Uint8Array(length);
|
||||
for (var n = 0; n < length; ++n)
|
||||
|
@ -79,22 +79,22 @@ var StringStream = (function stringStream() {
|
|||
Stream.call(this, bytes);
|
||||
}
|
||||
|
||||
constructor.prototype = Stream.prototype;
|
||||
StringStream.prototype = Stream.prototype;
|
||||
|
||||
return constructor;
|
||||
return StringStream;
|
||||
})();
|
||||
|
||||
// super class for the decoding streams
|
||||
var DecodeStream = (function decodeStream() {
|
||||
function constructor() {
|
||||
var DecodeStream = (function DecodeStreamClosure() {
|
||||
function DecodeStream() {
|
||||
this.pos = 0;
|
||||
this.bufferLength = 0;
|
||||
this.eof = false;
|
||||
this.buffer = null;
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
ensureBuffer: function decodestream_ensureBuffer(requested) {
|
||||
DecodeStream.prototype = {
|
||||
ensureBuffer: function DecodeStream_ensureBuffer(requested) {
|
||||
var buffer = this.buffer;
|
||||
var current = buffer ? buffer.byteLength : 0;
|
||||
if (requested < current)
|
||||
|
@ -107,7 +107,7 @@ var DecodeStream = (function decodeStream() {
|
|||
buffer2[i] = buffer[i];
|
||||
return (this.buffer = buffer2);
|
||||
},
|
||||
getByte: function decodestream_getByte() {
|
||||
getByte: function DecodeStream_getByte() {
|
||||
var pos = this.pos;
|
||||
while (this.bufferLength <= pos) {
|
||||
if (this.eof)
|
||||
|
@ -116,7 +116,7 @@ var DecodeStream = (function decodeStream() {
|
|||
}
|
||||
return this.buffer[this.pos++];
|
||||
},
|
||||
getBytes: function decodestream_getBytes(length) {
|
||||
getBytes: function DecodeStream_getBytes(length) {
|
||||
var end, pos = this.pos;
|
||||
|
||||
if (length) {
|
||||
|
@ -144,7 +144,7 @@ var DecodeStream = (function decodeStream() {
|
|||
this.pos = end;
|
||||
return this.buffer.subarray(pos, end);
|
||||
},
|
||||
lookChar: function decodestream_lookChar() {
|
||||
lookChar: function DecodeStream_lookChar() {
|
||||
var pos = this.pos;
|
||||
while (this.bufferLength <= pos) {
|
||||
if (this.eof)
|
||||
|
@ -153,7 +153,7 @@ var DecodeStream = (function decodeStream() {
|
|||
}
|
||||
return String.fromCharCode(this.buffer[this.pos]);
|
||||
},
|
||||
getChar: function decodestream_getChar() {
|
||||
getChar: function DecodeStream_getChar() {
|
||||
var pos = this.pos;
|
||||
while (this.bufferLength <= pos) {
|
||||
if (this.eof)
|
||||
|
@ -162,40 +162,40 @@ var DecodeStream = (function decodeStream() {
|
|||
}
|
||||
return String.fromCharCode(this.buffer[this.pos++]);
|
||||
},
|
||||
makeSubStream: function decodestream_makeSubstream(start, length, dict) {
|
||||
makeSubStream: function DecodeStream_makeSubStream(start, length, dict) {
|
||||
var end = start + length;
|
||||
while (this.bufferLength <= end && !this.eof)
|
||||
this.readBlock();
|
||||
return new Stream(this.buffer, start, length, dict);
|
||||
},
|
||||
skip: function decodestream_skip(n) {
|
||||
skip: function DecodeStream_skip(n) {
|
||||
if (!n)
|
||||
n = 1;
|
||||
this.pos += n;
|
||||
},
|
||||
reset: function decodestream_reset() {
|
||||
reset: function DecodeStream_reset() {
|
||||
this.pos = 0;
|
||||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return DecodeStream;
|
||||
})();
|
||||
|
||||
var FakeStream = (function fakeStream() {
|
||||
function constructor(stream) {
|
||||
var FakeStream = (function FakeStreamClosure() {
|
||||
function FakeStream(stream) {
|
||||
this.dict = stream.dict;
|
||||
DecodeStream.call(this);
|
||||
}
|
||||
|
||||
constructor.prototype = Object.create(DecodeStream.prototype);
|
||||
constructor.prototype.readBlock = function fakeStreamReadBlock() {
|
||||
FakeStream.prototype = Object.create(DecodeStream.prototype);
|
||||
FakeStream.prototype.readBlock = function FakeStream_readBlock() {
|
||||
var bufferLength = this.bufferLength;
|
||||
bufferLength += 1024;
|
||||
var buffer = this.ensureBuffer(bufferLength);
|
||||
this.bufferLength = bufferLength;
|
||||
};
|
||||
|
||||
constructor.prototype.getBytes = function fakeStreamGetBytes(length) {
|
||||
FakeStream.prototype.getBytes = function FakeStream_getBytes(length) {
|
||||
var end, pos = this.pos;
|
||||
|
||||
if (length) {
|
||||
|
@ -217,18 +217,20 @@ var FakeStream = (function fakeStream() {
|
|||
return this.buffer.subarray(pos, end);
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return FakeStream;
|
||||
})();
|
||||
|
||||
var StreamsSequenceStream = (function streamSequenceStream() {
|
||||
function constructor(streams) {
|
||||
var StreamsSequenceStream = (function StreamsSequenceStreamClosure() {
|
||||
function StreamsSequenceStream(streams) {
|
||||
this.streams = streams;
|
||||
DecodeStream.call(this);
|
||||
}
|
||||
|
||||
constructor.prototype = Object.create(DecodeStream.prototype);
|
||||
StreamsSequenceStream.prototype = Object.create(DecodeStream.prototype);
|
||||
|
||||
StreamsSequenceStream.prototype.readBlock =
|
||||
function streamSequenceStreamReadBlock() {
|
||||
|
||||
constructor.prototype.readBlock = function streamSequenceStreamReadBlock() {
|
||||
var streams = this.streams;
|
||||
if (streams.length == 0) {
|
||||
this.eof = true;
|
||||
|
@ -243,10 +245,10 @@ var StreamsSequenceStream = (function streamSequenceStream() {
|
|||
this.bufferLength = newLength;
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return StreamsSequenceStream;
|
||||
})();
|
||||
|
||||
var FlateStream = (function flateStream() {
|
||||
var FlateStream = (function FlateStreamClosure() {
|
||||
var codeLenCodeMap = new Uint32Array([
|
||||
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
|
||||
]);
|
||||
|
@ -339,7 +341,7 @@ var FlateStream = (function flateStream() {
|
|||
0x50003, 0x50013, 0x5000b, 0x5001b, 0x50007, 0x50017, 0x5000f, 0x00000
|
||||
]), 5];
|
||||
|
||||
function constructor(stream) {
|
||||
function FlateStream(stream) {
|
||||
var bytes = stream.getBytes();
|
||||
var bytesPos = 0;
|
||||
|
||||
|
@ -364,9 +366,9 @@ var FlateStream = (function flateStream() {
|
|||
DecodeStream.call(this);
|
||||
}
|
||||
|
||||
constructor.prototype = Object.create(DecodeStream.prototype);
|
||||
FlateStream.prototype = Object.create(DecodeStream.prototype);
|
||||
|
||||
constructor.prototype.getBits = function flateStreamGetBits(bits) {
|
||||
FlateStream.prototype.getBits = function FlateStream_getBits(bits) {
|
||||
var codeSize = this.codeSize;
|
||||
var codeBuf = this.codeBuf;
|
||||
var bytes = this.bytes;
|
||||
|
@ -386,7 +388,7 @@ var FlateStream = (function flateStream() {
|
|||
return b;
|
||||
};
|
||||
|
||||
constructor.prototype.getCode = function flateStreamGetCode(table) {
|
||||
FlateStream.prototype.getCode = function FlateStream_getCode(table) {
|
||||
var codes = table[0];
|
||||
var maxLen = table[1];
|
||||
var codeSize = this.codeSize;
|
||||
|
@ -412,7 +414,7 @@ var FlateStream = (function flateStream() {
|
|||
return codeVal;
|
||||
};
|
||||
|
||||
constructor.prototype.generateHuffmanTable =
|
||||
FlateStream.prototype.generateHuffmanTable =
|
||||
function flateStreamGenerateHuffmanTable(lengths) {
|
||||
var n = lengths.length;
|
||||
|
||||
|
@ -451,7 +453,7 @@ var FlateStream = (function flateStream() {
|
|||
return [codes, maxLen];
|
||||
};
|
||||
|
||||
constructor.prototype.readBlock = function flateStreamReadBlock() {
|
||||
FlateStream.prototype.readBlock = function FlateStream_readBlock() {
|
||||
// read block header
|
||||
var hdr = this.getBits(3);
|
||||
if (hdr & 1)
|
||||
|
@ -582,11 +584,11 @@ var FlateStream = (function flateStream() {
|
|||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return FlateStream;
|
||||
})();
|
||||
|
||||
var PredictorStream = (function predictorStream() {
|
||||
function constructor(stream, params) {
|
||||
var PredictorStream = (function PredictorStreamClosure() {
|
||||
function PredictorStream(stream, params) {
|
||||
var predictor = this.predictor = params.get('Predictor') || 1;
|
||||
|
||||
if (predictor <= 1)
|
||||
|
@ -613,15 +615,14 @@ var PredictorStream = (function predictorStream() {
|
|||
return this;
|
||||
}
|
||||
|
||||
constructor.prototype = Object.create(DecodeStream.prototype);
|
||||
PredictorStream.prototype = Object.create(DecodeStream.prototype);
|
||||
|
||||
constructor.prototype.readBlockTiff =
|
||||
PredictorStream.prototype.readBlockTiff =
|
||||
function predictorStreamReadBlockTiff() {
|
||||
var rowBytes = this.rowBytes;
|
||||
|
||||
var bufferLength = this.bufferLength;
|
||||
var buffer = this.ensureBuffer(bufferLength + rowBytes);
|
||||
var currentRow = buffer.subarray(bufferLength, bufferLength + rowBytes);
|
||||
|
||||
var bits = this.bits;
|
||||
var colors = this.colors;
|
||||
|
@ -630,6 +631,7 @@ var PredictorStream = (function predictorStream() {
|
|||
|
||||
var inbuf = 0, outbuf = 0;
|
||||
var inbits = 0, outbits = 0;
|
||||
var pos = bufferLength;
|
||||
|
||||
if (bits === 1) {
|
||||
for (var i = 0; i < rowBytes; ++i) {
|
||||
|
@ -637,19 +639,21 @@ var PredictorStream = (function predictorStream() {
|
|||
inbuf = (inbuf << 8) | c;
|
||||
// bitwise addition is exclusive or
|
||||
// first shift inbuf and then add
|
||||
currentRow[i] = (c ^ (inbuf >> colors)) & 0xFF;
|
||||
buffer[pos++] = (c ^ (inbuf >> colors)) & 0xFF;
|
||||
// truncate inbuf (assumes colors < 16)
|
||||
inbuf &= 0xFFFF;
|
||||
}
|
||||
} else if (bits === 8) {
|
||||
for (var i = 0; i < colors; ++i)
|
||||
currentRow[i] = rawBytes[i];
|
||||
for (; i < rowBytes; ++i)
|
||||
currentRow[i] = currentRow[i - colors] + rawBytes[i];
|
||||
buffer[pos++] = rawBytes[i];
|
||||
for (; i < rowBytes; ++i) {
|
||||
buffer[pos] = buffer[pos - colors] + rawBytes[i];
|
||||
pos++;
|
||||
}
|
||||
} else {
|
||||
var compArray = new Uint8Array(colors + 1);
|
||||
var bitMask = (1 << bits) - 1;
|
||||
var j = 0, k = 0;
|
||||
var j = 0, k = bufferLength;
|
||||
var columns = this.columns;
|
||||
for (var i = 0; i < columns; ++i) {
|
||||
for (var kk = 0; kk < colors; ++kk) {
|
||||
|
@ -663,20 +667,22 @@ var PredictorStream = (function predictorStream() {
|
|||
outbuf = (outbuf << bits) | compArray[kk];
|
||||
outbits += bits;
|
||||
if (outbits >= 8) {
|
||||
currentRow[k++] = (outbuf >> (outbits - 8)) & 0xFF;
|
||||
buffer[k++] = (outbuf >> (outbits - 8)) & 0xFF;
|
||||
outbits -= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (outbits > 0) {
|
||||
currentRow[k++] = (outbuf << (8 - outbits)) +
|
||||
buffer[k++] = (outbuf << (8 - outbits)) +
|
||||
(inbuf & ((1 << (8 - outbits)) - 1));
|
||||
}
|
||||
}
|
||||
this.bufferLength += rowBytes;
|
||||
};
|
||||
|
||||
constructor.prototype.readBlockPng = function predictorStreamReadBlockPng() {
|
||||
PredictorStream.prototype.readBlockPng =
|
||||
function predictorStreamReadBlockPng() {
|
||||
|
||||
var rowBytes = this.rowBytes;
|
||||
var pixBytes = this.pixBytes;
|
||||
|
||||
|
@ -686,32 +692,35 @@ var PredictorStream = (function predictorStream() {
|
|||
var bufferLength = this.bufferLength;
|
||||
var buffer = this.ensureBuffer(bufferLength + rowBytes);
|
||||
|
||||
var currentRow = buffer.subarray(bufferLength, bufferLength + rowBytes);
|
||||
var prevRow = buffer.subarray(bufferLength - rowBytes, bufferLength);
|
||||
if (prevRow.length == 0)
|
||||
prevRow = new Uint8Array(rowBytes);
|
||||
|
||||
var j = bufferLength;
|
||||
switch (predictor) {
|
||||
case 0:
|
||||
for (var i = 0; i < rowBytes; ++i)
|
||||
currentRow[i] = rawBytes[i];
|
||||
buffer[j++] = rawBytes[i];
|
||||
break;
|
||||
case 1:
|
||||
for (var i = 0; i < pixBytes; ++i)
|
||||
currentRow[i] = rawBytes[i];
|
||||
for (; i < rowBytes; ++i)
|
||||
currentRow[i] = (currentRow[i - pixBytes] + rawBytes[i]) & 0xFF;
|
||||
buffer[j++] = rawBytes[i];
|
||||
for (; i < rowBytes; ++i) {
|
||||
buffer[j] = (buffer[j - pixBytes] + rawBytes[i]) & 0xFF;
|
||||
j++;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for (var i = 0; i < rowBytes; ++i)
|
||||
currentRow[i] = (prevRow[i] + rawBytes[i]) & 0xFF;
|
||||
buffer[j++] = (prevRow[i] + rawBytes[i]) & 0xFF;
|
||||
break;
|
||||
case 3:
|
||||
for (var i = 0; i < pixBytes; ++i)
|
||||
currentRow[i] = (prevRow[i] >> 1) + rawBytes[i];
|
||||
buffer[j++] = (prevRow[i] >> 1) + rawBytes[i];
|
||||
for (; i < rowBytes; ++i) {
|
||||
currentRow[i] = (((prevRow[i] + currentRow[i - pixBytes]) >> 1) +
|
||||
buffer[j] = (((prevRow[i] + buffer[j - pixBytes]) >> 1) +
|
||||
rawBytes[i]) & 0xFF;
|
||||
j++;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
|
@ -720,12 +729,12 @@ var PredictorStream = (function predictorStream() {
|
|||
for (var i = 0; i < pixBytes; ++i) {
|
||||
var up = prevRow[i];
|
||||
var c = rawBytes[i];
|
||||
currentRow[i] = up + c;
|
||||
buffer[j++] = up + c;
|
||||
}
|
||||
for (; i < rowBytes; ++i) {
|
||||
var up = prevRow[i];
|
||||
var upLeft = prevRow[i - pixBytes];
|
||||
var left = currentRow[i - pixBytes];
|
||||
var left = buffer[j - pixBytes];
|
||||
var p = left + up - upLeft;
|
||||
|
||||
var pa = p - left;
|
||||
|
@ -740,11 +749,11 @@ var PredictorStream = (function predictorStream() {
|
|||
|
||||
var c = rawBytes[i];
|
||||
if (pa <= pb && pa <= pc)
|
||||
currentRow[i] = left + c;
|
||||
buffer[j++] = left + c;
|
||||
else if (pb <= pc)
|
||||
currentRow[i] = up + c;
|
||||
buffer[j++] = up + c;
|
||||
else
|
||||
currentRow[i] = upLeft + c;
|
||||
buffer[j++] = upLeft + c;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -753,7 +762,7 @@ var PredictorStream = (function predictorStream() {
|
|||
this.bufferLength += rowBytes;
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return PredictorStream;
|
||||
})();
|
||||
|
||||
/**
|
||||
|
@ -763,7 +772,7 @@ var PredictorStream = (function predictorStream() {
|
|||
* a library to decode these images and the stream behaves like all the other
|
||||
* DecodeStreams.
|
||||
*/
|
||||
var JpegStream = (function jpegStream() {
|
||||
var JpegStream = (function JpegStreamClosure() {
|
||||
function isAdobeImage(bytes) {
|
||||
var maxBytesScanned = Math.max(bytes.length - 16, 1024);
|
||||
// Looking for APP14, 'Adobe'
|
||||
|
@ -794,63 +803,184 @@ var JpegStream = (function jpegStream() {
|
|||
return newBytes;
|
||||
}
|
||||
|
||||
function constructor(bytes, dict, xref) {
|
||||
function JpegStream(bytes, dict, xref) {
|
||||
// TODO: per poppler, some images may have 'junk' before that
|
||||
// need to be removed
|
||||
this.dict = dict;
|
||||
|
||||
// Flag indicating wether the image can be natively loaded.
|
||||
this.isNative = true;
|
||||
|
||||
this.colorTransform = -1;
|
||||
this.isAdobeImage = false;
|
||||
this.colorTransform = dict.get('ColorTransform') || -1;
|
||||
|
||||
if (isAdobeImage(bytes)) {
|
||||
// when bug 674619 land, let's check if browser can do
|
||||
// normal cmyk and then we won't have to the following
|
||||
var cs = xref.fetchIfRef(dict.get('ColorSpace'));
|
||||
|
||||
// DeviceRGB and DeviceGray are the only Adobe images that work natively
|
||||
if (isName(cs) && (cs.name === 'DeviceRGB' || cs.name === 'DeviceGray')) {
|
||||
bytes = fixAdobeImage(bytes);
|
||||
this.src = bytesToString(bytes);
|
||||
} else {
|
||||
this.colorTransform = dict.get('ColorTransform');
|
||||
this.isNative = false;
|
||||
this.bytes = bytes;
|
||||
}
|
||||
} else {
|
||||
this.src = bytesToString(bytes);
|
||||
this.isAdobeImage = true;
|
||||
bytes = fixAdobeImage(bytes);
|
||||
}
|
||||
|
||||
this.bytes = bytes;
|
||||
|
||||
DecodeStream.call(this);
|
||||
}
|
||||
|
||||
constructor.prototype = Object.create(DecodeStream.prototype);
|
||||
JpegStream.prototype = Object.create(DecodeStream.prototype);
|
||||
|
||||
constructor.prototype.ensureBuffer = function jpegStreamEnsureBuffer(req) {
|
||||
JpegStream.prototype.ensureBuffer = function JpegStream_ensureBuffer(req) {
|
||||
if (this.bufferLength)
|
||||
return;
|
||||
var jpegImage = new JpegImage();
|
||||
jpegImage.colorTransform = this.colorTransform;
|
||||
jpegImage.parse(this.bytes);
|
||||
var width = jpegImage.width;
|
||||
var height = jpegImage.height;
|
||||
var data = jpegImage.getData(width, height);
|
||||
try {
|
||||
var jpegImage = new JpegImage();
|
||||
if (this.colorTransform != -1)
|
||||
jpegImage.colorTransform = this.colorTransform;
|
||||
jpegImage.parse(this.bytes);
|
||||
var width = jpegImage.width;
|
||||
var height = jpegImage.height;
|
||||
var data = jpegImage.getData(width, height);
|
||||
this.buffer = data;
|
||||
this.bufferLength = data.length;
|
||||
} catch (e) {
|
||||
error('JPEG error: ' + e);
|
||||
}
|
||||
};
|
||||
JpegStream.prototype.getIR = function JpegStream_getIR() {
|
||||
return bytesToString(this.bytes);
|
||||
};
|
||||
JpegStream.prototype.getChar = function JpegStream_getChar() {
|
||||
error('internal error: getChar is not valid on JpegStream');
|
||||
};
|
||||
/**
|
||||
* Checks if the image can be decoded and displayed by the browser without any
|
||||
* further processing such as color space conversions.
|
||||
*/
|
||||
JpegStream.prototype.isNativelySupported =
|
||||
function JpegStream_isNativelySupported(xref, res) {
|
||||
var cs = ColorSpace.parse(this.dict.get('ColorSpace'), xref, res);
|
||||
// when bug 674619 lands, let's check if browser can do
|
||||
// normal cmyk and then we won't need to decode in JS
|
||||
if (cs.name === 'DeviceGray' || cs.name === 'DeviceRGB')
|
||||
return true;
|
||||
if (cs.name === 'DeviceCMYK' && !this.isAdobeImage &&
|
||||
this.colorTransform < 1)
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
/**
|
||||
* Checks if the image can be decoded by the browser.
|
||||
*/
|
||||
JpegStream.prototype.isNativelyDecodable =
|
||||
function JpegStream_isNativelyDecodable(xref, res) {
|
||||
var cs = ColorSpace.parse(this.dict.get('ColorSpace'), xref, res);
|
||||
var numComps = cs.numComps;
|
||||
if (numComps == 1 || numComps == 3)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
return JpegStream;
|
||||
})();
|
||||
|
||||
/**
|
||||
* For JPEG 2000's we use a library to decode these images and
|
||||
* the stream behaves like all the other DecodeStreams.
|
||||
*/
|
||||
var JpxStream = (function JpxStreamClosure() {
|
||||
function JpxStream(bytes, dict) {
|
||||
this.dict = dict;
|
||||
this.bytes = bytes;
|
||||
|
||||
DecodeStream.call(this);
|
||||
}
|
||||
|
||||
JpxStream.prototype = Object.create(DecodeStream.prototype);
|
||||
|
||||
JpxStream.prototype.ensureBuffer = function JpxStream_ensureBuffer(req) {
|
||||
if (this.bufferLength)
|
||||
return;
|
||||
|
||||
var jpxImage = new JpxImage();
|
||||
jpxImage.parse(this.bytes);
|
||||
|
||||
var width = jpxImage.width;
|
||||
var height = jpxImage.height;
|
||||
var componentsCount = jpxImage.componentsCount;
|
||||
if (componentsCount != 1 && componentsCount != 3 && componentsCount != 4)
|
||||
error('JPX with ' + componentsCount + ' components is not supported');
|
||||
|
||||
var data = new Uint8Array(width * height * componentsCount);
|
||||
|
||||
for (var k = 0, kk = jpxImage.tiles.length; k < kk; k++) {
|
||||
var tileCompoments = jpxImage.tiles[k];
|
||||
var tileWidth = tileCompoments[0].width;
|
||||
var tileHeight = tileCompoments[0].height;
|
||||
var tileLeft = tileCompoments[0].left;
|
||||
var tileTop = tileCompoments[0].top;
|
||||
|
||||
var dataPosition, sourcePosition, data0, data1, data2, data3, rowFeed;
|
||||
switch (componentsCount) {
|
||||
case 1:
|
||||
data0 = tileCompoments[0].items;
|
||||
|
||||
dataPosition = width * tileTop + tileLeft;
|
||||
rowFeed = width - tileWidth;
|
||||
sourcePosition = 0;
|
||||
for (var j = 0; j < tileHeight; j++) {
|
||||
for (var i = 0; i < tileWidth; i++)
|
||||
data[dataPosition++] = data0[sourcePosition++];
|
||||
dataPosition += rowFeed;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
data0 = tileCompoments[0].items;
|
||||
data1 = tileCompoments[1].items;
|
||||
data2 = tileCompoments[2].items;
|
||||
|
||||
dataPosition = (width * tileTop + tileLeft) * 3;
|
||||
rowFeed = (width - tileWidth) * 3;
|
||||
sourcePosition = 0;
|
||||
for (var j = 0; j < tileHeight; j++) {
|
||||
for (var i = 0; i < tileWidth; i++) {
|
||||
data[dataPosition++] = data0[sourcePosition];
|
||||
data[dataPosition++] = data1[sourcePosition];
|
||||
data[dataPosition++] = data2[sourcePosition];
|
||||
sourcePosition++;
|
||||
}
|
||||
dataPosition += rowFeed;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
data0 = tileCompoments[0].items;
|
||||
data1 = tileCompoments[1].items;
|
||||
data2 = tileCompoments[2].items;
|
||||
data3 = tileCompoments[3].items;
|
||||
|
||||
dataPosition = (width * tileTop + tileLeft) * 4;
|
||||
rowFeed = (width - tileWidth) * 4;
|
||||
sourcePosition = 0;
|
||||
for (var j = 0; j < tileHeight; j++) {
|
||||
for (var i = 0; i < tileWidth; i++) {
|
||||
data[dataPosition++] = data0[sourcePosition];
|
||||
data[dataPosition++] = data1[sourcePosition];
|
||||
data[dataPosition++] = data2[sourcePosition];
|
||||
data[dataPosition++] = data3[sourcePosition];
|
||||
sourcePosition++;
|
||||
}
|
||||
dataPosition += rowFeed;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.buffer = data;
|
||||
this.bufferLength = data.length;
|
||||
};
|
||||
constructor.prototype.getIR = function jpegStreamGetIR() {
|
||||
return this.src;
|
||||
};
|
||||
constructor.prototype.getChar = function jpegStreamGetChar() {
|
||||
error('internal error: getChar is not valid on JpegStream');
|
||||
JpxStream.prototype.getChar = function JpxStream_getChar() {
|
||||
error('internal error: getChar is not valid on JpxStream');
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return JpxStream;
|
||||
})();
|
||||
|
||||
var DecryptStream = (function decryptStream() {
|
||||
function constructor(str, decrypt) {
|
||||
var DecryptStream = (function DecryptStreamClosure() {
|
||||
function DecryptStream(str, decrypt) {
|
||||
this.str = str;
|
||||
this.dict = str.dict;
|
||||
this.decrypt = decrypt;
|
||||
|
@ -860,9 +990,9 @@ var DecryptStream = (function decryptStream() {
|
|||
|
||||
var chunkSize = 512;
|
||||
|
||||
constructor.prototype = Object.create(DecodeStream.prototype);
|
||||
DecryptStream.prototype = Object.create(DecodeStream.prototype);
|
||||
|
||||
constructor.prototype.readBlock = function decryptStreamReadBlock() {
|
||||
DecryptStream.prototype.readBlock = function DecryptStream_readBlock() {
|
||||
var chunk = this.str.getBytes(chunkSize);
|
||||
if (!chunk || chunk.length == 0) {
|
||||
this.eof = true;
|
||||
|
@ -879,11 +1009,11 @@ var DecryptStream = (function decryptStream() {
|
|||
this.bufferLength = bufferLength;
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return DecryptStream;
|
||||
})();
|
||||
|
||||
var Ascii85Stream = (function ascii85Stream() {
|
||||
function constructor(str) {
|
||||
var Ascii85Stream = (function Ascii85StreamClosure() {
|
||||
function Ascii85Stream(str) {
|
||||
this.str = str;
|
||||
this.dict = str.dict;
|
||||
this.input = new Uint8Array(5);
|
||||
|
@ -891,9 +1021,9 @@ var Ascii85Stream = (function ascii85Stream() {
|
|||
DecodeStream.call(this);
|
||||
}
|
||||
|
||||
constructor.prototype = Object.create(DecodeStream.prototype);
|
||||
Ascii85Stream.prototype = Object.create(DecodeStream.prototype);
|
||||
|
||||
constructor.prototype.readBlock = function ascii85StreamReadBlock() {
|
||||
Ascii85Stream.prototype.readBlock = function Ascii85Stream_readBlock() {
|
||||
var tildaCode = '~'.charCodeAt(0);
|
||||
var zCode = 'z'.charCodeAt(0);
|
||||
var str = this.str;
|
||||
|
@ -948,11 +1078,11 @@ var Ascii85Stream = (function ascii85Stream() {
|
|||
}
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return Ascii85Stream;
|
||||
})();
|
||||
|
||||
var AsciiHexStream = (function asciiHexStream() {
|
||||
function constructor(str) {
|
||||
var AsciiHexStream = (function AsciiHexStreamClosure() {
|
||||
function AsciiHexStream(str) {
|
||||
this.str = str;
|
||||
this.dict = str.dict;
|
||||
|
||||
|
@ -986,9 +1116,9 @@ var AsciiHexStream = (function asciiHexStream() {
|
|||
102: 15
|
||||
};
|
||||
|
||||
constructor.prototype = Object.create(DecodeStream.prototype);
|
||||
AsciiHexStream.prototype = Object.create(DecodeStream.prototype);
|
||||
|
||||
constructor.prototype.readBlock = function asciiHexStreamReadBlock() {
|
||||
AsciiHexStream.prototype.readBlock = function AsciiHexStream_readBlock() {
|
||||
var gtCode = '>'.charCodeAt(0), bytes = this.str.getBytes(), c, n,
|
||||
decodeLength, buffer, bufferLength, i, length;
|
||||
|
||||
|
@ -1018,10 +1148,55 @@ var AsciiHexStream = (function asciiHexStream() {
|
|||
this.eof = true;
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return AsciiHexStream;
|
||||
})();
|
||||
|
||||
var CCITTFaxStream = (function ccittFaxStream() {
|
||||
var RunLengthStream = (function RunLengthStreamClosure() {
|
||||
function RunLengthStream(str) {
|
||||
this.str = str;
|
||||
this.dict = str.dict;
|
||||
|
||||
DecodeStream.call(this);
|
||||
}
|
||||
|
||||
RunLengthStream.prototype = Object.create(DecodeStream.prototype);
|
||||
|
||||
RunLengthStream.prototype.readBlock = function RunLengthStream_readBlock() {
|
||||
// The repeatHeader has following format. The first byte defines type of run
|
||||
// and amount of bytes to repeat/copy: n = 0 through 127 - copy next n bytes
|
||||
// (in addition to the second byte from the header), n = 129 through 255 -
|
||||
// duplicate the second byte from the header (257 - n) times, n = 128 - end.
|
||||
var repeatHeader = this.str.getBytes(2);
|
||||
if (!repeatHeader || repeatHeader.length < 2 || repeatHeader[0] == 128) {
|
||||
this.eof = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var bufferLength = this.bufferLength;
|
||||
var n = repeatHeader[0];
|
||||
if (n < 128) {
|
||||
// copy n bytes
|
||||
var buffer = this.ensureBuffer(bufferLength + n + 1);
|
||||
buffer[bufferLength++] = repeatHeader[1];
|
||||
if (n > 0) {
|
||||
var source = this.str.getBytes(n);
|
||||
buffer.set(source, bufferLength);
|
||||
bufferLength += n;
|
||||
}
|
||||
} else {
|
||||
n = 257 - n;
|
||||
var b = repeatHeader[1];
|
||||
var buffer = this.ensureBuffer(bufferLength + n + 1);
|
||||
for (var i = 0; i < n; i++)
|
||||
buffer[bufferLength++] = b;
|
||||
}
|
||||
this.bufferLength = bufferLength;
|
||||
};
|
||||
|
||||
return RunLengthStream;
|
||||
})();
|
||||
|
||||
var CCITTFaxStream = (function CCITTFaxStreamClosure() {
|
||||
|
||||
var ccittEOL = -2;
|
||||
var twoDimPass = 0;
|
||||
|
@ -1449,7 +1624,7 @@ var CCITTFaxStream = (function ccittFaxStream() {
|
|||
[2, 2], [2, 2], [2, 2], [2, 2]
|
||||
];
|
||||
|
||||
function constructor(str, params) {
|
||||
function CCITTFaxStream(str, params) {
|
||||
this.str = str;
|
||||
this.dict = str.dict;
|
||||
|
||||
|
@ -1494,9 +1669,9 @@ var CCITTFaxStream = (function ccittFaxStream() {
|
|||
DecodeStream.call(this);
|
||||
}
|
||||
|
||||
constructor.prototype = Object.create(DecodeStream.prototype);
|
||||
CCITTFaxStream.prototype = Object.create(DecodeStream.prototype);
|
||||
|
||||
constructor.prototype.readBlock = function ccittFaxStreamReadBlock() {
|
||||
CCITTFaxStream.prototype.readBlock = function CCITTFaxStream_readBlock() {
|
||||
while (!this.eof) {
|
||||
var c = this.lookChar();
|
||||
this.buf = EOF;
|
||||
|
@ -1505,7 +1680,7 @@ var CCITTFaxStream = (function ccittFaxStream() {
|
|||
}
|
||||
};
|
||||
|
||||
constructor.prototype.addPixels =
|
||||
CCITTFaxStream.prototype.addPixels =
|
||||
function ccittFaxStreamAddPixels(a1, blackPixels) {
|
||||
var codingLine = this.codingLine;
|
||||
var codingPos = this.codingPos;
|
||||
|
@ -1525,7 +1700,7 @@ var CCITTFaxStream = (function ccittFaxStream() {
|
|||
this.codingPos = codingPos;
|
||||
};
|
||||
|
||||
constructor.prototype.addPixelsNeg =
|
||||
CCITTFaxStream.prototype.addPixelsNeg =
|
||||
function ccittFaxStreamAddPixelsNeg(a1, blackPixels) {
|
||||
var codingLine = this.codingLine;
|
||||
var codingPos = this.codingPos;
|
||||
|
@ -1554,7 +1729,7 @@ var CCITTFaxStream = (function ccittFaxStream() {
|
|||
this.codingPos = codingPos;
|
||||
};
|
||||
|
||||
constructor.prototype.lookChar = function ccittFaxStreamLookChar() {
|
||||
CCITTFaxStream.prototype.lookChar = function CCITTFaxStream_lookChar() {
|
||||
if (this.buf != EOF)
|
||||
return this.buf;
|
||||
|
||||
|
@ -1852,10 +2027,10 @@ var CCITTFaxStream = (function ccittFaxStream() {
|
|||
// values. The first array element indicates whether a valid code is being
|
||||
// returned. The second array element is the actual code. The third array
|
||||
// element indicates whether EOF was reached.
|
||||
var findTableCode = function ccittFaxStreamFindTableCode(start, end, table,
|
||||
limit) {
|
||||
var limitValue = limit || 0;
|
||||
CCITTFaxStream.prototype.findTableCode =
|
||||
function ccittFaxStreamFindTableCode(start, end, table, limit) {
|
||||
|
||||
var limitValue = limit || 0;
|
||||
for (var i = start; i <= end; ++i) {
|
||||
var code = this.lookBits(i);
|
||||
if (code == EOF)
|
||||
|
@ -1873,18 +2048,20 @@ var CCITTFaxStream = (function ccittFaxStream() {
|
|||
return [false, 0, false];
|
||||
};
|
||||
|
||||
constructor.prototype.getTwoDimCode = function ccittFaxStreamGetTwoDimCode() {
|
||||
CCITTFaxStream.prototype.getTwoDimCode =
|
||||
function ccittFaxStreamGetTwoDimCode() {
|
||||
|
||||
var code = 0;
|
||||
var p;
|
||||
if (this.eoblock) {
|
||||
code = this.lookBits(7);
|
||||
p = twoDimTable[code];
|
||||
if (p[0] > 0) {
|
||||
if (p && p[0] > 0) {
|
||||
this.eatBits(p[0]);
|
||||
return p[1];
|
||||
}
|
||||
} else {
|
||||
var result = findTableCode(1, 7, twoDimTable);
|
||||
var result = this.findTableCode(1, 7, twoDimTable);
|
||||
if (result[0] && result[2])
|
||||
return result[1];
|
||||
}
|
||||
|
@ -1892,7 +2069,9 @@ var CCITTFaxStream = (function ccittFaxStream() {
|
|||
return EOF;
|
||||
};
|
||||
|
||||
constructor.prototype.getWhiteCode = function ccittFaxStreamGetWhiteCode() {
|
||||
CCITTFaxStream.prototype.getWhiteCode =
|
||||
function ccittFaxStreamGetWhiteCode() {
|
||||
|
||||
var code = 0;
|
||||
var p;
|
||||
var n;
|
||||
|
@ -1911,11 +2090,11 @@ var CCITTFaxStream = (function ccittFaxStream() {
|
|||
return p[1];
|
||||
}
|
||||
} else {
|
||||
var result = findTableCode(1, 9, whiteTable2);
|
||||
var result = this.findTableCode(1, 9, whiteTable2);
|
||||
if (result[0])
|
||||
return result[1];
|
||||
|
||||
result = findTableCode(11, 12, whiteTable1);
|
||||
result = this.findTableCode(11, 12, whiteTable1);
|
||||
if (result[0])
|
||||
return result[1];
|
||||
}
|
||||
|
@ -1924,7 +2103,9 @@ var CCITTFaxStream = (function ccittFaxStream() {
|
|||
return 1;
|
||||
};
|
||||
|
||||
constructor.prototype.getBlackCode = function ccittFaxStreamGetBlackCode() {
|
||||
CCITTFaxStream.prototype.getBlackCode =
|
||||
function ccittFaxStreamGetBlackCode() {
|
||||
|
||||
var code, p;
|
||||
if (this.eoblock) {
|
||||
code = this.lookBits(13);
|
||||
|
@ -1942,15 +2123,15 @@ var CCITTFaxStream = (function ccittFaxStream() {
|
|||
return p[1];
|
||||
}
|
||||
} else {
|
||||
var result = findTableCode(2, 6, blackTable3);
|
||||
var result = this.findTableCode(2, 6, blackTable3);
|
||||
if (result[0])
|
||||
return result[1];
|
||||
|
||||
result = findTableCode(7, 12, blackTable2, 64);
|
||||
result = this.findTableCode(7, 12, blackTable2, 64);
|
||||
if (result[0])
|
||||
return result[1];
|
||||
|
||||
result = findTableCode(10, 13, blackTable1);
|
||||
result = this.findTableCode(10, 13, blackTable1);
|
||||
if (result[0])
|
||||
return result[1];
|
||||
}
|
||||
|
@ -1959,7 +2140,7 @@ var CCITTFaxStream = (function ccittFaxStream() {
|
|||
return 1;
|
||||
};
|
||||
|
||||
constructor.prototype.lookBits = function ccittFaxStreamLookBits(n) {
|
||||
CCITTFaxStream.prototype.lookBits = function CCITTFaxStream_lookBits(n) {
|
||||
var c;
|
||||
while (this.inputBits < n) {
|
||||
if ((c = this.str.getByte()) == null) {
|
||||
|
@ -1974,16 +2155,16 @@ var CCITTFaxStream = (function ccittFaxStream() {
|
|||
return (this.inputBuf >> (this.inputBits - n)) & (0xFFFF >> (16 - n));
|
||||
};
|
||||
|
||||
constructor.prototype.eatBits = function ccittFaxStreamEatBits(n) {
|
||||
CCITTFaxStream.prototype.eatBits = function CCITTFaxStream_eatBits(n) {
|
||||
if ((this.inputBits -= n) < 0)
|
||||
this.inputBits = 0;
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return CCITTFaxStream;
|
||||
})();
|
||||
|
||||
var LZWStream = (function lzwStream() {
|
||||
function constructor(str, earlyChange) {
|
||||
var LZWStream = (function LZWStreamClosure() {
|
||||
function LZWStream(str, earlyChange) {
|
||||
this.str = str;
|
||||
this.dict = str.dict;
|
||||
this.cachedData = 0;
|
||||
|
@ -2009,9 +2190,9 @@ var LZWStream = (function lzwStream() {
|
|||
DecodeStream.call(this);
|
||||
}
|
||||
|
||||
constructor.prototype = Object.create(DecodeStream.prototype);
|
||||
LZWStream.prototype = Object.create(DecodeStream.prototype);
|
||||
|
||||
constructor.prototype.readBits = function lzwStreamReadBits(n) {
|
||||
LZWStream.prototype.readBits = function LZWStream_readBits(n) {
|
||||
var bitsCached = this.bitsCached;
|
||||
var cachedData = this.cachedData;
|
||||
while (bitsCached < n) {
|
||||
|
@ -2029,7 +2210,7 @@ var LZWStream = (function lzwStream() {
|
|||
return (cachedData >>> bitsCached) & ((1 << n) - 1);
|
||||
};
|
||||
|
||||
constructor.prototype.readBlock = function lzwStreamReadBlock() {
|
||||
LZWStream.prototype.readBlock = function LZWStream_readBlock() {
|
||||
var blockSize = 512;
|
||||
var estimatedDecodedSize = blockSize * 2, decodedSizeDelta = blockSize;
|
||||
var i, j, q;
|
||||
|
@ -2108,6 +2289,6 @@ var LZWStream = (function lzwStream() {
|
|||
this.bufferLength = currentBufferLength;
|
||||
};
|
||||
|
||||
return constructor;
|
||||
return LZWStream;
|
||||
})();
|
||||
|
||||
|
|
218
apps/files_pdfviewer/js/pdfjs/src/util.js
Executable file → Normal file
|
@ -76,24 +76,102 @@ function stringToBytes(str) {
|
|||
|
||||
var IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
|
||||
|
||||
var Util = (function utilUtil() {
|
||||
function constructor() {}
|
||||
constructor.makeCssRgb = function makergb(r, g, b) {
|
||||
var Util = (function UtilClosure() {
|
||||
function Util() {}
|
||||
|
||||
Util.makeCssRgb = function Util_makeCssRgb(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) {
|
||||
|
||||
Util.makeCssCmyk = function Util_makeCssCmyk(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) {
|
||||
|
||||
// For 2d affine transforms
|
||||
Util.applyTransform = function Util_applyTransform(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;
|
||||
// Apply a generic 3d matrix M on a 3-vector v:
|
||||
// | a b c | | X |
|
||||
// | d e f | x | Y |
|
||||
// | g h i | | Z |
|
||||
// M is assumed to be serialized as [a,b,c,d,e,f,g,h,i],
|
||||
// with v as [X,Y,Z]
|
||||
Util.apply3dTransform = function Util_apply3dTransform(m, v) {
|
||||
return [
|
||||
m[0] * v[0] + m[1] * v[1] + m[2] * v[2],
|
||||
m[3] * v[0] + m[4] * v[1] + m[5] * v[2],
|
||||
m[6] * v[0] + m[7] * v[1] + m[8] * v[2]
|
||||
];
|
||||
}
|
||||
|
||||
// Normalize rectangle rect=[x1, y1, x2, y2] so that (x1,y1) < (x2,y2)
|
||||
// For coordinate systems whose origin lies in the bottom-left, this
|
||||
// means normalization to (BL,TR) ordering. For systems with origin in the
|
||||
// top-left, this means (TL,BR) ordering.
|
||||
Util.normalizeRect = function Util_normalizeRect(rect) {
|
||||
var r = rect.slice(0); // clone rect
|
||||
if (rect[0] > rect[2]) {
|
||||
r[0] = rect[2];
|
||||
r[2] = rect[0];
|
||||
}
|
||||
if (rect[1] > rect[3]) {
|
||||
r[1] = rect[3];
|
||||
r[3] = rect[1];
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
// Returns a rectangle [x1, y1, x2, y2] corresponding to the
|
||||
// intersection of rect1 and rect2. If no intersection, returns 'false'
|
||||
// The rectangle coordinates of rect1, rect2 should be [x1, y1, x2, y2]
|
||||
Util.intersect = function Util_intersect(rect1, rect2) {
|
||||
function compare(a, b) {
|
||||
return a - b;
|
||||
};
|
||||
|
||||
// Order points along the axes
|
||||
var orderedX = [rect1[0], rect1[2], rect2[0], rect2[2]].sort(compare),
|
||||
orderedY = [rect1[1], rect1[3], rect2[1], rect2[3]].sort(compare),
|
||||
result = [];
|
||||
|
||||
rect1 = Util.normalizeRect(rect1);
|
||||
rect2 = Util.normalizeRect(rect2);
|
||||
|
||||
// X: first and second points belong to different rectangles?
|
||||
if ((orderedX[0] === rect1[0] && orderedX[1] === rect2[0]) ||
|
||||
(orderedX[0] === rect2[0] && orderedX[1] === rect1[0])) {
|
||||
// Intersection must be between second and third points
|
||||
result[0] = orderedX[1];
|
||||
result[2] = orderedX[2];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Y: first and second points belong to different rectangles?
|
||||
if ((orderedY[0] === rect1[1] && orderedY[1] === rect2[1]) ||
|
||||
(orderedY[0] === rect2[1] && orderedY[1] === rect1[1])) {
|
||||
// Intersection must be between second and third points
|
||||
result[1] = orderedY[1];
|
||||
result[3] = orderedY[2];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Util.sign = function Util_sign(num) {
|
||||
return num < 0 ? -1 : 1;
|
||||
};
|
||||
|
||||
return Util;
|
||||
})();
|
||||
|
||||
var PDFStringTranslateTable = [
|
||||
|
@ -197,7 +275,7 @@ function isPDFFunction(v) {
|
|||
* 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 promise() {
|
||||
var Promise = (function PromiseClosure() {
|
||||
var EMPTY_PROMISE = {};
|
||||
|
||||
/**
|
||||
|
@ -206,6 +284,8 @@ var Promise = (function promise() {
|
|||
*/
|
||||
function Promise(name, data) {
|
||||
this.name = name;
|
||||
this.isRejected = false;
|
||||
this.error = null;
|
||||
// If you build a promise and pass in some data it's already resolved.
|
||||
if (data != null) {
|
||||
this.isResolved = true;
|
||||
|
@ -216,8 +296,35 @@ var Promise = (function promise() {
|
|||
this._data = EMPTY_PROMISE;
|
||||
}
|
||||
this.callbacks = [];
|
||||
this.errbacks = [];
|
||||
};
|
||||
/**
|
||||
* Builds a promise that is resolved when all the passed in promises are
|
||||
* resolved.
|
||||
* @param {Promise[]} promises Array of promises to wait for.
|
||||
* @return {Promise} New dependant promise.
|
||||
*/
|
||||
Promise.all = function Promise_all(promises) {
|
||||
var deferred = new Promise();
|
||||
var unresolved = promises.length;
|
||||
var results = [];
|
||||
if (unresolved === 0) {
|
||||
deferred.resolve(results);
|
||||
return deferred;
|
||||
}
|
||||
for (var i = 0; i < unresolved; ++i) {
|
||||
var promise = promises[i];
|
||||
promise.then((function(i) {
|
||||
return function(value) {
|
||||
results[i] = value;
|
||||
unresolved--;
|
||||
if (unresolved === 0)
|
||||
deferred.resolve(results);
|
||||
};
|
||||
})(i));
|
||||
}
|
||||
return deferred;
|
||||
};
|
||||
|
||||
Promise.prototype = {
|
||||
hasData: false,
|
||||
|
||||
|
@ -226,8 +333,8 @@ var Promise = (function promise() {
|
|||
return;
|
||||
}
|
||||
if (this._data !== EMPTY_PROMISE) {
|
||||
throw 'Promise ' + this.name +
|
||||
': Cannot set the data of a promise twice';
|
||||
error('Promise ' + this.name +
|
||||
': Cannot set the data of a promise twice');
|
||||
}
|
||||
this._data = value;
|
||||
this.hasData = true;
|
||||
|
@ -239,12 +346,12 @@ var Promise = (function promise() {
|
|||
|
||||
get data() {
|
||||
if (this._data === EMPTY_PROMISE) {
|
||||
throw 'Promise ' + this.name + ': Cannot get data that isn\'t set';
|
||||
error('Promise ' + this.name + ': Cannot get data that isn\'t set');
|
||||
}
|
||||
return this._data;
|
||||
},
|
||||
|
||||
onData: function promiseOnData(callback) {
|
||||
onData: function Promise_onData(callback) {
|
||||
if (this._data !== EMPTY_PROMISE) {
|
||||
callback(this._data);
|
||||
} else {
|
||||
|
@ -252,13 +359,16 @@ var Promise = (function promise() {
|
|||
}
|
||||
},
|
||||
|
||||
resolve: function promiseResolve(data) {
|
||||
resolve: function Promise_resolve(data) {
|
||||
if (this.isResolved) {
|
||||
throw 'A Promise can be resolved only once ' + this.name;
|
||||
error('A Promise can be resolved only once ' + this.name);
|
||||
}
|
||||
if (this.isRejected) {
|
||||
error('The Promise was already rejected ' + this.name);
|
||||
}
|
||||
|
||||
this.isResolved = true;
|
||||
this.data = data;
|
||||
this.data = data || null;
|
||||
var callbacks = this.callbacks;
|
||||
|
||||
for (var i = 0, ii = callbacks.length; i < ii; i++) {
|
||||
|
@ -266,17 +376,39 @@ var Promise = (function promise() {
|
|||
}
|
||||
},
|
||||
|
||||
then: function promiseThen(callback) {
|
||||
reject: function Promise_reject(reason) {
|
||||
if (this.isRejected) {
|
||||
error('A Promise can be rejected only once ' + this.name);
|
||||
}
|
||||
if (this.isResolved) {
|
||||
error('The Promise was already resolved ' + this.name);
|
||||
}
|
||||
|
||||
this.isRejected = true;
|
||||
this.error = reason || null;
|
||||
var errbacks = this.errbacks;
|
||||
|
||||
for (var i = 0, ii = errbacks.length; i < ii; i++) {
|
||||
errbacks[i].call(null, reason);
|
||||
}
|
||||
},
|
||||
|
||||
then: function Promise_then(callback, errback) {
|
||||
if (!callback) {
|
||||
throw 'Requiring callback' + this.name;
|
||||
error('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 if (this.isRejected && errback) {
|
||||
var error = this.error;
|
||||
errback.call(null, error);
|
||||
} else {
|
||||
this.callbacks.push(callback);
|
||||
if (errback)
|
||||
this.errbacks.push(errback);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -284,3 +416,55 @@ var Promise = (function promise() {
|
|||
return Promise;
|
||||
})();
|
||||
|
||||
var StatTimer = (function StatTimerClosure() {
|
||||
function rpad(str, pad, length) {
|
||||
while (str.length < length)
|
||||
str += pad;
|
||||
return str;
|
||||
}
|
||||
function StatTimer() {
|
||||
this.started = {};
|
||||
this.times = [];
|
||||
this.enabled = true;
|
||||
}
|
||||
StatTimer.prototype = {
|
||||
time: function StatTimer_time(name) {
|
||||
if (!this.enabled)
|
||||
return;
|
||||
if (name in this.started)
|
||||
throw 'Timer is already running for ' + name;
|
||||
this.started[name] = Date.now();
|
||||
},
|
||||
timeEnd: function StatTimer_timeEnd(name) {
|
||||
if (!this.enabled)
|
||||
return;
|
||||
if (!(name in this.started))
|
||||
throw 'Timer has not been started for ' + name;
|
||||
this.times.push({
|
||||
'name': name,
|
||||
'start': this.started[name],
|
||||
'end': Date.now()
|
||||
});
|
||||
// Remove timer from started so it can be called again.
|
||||
delete this.started[name];
|
||||
},
|
||||
toString: function StatTimer_toString() {
|
||||
var times = this.times;
|
||||
var out = '';
|
||||
// Find the longest name for padding purposes.
|
||||
var longest = 0;
|
||||
for (var i = 0, ii = times.length; i < ii; ++i) {
|
||||
var name = times[i]['name'];
|
||||
if (name.length > longest)
|
||||
longest = name.length;
|
||||
}
|
||||
for (var i = 0, ii = times.length; i < ii; ++i) {
|
||||
var span = times[i];
|
||||
var duration = span.end - span.start;
|
||||
out += rpad(span['name'], ' ', longest) + ' ' + duration + 'ms\n';
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
return StatTimer;
|
||||
})();
|
||||
|
|
0
apps/files_pdfviewer/js/pdfjs/src/utils/cffStandardStrings.js
Executable file → Normal file
6
apps/files_pdfviewer/js/pdfjs/src/utils/fonts_utils.js
Executable file → Normal 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)
|
||||
|
|
154
apps/files_pdfviewer/js/pdfjs/src/worker.js
Executable file → Normal file
|
@ -6,6 +6,8 @@
|
|||
function MessageHandler(name, comObj) {
|
||||
this.name = name;
|
||||
this.comObj = comObj;
|
||||
this.callbackIndex = 1;
|
||||
var callbacks = this.callbacks = {};
|
||||
var ah = this.actionHandler = {};
|
||||
|
||||
ah['console_log'] = [function ahConsoleLog(data) {
|
||||
|
@ -17,11 +19,32 @@ function MessageHandler(name, comObj) {
|
|||
|
||||
comObj.onmessage = function messageHandlerComObjOnMessage(event) {
|
||||
var data = event.data;
|
||||
if (data.action in ah) {
|
||||
if (data.isReply) {
|
||||
var callbackId = data.callbackId;
|
||||
if (data.callbackId in callbacks) {
|
||||
var callback = callbacks[callbackId];
|
||||
delete callbacks[callbackId];
|
||||
callback(data.data);
|
||||
} else {
|
||||
error('Cannot resolve callback ' + callbackId);
|
||||
}
|
||||
} else if (data.action in ah) {
|
||||
var action = ah[data.action];
|
||||
action[0].call(action[1], data.data);
|
||||
if (data.callbackId) {
|
||||
var promise = new Promise();
|
||||
promise.then(function(resolvedData) {
|
||||
comObj.postMessage({
|
||||
isReply: true,
|
||||
callbackId: data.callbackId,
|
||||
data: resolvedData
|
||||
});
|
||||
});
|
||||
action[0].call(action[1], data.data, promise);
|
||||
} else {
|
||||
action[0].call(action[1], data.data);
|
||||
}
|
||||
} else {
|
||||
throw 'Unkown action from worker: ' + data.action;
|
||||
error('Unkown action from worker: ' + data.action);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -30,44 +53,47 @@ MessageHandler.prototype = {
|
|||
on: function messageHandlerOn(actionName, handler, scope) {
|
||||
var ah = this.actionHandler;
|
||||
if (ah[actionName]) {
|
||||
throw 'There is already an actionName called "' + actionName + '"';
|
||||
error('There is already an actionName called "' + actionName + '"');
|
||||
}
|
||||
ah[actionName] = [handler, scope];
|
||||
},
|
||||
|
||||
send: function messageHandlerSend(actionName, data) {
|
||||
this.comObj.postMessage({
|
||||
/**
|
||||
* Sends a message to the comObj to invoke the action with the supplied data.
|
||||
* @param {String} actionName Action to call.
|
||||
* @param {JSON} data JSON data to send.
|
||||
* @param {function} [callback] Optional callback that will handle a reply.
|
||||
*/
|
||||
send: function messageHandlerSend(actionName, data, callback) {
|
||||
var message = {
|
||||
action: actionName,
|
||||
data: data
|
||||
});
|
||||
};
|
||||
if (callback) {
|
||||
var callbackId = this.callbackIndex++;
|
||||
this.callbacks[callbackId] = callback;
|
||||
message.callbackId = callbackId;
|
||||
}
|
||||
this.comObj.postMessage(message);
|
||||
}
|
||||
};
|
||||
|
||||
var WorkerMessageHandler = {
|
||||
setup: function wphSetup(handler) {
|
||||
var pdfDoc = null;
|
||||
var pdfModel = null;
|
||||
|
||||
handler.on('test', function wphSetupTest(data) {
|
||||
handler.send('test', data instanceof Uint8Array);
|
||||
});
|
||||
|
||||
handler.on('workerSrc', function wphSetupWorkerSrc(data) {
|
||||
// In development, the `workerSrc` message is handled in the
|
||||
// `worker_loader.js` file. In production the workerProcessHandler is
|
||||
// called for this. This servers as a dummy to prevent calling an
|
||||
// undefined action `workerSrc`.
|
||||
});
|
||||
|
||||
handler.on('doc', function wphSetupDoc(data) {
|
||||
// Create only the model of the PDFDoc, which is enough for
|
||||
// processing the content of the pdf.
|
||||
pdfDoc = new PDFDocModel(new Stream(data));
|
||||
pdfModel = new PDFDocModel(new Stream(data));
|
||||
});
|
||||
|
||||
handler.on('page_request', function wphSetupPageRequest(pageNum) {
|
||||
pageNum = parseInt(pageNum);
|
||||
|
||||
var page = pdfDoc.getPage(pageNum);
|
||||
|
||||
// The following code does quite the same as
|
||||
// Page.prototype.startRendering, but stops at one point and sends the
|
||||
|
@ -77,12 +103,42 @@ var WorkerMessageHandler = {
|
|||
var start = Date.now();
|
||||
|
||||
var dependency = [];
|
||||
var operatorList = null;
|
||||
try {
|
||||
var page = pdfModel.getPage(pageNum);
|
||||
// Pre compile the pdf page and fetch the fonts/images.
|
||||
operatorList = page.getOperatorList(handler, dependency);
|
||||
} catch (e) {
|
||||
var minimumStackMessage =
|
||||
'worker.js: while trying to getPage() and getOperatorList()';
|
||||
|
||||
// Pre compile the pdf page and fetch the fonts/images.
|
||||
var IRQueue = page.getIRQueue(handler, dependency);
|
||||
// Turn the error into an obj that can be serialized
|
||||
if (typeof e === 'string') {
|
||||
e = {
|
||||
message: e,
|
||||
stack: minimumStackMessage
|
||||
};
|
||||
} else if (typeof e === 'object') {
|
||||
e = {
|
||||
message: e.message || e.toString(),
|
||||
stack: e.stack || minimumStackMessage
|
||||
};
|
||||
} else {
|
||||
e = {
|
||||
message: 'Unknown exception type: ' + (typeof e),
|
||||
stack: minimumStackMessage
|
||||
};
|
||||
}
|
||||
|
||||
console.log('page=%d - getIRQueue: time=%dms, len=%d', pageNum,
|
||||
Date.now() - start, IRQueue.fnArray.length);
|
||||
handler.send('page_error', {
|
||||
pageNum: pageNum,
|
||||
error: e
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('page=%d - getOperatorList: time=%dms, len=%d', pageNum,
|
||||
Date.now() - start, operatorList.fnArray.length);
|
||||
|
||||
// Filter the dependecies for fonts.
|
||||
var fonts = {};
|
||||
|
@ -95,59 +151,10 @@ var WorkerMessageHandler = {
|
|||
|
||||
handler.send('page', {
|
||||
pageNum: pageNum,
|
||||
IRQueue: IRQueue,
|
||||
operatorList: operatorList,
|
||||
depFonts: Object.keys(fonts)
|
||||
});
|
||||
}, this);
|
||||
|
||||
handler.on('font', function wphSetupFont(data) {
|
||||
var objId = data[0];
|
||||
var name = data[1];
|
||||
var file = data[2];
|
||||
var properties = data[3];
|
||||
|
||||
var font = {
|
||||
name: name,
|
||||
file: file,
|
||||
properties: properties
|
||||
};
|
||||
|
||||
// Some fonts don't have a file, e.g. the build in ones like Arial.
|
||||
if (file) {
|
||||
var fontFileDict = new Dict();
|
||||
fontFileDict.map = file.dict.map;
|
||||
|
||||
var fontFile = new Stream(file.bytes, file.start,
|
||||
file.end - file.start, fontFileDict);
|
||||
|
||||
// Check if this is a FlateStream. Otherwise just use the created
|
||||
// Stream one. This makes complex_ttf_font.pdf work.
|
||||
var cmf = file.bytes[0];
|
||||
if ((cmf & 0x0f) == 0x08) {
|
||||
font.file = new FlateStream(fontFile);
|
||||
} else {
|
||||
font.file = fontFile;
|
||||
}
|
||||
}
|
||||
|
||||
var obj = new Font(font.name, font.file, font.properties);
|
||||
|
||||
var str = '';
|
||||
var objData = obj.data;
|
||||
if (objData) {
|
||||
var length = objData.length;
|
||||
for (var j = 0; j < length; ++j)
|
||||
str += String.fromCharCode(objData[j]);
|
||||
}
|
||||
|
||||
obj.str = str;
|
||||
|
||||
// Remove the data array form the font object, as it's not needed
|
||||
// anymore as we sent over the ready str.
|
||||
delete obj.data;
|
||||
|
||||
handler.send('font_ready', [objId, obj]);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -168,6 +175,7 @@ var workerConsole = {
|
|||
action: 'console_error',
|
||||
data: args
|
||||
});
|
||||
throw 'pdf.js execution error';
|
||||
},
|
||||
|
||||
time: function time(name) {
|
||||
|
@ -177,7 +185,7 @@ var workerConsole = {
|
|||
timeEnd: function timeEnd(name) {
|
||||
var time = consoleTimer[name];
|
||||
if (time == null) {
|
||||
throw 'Unkown timer name ' + name;
|
||||
error('Unkown timer name ' + name);
|
||||
}
|
||||
this.log('Timer:', name, Date.now() - time);
|
||||
}
|
||||
|
|
73
apps/files_pdfviewer/js/pdfjs/src/worker_loader.js
Executable file → Normal file
|
@ -3,51 +3,32 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
function onMessageLoader(evt) {
|
||||
// Reset the `onmessage` function as it was only set to call
|
||||
// this function the first time a message is passed to the worker
|
||||
// but shouldn't get called anytime afterwards.
|
||||
this.onmessage = null;
|
||||
// List of files to include;
|
||||
var files = [
|
||||
'core.js',
|
||||
'util.js',
|
||||
'canvas.js',
|
||||
'obj.js',
|
||||
'function.js',
|
||||
'charsets.js',
|
||||
'cidmaps.js',
|
||||
'colorspace.js',
|
||||
'crypto.js',
|
||||
'evaluator.js',
|
||||
'fonts.js',
|
||||
'glyphlist.js',
|
||||
'image.js',
|
||||
'metrics.js',
|
||||
'parser.js',
|
||||
'pattern.js',
|
||||
'stream.js',
|
||||
'worker.js',
|
||||
'../external/jpgjs/jpg.js',
|
||||
'jpx.js',
|
||||
'bidi.js'
|
||||
];
|
||||
|
||||
if (evt.data.action !== 'workerSrc') {
|
||||
throw 'Worker expects first message to be `workerSrc`';
|
||||
}
|
||||
|
||||
// Content of `PDFJS.workerSrc` as defined on the main thread.
|
||||
var workerSrc = evt.data.data;
|
||||
|
||||
// Extract the directory that contains the source files to load.
|
||||
// Assuming the source files have the same relative possition as the
|
||||
// `workerSrc` file.
|
||||
var dir = workerSrc.substring(0, workerSrc.lastIndexOf('/') + 1);
|
||||
|
||||
// List of files to include;
|
||||
var files = [
|
||||
'core.js',
|
||||
'util.js',
|
||||
'canvas.js',
|
||||
'obj.js',
|
||||
'function.js',
|
||||
'charsets.js',
|
||||
'cidmaps.js',
|
||||
'colorspace.js',
|
||||
'crypto.js',
|
||||
'evaluator.js',
|
||||
'fonts.js',
|
||||
'glyphlist.js',
|
||||
'image.js',
|
||||
'metrics.js',
|
||||
'parser.js',
|
||||
'pattern.js',
|
||||
'stream.js',
|
||||
'worker.js',
|
||||
'../external/jpgjs/jpg.js'
|
||||
];
|
||||
|
||||
// Load all the files.
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
importScripts(dir + files[i]);
|
||||
}
|
||||
// Load all the files.
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
importScripts(files[i]);
|
||||
}
|
||||
|
||||
this.onmessage = onMessageLoader;
|
||||
|
|
3
apps/files_pdfviewer/js/pdfjs/web/images/bookmark.svg
Executable file → Normal file
|
@ -20,7 +20,8 @@
|
|||
height="48.000000px"
|
||||
width="48.000000px"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
version="1.1">
|
||||
version="1.1"
|
||||
viewbox="0 0 48 48">
|
||||
<defs
|
||||
id="defs3">
|
||||
<inkscape:perspective
|
||||
|
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
3
apps/files_pdfviewer/js/pdfjs/web/images/check.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg height="40" width="40" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.379,14.729 5.208,11.899 12.958,19.648 25.877,6.733 28.707,9.561 12.958,25.308z" fill="#333333"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 188 B |
3
apps/files_pdfviewer/js/pdfjs/web/images/comment.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg height="40" width="40" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M16,5.333c-7.732,0-14,4.701-14,10.5c0,1.982,0.741,3.833,2.016,5.414L2,25.667l5.613-1.441c2.339,1.317,5.237,2.107,8.387,2.107c7.732,0,14-4.701,14-10.5C30,10.034,23.732,5.333,16,5.333z" fill="#333333"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 289 B |
3
apps/files_pdfviewer/js/pdfjs/web/images/document-print.svg
Executable file → Normal file
|
@ -16,7 +16,8 @@
|
|||
id="svg2994"
|
||||
height="48px"
|
||||
width="48px"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape">
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
viewbox="0 0 48 48">
|
||||
<defs
|
||||
id="defs3">
|
||||
<inkscape:perspective
|
||||
|
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
3
apps/files_pdfviewer/js/pdfjs/web/images/download.svg
Executable file → Normal file
|
@ -16,7 +16,8 @@
|
|||
id="svg2913"
|
||||
height="48px"
|
||||
width="48px"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape">
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
viewbox="0 0 48 48">
|
||||
<defs
|
||||
id="defs3">
|
||||
<inkscape:perspective
|
||||
|
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
3
apps/files_pdfviewer/js/pdfjs/web/images/go-down.svg
Executable file → Normal file
|
@ -19,7 +19,8 @@
|
|||
inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
|
||||
inkscape:export-xdpi="90.000000"
|
||||
inkscape:export-ydpi="90.000000"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape">
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
viewbox="0 0 48 48">
|
||||
<defs
|
||||
id="defs3">
|
||||
<inkscape:perspective
|
||||
|
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.2 KiB |
3
apps/files_pdfviewer/js/pdfjs/web/images/go-up.svg
Executable file → Normal file
|
@ -19,7 +19,8 @@
|
|||
inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
|
||||
inkscape:export-xdpi="90.000000"
|
||||
inkscape:export-ydpi="90.000000"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape">
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
viewbox="0 0 48 48">
|
||||
<defs
|
||||
id="defs3">
|
||||
<inkscape:perspective
|
||||
|
|
Before Width: | Height: | Size: 8 KiB After Width: | Height: | Size: 8 KiB |
0
apps/files_pdfviewer/js/pdfjs/web/images/nav-outline.svg
Executable file → Normal file
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
0
apps/files_pdfviewer/js/pdfjs/web/images/nav-thumbs.svg
Executable file → Normal file
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
297
apps/files_pdfviewer/js/pdfjs/web/images/pin-down.svg
Normal file
|
@ -0,0 +1,297 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="48"
|
||||
height="48"
|
||||
id="svg3075"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
sodipodi:docname="pin-down.svg"
|
||||
viewPort="0 0 48 48">
|
||||
<defs
|
||||
id="defs3077">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient3804">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3806" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop3808" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3965">
|
||||
<stop
|
||||
id="stop3967"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
offset="1"
|
||||
id="stop3969" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3885">
|
||||
<stop
|
||||
style="stop-color:#a8b5e9;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3889" />
|
||||
<stop
|
||||
id="stop3891"
|
||||
offset="1"
|
||||
style="stop-color:#1d4488;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3865">
|
||||
<stop
|
||||
style="stop-color:#0e0ec3;stop-opacity:0"
|
||||
offset="0"
|
||||
id="stop3867" />
|
||||
<stop
|
||||
id="stop3883"
|
||||
offset="0.5"
|
||||
style="stop-color:#95b1e4;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#0d29c0;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3869" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3853">
|
||||
<stop
|
||||
style="stop-color:#717171;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3855" />
|
||||
<stop
|
||||
id="stop3861"
|
||||
offset="0.5"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#818181;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3857" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="radialGradient3792"
|
||||
cx="13.508819"
|
||||
cy="30.521608"
|
||||
fx="13.508819"
|
||||
fy="30.521608"
|
||||
r="13.254341"
|
||||
gradientTransform="matrix(1,0,0,1.045977,0,-1.4434017)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="linearGradient3802"
|
||||
x1="15.306904"
|
||||
y1="13.407407"
|
||||
x2="29.35461"
|
||||
y2="30.15519"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.2304178,0,0,1.1235308,-2.1158755,998.83747)" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3804"
|
||||
id="radialGradient3812"
|
||||
cx="20.111172"
|
||||
cy="28.238274"
|
||||
fx="20.111172"
|
||||
fy="28.238274"
|
||||
r="7.6291947"
|
||||
gradientTransform="matrix(1.2304178,0,0,1.1452771,-2.1158755,998.22337)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="radialGradient3822"
|
||||
cx="23.985939"
|
||||
cy="24.847366"
|
||||
fx="23.985939"
|
||||
fy="24.847366"
|
||||
r="10.593476"
|
||||
gradientTransform="matrix(0.63682384,0.44303926,-1.1714282,1.6838088,35.523491,-26.055439)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter3856"
|
||||
x="-0.30370581"
|
||||
width="1.6074116"
|
||||
y="-0.32771564"
|
||||
height="1.6554313">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="4.7808869"
|
||||
id="feGaussianBlur3858" />
|
||||
</filter>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="radialGradient3865"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,1.045977,0,-1.4434017)"
|
||||
cx="13.508819"
|
||||
cy="30.521608"
|
||||
fx="13.508819"
|
||||
fy="30.521608"
|
||||
r="13.254341" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="linearGradient3867"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.2304178,0,0,1.1235308,-2.1158755,998.83747)"
|
||||
x1="15.306904"
|
||||
y1="13.407407"
|
||||
x2="29.35461"
|
||||
y2="30.15519" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3804"
|
||||
id="radialGradient3869"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.2304178,0,0,1.1452771,-2.1158755,998.22337)"
|
||||
cx="20.111172"
|
||||
cy="28.238274"
|
||||
fx="20.111172"
|
||||
fy="28.238274"
|
||||
r="7.6291947" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="radialGradient3871"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.63682384,0.44303926,-1.1714282,1.6838088,35.523491,-26.055439)"
|
||||
cx="23.985939"
|
||||
cy="24.847366"
|
||||
fx="23.985939"
|
||||
fy="24.847366"
|
||||
r="10.593476" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="linearGradient3875"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.98683814,0,0,0.9524914,3.4991888,1004.1467)"
|
||||
x1="15.306904"
|
||||
y1="13.407407"
|
||||
x2="29.35461"
|
||||
y2="30.15519" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3804"
|
||||
id="radialGradient3877"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.195641,0.23932984,-0.18533175,0.95255553,4.5333676,999.33159)"
|
||||
cx="20.111172"
|
||||
cy="28.238274"
|
||||
fx="20.111172"
|
||||
fy="28.238274"
|
||||
r="7.6291947" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="radialGradient3880"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.5847553,0.52693722,-0.99805104,2.7064773,14.11088,-45.304477)"
|
||||
cx="18.133854"
|
||||
cy="19.778509"
|
||||
fx="18.133854"
|
||||
fy="19.778509"
|
||||
r="10.593476" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="radialGradient3882"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,1.045977,0,-1.4434017)"
|
||||
cx="13.508819"
|
||||
cy="30.521608"
|
||||
fx="13.508819"
|
||||
fy="30.521608"
|
||||
r="13.254341" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="4.9558805"
|
||||
inkscape:cx="3.0237013"
|
||||
inkscape:cy="17.287267"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1291"
|
||||
inkscape:window-height="776"
|
||||
inkscape:window-x="16"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata3080">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1004.3622)">
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter3856)"
|
||||
d="m 14.326415,1019.2702 c -8.3327876,4.0675 -9.8235436,10.8833 -8.8783416,15.1336 4.6840646,7.9754 8.3608166,13.8165 24.0118786,12.9139 9.657617,-3.7312 12.9762,-9.3269 13.519293,-15.7389 -0.547269,-4.3839 -1.957958,-9.3396 -5.649854,-14.9317 -3.965534,-2.471 -6.300859,-4.4246 -10.290805,-4.2374 -8.25193,0.5026 -8.752485,4.4502 -12.712171,6.8605 z"
|
||||
id="path3826"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc"
|
||||
transform="matrix(0.69099294,0,0,0.75978808,7.3427938,249.11025)" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:url(#radialGradient3882);fill-opacity:1;stroke:none"
|
||||
id="path3011"
|
||||
sodipodi:cx="21.176477"
|
||||
sodipodi:cy="31.393986"
|
||||
sodipodi:rx="13.254341"
|
||||
sodipodi:ry="13.863736"
|
||||
d="m 34.430819,31.393986 a 13.254341,13.863736 0 1 1 -26.5086827,0 13.254341,13.863736 0 1 1 26.5086827,0 z"
|
||||
transform="matrix(0.98683814,0,0,0.83062636,2.696034,1005.3655)" />
|
||||
<path
|
||||
style="fill:url(#linearGradient3875);fill-opacity:1;stroke:url(#radialGradient3877);stroke-width:0.9695127;stroke-opacity:1"
|
||||
d="m 17.246758,1026.7905 c -1.7156,4.5052 -2.482464,10.6205 8.726963,10.7476 4.849099,-1.8941 3.522783,-5.3561 6.021544,-11.8282 l -10.973104,-1.5977 z"
|
||||
id="path3794"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:url(#radialGradient3880);fill-opacity:1;stroke:none"
|
||||
id="path3814"
|
||||
sodipodi:cx="24.718111"
|
||||
sodipodi:cy="23.38278"
|
||||
sodipodi:rx="10.593476"
|
||||
sodipodi:ry="9.6854639"
|
||||
d="m 35.311587,23.38278 a 10.593476,9.6854639 0 1 1 -21.186952,0 10.593476,9.6854639 0 1 1 21.186952,0 z"
|
||||
transform="matrix(0.85425691,0,0,0.84187503,3.9779774,1006.7561)" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 9.6 KiB |
230
apps/files_pdfviewer/js/pdfjs/web/images/pin-up.svg
Normal file
|
@ -0,0 +1,230 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="48"
|
||||
height="48"
|
||||
id="svg3075"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
sodipodi:docname="pin-up.svg"
|
||||
viewPort="0 0 48 48">
|
||||
<defs
|
||||
id="defs3077">
|
||||
<linearGradient
|
||||
id="linearGradient3965">
|
||||
<stop
|
||||
id="stop3967"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
offset="1"
|
||||
id="stop3969" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3885">
|
||||
<stop
|
||||
style="stop-color:#a8b5e9;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3889" />
|
||||
<stop
|
||||
id="stop3891"
|
||||
offset="1"
|
||||
style="stop-color:#1d4488;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3865">
|
||||
<stop
|
||||
style="stop-color:#0e0ec3;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3867" />
|
||||
<stop
|
||||
id="stop3883"
|
||||
offset="0.5"
|
||||
style="stop-color:#95b1e4;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#0d29c0;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3869" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3853">
|
||||
<stop
|
||||
style="stop-color:#717171;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3855" />
|
||||
<stop
|
||||
id="stop3861"
|
||||
offset="0.5"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#818181;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3857" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3853"
|
||||
id="linearGradient3859"
|
||||
x1="7.7696066"
|
||||
y1="34.979828"
|
||||
x2="11.854106"
|
||||
y2="39.107044"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(4.8388015,1001.6582)" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="radialGradient3871"
|
||||
cx="14.801222"
|
||||
cy="1030.6609"
|
||||
fx="14.801222"
|
||||
fy="1030.6609"
|
||||
r="10.177785"
|
||||
gradientTransform="matrix(1,0,0,1.0108042,4.8388015,-13.880529)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3865"
|
||||
id="linearGradient3881"
|
||||
x1="15.012629"
|
||||
y1="11.922465"
|
||||
x2="31.098303"
|
||||
y2="28.858271"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,0.97315436,4.8388015,1002.4769)" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="radialGradient3909"
|
||||
cx="16.437693"
|
||||
cy="22.596292"
|
||||
fx="16.437693"
|
||||
fy="22.596292"
|
||||
r="1.7789712"
|
||||
gradientTransform="matrix(1,0,0,8.3599999,0,-166.30871)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3865"
|
||||
id="linearGradient3927"
|
||||
x1="26.47109"
|
||||
y1="1010.7343"
|
||||
x2="35.294788"
|
||||
y2="1019.8425"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(4.5541661,-2.1347654)" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3965"
|
||||
id="radialGradient3995"
|
||||
cx="23.189369"
|
||||
cy="25.704245"
|
||||
fx="23.189369"
|
||||
fy="25.704245"
|
||||
r="37.336674"
|
||||
gradientTransform="matrix(1,0,0,1.0332422,0,-0.85446479)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter4009"
|
||||
x="-0.19299152"
|
||||
width="1.385983"
|
||||
y="-0.18351803"
|
||||
height="1.3670361">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="3.8667902"
|
||||
id="feGaussianBlur4011" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="3.2819435"
|
||||
inkscape:cx="18.697469"
|
||||
inkscape:cy="17.287267"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="970"
|
||||
inkscape:window-height="778"
|
||||
inkscape:window-x="284"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata3080">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1004.3622)">
|
||||
<path
|
||||
style="fill:url(#radialGradient3995);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1.0;filter:url(#filter4009)"
|
||||
d="M -0.85390618,50.988672 14.231769,27.790888 C 12.21393,25.133052 9.5514307,24.605255 9.9622384,18.824874 13.947134,14.236899 17.362759,16.258973 21.347654,16.54779 l 8.966014,-8.6813789 c 1.467204,-2.4778468 -1.023584,-4.6422045 0.569271,-7.25820222 4.802307,-0.84764718 6.662499,1.15219542 11.527733,6.26197842 4.061691,4.1873637 5.648882,7.0611607 4.411848,9.5352857 -1.075122,2.776443 -4.518349,-0.692782 -5.835025,0.56927 l -9.108332,10.104556 c -0.418785,3.74872 2.078647,7.861968 -1.280859,11.243098 -4.132171,0.818036 -6.734336,-1.933944 -9.819921,-3.557942 z"
|
||||
id="path3955"
|
||||
inkscape:connector-curvature="0"
|
||||
transform="translate(0,1004.3622)"
|
||||
sodipodi:nodetypes="ccccccccccccc" />
|
||||
<g
|
||||
id="g3929">
|
||||
<path
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3083"
|
||||
d="m 3.2884874,1051.0662 c 3.1862139,-6.2911 11.3693156,-15.19 15.4471616,-20.0327 l 2.86533,3.0086 c -3.476851,3.6575 -10.192375,10.8664 -18.3124916,17.0241 z"
|
||||
style="fill:url(#linearGradient3859);fill-opacity:1;stroke:#a5a5a5;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3863"
|
||||
d="m 11.10078,1023.3294 c 5.038264,10.1095 11.83652,14.8875 18.358981,18.2167 1.196291,-2.5422 1.454996,-5.6203 0,-9.6776 l -8.539061,-8.6814 c -3.704654,-1.8936 -6.871076,-1.3652 -9.81992,0.1423 z"
|
||||
style="fill:url(#radialGradient3871);fill-opacity:1;stroke:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3873"
|
||||
d="m 33.729292,1011.5171 -13.235545,11.4952 c 2.869602,4.2703 6.221839,7.4544 9.108332,9.1408 l 11.385416,-13.0187 z"
|
||||
style="fill:url(#linearGradient3881);fill-opacity:1;stroke:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3893"
|
||||
d="m 33.228885,1011.6148 c 1.843189,2.7806 3.431654,5.6597 7.19852,7.6953 l 5.398891,1.7423 c -7.6738,-4.7914 -10.989683,-9.5828 -13.947133,-14.3741 z"
|
||||
style="fill:url(#linearGradient3927);fill-opacity:1;stroke:none" />
|
||||
<path
|
||||
transform="matrix(0.68275275,-0.5590416,0.45791123,0.47036287,17.42507,1012.2127)"
|
||||
d="m 18.216664,22.596292 a 1.7789712,14.872199 0 1 1 -3.557943,0 1.7789712,14.872199 0 1 1 3.557943,0 z"
|
||||
sodipodi:ry="14.872199"
|
||||
sodipodi:rx="1.7789712"
|
||||
sodipodi:cy="22.596292"
|
||||
sodipodi:cx="16.437693"
|
||||
id="path3901"
|
||||
style="fill:url(#radialGradient3909);fill-opacity:1;stroke:none"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 8.1 KiB |
7
apps/files_pdfviewer/js/pdfjs/web/images/zoom-in.svg
Executable file → Normal file
|
@ -16,7 +16,8 @@
|
|||
inkscape:version="0.46"
|
||||
sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
|
||||
sodipodi:docname="list-add.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape">
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
viewbox="0 0 48 48">
|
||||
<defs
|
||||
id="defs6433">
|
||||
<inkscape:perspective
|
||||
|
@ -418,12 +419,12 @@
|
|||
d="M 33.278212 34.94062 A 10.31934 2.320194 0 1 1 12.639532,34.94062 A 10.31934 2.320194 0 1 1 33.278212 34.94062 z"
|
||||
transform="matrix(1.550487,0,0,1.978714,-12.4813,-32.49103)" />
|
||||
<path
|
||||
style="font-size:59.901077px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;fill:#75a1d0;fill-opacity:1.0000000;stroke:#3465a4;stroke-width:1.0000004px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
|
||||
style="fill:#75a1d0;fill-opacity:1.0000000;stroke:#3465a4;stroke-width:1.0000004px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
|
||||
d="M 27.514356,37.542682 L 27.514356,28.515722 L 37.492820,28.475543 L 37.492820,21.480219 L 27.523285,21.480219 L 27.514356,11.520049 L 20.498082,11.531210 L 20.502546,21.462362 L 10.512920,21.536022 L 10.477206,28.504561 L 20.511475,28.475543 L 20.518171,37.515896 L 27.514356,37.542682 z "
|
||||
id="text1314"
|
||||
sodipodi:nodetypes="ccccccccccccc" />
|
||||
<path
|
||||
style="font-size:59.901077px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;opacity:0.40860215;fill:url(#linearGradient4975);fill-opacity:1.0000000;stroke:url(#linearGradient7922);stroke-width:1.0000006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
|
||||
style="opacity:0.40860215;fill:url(#linearGradient4975);fill-opacity:1.0000000;stroke:url(#linearGradient7922);stroke-width:1.0000006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
|
||||
d="M 26.498702,36.533920 L 26.498702,27.499738 L 36.501304,27.499738 L 36.494607,22.475309 L 26.507630,22.475309 L 26.507630,12.480335 L 21.512796,12.498193 L 21.521725,22.475309 L 11.495536,22.493166 L 11.468750,27.466256 L 21.533143,27.475185 L 21.519750,36.502670 L 26.498702,36.533920 z "
|
||||
id="path7076"
|
||||
sodipodi:nodetypes="ccccccccccccc" />
|
||||
|
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
7
apps/files_pdfviewer/js/pdfjs/web/images/zoom-out.svg
Executable file → Normal file
|
@ -16,7 +16,8 @@
|
|||
inkscape:version="0.46"
|
||||
sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
|
||||
sodipodi:docname="list-remove.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape">
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
viewbox="0 0 48 48">
|
||||
<defs
|
||||
id="defs6433">
|
||||
<inkscape:perspective
|
||||
|
@ -406,12 +407,12 @@
|
|||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<path
|
||||
style="font-size:59.901077px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;fill:#75a1d0;fill-opacity:1.0000000;stroke:#3465a4;stroke-width:1.0000004px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
|
||||
style="fill:#75a1d0;fill-opacity:1.0000000;stroke:#3465a4;stroke-width:1.0000004px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
|
||||
d="M 27.514356,28.359472 L 39.633445,28.475543 L 39.633445,21.480219 L 27.523285,21.480219 L 20.502546,21.462362 L 8.5441705,21.489147 L 8.5084565,28.457686 L 20.511475,28.475543 L 27.514356,28.359472 z "
|
||||
id="text1314"
|
||||
sodipodi:nodetypes="ccccccccc" />
|
||||
<path
|
||||
style="font-size:59.901077px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;opacity:0.40860215;fill:url(#linearGradient4975);fill-opacity:1.0000000;stroke:url(#linearGradient7922);stroke-width:1.0000006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
|
||||
style="opacity:0.40860215;fill:url(#linearGradient4975);fill-opacity:1.0000000;stroke:url(#linearGradient7922);stroke-width:1.0000006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
|
||||
d="M 38.579429,27.484113 L 38.588357,22.475309 L 9.5267863,22.493166 L 9.5000003,27.466256 L 38.579429,27.484113 z "
|
||||
id="path7076"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
|
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 13 KiB |
|
@ -1,4 +1,5 @@
|
|||
FileList={
|
||||
useUndo:true,
|
||||
update:function(fileListHtml) {
|
||||
$('#fileList').empty().html(fileListHtml);
|
||||
},
|
||||
|
@ -163,7 +164,7 @@ FileList={
|
|||
});
|
||||
},
|
||||
do_delete:function(files){
|
||||
if(FileList.deleteFiles){//finish any ongoing deletes first
|
||||
if(FileList.deleteFiles || !FileList.useUndo){//finish any ongoing deletes first
|
||||
FileList.finishDelete(function(){
|
||||
FileList.do_delete(files);
|
||||
});
|
||||
|
@ -196,7 +197,6 @@ FileList={
|
|||
boolOperationFinished(data, function(){
|
||||
$('#notification').fadeOut();
|
||||
$.each(FileList.deleteFiles,function(index,file){
|
||||
// alert(file);
|
||||
FileList.remove(file);
|
||||
});
|
||||
FileList.deleteCanceled=true;
|
||||
|
@ -225,7 +225,7 @@ $(document).ready(function(){
|
|||
}
|
||||
$('#notification').fadeOut();
|
||||
});
|
||||
|
||||
FileList.useUndo=('onbeforeunload' in window)
|
||||
$(window).bind('beforeunload', function (){
|
||||
FileList.finishDelete(null,true);
|
||||
});
|
||||
|
|