docs: def ellipsis(self, line_style, pattern, x, y, radius, ratio=1.0,
                   start_angle=0, end_angle=360, shadow=None):
          """Draw an ellipsis with line_style and fill PATTERN. The center is \
          (X, Y), X radius is RADIUS, and Y radius is RADIUS*RATIO, whose \
          default value is 1.0. SHADOW is either None or a tuple (XDELTA,
          YDELTA, fillstyle). If non-null, a shadow of FILLSTYLE is drawn
          beneath the polygon at the offset of (XDELTA, YDELTA)."""
  
          if invisible_p(x + radius, y + radius * ratio):
              return
  
          if pattern:
              if shadow:
                  x_off, y_off, shadow_pat = shadow
                  self.gsave()
                  self.newpath()
                  self._path_ellipsis(x + x_off, y + y_off, radius, ratio,
                                      start_angle, end_angle)
                  self.clip_sub()
                  self.fill_with_pattern(shadow_pat,
                                         x - radius * 2 + x_off,
                                         y - radius * ratio * 2 + y_off,
                                         x + radius * 2 + x_off,
                                         y + radius * ratio * 2 + y_off)
                  self.grestore()
              self.gsave()
              self.newpath()
              self._path_ellipsis(x, y, radius, ratio, start_angle, end_angle)
              self.clip_sub()
              self.fill_with_pattern(pattern,
                                     (x - radius * 2), (y - radius * ratio * 2),
                                     (x + radius * 2), (y + radius * ratio * 2))
              self.grestore()
          if line_style:
              self.set_line_style(line_style)
              self.newpath()
              self._path_ellipsis(x, y, radius, ratio, start_angle, end_angle)
              self.stroke()