}
},
getLinks: function pageGetLinks() {
+ var links = [];
+ var annotations = pageGetAnnotations();
+ var i, n = annotations.length;
+ for (i = 0; i < n; ++i) {
+ if (annotations[i].type != 'Link')
+ continue;
+ links.push(annotations[i]);
+ }
+ return links;
+ },
+ getAnnotations: function pageGetAnnotations() {
var xref = this.xref;
var annotations = xref.fetchIfRef(this.annotations) || [];
var i, n = annotations.length;
- var links = [];
+ var items = [];
for (i = 0; i < n; ++i) {
var annotation = xref.fetch(annotations[i]);
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');
- break;
- case 'GoTo':
- link.dest = a.get('D');
+ 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 = this.xref.fetchIfRef(annotation.get('A'));
+ if (a) {
+ switch (a.get('S').name) {
+ case 'URI':
+ link.url = a.get('URI');
+ 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;
+ }
+ break;
+ case 'Widget':
+ var fieldType = annotation.get('FT');
+ if (!isName(fieldType))
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;
+ var fieldName = [];
+ var name = stringToPDFString(annotation.get('T'));
+ if (name)
+ fieldName.push(name)
+ var parent = xref.fetchIfRef(annotation.get('Parent'));
+ while (parent) {
+ name = stringToPDFString(parent.get('T'));
+ if (name)
+ fieldName.unshift(name);
+ parent = xref.fetchIfRef(parent.get('Parent'));
+ }
+ item.fullName = fieldName.join('.');
+ var alternativeText = stringToPDFString(annotation.get('TU') || '');
+ item.alternativeText = alternativeText;
+ var da = annotation.get('DA') || '';
+ var m = /([\d\.]+)\sTf/.exec(da);
+ if (m)
+ item.fontSize = parseFloat(m[1]);
+ item.flags = annotation.get('Ff') || 0;
+ break;
}
- links.push(link);
+ items.push(item);
}
- return links;
+ return items;
},
startRendering: function pageStartRendering(ctx, callback) {
this.ctx = ctx;
assertWellFormed(stream.length > 0, 'stream must have data');
this.stream = stream;
this.setup();
+ this.acroForm = this.xref.fetchIfRef(this.catalog.catDict.get('AcroForm'));
}
function find(stream, needle, limit, backwards) {
thumbnails: [],
currentScale: kDefaultScale,
initialBookmark: document.location.hash.substring(1),
+ formFields: [],
setScale: function pdfViewSetScale(val, resetAutoSettings) {
var pages = this.pages;
div.removeAttribute('data-loaded');
};
- function setupLinks(content, scale) {
+ function setupAnnotations(content, scale) {
function bindLink(link, dest) {
link.href = PDFView.getDestinationHash(dest);
link.onclick = function pageViewSetupLinksOnclick() {
return false;
};
}
+ function bindInputItem(input, item) {
+ if (input.name in PDFView.formFields) {
+ var value = PDFView.formFields[input.name];
+ if (input.type == 'checkbox')
+ input.checked = value;
+ else if (!input.type || input.type == 'text')
+ input.value = value;
+ }
+ input.onchange = function pageViewSetupInputOnBlur() {
+ if (input.type == 'checkbox')
+ PDFView.formFields[input.name] = input.checked;
+ else if (!input.type || input.type == 'text')
+ PDFView.formFields[input.name] = input.value;
+ };
+ }
+ function createElementWithStyle(tagName, item) {
+ var element = document.createElement(tagName);
+ element.style.left = (Math.floor(item.x - view.x) * scale) + 'px';
+ element.style.top = (Math.floor(item.y - view.y) * scale) + 'px';
+ element.style.width = Math.ceil(item.width * scale) + 'px';
+ element.style.height = Math.ceil(item.height * scale) + 'px';
+ return element;
+ }
+ function assignFontStyle(element, item) {
+ var fontStyles = '';
+ if ('fontSize' in item)
+ fontStyles += 'font-size: ' + Math.round(item.fontSize * scale) + 'px';
+ element.setAttribute('style', element.getAttribute('style') + fontStyles);
+ }
- var links = content.getLinks();
- for (var i = 0; i < links.length; i++) {
- var link = document.createElement('a');
- link.style.left = (Math.floor(links[i].x - view.x) * scale) + 'px';
- link.style.top = (Math.floor(links[i].y - view.y) * scale) + 'px';
- link.style.width = Math.ceil(links[i].width * scale) + 'px';
- link.style.height = Math.ceil(links[i].height * scale) + 'px';
- link.href = links[i].url || '';
- if (!links[i].url)
- bindLink(link, ('dest' in links[i]) ? links[i].dest : null);
- div.appendChild(link);
+ var items = content.getAnnotations();
+ for (var i = 0; i < items.length; i++) {
+ var item = items[i];
+ switch (item.type) {
+ case 'Link':
+ var link = createElementWithStyle('a', item);
+ link.href = item.url || '';
+ if (!item.url)
+ bindLink(link, ('dest' in item) ? item.dest : null);
+ div.appendChild(link);
+ break;
+ case 'Widget':
+ if (item.fieldType != 'Tx' && item.fieldType != 'Btn' &&
+ item.fieldType != 'Ch')
+ break;
+ var inputDiv = createElementWithStyle('div', item);
+ inputDiv.className = 'inputHint';
+ div.appendChild(inputDiv);
+ var input;
+ if (item.fieldType == 'Tx') {
+ input = createElementWithStyle('input', item);
+ }
+ if (item.fieldType == 'Btn') {
+ input = createElementWithStyle('input', item);
+ if (item.flags & 32768) {
+ input.type = 'radio';
+ TODO('radio button is not supported');
+ } else if (item.flags & 65536) {
+ input.type = 'button';
+ TODO('pushbutton is not supported');
+ } else {
+ input.type = 'checkbox';
+ }
+ }
+ if (item.fieldType == 'Ch') {
+ input = createElementWithStyle('select', item);
+ TODO('select box is not supported');
+ }
+ input.className = 'inputControl';
+ input.name = item.fullName;
+ input.title = item.alternativeText;
+ assignFontStyle(input, item);
+ bindInputItem(input, item);
+ div.appendChild(input);
+ break;
+ }
}
}
stats.begin = Date.now();
this.content.startRendering(ctx, this.updateStats);
- setupLinks(this.content, this.scale);
+ setupAnnotations(this.content, this.scale);
div.setAttribute('data-loaded', true);
return true;
window.addEventListener('keydown', function keydown(evt) {
var curElement = document.activeElement;
+ if (curElement && curElement.tagName == 'INPUT')
+ return;
var controlsElement = document.getElementById('controls');
while (curElement) {
if (curElement === controlsElement)