# This file was automatically generated by SWIG (http://www.swig.org).
# Version 1.3.31
#
# Don't modify this file, modify the SWIG interface instead.
# This file is compatible with both classic and new-style classes.

import _agg
import new
new_instancemethod = new.instancemethod
try:
    _swig_property = property
except NameError:
    pass # Python < 2.2 doesn't have 'property'.
def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
    if (name == "thisown"): return self.this.own(value)
    if (name == "this"):
        if type(value).__name__ == 'PySwigObject':
            self.__dict__[name] = value
            return
    method = class_type.__swig_setmethods__.get(name,None)
    if method: return method(self,value)
    if (not static) or hasattr(self,name):
        self.__dict__[name] = value
    else:
        raise AttributeError("You cannot add attributes to %s" % self)

def _swig_setattr(self,class_type,name,value):
    return _swig_setattr_nondynamic(self,class_type,name,value,0)

def _swig_getattr(self,class_type,name):
    if (name == "thisown"): return self.this.own()
    method = class_type.__swig_getmethods__.get(name,None)
    if method: return method(self)
    raise AttributeError,name

def _swig_repr(self):
    try: strthis = "proxy of " + self.this.__repr__()
    except: strthis = ""
    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)

import types
try:
    _object = types.ObjectType
    _newclass = 1
except AttributeError:
    class _object : pass
    _newclass = 0
del types


iround = _agg.iround
uround = _agg.uround
ufloor = _agg.ufloor
uceil = _agg.uceil
cover_shift = _agg.cover_shift
cover_size = _agg.cover_size
cover_mask = _agg.cover_mask
cover_none = _agg.cover_none
cover_full = _agg.cover_full
poly_subpixel_shift = _agg.poly_subpixel_shift
poly_subpixel_scale = _agg.poly_subpixel_scale
poly_subpixel_mask = _agg.poly_subpixel_mask
fill_non_zero = _agg.fill_non_zero
fill_even_odd = _agg.fill_even_odd
deg2rad = _agg.deg2rad
rad2deg = _agg.rad2deg
path_cmd_stop = _agg.path_cmd_stop
path_cmd_move_to = _agg.path_cmd_move_to
path_cmd_line_to = _agg.path_cmd_line_to
path_cmd_curve3 = _agg.path_cmd_curve3
path_cmd_curve4 = _agg.path_cmd_curve4
path_cmd_curveN = _agg.path_cmd_curveN
path_cmd_catrom = _agg.path_cmd_catrom
path_cmd_ubspline = _agg.path_cmd_ubspline
path_cmd_end_poly = _agg.path_cmd_end_poly
path_cmd_mask = _agg.path_cmd_mask
path_flags_none = _agg.path_flags_none
path_flags_ccw = _agg.path_flags_ccw
path_flags_cw = _agg.path_flags_cw
path_flags_close = _agg.path_flags_close
path_flags_mask = _agg.path_flags_mask
is_vertex = _agg.is_vertex
is_drawing = _agg.is_drawing
is_stop = _agg.is_stop
is_move_to = _agg.is_move_to
is_line_to = _agg.is_line_to
is_curve = _agg.is_curve
is_curve3 = _agg.is_curve3
is_curve4 = _agg.is_curve4
is_end_poly = _agg.is_end_poly
is_close = _agg.is_close
is_next_poly = _agg.is_next_poly
is_cw = _agg.is_cw
is_ccw = _agg.is_ccw
is_oriented = _agg.is_oriented
is_closed = _agg.is_closed
get_close_flag = _agg.get_close_flag
clear_orientation = _agg.clear_orientation
get_orientation = _agg.get_orientation
set_orientation = _agg.set_orientation
CAP_ROUND = _agg.CAP_ROUND
CAP_BUTT = _agg.CAP_BUTT
CAP_SQUARE = _agg.CAP_SQUARE
JOIN_ROUND = _agg.JOIN_ROUND
JOIN_BEVEL = _agg.JOIN_BEVEL
JOIN_MITER = _agg.JOIN_MITER
FILL = _agg.FILL
EOF_FILL = _agg.EOF_FILL
STROKE = _agg.STROKE
FILL_STROKE = _agg.FILL_STROKE
EOF_FILL_STROKE = _agg.EOF_FILL_STROKE
NORMAL = _agg.NORMAL
BOLD = _agg.BOLD
ITALIC = _agg.ITALIC
TEXT_FILL = _agg.TEXT_FILL
TEXT_STROKE = _agg.TEXT_STROKE
TEXT_FILL_STROKE = _agg.TEXT_FILL_STROKE
TEXT_INVISIBLE = _agg.TEXT_INVISIBLE
TEXT_FILL_CLIP = _agg.TEXT_FILL_CLIP
TEXT_STROKE_CLIP = _agg.TEXT_STROKE_CLIP
TEXT_FILL_STROKE_CLIP = _agg.TEXT_FILL_STROKE_CLIP
TEXT_CLIP = _agg.TEXT_CLIP
nearest = _agg.nearest
bilinear = _agg.bilinear
bicubic = _agg.bicubic
spline16 = _agg.spline16
spline36 = _agg.spline36
sinc64 = _agg.sinc64
sinc144 = _agg.sinc144
sinc256 = _agg.sinc256
blackman64 = _agg.blackman64
blackman100 = _agg.blackman100
blackman256 = _agg.blackman256
pix_format_undefined = _agg.pix_format_undefined
pix_format_gray8 = _agg.pix_format_gray8
pix_format_rgb555 = _agg.pix_format_rgb555
pix_format_rgb565 = _agg.pix_format_rgb565
pix_format_rgb24 = _agg.pix_format_rgb24
pix_format_bgr24 = _agg.pix_format_bgr24
pix_format_rgba32 = _agg.pix_format_rgba32
pix_format_argb32 = _agg.pix_format_argb32
pix_format_abgr32 = _agg.pix_format_abgr32
pix_format_bgra32 = _agg.pix_format_bgra32
end_of_pix_formats = _agg.end_of_pix_formats
blend_normal = _agg.blend_normal
blend_copy = _agg.blend_copy
end_of_e = _agg.end_of_e
grad_none = _agg.grad_none
grad_linear = _agg.grad_linear
grad_radial = _agg.grad_radial
pad = _agg.pad
reflect = _agg.reflect
repeat = _agg.repeat
user_space = _agg.user_space
object_bounding_box = _agg.object_bounding_box
marker_square = _agg.marker_square
marker_diamond = _agg.marker_diamond
marker_circle = _agg.marker_circle
marker_crossed_circle = _agg.marker_crossed_circle
marker_semiellipse_left = _agg.marker_semiellipse_left
marker_semiellipse_right = _agg.marker_semiellipse_right
marker_semiellipse_up = _agg.marker_semiellipse_up
marker_semiellipse_down = _agg.marker_semiellipse_down
marker_triangle_left = _agg.marker_triangle_left
marker_triangle_right = _agg.marker_triangle_right
marker_triangle_up = _agg.marker_triangle_up
marker_triangle_down = _agg.marker_triangle_down
marker_four_rays = _agg.marker_four_rays
marker_cross = _agg.marker_cross
marker_x = _agg.marker_x
marker_dash = _agg.marker_dash
marker_dot = _agg.marker_dot
marker_pixel = _agg.marker_pixel
end_of_markers = _agg.end_of_markers
from numpy import ndarray

def is_array(obj):
    return type(obj) is ndarray

def is_correct_type(obj, numeric_type):
    return is_array(obj) and (obj.dtype == numeric_type)

def numpy_check(obj, typecode,
                exact_size = [],
                must_be_contiguous = 1,
                allow_coersion = 0):

    if is_correct_type(obj, typecode):
        ary = obj
    elif allow_coersion:
        ary = asarray(obj,typecode)
    else:
        raise TypeError, "input is not an array or the array has the wrong type"

    if must_be_contiguous and not ary.flags["CONTIGUOUS"]:
        if allow_coersion:
            ary = ary.copy()
        else:
            raise TypeError, "input array must be contiguous"

    # check number of dimensions
    required_dims = len(exact_size)
    if required_dims and required_dims != len(ary.shape):
        raise ValueError, "The input array does not have the correct shape"

    # check exact shape of each dimension
    cnt = 0
    for desired,actual in zip(exact_size,ary.shape):
        if desired != -1 and desired != actual:
            raise ValueError, "The %d dimensions of the array has the wrong shape" % (cnt)
        cnt += 1

    return ary

path_cmd = _agg.path_cmd
path_flags = _agg.path_flags
kiva_marker_to_agg = {}
kiva_marker_to_agg[1] = marker_square
kiva_marker_to_agg[2] = marker_diamond
kiva_marker_to_agg[3] = marker_circle
kiva_marker_to_agg[4] = marker_crossed_circle
kiva_marker_to_agg[5] = marker_x
kiva_marker_to_agg[6] = marker_triangle_up
kiva_marker_to_agg[7] = marker_triangle_down
kiva_marker_to_agg[8] = marker_cross    # "plus" sign; Agg calls this "cross"
kiva_marker_to_agg[9] = marker_dot
kiva_marker_to_agg[10] = marker_pixel










pix_format_string_map = {}
pix_format_string_map["gray8"] = pix_format_gray8
pix_format_string_map["rgb555"] = pix_format_rgb555
pix_format_string_map["rgb565"] = pix_format_rgb565
pix_format_string_map["rgb24"] = pix_format_rgb24
pix_format_string_map["bgr24"] = pix_format_bgr24
pix_format_string_map["rgba32"] = pix_format_rgba32
pix_format_string_map["argb32"] = pix_format_argb32
pix_format_string_map["abgr32"] = pix_format_abgr32
pix_format_string_map["bgra32"] = pix_format_bgra32

pix_format_enum_map = {}
for key,value in pix_format_string_map.items():
    pix_format_enum_map[value] = key





pix_format_bytes = {}
pix_format_bytes["gray8"] = 1
pix_format_bytes["rgb555"] = 2
pix_format_bytes["rgb565"] = 2
pix_format_bytes["rgb24"] = 3
pix_format_bytes["bgr24"] = 3
pix_format_bytes["rgba32"] = 4
pix_format_bytes["argb32"] = 4
pix_format_bytes["abgr32"] = 4
pix_format_bytes["bgra32"] = 4

pix_format_bits = {}
pix_format_bits["gray8"] = 8
pix_format_bits["rgb555"] = 15
pix_format_bits["rgb565"] = 16
pix_format_bits["rgb24"] = 24
pix_format_bits["bgr24"] = 24
pix_format_bits["rgba32"] = 32
pix_format_bits["argb32"] = 32
pix_format_bits["abgr32"] = 32
pix_format_bits["bgra32"] = 32









interp_string_map = {}
interp_string_map["nearest"] = nearest
interp_string_map["bilinear"] = bilinear
interp_string_map["bicubic"] = bicubic
interp_string_map["spline16"] = spline16
interp_string_map["spline36"] = spline36
interp_string_map["sinc64"] = sinc64
interp_string_map["sinc144"] = sinc144
interp_string_map["sinc256"] = sinc256
interp_string_map["blackman64"] = blackman64
interp_string_map["blackman100"] = blackman100
interp_string_map["blackman256"] = blackman256

interp_enum_map = {}
for key,value in interp_string_map.items():
    interp_enum_map[value] = key


class _Rgba(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, _Rgba, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, _Rgba, name)
    __swig_setmethods__["r"] = _agg._Rgba_r_set
    __swig_getmethods__["r"] = _agg._Rgba_r_get
    if _newclass:r = _swig_property(_agg._Rgba_r_get, _agg._Rgba_r_set)
    __swig_setmethods__["g"] = _agg._Rgba_g_set
    __swig_getmethods__["g"] = _agg._Rgba_g_get
    if _newclass:g = _swig_property(_agg._Rgba_g_get, _agg._Rgba_g_set)
    __swig_setmethods__["b"] = _agg._Rgba_b_set
    __swig_getmethods__["b"] = _agg._Rgba_b_get
    if _newclass:b = _swig_property(_agg._Rgba_b_get, _agg._Rgba_b_set)
    __swig_setmethods__["a"] = _agg._Rgba_a_set
    __swig_getmethods__["a"] = _agg._Rgba_a_get
    if _newclass:a = _swig_property(_agg._Rgba_a_get, _agg._Rgba_a_set)
    def __init__(self, *args): 
        this = _agg.new__Rgba(*args)
        try: self.this.append(this)
        except: self.this = this
    def gradient(*args): return _agg._Rgba_gradient(*args)
    def premultiply(*args): return _agg._Rgba_premultiply(*args)
    def __repr__(*args): return _agg._Rgba___repr__(*args)
    def __eq__(*args): return _agg._Rgba___eq__(*args)
    def asarray(*args): return _agg._Rgba_asarray(*args)
    __swig_destroy__ = _agg.delete__Rgba
    __del__ = lambda self : None;
_Rgba_swigregister = _agg._Rgba_swigregister
_Rgba_swigregister(_Rgba)
cvar = _agg.cvar
pi = cvar.pi

def is_sequence(arg):
    try:
        len(arg)
        return 1
    except:
        return 0


class Rgba(_Rgba):
    def __init__(self,*args):
        if len(args) == 1 and is_sequence(args[0]):
            args = tuple(args[0])
            if len(args) not in [3,4]:
                raise ValueError, "array argument must be 1x3 or 1x4"
        _Rgba.__init__(self,*args)

class AggFontType(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, AggFontType, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, AggFontType, name)
    __swig_setmethods__["size"] = _agg.AggFontType_size_set
    __swig_getmethods__["size"] = _agg.AggFontType_size_get
    if _newclass:size = _swig_property(_agg.AggFontType_size_get, _agg.AggFontType_size_set)
    __swig_setmethods__["name"] = _agg.AggFontType_name_set
    __swig_getmethods__["name"] = _agg.AggFontType_name_get
    if _newclass:name = _swig_property(_agg.AggFontType_name_get, _agg.AggFontType_name_set)
    __swig_setmethods__["family"] = _agg.AggFontType_family_set
    __swig_getmethods__["family"] = _agg.AggFontType_family_get
    if _newclass:family = _swig_property(_agg.AggFontType_family_get, _agg.AggFontType_family_set)
    __swig_setmethods__["style"] = _agg.AggFontType_style_set
    __swig_getmethods__["style"] = _agg.AggFontType_style_get
    if _newclass:style = _swig_property(_agg.AggFontType_style_get, _agg.AggFontType_style_set)
    __swig_setmethods__["encoding"] = _agg.AggFontType_encoding_set
    __swig_getmethods__["encoding"] = _agg.AggFontType_encoding_get
    if _newclass:encoding = _swig_property(_agg.AggFontType_encoding_get, _agg.AggFontType_encoding_set)
    __swig_setmethods__["filename"] = _agg.AggFontType_filename_set
    __swig_getmethods__["filename"] = _agg.AggFontType_filename_get
    if _newclass:filename = _swig_property(_agg.AggFontType_filename_get, _agg.AggFontType_filename_set)
    def __init__(self, *args): 
        this = _agg.new_AggFontType(*args)
        try: self.this.append(this)
        except: self.this = this
    def change_filename(*args): return _agg.AggFontType_change_filename(*args)
    def is_loaded(*args): return _agg.AggFontType_is_loaded(*args)
    def __repr__(*args): return _agg.AggFontType___repr__(*args)
    def __eq__(*args): return _agg.AggFontType___eq__(*args)
    __swig_destroy__ = _agg.delete_AggFontType
    __del__ = lambda self : None;
AggFontType_swigregister = _agg.AggFontType_swigregister
AggFontType_swigregister(AggFontType)

def unicode_safe_init(self, _name="Arial", _size=12, _family=0, _style=0,
                      _encoding=0, validate=True):
    if isinstance(_name, unicode):
        _name = _name.encode("latin1")
    obj = _agg.new_AggFontType(_name, _size, _family, _style,
                               _encoding, validate)
    _swig_setattr(self, AggFontType, "this", obj)
    _swig_setattr(self, AggFontType, "thisown", 1)

# This is a crappy way of overriding the constructor
AggFontType.__init__ = unicode_safe_init

rotation_matrix = _agg.rotation_matrix
scaling_matrix = _agg.scaling_matrix
translation_matrix = _agg.translation_matrix
skewing_matrix = _agg.skewing_matrix
class _AffineMatrix(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, _AffineMatrix, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, _AffineMatrix, name)
    def __init__(self, *args): 
        this = _agg.new__AffineMatrix(*args)
        try: self.this.append(this)
        except: self.this = this
    def __invert__(*args): return _agg._AffineMatrix___invert__(*args)
    def reset(*args): return _agg._AffineMatrix_reset(*args)
    def multiply(*args): return _agg._AffineMatrix_multiply(*args)
    def invert(*args): return _agg._AffineMatrix_invert(*args)
    def flip_x(*args): return _agg._AffineMatrix_flip_x(*args)
    def flip_y(*args): return _agg._AffineMatrix_flip_y(*args)
    def scale(*args): return _agg._AffineMatrix_scale(*args)
    def determinant(*args): return _agg._AffineMatrix_determinant(*args)
    def asarray(*args): return _agg._AffineMatrix_asarray(*args)
    def load_from(*args): return _agg._AffineMatrix_load_from(*args)
    def __repr__(*args): return _agg._AffineMatrix___repr__(*args)
    def __getitem__(*args): return _agg._AffineMatrix___getitem__(*args)
    def __eq__(*args): return _agg._AffineMatrix___eq__(*args)
    __swig_destroy__ = _agg.delete__AffineMatrix
    __del__ = lambda self : None;
_AffineMatrix_swigregister = _agg._AffineMatrix_swigregister
_AffineMatrix_swigregister(_AffineMatrix)

def is_sequence(arg):
    try:
        len(arg)
        return 1
    except:
        return 0




class AffineMatrix(_AffineMatrix):
    def __init__(self,*args):
        if len(args) == 1 and is_sequence(args[0]):
            args = tuple(args[0])
            if len(args) != 6:
                raise ValueError, "array argument must be 1x6"
        _AffineMatrix.__init__(self,*args)

    def __imul__(self,other):
        """ inplace multiply

            We don't use the C++ version of this because it ends up
            deleting the object out from under itself.
        """
        self.multiply(other)
        return self

class CompiledPath(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, CompiledPath, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, CompiledPath, name)
    __repr__ = _swig_repr
    def __init__(self, *args): 
        this = _agg.new_CompiledPath(*args)
        try: self.this.append(this)
        except: self.this = this
    def remove_all(*args): return _agg.CompiledPath_remove_all(*args)
    def begin_path(*args): return _agg.CompiledPath_begin_path(*args)
    def close_path(*args): return _agg.CompiledPath_close_path(*args)
    def move_to(*args): return _agg.CompiledPath_move_to(*args)
    def line_to(*args): return _agg.CompiledPath_line_to(*args)
    def quad_curve_to(*args): return _agg.CompiledPath_quad_curve_to(*args)
    def curve_to(*args): return _agg.CompiledPath_curve_to(*args)
    def arc(*args): return _agg.CompiledPath_arc(*args)
    def arc_to(*args): return _agg.CompiledPath_arc_to(*args)
    def add_path(*args): return _agg.CompiledPath_add_path(*args)
    def lines(*args): return _agg.CompiledPath_lines(*args)
    def line_set(*args): return _agg.CompiledPath_line_set(*args)
    def rect(*args): return _agg.CompiledPath_rect(*args)
    def rects(*args): return _agg.CompiledPath_rects(*args)
    def translate_ctm(*args): return _agg.CompiledPath_translate_ctm(*args)
    def rotate_ctm(*args): return _agg.CompiledPath_rotate_ctm(*args)
    def scale_ctm(*args): return _agg.CompiledPath_scale_ctm(*args)
    def concat_ctm_agg(*args): return _agg.CompiledPath_concat_ctm_agg(*args)
    def set_ctm_agg(*args): return _agg.CompiledPath_set_ctm_agg(*args)
    def kivaaffine_to_aggaffine(self, ctm):
        return AffineMatrix(ctm[0,0], ctm[0,1], ctm[1,0], ctm[1,1],
                            ctm[2,0], ctm[2,1])
    def concat_ctm(self, ctm):
        # This is really tortured and may cause performance problems.
        # Unfortunately I don't see a much better way right now.
        if '__class__' in dir(ctm) and ctm.__class__.__name__.count('AffineMatrix'):
            self.concat_ctm_agg(ctm)
        else:
            self.concat_ctm_agg(self.kivaaffine_to_aggaffine(ctm))
    def set_ctm(self, ctm):
        if '__class__' in dir(ctm) and ctm.__class__.__name__.count('AffineMatrix'):
            self.set_ctm_agg(ctm)
        else:
            self.set_ctm_agg(self.kivaaffine_to_aggaffine(ctm))

    def get_ctm(*args): return _agg.CompiledPath_get_ctm(*args)
    def save_ctm(*args): return _agg.CompiledPath_save_ctm(*args)
    def restore_ctm(*args): return _agg.CompiledPath_restore_ctm(*args)
    def total_vertices(*args): return _agg.CompiledPath_total_vertices(*args)
    def _rewind(*args): return _agg.CompiledPath__rewind(*args)
    def vertex(*args): return _agg.CompiledPath_vertex(*args)
    def _vertex(*args): return _agg.CompiledPath__vertex(*args)
    __swig_destroy__ = _agg.delete_CompiledPath
    __del__ = lambda self : None;
CompiledPath_swigregister = _agg.CompiledPath_swigregister
CompiledPath_swigregister(CompiledPath)

from numpy import array, float64
def _vertices(self):
        """ This is only used for testing.  It allows us to retrieve
            all the vertices in the path at once.  The vertices are
            returned as an Nx4 array of the following format.

	        x0, y0, cmd0, flag0
                x1, y1, cmd0, flag1
                ...
        """
        vertices = []
        self._rewind()
        cmd_flag = 1
        while cmd_flag != 0:
            pt, cmd_flag = self._vertex()
            cmd,flag = _agg.path_cmd(cmd_flag),_agg.path_flags(cmd_flag)
            vertices.append((pt[0],pt[1], cmd, flag))        
        return array(vertices)

CompiledPath._vertices = _vertices    


def get_kiva_ctm(self):
        aff = self.get_ctm()
        return array([[aff[0], aff[1], 0],
                      [aff[2], aff[3], 0],
                      [aff[4], aff[5], 1]], float64)

CompiledPath.get_kiva_ctm = get_kiva_ctm
       

graphics_context_from_array = _agg.graphics_context_from_array
destroy_graphics_context = _agg.destroy_graphics_context
graphics_context_multiply_alpha = _agg.graphics_context_multiply_alpha
# used in GraphicsContextArray constructors
from numpy import array, zeros, uint8, fromstring, shape, ndarray, resize, dtype
import numpy

# Define paths for the two markers that Agg renders incorrectly
from kiva.constants import DIAMOND_MARKER, CIRCLE_MARKER, FILL_STROKE

def circle_marker_path(path, size):
    circle_points = array([[ 1.   ,  0.   ],
                           [ 0.966,  0.259],
                           [ 0.866,  0.5  ],
                           [ 0.707,  0.707],
                           [ 0.5  ,  0.866],
                           [ 0.259,  0.966],
                           [ 0.   ,  1.   ],
                           [-0.259,  0.966],
                           [-0.5  ,  0.866],
                           [-0.707,  0.707],
                           [-0.866,  0.5  ],
                           [-0.966,  0.259],
                           [-1.   ,  0.   ],
                           [-0.966, -0.259],
                           [-0.866, -0.5  ],
                           [-0.707, -0.707],
                           [-0.5  , -0.866],
                           [-0.259, -0.966],
                           [ 0.   , -1.   ],
                           [ 0.259, -0.966],
                           [ 0.5  , -0.866],
                           [ 0.707, -0.707],
                           [ 0.866, -0.5  ],
                           [ 0.966, -0.259],
                           [ 1.   , 0.    ]])
    if size <= 5:
        pts = circle_points[::3] * size
    elif size <= 10:
        pts = circle_points[::2] * size
    else:
        pts = circle_points * size
    path.lines(pts)

substitute_markers = {
    CIRCLE_MARKER: (circle_marker_path, FILL_STROKE)
}

# global freetype engine for text rendering.
#from enthought import freetype
#ft_engine = freetype.FreeType(dpi=120.0)

from kiva import fonttools

def handle_unicode(text):
    "Returns a utf8 encoded 8-bit string from 'text'"
    # For now we just deal with unicode by converting to utf8
    # Later we can add full-blown support with wchar_t/Py_UNICODE
    # typemaps etc.
    try:
        if isinstance(text, unicode):
            text = text.encode("utf8")
        return text
    except:
        raise UnicodeError, "Error encoding text to utf8."

cleanup_font_threading_primitives = _agg.cleanup_font_threading_primitives
# Register module function to clean up mutexes and criticalsection
# objects when the process quits.

import atexit
atexit.register(cleanup_font_threading_primitives)


class GraphicsContextArray(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, GraphicsContextArray, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, GraphicsContextArray, name)
    def __init__(self): raise AttributeError, "No constructor defined"
    __repr__ = _swig_repr
    # We define our own constructor AND destructor.

    def __init__(self, ary_or_size, pix_format="bgra32",
                 interpolation="nearest",bottom_up = 1):
        """ When specifying size, it must be a two element tuple.
            Array input is always treated as an image.

            This class handles the polymorphism of the underlying
            template classes for individual pixel formats.
        """
        array_locally_allocated = False
        self.corner_pixel_origin = True

        pix_format_id = pix_format_string_map[pix_format]
        img_depth = pix_format_bytes[pix_format]
        interpolation_id = interp_string_map[interpolation]

        if type(ary_or_size) is tuple:
            width,height = ary_or_size
            # fix me: this is a slow way to create an array.
            #         the new empty() method in Numeric is much
            #         faster because it doesn\'t zero memory.
            ary = zeros((height,width,img_depth),uint8)
            array_locally_allocated = True
        else:
            ary = ary_or_size
            sh = shape(ary)
            if len(sh) == 2:
                msg = "2D arrays must use a format that is one byte per pixel"
                assert img_depth == 1, msg
            elif len(sh) == 3:
                msg = "Image depth and format are incompatible"
                assert img_depth == sh[2], msg
            else:
                msg = "only 2 or 3 dimensional arrays are supported as images"
                msg += " but got sh=%r" % (sh,)
                raise TypeError, msg
            msg = "Only UnsignedInt8 arrays are supported but got "
            assert(ary.dtype == dtype('uint8')), msg + repr(ary.dtype)

        obj = graphics_context_from_array(ary,pix_format_id,
                                          interpolation_id,
                                          bottom_up)

        _swig_setattr(self, GraphicsContextArray, 'this', obj)
        # swig 1.3.28 does not have real thisown, thisown is mapped
        # to this.own() but with previous 'self.this=obj' an
        # attribute 'own' error is raised. Does this workaround
        # work with pre-1.3.28 swig?
        _swig_setattr(self, GraphicsContextArray, 'thisown2', 1)

        self.bmp_array = ary

        if array_locally_allocated is True:
            self.clear()

    def __del__(self, destroy=_agg.destroy_graphics_context):
        try:
            if self.thisown2: destroy(self)
        except: pass


    def bottom_up(*args): return _agg.GraphicsContextArray_bottom_up(*args)
    def width(*args): return _agg.GraphicsContextArray_width(*args)
    def height(*args): return _agg.GraphicsContextArray_height(*args)
    def stride(*args): return _agg.GraphicsContextArray_stride(*args)
    def format(self):
        enum = _agg.GraphicsContextArray_format(self)
        return pix_format_enum_map[enum]


    def get_image_interpolation(self):
        enum = _agg.GraphicsContextArray_get_image_interpolation(self)
        return interp_enum_map[enum]


    def set_image_interpolation(self,interp):
        enum = interp_string_map[interp]
        _agg.GraphicsContextArray_set_image_interpolation(self,enum)


    def set_stroke_color(self,color):
        if is_array(color) and len(color) == 3:
            ary = color
            r,g,b = ary
            color = Rgba(r,g,b)
        elif is_array(color) and len(color) == 4:
            ary = color
            r,g,b,a = ary
            color = Rgba(r,g,b,a)
        _agg.GraphicsContextArray_set_stroke_color(self,color)


    def get_stroke_color(*args): return _agg.GraphicsContextArray_get_stroke_color(*args)
    def set_line_width(*args): return _agg.GraphicsContextArray_set_line_width(*args)
    def set_line_join(*args): return _agg.GraphicsContextArray_set_line_join(*args)
    def set_line_cap(*args): return _agg.GraphicsContextArray_set_line_cap(*args)
    def set_line_dash(*args): return _agg.GraphicsContextArray_set_line_dash(*args)
    def set_blend_mode(*args): return _agg.GraphicsContextArray_set_blend_mode(*args)
    def get_blend_mode(*args): return _agg.GraphicsContextArray_get_blend_mode(*args)
    def set_fill_color(self,color):
        if is_array(color) and len(color) == 3:
            ary = color
            r,g,b = ary
            color = Rgba(r,g,b)
        elif is_array(color) and len(color) == 4:
            ary = color
            r,g,b,a = ary
            color = Rgba(r,g,b,a)
        _agg.GraphicsContextArray_set_fill_color(self,color)


    def get_fill_color(*args): return _agg.GraphicsContextArray_get_fill_color(*args)
    def set_alpha(*args): return _agg.GraphicsContextArray_set_alpha(*args)
    def get_alpha(*args): return _agg.GraphicsContextArray_get_alpha(*args)
    def set_antialias(*args): return _agg.GraphicsContextArray_set_antialias(*args)
    def get_antialias(*args): return _agg.GraphicsContextArray_get_antialias(*args)
    def set_miter_limit(*args): return _agg.GraphicsContextArray_set_miter_limit(*args)
    def set_flatness(*args): return _agg.GraphicsContextArray_set_flatness(*args)
    def set_text_position(*args): return _agg.GraphicsContextArray_set_text_position(*args)
    def get_text_position(*args): return _agg.GraphicsContextArray_get_text_position(*args)
    def show_text_simple(*args): return _agg.GraphicsContextArray_show_text_simple(*args)
    def show_text_at_point(self, text, dx, dy):
        text = handle_unicode(text)
        return _agg.GraphicsContextArray_show_text_at_point(self, text, dx, dy)


    def show_text(self, text, point = None):
        """Displays text at point, or at the current text pen position
           if point is None.  Returns true if text displayed properly,
           false if there was a font issue or a glyph could not be
           rendered.  Will handle multi-line text separated by backslash-ns"""

        text = handle_unicode(text)

        linelist = text.split('\n')

        if point:
            savepoint = self.get_text_position()
            self.set_text_position(*point)
        orig_tm = self.get_text_matrix()
        next_tm = orig_tm
        success = True
        for line in linelist:
            self.set_text_matrix(next_tm)
            success = success and self.show_text_simple(line)
            extent = self.get_text_extent(line)
            txt_xlat = translation_matrix(0,(extent[1]-extent[3])*1.4)
            txt_xlat.multiply(next_tm)
            next_tm = txt_xlat

        if point:
            self.set_text_position(*savepoint)
        if not success:
            raise RuntimeError, "Font not loaded/initialized."


    def get_text_extent(self, text):
        if not self.is_font_initialized():
            raise RuntimeError, "Font not loaded/initialized."
        else:
            text = handle_unicode(text)
            return _agg.GraphicsContextArray_get_text_extent(self, text)


    def is_font_initialized(*args): return _agg.GraphicsContextArray_is_font_initialized(*args)
    def set_text_matrix(self, matrix):
        """ Set the text matrix.

        `matrix` must be either a kiva.agg.AffineMatrix instance, or
        a 3x3 numpy array.
        """
        if isinstance(matrix, ndarray) and matrix.shape == (3,3):
            matrix = AffineMatrix(matrix[0, 0], matrix[0, 1],
                                  matrix[1, 0], matrix[1, 1],
                                  matrix[2, 0], matrix[2, 1])
        _agg.GraphicsContextArray_set_text_matrix(self, matrix)


    def get_text_matrix(*args): return _agg.GraphicsContextArray_get_text_matrix(*args)
    def set_character_spacing(*args): return _agg.GraphicsContextArray_set_character_spacing(*args)
    def get_character_spacing(*args): return _agg.GraphicsContextArray_get_character_spacing(*args)
    def set_text_drawing_mode(*args): return _agg.GraphicsContextArray_set_text_drawing_mode(*args)
    # backward compatibility
    # Also, Enable calls get_full_text_extent exclusively; it expects the returned
    # arguments to be in a different order
    def get_full_text_extent(self, text):
        leading, descent, w, h = self.get_text_extent(text)
        return (w, h, descent, leading)

    def set_font(self, font):
        retval = False
        if isinstance(font, AggFontType):
            agg_font = font
        elif isinstance(font, fonttools.Font):
            cur_font = self.get_font()
            if cur_font.is_loaded() and (font.face_name == cur_font.name) and \
                (font.size == cur_font.size) and (font.style == cur_font.style) \
                and (font.encoding == cur_font.encoding):
                return
            else:
                newfilename = font.findfont()
                agg_font = AggFontType(font.face_name, font.size, font.family, font.style,
                                       font.encoding, False)
                agg_font.filename = newfilename
        else:
            agg_font = AggFontType(font.face_name, font.size, font.family, font.style, font.encoding)
        try:
            retval = _agg.GraphicsContextArray_set_font(self, agg_font)
            if not retval:
                raise RuntimeError, "Unable to load font."
        except:
            raise RuntimeError, "Unable to load font."


    def set_font_size(self, size):
        if not _agg.GraphicsContextArray_set_font_size(self, size):
            raise RuntimeError, "Font not loaded/initialized."


    def get_font(*args): return _agg.GraphicsContextArray_get_font(*args)
    def save_state(*args): return _agg.GraphicsContextArray_save_state(*args)
    def restore_state(*args): return _agg.GraphicsContextArray_restore_state(*args)
    def translate_ctm(*args): return _agg.GraphicsContextArray_translate_ctm(*args)
    def rotate_ctm(*args): return _agg.GraphicsContextArray_rotate_ctm(*args)
    def scale_ctm(*args): return _agg.GraphicsContextArray_scale_ctm(*args)
    def concat_ctm(self, m):
        if isinstance(m, tuple):
            _agg.GraphicsContextArray_concat_ctm(self, _AffineMatrix(*m))
        else:
            _agg.GraphicsContextArray_concat_ctm(self, m)


    def set_ctm(self, m):
        if isinstance(m, tuple):
            _agg.GraphicsContextArray_set_ctm(self, _AffineMatrix(*m))
        else:
            _agg.GraphicsContextArray_set_ctm(self, m)


    def get_ctm(self):
        tmp = _agg.GraphicsContextArray_get_ctm(self)
        return (tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5])


    def get_freetype_text_matrix(*args): return _agg.GraphicsContextArray_get_freetype_text_matrix(*args)
    def flush(*args): return _agg.GraphicsContextArray_flush(*args)
    def synchronize(*args): return _agg.GraphicsContextArray_synchronize(*args)
    def begin_page(*args): return _agg.GraphicsContextArray_begin_page(*args)
    def end_page(*args): return _agg.GraphicsContextArray_end_page(*args)
    def begin_path(*args): return _agg.GraphicsContextArray_begin_path(*args)
    def move_to(*args): return _agg.GraphicsContextArray_move_to(*args)
    def line_to(*args): return _agg.GraphicsContextArray_line_to(*args)
    def curve_to(*args): return _agg.GraphicsContextArray_curve_to(*args)
    def quad_curve_to(*args): return _agg.GraphicsContextArray_quad_curve_to(*args)
    def arc(*args): return _agg.GraphicsContextArray_arc(*args)
    def arc_to(*args): return _agg.GraphicsContextArray_arc_to(*args)
    def close_path(*args): return _agg.GraphicsContextArray_close_path(*args)
    def add_path(*args): return _agg.GraphicsContextArray_add_path(*args)
    def lines(*args): return _agg.GraphicsContextArray_lines(*args)
    def line_set(*args): return _agg.GraphicsContextArray_line_set(*args)
    def rect(*args): return _agg.GraphicsContextArray_rect(*args)
    def rects(*args): return _agg.GraphicsContextArray_rects(*args)
    def _get_path(*args): return _agg.GraphicsContextArray__get_path(*args)
    def clip(*args): return _agg.GraphicsContextArray_clip(*args)
    def even_odd_clip(*args): return _agg.GraphicsContextArray_even_odd_clip(*args)
    def get_num_clip_regions(*args): return _agg.GraphicsContextArray_get_num_clip_regions(*args)
    def get_clip_region(*args): return _agg.GraphicsContextArray_get_clip_region(*args)
    def clip_to_rect(*args): return _agg.GraphicsContextArray_clip_to_rect(*args)
    def clip_to_rects(*args): return _agg.GraphicsContextArray_clip_to_rects(*args)
    def clear_clip_path(*args): return _agg.GraphicsContextArray_clear_clip_path(*args)
    def clear(*args): return _agg.GraphicsContextArray_clear(*args)
    def stroke_path(*args): return _agg.GraphicsContextArray_stroke_path(*args)
    def fill_path(*args): return _agg.GraphicsContextArray_fill_path(*args)
    def eof_fill_path(*args): return _agg.GraphicsContextArray_eof_fill_path(*args)
    def draw_path(*args): return _agg.GraphicsContextArray_draw_path(*args)
    def draw_rect(*args): return _agg.GraphicsContextArray_draw_rect(*args)
    def draw_image(self, img, rect=None, force_copy=False):
        if isinstance(img, ndarray):
            # The C++ implementation only handles other
            # GraphicsContexts, so create one.
            if img.shape[-1] == 3:
                pix_format = 'rgb24'
            else:
                pix_format = 'rgba32'
            img = GraphicsContextArray(img, pix_format=pix_format)
        if rect is None:
            rect = array((0,0,img.width(),img.height()),float)
        return _agg.GraphicsContextArray_draw_image(self,img,rect,force_copy)


    def draw_marker_at_points(self, pts, size, kiva_marker_type):
        marker = kiva_marker_to_agg.get(kiva_marker_type, None)
        if marker is None:
            success = 0
        elif kiva_marker_type in (CIRCLE_MARKER,):
            # The kiva circle marker is rather jagged so lets
            # use our own
            path_func, mode = substitute_markers[kiva_marker_type]
            path = self.get_empty_path()
            path_func(path, size)
            success = _agg.GraphicsContextArray_draw_path_at_points(self, pts, path, mode)
        else:
            args = (self,pts,int(size),marker)
            success = _agg.GraphicsContextArray_draw_marker_at_points(self, pts,
                            int(size), marker)
        return success


    def draw_path_at_points(*args): return _agg.GraphicsContextArray_draw_path_at_points(*args)
    def convert_pixel_format(self,pix_format,inplace=0):
        """ Convert gc from one pixel format to another.

            !! This used to be done in C++ code, but difficult-to-find
            !! memory bugs pushed toward a simpler solution.
            !! HACK
            !! Now we just draw into a new gc and assume its underlying C++
            !! object. We must be careful not to add any attributes in the
            !! Python GraphicsContextArray constructor other than the bmp_array.
            !! if we do, we need to copy them here also.
        """
        # make sure it uses sub-class if needed
        new_img = self.__class__((self.width(),self.height()),
                                  pix_format=pix_format,
                                  interpolation=self.get_image_interpolation(),
                                  bottom_up = self.bottom_up())
        new_img.draw_image(self)

        if inplace:
            """
            # swap internals with new_self -- it will dealloc our (now unused) C++
            # object and we'll acquire its new one.  We also get a ref to his bmp_array
            """
            old_this = self.this
            self.this = new_img.this
            new_img.this = old_this
            self.bmp_array = new_img.bmp_array
            return self
        else:
            return new_img

    def get_empty_path(self):
        return CompiledPath()

    def save(self, filename, file_format=None, pil_options=None):
        """ Save the GraphicsContext to a file.  Output files are always
            saved in RGB or RGBA format; if this GC is not in one of
            these formats, it is automatically converted.

            If filename includes an extension, the image format is
            inferred from it.  file_format is only required if the
            format can't be inferred from the filename (e.g. if you
            wanted to save a PNG file as a .dat or .bin).

            filename may also be "file-like" object such as a
            StringIO, in which case a file_format must be supplied

            pil_options is a dict of format-specific options that
            are passed down to the PIL image file writer.  If a writer
            doesn't recognize an option, it is silently ignored.

            If the image has an alpha channel and the specified output
            file format does not support alpha, the image is saved in
            rgb24 format.
        """
        FmtsWithoutAlpha = ('jpg', 'bmp', 'eps', "jpeg")
        import Image as PilImage
        size = (self.width(), self.height())
        fmt = self.format()

        # determine the output pixel format and PIL format
        if fmt.endswith("32"):
            pilformat = "RGBA"
            pixelformat = "rgba32"
            if (isinstance(filename, basestring) and filename[-3:].lower() in FmtsWithoutAlpha) or \
               (file_format is not None and file_format.lower() in FmtsWithoutAlpha):
                pilformat = "RGB"
                pixelformat = "rgb24"
        elif fmt.endswith("24"):
            pilformat = "RGB"
            pixelformat = "rgb24"

        # perform a conversion if necessary
        if fmt != pixelformat:
            newimg = GraphicsContextArray(size, fmt)
            newimg.draw_image(self)
            newimg.convert_pixel_format(pixelformat, 1)
            bmp = newimg.bmp_array
        else:
            bmp = self.bmp_array

        img = PilImage.fromstring(pilformat, size, bmp.tostring())
        img.save(filename, format=file_format, options=pil_options)


    #----------------------------------------------------------------
    # context manager interface
    #----------------------------------------------------------------

    def __enter__(self):
        self.save_state()
        
    def __exit__(self, type, value, traceback):
        self.restore_state()


    def linear_gradient(*args): return _agg.GraphicsContextArray_linear_gradient(*args)
    def radial_gradient(*args): return _agg.GraphicsContextArray_radial_gradient(*args)
GraphicsContextArray_swigregister = _agg.GraphicsContextArray_swigregister
GraphicsContextArray_swigregister(GraphicsContextArray)

# constructors for GraphicsContextArray and Image

# !! Temporary until we get the __init__ code in swig fixed.
def init(self, ary_or_size, pix_format="bgra32",
             interpolation="nearest",bottom_up = 1):
    """ When specifying size, it must be a two element tuple.
        Array input is always treated as an image.

        This class handles the polymorphism of the underlying
        template classes for individual pixel formats.
    """

    pix_format_id = pix_format_string_map[pix_format]
    img_depth = pix_format_bytes[pix_format]
    interpolation_id = interp_string_map[interpolation]
    if type(ary_or_size) is tuple:
        width,height = ary_or_size
        ary = zeros((height,width,img_depth),uint8)
        ary[:] = 255
    else:
        ary = ary_or_size
        sh = shape(ary)
        if len(sh) == 2:
            msg = "2D arrays must use a format that is one byte per pixel"
            assert img_depth == 1, msg
        elif len(sh) == 3:
            msg = "Image depth and format are incompatible"
            assert img_depth == sh[2], msg
        else:
            msg = "only 2 or 3 dimensional arrays are supported as images"
            msg += " but got sh=%r" % (sh,)
            raise TypeError, msg
        msg = "Only UnsignedInt8 arrays are supported but got "
        assert ary.dtype == dtype('uint8'), msg + repr(ary.dtype)

    if cvar.ALWAYS_32BIT_WORKAROUND_FLAG:
        if ary.shape[-1] == 3:
            if pix_format not in ('rgb24', 'bgr24'):
                import warnings
                warnings.warn('need to workaround AGG bug since '
                	'ALWAYS_32BIT_WORKAROUND is on, but got unhandled '
                	'format %r' % pix_format)
            else:
                pix_format = '%sa32' % pix_format[:3]
                ary = numpy.dstack([ary, numpy.empty(ary.shape[:2], dtype=uint8)])
                ary[:,:,-1].fill(255)
        pix_format_id = pix_format_string_map[pix_format]
        img_depth = pix_format_bytes[pix_format]

    obj = graphics_context_from_array(ary,pix_format_id,interpolation_id,
                                      bottom_up)

    _swig_setattr(self, GraphicsContextArray, 'this', obj)
    # swig 1.3.28 does not have real thisown, thisown is mapped
    # to this.own() but with previous 'self.this=obj' an
    # attribute 'own' error is raised. Does this workaround
    # work with pre-1.3.28 swig?
    _swig_setattr(self, GraphicsContextArray, 'thisown2', 1)

    self.bmp_array = ary

GraphicsContextArray.__init__ = init

pil_format_map = {}
pil_format_map["RGB"] = "rgb24"
pil_format_map["RGBA"] = "rgba32"

pil_depth_map = {}
pil_depth_map["RGB"] = 3
pil_depth_map["RGBA"] = 4

class Image(GraphicsContextArray):
    """ Image is a GraphicsContextArray sub-class created from an image file.
    """
    def __init__(self, file, interpolation="nearest", bottom_up=1):
        """ Create an Image object (GraphicsContextArray) from a file.

        Parameters
        ----------
        file
            can be either a file name or an open file object
        interpolation
            specifies the type of filter used when putting the image into
            another GraphicsContextArray
        """
        # read the file using PIL
        import Image as PilImage
        pil_img = PilImage.open(file)

        # Convert image to a numeric array
        if (pil_img.mode not in ["RGB","RGBA"] or
            (cvar.ALWAYS_32BIT_WORKAROUND_FLAG and pil_img.mode != "RGBA")):
            pil_img = pil_img.convert(mode="RGBA")
        depth = pil_depth_map[pil_img.mode]
        img = fromstring(pil_img.tostring(),uint8)
        img = resize(img, (pil_img.size[1],pil_img.size[0],depth))
        format = pil_format_map[pil_img.mode]

        GraphicsContextArray.__init__(self, img, pix_format=format,
                                      interpolation=interpolation,
                                      bottom_up = bottom_up)

    def convert_pixel_format(self,pix_format,inplace=0):
        "Convert gc from one pixel format to another."
        # We override the one in the base GraphicsContextArray because that
        # one calls our __init__, which is not really the behavior we want.
        #
        # This problem can be avoided altogether down the road when the
        # Image subclass is turned into a factory function.
        new_img = GraphicsContextArray((self.width(),self.height()),
                                  pix_format=pix_format,
                                  interpolation=self.get_image_interpolation(),
                                  bottom_up = self.bottom_up())
        new_img.draw_image(self)

        if inplace:
            old_this = self.this
            self.this = new_img.this
            new_img.this = old_this
            self.bmp_array = new_img.bmp_array
            return self
        else:
            return new_img



class GraphicsContextGL(GraphicsContextArray):
    __swig_setmethods__ = {}
    for _s in [GraphicsContextArray]: __swig_setmethods__.update(getattr(_s,'__swig_setmethods__',{}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, GraphicsContextGL, name, value)
    __swig_getmethods__ = {}
    for _s in [GraphicsContextArray]: __swig_getmethods__.update(getattr(_s,'__swig_getmethods__',{}))
    __getattr__ = lambda self, name: _swig_getattr(self, GraphicsContextGL, name)
    __repr__ = _swig_repr
    def __init__(self, *args): 
        this = _agg.new_GraphicsContextGL(*args)
        try: self.this.append(this)
        except: self.this = this
    __swig_destroy__ = _agg.delete_GraphicsContextGL
    __del__ = lambda self : None;
    def gl_init(*args): return _agg.GraphicsContextGL_gl_init(*args)
    def gl_cleanup(*args): return _agg.GraphicsContextGL_gl_cleanup(*args)
    def begin_page(*args): return _agg.GraphicsContextGL_begin_page(*args)
    def gl_render_path(*args): return _agg.GraphicsContextGL_gl_render_path(*args)
    def gl_render_points(*args): return _agg.GraphicsContextGL_gl_render_points(*args)
    def format(self):
        enum = _agg.GraphicsContextArray_format(self)
        return pix_format_enum_map[enum]


    def save_state(*args): return _agg.GraphicsContextGL_save_state(*args)
    def restore_state(*args): return _agg.GraphicsContextGL_restore_state(*args)
    def clip(*args): return _agg.GraphicsContextGL_clip(*args)
    def even_odd_clip(*args): return _agg.GraphicsContextGL_even_odd_clip(*args)
    def clip_to_rect(*args): return _agg.GraphicsContextGL_clip_to_rect(*args)
    def clip_to_rects(*args): return _agg.GraphicsContextGL_clip_to_rects(*args)
    def transform_clip_rectangle(*args): return _agg.GraphicsContextGL_transform_clip_rectangle(*args)
    def clear_clip_path(*args): return _agg.GraphicsContextGL_clear_clip_path(*args)
    def get_num_clip_regions(*args): return _agg.GraphicsContextGL_get_num_clip_regions(*args)
    def get_clip_region(*args): return _agg.GraphicsContextGL_get_clip_region(*args)
    def clear(*args): return _agg.GraphicsContextGL_clear(*args)
    def fill_path(*args): return _agg.GraphicsContextGL_fill_path(*args)
    def eof_fill_path(*args): return _agg.GraphicsContextGL_eof_fill_path(*args)
    def stroke_path(*args): return _agg.GraphicsContextGL_stroke_path(*args)
    def _stroke_path(*args): return _agg.GraphicsContextGL__stroke_path(*args)
    def draw_path(*args): return _agg.GraphicsContextGL_draw_path(*args)
    def draw_rect(*args): return _agg.GraphicsContextGL_draw_rect(*args)
    def draw_marker_at_points(self,pts,size,kiva_marker_type):
        marker = kiva_marker_to_agg.get(kiva_marker_type, None)
        if marker is None:
            success = 0
        else:
            args = (self,pts,int(size),marker)
            success = _agg.GraphicsContextGL_draw_marker_at_points(self, pts,
                            int(size), marker)
        return success


    def draw_path_at_points(*args): return _agg.GraphicsContextGL_draw_path_at_points(*args)
    def show_text_simple(*args): return _agg.GraphicsContextGL_show_text_simple(*args)
    def draw_glyphs(*args): return _agg.GraphicsContextGL_draw_glyphs(*args)
    def draw_image(*args): return _agg.GraphicsContextGL_draw_image(*args)
GraphicsContextGL_swigregister = _agg.GraphicsContextGL_swigregister
GraphicsContextGL_swigregister(GraphicsContextGL)

point_in_polygon = _agg.point_in_polygon
points_in_polygon = _agg.points_in_polygon
point_in_polygon_winding = _agg.point_in_polygon_winding
points_in_polygon_winding = _agg.points_in_polygon_winding
from numpy import shape, transpose, zeros, rank, reshape, int32

def points_in_polygon(pts, poly_pts, use_winding=False):
    """ Test whether point pairs in pts are within the polygon, poly_pts.

    Parameters
    ----------
    pts 
        an Nx2 array of x,y point pairs (floating point).  Each point is tested
        to determine whether it falls within the polygon defined by `poly_pts`.                
    poly_pts
        an Mx2 array of x,y point pairs (floating point) that define the 
        boundaries of a polygon. The last point is considered to be connected
        to the first point.
    return 
        a 1D array of integers.  1 is returned if the corresponding x,y pair 
        in `pts` falls within `poly_pts`.  0 is returned otherwise.
        
    This algorithm works for complex polygons.  
         
    Note: If the test point is on the border of the polygon, this 
    algorithm will deliver unpredictable results; i.e. the result 
    may be "inside" or "outside" depending on arbitrary factors 
    such as how the polygon is oriented with respect to the 
    coordinate system.
        
    Adapted from: http://www.alienryderflex.com/polygon/
    
    Example::
    
        >>> from numpy import *
        >>> from kiva import agg        
        >>> poly = array(((0.0,   0.0),
                          (10.0,  0.0),
                          (10.0, 10.0),
                          ( 0.0, 10.0)))                
        >>> pts = array(((-1.0, -1.0),
                         ( 5.0,  5.0),  
                         ( 15.0, 15.0)))
        >>> results = agg.points_in_polygon(pts, poly)
        [0 1 0]
        
        
    """
    
    
    if rank(pts) == 1:
        pts = reshape(pts, (1,)+shape(pts))
    if shape(pts)[1] != 2:
        if shape(pts)[0] == 2:
            pts = transpose(pts)
        else:
            raise ValueError('pts must be an Nx2 or 2xN array')

    
    if rank(poly_pts) == 1:
        poly_pts = reshape(poly_pts, (1,)+shape(poly_pts))
    if shape(poly_pts)[1] != 2:
        if shape(poly_pts)[0] == 2:
            poly_pts = transpose(poly_pts)
        else:
            raise ValueError('poly_pts must be an Nx2 or 2xN array')

    results = zeros(len(pts),int32)
    if use_winding:
        _agg.points_in_polygon_winding(pts, poly_pts, results)
    else:
        _agg.points_in_polygon(pts, poly_pts, results)
    return results    



