code: def deskew_textboxes(page, skew_radians, skew_direction, about_pt):
      """
      Deskew all text boxes in <page> about a point <about_pt> by <skew_radians> radians in direction <skew_direction>.
      """
      if skew_direction not in (SKEW_X, SKEW_Y):
          raise ValueError(
              "invalid parameter value '%s' for skew_direction"
              % skew_direction
          )
  
      for t in page["texts"]:
          if skew_direction == SKEW_X:
              x = t["top"] + t["height"] / 2
              ref_idx = 1
              a = -1
          else:
              x = t["left"] + t["width"] / 2
              ref_idx = 0
              a = 1
  
          # x, y have nothing to do with the x and y in a cartesian coord. system
          # y is the coordinate that gets changed depending on x
          d = x - about_pt[ref_idx]
          y_diff = a * math.sin(skew_radians) * d
  
          if skew_direction == SKEW_X:
              pt_deskewed = pt(t["left"] + y_diff, t["top"])
          else:
              pt_deskewed = pt(t["left"], t["top"] + y_diff)
  
          update_text_dict_pos(t, pt_deskewed, update_node=True)
  
file_path: pdftabextract/pdftabextract/textboxes.py
imports: import math
  import numpy
  from pdftabextract.common import update_text_dict_pos, sorted_by_attr, DIRECTION_HORIZONTAL, DIRECTION_VERTICAL, SKEW_X, SKEW_Y
  from pdftabextract.geom import pt, vecrotate
label_desc: Use image node_id 7 for calling a global function with example usage: deskew_textboxes(page, skew_radians, skew_direction, about_pt) without return types