From 6a230af332f8125b88715feadffc640dac06e946 Mon Sep 17 00:00:00 2001 From: Rob Wu Date: Tue, 30 Sep 2014 19:33:16 +0200 Subject: [PATCH 1/2] Rename FontFace to FontFaceObject This name clashes with the FontFace constructor from the Font Loading CSS module: http://dev.w3.org/csswg/css-font-loading/#font-face-constructor --- src/display/api.js | 7 ++++--- src/display/font_loader.js | 12 ++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/display/api.js b/src/display/api.js index 23ff6421f..e400e1d5b 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -17,8 +17,9 @@ /* globals PDFJS, isArrayBuffer, error, combineUrl, createPromiseCapability, StatTimer, globalScope, MessageHandler, info, FontLoader, Util, warn, Promise, PasswordResponses, PasswordException, InvalidPDFException, - MissingPDFException, UnknownErrorException, FontFace, loadJpegStream, - createScratchCanvas, CanvasGraphics, UnexpectedResponseException */ + MissingPDFException, UnknownErrorException, FontFaceObject, + loadJpegStream, createScratchCanvas, CanvasGraphics, + UnexpectedResponseException */ 'use strict'; @@ -962,7 +963,7 @@ var WorkerTransport = (function WorkerTransportClosure() { this.commonObjs.resolve(id, error); break; } else { - font = new FontFace(exportedData); + font = new FontFaceObject(exportedData); } FontLoader.bind( diff --git a/src/display/font_loader.js b/src/display/font_loader.js index 105ed8322..a7deaaf1f 100644 --- a/src/display/font_loader.js +++ b/src/display/font_loader.js @@ -271,8 +271,8 @@ var FontLoader = { //#endif }; -var FontFace = (function FontFaceClosure() { - function FontFace(name, file, properties) { +var FontFaceObject = (function FontFaceObjectClosure() { + function FontFaceObject(name, file, properties) { this.compiledGlyphs = {}; if (arguments.length === 1) { // importing translated data @@ -283,8 +283,8 @@ var FontFace = (function FontFaceClosure() { return; } } - FontFace.prototype = { - bindDOM: function FontFace_bindDOM() { + FontFaceObject.prototype = { + bindDOM: function FontFaceObject_bindDOM() { if (!this.data) { return null; } @@ -311,7 +311,7 @@ var FontFace = (function FontFaceClosure() { return rule; }, - getPathGenerator: function (objs, character) { + getPathGenerator: function FontLoader_getPathGenerator(objs, character) { if (!(character in this.compiledGlyphs)) { var js = objs.get(this.loadedName + '_path_' + character); /*jshint -W054 */ @@ -320,5 +320,5 @@ var FontFace = (function FontFaceClosure() { return this.compiledGlyphs[character]; } }; - return FontFace; + return FontFaceObject; })(); From d0845df971b1462c361c9a3dd8cfd42d1b03a632 Mon Sep 17 00:00:00 2001 From: Rob Wu Date: Tue, 30 Sep 2014 21:24:31 +0200 Subject: [PATCH 2/2] Use Font Loading API if available http://dev.w3.org/csswg/css-font-loading/ --- src/display/font_loader.js | 65 ++++++++++++++++++++++++++++++++++---- web/debugger.js | 11 +++++-- 2 files changed, 67 insertions(+), 9 deletions(-) diff --git a/src/display/font_loader.js b/src/display/font_loader.js index a7deaaf1f..6d2b8a801 100644 --- a/src/display/font_loader.js +++ b/src/display/font_loader.js @@ -15,7 +15,7 @@ * limitations under the License. */ /* globals PDFJS, shadow, isWorker, assert, warn, bytesToString, string32, - globalScope */ + globalScope, FontFace, Promise */ 'use strict'; @@ -40,6 +40,12 @@ var FontLoader = { if (styleElement) { styleElement.parentNode.removeChild(styleElement); } +//#if !(MOZCENTRAL) + this.nativeFontFaces.forEach(function(nativeFontFace) { + document.fonts.delete(nativeFontFace); + }); + this.nativeFontFaces.length = 0; +//#endif }, //#if !(MOZCENTRAL) get loadTestFont() { @@ -97,10 +103,21 @@ var FontLoader = { return false; })(), + nativeFontFaces: [], + + isFontLoadingAPISupported: !isWorker && !!document.fonts, + + addNativeFontFace: function fontLoader_addNativeFontFace(nativeFontFace) { + this.nativeFontFaces.push(nativeFontFace); + document.fonts.add(nativeFontFace); + }, + bind: function fontLoaderBind(fonts, callback) { assert(!isWorker, 'bind() shall be called from main thread'); - var rules = [], fontsToLoad = []; + var rules = []; + var fontsToLoad = []; + var fontLoadPromises = []; for (var i = 0, ii = fonts.length; i < ii; i++) { var font = fonts[i]; @@ -111,15 +128,26 @@ var FontLoader = { } font.attached = true; - var rule = font.bindDOM(); - if (rule) { - rules.push(rule); - fontsToLoad.push(font); + if (this.isFontLoadingAPISupported) { + var nativeFontFace = font.createNativeFontFace(); + if (nativeFontFace) { + fontLoadPromises.push(nativeFontFace.loaded); + } + } else { + var rule = font.bindDOM(); + if (rule) { + rules.push(rule); + fontsToLoad.push(font); + } } } var request = FontLoader.queueLoadingCallback(callback); - if (rules.length > 0 && !this.isSyncFontLoadingSupported) { + if (this.isFontLoadingAPISupported) { + Promise.all(fontsToLoad).then(function() { + request.complete(); + }); + } else if (rules.length > 0 && !this.isSyncFontLoadingSupported) { FontLoader.prepareFontLoadEvent(rules, fontsToLoad, request); } else { request.complete(); @@ -284,6 +312,29 @@ var FontFaceObject = (function FontFaceObjectClosure() { } } FontFaceObject.prototype = { +//#if !(MOZCENTRAL) + createNativeFontFace: function FontFaceObject_createNativeFontFace() { + if (!this.data) { + return null; + } + + if (PDFJS.disableFontFace) { + this.disableFontFace = true; + return null; + } + + var nativeFontFace = new FontFace(this.loadedName, this.data); + + FontLoader.addNativeFontFace(nativeFontFace); + + if (PDFJS.pdfBug && 'FontInspector' in globalScope && + globalScope['FontInspector'].enabled) { + globalScope['FontInspector'].fontAdded(this); + } + return nativeFontFace; + }, +//#endif + bindDOM: function FontFaceObject_bindDOM() { if (!this.data) { return null; diff --git a/web/debugger.js b/web/debugger.js index 81da232ee..a9d173b72 100644 --- a/web/debugger.js +++ b/web/debugger.js @@ -112,13 +112,20 @@ var FontInspector = (function FontInspectorClosure() { return moreInfo; } var moreInfo = properties(fontObj, ['name', 'type']); - var m = /url\(['"]?([^\)"']+)/.exec(url); var fontName = fontObj.loadedName; var font = document.createElement('div'); var name = document.createElement('span'); name.textContent = fontName; var download = document.createElement('a'); - download.href = m[1]; + if (url) { + url = /url\(['"]?([^\)"']+)/.exec(url); + download.href = url[1]; + } else if (fontObj.data) { + url = URL.createObjectURL(new Blob([fontObj.data], { + type: fontObj.mimeType + })); + } + download.href = url; download.textContent = 'Download'; var logIt = document.createElement('a'); logIt.href = '';