Skip to content

Commit

Permalink
Improved annotations' display/behavior.
Browse files Browse the repository at this point in the history
Added an "InteractiveAnnotation" class to homogenize the annotations' structure (highlighting) and user interactions (for now, used for text and link annotations).

Text annotations:
The appearance (AP) has priority over the icon (Name).
The popup extends horizontally (up to a limit) as well as vertically.
Reduced the title's font size.
The annotation's color (C) is used to color the popup's background.
On top of the mouseover show/hide behavior, a click on the icon will lock the annotation open (for mobile purposes). It can be closed with another click on either the icon or the popup.

An annotation printing is conditioned by its "print" bit
Unsupported annotations are not displayed at all.
  • Loading branch information
Samuel Chantaraud committed Mar 7, 2014
1 parent 3e93104 commit 076b343
Show file tree
Hide file tree
Showing 8 changed files with 305 additions and 131 deletions.
9 changes: 5 additions & 4 deletions src/core/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ var Page = (function PageClosure() {
}.bind(this));
return promise;
},
getOperatorList: function Page_getOperatorList(handler) {
getOperatorList: function Page_getOperatorList(handler, intent) {
var self = this;
var promise = new LegacyPromise();

Expand Down Expand Up @@ -169,11 +169,12 @@ var Page = (function PageClosure() {
var contentStream = data[0];


var opList = new OperatorList(handler, self.pageIndex);
var opList = new OperatorList(intent, handler, self.pageIndex);

handler.send('StartRenderPage', {
transparency: partialEvaluator.hasBlendModes(self.resources),
pageIndex: self.pageIndex
pageIndex: self.pageIndex,
intent: intent
});
partialEvaluator.getOperatorList(contentStream, self.resources, opList);
pageListPromise.resolve(opList);
Expand All @@ -191,7 +192,7 @@ var Page = (function PageClosure() {
}

var annotationsReadyPromise = Annotation.appendToOperatorList(
annotations, pageOpList, pdfManager, partialEvaluator);
annotations, pageOpList, pdfManager, partialEvaluator, intent);
annotationsReadyPromise.then(function () {
pageOpList.flush(true);
promise.resolve(pageOpList);
Expand Down
6 changes: 4 additions & 2 deletions src/core/evaluator.js
Original file line number Diff line number Diff line change
Expand Up @@ -1376,7 +1376,7 @@ var OperatorList = (function OperatorListClosure() {
}


function OperatorList(messageHandler, pageIndex) {
function OperatorList(intent, messageHandler, pageIndex) {
this.messageHandler = messageHandler;
// When there isn't a message handler the fn array needs to be able to grow
// since we can't flush the operators.
Expand All @@ -1389,6 +1389,7 @@ var OperatorList = (function OperatorListClosure() {
this.dependencies = {};
this.pageIndex = pageIndex;
this.fnIndex = 0;
this.intent = intent;
}

OperatorList.prototype = {
Expand Down Expand Up @@ -1449,7 +1450,8 @@ var OperatorList = (function OperatorListClosure() {
lastChunk: lastChunk,
length: this.length
},
pageIndex: this.pageIndex
pageIndex: this.pageIndex,
intent: this.intent
}, null, transfers);
this.dependencies = [];
this.fnIndex = 0;
Expand Down
5 changes: 3 additions & 2 deletions src/core/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
var pageNum = data.pageIndex + 1;
var start = Date.now();
// Pre compile the pdf page and fetch the fonts/images.
page.getOperatorList(handler).then(function(operatorList) {
page.getOperatorList(handler, data.intent).then(function(operatorList) {

info('page=' + pageNum + ' - getOperatorList: time=' +
(Date.now() - start) + 'ms, len=' + operatorList.fnArray.length);
Expand Down Expand Up @@ -366,7 +366,8 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {

handler.send('PageError', {
pageNum: pageNum,
error: wrappedException
error: wrappedException,
intent: data.intent
});
});
});
Expand Down
87 changes: 55 additions & 32 deletions src/display/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -341,10 +341,9 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
this.stats.enabled = !!globalScope.PDFJS.enableStats;
this.commonObjs = transport.commonObjs;
this.objs = new PDFObjects();
this.receivingOperatorList = false;
this.cleanupAfterRender = false;
this.pendingDestroy = false;
this.renderTasks = [];
this.intentStates = {};
}
PDFPageProxy.prototype = /** @lends PDFPageProxy.prototype */ {
/**
Expand Down Expand Up @@ -423,31 +422,45 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
// this call to render.
this.pendingDestroy = false;

var renderingIntent = 'intent' in params ?
(params.intent == 'print' ? 'print' : 'display') :
'display';

if (!this.intentStates[renderingIntent]) {
this.intentStates[renderingIntent] = {};
}
var intentState = this.intentStates[renderingIntent];

// If there is no displayReadyPromise yet, then the operatorList was never
// requested before. Make the request and create the promise.
if (!this.displayReadyPromise) {
this.receivingOperatorList = true;
this.displayReadyPromise = new LegacyPromise();
this.operatorList = {
if (!intentState.displayReadyPromise) {
intentState.receivingOperatorList = true;
intentState.displayReadyPromise = new LegacyPromise();
intentState.operatorList = {
fnArray: [],
argsArray: [],
lastChunk: false
};

this.stats.time('Page Request');
this.transport.messageHandler.send('RenderPageRequest', {
pageIndex: this.pageNumber - 1
pageIndex: this.pageNumber - 1,
intent: renderingIntent
});
}

var internalRenderTask = new InternalRenderTask(complete, params,
this.objs, this.commonObjs,
this.operatorList, this.pageNumber);
this.renderTasks.push(internalRenderTask);
intentState.operatorList,
this.pageNumber);
if (!intentState.renderTasks) {
intentState.renderTasks = [];
}
intentState.renderTasks.push(internalRenderTask);
var renderTask = new RenderTask(internalRenderTask);

var self = this;
this.displayReadyPromise.then(
intentState.displayReadyPromise.then(
function pageDisplayReadyPromise(transparency) {
if (self.pendingDestroy) {
complete();
Expand All @@ -463,9 +476,9 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
);

function complete(error) {
var i = self.renderTasks.indexOf(internalRenderTask);
var i = intentState.renderTasks.indexOf(internalRenderTask);
if (i >= 0) {
self.renderTasks.splice(i, 1);
intentState.renderTasks.splice(i, 1);
}

if (self.cleanupAfterRender) {
Expand Down Expand Up @@ -513,43 +526,51 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
*/
_tryDestroy: function PDFPageProxy__destroy() {
if (!this.pendingDestroy ||
this.renderTasks.length !== 0 ||
this.receivingOperatorList) {
Object.keys(this.intentStates).some(function(intent) {
var intentState = this.intentStates[intent];
return intentState.renderTasks.length !== 0 ||
intentState.receivingOperatorList;
}, this)) {
return;
}

delete this.operatorList;
delete this.displayReadyPromise;
delete this.annotationsPromise;
Object.keys(this.intentStates).forEach(function(intent) {
delete this.intentStates[intent];
}, this);
this.objs.clear();
this.pendingDestroy = false;
},
/**
* For internal use only.
* @ignore
*/
_startRenderPage: function PDFPageProxy_startRenderPage(transparency) {
this.displayReadyPromise.resolve(transparency);
_startRenderPage: function PDFPageProxy_startRenderPage(transparency,
intent) {
var intentState = this.intentStates[intent];
intentState.displayReadyPromise.resolve(transparency);
},
/**
* For internal use only.
* @ignore
*/
_renderPageChunk: function PDFPageProxy_renderPageChunk(operatorListChunk) {
_renderPageChunk: function PDFPageProxy_renderPageChunk(operatorListChunk,
intent) {
var intentState = this.intentStates[intent];
// Add the new chunk to the current operator list.
for (var i = 0, ii = operatorListChunk.length; i < ii; i++) {
this.operatorList.fnArray.push(operatorListChunk.fnArray[i]);
this.operatorList.argsArray.push(operatorListChunk.argsArray[i]);
intentState.operatorList.fnArray.push(operatorListChunk.fnArray[i]);
intentState.operatorList.argsArray.push(
operatorListChunk.argsArray[i]);
}
this.operatorList.lastChunk = operatorListChunk.lastChunk;
intentState.operatorList.lastChunk = operatorListChunk.lastChunk;

// Notify all the rendering tasks there are more operators to be consumed.
for (var i = 0; i < this.renderTasks.length; i++) {
this.renderTasks[i].operatorListChanged();
for (var i = 0; i < intentState.renderTasks.length; i++) {
intentState.renderTasks[i].operatorListChanged();
}

if (operatorListChunk.lastChunk) {
this.receivingOperatorList = false;
intentState.receivingOperatorList = false;
this._tryDestroy();
}
}
Expand Down Expand Up @@ -775,13 +796,13 @@ var WorkerTransport = (function WorkerTransportClosure() {
var page = this.pageCache[data.pageIndex];

page.stats.timeEnd('Page Request');
page._startRenderPage(data.transparency);
page._startRenderPage(data.transparency, data.intent);
}, this);

messageHandler.on('RenderPageChunk', function transportRender(data) {
var page = this.pageCache[data.pageIndex];

page._renderPageChunk(data.operatorList);
page._renderPageChunk(data.operatorList, data.intent);
}, this);

messageHandler.on('commonobj', function transportObj(data) {
Expand Down Expand Up @@ -824,8 +845,9 @@ var WorkerTransport = (function WorkerTransportClosure() {
var pageIndex = data[1];
var type = data[2];
var pageProxy = this.pageCache[pageIndex];
if (pageProxy.objs.hasData(id))
if (pageProxy.objs.hasData(id)) {
return;
}

switch (type) {
case 'JpegStream':
Expand Down Expand Up @@ -861,10 +883,11 @@ var WorkerTransport = (function WorkerTransportClosure() {
this.workerReadyPromise.reject(data);
}, this);

messageHandler.on('PageError', function transportError(data) {
messageHandler.on('PageError', function transportError(data, intent) {
var page = this.pageCache[data.pageNum - 1];
if (page.displayReadyPromise)
page.displayReadyPromise.reject(data.error);
var intentState = page.intentStates[intent];
if (intentState.displayReadyPromise)
intentState.displayReadyPromise.reject(data.error);
else
error(data.error);
}, this);
Expand Down
Loading

0 comments on commit 076b343

Please sign in to comment.