Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refer to webfontloader, use fontfaceset to detect if font has loaded #3708

Merged
merged 1 commit into from Jan 3, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
103 changes: 91 additions & 12 deletions cocos2d/core/load-pipeline/font-loader.js
Expand Up @@ -26,14 +26,44 @@
const textUtils = require('../utils/text-utils');

let _canvasContext = null;
let _testString = "BES bswy:->@";
// letter symbol number CJK
let _testString = "BES bswy:->@123\u4E01\u3041\u1101";

let _fontFaces = {};
let _intervalId = -1;
let _loadingFonts = [];
// 60 seconds timeout
let _timeout = 60000;

// Refer to https://github.com/typekit/webfontloader/blob/master/src/core/fontwatcher.js
let useNativeCheck = (function () {
var nativeCheck = undefined;
return function () {
if (nativeCheck === undefined) {
if (!!window.FontFace) {
var match = /Gecko.*Firefox\/(\d+)/.exec(window.navigator.userAgent);
var safari10Match = /OS X.*Version\/10\..*Safari/.exec(window.navigator.userAgent) && /Apple/.exec(window.navigator.vendor);

if (match) {
nativeCheck = parseInt(match[1], 10) > 42;
}
else if (safari10Match) {
nativeCheck = false;
}
else {
nativeCheck = true;
}

} else {
nativeCheck = false;
}
}

return nativeCheck;

}
})();

function _checkFontLoaded () {
let allFontsLoaded = true;
let now = Date.now();
Expand Down Expand Up @@ -68,6 +98,50 @@ function _checkFontLoaded () {
}
}

// refer to https://github.com/typekit/webfontloader/blob/master/src/core/nativefontwatchrunner.js
function nativeCheckFontLoaded (start, font, callback) {
var loader = new Promise(function (resolve, reject) {
jareguo marked this conversation as resolved.
Show resolved Hide resolved
var check = function () {
var now = Date.now();

if (now - start >= _timeout) {
reject();
}
else {
document.fonts.load('40px ' + font).then(function (fonts) {
if (fonts.length >= 1) {
resolve();
}
else {
setTimeout(check, 100);
}
}, function () {
reject();
});
}
};

check();
});

var timeoutId = null,
timer = new Promise(function (resolve, reject) {
timeoutId = setTimeout(reject, _timeout);
});

Promise.race([timer, loader]).then(function () {
if (timeoutId) {
clearTimeout(timeoutId);
timeoutId = null;
}

callback(null, font);
}, function () {
cc.warnID(4933, font);
callback(null, font);
});
}

var fontLoader = {
loadFont: function (item, callback) {
let url = item.url;
Expand Down Expand Up @@ -112,19 +186,24 @@ var fontLoader = {
divStyle.top = "-100px";
document.body.appendChild(preloadDiv);

// Save loading font
let fontLoadHandle = {
fontFamilyName,
refWidth,
callback,
startTime: Date.now()
if (useNativeCheck()) {
nativeCheckFontLoaded(Date.now(), fontFamilyName, callback);
}
_loadingFonts.push(fontLoadHandle);
_fontFaces[fontFamilyName] = fontStyle;

if (_intervalId === -1) {
_intervalId = setInterval(_checkFontLoaded, 100);
else {
// Save loading font
let fontLoadHandle = {
fontFamilyName,
refWidth,
callback,
startTime: Date.now()
}
_loadingFonts.push(fontLoadHandle);
if (_intervalId === -1) {
_intervalId = setInterval(_checkFontLoaded, 100);
}
}
_fontFaces[fontFamilyName] = fontStyle;

},

_getFontFamily: function (fontHandle) {
Expand Down