Canvas 2D Context

Part 5. Working with Text

Every glyph to its taste
Rewritten proverb

Text-related methods and properties used to control fonts and set up text layout can be divided into two groups. First of all, CanvasRenderingContext2D API exposes a pair of methods dealing with text rendering mode. These are fillText(text, x, y, maxWidth) and strokeText(text, x, y, maxWidth). The second group is a set of API members influencing text alignment, font selection and glyphs measurement. They affect the text state and include the measureText(text) method as well as font, textAlign and textBaseline properties. Here's an example of drawing a styled text snippet on the canvas plane.

var linearGradient=context.createLinearGradient(0, 0, 500, 0);
linearGradient.addColorStop(0.1, "magenta");
linearGradient.addColorStop(0.3, "yellow");
linearGradient.addColorStop(0.5, "green");
linearGradient.addColorStop(0.7, "crimson");
linearGradient.addColorStop(0.9, "blue");
context.fillStyle=linearGradient;
context.font="200px Lucida Handwriting";
context.fillText("text", 10, 200, 300);

Filling style is created as an instance of the linear gradient. Then the font attribute is specified. The attribute is in some ways similar to the CSS font property and can have the same values except property-independent CSS syntax like 'inherit'. The CSS font is a shorthand property equivalent of the following properties: font-style font-variant font-weight font-size/line-height font-family. In the example above only font size and a family from the collection of fonts available on the host system were defined. Here's a more complicated font assignment: font style is italic; all glyphs are rendered as small capital letters; the font weight is bold; its size is equal to 200 pixels; minimal height of text lines is set to normal; font family is directly assigned to Arial. The user agent will use the Arial font if it is installed on the system. It is recommended to use generic font families (in our case - serif) as a fallback mechanism in case a specific font is not present.

...
context.font="italic small-caps bold 200px/normal Arial, serif";
...

The fillText(text, x, y, maxWidth) method renders the text starting from the point with the x and y coordinate values. The text block cannot be wider than the number specified as the value of the maxWidth parameter. Text stroking uses the same set of parameters. Before calling the stroke method such pen style attributes as strokeStyle, lineWidth and lineJoin are defined:

var linearGradient=context.createLinearGradient(0, 0, 500, 0);
linearGradient.addColorStop(0.1, "magenta");
linearGradient.addColorStop(0.3, "yellow");
linearGradient.addColorStop(0.5, "green");
linearGradient.addColorStop(0.7, "crimson");
linearGradient.addColorStop(0.9, "blue");
context.strokeStyle=linearGradient;
context.lineWidth=6;
context.lineJoin="round";
context.font="300px Rockwell";
context.strokeText("text", 10, 200, 400);

The subsidiary measureText(text) method returns an instance of the TextMetrics interface having a single width attribute: for example, the word "text" which is supposed to be rendered with glyphs from the Arial font with the size of 12 pixels has the width of 32 text space units. The same snippet rendered with glyphs from the Cantarell font having the size of 50 pixels will have the width equal to 128 units. Text metrics can prove useful to calculate proper text position during the development of complex scenes combining glyphs with geometric primitives.

Allowed values for the textAlign property are start (default), end, left, right, and center. Glyphs justification is computed relative to the point with x and y arguments passed to the text stroking or filling methods. In the example below text align keywords are displayed with the points of the text space origin.

...
context.fillStyle="silver";
context.textAlign="start";
context.font="51px serif";
context.fillText("start", 50, 50);
...

Font geometry centers around the concept of the EM box. This is an abstract square acting as the design grid for glyph outlines. Another notion used to describe the position of glyphs belonging to a certain script is the baseline. Glyphs of a given script are positioned so that a point on each glyph (alignment-point) is aligned with alignment-points of all other glyphs in the script. The straight line connecting all alignment-points of glyphs is the baseline. Baseline-related keywords are top, hanging, middle, alphabetic (default), ideographic and bottom. Below is an example of using various baseline values. For demonstration purposes, the Latin script and horizontal writing mode are used. All text blocks have one and the same y coordinate value. In real-world applications Western fonts are aligned along the alphabetic baseline, far-eastern glyphs are rendered according to ideographic baseline, certain Indic scripts employ hanging baseline. Middle baseline places alignment-points in the middle of the EM square. Top and bottom baseline assignment maps alignment-points to the top and bottom of the EM square, respectively.

Text state attributes (font, textAlign and textBaseline) are part of the current graphics state. As a result, they can be pushed onto the drawing stack and restored from it.

Summary: Text Rendering Methods and Properties

text rendering mode attributes
context.fillText(text, x, ,y, maxWidth)
context.strokeText(text, x, ,y, maxWidth)


text measurement
context.measureText(text)
textMetrics.width


text alignment
context.textAlign
context.textBaseline


choosing a font
context.font

CSS font-related properties and a range of their values

font-stylenormal
italic
oblique
font-variantnormal
small-caps
font-weight 100 | 200 | 300 | 400 (normal) | 500 | 600 | 700 (bold) | 800 | 900
normal
bold
bolder
lighter
font-size numerical value (absolute | relative | length | percentage)
xx-small | x-small | small
medium
large | x-large | xx-large
line-heightnormal
numerical value (length | percentage)
font-familyfamily name
fontfont-style font-variant font-weight font-size/line-height font-family