0

I'm using Shady to write some text on screen, and I'm wondering what would be the simplest way to control the alignment of the string. From my understanding, the align parameter in a Shady text object controls the paragraph alignment, but I'm interested in controlling the alignment of a single line of text.
Essentially I'd like to replicate the behavior of the horizontalalignment, verticalalignment and rotation parameters of the matplotlib text function. But to do that I need to estimate the area (in pixels) that will be occupied by the string once rendered. Can I get that out of Shady somehow? In the manual it says that the rendering is done on the CPU and the rendered String is then pushed to the GPU, so it should be doable.

jez
  • 14,867
  • 5
  • 37
  • 64
cq70
  • 21
  • 6

1 Answers1

0

You're correct that the .text.align and .text.wrapping properties are to do with "alignment" only at the logical level of the text flow—i.e., how the lines of a multi-line text stimulus are aligned relative to each other in the coordinate-frame in which they're read (independent of which way up the whole stimulus is physically).

The properties you're talking about—rotation, "vertical alignment", and even what you call "horizontal alignment" if there's only one line of text in play—are not text-specific properties: they could apply equally well to any rectangular patch. For this reason, the properties you want to manipulate are stim.* level properties, not stim.text.*. Specifically, they are .anchor and .rotation as demonstrated here:

#!/usr/bin/env python -m Shady shell

import Shady, Shady.Text
w = Shady.World(fullScreenMode=False)

axes = w.Stimulus(Shady.PixelRuler(1000), anchor=Shady.LOWER_LEFT, size=600)

xlabel = w.Stimulus(text='x axis label', x=300, y=0, anchor=Shady.TOP) 
ylabel = w.Stimulus(text='y axis label', x=0, y=300, anchor=Shady.BOTTOM, rotation=90)

speed = 30
msg = w.Stimulus(
    xy = 300,
    rotation = Shady.Integral( lambda t: speed ),
    text = 'Change msg.anchor to anything\nbetween [-1,-1] and [+1,+1]\nand see what happens',
    text_blockbg = [0, 0, 0, 0.5],
)
Shady.AutoFinish(w)

Somewhere in the undocumented functions of Shady.Text there is probably some way of estimating, in advance, what the size of a rendered text stimulus is going to be. In fact, on closer examination, it looks like the least annoying way to do it would be to actually make the texture array:

img = Shady.Text.MakeTextImage('hello world')
heightInPixels, widthInPixels, _ = img.shape

But hopefully with the appropriate usage of .anchor you should no longer need this.

jez
  • 14,867
  • 5
  • 37
  • 64