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