code: def draw_text_image(
      text,
      fontsize,
      height,
      width,
      fonts,
      use_ligatures=False,
      thetaX=0,
      thetaY=0,
      thetaZ=0,
      color=(0, 0, 0),
      permitted_contour=None,
      draw_contour=False,
  ):
      """Get a transparent image containing text.
  
      Args:
          text: The text to draw on the image
          fontsize: The size of text to show.
          height: The height of the output image
          width: The width of the output image
          fonts: A dictionary of {subalphabet: paths_to_font}
          thetaX: Rotation about the X axis
          thetaY: Rotation about the Y axis
          thetaZ: Rotation about the Z axis
          color: The color of drawn text
          permitted_contour: A contour defining which part of the image
              we can put text. If None, the entire canvas is permitted
              for text.
          use_ligatures: Whether to render ligatures. If True,
              ligatures are always used (with an initial check for support
              which sometimes yields false positives). If False, ligatures
              are never used.
  
      Returns:
          An (image, lines) tuple where image is the
          transparent text image and lines is a list of lines
          where each line itself is a list of (box, character) tuples and
          box is an array of points with shape (4, 2) providing the coordinates
          of the character box in clockwise order starting from the top left.
      """
      if not use_ligatures:
          fonts = {
              subalphabet: PIL.ImageFont.truetype(
                  font_path, size=fontsize
              )
              if font_path is not None
              else PIL.ImageFont.load_default()
              for subalphabet, font_path in fonts.items()
          }
      if use_ligatures:
          for subalphabet, font_path in fonts.items():
              ligatures_supported = True
              font = (
                  PIL.ImageFont.truetype(font_path, size=fontsize)
                  if font_path is not None
                  else PIL.ImageFont.load_default()
              )
              for ligature in LIGATURES:
                  try:
                      font.getsize(ligature)
                  except UnicodeEncodeError:
                      ligatures_supported = False
                      break
              if ligatures_supported:
                  del fonts[subalphabet]
                  subalphabet += LIGATURE_STRING
              fonts[subalphabet] = font
          for insert, search in LIGATURES.items():
              for subalphabet in fonts.keys()():
                  if insert in subalphabet:
                      text = text.replace(search, insert)
      character_font_pairs = [
          (
              character,
              next(
                  font
                  for subalphabet, font in fonts.items()
                  if character in subalphabet
              ),
          )
          for character in text
      ]
      M = get_rotation_matrix(
          width=width,
          height=height,
          thetaZ=thetaZ,
          thetaX=thetaX,
          thetaY=thetaY,
      )
      if permitted_contour is None:
          permitted_contour = np.array(
              [[0, 0], [width, 0], [width, height], [0, height]]
          ).astype("float32")
      character_sizes = np.array(
          [
              font.font.getsize(character)
              for character, font in character_font_pairs
          ]
      )
      min_character_size = character_sizes.sum(axis=1).min()
      transformed_contour = compute_transformed_contour(
          width=width,
          height=height,
          fontsize=max(min_character_size, 1),
          M=M,
          contour=permitted_contour,
      )
      start_x = transformed_contour[:, 0].min()
      start_y = transformed_contour[:, 1].min()
      end_x = transformed_contour[:, 0].max()
      end_y = transformed_contour[:, 1].max()
      image = PIL.Image.new(
          mode="RGBA", size=(width, height), color=(255, 255, 255, 0)
      )
      draw = PIL.ImageDraw.Draw(image)
      lines_raw: typing.List[
          typing.List[typing.Tuple[np.ndarray, str]]
      ] = [[]]
      x = start_x
      y = start_y
      max_y = start_y
      out_of_space = False
      for character_index, (character, font) in enumerate(
          character_font_pairs
      ):
          if out_of_space:
              break
          (character_width, character_height), (
              offset_x,
              offset_y,
          ) = character_sizes[character_index]
          if character in LIGATURES:
              subcharacters = LIGATURES[character]
              dx = character_width / len(subcharacters)
          else:
              subcharacters = character
              dx = character_width
          x2, y2 = (
              x + character_width + offset_x,
              y + character_height + offset_y,
          )
          while not all(
              cv2.pointPolygonTest(
                  contour=transformed_contour, pt=pt, measureDist=False
              )
              >= 0
              for pt in [
                  (int(x), int(y)),
                  (int(x2), int(y)),
                  (int(x2), int(y2)),
                  (int(x), int(y2)),
              ]
          ):
              if x2 > end_x:
                  dy = max(1, max_y - y)
                  if y + dy > end_y:
                      out_of_space = True
                      break
                  y += dy
                  x = start_x
              else:
                  x += fontsize
              if len(lines_raw[-1]) > 0:
                  # We add a new line whether we have advanced
                  # in the y-direction or not because we also want to separate
                  # horizontal segments of text.
                  lines_raw.append([])
              x2, y2 = (
                  x + character_width + offset_x,
                  y + character_height + offset_y,
              )
          if out_of_space:
              break
          max_y = max(y + character_height + offset_y, max_y)
          draw.text(
              xy=(x, y), text=character, fill=color + (255,), font=font
          )
          for subcharacter in subcharacters:
              lines_raw[-1].append(
                  (
                      np.array(
                          [
                              [x + offset_x, y + offset_y],
                              [x + dx + offset_x, y + offset_y],
                              [x + dx + offset_x, y2],
                              [x + offset_x, y2],
                          ]
                      ).astype("float32"),
                      subcharacter,
                  )
              )
              x += dx
      image = cv2.warpPerspective(
          src=np.array(image), M=M, dsize=(width, height)
      )
      if draw_contour:
          image = cv2.drawContours(
              image,
              contours=[
                  permitted_contour.reshape((-1, 1, 2)).astype("int32")
              ],
              contourIdx=0,
              color=(255, 0, 0, 255),
              thickness=int(width / 100),
          )
      lines_stripped = _strip_lines(lines_raw)
      lines_transformed = [
          [
              (
                  cv2.perspectiveTransform(src=coords[np.newaxis], m=M)[
                      0
                  ],
                  character,
              )
              for coords, character in line
          ]
          for line in lines_stripped
      ]
      return image, lines_transformed
  
imports: import os
  import math
  import glob
  import typing
  import random
  import zipfile
  import string
  import itertools
  import cv2
  import tqdm
  import numpy
  import essential_generators
  import PIL.Image
  import PIL.ImageDraw
  import PIL.ImageFont
  import fontTools.ttLib
  from .None import tools
label_desc: Use image node_id 11 for calling a global function with example usage: draw_text_image(text, fontsize, height, width, fonts, use_ligatures, thetaX, thetaY, thetaZ, color, permitted_contour, draw_contour) and returns: image,  lines_transformed