Source code for pi3d.util.PointText

from __future__ import absolute_import, division, print_function, unicode_literals

import numpy as np
import logging
from pi3d.shape.Points import Points
from pi3d.Shader import Shader
from pi3d.util.TextBlock import TextBlock

import math
import colorsys

LOGGER = logging.getLogger(__name__)

[docs]class PointText(object): def __init__(self, font, camera, max_chars=100, point_size=48): """ Arguments: *font*: A PointFont object. *camera*: camera to use for drawing the text. Normally a fixed 2d camera. *max_chars*: maximum number of chars, which determines the number of points in the buffer *point_size*: size of "default" characters created using the Points class and the font. This is further scaled by the TextBlock.size This refinement is needed to allow pointsize to be different in Points from Font to avoid clipping or overlap of corners when rotation some truetype fonts """ self.max_chars = max_chars self.font = font self.shader = Shader.create("uv_pointsprite") self.locations = np.zeros((max_chars, 3)) # :,2 for size and z offset. # size=fract(location[2] range 0.0 to 0.999) # zoffset = (location[2] - size)*0.1 self.normals = np.zeros((max_chars, 3)) # :,0 for rotation # :,1 for red and green, red=normal[1]/999, green=fract(normal[1]) # :,2 for blue and alpha, blue=normal[2]/999, alpha=fract(normal[2]) self.normals[:,1] = 0.0 self.normals[:,2] = 0.0 self.uv = np.zeros((max_chars, 2)) # u picnum.u v self.text_blocks = [] self._first_free_char = 0 self._do_buffer_reinit = False self.point_size = point_size self.text = Points(camera=camera, vertices=self.locations, normals=self.normals, tex_coords=self.uv, point_size=self.point_size) self.text.set_draw_details(self.shader, [self.font]) self.text.unif[48] = 0.928 / self.font.grid_size # used to hold "patch size" passed to shader - margin to allow rotating #Reset all characters to space so there are no false character shadows try: glyph = self.font.glyph_table[' '] #u' ' doesn't work on python3.2!! except: glyph = list(self.font.glyph_table.values())[0] #in case ' ' isn't there self.uv[:] = glyph[0:2]
[docs] def regen(self): ''' Regenerate all text blocks that are linked to data objects and have changed value ''' for block in self.text_blocks: if block.data_obj is not None: value = block.get_value() if value != block.last_value: block.last_value = value block.set_text()
[docs] def add_text_block(self, text_block): ''' Add a text block to the collection, setting the object link to this service and setting the buffer offset allocated to the text block. This is required for the text block to update the buffer allocated to it. Also tracks the next unallocated character in the buffer. ''' if self._first_free_char + text_block.char_count >= self.max_chars: LOGGER.error("failed to allocate space in characers for %s characters. Max set to %s", text_block.char_count, self.max_chars) return -1 self.text_blocks.append(text_block) text_block.set_text_manager(self, self._first_free_char) text_block.set_text() self._first_free_char += text_block.char_count return 0
[docs] def draw(self): ''' Draw all the text characters. If the re_init flag is set then update the points shape buffer. ''' if self._do_buffer_reinit: self.text.buf[0].re_init(pts=self.locations, normals=self.normals, texcoords=self.uv) # reform opengles array_buffer self.text.draw()
[docs] def set_do_reinit(self): self._do_buffer_reinit = True