mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 852981 - Update pdf.js to version 0.7.390. r=bdahl
This commit is contained in:
parent
f98ed9f89e
commit
977ac941d8
@ -1,4 +1,4 @@
|
||||
This is the pdf.js project output, https://github.com/mozilla/pdf.js
|
||||
|
||||
Current extension version is: 0.7.337
|
||||
Current extension version is: 0.7.390
|
||||
|
||||
|
155
browser/extensions/pdfjs/components/PdfRedirector.js
Normal file
155
browser/extensions/pdfjs/components/PdfRedirector.js
Normal file
@ -0,0 +1,155 @@
|
||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
/* Copyright 2012 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/* jshint esnext:true */
|
||||
/* globals Components, Services, XPCOMUtils, NetUtil, dump */
|
||||
|
||||
'use strict';
|
||||
|
||||
var EXPORTED_SYMBOLS = ['PdfRedirector'];
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
const Cu = Components.utils;
|
||||
|
||||
const PDF_CONTENT_TYPE = 'application/pdf';
|
||||
const FIREFOX_ID = '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}';
|
||||
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
Cu.import('resource://gre/modules/NetUtil.jsm');
|
||||
|
||||
|
||||
function getDOMWindow(aChannel) {
|
||||
var requestor = aChannel.notificationCallbacks ?
|
||||
aChannel.notificationCallbacks :
|
||||
aChannel.loadGroup.notificationCallbacks;
|
||||
var win = requestor.getInterface(Components.interfaces.nsIDOMWindow);
|
||||
return win;
|
||||
}
|
||||
|
||||
function getObjectUrl(window) {
|
||||
var url;
|
||||
var element = window.frameElement;
|
||||
var isOverlay = false;
|
||||
var params = {};
|
||||
if (element) {
|
||||
var tagName = element.nodeName;
|
||||
while (tagName != 'EMBED' && tagName != 'OBJECT') {
|
||||
// plugin overlay skipping until the target plugin is found
|
||||
isOverlay = true;
|
||||
element = element.parentNode;
|
||||
if (!element)
|
||||
throw 'Plugin element is not found';
|
||||
tagName = element.nodeName;
|
||||
}
|
||||
if (tagName == 'EMBED') {
|
||||
for (var i = 0; i < element.attributes.length; ++i) {
|
||||
params[element.attributes[i].localName] = element.attributes[i].value;
|
||||
}
|
||||
url = params.src;
|
||||
} else {
|
||||
for (var i = 0; i < element.childNodes.length; ++i) {
|
||||
var paramElement = element.childNodes[i];
|
||||
if (paramElement.nodeType != Ci.nsIDOMNode.ELEMENT_NODE ||
|
||||
paramElement.nodeName != 'PARAM') {
|
||||
continue;
|
||||
}
|
||||
|
||||
params[paramElement.getAttribute('name')] =
|
||||
paramElement.getAttribute('value');
|
||||
}
|
||||
var dataAttribute = element.getAttribute('data');
|
||||
url = dataAttribute || params.movie || params.src;
|
||||
}
|
||||
}
|
||||
if (!url) {
|
||||
return url; // src is not specified
|
||||
}
|
||||
|
||||
var element = window.frameElement;
|
||||
// XXX base uri?
|
||||
var baseUri = !element ? null :
|
||||
Services.io.newURI(element.ownerDocument.location.href, null, null);
|
||||
|
||||
return Services.io.newURI(url, null, baseUri).spec;
|
||||
}
|
||||
|
||||
function PdfRedirector() {
|
||||
}
|
||||
|
||||
PdfRedirector.prototype = {
|
||||
|
||||
// properties required for XPCOM registration:
|
||||
classID: Components.ID('{8cbfd8d0-2042-4976-b3ef-d9dee1efb975}'),
|
||||
classDescription: 'pdf.js Redirector',
|
||||
contractID:
|
||||
'@mozilla.org/streamconv;1?from=application/x-moz-playpreview-pdfjs&to=*/*',
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIStreamConverter,
|
||||
Ci.nsIStreamListener,
|
||||
Ci.nsIRequestObserver
|
||||
]),
|
||||
|
||||
// nsIStreamConverter::convert
|
||||
convert: function(aFromStream, aFromType, aToType, aCtxt) {
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
|
||||
// nsIStreamConverter::asyncConvertData
|
||||
asyncConvertData: function(aFromType, aToType, aListener, aCtxt) {
|
||||
// Store the listener passed to us
|
||||
this.listener = aListener;
|
||||
},
|
||||
|
||||
// nsIStreamListener::onDataAvailable
|
||||
onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) {
|
||||
// Do nothing since all the data loading is handled by the viewer.
|
||||
},
|
||||
|
||||
// nsIRequestObserver::onStartRequest
|
||||
onStartRequest: function(aRequest, aContext) {
|
||||
// Setup the request so we can use it below.
|
||||
aRequest.QueryInterface(Ci.nsIChannel);
|
||||
// Cancel the request so the viewer can handle it.
|
||||
aRequest.cancel(Cr.NS_BINDING_ABORTED);
|
||||
|
||||
var domWindow = getDOMWindow(aRequest);
|
||||
var pdfUrl = getObjectUrl(domWindow);
|
||||
if (!pdfUrl) {
|
||||
Services.console.logStringMessage(
|
||||
'PdfRedirector.js: PDF location is not specified for OBJECT/EMBED tag');
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a new channel that is viewer loaded as a resource.
|
||||
var ioService = Services.io;
|
||||
var channel = ioService.newChannel(pdfUrl, null, null);
|
||||
|
||||
channel.loadGroup = aRequest.loadGroup;
|
||||
|
||||
channel.asyncOpen(this.listener, aContext);
|
||||
},
|
||||
|
||||
// nsIRequestObserver::onStopRequest
|
||||
onStopRequest: function(aRequest, aContext, aStatusCode) {
|
||||
// Do nothing
|
||||
}
|
||||
};
|
||||
|
||||
var NSGetFactory = XPCOMUtils.generateNSGetFactory([PdfRedirector]);
|
@ -337,6 +337,7 @@ ChromeActions.prototype = {
|
||||
}, '*');
|
||||
};
|
||||
|
||||
var self = this;
|
||||
this.dataListener.oncomplete =
|
||||
function ChromeActions_dataListenerComplete(data, errorCode) {
|
||||
|
||||
@ -346,7 +347,7 @@ ChromeActions.prototype = {
|
||||
errorCode: errorCode
|
||||
}, '*');
|
||||
|
||||
delete this.dataListener;
|
||||
delete self.dataListener;
|
||||
};
|
||||
|
||||
return true;
|
||||
@ -385,21 +386,19 @@ ChromeActions.prototype = {
|
||||
var message = getLocalizedString(strings, 'unsupported_feature');
|
||||
|
||||
var notificationBox = null;
|
||||
// Multiple browser windows can be opened, finding one for notification box
|
||||
var windowsEnum = Services.wm
|
||||
.getZOrderDOMWindowEnumerator('navigator:browser', true);
|
||||
while (windowsEnum.hasMoreElements()) {
|
||||
var win = windowsEnum.getNext();
|
||||
if (win.closed)
|
||||
continue;
|
||||
var browser = win.gBrowser.getBrowserForDocument(domWindow.top.document);
|
||||
if (browser) {
|
||||
// right window/browser is found, getting the notification box
|
||||
notificationBox = win.gBrowser.getNotificationBox(browser);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!notificationBox) {
|
||||
try {
|
||||
// Based on MDN's "Working with windows in chrome code"
|
||||
var mainWindow = domWindow
|
||||
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindow);
|
||||
var browser = mainWindow.gBrowser
|
||||
.getBrowserForDocument(domWindow.top.document);
|
||||
notificationBox = mainWindow.gBrowser.getNotificationBox(browser);
|
||||
} catch (e) {
|
||||
log('Unable to get a notification box for the fallback message');
|
||||
return;
|
||||
}
|
||||
|
@ -33,11 +33,15 @@ const PDF_CONTENT_TYPE = 'application/pdf';
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
Cu.import('resource://pdf.js.components/PdfStreamConverter.js');
|
||||
Cu.import('resource://pdf.js.components/PdfRedirector.js');
|
||||
|
||||
let Svc = {};
|
||||
XPCOMUtils.defineLazyServiceGetter(Svc, 'mime',
|
||||
'@mozilla.org/mime;1',
|
||||
'nsIMIMEService');
|
||||
XPCOMUtils.defineLazyServiceGetter(Svc, 'pluginHost',
|
||||
'@mozilla.org/plugin/host;1',
|
||||
'nsIPluginHost');
|
||||
|
||||
function getBoolPref(aPref, aDefaultValue) {
|
||||
try {
|
||||
@ -55,8 +59,10 @@ function getIntPref(aPref, aDefaultValue) {
|
||||
}
|
||||
}
|
||||
|
||||
// Register/unregister a constructor as a component.
|
||||
let Factory = {
|
||||
// Factory that registers/unregisters a constructor as a component.
|
||||
function Factory() {}
|
||||
|
||||
Factory.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory]),
|
||||
_targetConstructor: null,
|
||||
|
||||
@ -193,7 +199,14 @@ let PdfJs = {
|
||||
if (this._registered)
|
||||
return;
|
||||
|
||||
Factory.register(PdfStreamConverter);
|
||||
this._pdfStreamConverterFactory = new Factory();
|
||||
this._pdfStreamConverterFactory.register(PdfStreamConverter);
|
||||
|
||||
this._pdfRedirectorFactory = new Factory();
|
||||
this._pdfRedirectorFactory.register(PdfRedirector);
|
||||
Svc.pluginHost.registerPlayPreviewMimeType('application/pdf', true,
|
||||
'data:application/x-moz-playpreview-pdfjs;,');
|
||||
|
||||
this._registered = true;
|
||||
},
|
||||
|
||||
@ -201,7 +214,13 @@ let PdfJs = {
|
||||
if (!this._registered)
|
||||
return;
|
||||
|
||||
Factory.unregister();
|
||||
this._pdfStreamConverterFactory.unregister();
|
||||
delete this._pdfStreamConverterFactory;
|
||||
|
||||
this._pdfRedirectorFactory.unregister;
|
||||
delete this._pdfRedirectorFactory;
|
||||
Svc.pluginHost.unregisterPlayPreviewMimeType('application/pdf');
|
||||
|
||||
this._registered = false;
|
||||
}
|
||||
};
|
||||
|
@ -16,8 +16,8 @@
|
||||
*/
|
||||
|
||||
var PDFJS = {};
|
||||
PDFJS.version = '0.7.337';
|
||||
PDFJS.build = 'f58aee1';
|
||||
PDFJS.version = '0.7.390';
|
||||
PDFJS.build = '921f321';
|
||||
|
||||
(function pdfjsWrapper() {
|
||||
// Use strict in our context only - users might not want it
|
||||
@ -832,6 +832,23 @@ var Util = PDFJS.Util = (function UtilClosure() {
|
||||
return [xt, yt];
|
||||
};
|
||||
|
||||
// Applies the transform to the rectangle and finds the minimum axially
|
||||
// aligned bounding box.
|
||||
Util.getAxialAlignedBoundingBox =
|
||||
function Util_getAxialAlignedBoundingBox(r, m) {
|
||||
|
||||
var p1 = Util.applyTransform(r, m);
|
||||
var p2 = Util.applyTransform(r.slice(2, 4), m);
|
||||
var p3 = Util.applyTransform([r[0], r[3]], m);
|
||||
var p4 = Util.applyTransform([r[2], r[1]], m);
|
||||
return [
|
||||
Math.min(p1[0], p2[0], p3[0], p4[0]),
|
||||
Math.min(p1[1], p2[1], p3[1], p4[1]),
|
||||
Math.max(p1[0], p2[0], p3[0], p4[0]),
|
||||
Math.max(p1[1], p2[1], p3[1], p4[1])
|
||||
];
|
||||
};
|
||||
|
||||
Util.inverseTransform = function Util_inverseTransform(m) {
|
||||
var d = m[0] * m[3] - m[1] * m[2];
|
||||
return [m[3] / d, -m[1] / d, -m[2] / d, m[0] / d,
|
||||
@ -2260,6 +2277,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
this.objs = objs;
|
||||
this.textLayer = textLayer;
|
||||
this.imageLayer = imageLayer;
|
||||
this.groupStack = [];
|
||||
if (canvasCtx) {
|
||||
addContextCurrentTransform(canvasCtx);
|
||||
}
|
||||
@ -2392,6 +2410,25 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
return tmpCanvas;
|
||||
}
|
||||
|
||||
function copyCtxState(sourceCtx, destCtx) {
|
||||
var properties = ['strokeStyle', 'fillStyle', 'fillRule', 'globalAlpha',
|
||||
'lineWidth', 'lineCap', 'lineJoin', 'miterLimit',
|
||||
'globalCompositeOperation', 'font'];
|
||||
for (var i = 0, ii = properties.length; i < ii; i++) {
|
||||
var property = properties[i];
|
||||
if (property in sourceCtx) {
|
||||
destCtx[property] = sourceCtx[property];
|
||||
}
|
||||
}
|
||||
if ('setLineDash' in sourceCtx) {
|
||||
destCtx.setLineDash(sourceCtx.getLineDash());
|
||||
destCtx.lineDashOffset = sourceCtx.lineDashOffset;
|
||||
} else if ('mozDash' in sourceCtx) {
|
||||
destCtx.mozDash = sourceCtx.mozDash;
|
||||
destCtx.mozDashOffset = sourceCtx.mozDashOffset;
|
||||
}
|
||||
}
|
||||
|
||||
var LINE_CAP_STYLES = ['butt', 'round', 'square'];
|
||||
var LINE_JOIN_STYLES = ['miter', 'round', 'bevel'];
|
||||
var NORMAL_CLIP = {};
|
||||
@ -2596,6 +2633,22 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
this.current.fillAlpha = state[1];
|
||||
this.ctx.globalAlpha = state[1];
|
||||
break;
|
||||
case 'BM':
|
||||
if (value && value.name && (value.name !== 'Normal')) {
|
||||
var mode = value.name.replace(/([A-Z])/g,
|
||||
function(c) {
|
||||
return '-' + c.toLowerCase();
|
||||
}
|
||||
).substring(1);
|
||||
this.ctx.globalCompositeOperation = mode;
|
||||
if (this.ctx.globalCompositeOperation !== mode) {
|
||||
warn('globalCompositeOperation "' + mode +
|
||||
'" is not supported');
|
||||
}
|
||||
} else {
|
||||
this.ctx.globalCompositeOperation = 'source-over';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -3008,7 +3061,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
var character = glyph.fontChar;
|
||||
var vmetric = glyph.vmetric || defaultVMetrics;
|
||||
if (vertical) {
|
||||
var vx = vmetric[1] * fontSize * current.fontMatrix[0];
|
||||
var vx = glyph.vmetric ? vmetric[1] : glyph.width * 0.5;
|
||||
vx = -vx * fontSize * current.fontMatrix[0];
|
||||
var vy = vmetric[2] * fontSize * current.fontMatrix[0];
|
||||
}
|
||||
var width = vmetric ? -vmetric[0] : glyph.width;
|
||||
@ -3083,7 +3137,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
geom.canvasWidth = canvasWidth;
|
||||
if (vertical) {
|
||||
var vmetric = font.defaultVMetrics;
|
||||
geom.x -= vmetric[1] * fontSize * current.fontMatrix[0] /
|
||||
geom.x += vmetric[1] * fontSize * current.fontMatrix[0] /
|
||||
fontSizeScale * geom.hScale;
|
||||
geom.y += vmetric[2] * fontSize * current.fontMatrix[0] /
|
||||
fontSizeScale * geom.vScale;
|
||||
@ -3144,7 +3198,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
if (vertical) {
|
||||
var fontSizeScale = current.fontSizeScale;
|
||||
var vmetric = font.defaultVMetrics;
|
||||
geom.x -= vmetric[1] * fontSize * current.fontMatrix[0] /
|
||||
geom.x += vmetric[1] * fontSize * current.fontMatrix[0] /
|
||||
fontSizeScale * geom.hScale;
|
||||
geom.y += vmetric[2] * fontSize * current.fontMatrix[0] /
|
||||
fontSizeScale * geom.vScale;
|
||||
@ -3365,6 +3419,89 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
} while (this.current.paintFormXObjectDepth >= depth);
|
||||
},
|
||||
|
||||
beginGroup: function CanvasGraphics_beginGroup(group) {
|
||||
this.save();
|
||||
var currentCtx = this.ctx;
|
||||
// TODO non-isolated groups - according to Rik at adobe non-isolated
|
||||
// group results aren't usually that different and they even have tools
|
||||
// that ignore this setting. Notes from Rik on implmenting:
|
||||
// - When you encounter an transparency group, create a new canvas with
|
||||
// the dimensions of the bbox
|
||||
// - copy the content from the previous canvas to the new canvas
|
||||
// - draw as usual
|
||||
// - remove the backdrop alpha:
|
||||
// alphaNew = 1 - (1 - alpha)/(1 - alphaBackdrop) with 'alpha' the alpha
|
||||
// value of your transparency group and 'alphaBackdrop' the alpha of the
|
||||
// backdrop
|
||||
// - remove background color:
|
||||
// colorNew = color - alphaNew *colorBackdrop /(1 - alphaNew)
|
||||
if (!group.isolated) {
|
||||
TODO('Support non-isolated groups.');
|
||||
}
|
||||
|
||||
// TODO knockout - supposedly possible with the clever use of compositing
|
||||
// modes.
|
||||
if (group.knockout) {
|
||||
TODO('Support knockout groups.');
|
||||
}
|
||||
|
||||
var currentTransform = currentCtx.mozCurrentTransform;
|
||||
if (group.matrix) {
|
||||
currentCtx.transform.apply(currentCtx, group.matrix);
|
||||
}
|
||||
assert(group.bbox, 'Bounding box is required.');
|
||||
|
||||
// Based on the current transform figure out how big the bounding box
|
||||
// will actually be.
|
||||
var bounds = Util.getAxialAlignedBoundingBox(
|
||||
group.bbox,
|
||||
currentCtx.mozCurrentTransform);
|
||||
// Use ceil in case we're between sizes so we don't create canvas that is
|
||||
// too small.
|
||||
var drawnWidth = Math.ceil(bounds[2] - bounds[0]);
|
||||
var drawnHeight = Math.ceil(bounds[3] - bounds[1]);
|
||||
var scratchCanvas = createScratchCanvas(drawnWidth, drawnHeight);
|
||||
var groupCtx = scratchCanvas.getContext('2d');
|
||||
addContextCurrentTransform(groupCtx);
|
||||
// Since we created a new canvas that is just the size of the bounding box
|
||||
// we have to translate the group ctx.
|
||||
var offsetX = bounds[0];
|
||||
var offsetY = bounds[1];
|
||||
groupCtx.translate(-offsetX, -offsetY);
|
||||
groupCtx.transform.apply(groupCtx, currentTransform);
|
||||
|
||||
// Setup the current ctx so when the group is popped we draw it the right
|
||||
// location.
|
||||
currentCtx.setTransform(1, 0, 0, 1, 0, 0);
|
||||
currentCtx.translate(offsetX, offsetY);
|
||||
|
||||
// The transparency group inherits all off the current graphics state
|
||||
// except the blend mode, soft mask, and alpha constants.
|
||||
copyCtxState(currentCtx, groupCtx);
|
||||
this.ctx = groupCtx;
|
||||
this.setGState([
|
||||
['SMask', 'None'],
|
||||
['BM', 'Normal'],
|
||||
['ca', 1],
|
||||
['CA', 1]
|
||||
]);
|
||||
this.groupStack.push(currentCtx);
|
||||
},
|
||||
|
||||
endGroup: function CanvasGraphics_endGroup(group) {
|
||||
var groupCtx = this.ctx;
|
||||
this.ctx = this.groupStack.pop();
|
||||
// Turn off image smoothing to avoid sub pixel interpolation which can
|
||||
// look kind of blurry for some pdfs.
|
||||
if ('imageSmoothingEnabled' in this.ctx) {
|
||||
this.ctx.imageSmoothingEnabled = false;
|
||||
} else {
|
||||
this.ctx.mozImageSmoothingEnabled = false;
|
||||
}
|
||||
this.ctx.drawImage(groupCtx.canvas, 0, 0);
|
||||
this.restore();
|
||||
},
|
||||
|
||||
paintJpegXObject: function CanvasGraphics_paintJpegXObject(objId, w, h) {
|
||||
var domImage = this.objs.get(objId);
|
||||
if (!domImage) {
|
||||
@ -3920,7 +4057,7 @@ var Catalog = (function CatalogClosure() {
|
||||
if (isStream(js)) {
|
||||
js = bytesToString(js.getBytes());
|
||||
}
|
||||
javaScript.push(js);
|
||||
javaScript.push(stringToPDFString(js));
|
||||
}
|
||||
}
|
||||
return shadow(this, 'javaScript', javaScript);
|
||||
@ -4385,6 +4522,9 @@ var NameTree = (function NameTreeClosure() {
|
||||
while (queue.length > 0) {
|
||||
var i, n;
|
||||
var obj = xref.fetchIfRef(queue.shift());
|
||||
if (!isDict(obj)) {
|
||||
continue;
|
||||
}
|
||||
if (obj.has('Kids')) {
|
||||
var kids = obj.get('Kids');
|
||||
for (i = 0, n = kids.length; i < n; i++) {
|
||||
@ -14652,6 +14792,60 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
return loadedName;
|
||||
}
|
||||
|
||||
function buildFormXObject(xobj, smask) {
|
||||
var matrix = xobj.dict.get('Matrix');
|
||||
var bbox = xobj.dict.get('BBox');
|
||||
var group = xobj.dict.get('Group');
|
||||
if (group) {
|
||||
var groupOptions = {
|
||||
matrix: matrix,
|
||||
bbox: bbox,
|
||||
smask: !!smask,
|
||||
isolated: false,
|
||||
knockout: false
|
||||
};
|
||||
|
||||
var groupSubtype = group.get('S');
|
||||
if (isName(groupSubtype) && groupSubtype.name === 'Transparency') {
|
||||
groupOptions.isolated = group.get('I') || false;
|
||||
groupOptions.knockout = group.get('K') || false;
|
||||
// There is also a group colorspace, but since we put everything in
|
||||
// RGB I'm not sure we need it.
|
||||
}
|
||||
fnArray.push('beginGroup');
|
||||
argsArray.push([groupOptions]);
|
||||
}
|
||||
|
||||
fnArray.push('paintFormXObjectBegin');
|
||||
argsArray.push([matrix, bbox]);
|
||||
|
||||
// This adds the operatorList of the xObj to the current queue.
|
||||
var depIdx = dependencyArray.length;
|
||||
|
||||
// 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.
|
||||
self.getOperatorList(xobj,
|
||||
xobj.dict.get('Resources') || resources,
|
||||
dependencyArray, queue);
|
||||
|
||||
self.getOperatorList(xobj,
|
||||
xobj.dict.get('Resources') || resources,
|
||||
dependencyArray, queue);
|
||||
|
||||
// Add the dependencies that are required to execute the
|
||||
// operatorList.
|
||||
insertDependency(dependencyArray.slice(depIdx));
|
||||
|
||||
fnArray.push('paintFormXObjectEnd');
|
||||
argsArray.push([]);
|
||||
|
||||
if (group) {
|
||||
fnArray.push('endGroup');
|
||||
argsArray.push([groupOptions]);
|
||||
}
|
||||
}
|
||||
|
||||
function buildPaintImageXObject(image, inline) {
|
||||
var dict = image.dict;
|
||||
var w = dict.get('Width', 'W');
|
||||
@ -14825,28 +15019,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
);
|
||||
|
||||
if ('Form' == type.name) {
|
||||
var matrix = xobj.dict.get('Matrix');
|
||||
var bbox = xobj.dict.get('BBox');
|
||||
|
||||
fnArray.push('paintFormXObjectBegin');
|
||||
argsArray.push([matrix, bbox]);
|
||||
|
||||
// This adds the operatorList of the xObj to the current queue.
|
||||
var depIdx = dependencyArray.length;
|
||||
|
||||
// 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
|
||||
// operatorList.
|
||||
insertDependency(dependencyArray.slice(depIdx));
|
||||
|
||||
fn = 'paintFormXObjectEnd';
|
||||
buildFormXObject(xobj);
|
||||
args = [];
|
||||
continue;
|
||||
} else if ('Image' == type.name) {
|
||||
buildPaintImageXObject(xobj, false);
|
||||
} else {
|
||||
@ -14905,6 +15080,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
case 'FL':
|
||||
case 'CA':
|
||||
case 'ca':
|
||||
case 'BM':
|
||||
gsStateObj.push([key, value]);
|
||||
break;
|
||||
case 'Font':
|
||||
@ -14914,11 +15090,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
value[1]
|
||||
]);
|
||||
break;
|
||||
case 'BM':
|
||||
// We support the default so don't trigger the TODO.
|
||||
if (!isName(value) || value.name != 'Normal')
|
||||
TODO('graphic state operator ' + key);
|
||||
break;
|
||||
case 'SMask':
|
||||
// We support the default so don't trigger the TODO.
|
||||
if (!isName(value) || value.name != 'None')
|
||||
@ -15459,7 +15630,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
|
||||
if (properties.vertical) {
|
||||
var vmetrics = dict.get('DW2') || [880, -1000];
|
||||
defaultVMetrics = [vmetrics[1], vmetrics[1] / 2, vmetrics[0]];
|
||||
defaultVMetrics = [vmetrics[1], defaultWidth * 0.5, vmetrics[0]];
|
||||
vmetrics = dict.get('W2');
|
||||
if (vmetrics) {
|
||||
for (var i = 0, ii = vmetrics.length; i < ii; i++) {
|
||||
@ -16073,7 +16244,23 @@ var nonStdFontMap = {
|
||||
'LucidaConsole': 'Courier',
|
||||
'LucidaConsole-Bold': 'Courier-Bold',
|
||||
'LucidaConsole-BoldItalic': 'Courier-BoldOblique',
|
||||
'LucidaConsole-Italic': 'Courier-Oblique'
|
||||
'LucidaConsole-Italic': 'Courier-Oblique',
|
||||
'MS-Gothic': 'MS Gothic',
|
||||
'MS-Gothic-Bold': 'MS Gothic-Bold',
|
||||
'MS-Gothic-BoldItalic': 'MS Gothic-BoldItalic',
|
||||
'MS-Gothic-Italic': 'MS Gothic-Italic',
|
||||
'MS-Mincho': 'MS Mincho',
|
||||
'MS-Mincho-Bold': 'MS Mincho-Bold',
|
||||
'MS-Mincho-BoldItalic': 'MS Mincho-BoldItalic',
|
||||
'MS-Mincho-Italic': 'MS Mincho-Italic',
|
||||
'MS-PGothic': 'MS PGothic',
|
||||
'MS-PGothic-Bold': 'MS PGothic-Bold',
|
||||
'MS-PGothic-BoldItalic': 'MS PGothic-BoldItalic',
|
||||
'MS-PGothic-Italic': 'MS PGothic-Italic',
|
||||
'MS-PMincho': 'MS PMincho',
|
||||
'MS-PMincho-Bold': 'MS PMincho-Bold',
|
||||
'MS-PMincho-BoldItalic': 'MS PMincho-BoldItalic',
|
||||
'MS-PMincho-Italic': 'MS PMincho-Italic',
|
||||
};
|
||||
|
||||
var serifFonts = {
|
||||
@ -16139,6 +16326,7 @@ var CMapConverterList = {
|
||||
'90msp-RKSJ-H': sjisToUnicode,
|
||||
'90msp-RKSJ-V': sjisToUnicode,
|
||||
'GBK-EUC-H': gbkToUnicode,
|
||||
'B5pc-H': big5ToUnicode,
|
||||
'ETenms-B5-H': big5ToUnicode,
|
||||
'ETenms-B5-V': big5ToUnicode,
|
||||
};
|
||||
@ -18164,8 +18352,8 @@ var Font = (function FontClosure() {
|
||||
}
|
||||
var bmpLength = i + 1;
|
||||
|
||||
var trailingRangesCount = ranges[bmpLength - 1][1] < 0xFFFF ? 1 : 0;
|
||||
var segCount = bmpLength + trailingRangesCount;
|
||||
if (ranges[i][1] === 0xFFFF) { ranges[i][1] = 0xFFFE; }
|
||||
var segCount = bmpLength + 1;
|
||||
var segCount2 = segCount * 2;
|
||||
var searchRange = getMaxPower2(segCount) * 2;
|
||||
var searchEntry = Math.log(segCount) / Math.log(2);
|
||||
@ -18210,12 +18398,10 @@ var Font = (function FontClosure() {
|
||||
}
|
||||
}
|
||||
|
||||
if (trailingRangesCount > 0) {
|
||||
endCount += '\xFF\xFF';
|
||||
startCount += '\xFF\xFF';
|
||||
idDeltas += '\x00\x01';
|
||||
idRangeOffsets += '\x00\x00';
|
||||
}
|
||||
endCount += '\xFF\xFF';
|
||||
startCount += '\xFF\xFF';
|
||||
idDeltas += '\x00\x01';
|
||||
idRangeOffsets += '\x00\x00';
|
||||
|
||||
var format314 = '\x00\x00' + // language
|
||||
string16(segCount2) +
|
||||
@ -18302,6 +18488,14 @@ var Font = (function FontClosure() {
|
||||
if (firstChar > lastChar) {
|
||||
return false;
|
||||
}
|
||||
stream.getBytes(6); // skipping sTypoAscender/Descender/LineGap
|
||||
var usWinAscent = int16(stream.getBytes(2));
|
||||
if (usWinAscent === 0) { // makes font unreadable by windows
|
||||
return false;
|
||||
}
|
||||
|
||||
// OS/2 appears to be valid, resetting some fields
|
||||
os2.data[8] = os2.data[9] = 0; // IE rejects fonts if fsType != 0
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -19151,16 +19345,6 @@ var Font = (function FontClosure() {
|
||||
return names;
|
||||
}
|
||||
|
||||
function isOS2Valid(os2Table) {
|
||||
var data = os2Table.data;
|
||||
// usWinAscent == 0 makes font unreadable by windows
|
||||
var usWinAscent = (data[74] << 8) | data[75];
|
||||
if (usWinAscent === 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
var TTOpsStackDeltas = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -2, -2, 0, 0, -2, -5,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1,
|
||||
@ -19355,12 +19539,6 @@ var Font = (function FontClosure() {
|
||||
// of missing tables
|
||||
createOpenTypeHeader(header.version, ttf, numTables);
|
||||
|
||||
// Invalid OS/2 can break the font for the Windows
|
||||
if (os2 && !isOS2Valid(os2)) {
|
||||
tables.splice(tables.indexOf(os2), 1);
|
||||
os2 = null;
|
||||
}
|
||||
|
||||
// Ensure the hmtx table contains the advance width and
|
||||
// sidebearings information for numGlyphs in the maxp table
|
||||
font.pos = (font.start || 0) + maxp.offset;
|
||||
@ -21658,10 +21836,19 @@ var CFFParser = (function CFFParserClosure() {
|
||||
}
|
||||
return { charStrings: charStrings, seacs: seacs };
|
||||
},
|
||||
emptyPrivateDictionary:
|
||||
function CFFParser_emptyPrivateDictionary(parentDict) {
|
||||
var privateDict = this.createDict(CFFPrivateDict, [],
|
||||
parentDict.strings);
|
||||
parentDict.setByKey(18, [0, 0]);
|
||||
parentDict.privateDict = privateDict;
|
||||
},
|
||||
parsePrivateDict: function CFFParser_parsePrivateDict(parentDict) {
|
||||
// no private dict, do nothing
|
||||
if (!parentDict.hasName('Private'))
|
||||
if (!parentDict.hasName('Private')) {
|
||||
this.emptyPrivateDictionary(parentDict);
|
||||
return;
|
||||
}
|
||||
var privateOffset = parentDict.getByName('Private');
|
||||
// make sure the params are formatted correctly
|
||||
if (!isArray(privateOffset) || privateOffset.length !== 2) {
|
||||
@ -21672,7 +21859,7 @@ var CFFParser = (function CFFParserClosure() {
|
||||
var offset = privateOffset[1];
|
||||
// remove empty dicts or ones that refer to invalid location
|
||||
if (size === 0 || offset >= this.bytes.length) {
|
||||
parentDict.removeByName('Private');
|
||||
this.emptyPrivateDictionary(parentDict);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -21690,7 +21877,7 @@ var CFFParser = (function CFFParserClosure() {
|
||||
var relativeOffset = offset + subrsOffset;
|
||||
// Validate the offset.
|
||||
if (subrsOffset === 0 || relativeOffset >= this.bytes.length) {
|
||||
privateDict.removeByName('Subrs');
|
||||
this.emptyPrivateDictionary(parentDict);
|
||||
return;
|
||||
}
|
||||
var subrsIndex = this.parseIndex(relativeOffset);
|
||||
@ -22371,15 +22558,23 @@ var CFFCompiler = (function CFFCompilerClosure() {
|
||||
output) {
|
||||
for (var i = 0, ii = dicts.length; i < ii; ++i) {
|
||||
var fontDict = dicts[i];
|
||||
if (!fontDict.privateDict || !fontDict.hasName('Private'))
|
||||
continue;
|
||||
assert(fontDict.privateDict && fontDict.hasName('Private'),
|
||||
'There must be an private dictionary.');
|
||||
var privateDict = fontDict.privateDict;
|
||||
var privateDictTracker = new CFFOffsetTracker();
|
||||
var privateDictData = this.compileDict(privateDict, privateDictTracker);
|
||||
|
||||
privateDictTracker.offset(output.length);
|
||||
var outputLength = output.length;
|
||||
privateDictTracker.offset(outputLength);
|
||||
if (!privateDictData.length) {
|
||||
// The private dictionary was empty, set the output length to zero to
|
||||
// ensure the offset length isn't out of bounds in the eyes of the
|
||||
// sanitizer.
|
||||
outputLength = 0;
|
||||
}
|
||||
|
||||
trackers[i].setEntryLocation('Private',
|
||||
[privateDictData.length, output.length],
|
||||
[privateDictData.length, outputLength],
|
||||
output);
|
||||
output.add(privateDictData);
|
||||
|
||||
|
@ -826,6 +826,11 @@ html[dir='rtl'] .toolbarButton.pageDown::before {
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
#viewBookmark[href='#'] {
|
||||
opacity: .5;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.toolbarButton.bookmark::before {
|
||||
content: url(images/toolbarButton-bookmark.png);
|
||||
}
|
||||
|
@ -1290,6 +1290,7 @@ var PDFView = {
|
||||
if (PDFView.supportsPrinting) {
|
||||
pdfDocument.getJavaScript().then(function(javaScript) {
|
||||
if (javaScript.length) {
|
||||
console.warn('Warning: JavaScript is not supported');
|
||||
PDFView.fallback();
|
||||
}
|
||||
// Hack to support auto printing.
|
||||
@ -1363,7 +1364,7 @@ var PDFView = {
|
||||
self.setTitle(pdfTitle + ' - ' + document.title);
|
||||
|
||||
if (info.IsAcroFormPresent) {
|
||||
// AcroForm/XFA was found
|
||||
console.warn('Warning: AcroForm/XFA is not supported');
|
||||
PDFView.fallback();
|
||||
}
|
||||
});
|
||||
@ -1565,55 +1566,52 @@ var PDFView = {
|
||||
},
|
||||
|
||||
getVisiblePages: function pdfViewGetVisiblePages() {
|
||||
return this.getVisibleElements(this.container,
|
||||
this.pages, true);
|
||||
if (!this.isFullscreen) {
|
||||
return this.getVisibleElements(this.container, this.pages, true);
|
||||
} else {
|
||||
// The algorithm in getVisibleElements is broken in fullscreen mode.
|
||||
var visible = [], page = this.page;
|
||||
var currentPage = this.pages[page - 1];
|
||||
visible.push({ id: currentPage.id, view: currentPage });
|
||||
|
||||
return { first: currentPage, last: currentPage, views: visible};
|
||||
}
|
||||
},
|
||||
|
||||
getVisibleThumbs: function pdfViewGetVisibleThumbs() {
|
||||
return this.getVisibleElements(this.thumbnailContainer,
|
||||
this.thumbnails);
|
||||
return this.getVisibleElements(this.thumbnailContainer, this.thumbnails);
|
||||
},
|
||||
|
||||
// Generic helper to find out what elements are visible within a scroll pane.
|
||||
getVisibleElements: function pdfViewGetVisibleElements(
|
||||
scrollEl, views, sortByVisibility) {
|
||||
var currentHeight = 0, view;
|
||||
var top = scrollEl.scrollTop;
|
||||
var top = scrollEl.scrollTop, bottom = top + scrollEl.clientHeight;
|
||||
var left = scrollEl.scrollLeft, right = left + scrollEl.clientWidth;
|
||||
|
||||
for (var i = 1, ii = views.length; i <= ii; ++i) {
|
||||
view = views[i - 1];
|
||||
var visible = [], view;
|
||||
var currentHeight, viewHeight, hiddenHeight, percentHeight;
|
||||
var currentWidth, viewWidth;
|
||||
for (var i = 0, ii = views.length; i < ii; ++i) {
|
||||
view = views[i];
|
||||
currentHeight = view.el.offsetTop + view.el.clientTop;
|
||||
if (currentHeight + view.el.clientHeight > top)
|
||||
break;
|
||||
currentHeight += view.el.clientHeight;
|
||||
}
|
||||
|
||||
var visible = [];
|
||||
|
||||
// Algorithm broken in fullscreen mode
|
||||
if (this.isFullscreen) {
|
||||
var currentPage = this.pages[this.page - 1];
|
||||
visible.push({
|
||||
id: currentPage.id,
|
||||
view: currentPage
|
||||
});
|
||||
|
||||
return { first: currentPage, last: currentPage, views: visible};
|
||||
}
|
||||
|
||||
var bottom = top + scrollEl.clientHeight;
|
||||
var nextHeight, hidden, percent, viewHeight;
|
||||
for (; i <= ii && currentHeight < bottom; ++i) {
|
||||
view = views[i - 1];
|
||||
viewHeight = view.el.clientHeight;
|
||||
currentHeight = view.el.offsetTop + view.el.clientTop;
|
||||
nextHeight = currentHeight + viewHeight;
|
||||
hidden = Math.max(0, top - currentHeight) +
|
||||
Math.max(0, nextHeight - bottom);
|
||||
percent = Math.floor((viewHeight - hidden) * 100.0 / viewHeight);
|
||||
if ((currentHeight + viewHeight) < top) {
|
||||
continue;
|
||||
}
|
||||
if (currentHeight > bottom) {
|
||||
break;
|
||||
}
|
||||
currentWidth = view.el.offsetLeft + view.el.clientLeft;
|
||||
viewWidth = view.el.clientWidth;
|
||||
if ((currentWidth + viewWidth) < left || currentWidth > right) {
|
||||
continue;
|
||||
}
|
||||
hiddenHeight = Math.max(0, top - currentHeight) +
|
||||
Math.max(0, currentHeight + viewHeight - bottom);
|
||||
percentHeight = ((viewHeight - hiddenHeight) * 100 / viewHeight) | 0;
|
||||
|
||||
visible.push({ id: view.id, y: currentHeight,
|
||||
view: view, percent: percent });
|
||||
currentHeight = nextHeight;
|
||||
view: view, percent: percentHeight });
|
||||
}
|
||||
|
||||
var first = visible[0];
|
||||
@ -1622,13 +1620,12 @@ var PDFView = {
|
||||
if (sortByVisibility) {
|
||||
visible.sort(function(a, b) {
|
||||
var pc = a.percent - b.percent;
|
||||
if (Math.abs(pc) > 0.001)
|
||||
if (Math.abs(pc) > 0.001) {
|
||||
return -pc;
|
||||
|
||||
}
|
||||
return a.id - b.id; // ensure stability
|
||||
});
|
||||
}
|
||||
|
||||
return {first: first, last: last, views: visible};
|
||||
},
|
||||
|
||||
@ -1704,6 +1701,10 @@ var PDFView = {
|
||||
this.page = this.page;
|
||||
this.clearMouseScrollState();
|
||||
this.hidePresentationControls();
|
||||
|
||||
// Ensure that the thumbnail of the current page is visible
|
||||
// when exiting fullscreen mode.
|
||||
scrollIntoView(document.getElementById('thumbnailContainer' + this.page));
|
||||
},
|
||||
|
||||
showPresentationControls: function pdfViewShowPresentationControls() {
|
||||
@ -2086,7 +2087,6 @@ var PageView = function pageView(container, pdfPage, id, scale,
|
||||
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.id = 'page' + this.id;
|
||||
canvas.mozOpaque = true;
|
||||
div.appendChild(canvas);
|
||||
this.canvas = canvas;
|
||||
|
||||
@ -2116,13 +2116,10 @@ var PageView = function pageView(container, pdfPage, id, scale,
|
||||
}
|
||||
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
// TODO(mack): use data attributes to store these
|
||||
ctx._scaleX = outputScale.sx;
|
||||
ctx._scaleY = outputScale.sy;
|
||||
ctx.save();
|
||||
ctx.fillStyle = 'rgb(255, 255, 255)';
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.restore();
|
||||
if (outputScale.scaled) {
|
||||
ctx.scale(outputScale.sx, outputScale.sy);
|
||||
}
|
||||
@ -2337,7 +2334,6 @@ var ThumbnailView = function thumbnailView(container, pdfPage, id) {
|
||||
function getPageDrawContext() {
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.id = 'thumbnail' + id;
|
||||
canvas.mozOpaque = true;
|
||||
|
||||
canvas.width = canvasWidth;
|
||||
canvas.height = canvasHeight;
|
||||
@ -2599,7 +2595,7 @@ var TextLayerBuilder = function textLayerBuilder(textLayerDiv, pageIdx) {
|
||||
var textDiv = document.createElement('div');
|
||||
|
||||
// vScale and hScale already contain the scaling to pixel units
|
||||
var fontHeight = geom.fontSize * geom.vScale;
|
||||
var fontHeight = geom.fontSize * Math.abs(geom.vScale);
|
||||
textDiv.dataset.canvasWidth = geom.canvasWidth * geom.hScale;
|
||||
textDiv.dataset.fontName = geom.fontName;
|
||||
|
||||
@ -3250,7 +3246,8 @@ window.addEventListener('keydown', function keydown(evt) {
|
||||
|
||||
// First, handle the key bindings that are independent whether an input
|
||||
// control is selected or not.
|
||||
if (cmd == 1 || cmd == 8) { // either CTRL or META key.
|
||||
if (cmd === 1 || cmd === 8 || cmd === 5 || cmd === 12) {
|
||||
// either CTRL or META key with optional SHIFT.
|
||||
switch (evt.keyCode) {
|
||||
case 70:
|
||||
if (!PDFView.supportsIntegratedFind) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
chrome.manifest
|
||||
components/PdfRedirector.js
|
||||
components/PdfStreamConverter.js
|
||||
content/build/pdf.js
|
||||
content/PdfJs.jsm
|
||||
|
Loading…
Reference in New Issue
Block a user