Draw a polygon with EDGE_STYLE, fill with PAT, and the edges
        POINTS. POINTS is a sequence of coordinates, e.g., ((10,10), (15,5),
        (20,8)). 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).

def polygon(self, edge_style, pat, points, shadow=None):
        """Draw a polygon with EDGE_STYLE, fill with PAT, and the edges
        POINTS. POINTS is a sequence of coordinates, e.g., ((10,10), (15,5),
        (20,8)). 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 pat:
            self.comment("POLYGON points=[%s] pat=[%s]"
                         % (str(points), str(pat)))
            (xmin, ymin, xmax, ymax) = _compute_bounding_box(points)

            if shadow:
                xoff, yoff, shadow_pat = shadow
                self.gsave()
                self._path_polygon(list(map(lambda p, xoff=xoff, yoff=yoff: (p[0] + xoff, p[1] + yoff), points)))
                self.clip_sub()
                self.fill_with_pattern(shadow_pat, xmin + xoff, ymin + yoff,
                                       xmax + xoff, ymax + yoff)
                self.grestore()

            self.gsave()
            self._path_polygon(points)
            self.clip_sub()
            self.fill_with_pattern(pat, xmin, ymin, xmax, ymax)
            self.grestore()
        if edge_style:
            self.comment("POLYGON points=[%s] edge=[%s]"
                         % (str(points), str(edge_style)))
            self.set_line_style(edge_style)
            self._path_polygon(points)
            self.stroke()