Refactor code for annotations
This commit is contained in:
parent
e5b5c94925
commit
f8f4b3f45d
@ -12,6 +12,7 @@
|
||||
<script type="text/javascript" src="../../src/api.js"></script>
|
||||
<script type="text/javascript" src="../../src/canvas.js"></script>
|
||||
<script type="text/javascript" src="../../src/obj.js"></script>
|
||||
<script type="text/javascript" src="../../src/annotation.js"></script>
|
||||
<script type="text/javascript" src="../../src/function.js"></script>
|
||||
<script type="text/javascript" src="../../src/charsets.js"></script>
|
||||
<script type="text/javascript" src="../../src/cidmaps.js"></script>
|
||||
|
@ -12,6 +12,7 @@
|
||||
<script type="text/javascript" src="../../src/api.js"></script>
|
||||
<script type="text/javascript" src="../../src/canvas.js"></script>
|
||||
<script type="text/javascript" src="../../src/obj.js"></script>
|
||||
<script type="text/javascript" src="../../src/annotation.js"></script>
|
||||
<script type="text/javascript" src="../../src/function.js"></script>
|
||||
<script type="text/javascript" src="../../src/charsets.js"></script>
|
||||
<script type="text/javascript" src="../../src/cidmaps.js"></script>
|
||||
|
@ -105,7 +105,10 @@
|
||||
// Arabic, Hebrew, Farsi, Pashto, Urdu
|
||||
var rtlList = ['ar', 'he', 'fa', 'ps', 'ur'];
|
||||
return (rtlList.indexOf(gLanguage) >= 0) ? 'rtl' : 'ltr';
|
||||
}
|
||||
},
|
||||
|
||||
// translate an element or document fragment
|
||||
translate: translateFragment
|
||||
};
|
||||
})(this);
|
||||
|
||||
|
@ -98,11 +98,11 @@ page_scale_actual=الحجم الحقيقي
|
||||
loading_error_indicator=خطأ
|
||||
loading_error=حدث خطأ أثناء تحميل وثيقه الـPDF
|
||||
|
||||
# LOCALIZATION NOTE (text_annotation_type): This is used as a tooltip.
|
||||
# LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip.
|
||||
# "{{type}}" will be replaced with an annotation type from a list defined in
|
||||
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
|
||||
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
||||
text_annotation_type=[ملاحظة {{type}}]
|
||||
text_annotation_type.alt=[ملاحظة {{type}}]
|
||||
request_password=الـPDF محمي بكلمة مرور:
|
||||
|
||||
printing_not_supported=تحذير: الطباعة ليست مدعومة كليًا في هذا المتصفح.
|
||||
|
@ -114,11 +114,11 @@ loading_error_indicator=Error
|
||||
loading_error=Ha ocorregut un error mentres es carregava el PDF.
|
||||
invalid_file_error=Invàlid o fitxer PDF corrupte.
|
||||
|
||||
# LOCALIZATION NOTE (text_annotation_type): This is used as a tooltip.
|
||||
# LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip.
|
||||
# "{{type}}" will be replaced with an annotation type from a list defined in
|
||||
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
|
||||
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
||||
text_annotation_type=[Anotació {{type}}]
|
||||
text_annotation_type.alt=[Anotació {{type}}]
|
||||
request_password=El PDF està protegit amb una contrasenya:
|
||||
|
||||
printing_not_supported=Avís: La impressió no és compatible totalment en aquest navegador.
|
||||
|
@ -41,7 +41,7 @@ rendering_error=Došlo k chybě při vykreslování stránky.
|
||||
page_label=Stránka:
|
||||
page_of=z{{pageCount}}
|
||||
open_file.title=Otevřít soubor
|
||||
text_annotation_type=[{{type}}Anotace]
|
||||
text_annotation_type.alt=[{{type}}Anotace]
|
||||
toggle_slider_label=Přepnout posuvník
|
||||
thumbs_label=Náhledy
|
||||
outline_label=Přehled dokumentu
|
||||
|
@ -114,7 +114,7 @@ missing_file_error=Manglende PDF-fil
|
||||
# "{{type}}" vil blive ersattet af en kommentar type fra en liste
|
||||
# defineret i PDF specifikationen (32000-1:2008 Table 169 – Annotation types).
|
||||
# Nogle almindelige typer er f.eks.: "Check", "Text", "Comment" og "Note"
|
||||
text_annotation_type=[{{type}} Kommentar]
|
||||
text_annotation_type.alt=[{{type}} Kommentar]
|
||||
request_password=PDF filen er beskyttet med et kodeord:
|
||||
invalid_password=Ugyldigt kodeord.
|
||||
|
||||
|
@ -109,11 +109,11 @@ loading_error_indicator=Fehler
|
||||
loading_error=Das PDF konnte nicht geladen werden.
|
||||
invalid_file_error=Ungültige oder beschädigte PDF-Datei.
|
||||
|
||||
# LOCALIZATION NOTE (text_annotation_type): This is used as a tooltip.
|
||||
# LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip.
|
||||
# "{{type}}" will be replaced with an annotation type from a list defined in
|
||||
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
|
||||
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
||||
text_annotation_type=[{{type}} Annotation]
|
||||
text_annotation_type.alt=[{{type}} Annotation]
|
||||
request_password=Das PDF ist passwortgeschützt:
|
||||
|
||||
printing_not_supported=Warnung: Drucken wird durch diesen Browser nicht vollständig unterstützt.
|
||||
|
@ -110,11 +110,11 @@ loading_error=An error occurred while loading the PDF.
|
||||
invalid_file_error=Invalid or corrupted PDF file.
|
||||
missing_file_error=Missing PDF file.
|
||||
|
||||
# LOCALIZATION NOTE (text_annotation_type): This is used as a tooltip.
|
||||
# LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip.
|
||||
# "{{type}}" will be replaced with an annotation type from a list defined in
|
||||
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
|
||||
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
||||
text_annotation_type=[{{type}} Annotation]
|
||||
text_annotation_type.alt=[{{type}} Annotation]
|
||||
request_password=PDF is protected by a password:
|
||||
invalid_password=Invalid Password.
|
||||
|
||||
|
@ -114,7 +114,7 @@ missing_file_error=Falta el archivo PDF.
|
||||
# "{{type}}" will be replaced with an annotation type from a list defined in
|
||||
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
|
||||
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
||||
text_annotation_type=[Anotación {{type}}]
|
||||
text_annotation_type.alt=[Anotación {{type}}]
|
||||
request_password=El archivo PDF está protegido por una contraseña:
|
||||
|
||||
printing_not_supported=Aviso: Este navegador no es compatible completamente con la impresión.
|
||||
|
@ -110,11 +110,11 @@ loading_error=Virhe on tapahtunut PDF:ää ladattaessa.
|
||||
invalid_file_error=Virheellinen tai vioittunut PDF tiedosto.
|
||||
missing_file_error=PDF tiedostoa ei löytynyt.
|
||||
|
||||
# LOCALIZATION NOTE (text_annotation_type): This is used as a tooltip.
|
||||
# LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip.
|
||||
# "{{type}}" will be replaced with an annotation type from a list defined in
|
||||
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
|
||||
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
||||
text_annotation_type=[{{type}} Selite]
|
||||
text_annotation_type.alt=[{{type}} Selite]
|
||||
request_password=PDF on salasanasuojattu:
|
||||
|
||||
printing_not_supported=Varoitus: Tämä selain ei täysin tue tulostusta.
|
||||
|
@ -114,7 +114,7 @@ missing_file_error=Fichier PDF manquant.
|
||||
# "{{type}}" will be replaced with an annotation type from a list defined in
|
||||
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
|
||||
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
||||
text_annotation_type=[Annotation {{type}}]
|
||||
text_annotation_type.alt=[Annotation {{type}}]
|
||||
request_password=Le PDF est protégé par un mot de passe :
|
||||
|
||||
printing_not_supported=Attention : l'impression n'est pas totalement prise en charge par ce navigateur.
|
||||
|
@ -41,7 +41,7 @@ rendering_error=אירעה שגיאה בעת עיבוד הדף.
|
||||
page_label=דף:
|
||||
page_of=מתוך {{pageCount}}
|
||||
open_file.title=פתיחת קובץ
|
||||
text_annotation_type=[{{type}} Annotation]
|
||||
text_annotation_type.alt=[{{type}} Annotation]
|
||||
toggle_slider_label=מתג החלקה
|
||||
thumbs_label=תמונות ממוזערות
|
||||
outline_label=מתאר מסמך
|
||||
|
@ -41,4 +41,4 @@ rendering_error=
|
||||
page_label=Pagina:
|
||||
page_of=di {{pageCount}}
|
||||
open_file.title=Apri File
|
||||
text_annotation_type=[{{type}} Annotazione]
|
||||
text_annotation_type.alt=[{{type}} Annotazione]
|
||||
|
@ -110,11 +110,11 @@ loading_error=PDF の読み込み中にエラーが発生しました
|
||||
invalid_file_error=無効または破損した PDF ファイル
|
||||
missing_file_error=PDF ファイルが見つかりません。
|
||||
|
||||
# LOCALIZATION NOTE (text_annotation_type): This is used as a tooltip.
|
||||
# LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip.
|
||||
# "{{type}}" will be replaced with an annotation type from a list defined in
|
||||
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
|
||||
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
||||
text_annotation_type=[{{type}} 注釈]
|
||||
text_annotation_type.alt=[{{type}} 注釈]
|
||||
request_password=PDF はパスワードによって保護されています
|
||||
|
||||
printing_not_supported=警告:このブラウザでは印刷が完全にサポートされていません
|
||||
|
@ -110,11 +110,11 @@ loading_error=PDF bylos įkelimo metu įvyko klaida.
|
||||
invalid_file_error=Neteisinga arba pažeista PDF byla.
|
||||
missing_file_error=Trūksta PDF bylos.
|
||||
|
||||
# LOCALIZATION NOTE (text_annotation_type): This is used as a tooltip.
|
||||
# LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip.
|
||||
# "{{type}}" will be replaced with an annotation type from a list defined in
|
||||
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
|
||||
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
||||
text_annotation_type=[{{type}} Pastaba]
|
||||
text_annotation_type.alt=[{{type}} Pastaba]
|
||||
request_password=PDF byla yra apsaugota slaptažodžiu:
|
||||
|
||||
printing_not_supported=Dėmesio: Naršyklė pilnai nepalaiko spausdinimo.
|
||||
|
@ -110,11 +110,11 @@ loading_error=Er is een fout opgetreden bij het laden van het PDF-bestand.
|
||||
invalid_file_error=Ongeldig of corrupt PDF-bestand.
|
||||
missing_file_error=Ontbrekend PDF-bestand.
|
||||
|
||||
# LOCALIZATION NOTE (text_annotation_type): This is used as a tooltip.
|
||||
# LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip.
|
||||
# "{{type}}" will be replaced with an annotation type from a list defined in
|
||||
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
|
||||
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
||||
text_annotation_type=[{{type}}-aantekening]
|
||||
text_annotation_type.alt=[{{type}}-aantekening]
|
||||
request_password=Dit PDF-bestand is beveiligd met een wachtwoord:
|
||||
|
||||
printing_not_supported=Waarschuwing: afdrukken wordt niet volledig ondersteund door deze browser.
|
||||
|
@ -110,11 +110,11 @@ loading_error=Wystąpił błąd podczas wczytywania pliku PDF.
|
||||
invalid_file_error=Błędny lub uszkodzony plik PDF.
|
||||
missing_file_error=Nie znaleziono pliku PDF.
|
||||
|
||||
# LOCALIZATION NOTE (text_annotation_type): This is used as a tooltip.
|
||||
# LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip.
|
||||
# "{{type}}" will be replaced with an annotation type from a list defined in
|
||||
# the PDF spec (32000-1:2008 Table 169 - Annotation types).
|
||||
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
||||
text_annotation_type=[Komentarz {{type}}]
|
||||
text_annotation_type.alt=[Komentarz {{type}}]
|
||||
request_password=Plik PDF jest chroniony przez hasło:
|
||||
|
||||
printing_not_supported=Ostrzeżenie: Drukowanie nie jest w pełni obsługiwane przez tę przeglądarkę.
|
||||
|
@ -41,4 +41,4 @@ rendering_error=Um erro ocorreu ao apresentar a página.
|
||||
page_label=Página:
|
||||
page_of=de {{pageCount}}
|
||||
open_file.title=Abrir arquivo
|
||||
text_annotation_type=[{{type}} Anotações]
|
||||
text_annotation_type.alt=[{{type}} Anotações]
|
||||
|
@ -41,7 +41,7 @@ rendering_error=S-a produs o eroare în timpul procesării paginii.
|
||||
page_label=Pagina:
|
||||
page_of=din {{pageCount}}
|
||||
open_file.title=Deschide fișier
|
||||
text_annotation_type=[Adnotare {{type}}]
|
||||
text_annotation_type.alt=[Adnotare {{type}}]
|
||||
toggle_slider_label=Vedere de ansamblu
|
||||
thumbs_label=Miniaturi
|
||||
outline_label=Cuprins
|
||||
|
@ -41,7 +41,7 @@ rendering_error=Произошла ошибка во время создания
|
||||
page_label=Страница:
|
||||
page_of=из {{pageCount}}
|
||||
open_file.title=Открыть файл
|
||||
text_annotation_type=[Аннотация {{type}}]
|
||||
text_annotation_type.alt=[Аннотация {{type}}]
|
||||
toggle_slider_label=Вспомогательная панель
|
||||
thumbs_label=Уменьшенные изображения
|
||||
outline_label=Содержание документа
|
||||
|
@ -41,7 +41,7 @@ rendering_error=Дошло је до грешке приликом приказ
|
||||
page_label=Страна:
|
||||
page_of=од {{pageCount}}
|
||||
open_file.title=Отвори датотеку
|
||||
text_annotation_type=[{{type}} Annotation]
|
||||
text_annotation_type.alt=[{{type}} Annotation]
|
||||
toggle_slider_label=Клизач
|
||||
thumbs_label=Сличице
|
||||
outline_label=Документи у линијама
|
||||
|
@ -110,11 +110,11 @@ loading_error=Ett fel inträffade när PDF-filen laddades.
|
||||
invalid_file_error=Ogiltig eller korrupt PDF-fil.
|
||||
missing_file_error=PDF-filen saknas.
|
||||
|
||||
# LOCALIZATION NOTE (text_annotation_type): This is used as a tooltip.
|
||||
# LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip.
|
||||
# "{{type}}" will be replaced with an annotation type from a list defined in
|
||||
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
|
||||
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
||||
text_annotation_type=[{{type}}-anteckning]
|
||||
text_annotation_type.alt=[{{type}}-anteckning]
|
||||
request_password=PDF-filen är lösenordsskyddad:
|
||||
|
||||
printing_not_supported=Varning: Utskrifter stöds inte fullt ut av denna webbläsare.
|
||||
|
@ -110,11 +110,11 @@ loading_error=PDF yüklenirken hata.
|
||||
invalid_file_error=Geçersiz yada bozuk dosya.
|
||||
missing_file_error=PDF dosyası bulunamadı.
|
||||
|
||||
# LOCALIZATION NOTE (text_annotation_type): This is used as a tooltip.
|
||||
# LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip.
|
||||
# "{{type}}" will be replaced with an annotation type from a list defined in
|
||||
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
|
||||
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
||||
text_annotation_type=[{{type}} Not]
|
||||
text_annotation_type.alt=[{{type}} Not]
|
||||
request_password=PDF Şifre ile korunmakta:
|
||||
|
||||
printing_not_supported=Uyarı: Yazdırma işlemi bu tarayıcı ile tam desteklenmiyor.
|
||||
|
@ -110,11 +110,11 @@ loading_error=加载 PDF 文件时出错。
|
||||
invalid_file_error=PDF 文件无效或已损坏。
|
||||
missing_file_error=缺失 PDF 文件。
|
||||
|
||||
# LOCALIZATION NOTE (text_annotation_type): This is used as a tooltip.
|
||||
# LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip.
|
||||
# "{{type}}" will be replaced with an annotation type from a list defined in
|
||||
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
|
||||
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
||||
text_annotation_type=[{{type}} 注解]
|
||||
text_annotation_type.alt=[{{type}} 注解]
|
||||
request_password=该 PDF 文档受密码保护:
|
||||
|
||||
printing_not_supported=警告:该浏览器不能完全支持打印。
|
||||
|
@ -104,7 +104,7 @@ missing_file_error=遺失PDF檔案。
|
||||
# 其他標籤和訊息
|
||||
# "{{type}}" 用來表示PDF格式規範 (32000-1:2008 Table 169 – Annotation types) 入面所定義的註解種類。
|
||||
# 一些常見的類型有: "Check"、 "Text"、 "Comment"、 "Note"
|
||||
text_annotation_type=[{{type}} 註解]
|
||||
text_annotation_type.alt=[{{type}} 註解]
|
||||
request_password=PDF檔案受密碼保護:
|
||||
|
||||
printing_not_supported=警告:這個瀏覽器不完全支援列印。
|
||||
|
1
make.js
1
make.js
@ -239,6 +239,7 @@ target.bundle = function(args) {
|
||||
'api.js',
|
||||
'canvas.js',
|
||||
'obj.js',
|
||||
'annotation.js',
|
||||
'function.js',
|
||||
'charsets.js',
|
||||
'cidmaps.js',
|
||||
|
501
src/annotation.js
Normal file
501
src/annotation.js
Normal file
@ -0,0 +1,501 @@
|
||||
/* -*- 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.
|
||||
*/
|
||||
/* globals Util, isDict, isName, stringToPDFString, TODO, Dict, Stream,
|
||||
stringToBytes, PDFJS, isWorker, assert, NotImplementedException,
|
||||
Promise */
|
||||
|
||||
'use strict';
|
||||
|
||||
var Annotation = (function AnnotationClosure() {
|
||||
// 12.5.5: Algorithm: Appearance streams
|
||||
function getTransformMatrix(rect, bbox, matrix) {
|
||||
var bounds = Util.getAxialAlignedBoundingBox(bbox, matrix);
|
||||
var minX = bounds[0];
|
||||
var minY = bounds[1];
|
||||
var maxX = bounds[2];
|
||||
var maxY = bounds[3];
|
||||
|
||||
if (minX === maxX || minY === maxY) {
|
||||
// From real-life file, bbox was [0, 0, 0, 0]. In this case,
|
||||
// just apply the transform for rect
|
||||
return [1, 0, 0, 1, rect[0], rect[1]];
|
||||
}
|
||||
|
||||
var xRatio = (rect[2] - rect[0]) / (maxX - minX);
|
||||
var yRatio = (rect[3] - rect[1]) / (maxY - minY);
|
||||
return [
|
||||
xRatio,
|
||||
0,
|
||||
0,
|
||||
yRatio,
|
||||
rect[0] - minX * xRatio,
|
||||
rect[1] - minY * yRatio
|
||||
];
|
||||
}
|
||||
|
||||
function getDefaultAppearance(dict) {
|
||||
var appearanceState = dict.get('AP');
|
||||
if (!isDict(appearanceState)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var appearance;
|
||||
var appearances = appearanceState.get('N');
|
||||
if (isDict(appearances)) {
|
||||
var as = dict.get('AS');
|
||||
if (as && appearances.has(as.name)) {
|
||||
appearance = appearances.get(as.name);
|
||||
}
|
||||
} else {
|
||||
appearance = appearances;
|
||||
}
|
||||
return appearance;
|
||||
}
|
||||
|
||||
function Annotation(params) {
|
||||
if (params.data) {
|
||||
this.data = params.data;
|
||||
return;
|
||||
}
|
||||
|
||||
var dict = params.dict;
|
||||
var data = this.data = {};
|
||||
|
||||
data.subtype = dict.get('Subtype').name;
|
||||
var rect = dict.get('Rect');
|
||||
data.rect = Util.normalizeRect(rect);
|
||||
data.annotationFlags = dict.get('F');
|
||||
|
||||
var border = dict.get('BS');
|
||||
if (isDict(border)) {
|
||||
var borderWidth = border.has('W') ? border.get('W') : 1;
|
||||
data.border = {
|
||||
width: borderWidth,
|
||||
type: border.get('S') || 'S',
|
||||
rgb: dict.get('C') || [0, 0, 1]
|
||||
};
|
||||
}
|
||||
|
||||
this.appearance = getDefaultAppearance(dict);
|
||||
}
|
||||
|
||||
Annotation.prototype = {
|
||||
|
||||
getData: function Annotation_getData() {
|
||||
return this.data;
|
||||
},
|
||||
|
||||
hasHtml: function Annotation_hasHtml() {
|
||||
return false;
|
||||
},
|
||||
|
||||
getHtmlElement: function Annotation_getHtmlElement(commonObjs) {
|
||||
throw new NotImplementedException(
|
||||
'getHtmlElement() should be implemented in subclass');
|
||||
},
|
||||
|
||||
getEmptyContainer: function Annotaiton_getEmptyContainer(tagName, rect) {
|
||||
assert(!isWorker,
|
||||
'getEmptyContainer() should be called from main thread');
|
||||
|
||||
rect = rect || this.data.rect;
|
||||
var element = document.createElement(tagName);
|
||||
element.style.width = Math.ceil(rect[2] - rect[0]) + 'px';
|
||||
element.style.height = Math.ceil(rect[3] - rect[1]) + 'px';
|
||||
return element;
|
||||
},
|
||||
|
||||
isViewable: function Annotation_isViewable() {
|
||||
var data = this.data;
|
||||
return !!(
|
||||
data &&
|
||||
(!data.annotationFlags ||
|
||||
!(data.annotationFlags & 0x22)) && // Hidden or NoView
|
||||
data.rect // rectangle is nessessary
|
||||
);
|
||||
},
|
||||
|
||||
getOperatorList: function Annotation_appendToOperatorList(evaluator) {
|
||||
|
||||
var promise = new Promise();
|
||||
|
||||
if (!this.appearance) {
|
||||
promise.resolve({
|
||||
queue: {
|
||||
fnArray: [],
|
||||
argsArray: []
|
||||
},
|
||||
dependency: {}
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
var data = this.data;
|
||||
|
||||
var appearanceDict = this.appearance.dict;
|
||||
var resources = appearanceDict.get('Resources');
|
||||
var bbox = appearanceDict.get('BBox') || [0, 0, 1, 1];
|
||||
var matrix = appearanceDict.get('Matrix') || [1, 0, 0, 1, 0 ,0];
|
||||
var transform = getTransformMatrix(data.rect, bbox, matrix);
|
||||
|
||||
var border = data.border;
|
||||
|
||||
var listPromise = evaluator.getOperatorList(this.appearance, resources);
|
||||
listPromise.then(function(appearanceStreamData) {
|
||||
var fnArray = appearanceStreamData.queue.fnArray;
|
||||
var argsArray = appearanceStreamData.queue.argsArray;
|
||||
|
||||
fnArray.unshift('beginAnnotation');
|
||||
argsArray.unshift([data.rect, transform, matrix]);
|
||||
|
||||
fnArray.push('endAnnotation');
|
||||
argsArray.push([]);
|
||||
|
||||
promise.resolve(appearanceStreamData);
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
};
|
||||
|
||||
Annotation.getConstructor =
|
||||
function Annotation_getConstructor(subtype, fieldType) {
|
||||
|
||||
if (!subtype) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(mack): Implement FreeText annotations
|
||||
if (subtype === 'Link') {
|
||||
return LinkAnnotation;
|
||||
} else if (subtype === 'Text') {
|
||||
return TextAnnotation;
|
||||
} else if (subtype === 'Widget') {
|
||||
if (!fieldType) {
|
||||
return;
|
||||
}
|
||||
|
||||
return WidgetAnnotation;
|
||||
} else {
|
||||
return Annotation;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO(mack): Support loading annotation from data
|
||||
Annotation.fromData = function Annotation_fromData(data) {
|
||||
var subtype = data.subtype;
|
||||
var fieldType = data.fieldType;
|
||||
var Constructor = Annotation.getConstructor(subtype, fieldType);
|
||||
if (Constructor) {
|
||||
return new Constructor({ data: data });
|
||||
}
|
||||
};
|
||||
|
||||
Annotation.fromRef = function Annotation_fromRef(xref, ref) {
|
||||
|
||||
var dict = xref.fetchIfRef(ref);
|
||||
if (!isDict(dict)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var subtype = dict.get('Subtype');
|
||||
subtype = isName(subtype) ? subtype.name : '';
|
||||
if (!subtype) {
|
||||
return;
|
||||
}
|
||||
|
||||
var fieldType = Util.getInheritableProperty(dict, 'FT');
|
||||
fieldType = isName(fieldType) ? fieldType.name : '';
|
||||
|
||||
var Constructor = Annotation.getConstructor(subtype, fieldType);
|
||||
if (!Constructor) {
|
||||
return;
|
||||
}
|
||||
|
||||
var params = {
|
||||
dict: dict,
|
||||
ref: ref,
|
||||
};
|
||||
|
||||
var annotation = new Constructor(params);
|
||||
|
||||
if (annotation.isViewable()) {
|
||||
return annotation;
|
||||
} else {
|
||||
TODO('unimplemented annotation type: ' + subtype);
|
||||
}
|
||||
};
|
||||
|
||||
return Annotation;
|
||||
})();
|
||||
PDFJS.Annotation = Annotation;
|
||||
|
||||
|
||||
var WidgetAnnotation = (function WidgetAnnotationClosure() {
|
||||
|
||||
function WidgetAnnotation(params) {
|
||||
Annotation.call(this, params);
|
||||
|
||||
if (params.data) {
|
||||
return;
|
||||
}
|
||||
|
||||
var dict = params.dict;
|
||||
var data = this.data;
|
||||
|
||||
data.fieldValue = stringToPDFString(
|
||||
Util.getInheritableProperty(dict, 'V') || '');
|
||||
data.alternativeText = stringToPDFString(dict.get('TU') || '');
|
||||
data.defaultAppearance = Util.getInheritableProperty(dict, 'DA') || '';
|
||||
var fieldType = Util.getInheritableProperty(dict, 'FT');
|
||||
data.fieldType = isName(fieldType) ? fieldType.name : '';
|
||||
data.fieldFlags = Util.getInheritableProperty(dict, 'Ff') || 0;
|
||||
this.fieldResources = Util.getInheritableProperty(dict, 'DR') || new Dict();
|
||||
|
||||
// Building the full field name by collecting the field and
|
||||
// its ancestors 'T' data and joining them using '.'.
|
||||
var fieldName = [];
|
||||
var namedItem = dict;
|
||||
var ref = params.ref;
|
||||
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;
|
||||
}
|
||||
data.fullName = fieldName.join('.');
|
||||
}
|
||||
|
||||
var parent = Annotation.prototype;
|
||||
Util.inherit(WidgetAnnotation, Annotation, {
|
||||
isViewable: function WidgetAnnotation_isViewable() {
|
||||
if (this.data.fieldType === 'Sig') {
|
||||
TODO('unimplemented annotation type: Widget signature');
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent.isViewable.call(this);
|
||||
}
|
||||
});
|
||||
|
||||
return WidgetAnnotation;
|
||||
})();
|
||||
|
||||
var TextAnnotation = (function TextAnnotationClosure() {
|
||||
function TextAnnotation(params) {
|
||||
Annotation.call(this, params);
|
||||
|
||||
if (params.data) {
|
||||
return;
|
||||
}
|
||||
|
||||
var dict = params.dict;
|
||||
var data = this.data;
|
||||
|
||||
var content = dict.get('Contents');
|
||||
var title = dict.get('T');
|
||||
data.content = stringToPDFString(content || '');
|
||||
data.title = stringToPDFString(title || '');
|
||||
data.name = !dict.has('Name') ? 'Note' : dict.get('Name').name;
|
||||
}
|
||||
|
||||
var ANNOT_MIN_SIZE = 10;
|
||||
var IMAGE_DIR = './images/';
|
||||
|
||||
Util.inherit(TextAnnotation, Annotation, {
|
||||
|
||||
appendToOperatorList: function TextAnnotation_appendToOperatorList(
|
||||
operatorList, dependencies, evaluator) {
|
||||
return;
|
||||
},
|
||||
|
||||
hasHtml: function TextAnnotation_hasHtml() {
|
||||
return true;
|
||||
},
|
||||
|
||||
getHtmlElement: function TextAnnotation_getHtmlElement(commonObjs) {
|
||||
assert(!isWorker, 'getHtmlElement() shall be called from main thread');
|
||||
|
||||
var item = this.data;
|
||||
var rect = item.rect;
|
||||
|
||||
// sanity check because of OOo-generated PDFs
|
||||
if ((rect[3] - rect[1]) < ANNOT_MIN_SIZE) {
|
||||
rect[3] = rect[1] + ANNOT_MIN_SIZE;
|
||||
}
|
||||
if ((rect[2] - rect[0]) < ANNOT_MIN_SIZE) {
|
||||
rect[2] = rect[0] + (rect[3] - rect[1]); // make it square
|
||||
}
|
||||
|
||||
var container = this.getEmptyContainer('section', rect);
|
||||
container.className = 'annotText';
|
||||
|
||||
var image = document.createElement('img');
|
||||
image.style.width = container.style.width;
|
||||
image.style.height = container.style.height;
|
||||
var iconName = item.name;
|
||||
image.src = IMAGE_DIR + 'annotation-' +
|
||||
iconName.toLowerCase() + '.svg';
|
||||
image.alt = '[{{type}} Annotation]';
|
||||
image.dataset.l10nId = 'text_annotation_type';
|
||||
image.dataset.l10nArgs = JSON.stringify({type: iconName});
|
||||
var content = document.createElement('div');
|
||||
content.setAttribute('hidden', true);
|
||||
var title = document.createElement('h1');
|
||||
var text = document.createElement('p');
|
||||
content.style.left = Math.floor(rect[2] - rect[0]) + 'px';
|
||||
content.style.top = '0px';
|
||||
title.textContent = item.title;
|
||||
|
||||
if (!item.content && !item.title) {
|
||||
content.setAttribute('hidden', true);
|
||||
} else {
|
||||
var e = document.createElement('span');
|
||||
var lines = item.content.split(/(?:\r\n?|\n)/);
|
||||
for (var i = 0, ii = lines.length; i < ii; ++i) {
|
||||
var line = lines[i];
|
||||
e.appendChild(document.createTextNode(line));
|
||||
if (i < (ii - 1))
|
||||
e.appendChild(document.createElement('br'));
|
||||
}
|
||||
text.appendChild(e);
|
||||
image.addEventListener('mouseover', function annotationImageOver() {
|
||||
container.style.zIndex += 1;
|
||||
content.removeAttribute('hidden');
|
||||
}, false);
|
||||
|
||||
image.addEventListener('mouseout', function annotationImageOut() {
|
||||
container.style.zIndex -= 1;
|
||||
content.setAttribute('hidden', true);
|
||||
}, false);
|
||||
}
|
||||
|
||||
content.appendChild(title);
|
||||
content.appendChild(text);
|
||||
container.appendChild(image);
|
||||
container.appendChild(content);
|
||||
|
||||
return container;
|
||||
}
|
||||
});
|
||||
|
||||
return TextAnnotation;
|
||||
})();
|
||||
|
||||
var LinkAnnotation = (function LinkAnnotationClosure() {
|
||||
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':
|
||||
case 'mailto':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function LinkAnnotation(params) {
|
||||
Annotation.call(this, params);
|
||||
|
||||
if (params.data) {
|
||||
return;
|
||||
}
|
||||
|
||||
var dict = params.dict;
|
||||
var data = this.data;
|
||||
|
||||
var action = dict.get('A');
|
||||
if (action) {
|
||||
var linkType = action.get('S').name;
|
||||
if (linkType === 'URI') {
|
||||
var url = action.get('URI');
|
||||
// TODO: pdf spec mentions urls can be relative to a Base
|
||||
// entry in the dictionary.
|
||||
if (!isValidUrl(url)) {
|
||||
url = '';
|
||||
}
|
||||
data.url = url;
|
||||
} else if (linkType === 'GoTo') {
|
||||
data.dest = action.get('D');
|
||||
} else if (linkType === 'GoToR') {
|
||||
var urlDict = action.get('F');
|
||||
if (isDict(urlDict)) {
|
||||
// We assume that the 'url' is a Filspec dictionary
|
||||
// and fetch the url without checking any further
|
||||
url = urlDict.get('F') || '';
|
||||
}
|
||||
|
||||
// TODO: pdf reference says that GoToR
|
||||
// can also have 'NewWindow' attribute
|
||||
if (!isValidUrl(url)) {
|
||||
url = '';
|
||||
}
|
||||
data.url = url;
|
||||
data.dest = action.get('D');
|
||||
} else {
|
||||
TODO('unrecognized link type: ' + linkType);
|
||||
}
|
||||
} else if (dict.has('Dest')) {
|
||||
// simple destination link
|
||||
var dest = dict.get('Dest');
|
||||
data.dest = isName(dest) ? dest.name : dest;
|
||||
}
|
||||
}
|
||||
|
||||
Util.inherit(LinkAnnotation, Annotation, {
|
||||
hasOperatorList: function LinkAnnotation_hasOperatorList() {
|
||||
return false;
|
||||
},
|
||||
|
||||
hasHtml: function LinkAnnotation_hasHtml() {
|
||||
return true;
|
||||
},
|
||||
|
||||
getHtmlElement: function LinkAnnotation_getHtmlElement(commonObjs) {
|
||||
var element = this.getEmptyContainer('a');
|
||||
element.href = this.data.url || '';
|
||||
return element;
|
||||
}
|
||||
});
|
||||
|
||||
return LinkAnnotation;
|
||||
})();
|
@ -1476,24 +1476,12 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
},
|
||||
|
||||
beginAnnotation: function CanvasGraphics_beginAnnotation(rect, transform,
|
||||
matrix, border) {
|
||||
matrix) {
|
||||
this.save();
|
||||
|
||||
if (rect && isArray(rect) && 4 == rect.length) {
|
||||
var width = rect[2] - rect[0];
|
||||
var height = rect[3] - rect[1];
|
||||
|
||||
if (border) {
|
||||
// TODO(mack): Support different border styles
|
||||
this.save();
|
||||
var rgb = border.rgb;
|
||||
this.setStrokeRGBColor(rgb[0], rgb[1], rgb[2]);
|
||||
this.setLineWidth(border.width);
|
||||
this.rectangle(rect[0], rect[1], width, height);
|
||||
this.stroke();
|
||||
this.restore();
|
||||
}
|
||||
|
||||
this.rectangle(rect[0], rect[1], width, height);
|
||||
this.clip();
|
||||
this.endPath();
|
||||
|
317
src/core.js
317
src/core.js
@ -18,7 +18,7 @@
|
||||
isArrayBuffer, isDict, isName, isStream, isString, Lexer,
|
||||
Linearization, NullStream, PartialEvaluator, shadow, Stream,
|
||||
StreamsSequenceStream, stringToPDFString, TODO, Util, warn, XRef,
|
||||
MissingDataException, Promise */
|
||||
MissingDataException, Promise, Annotation */
|
||||
|
||||
'use strict';
|
||||
|
||||
@ -41,25 +41,6 @@ globalScope.PDFJS.pdfBug = false;
|
||||
|
||||
var Page = (function PageClosure() {
|
||||
|
||||
function getDefaultAnnotationAppearance(annotationDict) {
|
||||
var appearanceState = annotationDict.get('AP');
|
||||
if (!isDict(appearanceState)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var appearance;
|
||||
var appearances = appearanceState.get('N');
|
||||
if (isDict(appearances)) {
|
||||
var as = annotationDict.get('AS');
|
||||
if (as && appearances.has(as.name)) {
|
||||
appearance = appearances.get(as.name);
|
||||
}
|
||||
} else {
|
||||
appearance = appearances;
|
||||
}
|
||||
return appearance;
|
||||
}
|
||||
|
||||
function Page(pdfManager, xref, pageIndex, pageDict, ref) {
|
||||
this.pdfManager = pdfManager;
|
||||
this.pageIndex = pageIndex;
|
||||
@ -116,8 +97,8 @@ var Page = (function PageClosure() {
|
||||
|
||||
return shadow(this, 'view', cropBox);
|
||||
},
|
||||
get annotations() {
|
||||
return shadow(this, 'annotations', this.inheritPageProp('Annots'));
|
||||
get annotationRefs() {
|
||||
return shadow(this, 'annotationRefs', this.inheritPageProp('Annots'));
|
||||
},
|
||||
get rotate() {
|
||||
var rotate = this.inheritPageProp('Rotate') || 0;
|
||||
@ -157,7 +138,6 @@ var Page = (function PageClosure() {
|
||||
var promise = new Promise();
|
||||
|
||||
var pageListPromise = new Promise();
|
||||
var annotationListPromise = new Promise();
|
||||
|
||||
var pdfManager = this.pdfManager;
|
||||
var contentStreamPromise = pdfManager.ensure(this, 'getContentStream',
|
||||
@ -185,37 +165,41 @@ var Page = (function PageClosure() {
|
||||
);
|
||||
});
|
||||
|
||||
pdfManager.ensure(this, 'getAnnotationsForDraw', []).then(
|
||||
function(annotations) {
|
||||
pdfManager.ensure(partialEvaluator, 'getAnnotationsOperatorList',
|
||||
[annotations]).then(
|
||||
function(opListPromise) {
|
||||
opListPromise.then(function(data) {
|
||||
annotationListPromise.resolve(data);
|
||||
});
|
||||
var annotationsPromise = pdfManager.ensure(this, 'annotations');
|
||||
Promise.all([pageListPromise, annotationsPromise]).then(function(datas) {
|
||||
var pageData = datas[0];
|
||||
var pageQueue = pageData.queue;
|
||||
var annotations = datas[1];
|
||||
|
||||
var ensurePromises = [];
|
||||
for (var i = 0, n = annotations.length; i < n; ++i) {
|
||||
var ensurePromise = pdfManager.ensure(annotations[i],
|
||||
'getOperatorList',
|
||||
[partialEvaluator]);
|
||||
ensurePromises.push(ensurePromise);
|
||||
}
|
||||
|
||||
Promise.all(ensurePromises).then(function(listPromises) {
|
||||
Promise.all(listPromises).then(function(datas) {
|
||||
for (var i = 0, n = datas.length; i < n; ++i) {
|
||||
var annotationData = datas[i];
|
||||
var annotationQueue = annotationData.queue;
|
||||
Util.concatenateToArray(pageQueue.fnArray,
|
||||
annotationQueue.fnArray);
|
||||
Util.concatenateToArray(pageQueue.argsArray,
|
||||
annotationQueue.argsArray);
|
||||
Util.extendObj(pageData.dependencies,
|
||||
annotationData.dependencies);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Promise.all([pageListPromise, annotationListPromise]).then(
|
||||
function(datas) {
|
||||
var pageData = datas[0];
|
||||
var pageQueue = pageData.queue;
|
||||
var annotationData = datas[1];
|
||||
var annotationQueue = annotationData.queue;
|
||||
Util.concatenateToArray(pageQueue.fnArray, annotationQueue.fnArray);
|
||||
Util.concatenateToArray(pageQueue.argsArray,
|
||||
annotationQueue.argsArray);
|
||||
PartialEvaluator.optimizeQueue(pageQueue);
|
||||
Util.extendObj(pageData.dependencies, annotationData.dependencies);
|
||||
PartialEvaluator.optimizeQueue(pageQueue);
|
||||
|
||||
promise.resolve(pageData);
|
||||
}
|
||||
);
|
||||
promise.resolve(pageData);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return promise;
|
||||
|
||||
},
|
||||
extractTextContent: function Page_extractTextContent() {
|
||||
var handler = {
|
||||
@ -259,230 +243,27 @@ var Page = (function PageClosure() {
|
||||
|
||||
return textContentPromise;
|
||||
},
|
||||
getLinks: function Page_getLinks() {
|
||||
var links = [];
|
||||
var annotations = this.getAnnotations();
|
||||
var i, n = annotations.length;
|
||||
for (i = 0; i < n; ++i) {
|
||||
if (annotations[i].type != 'Link')
|
||||
continue;
|
||||
links.push(annotations[i]);
|
||||
|
||||
getAnnotationsData: function Page_getAnnotationsData() {
|
||||
var annotations = this.annotations;
|
||||
var annotationsData = [];
|
||||
for (var i = 0, n = annotations.length; i < n; ++i) {
|
||||
annotationsData.push(annotations[i].getData());
|
||||
}
|
||||
return links;
|
||||
return annotationsData;
|
||||
},
|
||||
|
||||
getAnnotations: function Page_getAnnotations() {
|
||||
var annotations = this.getAnnotationsBase();
|
||||
var items = [];
|
||||
for (var i = 0, length = annotations.length; i < length; ++i) {
|
||||
items.push(annotations[i].item);
|
||||
}
|
||||
return items;
|
||||
},
|
||||
|
||||
getAnnotationsForDraw: function Page_getAnnotationsForDraw() {
|
||||
var annotations = this.getAnnotationsBase();
|
||||
var items = [];
|
||||
for (var i = 0, length = annotations.length; i < length; ++i) {
|
||||
var item = annotations[i].item;
|
||||
var annotationDict = annotations[i].dict;
|
||||
|
||||
item.annotationFlags = annotationDict.get('F');
|
||||
|
||||
var appearance = getDefaultAnnotationAppearance(annotationDict);
|
||||
if (appearance &&
|
||||
// TODO(mack): The proper implementation requires that the
|
||||
// appearance stream overrides Name, but we're currently
|
||||
// doing it the other way around for 'Text' annotations since we
|
||||
// have special rendering for it
|
||||
item.type !== 'Text') {
|
||||
|
||||
item.appearance = appearance;
|
||||
var appearanceDict = appearance.dict;
|
||||
item.resources = appearanceDict.get('Resources');
|
||||
item.bbox = appearanceDict.get('BBox') || [0, 0, 1, 1];
|
||||
item.matrix = appearanceDict.get('Matrix') || [1, 0, 0, 1, 0 ,0];
|
||||
}
|
||||
|
||||
var border = annotationDict.get('BS');
|
||||
if (isDict(border) && !item.appearance) {
|
||||
var borderWidth = border.has('W') ? border.get('W') : 1;
|
||||
if (borderWidth !== 0) {
|
||||
item.border = {
|
||||
width: borderWidth,
|
||||
type: border.get('S') || 'S',
|
||||
rgb: annotationDict.get('C') || [0, 0, 1]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
items.push(item);
|
||||
}
|
||||
|
||||
return items;
|
||||
},
|
||||
|
||||
getAnnotationsBase: function Page_getAnnotationsBase() {
|
||||
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':
|
||||
case 'mailto':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
get annotations() {
|
||||
var annotations = [];
|
||||
var annotationRefs = this.annotationRefs || [];
|
||||
for (var i = 0, n = annotationRefs.length; i < n; ++i) {
|
||||
var annotationRef = annotationRefs[i];
|
||||
var annotation = Annotation.fromRef(this.xref, annotationRef);
|
||||
if (annotation) {
|
||||
annotations.push(annotation);
|
||||
}
|
||||
}
|
||||
|
||||
var annotations = this.annotations || [];
|
||||
var i, n = annotations.length;
|
||||
var items = [];
|
||||
for (i = 0; i < n; ++i) {
|
||||
var annotationRef = annotations[i];
|
||||
var annotation = xref.fetchIfRef(annotationRef);
|
||||
if (!isDict(annotation))
|
||||
continue;
|
||||
var subtype = annotation.get('Subtype');
|
||||
if (!isName(subtype))
|
||||
continue;
|
||||
|
||||
var item = {};
|
||||
item.type = subtype.name;
|
||||
var rect = annotation.get('Rect');
|
||||
item.rect = Util.normalizeRect(rect);
|
||||
|
||||
var includeAnnotation = true;
|
||||
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;
|
||||
case 'GoToR':
|
||||
var url = a.get('F');
|
||||
if (isDict(url)) {
|
||||
// We assume that the 'url' is a Filspec dictionary
|
||||
// and fetch the url without checking any further
|
||||
url = url.get('F') || '';
|
||||
}
|
||||
|
||||
// TODO: pdf reference says that GoToR
|
||||
// can also have 'NewWindow' attribute
|
||||
if (!isValidUrl(url))
|
||||
url = '';
|
||||
item.url = url;
|
||||
item.dest = a.get('D');
|
||||
break;
|
||||
default:
|
||||
TODO('unrecognized link type: ' + a.get('S').name);
|
||||
}
|
||||
} 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;
|
||||
|
||||
// Do not display digital signatures since we do not currently
|
||||
// validate them.
|
||||
if (fieldType.name === 'Sig') {
|
||||
includeAnnotation = false;
|
||||
break;
|
||||
}
|
||||
|
||||
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.has('Name') ? 'Note' :
|
||||
annotation.get('Name').name;
|
||||
break;
|
||||
default:
|
||||
var appearance = getDefaultAnnotationAppearance(annotation);
|
||||
if (!appearance) {
|
||||
TODO('unimplemented annotation type: ' + subtype.name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (includeAnnotation) {
|
||||
items.push({
|
||||
item: item,
|
||||
dict: annotation
|
||||
});
|
||||
}
|
||||
}
|
||||
return items;
|
||||
return shadow(this, 'annotations', annotations);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -504,10 +504,11 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
var promise = new Promise();
|
||||
|
||||
var fontRes = resources.get('Font');
|
||||
if (!fontRes) {
|
||||
warn('fontRes not available');
|
||||
}
|
||||
|
||||
assert(fontRes, 'fontRes not available');
|
||||
|
||||
font = xref.fetchIfRef(font) || fontRes.get(fontName);
|
||||
font = xref.fetchIfRef(font) || (fontRes && fontRes.get(fontName));
|
||||
if (!isDict(font)) {
|
||||
++this.idCounters.font;
|
||||
promise.resolve({
|
||||
@ -828,93 +829,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
return promise;
|
||||
},
|
||||
|
||||
getAnnotationsOperatorList:
|
||||
function PartialEvaluator_getAnnotationsOperatorList(annotations,
|
||||
dependency) {
|
||||
var promise = new Promise();
|
||||
|
||||
// 12.5.5: Algorithm: Appearance streams
|
||||
function getTransformMatrix(rect, bbox, matrix) {
|
||||
var bounds = Util.getAxialAlignedBoundingBox(bbox, matrix);
|
||||
var minX = bounds[0];
|
||||
var minY = bounds[1];
|
||||
var maxX = bounds[2];
|
||||
var maxY = bounds[3];
|
||||
var width = rect[2] - rect[0];
|
||||
var height = rect[3] - rect[1];
|
||||
var xRatio = width / (maxX - minX);
|
||||
var yRatio = height / (maxY - minY);
|
||||
return [
|
||||
xRatio,
|
||||
0,
|
||||
0,
|
||||
yRatio,
|
||||
rect[0] - minX * xRatio,
|
||||
rect[1] - minY * yRatio
|
||||
];
|
||||
}
|
||||
|
||||
var opListPromises = [];
|
||||
var includedAnnotations = [];
|
||||
|
||||
// deal with annotations
|
||||
for (var i = 0, length = annotations.length; i < length; ++i) {
|
||||
var annotation = annotations[i];
|
||||
|
||||
// check whether we can visualize annotation
|
||||
if (!annotation ||
|
||||
!annotation.annotationFlags ||
|
||||
(annotation.annotationFlags & 0x0022) || // Hidden or NoView
|
||||
!annotation.rect || // rectangle is nessessary
|
||||
!annotation.appearance) { // appearance is nessessary
|
||||
continue;
|
||||
}
|
||||
|
||||
includedAnnotations.push(annotation);
|
||||
|
||||
if (annotation.appearance) {
|
||||
var opListPromise = this.getOperatorList(annotation.appearance,
|
||||
annotation.resources);
|
||||
opListPromises.push(opListPromise);
|
||||
} else {
|
||||
var opListPromise = new Promise();
|
||||
opListPromise.resolve(createOperatorList());
|
||||
opListPromises.push(opListPromise);
|
||||
}
|
||||
}
|
||||
|
||||
Promise.all(opListPromises).then(function(datas) {
|
||||
var fnArray = [];
|
||||
var argsArray = [];
|
||||
var dependencies = {};
|
||||
for (var i = 0, n = datas.length; i < n; ++i) {
|
||||
var annotation = includedAnnotations[i];
|
||||
var data = datas[i];
|
||||
|
||||
// apply rectangle
|
||||
var rect = annotation.rect;
|
||||
var bbox = annotation.bbox;
|
||||
var matrix = annotation.matrix;
|
||||
var transform = getTransformMatrix(rect, bbox, matrix);
|
||||
var border = annotation.border;
|
||||
|
||||
fnArray.push('beginAnnotation');
|
||||
argsArray.push([rect, transform, matrix, border]);
|
||||
|
||||
Util.concatenateToArray(fnArray, data.queue.fnArray);
|
||||
Util.concatenateToArray(argsArray, data.queue.argsArray);
|
||||
Util.extendObj(dependencies, data.dependencies);
|
||||
|
||||
fnArray.push('endAnnotation');
|
||||
argsArray.push([]);
|
||||
}
|
||||
|
||||
promise.resolve(createOperatorList(fnArray, argsArray, dependencies));
|
||||
});
|
||||
|
||||
return promise;
|
||||
},
|
||||
|
||||
getTextContent: function PartialEvaluator_getTextContent(
|
||||
stream, resources) {
|
||||
|
||||
|
36
src/util.js
36
src/util.js
@ -424,11 +424,30 @@ var Util = PDFJS.Util = (function UtilClosure() {
|
||||
}
|
||||
};
|
||||
|
||||
Util.getInheritableProperty = function Util_getInheritableProperty(dict,
|
||||
name) {
|
||||
while (dict && !dict.has(name)) {
|
||||
dict = dict.get('Parent');
|
||||
}
|
||||
if (!dict) {
|
||||
return null;
|
||||
}
|
||||
return dict.get(name);
|
||||
};
|
||||
|
||||
Util.inherit = function Util_inherit(sub, base, prototype) {
|
||||
sub.prototype = Object.create(base.prototype);
|
||||
sub.prototype.constructor = sub;
|
||||
for (var prop in prototype) {
|
||||
sub.prototype[prop] = prototype[prop];
|
||||
}
|
||||
};
|
||||
|
||||
return Util;
|
||||
})();
|
||||
|
||||
var PageViewport = PDFJS.PageViewport = (function PageViewportClosure() {
|
||||
function PageViewport(viewBox, scale, rotation, offsetX, offsetY) {
|
||||
function PageViewport(viewBox, scale, rotation, offsetX, offsetY, dontFlip) {
|
||||
this.viewBox = viewBox;
|
||||
this.scale = scale;
|
||||
this.rotation = rotation;
|
||||
@ -440,25 +459,28 @@ var PageViewport = PDFJS.PageViewport = (function PageViewportClosure() {
|
||||
var centerX = (viewBox[2] + viewBox[0]) / 2;
|
||||
var centerY = (viewBox[3] + viewBox[1]) / 2;
|
||||
var rotateA, rotateB, rotateC, rotateD;
|
||||
switch (rotation % 360) {
|
||||
case -180:
|
||||
rotation = rotation % 360;
|
||||
rotation = rotation < 0 ? rotation + 360 : rotation;
|
||||
switch (rotation) {
|
||||
case 180:
|
||||
rotateA = -1; rotateB = 0; rotateC = 0; rotateD = 1;
|
||||
break;
|
||||
case -270:
|
||||
case 90:
|
||||
rotateA = 0; rotateB = 1; rotateC = 1; rotateD = 0;
|
||||
break;
|
||||
case -90:
|
||||
case 270:
|
||||
rotateA = 0; rotateB = -1; rotateC = -1; rotateD = 0;
|
||||
break;
|
||||
//case 360:
|
||||
//case 0:
|
||||
default:
|
||||
rotateA = 1; rotateB = 0; rotateC = 0; rotateD = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dontFlip) {
|
||||
rotateC = -rotateC; rotateD = -rotateD;
|
||||
}
|
||||
|
||||
var offsetCanvasX, offsetCanvasY;
|
||||
var width, height;
|
||||
if (rotateA === 0) {
|
||||
@ -494,7 +516,7 @@ var PageViewport = PDFJS.PageViewport = (function PageViewportClosure() {
|
||||
var scale = 'scale' in args ? args.scale : this.scale;
|
||||
var rotation = 'rotation' in args ? args.rotation : this.rotation;
|
||||
return new PageViewport(this.viewBox.slice(), scale, rotation,
|
||||
this.offsetX, this.offsetY);
|
||||
this.offsetX, this.offsetY, args.dontFlip);
|
||||
},
|
||||
convertToViewportPoint: function PageViewport_convertToViewportPoint(x, y) {
|
||||
return Util.applyTransform([x, y], this.transform);
|
||||
|
@ -350,11 +350,11 @@ var WorkerMessageHandler = {
|
||||
|
||||
handler.on('GetAnnotationsRequest', function wphSetupGetAnnotations(data) {
|
||||
pdfManager.getPage(data.pageIndex).then(function(page) {
|
||||
pdfManager.ensure(page, 'getAnnotations',[]).then(
|
||||
function(annotations) {
|
||||
pdfManager.ensure(page, 'getAnnotationsData', []).then(
|
||||
function(annotationsData) {
|
||||
handler.send('GetAnnotations', {
|
||||
pageIndex: data.pageIndex,
|
||||
annotations: annotations
|
||||
annotations: annotationsData
|
||||
});
|
||||
}
|
||||
);
|
||||
|
@ -26,6 +26,7 @@ var files = [
|
||||
'util.js',
|
||||
'canvas.js',
|
||||
'obj.js',
|
||||
'annotation.js',
|
||||
'function.js',
|
||||
'charsets.js',
|
||||
'cidmaps.js',
|
||||
|
@ -20,6 +20,7 @@
|
||||
<script type="text/javascript" src="../../src/util.js"></script>
|
||||
<script type="text/javascript" src="../../src/canvas.js"></script>
|
||||
<script type="text/javascript" src="../../src/obj.js"></script>
|
||||
<script type="text/javascript" src="../../src/annotation.js"></script>
|
||||
<script type="text/javascript" src="../../src/function.js"></script>
|
||||
<script type="text/javascript" src="../../src/charsets.js"></script>
|
||||
<script type="text/javascript" src="../../src/cidmaps.js"></script>
|
||||
|
@ -27,6 +27,7 @@ limitations under the License.
|
||||
<script type="text/javascript" src="/src/api.js"></script>
|
||||
<script type="text/javascript" src="/src/canvas.js"></script>
|
||||
<script type="text/javascript" src="/src/obj.js"></script>
|
||||
<script type="text/javascript" src="/src/annotation.js"></script>
|
||||
<script type="text/javascript" src="/src/function.js"></script>
|
||||
<script type="text/javascript" src="/src/charsets.js"></script>
|
||||
<script type="text/javascript" src="/src/cidmaps.js"></script>
|
||||
|
@ -19,6 +19,7 @@
|
||||
<script type="text/javascript" src="../../src/util.js"></script>
|
||||
<script type="text/javascript" src="../../src/canvas.js"></script>
|
||||
<script type="text/javascript" src="../../src/obj.js"></script>
|
||||
<script type="text/javascript" src="../../src/annotation.js"></script>
|
||||
<script type="text/javascript" src="../../src/function.js"></script>
|
||||
<script type="text/javascript" src="../../src/charsets.js"></script>
|
||||
<script type="text/javascript" src="../../src/cidmaps.js"></script>
|
||||
|
@ -47,6 +47,7 @@ limitations under the License.
|
||||
<script type="text/javascript" src="../src/metadata.js"></script>
|
||||
<script type="text/javascript" src="../src/canvas.js"></script>
|
||||
<script type="text/javascript" src="../src/obj.js"></script>
|
||||
<script type="text/javascript" src="../src/annotation.js"></script>
|
||||
<script type="text/javascript" src="../src/function.js"></script>
|
||||
<script type="text/javascript" src="../src/charsets.js"></script>
|
||||
<script type="text/javascript" src="../src/cidmaps.js"></script>
|
||||
|
115
web/viewer.js
115
web/viewer.js
@ -28,9 +28,7 @@ var SCROLLBAR_PADDING = 40;
|
||||
var VERTICAL_PADDING = 5;
|
||||
var MIN_SCALE = 0.25;
|
||||
var MAX_SCALE = 4.0;
|
||||
var IMAGE_DIR = './images/';
|
||||
var SETTINGS_MEMORY = 20;
|
||||
var ANNOT_MIN_SIZE = 10;
|
||||
var RenderingStates = {
|
||||
INITIAL: 0,
|
||||
RUNNING: 1,
|
||||
@ -2115,7 +2113,8 @@ var PageView = function pageView(container, id, scale,
|
||||
enumerable: true
|
||||
});
|
||||
|
||||
function setupAnnotations(pdfPage, viewport) {
|
||||
function setupAnnotations(annotationsDiv, pdfPage, viewport) {
|
||||
|
||||
function bindLink(link, dest) {
|
||||
link.href = PDFView.getDestinationHash(dest);
|
||||
link.onclick = function pageViewSetupLinksOnclick() {
|
||||
@ -2125,91 +2124,43 @@ var PageView = function pageView(container, id, scale,
|
||||
};
|
||||
link.className = 'internalLink';
|
||||
}
|
||||
function createElementWithStyle(tagName, item, rect) {
|
||||
if (!rect) {
|
||||
rect = viewport.convertToViewportRectangle(item.rect);
|
||||
rect = PDFJS.Util.normalizeRect(rect);
|
||||
}
|
||||
var element = document.createElement(tagName);
|
||||
element.style.left = Math.floor(rect[0]) + 'px';
|
||||
element.style.top = Math.floor(rect[1]) + 'px';
|
||||
element.style.width = Math.ceil(rect[2] - rect[0]) + 'px';
|
||||
element.style.height = Math.ceil(rect[3] - rect[1]) + 'px';
|
||||
return element;
|
||||
}
|
||||
function createTextAnnotation(item) {
|
||||
var container = document.createElement('section');
|
||||
container.className = 'annotText';
|
||||
|
||||
var rect = viewport.convertToViewportRectangle(item.rect);
|
||||
rect = PDFJS.Util.normalizeRect(rect);
|
||||
// sanity check because of OOo-generated PDFs
|
||||
if ((rect[3] - rect[1]) < ANNOT_MIN_SIZE) {
|
||||
rect[3] = rect[1] + ANNOT_MIN_SIZE;
|
||||
}
|
||||
if ((rect[2] - rect[0]) < ANNOT_MIN_SIZE) {
|
||||
rect[2] = rect[0] + (rect[3] - rect[1]); // make it square
|
||||
}
|
||||
var image = createElementWithStyle('img', item, rect);
|
||||
var iconName = item.name;
|
||||
image.src = IMAGE_DIR + 'annotation-' +
|
||||
iconName.toLowerCase() + '.svg';
|
||||
image.alt = mozL10n.get('text_annotation_type', {type: iconName},
|
||||
'[{{type}} Annotation]');
|
||||
var content = document.createElement('div');
|
||||
content.setAttribute('hidden', true);
|
||||
var title = document.createElement('h1');
|
||||
var text = document.createElement('p');
|
||||
content.style.left = Math.floor(rect[2]) + 'px';
|
||||
content.style.top = Math.floor(rect[1]) + 'px';
|
||||
title.textContent = item.title;
|
||||
|
||||
if (!item.content && !item.title) {
|
||||
content.setAttribute('hidden', true);
|
||||
} else {
|
||||
var e = document.createElement('span');
|
||||
var lines = item.content.split(/(?:\r\n?|\n)/);
|
||||
for (var i = 0, ii = lines.length; i < ii; ++i) {
|
||||
var line = lines[i];
|
||||
e.appendChild(document.createTextNode(line));
|
||||
if (i < (ii - 1))
|
||||
e.appendChild(document.createElement('br'));
|
||||
pdfPage.getAnnotations().then(function(annotationsData) {
|
||||
viewport = viewport.clone({ dontFlip: true });
|
||||
for (var i = 0; i < annotationsData.length; i++) {
|
||||
var data = annotationsData[i];
|
||||
var annotation = PDFJS.Annotation.fromData(data);
|
||||
if (!annotation || !annotation.hasHtml()) {
|
||||
continue;
|
||||
}
|
||||
text.appendChild(e);
|
||||
image.addEventListener('mouseover', function annotationImageOver() {
|
||||
content.removeAttribute('hidden');
|
||||
}, false);
|
||||
|
||||
image.addEventListener('mouseout', function annotationImageOut() {
|
||||
content.setAttribute('hidden', true);
|
||||
}, false);
|
||||
}
|
||||
var element = annotation.getHtmlElement(pdfPage.commonObjs);
|
||||
mozL10n.translate(element);
|
||||
|
||||
content.appendChild(title);
|
||||
content.appendChild(text);
|
||||
container.appendChild(image);
|
||||
container.appendChild(content);
|
||||
data = annotation.getData();
|
||||
var rect = data.rect;
|
||||
var view = pdfPage.view;
|
||||
rect = PDFJS.Util.normalizeRect([
|
||||
rect[0],
|
||||
view[3] - rect[1] + view[1],
|
||||
rect[2],
|
||||
view[3] - rect[3] + view[1]
|
||||
]);
|
||||
element.style.left = rect[0] + 'px';
|
||||
element.style.top = rect[1] + 'px';
|
||||
element.style.position = 'absolute';
|
||||
|
||||
return container;
|
||||
}
|
||||
var transform = viewport.transform;
|
||||
var transformStr = 'matrix(' + transform.join(',') + ')';
|
||||
CustomStyle.setProp('transform', element, transformStr);
|
||||
var transformOriginStr = -rect[0] + 'px ' + -rect[1] + 'px';
|
||||
CustomStyle.setProp('transformOrigin', element, transformOriginStr);
|
||||
|
||||
pdfPage.getAnnotations().then(function(items) {
|
||||
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 'Text':
|
||||
var textAnnotation = createTextAnnotation(item);
|
||||
if (textAnnotation)
|
||||
div.appendChild(textAnnotation);
|
||||
break;
|
||||
if (data.subtype === 'Link' && !data.url) {
|
||||
bindLink(element, ('dest' in data) ? data.dest : null);
|
||||
}
|
||||
|
||||
annotationsDiv.appendChild(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -2457,7 +2408,7 @@ var PageView = function pageView(container, id, scale,
|
||||
);
|
||||
}
|
||||
|
||||
setupAnnotations(this.pdfPage, this.viewport);
|
||||
setupAnnotations(div, pdfPage, this.viewport);
|
||||
div.setAttribute('data-loaded', true);
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user