Shady.Text Sub-module

To activate Shady’s ability to render text, you have to explicitly:

import Shady.Text

This is a break from Shady’s usual behavior of arriving with all batteries included. The reason is that this import can take several seconds, as Shady (via the third-party package matplotlib, if available) collates a list of available fonts. (For some reason, even in the twenty-first century, it is a universal truth that the initialization of any application that wants a few dozen fonts to be available must be ridiculously time-consuming.)

The third-party packages numpy and pillow (or PIL) are required. The matplotlib package is optional, but without it you will be limited to one font (monaco).

Once activated, you probably do not need direct access to anything inside the Shady.Text submodule. Instead you can just work with the text property of any Shady.Stimulus object. It can be as simple as:

import Shady.Text
w = Shady.World()
s = w.Stimulus( text='Hello, World!' )

You can assign a string to the Stimulus property text, but what that really does is create an instance of type TextGenerator which has a number of sub-properties. In fact, assigning a string to s.text is really a syntactic shortcut for creating the TextGenerator instance s.text if it doesn’t already exist, then assigning the string to the sub-property s.text.string. Subproperties are accessible in the Stimulus() constructor, and also as (dynamic-assignment-capable) properties of the Stimulus instance itself, using an underscore-delimited notation:

s = w.Stimulus( text='Hello, World!', text_font='times', text_size=100 )

Note that, in contrast to Shady’s usual way of doing things, any change to the content, style or appearance of a piece of text requires the CPU to do the rendering work and then transfer the resulting image texture from CPU to GPU. This will very quickly cause frame skips if you want to change the content of a large text image frequently.

The subproperties are as follows:

family, a.k.a. family_name, font, font_family, font_name:

Assign a string here, and Shady will attempt to find a font whose name contains all the words in that string. If no match can be found, the font_found property will be False.

bold, italic, black, heavy, light, regular, etc…:

These style properties will be present to the extent that the operating system has fonts installed whose names end with these words. Each one is a boolean property that allows you to toggle its respective style on or off. They may or may not work for any given font (e.g. the “bold” version of a given font may not exist on your system). You can always query the font_found property to discover whether it has worked.


This is an alternative way of controlling font style. You can assign a string containing one or more style words here, for example 'bold italic'. As explained above, this may or may not succeed depending on what your current font provides.


This read-only property is a boolean value that indicates whether the requested font family name and style can be found. If not, the stimulus will render text in Shady’s built-in default font (monaco). This will always be the case if the third-party package matplotlib is not installed, because matplotlib is required in order to access the operating system’s fonts.

emWidthInPixels, a.k.a. em:

By default, this is None, because by default the size of your font is specified by lineHeightInPixels (a.k.a size). If you assign a value here, lineHeightInPixels will become None, and the font size will be chosen such that the lower-case letter “m” is this many pixels wide.

lineHeightInPixels, a.k.a. size:

This is the default way of dictating font size, although it will be None if you have assigned a value to emWidthInPixels instead. It dictates the vertical space allocated to each line of text, in pixels (to within a margin of error that depends on the sizes that the current font provides). Note that the lines may appear to occupy additional space if linespacing is not 1.0


This dictates where one line of text starts, vertically, relative to the next. It is expressed as a proportion of the line height. The default value is 1.1, which means there will be blank space between lines equal to 10% of the line height. Values less than 1.0 may cause lines of text to overlap.


This is the text string to be rendered. It may contain newline characters. It may be a unicode string (however, note that special characters will only be rendered correctly to the extent that the currently selected font provides them).


This is None by default, which means your string content will be rendered unchanged. If you give it a positive integer, then your string will be re-wrapped to the specified number of pixels, with a ragged edge. If you give it a negative integer, then similarly the wrapped width in pixels is equal to the magnitude of that integer, but now the text is left- and right-justified to remove the ragged edge. Paragraph breaks are retained, as are whitespace characters that indent the beginning of each paragraph. A paragraph break can be indicated by a blank line, or indeed by a newline character that is immediately followed by any additional whitespace.


This dictates the thickness of the border around the text. It can be a scalar (in which case it is considered to be a proportion of the text size) or it can be a pair of numbers (in which case it is interpreted as horizontal and vertical thickness in pixels).


This is None by default, indicating that the resulting texture image should occupy the minimal space necessary to satisfy the other parameters. However, you can use this property to guarantee a larger minimum size, in pixels. Supply either a single integer (to create a square image) or a pair of integers indicating width and height.


Set this to 'left', 'right' or 'center' to dictate the way in which multiple lines of the same text image are aligned relative to each other.


This can be a single number in the range 0 to 1, or it can be a sequence of three or four such numbers specifying an RGB or RGBA color that is used for the text. By default, the text is white (1.0) which means that the text color can also be controlled as expected by the color property of the Stimulus instance itself.


This can be a single number in the range 0 to 1, or it can be a sequence of three or four such numbers specifying an RGB or RGBA color that is used fill the background of each line of text. This includes the border, but does not include space beyond the end of shorter lines, nor does it include space between lines that results from linespacing values greater than 1. By default, the background is fully transparent.


This can be a single number in the range 0 to 1, or it can be a sequence of three or four such numbers specifying an RGB or RGBA color that is used fill the background of the entire image. If bg is also specified, then it can be used to manipulate independently the background color of the text lines themselves, superimposed on the blockbg color. By default, the background is fully transparent.