1
2
3
4
5
6
7
8
9
10
11 """
12 Text stimuli.
13
14 """
15
16
17
18
19
20
21
22 import logging
23 import logging.handlers
24
25 import VisionEgg.Core
26 import VisionEgg.Textures
27 import VisionEgg.ParameterTypes as ve_types
28
29 import VisionEgg.GL as gl
30
31 import pygame
32
33 try:
34 import OpenGL.GLUT as glut
35 have_glut = True
36 except:
37 have_glut = False
38
39 _font_objects = {}
40
41 -class Text(VisionEgg.Textures.TextureStimulus):
42 """Single line of text rendered using pygame/SDL true type fonts.
43
44 Parameters
45 ==========
46 anchor -- specifies how position parameter is interpreted (String)
47 Inherited from VisionEgg.Textures.TextureStimulus
48 Default: lowerleft
49 angle -- units: degrees, 0=right, 90=up (Real)
50 Inherited from VisionEgg.Textures.TextureStimulus
51 Default: 0.0
52 color -- texture environment color. alpha ignored (if given) for max_alpha parameter (AnyOf(Sequence3 of Real or Sequence4 of Real))
53 Inherited from VisionEgg.Textures.TextureStimulus
54 Default: (1.0, 1.0, 1.0)
55 depth_test -- perform depth test? (Boolean)
56 Inherited from VisionEgg.Textures.TextureStimulus
57 Default: False
58 ignore_size_parameter -- (Boolean)
59 Default: True
60 mask -- optional masking function (Instance of <class 'VisionEgg.Textures.Mask2D'>)
61 Inherited from VisionEgg.Textures.TextureStimulus
62 Default: (determined at runtime)
63 max_alpha -- controls opacity. 1.0=copletely opaque, 0.0=completely transparent (Real)
64 Inherited from VisionEgg.Textures.TextureStimulus
65 Default: 1.0
66 on -- draw stimulus? (Boolean)
67 Inherited from VisionEgg.Textures.TextureStimulus
68 Default: True
69 position -- units: eye coordinates (AnyOf(Sequence2 of Real or Sequence3 of Real or Sequence4 of Real))
70 Inherited from VisionEgg.Textures.TextureStimulus
71 Default: (0.0, 0.0)
72 size -- defaults to texture data size (units: eye coordinates) (Sequence2 of Real)
73 Inherited from VisionEgg.Textures.TextureStimulus
74 Default: (determined at runtime)
75 text -- (AnyOf(String or Unicode))
76 Default: the string to display
77 texture -- source of texture data (Instance of <class 'VisionEgg.Textures.Texture'>)
78 Inherited from VisionEgg.Textures.TextureStimulusBaseClass
79 Default: (determined at runtime)
80 texture_mag_filter -- OpenGL filter enum (Integer)
81 Inherited from VisionEgg.Textures.TextureStimulusBaseClass
82 Default: GL_LINEAR (9729)
83 texture_min_filter -- OpenGL filter enum (Integer)
84 Inherited from VisionEgg.Textures.TextureStimulusBaseClass
85 Default: (GL enum determined at runtime)
86 texture_wrap_s -- OpenGL texture wrap enum (Integer)
87 Inherited from VisionEgg.Textures.TextureStimulusBaseClass
88 Default: (GL enum determined at runtime)
89 texture_wrap_t -- OpenGL texture wrap enum (Integer)
90 Inherited from VisionEgg.Textures.TextureStimulusBaseClass
91 Default: (GL enum determined at runtime)
92
93 Constant Parameters
94 ===================
95 font_name -- (AnyOf(String or Unicode))
96 Default: (determined at runtime)
97 font_size -- (UnsignedInteger)
98 Default: 30
99 internal_format -- format with which OpenGL uses texture data (OpenGL data type enum) (Integer)
100 Inherited from VisionEgg.Textures.TextureStimulus
101 Default: GL_RGB (6407)
102 mipmaps_enabled -- Are mipmaps enabled? (Boolean)
103 Inherited from VisionEgg.Textures.TextureStimulus
104 Default: True
105 shrink_texture_ok -- Allow automatic shrinking of texture if too big? (Boolean)
106 Inherited from VisionEgg.Textures.TextureStimulus
107 Default: False
108 """
109
110 parameters_and_defaults = {
111 'text': ( 'the string to display',
112 ve_types.AnyOf(ve_types.String,ve_types.Unicode)),
113 'ignore_size_parameter':(True,
114 ve_types.Boolean),
115 }
116
117 constant_parameters_and_defaults = {
118 'font_size':(30,
119 ve_types.UnsignedInteger),
120 'font_name':(None,
121 ve_types.AnyOf(ve_types.String,ve_types.Unicode)),
122 }
123
124 __slots__ = (
125 'font',
126 '_text',
127 )
128
129 - def __init__(self,**kw):
130 if not pygame.font:
131 raise RuntimeError("no pygame font module")
132 if not pygame.font.get_init():
133 pygame.font.init()
134 if not pygame.font.get_init():
135 raise RuntimeError("pygame doesn't init")
136
137 if 'internal_format' not in kw.keys():
138 kw['internal_format'] = gl.GL_RGBA
139 if 'mipmaps_enabled' not in kw.keys():
140 kw['mipmaps_enabled'] = 0
141 if 'texture_min_filter' not in kw.keys():
142 kw['texture_min_filter'] = gl.GL_LINEAR
143 VisionEgg.Textures.TextureStimulus.__init__(self,**kw)
144 cp = self.constant_parameters
145 fontobject_args = (cp.font_name,cp.font_size)
146 if fontobject_args not in _font_objects:
147
148 fontobject = pygame.font.Font(*fontobject_args)
149 _font_objects[fontobject_args] = fontobject
150
151 self.font = _font_objects[fontobject_args]
152 self._render_text()
153
154 - def _render_text(self):
155 p = self.parameters
156 rendered_surf = self.font.render(p.text, 1, (255,255,255))
157
158
159 p.texture = VisionEgg.Textures.Texture(rendered_surf)
160 self._reload_texture()
161 self._text = p.text
162 if p.ignore_size_parameter:
163 p.size = p.texture.size
164
166 p = self.parameters
167 if p.texture != self._using_texture:
168 raise RuntimeError("my texture has been modified, but it shouldn't be")
169 if p.text != self._text:
170 self._render_text()
171 if p.ignore_size_parameter:
172 p.size = p.texture.size
173 VisionEgg.Textures.TextureStimulus.draw(self)
174
175 if have_glut:
176
177 - class GlutTextBase(VisionEgg.Core.Stimulus):
178 """DEPRECATED. Base class: don't instantiate this class directly.
179
180 Base class that defines the common interface between the
181 other glut-based text stimuli.
182
183 Parameters
184 ==========
185 color -- (AnyOf(Sequence3 of Real or Sequence4 of Real))
186 Default: (1.0, 1.0, 1.0)
187 lowerleft -- (Sequence2 of Real)
188 Default: (320, 240)
189 on -- (Boolean)
190 Default: True
191 text -- (String)
192 Default: the string to display
193 """
194
195 parameters_and_defaults = {
196 'on':(True,
197 ve_types.Boolean),
198 'color':((1.0,1.0,1.0),
199 ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
200 ve_types.Sequence4(ve_types.Real))),
201 'lowerleft':((320,240),
202 ve_types.Sequence2(ve_types.Real)),
203 'text':('the string to display',
204 ve_types.String)}
205
206 - def __init__(self,**kw):
207 if not hasattr(VisionEgg.config,"_GAVE_GLUT_TEXT_DEPRECATION"):
208 logger = logging.getLogger('VisionEgg.Text')
209 logger.warning("Using GlutTextBase class. This will be "
210 "removed in a future release. Use "
211 "VisionEgg.Text.Text instead.")
212 VisionEgg.config._GAVE_GLUT_TEXT_DEPRECATION = 1
213 VisionEgg.Core.Stimulus.__init__(self,**kw)
214
215 - class BitmapText(GlutTextBase):
216 """DEPRECATED. Bitmap fonts from GLUT.
217
218 Parameters
219 ==========
220 color -- (AnyOf(Sequence3 of Real or Sequence4 of Real))
221 Inherited from GlutTextBase
222 Default: (1.0, 1.0, 1.0)
223 font -- (Integer)
224 Default: 5
225 lowerleft -- (Sequence2 of Real)
226 Inherited from GlutTextBase
227 Default: (320, 240)
228 on -- (Boolean)
229 Inherited from GlutTextBase
230 Default: True
231 text -- (String)
232 Inherited from GlutTextBase
233 Default: the string to display
234 """
235
236 parameters_and_defaults = {
237 'font':(glut.GLUT_BITMAP_TIMES_ROMAN_24,
238 ve_types.Integer),
239 }
240
241 - def __init__(self,**kw):
243
245 if self.parameters.on:
246 gl.glDisable(gl.GL_TEXTURE_2D)
247 gl.glDisable(gl.GL_BLEND)
248 gl.glDisable(gl.GL_DEPTH_TEST)
249
250 gl.glMatrixMode(gl.GL_MODELVIEW)
251 gl.glPushMatrix()
252 gl.glTranslate(self.parameters.lowerleft[0],self.parameters.lowerleft[1],0.0)
253
254 c = self.parameters.color
255
256 if len(c)==3:
257 gl.glColor3f(*c)
258 elif len(c)==4:
259 gl.glColor4f(*c)
260 gl.glDisable(gl.GL_TEXTURE_2D)
261
262 gl.glRasterPos3f(0.0,0.0,0.0)
263 for char in self.parameters.text:
264 glut.glutBitmapCharacter(self.parameters.font,ord(char))
265 gl.glPopMatrix()
266
267 - class StrokeText(GlutTextBase):
268 """DEPRECATED. Text rendered by GLUT using stroke fonts.
269
270 Parameters
271 ==========
272 anti_aliasing -- (Boolean)
273 Default: True
274 color -- (AnyOf(Sequence3 of Real or Sequence4 of Real))
275 Inherited from GlutTextBase
276 Default: (1.0, 1.0, 1.0)
277 font -- (Integer)
278 Default: 0
279 linewidth -- (Real)
280 Default: 3.0
281 lowerleft -- (Sequence2 of Real)
282 Inherited from GlutTextBase
283 Default: (320, 240)
284 on -- (Boolean)
285 Inherited from GlutTextBase
286 Default: True
287 orientation -- (Real)
288 Default: 0.0
289 text -- (String)
290 Inherited from GlutTextBase
291 Default: the string to display
292 """
293
294 parameters_and_defaults = {
295 'font':(glut.GLUT_STROKE_ROMAN,
296 ve_types.Integer),
297 'orientation':(0.0,
298 ve_types.Real),
299 'linewidth':(3.0,
300 ve_types.Real),
301 'anti_aliasing':(True,
302 ve_types.Boolean),
303 }
304
305 - def __init__(self,**kw):
306 raise NotImplementedError("There's something broken with StrokeText, and I haven't figured it out yet!")
307 GlutTextBase.__init__(self,**kw)
308
310 if self.parameters.on:
311 gl.glDisable(gl.GL_TEXTURE_2D)
312 gl.glDisable(gl.GL_DEPTH_TEST)
313
314 gl.glMatrixMode(gl.GL_MODELVIEW)
315 gl.glPushMatrix()
316 gl.glTranslate(self.parameters.lowerleft[0],self.parameters.lowerleft[1],0.0)
317 gl.glRotate(self.parameters.orientation,0.0,0.0,1.0)
318
319 c = self.parameters.color
320 if len(c)==3:
321 gl.glColor3f(*c)
322 elif len(c)==4:
323 gl.glColor4f(*c)
324
325 gl.glLineWidth(self.parameters.linewidth)
326
327 if self.parameters.anti_aliasing:
328 gl.glEnable(gl.GL_BLEND)
329 gl.glBlendFunc(gl.GL_SRC_ALPHA,gl.GL_ONE_MINUS_SRC_ALPHA)
330 gl.glEnable(gl.GL_LINE_SMOOTH)
331 else:
332 gl.glDisable(gl.GL_BLEND)
333
334
335
336
337
338
339
340
341
342
343 for char in self.parameters.text:
344 glut.glutStrokeCharacter(self.parameters.font,ord(char))
345 gl.glPopMatrix()
346