class_docstr: Visual that displays text
  
  Parameters
  ----------
  text : str | list of str
      Text to display. Can also be a list of strings.
      Note: support for list of str might be removed soon
      in favor of text collections.
  color : instance of Color
      Color to use.
  bold : bool
      Bold face.
  italic : bool
      Italic face.
  face : str
      Font face to use.
  font_size : float
      Point size to use.
  pos : tuple | list of tuple
      Position (x, y) or (x, y, z) of the text.
      Can also be a list of tuple if `text` is a list.
  rotation : float
      Rotation (in degrees) of the text clockwise.
  anchor_x : str
      Horizontal text anchor.
  anchor_y : str
      Vertical text anchor.
  method : str
      Rendering method for text characters. Either 'cpu' (default) or
      'gpu'. The 'cpu' method should perform better on remote backends.
      The 'gpu' method should produce higher quality results.
  font_manager : object | None
      Font manager to use (can be shared if the GLContext is shared).
  depth_test : bool
      Whether to apply depth testing. Default False. If False, the text
      behaves like an overlay that does not get hidden behind other
      visuals in the scene.
class_docstr_tok: ["Visual","that","displays","text","Parameters","--","--","--","--","--","text",":","str","|","list","of","str","Text","to","display",".","Can","also","be","a","list","of","strings",".","Note",":","support","for","list","of","str","might","be","removed","soon","in","favor","of","text","collections",".","color",":","instance","of","Color","Color","to","use",".","bold",":","bool","Bold","face",".","italic",":","bool","Italic","face",".","face",":","str","Font","face","to","use",".","font_size",":","float","Point","size","to","use",".","pos",":","tuple","|","list","of","tuple","Position","(","x",",","y",")","or","(","x",",","y",",","z",")","of","the","text",".","Can","also","be","a","list","of","tuple","if","`","text","`","is","a","list",".","rotation",":","float","Rotation","(","in","degrees",")","of","the","text","clockwise",".","anchor_x",":","str","Horizontal","text","anchor",".","anchor_y",":","str","Vertical","text","anchor",".","method",":","str","Rendering","method","for","text","characters",".","Either","'cpu","'","(","default",")","or","'gpu","'",".","The","'cpu","'","method","should","perform","better","on","remote","backends",".","The","'gpu","'","method","should","produce","higher","quality","results",".","font_manager",":","object","|","None","Font","manager","to","use","(","can","be","shared","if","the","GLContext","is","shared",")",".","depth_test",":","bool","Whether","to","apply","depth","testing",".","Default","False",".","If","False",",","the","text","behaves","like","an","overlay","that","does","not","get","hidden","behind","other","visuals","in","the","scene","."]
code: def _prepare_draw(self, view):
      # attributes / uniforms are not available until program is built
      if len(self.text) == 0:
          return False
      if self._vertices is None:
          text = self.text
          if isinstance(text, str):
              text = [text]
          n_char = sum(len(t) for t in text)
          # we delay creating vertices because it requires a context,
          # which may or may not exist when the object is initialized
          self._vertices = np.concatenate(
              [
                  _text_to_vbo(
                      t,
                      self._font,
                      self._anchors[0],
                      self._anchors[1],
                      self._font._lowres_size,
                  )
                  for t in text
              ]
          )
          self._vertices = VertexBuffer(self._vertices)
          idx = (
              np.array([0, 1, 2, 0, 2, 3], np.uint32)
              + np.arange(0, 4 * n_char, 4, dtype=np.uint32)[
                  :, np.newaxis
              ]
          )
          self._index_buffer = IndexBuffer(idx.ravel())
          self.shared_program.bind(self._vertices)
          # This is necessary to reset the GL drawing state after generating
          # SDF textures. A better way would be to enable the state to be
          # pushed/popped by the context.
          self._configure_gl_state()
      if self._pos_changed:
          # now we promote pos to the proper shape (attribute)
          text = self.text
          if not isinstance(text, str):
              repeats = [4 * len(t) for t in text]
              text = "".join(text)
          else:
              repeats = [4 * len(text)]
          n_text = len(repeats)
          pos = self.pos
          # Rotation
          _rot = self._rotation
          if isinstance(_rot, (int, float)):
              _rot = np.full((pos.shape[0],), self._rotation)
          _rot = np.asarray(_rot)
          if _rot.shape[0] < n_text:
              _rep = [1] * (len(_rot) - 1) + [n_text - len(_rot) + 1]
              _rot = np.repeat(_rot, _rep, axis=0)
          _rot = np.repeat(_rot[:n_text], repeats, axis=0)
          self.shared_program["a_rotation"] = _rot.astype(np.float32)
          # Position
          if pos.shape[0] < n_text:
              _rep = [1] * (len(pos) - 1) + [n_text - len(pos) + 1]
              pos = np.repeat(pos, _rep, axis=0)
          pos = np.repeat(pos[:n_text], repeats, axis=0)
          assert pos.shape[0] == self._vertices.size == len(_rot)
          self.shared_program["a_pos"] = pos
          self._pos_changed = False
      if self._color_changed:
          # now we promote color to the proper shape (varying)
          text = self.text
          if not isinstance(text, str):
              repeats = [4 * len(t) for t in text]
              text = "".join(text)
          else:
              repeats = [4 * len(text)]
          n_text = len(repeats)
          color = self.color.rgba
          if color.shape[0] < n_text:
              color = np.repeat(
                  color,
                  [1] * (len(color) - 1) + [n_text - len(color) + 1],
                  axis=0,
              )
          color = np.repeat(color[:n_text], repeats, axis=0)
          assert color.shape[0] == self._vertices.size
          self._color_vbo = VertexBuffer(color)
          self.shared_program.vert["color"] = self._color_vbo
          self._color_changed = False
  
      transforms = self.transforms
      n_pix = (self._font_size / 72.0) * transforms.dpi  # logical pix
      tr = transforms.get_transform("document", "render")
      px_scale = (tr.map((1, 0)) - tr.map((0, 1)))[:2]
      self._text_scale.scale = px_scale * n_pix
      self.shared_program.vert["text_scale"] = self._text_scale
      self.shared_program["u_npix"] = n_pix
      self.shared_program["u_kernel"] = self._font._kernel
      self.shared_program["u_color"] = self._color.rgba
      self.shared_program["u_font_atlas"] = self._font._atlas
      self.shared_program[
          "u_font_atlas_shape"
      ] = self._font._atlas.shape[:2]
  
imports: from __future__ import division
  import numpy
  from copy import deepcopy
  import sys
  from ._sdf_gpu import SDFRendererGPU
  from ._sdf_cpu import _calc_distance_field
  from ...gloo import TextureAtlas, IndexBuffer, VertexBuffer
  from ...gloo import context
  from ...gloo.wrappers import _check_valid
  from ...util.fonts import _load_glyph
  from ..transforms import STTransform
  from ...color import ColorArray
  from ..visual import Visual
  from ...io import load_spatial_filters
label_desc: Use image node_id 14 for calling the TextVisual obj's underlying member method code with example usage: obj._prepare_draw(view) and returns: False