Text


Martin McBride, 2020-08-18
Tags geometry text
Categories generativepy generative art

The Text class draws a rectangle. It inherits add, fill, stroke, fill_stroke, path, clip and other methods from Shape.

There is also a text function that draws text. Note that the text function actually paints the text (unlike other shape functions such as rectangle, that simply add the shape as a path without painting it). This is because text is almost always painted in a flat colour.

Text class methods

The Text class inherits add, fill, stroke, fill_stroke, path, clip and other methods from Shape.

It has additional methods:

  • of
  • font
  • size
  • align
  • align_left
  • align_center
  • align_right
  • align_bottom
  • align_baseline
  • align_middle
  • align_top
  • flip
  • offset
  • offset_angle
  • offset_towards

of

Creates a text item.

of(text, position)
Parameter Type Description
text String The text to display. Only single line text is supported.
position (number, number) (x, y) position of the text.

The text is placed at the position, using the alignment specified by the align functions below.

font

Selects the font face.

font(font)
Parameter Type Description
font string Name of the font to use.

Selects the font face. If it is not supplied, the currently selected font face will be used.

size

Selects the font size.

size(size)
Parameter Type Description
size number The size of the text.

Sets the font size. For western fonts, the font size is approximately equal to the height of the font in user units. This may vary slightly for different font faces, and non-western fonts (for example Chinese fonts). If it is not supplied, the currently selected font size will be used.

align

Sets the text alignment.

align(alignx, aligny)
Parameter Type Description
alignx enum Sets the horizontal alignment of the text.
aligny enum Sets the horizontal alignment of the text.

alignx should be set to LEFT, CENTER, or RIGHT. This causes the left, centre, or right of the text bounding box to be aligned with the x value of the text position.

aligny should be set to BOTTOM, MIDDLE, TOP, or BASELINE. This causes the bottom, middle, top, or baseline of the text to be aligned with the y value of the text position.

The bottom, middle, and top positions are calculated from the text bounding box, but the baseline comes from the font metrics. If you need to correctly align two text strings you should use baseline rather than bottom, because the bottom depends on the string contents.

The default is LEFT and BASELINE.

align_xxx methods

align_left() sets the horizontal alignment to LEFT but leaves the vertical alignment unchanged. align_center() and align_right() set the alignment to CENTER or RIGHT.

align_bottom() sets the horizontal alignment to LEFT but leaves the vertical alignment unchanged. align_middle(), align_top(), and align_baseline() set the alignment to MIDDLE, TOP, or BASELINE.

These are alternatives to that align method, that are mainly provided for readability, particularly if you only wish to set the alignment in one direction an leave the other at the default. There is no particular advantage to using one style or the other.

offset

Offsets the text in the x and y axes.

offset(x=0, y=0)
Parameter Type Description
x number Sets the x offset.
y number Sets the y offset.

The offset moves the text in the x and y direction. The amount of offset is measured in user space.

The offset is simple added to the position of the text. So for example:

Text(ctx).of("text", p).offset(x, y).fill(color)

is equivalent to:

Text(ctx).of("text", (p[0]+x, p[1]+y)).fill(color)

It is a matter of personal preference which form you use.

offset_angle

Offsets the text by a given distance in a specified direction.

offset_angle(angle, distance)
Parameter Type Description
angle number Sets the direction to move the text.
distance number Sets the distance to move the text.

Displaces the text by an amount distance at the specified angle.

For example:

  • offset_angle(0, 10) moves the text 10 units in the x direction (angle 0 degrees), ie ten units to the left.
  • offset_angle(math.pi/2, 5) moves the text 5 units in the y direction (angle 90 degrees), ie 5 units down.
  • offset_angle(math.pi/4, 1) moves the text 0.707 units in the x direction and 0.707 units in the y direction (angle 45 degrees).

This function is equivalent to:

 offset(distance*math.cos(angle), distance*math.sin(angle)

offset_towards

Offsets the text by a given distance towards a specified point.

offset_towards(point, distance)
Parameter Type Description
point (number, number) Sets the point to move the text towards.
distance number Sets the distance to move the text.

Displaces the text by an amount distance towards the point.

If distance is negative, the text will be moved in the opposite direction, ie away from the point.

text function

Paints text at a location, without the need to create a Text object

text(ctx, txt, x, y, font=None, size=None, color=None,
                   alignx=LEFT, aligny=BASELINE, flip=False)
Parameter Type Description
ctx Context The Pycairo Context to draw to
txt string The text content.
x number The x position of the text.
y number The y position of the text.
font string Name of the font to use (see font function above).
size number The size of the text (see size function above).
color Color The colour of the text.
alignx number The horizontal alignment of the text (see align function above).
aligny number The vertical alignment of the text (see align function above).
flip boolean True to flip the text (see flip function above).

This draws a line of text at position (x, y).

color selects the font color. If no value is supplied, the shape will be filled with whatever paint source is current for the context.

Example

Here is an example that uses the Text class to create text with various alignments:

from generativepy.drawing import make_image, setup
from generativepy.color import Color
from generativepy.geometry import Text, Circle

'''
Create text using the geometry module.
'''

def draw(ctx, width, height, frame_no, frame_count):
    setup(ctx, width, height, width=5, background=Color(0.8))

    Text(ctx).of("Left", (0.5, 0.5)).font("Times").size(0.2).align_left().align_baseline().fill(Color('blue'))
    Text(ctx).of("Aligned", (0.5, 0.7)).font("Times").size(0.2).align_left().align_baseline().fill(Color('red'))
    Text(ctx).of("Text", (0.5, 0.9)).font("Times").size(0.2).align_left().align_baseline().fill(Color('blue'))

    Text(ctx).of("Centre", (2.5, 0.5)).font("Times").size(0.2).align_center().align_baseline().fill(Color('blue'))
    Text(ctx).of("Aligned", (2.5, 0.7)).font("Times").size(0.2).align_center().align_baseline().fill(Color('red'))
    Text(ctx).of("Text", (2.5, 0.9)).font("Times").size(0.2).align_center().align_baseline().fill(Color('blue'))

    Text(ctx).of("Right", (4.5, 0.5)).font("Times").size(0.2).align_right().align_baseline().fill(Color('blue'))
    Text(ctx).of("Aligned", (4.5, 0.7)).font("Times").size(0.2).align_right().align_baseline().fill(Color('red'))
    Text(ctx).of("Text", (4.5, 0.9)).font("Times").size(0.2).align_right().align_baseline().fill(Color('blue'))

    Circle(ctx).of_center_radius((1.9, 2), 0.02).fill(Color(0, 0, 1))
    Text(ctx).of("gTop", (2, 2)).font("Times").size(0.2).align_left().align_top().fill(Color('black'))

    Circle(ctx).of_center_radius((1.9, 2.5), 0.02).fill(Color(0, 0, 1))
    Text(ctx).of("gMid", (2, 2.5)).font("Times").size(0.2).align_left().align_middle().fill(Color('black'))

    Circle(ctx).of_center_radius((1.9, 3), 0.02).fill(Color(0, 0, 1))
    Text(ctx).of("gBase", (2, 3)).font("Times").size(0.2).align_left().align_baseline().fill(Color('black'))

    Circle(ctx).of_center_radius((1.9, 3.5), 0.02).fill(Color(0, 0, 1))
    Text(ctx).of("gBottom", (2, 3.5)).font("Times").size(0.2).align_left().align_bottom().fill(Color('black'))

make_image("/tmp/geometry-text.png", draw, 500, 500)

Here is the result:

If you found this article useful, you might be interested in the book Computer Graphics in Python or other books by the same author.

Prev

Popular tags

2d arrays abstract data type alignment and animation arc array arrays bezier curve built-in function callable object circle classes close closure cmyk colour comparison operator comprehension context context manager conversion creational pattern data types design pattern device space dictionary drawing duck typing efficiency else encryption enumerate fill filter font font style for loop function function composition function plot functools game development generativepy tutorial generator geometry gif gradient greyscale higher order function hsl html image image processing imagesurface immutable object index inner function input installing iter iterable iterator itertools l system lambda function len line linspace list list comprehension logical operator lru_cache magic method mandelbrot mandelbrot set map monad mutability named parameter numeric python numpy object open operator optional parameter or partial application path polygon positional parameter print pure function pycairo radial gradient range recipes rectangle recursion reduce rgb rotation scaling sector segment sequence singleton slice slicing sound spirograph sprite square str stream string stroke subpath symmetric encryption template text text metrics tinkerbell fractal transform translation transparency tuple turtle unpacking user space vectorisation webserver website while loop zip