code: def _text_to_vbo(text, font, anchor_x, anchor_y, lowres_size):
      """Convert text characters to VBO"""
      # Necessary to flush commands before requesting current viewport because
      # There may be a set_viewport command waiting in the queue.
      # TODO: would be nicer if each canvas just remembers and manages its own
      # viewport, rather than relying on the context for this.
      canvas = context.get_current_canvas()
      canvas.context.flush_commands()
  
      text_vtype = np.dtype(
          [("a_position", np.float32, 2), ("a_texcoord", np.float32, 2)]
      )
      vertices = np.zeros(len(text) * 4, dtype=text_vtype)
      prev = None
      width = height = ascender = descender = 0
      ratio, slop = 1.0 / font.ratio, font.slop
      x_off = -slop
      # Need to make sure we have a unicode string here (Py2.7 mis-interprets
      # characters like "•" otherwise)
      if sys.version[0] == "2" and isinstance(text, str):
          text = text.decode("utf-8")
      # Need to store the original viewport, because the font[char] will
      # trigger SDF rendering, which changes our viewport
      # todo: get rid of call to glGetParameter!
  
      # Also analyse chars with large ascender and descender, otherwise the
      # vertical alignment can be very inconsistent
      for char in "hy":
          glyph = font[char]
          y0 = glyph["offset"][1] * ratio + slop
          y1 = y0 - glyph["size"][1]
          ascender = max(ascender, y0 - slop)
          descender = min(descender, y1 + slop)
          height = max(height, glyph["size"][1] - 2 * slop)
  
      # Get/set the fonts whitespace length and line height (size of this ok?)
      glyph = font[" "]
      spacewidth = glyph["advance"] * ratio
      lineheight = height * 1.5
  
      # Added escape sequences characters: {unicode:offset,...}
      #   ord('\a') = 7
      #   ord('\b') = 8
      #   ord('\f') = 12
      #   ord('\n') = 10  => linebreak
      #   ord('\r') = 13
      #   ord('\t') = 9   => tab, set equal 4 whitespaces?
      #   ord('\v') = 11  => vertical tab, set equal 4 linebreaks?
      # If text coordinate offset > 0 -> it applies to x-direction
      # If text coordinate offset < 0 -> it applies to y-direction
      esc_seq = {7: 0, 8: 0, 9: -4, 10: 1, 11: 4, 12: 0, 13: 0}
  
      # Keep track of y_offset to set lines at right position
      y_offset = 0
  
      # When a line break occur, record the vertices index value
      vi_marker = 0
      ii_offset = 0  # Offset since certain characters won't be drawn
  
      # The running tracker of characters vertex index
      vi = 0
  
      orig_viewport = canvas.context.get_viewport()
      for ii, char in enumerate(text):
          if ord(char) in esc_seq:
              if esc_seq[ord(char)] < 0:
                  # Add offset in x-direction
                  x_off += abs(esc_seq[ord(char)]) * spacewidth
                  width += abs(esc_seq[ord(char)]) * spacewidth
              elif esc_seq[ord(char)] > 0:
                  # Add offset in y-direction and reset things in x-direction
                  dx = dy = 0
                  if anchor_x == "right":
                      dx = -width
                  elif anchor_x == "center":
                      dx = -width / 2.0
                  vertices["a_position"][vi_marker : vi + 4] += (dx, dy)
                  vi_marker = vi + 4
                  ii_offset -= 1
                  # Reset variables that affects x-direction positioning
                  x_off = -slop
                  width = 0
                  # Add offset in y-direction
                  y_offset += esc_seq[ord(char)] * lineheight
          else:
              # For ordinary characters, normal procedure
              glyph = font[char]
              kerning = glyph["kerning"].get(prev, 0.0) * ratio
              x0 = x_off + glyph["offset"][0] * ratio + kerning
              y0 = glyph["offset"][1] * ratio + slop - y_offset
              x1 = x0 + glyph["size"][0]
              y1 = y0 - glyph["size"][1]
              u0, v0, u1, v1 = glyph["texcoords"]
              position = [[x0, y0], [x0, y1], [x1, y1], [x1, y0]]
              texcoords = [[u0, v0], [u0, v1], [u1, v1], [u1, v0]]
              vi = (ii + ii_offset) * 4
              vertices["a_position"][vi : vi + 4] = position
              vertices["a_texcoord"][vi : vi + 4] = texcoords
              x_move = glyph["advance"] * ratio + kerning
              x_off += x_move
              ascender = max(ascender, y0 - slop)
              descender = min(descender, y1 + slop)
              width += x_move
              height = max(height, glyph["size"][1] - 2 * slop)
              prev = char
  
      if orig_viewport is not None:
          canvas.context.set_viewport(*orig_viewport)
  
      dx = dy = 0
      if anchor_y == "top":
          dy = -descender
      elif anchor_y in ("center", "middle"):
          dy = (-descender - ascender) / 2
      elif anchor_y == "bottom":
          dy = -ascender
      if anchor_x == "right":
          dx = -width
      elif anchor_x == "center":
          dx = -width / 2.0
  
      # If any linebreaks occured in text, we only want to translate characters
      # in the last line in text (those after the vi_marker)
      vertices["a_position"][0:vi_marker] += (0, dy)
      vertices["a_position"][vi_marker:] += (dx, dy)
      vertices["a_position"] /= lowres_size
  
      return vertices
  
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 1 for calling a global function with example usage: _text_to_vbo(text, font, anchor_x, anchor_y, lowres_size) and returns: vertices