Skip to content

Fonts & Text

Taco de Wolff edited this page Nov 17, 2022 · 7 revisions

Individual font files are represented by Font. Each font should go into a FontFamily, which can contain different fonts for different weights or for italic. From a FontFamily we can construct a FontFace at a given font size and weight/italic. This font face is what is used to create text objects.

Text objects can be generated as a simple text line, a text box, or using the more complex rich text environment allowing multiple font faces to be used.

Fonts

Typical usage for font loading would look like the following:

fontDejaVu := canvas.NewFontFamily("dejavu")
if err := fontDejaVu.LoadFontFile("DejaVuSans.ttf", canvas.FontRegular); err != nil {
    panic(err)
}
if err := fontDejaVu.LoadFontFile("DejaVuSans-Bold.ttf", canvas.FontBold); err != nil {
    panic(err)
}

face := fontDejaVu.Face(12.0, canvas.Black, canvas.FontBold, canvas.FontNormal)

Here we load two fonts into one font family. Next we select a font face at point size 12 from the font family. In this case the bold font is provided and will thus be used directly. If there is no bold font provided, the font face will use the regular font and use an artificial faux bold style.

Text

We can draw a simple text line to a context for a given font face using NewTextLine:

ctx.DrawText(10, 10, canvas.NewTextLine(face, "Lorem ipsum", canvas.Left))

This will draw the text "Lorem ipsum", with its baseline aligned to coordinates (10,10). The text anchor is on the left. To center the text horizontally around (10,10) you can use canvas.Center, or to write the text to the left on (10,10) you can use canvas.Right.

We can draw a text box to a context for a given font face, a text string, the width and height of the box, the horizontal and vertical alignment of the text, the indentation of the first line, and the line stretch factor by using NewTextBox:

ctx.DrawText(10, 10, canvas.NewTextBox(face, "Lorem ipsum", 100, 80, canvas.Left, canvas.Top, 0.0, 0.0))

If the horizontal alignment is set to canvas.Justify, the text is justified using Donald Knuth's line breaking algorithm. The various combinations of those settings can be observed in the following image.

Text

Rich Text

A rich text environment allows for various font faces to be used in one text box. An example usage drawing two text spans with different font faces at coordinates (10,10) into a text box of size (100,80) follows:

// Create a new rich text object with a default font face and write one text span
rt := canvas.NewRichText(face1)
rt.WriteString("Lorem ")

// Write a second text span with a different font face
rt.SetFace(face2)
rt.WriteString("ipsum")

// Convert to a text object with:
//   width=100, height=80
//   halign=Left, valign=Right
//   indent=0.0, lineStretch=0.0
text := rt.ToText(100, 80, canvas.Left, canvas.Right, 0.0, 0.0)

// Draw at (10,90) as top-left corner
ctx.DrawText(10, 90, text)

Images, paths, and formulas between text

You can embed images and paths within a text object. Actually, you can embed another Canvas which may contains any number of paths, images, or even other text objects.

// Add blue triangle to text
p := &canvas.Path{}
p.LineTo(2.0, 0.0)
p.LineTo(1.0, 2.0)
p.Close()
rt.AddPath(p, canvas.Blue, canvas.Baseline)


// Add image to text
lenna, err := os.Open("../resources/lenna.png")
if err != nil {
    panic(err)
}
img, err := png.Decode(lenna)
if err != nil {
    panic(err)
}
rt.AddImage(img, canvas.DPMM(200.0), canvas.Baseline)


// Add formula to text
rt.AddLaTeX("x = \\frac{1}{2}", 10.0, canvas.LatinModernFonts)

Text

CJK and vertical text

All scripts including vertical scripts such as CJK are naturally supported. By default the HorizontalTB writing mode is used, that formats lines horizontally from top to bottom. We can set the writing mode as:

// Set writing mode, can be: HorizontalTB, VerticalLR, VerticalRL
rt.SetWritingMode(canvas.VerticalLR)

Vertical scripts (e.g. CJK) can be mixed with horizontal scripts (e.g. Latin). By default the horizontal script is rotated 90 degrees clockwise, but we can also format the characters individually upright:

// Set text orientation, can be: Natural, Upright
rt.SetTextOrientation(canvas.Upright)

Text

Clone this wiki locally