merge upstream
This commit is contained in:
commit
863dd0d214
@ -32,6 +32,7 @@ const PDF_VIEWER_WEB_PAGE = 'resource://pdf.js/web/viewer.html';
|
|||||||
const MAX_DATABASE_LENGTH = 4096;
|
const MAX_DATABASE_LENGTH = 4096;
|
||||||
const FIREFOX_ID = '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}';
|
const FIREFOX_ID = '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}';
|
||||||
const SEAMONKEY_ID = '{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}';
|
const SEAMONKEY_ID = '{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}';
|
||||||
|
const METRO_ID = '{99bceaaa-e3c6-48c1-b981-ef9b46b67d60}';
|
||||||
|
|
||||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||||
Cu.import('resource://gre/modules/Services.jsm');
|
Cu.import('resource://gre/modules/Services.jsm');
|
||||||
@ -50,7 +51,8 @@ if (appInfo.ID === FIREFOX_ID) {
|
|||||||
privateBrowsing = Cc['@mozilla.org/privatebrowsing;1']
|
privateBrowsing = Cc['@mozilla.org/privatebrowsing;1']
|
||||||
.getService(Ci.nsIPrivateBrowsingService);
|
.getService(Ci.nsIPrivateBrowsingService);
|
||||||
inPrivateBrowsing = privateBrowsing.privateBrowsingEnabled;
|
inPrivateBrowsing = privateBrowsing.privateBrowsingEnabled;
|
||||||
} else if (appInfo.ID === SEAMONKEY_ID) {
|
} else if (appInfo.ID === SEAMONKEY_ID ||
|
||||||
|
appInfo.ID === METRO_ID) {
|
||||||
privateBrowsing = null;
|
privateBrowsing = null;
|
||||||
inPrivateBrowsing = false;
|
inPrivateBrowsing = false;
|
||||||
}
|
}
|
||||||
|
@ -51,8 +51,8 @@ thumb_page_title=Page {{page}}
|
|||||||
thumb_page_canvas=Thumbnail of Page {{page}}
|
thumb_page_canvas=Thumbnail of Page {{page}}
|
||||||
|
|
||||||
# Context menu
|
# Context menu
|
||||||
page_rotate_cw=Rotate Clockwise
|
page_rotate_cw.label=Rotate Clockwise
|
||||||
page_rotate_ccw=Rotate Counter-Clockwise
|
page_rotate_ccw.label=Rotate Counter-Clockwise
|
||||||
|
|
||||||
# Search panel button title and messages
|
# Search panel button title and messages
|
||||||
search=Find
|
search=Find
|
||||||
|
@ -50,6 +50,10 @@ thumb_page_title={{page}} ページ
|
|||||||
# number.
|
# number.
|
||||||
thumb_page_canvas=ページの縮小版 {{page}}
|
thumb_page_canvas=ページの縮小版 {{page}}
|
||||||
|
|
||||||
|
# Context menu
|
||||||
|
page_rotate_cw.label=右回転
|
||||||
|
page_rotate_ccw.label=左回転
|
||||||
|
|
||||||
# Search panel button title and messages
|
# Search panel button title and messages
|
||||||
search=検索
|
search=検索
|
||||||
search_terms_not_found=(見つかりませんでした)
|
search_terms_not_found=(見つかりませんでした)
|
||||||
|
@ -43,3 +43,7 @@ zoom.title=Масштаб
|
|||||||
thumb_page_title=Страница {{page}}
|
thumb_page_title=Страница {{page}}
|
||||||
thumb_page_canvas=Уменьшенное изображение страницы {{page}}
|
thumb_page_canvas=Уменьшенное изображение страницы {{page}}
|
||||||
request_password=PDF защищён паролем:
|
request_password=PDF защищён паролем:
|
||||||
|
fullscreen.title=Полный экран
|
||||||
|
fullscreen_label=Полный экран
|
||||||
|
page_rotate_cw.label=Повернуть по часовой стрелке
|
||||||
|
page_rotate_ccw.label=Повернуть против часовой стрелки
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
# Chrome 通知欄的訊息及按鍵
|
# Chrome 通知欄的訊息及按鍵
|
||||||
unsupported_feature=本 PDF 文件可能無法正常顯示。
|
unsupported_feature=本 PDF 文件可能無法正常顯示。
|
||||||
open_with_different_viewer=使用其他檢視器打開文件
|
open_with_different_viewer=使用其他檢視器打開文件
|
||||||
|
open_with_different_viewer.accessKey=o
|
@ -1,83 +1,89 @@
|
|||||||
# 主工具列按鍵 (工具提示和圖像的替代文字)
|
# 主工具列按鍵 (工具提示和圖像的替代文字)
|
||||||
previous.title=上一頁
|
previous.title=上一頁
|
||||||
previous_label=上一頁
|
previous_label=上一頁
|
||||||
next.title=下一頁
|
next.title=下一頁
|
||||||
next_label=下一頁
|
next_label=下一頁
|
||||||
|
|
||||||
# 本地化提示 (page_label, page_of):
|
# 本地化提示 (page_label, page_of):
|
||||||
# 這些字符串會連接成 "Page: X of Y" 的表示方式。
|
# 這些字符串會連接成 "Page: X of Y" 的表示方式。
|
||||||
# 不要翻譯 "{{pageCount}}" , 因為它用來表示總頁數。
|
# 不要翻譯 "{{pageCount}}" , 因為它用來表示總頁數。
|
||||||
page_label=第
|
page_label=第
|
||||||
page_of=頁, 共 {{pageCount}} 頁
|
page_of=頁,共 {{pageCount}} 頁
|
||||||
|
|
||||||
zoom_out.title=縮小
|
zoom_out.title=縮小
|
||||||
zoom_out_label=縮小
|
zoom_out_label=縮小
|
||||||
zoom_in.title=放大
|
zoom_in.title=放大
|
||||||
zoom_in_label=放大
|
zoom_in_label=放大
|
||||||
zoom.title=縮放
|
zoom.title=縮放
|
||||||
print.title=列印
|
print.title=列印
|
||||||
print_label=列印
|
print_label=列印
|
||||||
open_file.title=開啟檔案
|
fullscreen.title=全螢幕
|
||||||
open_file_label=開啟
|
fullscreen_label=全螢幕
|
||||||
download.title=下載
|
open_file.title=開啟檔案
|
||||||
download_label=下載
|
open_file_label=開啟
|
||||||
bookmark.title=目前檢視(複製或在新視窗中開啟)
|
download.title=下載
|
||||||
bookmark_label=目前檢視
|
download_label=下載
|
||||||
|
bookmark.title=目前檢視(複製或在新視窗中開啟)
|
||||||
# 側邊欄工具列按鍵 (工具提示和圖像的替代文字)
|
bookmark_label=目前檢視
|
||||||
# (_label 字符串是按鍵的替代文字, .title 字符串是工具提示)
|
|
||||||
toggle_slider.title=切換側邊欄
|
# 側邊欄工具列按鍵 (工具提示和圖像的替代文字)
|
||||||
toggle_slider_label=切換側邊欄
|
# (_label 字符串是按鍵的替代文字, .title 字符串是工具提示)
|
||||||
outline.title=顯示文件綱要
|
toggle_slider.title=切換側邊欄
|
||||||
outline_label=文件綱要
|
toggle_slider_label=切換側邊欄
|
||||||
thumbs.title=顯示縮圖
|
outline.title=顯示文件綱要
|
||||||
thumbs_label=縮圖
|
outline_label=文件綱要
|
||||||
search_panel.title=搜索文件
|
thumbs.title=顯示縮圖
|
||||||
search_panel_label=搜索
|
thumbs_label=縮圖
|
||||||
|
search_panel.title=搜索文件
|
||||||
# 文件綱要相關訊息
|
search_panel_label=搜索
|
||||||
no_outline=無可用的綱要
|
|
||||||
|
# 文件綱要相關訊息
|
||||||
# 縮圖面板項目 (工具提示和圖像的替代文字)
|
no_outline=無可用的綱要
|
||||||
# 本地化提示 (thumb_page_title): "{{page}}" 會被頁數取代。
|
|
||||||
thumb_page_title=第 {{page}} 頁
|
# 縮圖面板項目 (工具提示和圖像的替代文字)
|
||||||
# 本地化提示 (thumb_page_canvas): "{{page}}" 會被頁數取代。
|
# 本地化提示 (thumb_page_title): "{{page}}" 會被頁數取代。
|
||||||
thumb_page_canvas=第 {{page}} 頁的縮圖
|
thumb_page_title=第 {{page}} 頁
|
||||||
|
# 本地化提示 (thumb_page_canvas): "{{page}}" 會被頁數取代。
|
||||||
# 搜尋面板按鍵文字及訊息
|
thumb_page_canvas=第 {{page}} 頁的縮圖
|
||||||
search=搜索
|
|
||||||
search_terms_not_found=(沒有找到)
|
# 右鍵菜單
|
||||||
|
page_rotate_cw.label=順時針旋轉
|
||||||
# 錯誤面板標籤
|
page_rotate_ccw.label=逆時針旋轉
|
||||||
error_more_info=更多資訊
|
|
||||||
error_less_info=更少資訊
|
# 搜尋面板按鍵文字及訊息
|
||||||
error_close=關閉
|
search=搜索
|
||||||
# 本地化提示 (error_build): "{{build}}" 會被PDF.JS版本號取代。
|
search_terms_not_found=(沒有找到)
|
||||||
error_build=PDF.JS 版本號: {{build}}
|
|
||||||
# 本地化提示 (error_message): "{{message}}" 會被英文的錯誤描述取代。
|
# 錯誤面板標籤
|
||||||
error_message=錯誤信息: {{message}}
|
error_more_info=更多資訊
|
||||||
# 本地化提示 (error_stack): "{{stack}}" 會被錯誤堆疊取代。
|
error_less_info=更少資訊
|
||||||
error_stack=堆疊: {{stack}}
|
error_close=關閉
|
||||||
# 本地化提示 (error_file): "{{file}}" 會被檔案名稱取代。
|
# 本地化提示 (error_build): "{{build}}" 會被PDF.JS版本號取代。
|
||||||
error_file=檔案: {{file}}
|
error_build=PDF.JS 版本號: {{build}}
|
||||||
# 本地化提示 (error_line): "{{line}}" 會被行數取代。
|
# 本地化提示 (error_message): "{{message}}" 會被英文的錯誤描述取代。
|
||||||
error_line=行數: {{line}}
|
error_message=錯誤信息: {{message}}
|
||||||
rendering_error=渲染頁面時發生錯誤。
|
# 本地化提示 (error_stack): "{{stack}}" 會被錯誤堆疊取代。
|
||||||
|
error_stack=堆疊: {{stack}}
|
||||||
# 預設的縮放值
|
# 本地化提示 (error_file): "{{file}}" 會被檔案名稱取代。
|
||||||
page_scale_width=符合頁寬
|
error_file=檔案: {{file}}
|
||||||
page_scale_fit=符合頁面
|
# 本地化提示 (error_line): "{{line}}" 會被行數取代。
|
||||||
page_scale_auto=自動縮放
|
error_line=行數: {{line}}
|
||||||
page_scale_actual=實際大小
|
rendering_error=渲染頁面時發生錯誤。
|
||||||
|
|
||||||
# 載入指示訊息
|
# 預設的縮放值
|
||||||
# 本地化提示 (error_line): "{{percent}}" 會被百分比取代。
|
page_scale_width=符合頁寬
|
||||||
loading=正在載入... {{percent}}%
|
page_scale_fit=符合頁面
|
||||||
loading_error_indicator=錯誤
|
page_scale_auto=自動縮放
|
||||||
loading_error=載入PDF檔案時發生錯誤。
|
page_scale_actual=實際大小
|
||||||
|
|
||||||
# 其他標籤和訊息
|
# 載入指示訊息
|
||||||
# "{{type}}" 用來表示PDF格式規範 (32000-1:2008 Table 169 – Annotation types) 入面所定義的註解種類。
|
loading_error_indicator=錯誤
|
||||||
# 一些常見的類型有: "Check"、 "Text"、 "Comment"、 "Note"
|
loading_error=載入PDF檔案時發生錯誤。
|
||||||
text_annotation_type=[{{type}} 註解]
|
|
||||||
request_password=PDF檔案受密碼保護:
|
# 其他標籤和訊息
|
||||||
|
# "{{type}}" 用來表示PDF格式規範 (32000-1:2008 Table 169 – Annotation types) 入面所定義的註解種類。
|
||||||
|
# 一些常見的類型有: "Check"、 "Text"、 "Comment"、 "Note"
|
||||||
|
text_annotation_type=[{{type}} 註解]
|
||||||
|
request_password=PDF檔案受密碼保護:
|
||||||
|
|
||||||
|
printing_not_supported=警告:這個瀏覽器不完全支援列印。
|
||||||
|
19
src/api.js
19
src/api.js
@ -575,24 +575,15 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
|||||||
this.objs.resolve(id, imageData);
|
this.objs.resolve(id, imageData);
|
||||||
break;
|
break;
|
||||||
case 'Font':
|
case 'Font':
|
||||||
var name = data[2];
|
var exportedData = data[2];
|
||||||
var file = data[3];
|
|
||||||
var properties = data[4];
|
|
||||||
|
|
||||||
if (file) {
|
|
||||||
// Rewrap the ArrayBuffer in a stream.
|
|
||||||
var fontFileDict = new Dict();
|
|
||||||
file = new Stream(file, 0, file.length, fontFileDict);
|
|
||||||
}
|
|
||||||
|
|
||||||
// At this point, only the font object is created but the font is
|
// At this point, only the font object is created but the font is
|
||||||
// not yet attached to the DOM. This is done in `FontLoader.bind`.
|
// not yet attached to the DOM. This is done in `FontLoader.bind`.
|
||||||
var font;
|
var font;
|
||||||
try {
|
if ('error' in exportedData)
|
||||||
font = new Font(name, file, properties);
|
font = new ErrorFont(exportedData.error);
|
||||||
} catch (e) {
|
else
|
||||||
font = new ErrorFont(e);
|
font = new Font(exportedData);
|
||||||
}
|
|
||||||
this.objs.resolve(id, font);
|
this.objs.resolve(id, font);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -596,8 +596,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
(fontObj.bold ? 'bold' : 'normal');
|
(fontObj.bold ? 'bold' : 'normal');
|
||||||
|
|
||||||
var italic = fontObj.italic ? 'italic' : 'normal';
|
var italic = fontObj.italic ? 'italic' : 'normal';
|
||||||
var serif = fontObj.isSerifFont ? 'serif' : 'sans-serif';
|
var typeface = '"' + name + '", ' + fontObj.fallbackName;
|
||||||
var typeface = '"' + name + '", ' + serif;
|
|
||||||
|
|
||||||
// Some font backends cannot handle fonts below certain size.
|
// Some font backends cannot handle fonts below certain size.
|
||||||
// Keeping the font at minimal size and using the fontSizeScale to change
|
// Keeping the font at minimal size and using the fontSizeScale to change
|
||||||
@ -782,15 +781,9 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
x += charWidth;
|
x += charWidth;
|
||||||
|
|
||||||
var glyphUnicode = glyph.unicode === ' ' ? '\u00A0' : glyph.unicode;
|
var glyphUnicode = glyph.unicode === ' ' ? '\u00A0' : glyph.unicode;
|
||||||
var glyphUnicodeLength = glyphUnicode.length;
|
if (glyphUnicode in NormalizedUnicodes)
|
||||||
//reverse an arabic ligature
|
glyphUnicode = NormalizedUnicodes[glyphUnicode];
|
||||||
if (glyphUnicodeLength > 1 &&
|
text.str += reverseIfRtl(glyphUnicode);
|
||||||
isRTLRangeFor(glyphUnicode.charCodeAt(0))) {
|
|
||||||
for (var ii = glyphUnicodeLength - 1; ii >= 0; ii--)
|
|
||||||
text.str += glyphUnicode[ii];
|
|
||||||
} else
|
|
||||||
text.str += glyphUnicode;
|
|
||||||
text.length += glyphUnicodeLength;
|
|
||||||
text.canvasWidth += charWidth;
|
text.canvasWidth += charWidth;
|
||||||
}
|
}
|
||||||
current.x += x * textHScale2;
|
current.x += x * textHScale2;
|
||||||
@ -798,7 +791,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (textSelection)
|
if (textSelection)
|
||||||
this.textLayer.appendText(text, font.loadedName, fontSize);
|
this.textLayer.appendText(text, font.fallbackName, fontSize);
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
},
|
},
|
||||||
@ -842,7 +835,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
var numFakeSpaces = Math.round(-e / text.geom.spaceWidth);
|
var numFakeSpaces = Math.round(-e / text.geom.spaceWidth);
|
||||||
if (numFakeSpaces > 0) {
|
if (numFakeSpaces > 0) {
|
||||||
text.str += '\u00A0';
|
text.str += '\u00A0';
|
||||||
text.length++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -856,7 +848,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
text.str += shownText.str;
|
text.str += shownText.str;
|
||||||
}
|
}
|
||||||
text.canvasWidth += shownText.canvasWidth;
|
text.canvasWidth += shownText.canvasWidth;
|
||||||
text.length += shownText.length;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
error('TJ array element ' + e + ' is not string or num');
|
error('TJ array element ' + e + ' is not string or num');
|
||||||
@ -864,7 +855,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (textSelection)
|
if (textSelection)
|
||||||
this.textLayer.appendText(text, font.loadedName, fontSize);
|
this.textLayer.appendText(text, font.fallbackName, fontSize);
|
||||||
},
|
},
|
||||||
nextLineShowText: function CanvasGraphics_nextLineShowText(text) {
|
nextLineShowText: function CanvasGraphics_nextLineShowText(text) {
|
||||||
this.nextLine();
|
this.nextLine();
|
||||||
|
165
src/evaluator.js
165
src/evaluator.js
@ -26,6 +26,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
this.uniquePrefix = uniquePrefix;
|
this.uniquePrefix = uniquePrefix;
|
||||||
this.objIdCounter = 0;
|
this.objIdCounter = 0;
|
||||||
|
this.fontIdCounter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var OP_MAP = {
|
var OP_MAP = {
|
||||||
@ -138,6 +139,35 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
PartialEvaluator.prototype = {
|
PartialEvaluator.prototype = {
|
||||||
|
loadFont: function PartialEvaluator_loadFont(fontName, font, xref,
|
||||||
|
resources, dependency) {
|
||||||
|
var fontRes = resources.get('Font');
|
||||||
|
|
||||||
|
assert(fontRes, 'fontRes not available');
|
||||||
|
|
||||||
|
font = xref.fetchIfRef(font) || fontRes.get(fontName);
|
||||||
|
assertWellFormed(isDict(font));
|
||||||
|
|
||||||
|
++this.fontIdCounter;
|
||||||
|
var loadedName = font.loadedName;
|
||||||
|
if (!loadedName) {
|
||||||
|
// keep track of each font we translated so the caller can
|
||||||
|
// load them asynchronously before calling display on a page
|
||||||
|
loadedName = 'font_' + this.uniquePrefix + this.fontIdCounter;
|
||||||
|
font.loadedName = loadedName;
|
||||||
|
|
||||||
|
var translated;
|
||||||
|
try {
|
||||||
|
translated = this.translateFont(font, xref, resources,
|
||||||
|
dependency);
|
||||||
|
} catch (e) {
|
||||||
|
translated = { error: e };
|
||||||
|
}
|
||||||
|
font.translated = translated;
|
||||||
|
}
|
||||||
|
return font;
|
||||||
|
},
|
||||||
|
|
||||||
getOperatorList: function PartialEvaluator_getOperatorList(stream,
|
getOperatorList: function PartialEvaluator_getOperatorList(stream,
|
||||||
resources,
|
resources,
|
||||||
dependency,
|
dependency,
|
||||||
@ -160,46 +190,35 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleSetFont(fontName, font) {
|
function handleSetFont(fontName, font) {
|
||||||
var loadedName = null;
|
font = self.loadFont(fontName, font, xref, resources, dependency);
|
||||||
|
|
||||||
var fontRes = resources.get('Font');
|
var loadedName = font.loadedName;
|
||||||
|
if (!font.sent) {
|
||||||
|
var data = font.translated;
|
||||||
|
if (data.loadCharProcs) {
|
||||||
|
delete data.loadCharProcs;
|
||||||
|
|
||||||
assert(fontRes, 'fontRes not available');
|
var charProcs = font.get('CharProcs').getAll();
|
||||||
|
var fontResources = font.get('Resources') || resources;
|
||||||
font = xref.fetchIfRef(font) || fontRes.get(fontName);
|
var charProcOperatorList = {};
|
||||||
assertWellFormed(isDict(font));
|
for (var key in charProcs) {
|
||||||
|
var glyphStream = charProcs[key];
|
||||||
++self.objIdCounter;
|
charProcOperatorList[key] =
|
||||||
if (!font.loadedName) {
|
self.getOperatorList(glyphStream, fontResources, dependency);
|
||||||
font.translated = self.translateFont(font, xref, resources,
|
|
||||||
dependency);
|
|
||||||
if (font.translated) {
|
|
||||||
// keep track of each font we translated so the caller can
|
|
||||||
// load them asynchronously before calling display on a page
|
|
||||||
loadedName = 'font_' + uniquePrefix + self.objIdCounter;
|
|
||||||
font.translated.properties.loadedName = loadedName;
|
|
||||||
font.loadedName = loadedName;
|
|
||||||
|
|
||||||
var translated = font.translated;
|
|
||||||
// Convert the file to an ArrayBuffer which will be turned back into
|
|
||||||
// a Stream in the main thread.
|
|
||||||
if (translated.file)
|
|
||||||
translated.file = translated.file.getBytes();
|
|
||||||
if (translated.properties.file) {
|
|
||||||
translated.properties.file =
|
|
||||||
translated.properties.file.getBytes();
|
|
||||||
}
|
}
|
||||||
|
data.charProcOperatorList = charProcOperatorList;
|
||||||
handler.send('obj', [
|
|
||||||
loadedName,
|
|
||||||
'Font',
|
|
||||||
translated.name,
|
|
||||||
translated.file,
|
|
||||||
translated.properties
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data instanceof Font)
|
||||||
|
data = data.export();
|
||||||
|
|
||||||
|
handler.send('obj', [
|
||||||
|
loadedName,
|
||||||
|
'Font',
|
||||||
|
data
|
||||||
|
]);
|
||||||
|
font.sent = true;
|
||||||
}
|
}
|
||||||
loadedName = loadedName || font.loadedName;
|
|
||||||
|
|
||||||
// Ensure the font is ready before the font is set
|
// Ensure the font is ready before the font is set
|
||||||
// and later on used for drawing.
|
// and later on used for drawing.
|
||||||
@ -492,20 +511,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
var xref = this.xref;
|
var xref = this.xref;
|
||||||
|
|
||||||
function handleSetFont(fontName, fontRef) {
|
function handleSetFont(fontName, fontRef) {
|
||||||
var fontRes = resources.get('Font');
|
return self.loadFont(fontName, fontRef, xref, resources, null);
|
||||||
|
|
||||||
// TODO: TOASK: Is it possible to get here? If so, what does
|
|
||||||
// args[0].name should be like???
|
|
||||||
assert(fontRes, 'fontRes not available');
|
|
||||||
|
|
||||||
fontRes = xref.fetchIfRef(fontRes);
|
|
||||||
fontRef = fontRef || fontRes.get(fontName);
|
|
||||||
var font = xref.fetchIfRef(fontRef), tra;
|
|
||||||
assertWellFormed(isDict(font));
|
|
||||||
if (!font.translated) {
|
|
||||||
font.translated = self.translateFont(font, xref, resources);
|
|
||||||
}
|
|
||||||
return font;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resources = xref.fetchIfRef(resources) || new Dict();
|
resources = xref.fetchIfRef(resources) || new Dict();
|
||||||
@ -522,13 +528,13 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
var cmd = obj.cmd;
|
var cmd = obj.cmd;
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case 'Tf':
|
case 'Tf':
|
||||||
font = handleSetFont(args[0].name);
|
font = handleSetFont(args[0].name).translated;
|
||||||
break;
|
break;
|
||||||
case 'TJ':
|
case 'TJ':
|
||||||
var items = args[0];
|
var items = args[0];
|
||||||
for (var j = 0, jj = items.length; j < jj; j++) {
|
for (var j = 0, jj = items.length; j < jj; j++) {
|
||||||
if (typeof items[j] === 'string') {
|
if (typeof items[j] === 'string') {
|
||||||
chunk += items[j];
|
chunk += fontCharsToUnicode(items[j], font);
|
||||||
} else if (items[j] < 0) {
|
} else if (items[j] < 0) {
|
||||||
// making all negative offsets a space - better to have
|
// making all negative offsets a space - better to have
|
||||||
// a space in incorrect place than not have them at all
|
// a space in incorrect place than not have them at all
|
||||||
@ -537,17 +543,17 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'Tj':
|
case 'Tj':
|
||||||
chunk += args[0];
|
chunk += fontCharsToUnicode(args[0], font);
|
||||||
break;
|
break;
|
||||||
case "'":
|
case "'":
|
||||||
chunk += args[0] + ' ';
|
chunk += fontCharsToUnicode(args[0], font) + ' ';
|
||||||
break;
|
break;
|
||||||
case '"':
|
case '"':
|
||||||
chunk += args[2] + ' ';
|
chunk += fontCharsToUnicode(args[2], font) + ' ';
|
||||||
break;
|
break;
|
||||||
} // switch
|
} // switch
|
||||||
if (chunk !== '') {
|
if (chunk !== '') {
|
||||||
text += fontCharsToUnicode(chunk, font.translated.properties);
|
text += chunk;
|
||||||
chunk = '';
|
chunk = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -819,21 +825,41 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Heuristic: detection of monospace font by checking all non-zero widths
|
||||||
|
var isMonospace = true, firstWidth = defaultWidth;
|
||||||
|
for (var glyph in glyphsWidths) {
|
||||||
|
var glyphWidth = glyphsWidths[glyph];
|
||||||
|
if (!glyphWidth)
|
||||||
|
continue;
|
||||||
|
if (!firstWidth) {
|
||||||
|
firstWidth = glyphWidth;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (firstWidth != glyphWidth) {
|
||||||
|
isMonospace = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isMonospace)
|
||||||
|
properties.flags |= FontFlags.FixedPitch;
|
||||||
|
|
||||||
properties.defaultWidth = defaultWidth;
|
properties.defaultWidth = defaultWidth;
|
||||||
properties.widths = glyphsWidths;
|
properties.widths = glyphsWidths;
|
||||||
},
|
},
|
||||||
|
|
||||||
getBaseFontMetrics: function PartialEvaluator_getBaseFontMetrics(name) {
|
getBaseFontMetrics: function PartialEvaluator_getBaseFontMetrics(name) {
|
||||||
var defaultWidth = 0, widths = [];
|
var defaultWidth = 0, widths = [], monospace = false;
|
||||||
var glyphWidths = Metrics[stdFontMap[name] || name];
|
var glyphWidths = Metrics[stdFontMap[name] || name];
|
||||||
if (isNum(glyphWidths)) {
|
if (isNum(glyphWidths)) {
|
||||||
defaultWidth = glyphWidths;
|
defaultWidth = glyphWidths;
|
||||||
|
monospace = true;
|
||||||
} else {
|
} else {
|
||||||
widths = glyphWidths;
|
widths = glyphWidths;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
defaultWidth: defaultWidth,
|
defaultWidth: defaultWidth,
|
||||||
|
monospace: monospace,
|
||||||
widths: widths
|
widths: widths
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -854,7 +880,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
// - get the FontDescriptor from the descendant font
|
// - get the FontDescriptor from the descendant font
|
||||||
var df = dict.get('DescendantFonts');
|
var df = dict.get('DescendantFonts');
|
||||||
if (!df)
|
if (!df)
|
||||||
return null;
|
error('Descendant fonts are not specified');
|
||||||
|
|
||||||
dict = isArray(df) ? xref.fetchIfRef(df[0]) : df;
|
dict = isArray(df) ? xref.fetchIfRef(df[0]) : df;
|
||||||
|
|
||||||
@ -877,7 +903,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
// This case is here for compatibility.
|
// This case is here for compatibility.
|
||||||
var baseFontName = dict.get('BaseFont');
|
var baseFontName = dict.get('BaseFont');
|
||||||
if (!isName(baseFontName))
|
if (!isName(baseFontName))
|
||||||
return null;
|
error('Base font is not specified');
|
||||||
|
|
||||||
// Using base font name as a font name.
|
// Using base font name as a font name.
|
||||||
baseFontName = baseFontName.name.replace(/[,_]/g, '-');
|
baseFontName = baseFontName.name.replace(/[,_]/g, '-');
|
||||||
@ -887,6 +913,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
var fontNameWoStyle = baseFontName.split('-')[0];
|
var fontNameWoStyle = baseFontName.split('-')[0];
|
||||||
var flags = (serifFonts[fontNameWoStyle] ||
|
var flags = (serifFonts[fontNameWoStyle] ||
|
||||||
(fontNameWoStyle.search(/serif/gi) != -1) ? FontFlags.Serif : 0) |
|
(fontNameWoStyle.search(/serif/gi) != -1) ? FontFlags.Serif : 0) |
|
||||||
|
(metrics.monospace ? FontFlags.FixedPitch : 0) |
|
||||||
(symbolsFonts[fontNameWoStyle] ? FontFlags.Symbolic :
|
(symbolsFonts[fontNameWoStyle] ? FontFlags.Symbolic :
|
||||||
FontFlags.Nonsymbolic);
|
FontFlags.Nonsymbolic);
|
||||||
|
|
||||||
@ -900,11 +927,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
};
|
};
|
||||||
this.extractDataStructures(dict, dict, xref, properties);
|
this.extractDataStructures(dict, dict, xref, properties);
|
||||||
|
|
||||||
return {
|
return new Font(baseFontName, null, properties);
|
||||||
name: baseFontName,
|
|
||||||
dict: baseDict,
|
|
||||||
properties: properties
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -940,6 +963,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
file: fontFile,
|
file: fontFile,
|
||||||
length1: length1,
|
length1: length1,
|
||||||
length2: length2,
|
length2: length2,
|
||||||
|
loadedName: baseDict.loadedName,
|
||||||
composite: composite,
|
composite: composite,
|
||||||
wideChars: composite,
|
wideChars: composite,
|
||||||
fixedPitch: false,
|
fixedPitch: false,
|
||||||
@ -960,22 +984,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
|
|
||||||
if (type.name === 'Type3') {
|
if (type.name === 'Type3') {
|
||||||
properties.coded = true;
|
properties.coded = true;
|
||||||
var charProcs = dict.get('CharProcs').getAll();
|
|
||||||
var fontResources = dict.get('Resources') || resources;
|
|
||||||
properties.charProcOperatorList = {};
|
|
||||||
for (var key in charProcs) {
|
|
||||||
var glyphStream = charProcs[key];
|
|
||||||
properties.charProcOperatorList[key] =
|
|
||||||
this.getOperatorList(glyphStream, fontResources, dependency);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return new Font(fontName.name, fontFile, properties);
|
||||||
name: fontName.name,
|
|
||||||
dict: baseDict,
|
|
||||||
file: fontFile,
|
|
||||||
properties: properties
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
155
src/fonts.js
155
src/fonts.js
@ -418,11 +418,26 @@ function mapPrivateUseChars(code) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var FontLoader = {
|
var FontLoader = {
|
||||||
|
//#if !(MOZCENTRAL)
|
||||||
loadingContext: {
|
loadingContext: {
|
||||||
requests: [],
|
requests: [],
|
||||||
nextRequestId: 0
|
nextRequestId: 0
|
||||||
},
|
},
|
||||||
|
|
||||||
|
isSyncFontLoadingSupported: (function detectSyncFontLoadingSupport() {
|
||||||
|
if (isWorker)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// User agent string sniffing is bad, but there is no reliable way to tell
|
||||||
|
// if font is fully loaded and ready to be used with canvas.
|
||||||
|
var userAgent = window.navigator.userAgent;
|
||||||
|
var m = /Mozilla\/5.0.*?rv:(\d+).*? Gecko/.exec(userAgent);
|
||||||
|
if (m && m[1] >= 14)
|
||||||
|
return true;
|
||||||
|
// TODO other browsers
|
||||||
|
return false;
|
||||||
|
})(),
|
||||||
|
|
||||||
bind: function fontLoaderBind(fonts, callback) {
|
bind: function fontLoaderBind(fonts, callback) {
|
||||||
assert(!isWorker, 'bind() shall be called from main thread');
|
assert(!isWorker, 'bind() shall be called from main thread');
|
||||||
|
|
||||||
@ -437,23 +452,15 @@ var FontLoader = {
|
|||||||
}
|
}
|
||||||
font.attached = true;
|
font.attached = true;
|
||||||
|
|
||||||
var str = '';
|
var rule = font.bindDOM();
|
||||||
var data = font.data;
|
if (rule) {
|
||||||
if (data) {
|
rules.push(rule);
|
||||||
var length = data.length;
|
fontsToLoad.push(font);
|
||||||
for (var j = 0; j < length; j++)
|
|
||||||
str += String.fromCharCode(data[j]);
|
|
||||||
|
|
||||||
var rule = font.bindDOM(str);
|
|
||||||
if (rule) {
|
|
||||||
rules.push(rule);
|
|
||||||
fontsToLoad.push(font);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var request = FontLoader.queueLoadingCallback(callback);
|
var request = FontLoader.queueLoadingCallback(callback);
|
||||||
if (rules.length > 0) {
|
if (rules.length > 0 && !this.isSyncFontLoadingSupported) {
|
||||||
FontLoader.prepareFontLoadEvent(rules, fontsToLoad, request);
|
FontLoader.prepareFontLoadEvent(rules, fontsToLoad, request);
|
||||||
} else {
|
} else {
|
||||||
request.complete();
|
request.complete();
|
||||||
@ -595,6 +602,22 @@ var FontLoader = {
|
|||||||
document.body.appendChild(frame);
|
document.body.appendChild(frame);
|
||||||
/** Hack end */
|
/** Hack end */
|
||||||
}
|
}
|
||||||
|
//#else
|
||||||
|
//bind: function fontLoaderBind(fonts, callback) {
|
||||||
|
// assert(!isWorker, 'bind() shall be called from main thread');
|
||||||
|
//
|
||||||
|
// for (var i = 0, ii = fonts.length; i < ii; i++) {
|
||||||
|
// var font = fonts[i];
|
||||||
|
// if (font.attached)
|
||||||
|
// continue;
|
||||||
|
//
|
||||||
|
// font.attached = true;
|
||||||
|
// font.bindDOM()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// setTimeout(callback);
|
||||||
|
//}
|
||||||
|
//#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
var UnicodeRanges = [
|
var UnicodeRanges = [
|
||||||
@ -1464,54 +1487,30 @@ var NormalizedUnicodes = {
|
|||||||
'\uFE4F': '\u005F'
|
'\uFE4F': '\u005F'
|
||||||
};
|
};
|
||||||
|
|
||||||
function fontCharsToUnicode(charCodes, fontProperties) {
|
function reverseIfRtl(chars) {
|
||||||
var toUnicode = fontProperties.toUnicode;
|
var charsLength = chars.length;
|
||||||
var composite = fontProperties.composite;
|
//reverse an arabic ligature
|
||||||
var encoding, differences, cidToUnicode;
|
if (charsLength <= 1 || !isRTLRangeFor(chars.charCodeAt(0)))
|
||||||
var result = '';
|
return chars;
|
||||||
if (composite) {
|
|
||||||
cidToUnicode = fontProperties.cidToUnicode;
|
|
||||||
for (var i = 0, ii = charCodes.length; i < ii; i += 2) {
|
|
||||||
var charCode = (charCodes.charCodeAt(i) << 8) |
|
|
||||||
charCodes.charCodeAt(i + 1);
|
|
||||||
if (toUnicode && charCode in toUnicode) {
|
|
||||||
var unicode = toUnicode[charCode];
|
|
||||||
result += typeof unicode !== 'number' ? unicode :
|
|
||||||
String.fromCharCode(unicode);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
result += String.fromCharCode(!cidToUnicode ? charCode :
|
|
||||||
cidToUnicode[charCode] || charCode);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
differences = fontProperties.differences;
|
|
||||||
encoding = fontProperties.baseEncoding;
|
|
||||||
for (var i = 0, ii = charCodes.length; i < ii; i++) {
|
|
||||||
var charCode = charCodes.charCodeAt(i);
|
|
||||||
var unicode;
|
|
||||||
if (toUnicode && charCode in toUnicode) {
|
|
||||||
var unicode = toUnicode[charCode];
|
|
||||||
result += typeof unicode !== 'number' ? unicode :
|
|
||||||
String.fromCharCode(unicode);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var glyphName = charCode in differences ? differences[charCode] :
|
var s = '';
|
||||||
encoding[charCode];
|
for (var ii = charsLength - 1; ii >= 0; ii--)
|
||||||
if (glyphName in GlyphsUnicode) {
|
s += chars[ii];
|
||||||
result += String.fromCharCode(GlyphsUnicode[glyphName]);
|
return s;
|
||||||
continue;
|
}
|
||||||
}
|
|
||||||
result += String.fromCharCode(charCode);
|
function fontCharsToUnicode(charCodes, font) {
|
||||||
}
|
var glyphs = font.charsToGlyphs(charCodes);
|
||||||
}
|
var result = '';
|
||||||
// normalizing the unicode characters
|
for (var i = 0, ii = glyphs.length; i < ii; i++) {
|
||||||
for (var i = 0, ii = result.length; i < ii; i++) {
|
var glyph = glyphs[i];
|
||||||
if (!(result[i] in NormalizedUnicodes))
|
if (!glyph)
|
||||||
continue;
|
continue;
|
||||||
result = result.substring(0, i) + NormalizedUnicodes[result[i]] +
|
|
||||||
result.substring(i + 1);
|
var glyphUnicode = glyph.unicode;
|
||||||
ii = result.length;
|
if (glyphUnicode in NormalizedUnicodes)
|
||||||
|
glyphUnicode = NormalizedUnicodes[glyphUnicode];
|
||||||
|
result += reverseIfRtl(glyphUnicode);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1526,9 +1525,19 @@ function fontCharsToUnicode(charCodes, fontProperties) {
|
|||||||
*/
|
*/
|
||||||
var Font = (function FontClosure() {
|
var Font = (function FontClosure() {
|
||||||
function Font(name, file, properties) {
|
function Font(name, file, properties) {
|
||||||
|
if (arguments.length === 1) {
|
||||||
|
// importing translated data
|
||||||
|
var data = arguments[0];
|
||||||
|
for (var i in data) {
|
||||||
|
this[i] = data[i];
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.loadedName = properties.loadedName;
|
||||||
this.coded = properties.coded;
|
this.coded = properties.coded;
|
||||||
this.charProcOperatorList = properties.charProcOperatorList;
|
this.loadCharProcs = properties.coded;
|
||||||
this.sizes = [];
|
this.sizes = [];
|
||||||
|
|
||||||
var names = name.split('+');
|
var names = name.split('+');
|
||||||
@ -1536,17 +1545,13 @@ var Font = (function FontClosure() {
|
|||||||
names = names.split(/[-,_]/g)[0];
|
names = names.split(/[-,_]/g)[0];
|
||||||
this.isSerifFont = !!(properties.flags & FontFlags.Serif);
|
this.isSerifFont = !!(properties.flags & FontFlags.Serif);
|
||||||
this.isSymbolicFont = !!(properties.flags & FontFlags.Symbolic);
|
this.isSymbolicFont = !!(properties.flags & FontFlags.Symbolic);
|
||||||
|
this.isMonospace = !!(properties.flags & FontFlags.FixedPitch);
|
||||||
|
|
||||||
var type = properties.type;
|
var type = properties.type;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
|
||||||
// If the font is to be ignored, register it like an already loaded font
|
this.fallbackName = this.isMonospace ? 'monospace' :
|
||||||
// to avoid the cost of waiting for it be be loaded by the platform.
|
this.isSerifFont ? 'serif' : 'sans-serif';
|
||||||
if (properties.ignore) {
|
|
||||||
this.loadedName = this.isSerifFont ? 'serif' : 'sans-serif';
|
|
||||||
this.loading = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.differences = properties.differences;
|
this.differences = properties.differences;
|
||||||
this.widths = properties.widths;
|
this.widths = properties.widths;
|
||||||
@ -1632,7 +1637,6 @@ var Font = (function FontClosure() {
|
|||||||
this.widthMultiplier = !properties.fontMatrix ? 1.0 :
|
this.widthMultiplier = !properties.fontMatrix ? 1.0 :
|
||||||
1.0 / properties.fontMatrix[0];
|
1.0 / properties.fontMatrix[0];
|
||||||
this.encoding = properties.baseEncoding;
|
this.encoding = properties.baseEncoding;
|
||||||
this.loadedName = properties.loadedName;
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2036,6 +2040,15 @@ var Font = (function FontClosure() {
|
|||||||
mimetype: null,
|
mimetype: null,
|
||||||
encoding: null,
|
encoding: null,
|
||||||
|
|
||||||
|
export: function Font_export() {
|
||||||
|
var data = {};
|
||||||
|
for (var i in this) {
|
||||||
|
if (this.hasOwnProperty(i))
|
||||||
|
data[i] = this[i];
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
|
||||||
checkAndRepair: function Font_checkAndRepair(name, font, properties) {
|
checkAndRepair: function Font_checkAndRepair(name, font, properties) {
|
||||||
function readTableEntry(file) {
|
function readTableEntry(file) {
|
||||||
var tag = file.getBytes(4);
|
var tag = file.getBytes(4);
|
||||||
@ -3138,7 +3151,11 @@ var Font = (function FontClosure() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
bindDOM: function Font_bindDOM(data) {
|
bindDOM: function Font_bindDOM() {
|
||||||
|
if (!this.data)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var data = bytesToString(this.data);
|
||||||
var fontName = this.loadedName;
|
var fontName = this.loadedName;
|
||||||
|
|
||||||
// Add the font-face rule to the document
|
// Add the font-face rule to the document
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
// "firefox-bin: Fatal IO error 12 (Cannot allocate memory) on X server :1."
|
// "firefox-bin: Fatal IO error 12 (Cannot allocate memory) on X server :1."
|
||||||
// PDFJS.disableWorker = true;
|
// PDFJS.disableWorker = true;
|
||||||
|
|
||||||
var appPath, browser, canvas, currentTaskIdx, manifest, stdout;
|
var appPath, browser, canvas, dummyCanvas, currentTaskIdx, manifest, stdout;
|
||||||
var inFlightRequests = 0;
|
var inFlightRequests = 0;
|
||||||
|
|
||||||
function queryParams() {
|
function queryParams() {
|
||||||
@ -148,6 +148,46 @@ function canvasToDataURL() {
|
|||||||
return canvas.toDataURL('image/png');
|
return canvas.toDataURL('image/png');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function NullTextLayerBuilder() {
|
||||||
|
}
|
||||||
|
NullTextLayerBuilder.prototype = {
|
||||||
|
beginLayout: function NullTextLayerBuilder_BeginLayout() {},
|
||||||
|
endLayout: function NullTextLayerBuilder_EndLayout() {},
|
||||||
|
appendText: function NullTextLayerBuilder_AppendText() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
function SimpleTextLayerBuilder(ctx, viewport) {
|
||||||
|
this.ctx = ctx;
|
||||||
|
this.viewport = viewport;
|
||||||
|
}
|
||||||
|
SimpleTextLayerBuilder.prototype = {
|
||||||
|
beginLayout: function SimpleTextLayerBuilder_BeginLayout() {
|
||||||
|
this.ctx.save();
|
||||||
|
},
|
||||||
|
endLayout: function SimpleTextLayerBuilder_EndLayout() {
|
||||||
|
this.ctx.restore();
|
||||||
|
},
|
||||||
|
appendText: function SimpleTextLayerBuilder_AppendText(text, fontName,
|
||||||
|
fontSize) {
|
||||||
|
var ctx = this.ctx, viewport = this.viewport;
|
||||||
|
// vScale and hScale already contain the scaling to pixel units
|
||||||
|
var fontHeight = fontSize * text.geom.vScale;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.strokeStyle = 'red';
|
||||||
|
ctx.fillStyle = 'yellow';
|
||||||
|
ctx.rect(text.geom.x, text.geom.y - fontHeight,
|
||||||
|
text.canvasWidth * text.geom.hScale, fontHeight);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.fill();
|
||||||
|
|
||||||
|
var textContent = bidi(text, -1);
|
||||||
|
ctx.font = fontHeight + 'px ' + fontName;
|
||||||
|
ctx.fillStyle = 'black';
|
||||||
|
ctx.fillText(textContent, text.geom.x, text.geom.y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
function nextPage(task, loadError) {
|
function nextPage(task, loadError) {
|
||||||
var failure = loadError || '';
|
var failure = loadError || '';
|
||||||
|
|
||||||
@ -196,16 +236,21 @@ function nextPage(task, loadError) {
|
|||||||
canvas.height = viewport.height;
|
canvas.height = viewport.height;
|
||||||
clear(ctx);
|
clear(ctx);
|
||||||
|
|
||||||
// using the text layer builder that does nothing to test
|
var drawContext, textLayerBuilder;
|
||||||
// text layer creation operations
|
if (task.type == 'text') {
|
||||||
var textLayerBuilder = {
|
// using dummy canvas for pdf context drawing operations
|
||||||
beginLayout: function nullTextLayerBuilderBeginLayout() {},
|
if (!dummyCanvas) {
|
||||||
endLayout: function nullTextLayerBuilderEndLayout() {},
|
dummyCanvas = document.createElement('canvas');
|
||||||
appendText: function nullTextLayerBuilderAppendText(text, fontName,
|
}
|
||||||
fontSize) {}
|
drawContext = dummyCanvas.getContext('2d');
|
||||||
};
|
// ... text builder will draw its content on the test canvas
|
||||||
|
textLayerBuilder = new SimpleTextLayerBuilder(ctx, viewport);
|
||||||
|
} else {
|
||||||
|
drawContext = ctx;
|
||||||
|
textLayerBuilder = new NullTextLayerBuilder();
|
||||||
|
}
|
||||||
var renderContext = {
|
var renderContext = {
|
||||||
canvasContext: ctx,
|
canvasContext: drawContext,
|
||||||
textLayer: textLayerBuilder,
|
textLayer: textLayerBuilder,
|
||||||
viewport: viewport
|
viewport: viewport
|
||||||
};
|
};
|
||||||
|
@ -514,7 +514,7 @@ def check(task, results, browser, masterMode):
|
|||||||
return
|
return
|
||||||
|
|
||||||
kind = task['type']
|
kind = task['type']
|
||||||
if 'eq' == kind:
|
if 'eq' == kind or 'text' == kind:
|
||||||
checkEq(task, results, browser, masterMode)
|
checkEq(task, results, browser, masterMode)
|
||||||
elif 'fbf' == kind:
|
elif 'fbf' == kind:
|
||||||
checkFBF(task, results, browser)
|
checkFBF(task, results, browser)
|
||||||
@ -528,6 +528,7 @@ def checkEq(task, results, browser, masterMode):
|
|||||||
pfx = os.path.join(REFDIR, sys.platform, browser, task['id'])
|
pfx = os.path.join(REFDIR, sys.platform, browser, task['id'])
|
||||||
results = results[0]
|
results = results[0]
|
||||||
taskId = task['id']
|
taskId = task['id']
|
||||||
|
taskType = task['type']
|
||||||
|
|
||||||
passed = True
|
passed = True
|
||||||
for page in xrange(len(results)):
|
for page in xrange(len(results)):
|
||||||
@ -547,7 +548,7 @@ def checkEq(task, results, browser, masterMode):
|
|||||||
|
|
||||||
eq = (ref == snapshot)
|
eq = (ref == snapshot)
|
||||||
if not eq:
|
if not eq:
|
||||||
print 'TEST-UNEXPECTED-FAIL | eq', taskId, '| in', browser, '| rendering of page', page + 1, '!= reference rendering'
|
print 'TEST-UNEXPECTED-FAIL | ', taskType, taskId, '| in', browser, '| rendering of page', page + 1, '!= reference rendering'
|
||||||
|
|
||||||
if not State.eqLog:
|
if not State.eqLog:
|
||||||
State.eqLog = open(EQLOG_FILE, 'w')
|
State.eqLog = open(EQLOG_FILE, 'w')
|
||||||
@ -576,7 +577,7 @@ def checkEq(task, results, browser, masterMode):
|
|||||||
of.close()
|
of.close()
|
||||||
|
|
||||||
if passed:
|
if passed:
|
||||||
print 'TEST-PASS | eq test', task['id'], '| in', browser
|
print 'TEST-PASS | ', taskType, ' test', task['id'], '| in', browser
|
||||||
|
|
||||||
def checkFBF(task, results, browser):
|
def checkFBF(task, results, browser):
|
||||||
round0, round1 = results[0], results[1]
|
round0, round1 = results[0], results[1]
|
||||||
|
@ -11,6 +11,12 @@
|
|||||||
"rounds": 2,
|
"rounds": 2,
|
||||||
"type": "fbf"
|
"type": "fbf"
|
||||||
},
|
},
|
||||||
|
{ "id": "tracemonkey-text",
|
||||||
|
"file": "pdfs/tracemonkey.pdf",
|
||||||
|
"md5": "9a192d8b1a7dc652a19835f6f08098bd",
|
||||||
|
"rounds": 1,
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
{ "id": "html5-canvas-cheat-sheet-load",
|
{ "id": "html5-canvas-cheat-sheet-load",
|
||||||
"file": "pdfs/canvas.pdf",
|
"file": "pdfs/canvas.pdf",
|
||||||
"md5": "59510028561daf62e00bf9f6f066b033",
|
"md5": "59510028561daf62e00bf9f6f066b033",
|
||||||
@ -77,6 +83,12 @@
|
|||||||
"rounds": 1,
|
"rounds": 1,
|
||||||
"type": "load"
|
"type": "load"
|
||||||
},
|
},
|
||||||
|
{ "id": "arabiccidtruetype-text",
|
||||||
|
"file": "pdfs/ArabicCIDTrueType.pdf",
|
||||||
|
"md5": "d66dbd18bdb572d3ac8b88b32de2ece6",
|
||||||
|
"rounds": 1,
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
{ "id": "complexttffont-pdf",
|
{ "id": "complexttffont-pdf",
|
||||||
"file": "pdfs/complex_ttf_font.pdf",
|
"file": "pdfs/complex_ttf_font.pdf",
|
||||||
"md5": "76de93f9116b01b693bf8583b3e76d91",
|
"md5": "76de93f9116b01b693bf8583b3e76d91",
|
||||||
@ -89,6 +101,12 @@
|
|||||||
"rounds": 1,
|
"rounds": 1,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{ "id": "thuluthfont-text",
|
||||||
|
"file": "pdfs/ThuluthFeatures.pdf",
|
||||||
|
"md5": "b7e18bf7a3d6a9c82aefa12d721072fc",
|
||||||
|
"rounds": 1,
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
{ "id": "freeculture",
|
{ "id": "freeculture",
|
||||||
"file": "pdfs/freeculture.pdf",
|
"file": "pdfs/freeculture.pdf",
|
||||||
"md5": "dcdf3a8268e6a18938a42d5149efcfca",
|
"md5": "dcdf3a8268e6a18938a42d5149efcfca",
|
||||||
@ -263,6 +281,13 @@
|
|||||||
"rounds": 1,
|
"rounds": 1,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{ "id": "simpletype3font-text",
|
||||||
|
"file": "pdfs/simpletype3font.pdf",
|
||||||
|
"md5": "b374c7543920840c61999e9e86939f99",
|
||||||
|
"link": false,
|
||||||
|
"rounds": 1,
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
{ "id": "close-path-bug",
|
{ "id": "close-path-bug",
|
||||||
"file": "pdfs/close-path-bug.pdf",
|
"file": "pdfs/close-path-bug.pdf",
|
||||||
"md5": "48dd17ef58393857d2d038d33699cac5",
|
"md5": "48dd17ef58393857d2d038d33699cac5",
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
body {
|
body {
|
||||||
margin-top: 1.0em;
|
margin-top: 1.0em;
|
||||||
background-color: #482a30;
|
background-color: rgb(64, 64, 64);
|
||||||
|
background-image: url(web/images/texture.png);
|
||||||
font-family: Helvetica, Arial, FreeSans, san-serif;
|
font-family: Helvetica, Arial, FreeSans, san-serif;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
@ -50,20 +51,28 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2>Try it out!</h2>
|
<h2>Try it out!</h2>
|
||||||
<p>Live <a href="web/viewer.html">demo</a> lives here.</p>
|
<p>Live <a href="web/viewer.html">demo</a> or firefox <a href="https://addons.mozilla.org/en-US/firefox/addon/pdfjs/">extension</a>.</p>
|
||||||
|
|
||||||
<h2>Authors</h2>
|
<h2>Authors</h2>
|
||||||
<p>Vivien Nicolas (21@vingtetun.org)
|
Andreas Gal (gal@mozilla.com)<br/>
|
||||||
<br/>Andreas Gal (andreas.gal@gmail.com)
|
Chris G Jones (cjones@mozilla.com)<br/>
|
||||||
<br/>Soumya Deb (debloper@gmail.com)
|
Shaon Barman (shaon.barman@gmail.com)<br/>
|
||||||
<br/>Chris Jones (jones.chris.g@gmail.com)
|
Vivien Nicolas (21@vingtetun.org)<br/>
|
||||||
<br/>Justin D'Arcangelo (justindarc@gmail.com)
|
Justin D'Arcangelo (justindarc@gmail.com)<br/>
|
||||||
<br/>sbarman (sbarman@eecs.berkeley.edu)
|
Yury Delendik (ydelendik@mozilla.com)<br/>
|
||||||
<br/>
|
Kalervo Kujala<br/>
|
||||||
<br/> </p>
|
Adil Allawi (@ironymark)<br/>
|
||||||
<h2>Contact</h2>
|
Jakob Miland (saebekassebil@gmail.com)<br/>
|
||||||
<p> (andreas.gal@gmail.com)
|
Artur Adib (aadib@mozilla.com)<br/>
|
||||||
<br/> </p>
|
Brendan Dahl (bdahl@mozilla.com)<br/>
|
||||||
|
David Quintana (gigaherz@gmail.com)<br/>
|
||||||
|
Julian Viereck<br/>
|
||||||
|
<a href="https://github.com/mozilla/pdf.js/graphs/contributors">...</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Contact</h2>
|
||||||
|
<p> (dev-pdf-js@lists.mozilla.org)
|
||||||
|
<br/> </p>
|
||||||
|
|
||||||
|
|
||||||
<h2>Download</h2>
|
<h2>Download</h2>
|
||||||
|
@ -1843,22 +1843,18 @@ var TextLayerBuilder = function textLayerBuilder(textLayerDiv) {
|
|||||||
|
|
||||||
while (textDivs.length > 0) {
|
while (textDivs.length > 0) {
|
||||||
var textDiv = textDivs.shift();
|
var textDiv = textDivs.shift();
|
||||||
if (textDiv.dataset.textLength > 0) {
|
textLayerFrag.appendChild(textDiv);
|
||||||
textLayerFrag.appendChild(textDiv);
|
|
||||||
|
|
||||||
if (textDiv.dataset.textLength > 1) { // avoid div by zero
|
ctx.font = textDiv.style.fontSize + ' ' + textDiv.style.fontFamily;
|
||||||
// Adjust div width to match canvas text
|
var width = ctx.measureText(textDiv.textContent).width;
|
||||||
|
|
||||||
ctx.font = textDiv.style.fontSize + ' sans-serif';
|
if (width > 0) {
|
||||||
var width = ctx.measureText(textDiv.textContent).width;
|
var textScale = textDiv.dataset.canvasWidth / width;
|
||||||
|
|
||||||
var textScale = textDiv.dataset.canvasWidth / width;
|
CustomStyle.setProp('transform' , textDiv,
|
||||||
|
'scale(' + textScale + ', 1)');
|
||||||
CustomStyle.setProp('transform' , textDiv,
|
CustomStyle.setProp('transformOrigin' , textDiv, '0% 0%');
|
||||||
'scale(' + textScale + ', 1)');
|
}
|
||||||
CustomStyle.setProp('transformOrigin' , textDiv, '0% 0%');
|
|
||||||
}
|
|
||||||
} // textLength > 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
textLayerDiv.appendChild(textLayerFrag);
|
textLayerDiv.appendChild(textLayerFrag);
|
||||||
@ -1889,14 +1885,13 @@ var TextLayerBuilder = function textLayerBuilder(textLayerDiv) {
|
|||||||
// vScale and hScale already contain the scaling to pixel units
|
// vScale and hScale already contain the scaling to pixel units
|
||||||
var fontHeight = fontSize * text.geom.vScale;
|
var fontHeight = fontSize * text.geom.vScale;
|
||||||
textDiv.dataset.canvasWidth = text.canvasWidth * text.geom.hScale;
|
textDiv.dataset.canvasWidth = text.canvasWidth * text.geom.hScale;
|
||||||
textDiv.dataset.fontName = fontName;
|
|
||||||
|
|
||||||
textDiv.style.fontSize = fontHeight + 'px';
|
textDiv.style.fontSize = fontHeight + 'px';
|
||||||
|
textDiv.style.fontFamily = fontName;
|
||||||
textDiv.style.left = text.geom.x + 'px';
|
textDiv.style.left = text.geom.x + 'px';
|
||||||
textDiv.style.top = (text.geom.y - fontHeight) + 'px';
|
textDiv.style.top = (text.geom.y - fontHeight) + 'px';
|
||||||
textDiv.textContent = PDFJS.bidi(text, -1);
|
textDiv.textContent = PDFJS.bidi(text, -1);
|
||||||
textDiv.dir = text.direction;
|
textDiv.dir = text.direction;
|
||||||
textDiv.dataset.textLength = text.length;
|
|
||||||
this.textDivs.push(textDiv);
|
this.textDivs.push(textDiv);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -2065,7 +2060,7 @@ document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('searchTermsInput').addEventListener('keydown',
|
document.getElementById('searchTermsInput').addEventListener('keydown',
|
||||||
function() {
|
function(event) {
|
||||||
if (event.keyCode == 13) {
|
if (event.keyCode == 13) {
|
||||||
PDFView.search();
|
PDFView.search();
|
||||||
}
|
}
|
||||||
@ -2292,6 +2287,7 @@ window.addEventListener('keydown', function keydown(evt) {
|
|||||||
PDFView.zoomIn();
|
PDFView.zoomIn();
|
||||||
handled = true;
|
handled = true;
|
||||||
break;
|
break;
|
||||||
|
case 173: // FF/Mac '-'
|
||||||
case 109: // FF '-'
|
case 109: // FF '-'
|
||||||
case 189: // Chrome '-'
|
case 189: // Chrome '-'
|
||||||
PDFView.zoomOut();
|
PDFView.zoomOut();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user