How to detect font-smoothing using JavaScript

Source: Internet
Author: User
Tags pixel coloring

In an earlier article, I mentioned that boing-boing had a few issues when they wanted to use @ font-face embedding inside their website. in short, the problem was that some fonts look bad on computer monitors without font-smoothing enabled in the operating system. this brought on a lot of discussion as to whether there was a way to detect whether or not font-smoothing was being used using JavaScript. I initially thought there wasn't a way, but after seeing a promising but incomplete Method of Detecting font-smoothing, I spent a few days devising a way to do it.

Internet Explorer does something easily (for a change)

Paul Irish mentioned to me and a few other colleagues that he came should ss a page using an Active X control that detects font-smoothing in IE. I was so hopeful... Until I realized that this only works on browsers that have come into contact with Microsoft's online cleartype tuner, which I visited with my copy of IE months before. if a users had never visited this page, the script wowould fail.

I was more disappointed because googling "JavaScript cleartype" did not point to anything useful. however, searching for "javascript font-Smoothing" pointed me to an article that told me about Internet Explorer's screen. fontsmoothingenabled property. this gives us what we need... But only in Internet Explorer. How on earth can we detect font-smoothing in other browsers, and in non-Windows operating systems?

Canvas to the rescue

Letter 'O', Arial font, 32 px, rendered both without (left) and with (right) font-Smoothing

I then thought about the screenshots I made for the @ font-face in depth article. can a browser render a black glyph and detect if there is some sort of non-black pixel coloring around the its edges of the glyphs?A human can tell the difference: If there are some non-black pixels around the edge of the glyph, it must be using font-smoothing.

ButWeb browsers can do this too!Just have the browser draw a letter in black insideCanvasTag, and then have it sift through the canvas 'pixels to see if there are any that areNotPure black or pure white (more accurately, have the browser check the alpha channel to see if there are any semi-transparent pixels, which have a value that is not 0 or 255 ). if there are no semi-transparent pixels, then the algorithm assumes that no font-smoothing is being used. I wrote an JavaScript routine that does this-it starts from co-ordinate (8, 1) and scans left to right, to the bottom of the canvas (any point on near the top on the left-hand side of the canvas wowould have done as well ).

The result is a JavaScript Object,Typehelpers, Which implements this routine in one method,Hassmoothing ():

VaR typehelpers = new function () {// I use me instead of this. for reasons why, please read: // http://w3future.com/html/stories/callbacks.xml var me = This; me. hassmoothing = function () {// IE has screen. fontsmoothingenabled-sweet! If (typeof (screen. fontsmoothingenabled )! = "Undefined") {return screen. fontsmoothingenabled;} else {try {// create a 35x35 canvas block. vaR canvasnode = document. createelement ('canvas '); canvasnode. width = "35"; canvasnode. height = "35" // we must put this node into the body, otherwise // safari Windows does not report correctly. canvasnode. style. display = 'none'; document. body. appendchild (canvasnode); var CTX = canvasnode. getcontext ('2d '); // draw a black letter 'O', 32px Arial. CTX. textbaseline = "TOP"; CTX. font = "32px Arial"; CTX. fillstyle = "black"; CTX. strokestyle = "black"; CTX. filltext ("O", 0, 0); // start at (8, 1) and search the canvas from left to right, // top to bottom to see if we can find a non-black pixel. if // so we return true. for (var j = 8; j <= 32; j ++) {for (VAR I = 1; I <= 32; I ++) {var imagedata = C TX. getimagedata (I, j, 1, 1). Data; var alpha = imagedata [3]; If (Alpha! = 255 & Alpha! = 0) {return true; // font-smoothing must be on .}}} // didn't find any non-black pixels-return false. return false;} catch (Ex) {// something went wrong (for example, opera cannot use the // canvas filltext () method. return NULL (unknown ). return NULL ;}} me. insertclasses = function () {var result = me. hassmoothing (); var htmlnode = document. getelementsbytagname ('html') [0]; If (result = true) {htmlnode. classname + = "hasfontsmoothing-true";} else if (result = false) {htmlnode. classname + = "hasfontsmoothing-false";} else {// result = NULL htmlnode. classname + = "hasfontsmoothing-Unknown" ;}}// if eventhelpers. JS is wrongly ded, insert the hasfontsmoothing CSS classesif (window. eventhelpers) {eventhelpers. addpageloadevent ('typehelpers. insertclasses ')}

Note the object also hasInsertclasses ()Method. This method, when run, adds a class toHtmlTag:

    • Hasfontsmoothing-trueIf font-smoothing is being used
    • Hasfontsmoothing-falseIf it is not
    • Hasfontsmoothing-UnknownIf the user agent is unable to tell

This makes it easy for developers who don't want to mess with JavaScript code and just want to use CSS.

Also noteEventhelpers. addpageloadevent ()Call at the end of the Code. This method (which is partEventhelpers. js, Required ded with the archive below) implements Dean Edwards 'window. onload alternative which doesn' t wait for all the objects in the page to be loaded. I use this implementation to executeTypehelpers. insertclasses ()When the page loads so any font-detection CSS rules will work right away. please feel free to change this code to use the equivalent function call in Dojo, prototype, jquery, or whatever JavaScript code framework you prefer.

Example #1: javascript font smoothing Detection

Enough of theory... Let's look at it in practice! To show how to detect font-smoothing with JavaScript, I created a page that, when the page is loaded, checks to see if it can tell if font-smoothing has been implemented and tells the user. here is the code that does this check:

Function displayinfo () {var message; var isfontsmoothingon = typehelpers. hassmoothing (); If (isfontsmoothingon = true) {message = "This browser is using a font-smoothing technology";} else if (isfontsmoothingon = false) {message = "This browser isn' t using a font-smoothing technology"} else {message = "We cocould not detect if font-smoothing is being used. "} document. getelementbyid ('detectinfo '). innerhtml = message;} window. onload = displayinfo;

See the above Code in action

Example #2: CSS font smoothing Detection

As implied earlier, this library can help CSS use different fonts if the browser is using a font-smoothing technology. for example, using the following CSS will allow a browser to use the droid sans embedded font only if it using font-smoothing-otherwise, it will use Arial:

@ Font-face {font-family: "droid sans"; SRC: URL ("/shared/fonts/droidsans. EOT "); SRC: Local (" droid sans "), local (" droid sans "), URL ("/shared/fonts/droidsans. TTF ") format (" TrueType ");} body {font-family:" Arial "," Helvetica ", sans-serif;} HTML. hasfontsmoothing-true body {font-family: "droid sans", "Arial", "Helvetica", sans-serif ;}

We can also serve special content to users depending on the way fonts are rendered on their browser. we first create content for all three scenerios (browser uses font-smoothing, browser doesn' t use font-smoothing, and the "We cannot detect" case) and wrap the content inside <code> Div </code> tags using appropriate CSS classes:

<Div class = "fontsmoothingmessage initiallyhidden"> <p> You browser <strong> is </strong> rendering this page with font-smoothing. because of that, we will attempt to serve up the droid Sans font to render this page, because we think it looks cool. if you are using a browser (such as Google Chrome) that cannot render downloaded True Type fonts by default, then the page will be rendered using Arial instead. </P> </div> <Div class = "nofontsmoothingmessage initiallyhidden"> your browser <strong> is not </strong> rendering this page with font-smoothing. it is for that reason we have decided to use the plain old Arial font to render this page, because it is hinted for use for displays that don't employ a font-smoothing technology. </div> <Div class = "unknownfontsmoothingmessage initiallyhidden"> <strong> we are not sure </strong> If your browser is rendering this page with a font-smoothing technology. it is for that reason we have decided to use the plain old Arial font to render this page, because it is hinted for use for displays that don't employ a font-smoothing technology. </div>

Note allDivTags are members of the classInitiallyhidden. This class will be used to hide all font-smoothing related content until the script kicks in.

However, all this will not work unless we use the following CSS code:

. Initiallyhidden {display: none;} html. hasfontsmoothing-True. fontsmoothingmessage, HTML. hasfontsmoothing-False. nofontsmoothingmessage, HTML. hasfontsmoothing-Unknown. Detail {display: block ;}

Of course, this whole soltution relies on whether JavaScript being turned on in the user's browser. This shoshould be kept in mind when implementing this solution.

See the above Code in action

Download

All code used in this article can be downloaded below (Note:Version 1.0 was missing the droid sans fonts which have now been put into the archive. Thanks to John Faulds for pointing this out ).

Typehelpers. js v.1.0a and sample code.

With the help of Tim Brown, it was determined that the Code detected font-smoothing correctly in the following browsers:

    • Internet Explorer 6 and up on Windows XP and higher.
    • Firefox 3.5 and higher on Windows XP and higher, Mac OS X 10.4 and higher, and Ubuntu Linux 9.10 (and probably lower)
    • Google Chrome 3.0 on Windows XP and higher
    • Safari 4.0.3 on Windows XP and higher and Mac OS X 10.4 and higher

This scriptCannot detect font-smoothing in any version of Opera(At the time of this writing, this includes des all versions up to 10.10), since it cannot write text inside the Canvas Element in a way we can poll the pixels afterwards. if anyone can find a way of making it work with opera, please write a comment below-I 'd love to be able to support this browser.

Testing caveats

testing font-smoothing in most Windows Web browsers is easy since it can be turned off inside the display control panel. however, when using safari for windows, it is necessary to navigate inside safari's appearance preferences and set the font-smoothing Option to Windows Standard . this is because by default, Safari uses it's own built-in font-rendering engine which doesn't seem to render aliased fonts. in Mac OS X, it seems anti-aliasing only works for fonts below a certain size, so aliased fonts don't seem to be an issue with that operating system. in Ubuntu Linux I have yet to find a way of shutting of font-smoothing. if anyone knows a way, please let me know.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.