Primitive Text Functions for the HTML5 <canvas> Element
The
<canvas> element
provides the browser's javascript with a two dimensional
drawing area. It is a simple path/stroke-fill model but provides
the primitives necessary for making sophisticated graphical
presentations. And you will need to be sophisticated with your
graphical presentation because you won't be using any printed words
or numbers. What could have been the holy grail of javascript to user
communication was turned into a mime by the omission of text.
Fortunately the 1960s has come to the rescue. A. V. Hershey created a
set of simple vector fonts for pen plotters which were released by the US
National Institute of Standards (NIST). The code presented here encodes
the printable 7-bit ASCII characters in a javascript file with a
handful of functions to add text operations to the canvas element.
The Code
You can find the code at
http://www.federated.com/~jim/canvastext/canvastext.js
, or in your browser cache since it got loaded with this page. As
written it is about 14k bytes. If you ran it through a javascript
minimizer and prezipped it you would squeak it into two 1500 byte
datagrams. Allow me to stress this: Do not link to this file.
I will mess you up if you try to save bandwidth by using my copy
in production.
The demonstration code that is drawing that little box on the right is found in
http://www.federated.com/~jim/canvastext/drawdemo.js
.
License
This code is released to the public domain. Do with it as you will.
Documentation
In a nutshell the following methods are added to your canvas context:
-
ctx.drawText = function(font,size,x,y,text)
-
Draw text in the specified font and size at the position (baseline). Font is ignored for now, there is only one. The width of the line is set
automatically from the font size. The ctx.strokeStyle is used.
-
ctx.measureText = function(font,size,text)
-
Return the width of the text if it were drawn with the current settings.
-
ctx.fontAscent = function(font,size)
-
This is the ascent from the baseline. It is taller than the capital letters. It sort of encompasses the ascent and half the leading.
-
ctx.fontDescent = function(font,size)
-
Similar.
-
ctx.drawTextRight = function(font,size,x,y,text)
-
Just for lazy programmers.
-
ctx.drawTextCenter = function(font,size,x,y,text)
-
Also for lazy programmers.
Future Work
The bodies responsible for defining the <canvas> should spend a
day or two and define some text functions. Yes, I realize we all have
different fonts and even within allegedly same fonts the metrics are
different. We are programmers. We will deal with that. Give us three
pseudo named fonts, "default", "sans", and "serif" perhaps and then
let us use the style sheet for anything else the graphics designers
want to inflict on the users.
More narrowly...
-
The Hershey fonts contained a fair number of international symbols. If
the encoding is something useful to modern programmers, maybe the
most common ones could be added to this.
-
Maybe a function to scale the weight of the stroke, or maybe people
would just be ugly with it.
-
Perhaps the serif font, but it looks pretty ugly and takes more bytes to encode.
-
I suspect the functions could be added to the context's prototype,
making the .enable() call irrelevant, but I don't know how to do that.
Related Work
-
Rendering text with <canvas>
-
The CanvasPaint folks do a nice survey of text rendering options.
-
Rhino Canvas drawString
-
A proposed model for text in canvas.
-
Textout Canvas Html with Embedded Fonts
-
A means of encoding a particular truetype font at a particular size
into an image and a function to print by extracting characters from
the image. Prettier for large type, doesn't kern as well at small
sizes. Takes more bytes.
-
TextCanvas
-
A way of floating text over the canvas so it can be rendered with
the standard HTML mechanisms. Nice font handling, but no control
over rotation and placement is a little loose.
Contact
The author, Jim Studt, can be contacted at jim@federated.com. Don't
write like a spammer if you want any hope of getting through the
filters.