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 grpahical 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 Embed 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.