Reputation:
How to detect whether or not a particular font is installed using javascript only. (Disregard to whether it is enabled or not).
Thanks
Upvotes: 15
Views: 20923
Reputation: 1413
For latest browser , the window.queryLocalFonts() method returns a Promise that fulfills with an array of FontData objects representing the font faces available locally.
for older browser, here is a solution to check if font is installed in your device in a html page. The idea is :create a extreme narrow font and define it in css with data object url, check target font's width with this font.
Here is the example:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<script type="text/javascript">
(function () {
const context = document.createElement("canvas").getContext("2d");
context.font = "200px SANS-SERIF"
const TEXT_TO_MEASURE = "A";
var FONT_WIDTH = context.measureText(TEXT_TO_MEASURE).width;
(function () {
var style = document.createElement("style");
style.setAttribute("type", "text/css");
style.textContent = `@font-face{font-family:'__DEFAULT_FONT__';src:url('data:application/font-woff;base64,d09GRgABAAAAAAM0AAsAAAAABCQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAABVPUy8yAAABcAAAADwAAABgNVxaOmNtYXAAAAG0AAAAKQAAADQADACUZ2FzcAAAAywAAAAIAAAACP//AANnbHlmAAAB6AAAACQAAAAwK9MKuGhlYWQAAAEIAAAAMwAAADYLo1XbaGhlYQAAATwAAAAcAAAAJP2RAdRobXR4AAABrAAAAAgAAAAIAMn9LGxvY2EAAAHgAAAABgAAAAYAGAAMbWF4cAAAAVgAAAAXAAAAIAAEAAVuYW1lAAACDAAAAQsAAAHwJKxCKHBvc3QAAAMYAAAAEwAAACD/KgCWeNpjYGRgYABi+QdqV+P5bb4ycHMwgMD1GraPEJqz/d80BoZ/PxgygFw2kFoGBgA++AvVAHjaY2BkYGBgBMOUf9MYc/79YACJIAMmAF7xBGN42mNgZGBgYGJgYQDRDFASCQAAAQEACgB42mNgZkhhnMDAysDAOovVmIGBURpCM19kSGMSYmBgAklhBR4+CgoMDgyOQMgIhhlgYUYoCaEZAIdLBiEAZP6WAGT+lnjaY2BgYGJgYGAGYhEgyQimWRgUgDQLEIL4jv//Q8j/B8B8BgBSlwadAAAAAAAADAAYAAB42mNg/DeNgeHfD4YMBmYGBkVTY9F/05IyMhgYcIgDAGnPDrV42oWQzU7CUBCFvwISZcEz3LjSBBoQ/yIrYzTEGEmIYY9QiglS01YMOx/DV+AtPXeophtjmumdOffMmXMH2GdOlaB2ACwUuzwQvi7yCk3d7PIqh794rcTZI+WryOslvMFn0OCJDW9EmjRhqtOxVRwJTXhXpxOa8CrOhJXQY0JhJ3Tocmn5NUt9jhEvxHKTk1kV6YyksNZ/ZnUsxaV0Uh4ZKm65YmycTL2J9J1UQ2l3/sT73JvKxlz0aJXc9Lkzds6NeiNNylWn1u37z0wjFP9UcSH8XFmbZ03JtYmFTu99Xqg4PqSR2Q5+9PxbnBx4Zyu9yP070+ultkPHoNhRmwchsaqpOLbhb0h9RfYAeNpjYGYAg//qDNMYsAAAKDQBwAAAAAAB//8AAg==');}`;
document.documentElement.appendChild(style);
var handleId = null;
(function initailizeDefaultFont() {
context.font = "200px __DEFAULT_FONT__";
var width = context.measureText(TEXT_TO_MEASURE).width;
if (width != FONT_WIDTH) {
FONT_WIDTH = width;
cancelAnimationFrame(handleId);
}
else if (handleId == null) {
handleId = requestAnimationFrame(initailizeDefaultFont);
}
})();
})();
function checkFontAvailable(font) {
if (/^\s*SANS-SERIF\s*$/i.test(font)) {
return true;
}
if (!font || font == '__DEFAULT_FONT__') {
return false;
}
context.font = `200px ${font.replace(/^\s*['"]|['"]\s*$/g, "")}, __DEFAULT_FONT__`;
var width = context.measureText(TEXT_TO_MEASURE).width;
return width != FONT_WIDTH;
}
this.checkFontAvailable = checkFontAvailable;
}).apply(this);
console.log([checkFontAvailable("arial black b"), checkFontAvailable("arial black")]);
</script>
</head>
<body>
</body>
</html>
Here is the test result:
checkFontAvailable("微软雅黑333")
false
checkFontAvailable("微软雅黑")
true
checkFontAvailable("arial")
true
checkFontAvailable("arial black")
true
Upvotes: 7
Reputation: 143
The last answer was provided 11 years ago. In the meantime there are new solutions available for people who are still looking for a solution:
You could use the FontFaceSet
API provided by browsers. It is currently still an experimental technology, but already available in most browsers (except IE).
The check() method of the FontFaceSet returns whether all fonts in the given font list have been loaded and are available.
Example:
const fontAvailable = document.fonts.check("16px Arial");
When using the check()
method, make sure to check if font loading operations have been completed by using the ready
property, which returns a Promise
when the loading has finished:
let fontAvailable;
document.fonts.ready.then(() => {
fontAvailable = document.fonts.check("16px Arial");
});
Upvotes: 10
Reputation: 328614
If you absolutely need a specific font, all your visitors must have current browsers. Then you can use webfonts.
If that's not an option, you must render the font on your server and serve an image.
Upvotes: 1
Reputation: 155
Put this code anywhere in your javascript file.
(function (document) {
var width;
var body = document.body;
var container = document.createElement('span');
container.innerHTML = Array(100).join('wi');
container.style.cssText = [
'position:absolute',
'width:auto',
'font-size:128px',
'left:-99999px'
].join(' !important;');
var getWidth = function (fontFamily) {
container.style.fontFamily = fontFamily;
body.appendChild(container);
width = container.clientWidth;
body.removeChild(container);
return width;
};
// Pre compute the widths of monospace, serif & sans-serif
// to improve performance.
var monoWidth = getWidth('monospace');
var serifWidth = getWidth('serif');
var sansWidth = getWidth('sans-serif');
window.isFontAvailable = function (font) {
return monoWidth !== getWidth(font + ',monospace') ||
sansWidth !== getWidth(font + ',sans-serif') ||
serifWidth !== getWidth(font + ',serif');
};
})(document);
Usage
console.log(isFontAvailable('Arial Black'))
// Evaluates true
console.log(isFontAvailable('thisdoesntexists'))
// Evaluates false
Source
https://www.samclarke.com/javascript-is-font-available
Upvotes: 3
Reputation: 25147
Font family declarations should suffice to provide a fallback in case the font you want to use is not present.
But if you really need to use a special font in your site, although this uses JavaScript, I'd recommend Cufon since it's the most cross-browser solution out there - there is a CSS3 fix (font-face declarations), but it doesn't work in all browsers yet.
Upvotes: 0
Reputation: 382706
@Matchu suggested you rightly but here is what you are looking for:
http://remysharp.com/2008/07/08/how-to-detect-if-a-font-is-installed-only-using-javascript/
Upvotes: 1
Reputation: 85792
How about you just do what the rest of the world does: specify the font with CSS, and offer fallbacks? No app should ever need to know what fonts are available, nor is there a reliable way of doing so. (You would probably have to print hidden div with the font and measure it to see if the dimensions are what you expected, but that would be extremely brittle.)
Just go for:
body { font-family: MyFont, Helvetica, Arial, sans-serif }
If you want to be doing anything with the font other than display things in it if possible, consider an alternative solution.
Upvotes: -1