views:

566

answers:

2

Hi all,

First try the test case please: http://lemon-factory.net/test/font-face-and-canvas.html

I'm not good at English, so I made the test case to be self-explanatory.

On the first click to the DRAW button, it will not draw text, or will draw with an incorrect typeface instead of the specified "PressStart", according to your browser. After then it works as expected.

At the first time the text does not appear correctly in all browsers I've tested (Firefox, Google Chrome, Safari, Opera).

Is it the standard behavior or something?

Thank you.

PS: Following is the code of the test case

<!DOCTYPE html> 
<html> 
 <head> 
  <meta http-equiv=Content-Type content="text/html;charset=utf-8"> 
  <title>@font-face and canvas</title> 
  <style> 
@font-face {
  font-family: 'PressStart';
  src: url('http://lemon-factory.net/css/fonts/prstart.ttf');
}
canvas, pre {
  border: 1px solid #666;
}
pre {
  float: left;
  margin: .5em;
  padding: .5em;
}
  </style> 
 </head> 
 <body> 
  <div> 
   <canvas id=canvas width=250 height=250> 
    Your browser does not support the CANVAS element.
    Try the latest Firefox, Google Chrome, Safari or Opera.
   </canvas> 
   <button>DRAW</button> 
  </div> 
  <pre id=style></pre> 
  <pre id=script></pre> 
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt; 
  <script> 
var canvas = document.getElementById('canvas')
var ctx = canvas.getContext('2d')

var x = 30
var y = 10

function draw() {
    ctx.font = '12px PressStart'
    ctx.fillStyle = '#000'
    ctx.fillText('Hello, world!', x, y += 20)
    ctx.fillRect(x - 20, y - 10, 10, 10)
}

$('button').click(draw)

$('pre#style').text($('style').text())
$('pre#script').text($('script').text())
  </script> 
 </body> 
</html>
+1  A: 

Drawing on canvas has to happen and return immediately when you call the fillText method. However, the browser has not yet loaded the font from the network, which is a background task. So it has to fall back to the font it does have available.

If you want to make sure the font is available, have some other element on the page preload it, eg.:

<div style="font-family: PressStart;">.</div>
bobince
You might be tempted to add `display: none`, but that might cause browsers to skip loading the font. It's better to use a space instead of a `.`.
Thomas
Using a space will cause IE to throw away the whitespace node that should be in the div, leaving no text to render in the font. Of course IE doesn't support canvas yet, so it's unknown whether future-IE will continue to do this, and whether that would have an effect on font loading behaviour, but it's a long-standing IE HTML-parsing problem.
bobince
+1  A: 

i've bumped into the issue when playing with it recently http://people.opera.com/patrickl/experiments/canvas/scroller/

worked around it by adding the font-family to canvas directly in the CSS, so you can just add

canvas { font-family: PressStart; }

Patrick H. Lauke