Refactor code for annotations

This commit is contained in:
Mack Duan 2013-03-21 01:04:44 -07:00
parent e5b5c94925
commit f8f4b3f45d
39 changed files with 667 additions and 499 deletions

View File

@ -12,6 +12,7 @@
<script type="text/javascript" src="../../src/api.js"></script> <script type="text/javascript" src="../../src/api.js"></script>
<script type="text/javascript" src="../../src/canvas.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/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/function.js"></script>
<script type="text/javascript" src="../../src/charsets.js"></script> <script type="text/javascript" src="../../src/charsets.js"></script>
<script type="text/javascript" src="../../src/cidmaps.js"></script> <script type="text/javascript" src="../../src/cidmaps.js"></script>

View File

@ -12,6 +12,7 @@
<script type="text/javascript" src="../../src/api.js"></script> <script type="text/javascript" src="../../src/api.js"></script>
<script type="text/javascript" src="../../src/canvas.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/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/function.js"></script>
<script type="text/javascript" src="../../src/charsets.js"></script> <script type="text/javascript" src="../../src/charsets.js"></script>
<script type="text/javascript" src="../../src/cidmaps.js"></script> <script type="text/javascript" src="../../src/cidmaps.js"></script>

View File

@ -105,7 +105,10 @@
// Arabic, Hebrew, Farsi, Pashto, Urdu // Arabic, Hebrew, Farsi, Pashto, Urdu
var rtlList = ['ar', 'he', 'fa', 'ps', 'ur']; var rtlList = ['ar', 'he', 'fa', 'ps', 'ur'];
return (rtlList.indexOf(gLanguage) >= 0) ? 'rtl' : 'ltr'; return (rtlList.indexOf(gLanguage) >= 0) ? 'rtl' : 'ltr';
} },
// translate an element or document fragment
translate: translateFragment
}; };
})(this); })(this);

View File

@ -98,11 +98,11 @@ page_scale_actual=الحجم الحقيقي
loading_error_indicator=خطأ loading_error_indicator=خطأ
loading_error=حدث خطأ أثناء تحميل وثيقه الـPDF 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 # "{{type}}" will be replaced with an annotation type from a list defined in
# the PDF spec (32000-1:2008 Table 169 Annotation types). # the PDF spec (32000-1:2008 Table 169 Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note" # Some common types are e.g.: "Check", "Text", "Comment", "Note"
text_annotation_type=[ملاحظة {{type}}] text_annotation_type.alt=[ملاحظة {{type}}]
request_password=الـPDF محمي بكلمة مرور: request_password=الـPDF محمي بكلمة مرور:
printing_not_supported=تحذير: الطباعة ليست مدعومة كليًا في هذا المتصفح. printing_not_supported=تحذير: الطباعة ليست مدعومة كليًا في هذا المتصفح.

View File

@ -114,11 +114,11 @@ loading_error_indicator=Error
loading_error=Ha ocorregut un error mentres es carregava el PDF. loading_error=Ha ocorregut un error mentres es carregava el PDF.
invalid_file_error=Invàlid o fitxer PDF corrupte. 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 # "{{type}}" will be replaced with an annotation type from a list defined in
# the PDF spec (32000-1:2008 Table 169 Annotation types). # the PDF spec (32000-1:2008 Table 169 Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note" # 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: request_password=El PDF està protegit amb una contrasenya:
printing_not_supported=Avís: La impressió no és compatible totalment en aquest navegador. printing_not_supported=Avís: La impressió no és compatible totalment en aquest navegador.

View File

@ -41,7 +41,7 @@ rendering_error=Došlo k chybě při vykreslování stránky.
page_label=Stránka: page_label=Stránka:
page_of=z{{pageCount}} page_of=z{{pageCount}}
open_file.title=Otevřít soubor open_file.title=Otevřít soubor
text_annotation_type=[{{type}}Anotace] text_annotation_type.alt=[{{type}}Anotace]
toggle_slider_label=Přepnout posuvník toggle_slider_label=Přepnout posuvník
thumbs_label=Náhledy thumbs_label=Náhledy
outline_label=Přehled dokumentu outline_label=Přehled dokumentu

View File

@ -114,7 +114,7 @@ missing_file_error=Manglende PDF-fil
# "{{type}}" vil blive ersattet af en kommentar type fra en liste # "{{type}}" vil blive ersattet af en kommentar type fra en liste
# defineret i PDF specifikationen (32000-1:2008 Table 169 Annotation types). # defineret i PDF specifikationen (32000-1:2008 Table 169 Annotation types).
# Nogle almindelige typer er f.eks.: "Check", "Text", "Comment" og "Note" # 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: request_password=PDF filen er beskyttet med et kodeord:
invalid_password=Ugyldigt kodeord. invalid_password=Ugyldigt kodeord.

View File

@ -109,11 +109,11 @@ loading_error_indicator=Fehler
loading_error=Das PDF konnte nicht geladen werden. loading_error=Das PDF konnte nicht geladen werden.
invalid_file_error=Ungültige oder beschädigte PDF-Datei. 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 # "{{type}}" will be replaced with an annotation type from a list defined in
# the PDF spec (32000-1:2008 Table 169 Annotation types). # the PDF spec (32000-1:2008 Table 169 Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note" # 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: request_password=Das PDF ist passwortgeschützt:
printing_not_supported=Warnung: Drucken wird durch diesen Browser nicht vollständig unterstützt. printing_not_supported=Warnung: Drucken wird durch diesen Browser nicht vollständig unterstützt.

View File

@ -110,11 +110,11 @@ loading_error=An error occurred while loading the PDF.
invalid_file_error=Invalid or corrupted PDF file. invalid_file_error=Invalid or corrupted PDF file.
missing_file_error=Missing 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 # "{{type}}" will be replaced with an annotation type from a list defined in
# the PDF spec (32000-1:2008 Table 169 Annotation types). # the PDF spec (32000-1:2008 Table 169 Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note" # 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: request_password=PDF is protected by a password:
invalid_password=Invalid Password. invalid_password=Invalid Password.

View File

@ -114,7 +114,7 @@ missing_file_error=Falta el archivo PDF.
# "{{type}}" will be replaced with an annotation type from a list defined in # "{{type}}" will be replaced with an annotation type from a list defined in
# the PDF spec (32000-1:2008 Table 169 Annotation types). # the PDF spec (32000-1:2008 Table 169 Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note" # 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: 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. printing_not_supported=Aviso: Este navegador no es compatible completamente con la impresión.

View File

@ -110,11 +110,11 @@ loading_error=Virhe on tapahtunut PDF:ää ladattaessa.
invalid_file_error=Virheellinen tai vioittunut PDF tiedosto. invalid_file_error=Virheellinen tai vioittunut PDF tiedosto.
missing_file_error=PDF tiedostoa ei löytynyt. 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 # "{{type}}" will be replaced with an annotation type from a list defined in
# the PDF spec (32000-1:2008 Table 169 Annotation types). # the PDF spec (32000-1:2008 Table 169 Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note" # 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: request_password=PDF on salasanasuojattu:
printing_not_supported=Varoitus: Tämä selain ei täysin tue tulostusta. printing_not_supported=Varoitus: Tämä selain ei täysin tue tulostusta.

View File

@ -114,7 +114,7 @@ missing_file_error=Fichier PDF manquant.
# "{{type}}" will be replaced with an annotation type from a list defined in # "{{type}}" will be replaced with an annotation type from a list defined in
# the PDF spec (32000-1:2008 Table 169 Annotation types). # the PDF spec (32000-1:2008 Table 169 Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note" # 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 : 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. printing_not_supported=Attention : l'impression n'est pas totalement prise en charge par ce navigateur.

View File

@ -41,7 +41,7 @@ rendering_error=אירעה שגיאה בעת עיבוד הדף.
page_label=דף: page_label=דף:
page_of=מתוך {{pageCount}} page_of=מתוך {{pageCount}}
open_file.title=פתיחת קובץ open_file.title=פתיחת קובץ
text_annotation_type=[{{type}} Annotation] text_annotation_type.alt=[{{type}} Annotation]
toggle_slider_label=מתג החלקה toggle_slider_label=מתג החלקה
thumbs_label=תמונות ממוזערות thumbs_label=תמונות ממוזערות
outline_label=מתאר מסמך outline_label=מתאר מסמך

View File

@ -41,4 +41,4 @@ rendering_error=
page_label=Pagina: page_label=Pagina:
page_of=di {{pageCount}} page_of=di {{pageCount}}
open_file.title=Apri File open_file.title=Apri File
text_annotation_type=[{{type}} Annotazione] text_annotation_type.alt=[{{type}} Annotazione]

View File

@ -110,11 +110,11 @@ loading_error=PDF の読み込み中にエラーが発生しました
invalid_file_error=無効または破損した PDF ファイル invalid_file_error=無効または破損した PDF ファイル
missing_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 # "{{type}}" will be replaced with an annotation type from a list defined in
# the PDF spec (32000-1:2008 Table 169 Annotation types). # the PDF spec (32000-1:2008 Table 169 Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note" # Some common types are e.g.: "Check", "Text", "Comment", "Note"
text_annotation_type=[{{type}} 注釈] text_annotation_type.alt=[{{type}} 注釈]
request_password=PDF はパスワードによって保護されています request_password=PDF はパスワードによって保護されています
printing_not_supported=警告:このブラウザでは印刷が完全にサポートされていません printing_not_supported=警告:このブラウザでは印刷が完全にサポートされていません

View File

@ -110,11 +110,11 @@ loading_error=PDF bylos įkelimo metu įvyko klaida.
invalid_file_error=Neteisinga arba pažeista PDF byla. invalid_file_error=Neteisinga arba pažeista PDF byla.
missing_file_error=Trūksta PDF bylos. 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 # "{{type}}" will be replaced with an annotation type from a list defined in
# the PDF spec (32000-1:2008 Table 169 Annotation types). # the PDF spec (32000-1:2008 Table 169 Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note" # 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: request_password=PDF byla yra apsaugota slaptažodžiu:
printing_not_supported=Dėmesio: Naršyklė pilnai nepalaiko spausdinimo. printing_not_supported=Dėmesio: Naršyklė pilnai nepalaiko spausdinimo.

View File

@ -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. invalid_file_error=Ongeldig of corrupt PDF-bestand.
missing_file_error=Ontbrekend 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 # "{{type}}" will be replaced with an annotation type from a list defined in
# the PDF spec (32000-1:2008 Table 169 Annotation types). # the PDF spec (32000-1:2008 Table 169 Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note" # 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: request_password=Dit PDF-bestand is beveiligd met een wachtwoord:
printing_not_supported=Waarschuwing: afdrukken wordt niet volledig ondersteund door deze browser. printing_not_supported=Waarschuwing: afdrukken wordt niet volledig ondersteund door deze browser.

View File

@ -110,11 +110,11 @@ loading_error=Wystąpił błąd podczas wczytywania pliku PDF.
invalid_file_error=Błędny lub uszkodzony plik PDF. invalid_file_error=Błędny lub uszkodzony plik PDF.
missing_file_error=Nie znaleziono pliku 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 # "{{type}}" will be replaced with an annotation type from a list defined in
# the PDF spec (32000-1:2008 Table 169 - Annotation types). # the PDF spec (32000-1:2008 Table 169 - Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note" # 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: 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ę. printing_not_supported=Ostrzeżenie: Drukowanie nie jest w pełni obsługiwane przez tę przeglądarkę.

View File

@ -41,4 +41,4 @@ rendering_error=Um erro ocorreu ao apresentar a página.
page_label=Página: page_label=Página:
page_of=de {{pageCount}} page_of=de {{pageCount}}
open_file.title=Abrir arquivo open_file.title=Abrir arquivo
text_annotation_type=[{{type}} Anotações] text_annotation_type.alt=[{{type}} Anotações]

View File

@ -41,7 +41,7 @@ rendering_error=S-a produs o eroare în timpul procesării paginii.
page_label=Pagina: page_label=Pagina:
page_of=din {{pageCount}} page_of=din {{pageCount}}
open_file.title=Deschide fișier open_file.title=Deschide fișier
text_annotation_type=[Adnotare {{type}}] text_annotation_type.alt=[Adnotare {{type}}]
toggle_slider_label=Vedere de ansamblu toggle_slider_label=Vedere de ansamblu
thumbs_label=Miniaturi thumbs_label=Miniaturi
outline_label=Cuprins outline_label=Cuprins

View File

@ -41,7 +41,7 @@ rendering_error=Произошла ошибка во время создания
page_label=Страница: page_label=Страница:
page_of=из {{pageCount}} page_of=из {{pageCount}}
open_file.title=Открыть файл open_file.title=Открыть файл
text_annotation_type=[Аннотация {{type}}] text_annotation_type.alt=[Аннотация {{type}}]
toggle_slider_label=Вспомогательная панель toggle_slider_label=Вспомогательная панель
thumbs_label=Уменьшенные изображения thumbs_label=Уменьшенные изображения
outline_label=Содержание документа outline_label=Содержание документа

View File

@ -41,7 +41,7 @@ rendering_error=Дошло је до грешке приликом приказ
page_label=Страна: page_label=Страна:
page_of=од {{pageCount}} page_of=од {{pageCount}}
open_file.title=Отвори датотеку open_file.title=Отвори датотеку
text_annotation_type=[{{type}} Annotation] text_annotation_type.alt=[{{type}} Annotation]
toggle_slider_label=Клизач toggle_slider_label=Клизач
thumbs_label=Сличице thumbs_label=Сличице
outline_label=Документи у линијама outline_label=Документи у линијама

View File

@ -110,11 +110,11 @@ loading_error=Ett fel inträffade när PDF-filen laddades.
invalid_file_error=Ogiltig eller korrupt PDF-fil. invalid_file_error=Ogiltig eller korrupt PDF-fil.
missing_file_error=PDF-filen saknas. 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 # "{{type}}" will be replaced with an annotation type from a list defined in
# the PDF spec (32000-1:2008 Table 169 Annotation types). # the PDF spec (32000-1:2008 Table 169 Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note" # 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: request_password=PDF-filen är lösenordsskyddad:
printing_not_supported=Varning: Utskrifter stöds inte fullt ut av denna webbläsare. printing_not_supported=Varning: Utskrifter stöds inte fullt ut av denna webbläsare.

View File

@ -110,11 +110,11 @@ loading_error=PDF yüklenirken hata.
invalid_file_error=Geçersiz yada bozuk dosya. invalid_file_error=Geçersiz yada bozuk dosya.
missing_file_error=PDF dosyası bulunamadı. 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 # "{{type}}" will be replaced with an annotation type from a list defined in
# the PDF spec (32000-1:2008 Table 169 Annotation types). # the PDF spec (32000-1:2008 Table 169 Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note" # 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: request_password=PDF Şifre ile korunmakta:
printing_not_supported=Uyarı: Yazdırma işlemi bu tarayıcı ile tam desteklenmiyor. printing_not_supported=Uyarı: Yazdırma işlemi bu tarayıcı ile tam desteklenmiyor.

View File

@ -110,11 +110,11 @@ loading_error=加载 PDF 文件时出错。
invalid_file_error=PDF 文件无效或已损坏。 invalid_file_error=PDF 文件无效或已损坏。
missing_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 # "{{type}}" will be replaced with an annotation type from a list defined in
# the PDF spec (32000-1:2008 Table 169 Annotation types). # the PDF spec (32000-1:2008 Table 169 Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note" # Some common types are e.g.: "Check", "Text", "Comment", "Note"
text_annotation_type=[{{type}} 注解] text_annotation_type.alt=[{{type}} 注解]
request_password=该 PDF 文档受密码保护: request_password=该 PDF 文档受密码保护:
printing_not_supported=警告:该浏览器不能完全支持打印。 printing_not_supported=警告:该浏览器不能完全支持打印。

View File

@ -104,7 +104,7 @@ missing_file_error=遺失PDF檔案。
# 其他標籤和訊息 # 其他標籤和訊息
# "{{type}}" 用來表示PDF格式規範 (32000-1:2008 Table 169 Annotation types) 入面所定義的註解種類。 # "{{type}}" 用來表示PDF格式規範 (32000-1:2008 Table 169 Annotation types) 入面所定義的註解種類。
# 一些常見的類型有: "Check"、 "Text"、 "Comment"、 "Note" # 一些常見的類型有: "Check"、 "Text"、 "Comment"、 "Note"
text_annotation_type={{type}} 註解] text_annotation_type.alt={{type}} 註解]
request_password=PDF檔案受密碼保護 request_password=PDF檔案受密碼保護
printing_not_supported=警告:這個瀏覽器不完全支援列印。 printing_not_supported=警告:這個瀏覽器不完全支援列印。

View File

@ -239,6 +239,7 @@ target.bundle = function(args) {
'api.js', 'api.js',
'canvas.js', 'canvas.js',
'obj.js', 'obj.js',
'annotation.js',
'function.js', 'function.js',
'charsets.js', 'charsets.js',
'cidmaps.js', 'cidmaps.js',

501
src/annotation.js Normal file
View 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;
})();

View File

@ -1476,24 +1476,12 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
}, },
beginAnnotation: function CanvasGraphics_beginAnnotation(rect, transform, beginAnnotation: function CanvasGraphics_beginAnnotation(rect, transform,
matrix, border) { matrix) {
this.save(); this.save();
if (rect && isArray(rect) && 4 == rect.length) { if (rect && isArray(rect) && 4 == rect.length) {
var width = rect[2] - rect[0]; var width = rect[2] - rect[0];
var height = rect[3] - rect[1]; 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.rectangle(rect[0], rect[1], width, height);
this.clip(); this.clip();
this.endPath(); this.endPath();

View File

@ -18,7 +18,7 @@
isArrayBuffer, isDict, isName, isStream, isString, Lexer, isArrayBuffer, isDict, isName, isStream, isString, Lexer,
Linearization, NullStream, PartialEvaluator, shadow, Stream, Linearization, NullStream, PartialEvaluator, shadow, Stream,
StreamsSequenceStream, stringToPDFString, TODO, Util, warn, XRef, StreamsSequenceStream, stringToPDFString, TODO, Util, warn, XRef,
MissingDataException, Promise */ MissingDataException, Promise, Annotation */
'use strict'; 'use strict';
@ -41,25 +41,6 @@ globalScope.PDFJS.pdfBug = false;
var Page = (function PageClosure() { 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) { function Page(pdfManager, xref, pageIndex, pageDict, ref) {
this.pdfManager = pdfManager; this.pdfManager = pdfManager;
this.pageIndex = pageIndex; this.pageIndex = pageIndex;
@ -116,8 +97,8 @@ var Page = (function PageClosure() {
return shadow(this, 'view', cropBox); return shadow(this, 'view', cropBox);
}, },
get annotations() { get annotationRefs() {
return shadow(this, 'annotations', this.inheritPageProp('Annots')); return shadow(this, 'annotationRefs', this.inheritPageProp('Annots'));
}, },
get rotate() { get rotate() {
var rotate = this.inheritPageProp('Rotate') || 0; var rotate = this.inheritPageProp('Rotate') || 0;
@ -157,7 +138,6 @@ var Page = (function PageClosure() {
var promise = new Promise(); var promise = new Promise();
var pageListPromise = new Promise(); var pageListPromise = new Promise();
var annotationListPromise = new Promise();
var pdfManager = this.pdfManager; var pdfManager = this.pdfManager;
var contentStreamPromise = pdfManager.ensure(this, 'getContentStream', var contentStreamPromise = pdfManager.ensure(this, 'getContentStream',
@ -185,37 +165,41 @@ var Page = (function PageClosure() {
); );
}); });
pdfManager.ensure(this, 'getAnnotationsForDraw', []).then( var annotationsPromise = pdfManager.ensure(this, 'annotations');
function(annotations) { Promise.all([pageListPromise, annotationsPromise]).then(function(datas) {
pdfManager.ensure(partialEvaluator, 'getAnnotationsOperatorList', var pageData = datas[0];
[annotations]).then( var pageQueue = pageData.queue;
function(opListPromise) { var annotations = datas[1];
opListPromise.then(function(data) {
annotationListPromise.resolve(data); 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( PartialEvaluator.optimizeQueue(pageQueue);
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);
promise.resolve(pageData); promise.resolve(pageData);
} });
); });
});
return promise; return promise;
}, },
extractTextContent: function Page_extractTextContent() { extractTextContent: function Page_extractTextContent() {
var handler = { var handler = {
@ -259,230 +243,27 @@ var Page = (function PageClosure() {
return textContentPromise; return textContentPromise;
}, },
getLinks: function Page_getLinks() {
var links = []; getAnnotationsData: function Page_getAnnotationsData() {
var annotations = this.getAnnotations(); var annotations = this.annotations;
var i, n = annotations.length; var annotationsData = [];
for (i = 0; i < n; ++i) { for (var i = 0, n = annotations.length; i < n; ++i) {
if (annotations[i].type != 'Link') annotationsData.push(annotations[i].getData());
continue;
links.push(annotations[i]);
} }
return links; return annotationsData;
}, },
getAnnotations: function Page_getAnnotations() { get annotations() {
var annotations = this.getAnnotationsBase(); var annotations = [];
var items = []; var annotationRefs = this.annotationRefs || [];
for (var i = 0, length = annotations.length; i < length; ++i) { for (var i = 0, n = annotationRefs.length; i < n; ++i) {
items.push(annotations[i].item); var annotationRef = annotationRefs[i];
} var annotation = Annotation.fromRef(this.xref, annotationRef);
return items; if (annotation) {
}, annotations.push(annotation);
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;
} }
} }
return shadow(this, 'annotations', annotations);
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;
} }
}; };

View File

@ -504,10 +504,11 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
var promise = new Promise(); var promise = new Promise();
var fontRes = resources.get('Font'); var fontRes = resources.get('Font');
if (!fontRes) {
warn('fontRes not available');
}
assert(fontRes, 'fontRes not available'); font = xref.fetchIfRef(font) || (fontRes && fontRes.get(fontName));
font = xref.fetchIfRef(font) || fontRes.get(fontName);
if (!isDict(font)) { if (!isDict(font)) {
++this.idCounters.font; ++this.idCounters.font;
promise.resolve({ promise.resolve({
@ -828,93 +829,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
return promise; 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( getTextContent: function PartialEvaluator_getTextContent(
stream, resources) { stream, resources) {

View File

@ -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; return Util;
})(); })();
var PageViewport = PDFJS.PageViewport = (function PageViewportClosure() { 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.viewBox = viewBox;
this.scale = scale; this.scale = scale;
this.rotation = rotation; this.rotation = rotation;
@ -440,25 +459,28 @@ var PageViewport = PDFJS.PageViewport = (function PageViewportClosure() {
var centerX = (viewBox[2] + viewBox[0]) / 2; var centerX = (viewBox[2] + viewBox[0]) / 2;
var centerY = (viewBox[3] + viewBox[1]) / 2; var centerY = (viewBox[3] + viewBox[1]) / 2;
var rotateA, rotateB, rotateC, rotateD; var rotateA, rotateB, rotateC, rotateD;
switch (rotation % 360) { rotation = rotation % 360;
case -180: rotation = rotation < 0 ? rotation + 360 : rotation;
switch (rotation) {
case 180: case 180:
rotateA = -1; rotateB = 0; rotateC = 0; rotateD = 1; rotateA = -1; rotateB = 0; rotateC = 0; rotateD = 1;
break; break;
case -270:
case 90: case 90:
rotateA = 0; rotateB = 1; rotateC = 1; rotateD = 0; rotateA = 0; rotateB = 1; rotateC = 1; rotateD = 0;
break; break;
case -90:
case 270: case 270:
rotateA = 0; rotateB = -1; rotateC = -1; rotateD = 0; rotateA = 0; rotateB = -1; rotateC = -1; rotateD = 0;
break; break;
//case 360:
//case 0: //case 0:
default: default:
rotateA = 1; rotateB = 0; rotateC = 0; rotateD = -1; rotateA = 1; rotateB = 0; rotateC = 0; rotateD = -1;
break; break;
} }
if (dontFlip) {
rotateC = -rotateC; rotateD = -rotateD;
}
var offsetCanvasX, offsetCanvasY; var offsetCanvasX, offsetCanvasY;
var width, height; var width, height;
if (rotateA === 0) { if (rotateA === 0) {
@ -494,7 +516,7 @@ var PageViewport = PDFJS.PageViewport = (function PageViewportClosure() {
var scale = 'scale' in args ? args.scale : this.scale; var scale = 'scale' in args ? args.scale : this.scale;
var rotation = 'rotation' in args ? args.rotation : this.rotation; var rotation = 'rotation' in args ? args.rotation : this.rotation;
return new PageViewport(this.viewBox.slice(), scale, 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) { convertToViewportPoint: function PageViewport_convertToViewportPoint(x, y) {
return Util.applyTransform([x, y], this.transform); return Util.applyTransform([x, y], this.transform);

View File

@ -350,11 +350,11 @@ var WorkerMessageHandler = {
handler.on('GetAnnotationsRequest', function wphSetupGetAnnotations(data) { handler.on('GetAnnotationsRequest', function wphSetupGetAnnotations(data) {
pdfManager.getPage(data.pageIndex).then(function(page) { pdfManager.getPage(data.pageIndex).then(function(page) {
pdfManager.ensure(page, 'getAnnotations',[]).then( pdfManager.ensure(page, 'getAnnotationsData', []).then(
function(annotations) { function(annotationsData) {
handler.send('GetAnnotations', { handler.send('GetAnnotations', {
pageIndex: data.pageIndex, pageIndex: data.pageIndex,
annotations: annotations annotations: annotationsData
}); });
} }
); );

View File

@ -26,6 +26,7 @@ var files = [
'util.js', 'util.js',
'canvas.js', 'canvas.js',
'obj.js', 'obj.js',
'annotation.js',
'function.js', 'function.js',
'charsets.js', 'charsets.js',
'cidmaps.js', 'cidmaps.js',

View File

@ -20,6 +20,7 @@
<script type="text/javascript" src="../../src/util.js"></script> <script type="text/javascript" src="../../src/util.js"></script>
<script type="text/javascript" src="../../src/canvas.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/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/function.js"></script>
<script type="text/javascript" src="../../src/charsets.js"></script> <script type="text/javascript" src="../../src/charsets.js"></script>
<script type="text/javascript" src="../../src/cidmaps.js"></script> <script type="text/javascript" src="../../src/cidmaps.js"></script>

View File

@ -27,6 +27,7 @@ limitations under the License.
<script type="text/javascript" src="/src/api.js"></script> <script type="text/javascript" src="/src/api.js"></script>
<script type="text/javascript" src="/src/canvas.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/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/function.js"></script>
<script type="text/javascript" src="/src/charsets.js"></script> <script type="text/javascript" src="/src/charsets.js"></script>
<script type="text/javascript" src="/src/cidmaps.js"></script> <script type="text/javascript" src="/src/cidmaps.js"></script>

View File

@ -19,6 +19,7 @@
<script type="text/javascript" src="../../src/util.js"></script> <script type="text/javascript" src="../../src/util.js"></script>
<script type="text/javascript" src="../../src/canvas.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/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/function.js"></script>
<script type="text/javascript" src="../../src/charsets.js"></script> <script type="text/javascript" src="../../src/charsets.js"></script>
<script type="text/javascript" src="../../src/cidmaps.js"></script> <script type="text/javascript" src="../../src/cidmaps.js"></script>

View File

@ -47,6 +47,7 @@ limitations under the License.
<script type="text/javascript" src="../src/metadata.js"></script> <script type="text/javascript" src="../src/metadata.js"></script>
<script type="text/javascript" src="../src/canvas.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/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/function.js"></script>
<script type="text/javascript" src="../src/charsets.js"></script> <script type="text/javascript" src="../src/charsets.js"></script>
<script type="text/javascript" src="../src/cidmaps.js"></script> <script type="text/javascript" src="../src/cidmaps.js"></script>

View File

@ -28,9 +28,7 @@ var SCROLLBAR_PADDING = 40;
var VERTICAL_PADDING = 5; var VERTICAL_PADDING = 5;
var MIN_SCALE = 0.25; var MIN_SCALE = 0.25;
var MAX_SCALE = 4.0; var MAX_SCALE = 4.0;
var IMAGE_DIR = './images/';
var SETTINGS_MEMORY = 20; var SETTINGS_MEMORY = 20;
var ANNOT_MIN_SIZE = 10;
var RenderingStates = { var RenderingStates = {
INITIAL: 0, INITIAL: 0,
RUNNING: 1, RUNNING: 1,
@ -2115,7 +2113,8 @@ var PageView = function pageView(container, id, scale,
enumerable: true enumerable: true
}); });
function setupAnnotations(pdfPage, viewport) { function setupAnnotations(annotationsDiv, pdfPage, viewport) {
function bindLink(link, dest) { function bindLink(link, dest) {
link.href = PDFView.getDestinationHash(dest); link.href = PDFView.getDestinationHash(dest);
link.onclick = function pageViewSetupLinksOnclick() { link.onclick = function pageViewSetupLinksOnclick() {
@ -2125,91 +2124,43 @@ var PageView = function pageView(container, id, scale,
}; };
link.className = 'internalLink'; 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); pdfPage.getAnnotations().then(function(annotationsData) {
rect = PDFJS.Util.normalizeRect(rect); viewport = viewport.clone({ dontFlip: true });
// sanity check because of OOo-generated PDFs for (var i = 0; i < annotationsData.length; i++) {
if ((rect[3] - rect[1]) < ANNOT_MIN_SIZE) { var data = annotationsData[i];
rect[3] = rect[1] + ANNOT_MIN_SIZE; var annotation = PDFJS.Annotation.fromData(data);
} if (!annotation || !annotation.hasHtml()) {
if ((rect[2] - rect[0]) < ANNOT_MIN_SIZE) { continue;
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'));
} }
text.appendChild(e);
image.addEventListener('mouseover', function annotationImageOver() {
content.removeAttribute('hidden');
}, false);
image.addEventListener('mouseout', function annotationImageOut() { var element = annotation.getHtmlElement(pdfPage.commonObjs);
content.setAttribute('hidden', true); mozL10n.translate(element);
}, false);
}
content.appendChild(title); data = annotation.getData();
content.appendChild(text); var rect = data.rect;
container.appendChild(image); var view = pdfPage.view;
container.appendChild(content); 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) { if (data.subtype === 'Link' && !data.url) {
for (var i = 0; i < items.length; i++) { bindLink(element, ('dest' in data) ? data.dest : null);
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;
} }
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); div.setAttribute('data-loaded', true);
}; };