Skip to content

Seeing PNG fonts, how it relates to browser security policies and what's changed in 2.0

Davide P. Cervone edited this page May 28, 2013 · 2 revisions

jsFiddle URL: http://jsfiddle.net/XBwWV/

Code:

<!DOCTYPE html>
<html>
<head>
<title>Math rendering with MathJax 2.0-beta</title>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
  jax: ["input/TeX","output/HTML-CSS"],
  extensions: ["tex2jax.js"],
});
</script>
<script type="text/javascript"
  src="http://cdn.mathjax.org/mathjax/2.0-beta/MathJax.js">
</script>
<style type="text/css">
body {
    font-family: helvetica, arial, "trebuchet ms", sans-serif;
    font-size: 16px;
    line-height: 24px;
    color: #333333;
}
</style>
</head>
<body>
<h1>Rendering with MathJax 2.0-beta</h1>
<p>
An example: \((a + b)^2 = a^2 + 2ab + b^2\).
</p><p>
We get the above from below.
</p><p>
\begin{align}
(a + b)^2 & = (a + b)(a + b) \\\\
          & = a^2 + ab + ab + b^2 \\\\
          & = a^2 + 2ab + b^2
\end{align}
</p>
</body>
</html>

When I put the above code in an HTML file and open it using Firefox 10.0.2 on Windows XP, I see that the math text is displayed using PNG images and the font color appears very dark. For example, when I try to find the first opening parenthesis after the text "An example:" using Firebug, this is the code I find for it:

<span class="mo" id="MathJax-Span-3"><img src="http://cdn.mathjax.org/
mathjax/latest/fonts/HTML-CSS/TeX/png/Main/Regular/141/0028.png"
style="width: 7px; height: 21px; vertical-align: -5px; margin-right:
0.054em;"></span>

But when I visit the jsFiddle URL I have given above using the same browser, I see that the math text is rendered with HTML-CSS and the font color isn't so dark. For the same open parenthesis, I now see this code with Firebug:

<span class="mo" id="MathJax-Span-10" style="font-family:
MathJax_Main;">(</span>

To make sure that I didn't have any setting stored by MathJax scripts in my cookies, I searched for cookies containing the string "menu" or "mathjax" and all cookies from a domain containing the string "mathjax" and removed them before obtaining the outputs I have mentioned above.

Could you please explain why I see a difference in rendering with the same code for the same browser between the output of an HTML file on my disk and an HTML embedded in jsFiddle?

Secondly, why does MathJax resort to using PNG images when I have specified "output/HTML-CSS" in the configuration?


Could you please explain why I see a difference in rendering with the same code for the same browser between the output of an HTML file on my disk and an HTML embedded in jsFiddle?

Please see the firefox and local fonts documentation, and the Firefox section of the FAQ for details.

Secondly, why does MathJax resort to using PNG images when I have specified "output/HTML-CSS" in the configuration?

The layout is being done by the HTML-CSS output jax, but instead of using system fonts it is using images of the characters (one image per character) instead. The reason for this is explained in the links above.


Hi Davide,

Firstly, thank you very much for providing clear and concise answers to all the questions I post to this list.

As per the links you have mentioned, I should see PNG images when I use the same code in jsfiddle.net. But if you see my example at http://jsfiddle.net/XBwWV/ you'll see that in this case, MathJax_Main font is used to render the math formulas. How can this be explained?


The explanation is that Firefox handles local files (files from your hard disk) differently from files obtained over the network. The same-origin security policy says that anything outside of the directory containing the HTML file you are viewing is not the same origin, and is subject to security restrictions. That means that if you have a local copy of MathJax on your hard disk that is being used by your local HTML page, and if that local copy is not in a subdirectory of the directory containing the HTML page, then Firefox will refuse to load the MathJax fonts. Because of this, when MathJax sees that your page has a file:// URL and MathJax is not being taken from a subdirectory of the HTML page's directory, it will switch to image fonts automatically. In version 2.0, if MathJax is being taken from a network location rather than also from the hard disk (i.e., an http:// URL rather than a file:// URL), then then it will not switch to image fonts (unless it fails to load the first font from that server). This allows the use of the CDN with local files (as you are doing). That was not the case with v1.1, so any local file would always use image fonts, whereas v2.0 will use web fonts when MathJax is coming from a server even for local HTML pages.

Your code shows you are using the 2.0-beta copy, so I would expect that it would use the web fonts, but the URL for the image that you list later is mathjax/latest not mathjax/2.0-beta, so I'm wondering if you are actually using the code you provided, as it should not be using mathjax/latest. If your page really uses mathjax/latest, then that is using v1.1a, which would always go to image fonts. If you are using mathjax/2.0-beta, it should allow the web fonts to be used. The code you sent works correctly for me form a local file in Firefox, properly obtaining the web fonts from the CDN. That suggests that your results are really from a file using mathjax/latest not mathjax/2.0-beta, where you would get image fonts instead.

Please check that you are using the proper copy of MathJax in your test. You may have to clear the cache and restart the browser to be sure.


Hi Davide,

Sorry, the code I posted here was wrong earlier. Yes, I am using MathJax 1.1 for testing on my local file system. Here is the code:

<!DOCTYPE html>
<html>
<head>
<title>Math rendering with MathJax 1.1</title>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
  jax: ["input/TeX","output/HTML-CSS"],
  extensions: ["tex2jax.js"],
});
</script>
<script type="text/javascript"
  src="http://cdn.mathjax.org/mathjax/latest/MathJax.js">
</script>
<style type="text/css">
body {
    font-family: helvetica, arial, "trebuchet ms", sans-serif;
    font-size: 16px;
    line-height: 24px;
    color: #333333;
}
</style>
</head>
<body>
<h1>Rendering with MathJax 1.1</h1>
<p>
An example: \((a + b)^2 = a^2 + 2ab + b^2\).
</p><p>
We get the above from below.
</p><p>
\begin{align}
(a + b)^2 & = (a + b)(a + b) \\\\
          & = a^2 + ab + ab + b^2 \\\\
          & = a^2 + 2ab + b^2
\end{align}
</p>
</body>
</html>

The behavior I observe is that if I open this file from my local file system using a file:/// URL, it loads PNGs to render the math text. But if I host this page on a web-server (such as jsfiddle or my own web server) and then access the page using an http:// URL, it loads the web fonts fine.

I see that cdn.mathjax.org sets "Access-Control-Allow-Origin: *" header for all fonts it is serving.

$ curl -I http://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_AMS-Regular.otf
HTTP/1.0 200 OK
Server: nginx
Date: Wed, 26 Oct 2011 15:58:24 GMT
Content-Type: font/opentype
Last-Modified: Fri, 09 Sep 2011 22:28:43 GMT
ETag: "4038021-e4a0-4ac89b326bcc0"
Accept-Ranges: bytes
Content-Length: 58528
Cache-Control: max-age=86400
Access-Control-Allow-Origin: *
Age: 48642
Vary: Accept-Encoding
X-Cache: Hit from cloudfront
X-Amz-Cf-Id: iAFT9lXT-5blTiinIfXpm-
AhrlLQzHIFAYPOWXsZP4WwwFfEN2Qcvg==,oP7fc5Z4efweGmG9bCqavP4SV1sb8ch0IFO9upzU_J6buo4WrvKdeg==
Via: 1.0 a7b00a563ffc5cb28d129b24812779c7.cloudfront.net:11180
(CloudFront), 1.0 c87e032033404ba271592462aab82758.cloudfront.net:
11180 (CloudFront)
Connection: close

So, in this case both my local copy of my test page (accessed using file:/// URL) and web server copy of my test page (accessed using http:// URL) should be able to load the web-fonts. So, I didn't understand why you say that the local copy of my test page would be unable to load the web-fonts. Pages accessed with file:/// URL can access remote http:// resources as long as the remote resource sets a proper "Access-Control- Allow-Origin:" header.

Are you saying that the MathJax script itself checks the document URL (URL of the page using MathJax) and if the document URL is file:/// but the MathJax URL is not a local sub-directory of the directory in which the page resides or if the MathJaX URL is http:// then it loads web-fonts? If yes, why is the behaviour so? It should have been possible to load web fonts instead in both cases. Or was this a bug or limitation of version 1.1 which has been fixed in version 2.0?


Sorry, the code I posted here was wrong earlier. Yes, I am using MathJax 1.1 for testing on my local file system.

OK, then that accounts for the switch to image mode. MathJax v2.0 doesn't switch when MathJax is taken from a server (unless the fonts fail to load).

The behavior I observe is that if I open this file from my local file system using a file:/// URL, it loads PNGs to render the math text. But if I host this page on a web-server (such as jsfiddle or my own web server) and then access the page using an http:// URL, it loads the web fonts fine.

Yes, that is the behavior for v1.1a.

So, in this case both my local copy of my test page (accessed using file:/// URL) and web server copy of my test page (accessed using http:// URL) should be able to load the web-fonts. So, I didn't understand why you say that the local copy of my test page would be unable to load the web-fonts. Pages accessed with file:/// URL can access remote http:// resources as long as the remote resource sets a proper "Access-Control-Allow-Origin: " header.

Yes, and 2.0 does that, but not 1.1a. Version 1.1 was when we introduced the CDN and prior to that most people who where doing local development had a local copy of MathJax on their hard disks. The CDN-based use cases hadn't yet been developed, so that case was left out of the logic for deciding on image fonts.

Are you saying that the MathJax script itself checks the document URL (URL of the page using MathJax) and if the document URL is file:/// but the MathJax URL is not a local sub-directory of the directory in which the page resides or if the MathJaX URL is http:// then it loads web-fonts?

Version 2.0 and version 1.1 differ in their implementations. In v1.1 if the page is a file:// URL and MathJax was not taken from a subdirectory of the page's directory (and that includes if MathJax was taken from a remote URL), then MathJax used image fonts. That is sub-optimal, as you point out, and was fixed in v2.0.

For v2.0, If the local document is a file:// URL and MathJax also comes from a file:// URL, then if MathJax isn't from a subdirectory, then MathJax forced image mode since Firefox will fail to load the fonts in that case.

If yes, why is the behaviour so?

This avoids the delay waiting for the fonts to fail. The only way MathJax can detect that is to wait for a time and see if they have arrived, and if not, give up. The length of that time out is based on network delay times, and would appear annoyingly long to wait when you are using local files.

It should have been possible to load web fonts instead in both cases.

I'm not sure what the two cases are you mean. You are right that if MathJax is taken from the CDN then it should always be possible, regardless of the source of the page (and that is how v2.0 handles it). But of MathJax comes from a local directory, it must be within the directory of the HTML page to be accessible.

Or was this a bug or limitation of version 1.1 which has been fixed in version 2.0?

Yes. That is what I tried to say in my original response: "In version 2.0, if MathJax is being taken from a network location rather than also from the hard disk ... then it will not switch to image fonts ... . That was not the case with v1.1" and "If your page really uses mathjax/latest, then that is using v1.1a, which would always go to image fonts. If you are using mathjax/2.0-beta, it should allow the web fonts to be used." Sorry that this wasn't clear enough. I hope it is straightened out now.


Yes, this makes it very clear. Thank you for the detailed explanation.

A big thank you from me too for patiently helping me understand why and when MathJax resorts to using PNG images to render math.

Clone this wiki locally