Revision: 6771
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6771&view=rev
Author:   jdh2358
Date:     2009-01-10 20:03:59 +0000 (Sat, 10 Jan 2009)

Log Message:
-----------
applied michiel's hatch patch for macosx sf id 2497785

Modified Paths:
--------------
    trunk/matplotlib/CHANGELOG
    trunk/matplotlib/examples/pylab_examples/hatch_demo.py
    trunk/matplotlib/lib/matplotlib/backends/backend_macosx.py
    trunk/matplotlib/src/_macosx.m

Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG  2009-01-08 22:11:09 UTC (rev 6770)
+++ trunk/matplotlib/CHANGELOG  2009-01-10 20:03:59 UTC (rev 6771)
@@ -1,3 +1,6 @@
+2009-01-10 Applied Michiel's hatch patch for macosx backend.  Closes
+           sf patch 2497785 - JDH
+
 2009-01-06 Fix bug in setting of dashed negative contours. - EF
 
 2009-01-06 Be fault tolerant when len(linestyles)>NLev in contour. - MM

Modified: trunk/matplotlib/examples/pylab_examples/hatch_demo.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/hatch_demo.py      2009-01-08 
22:11:09 UTC (rev 6770)
+++ trunk/matplotlib/examples/pylab_examples/hatch_demo.py      2009-01-10 
20:03:59 UTC (rev 6771)
@@ -6,10 +6,6 @@
 
 fig = plt.figure()
 ax1 = fig.add_subplot(121)
-ax1.annotate("Hatch is only supported in the PS, PDF, SVG and Agg backends", 
(1, 1),
-             xytext=(0, 5),
-             xycoords="axes fraction", textcoords="offset points", ha="center"
-             )
 ax1.bar(range(1,5), range(1,5), color='red', edgecolor='black', hatch="/")
 ax1.bar(range(1,5), [6] * 4, bottom=range(1,5), color='blue', 
edgecolor='black', hatch='//')
 

Modified: trunk/matplotlib/lib/matplotlib/backends/backend_macosx.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_macosx.py  2009-01-08 
22:11:09 UTC (rev 6770)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_macosx.py  2009-01-10 
20:03:59 UTC (rev 6771)
@@ -77,6 +77,7 @@
 
     def new_gc(self):
         self.gc.reset()
+        self.gc.set_hatch(None)
         return self.gc
 
     def draw_image(self, x, y, im, bbox, clippath=None, clippath_trans=None):
@@ -166,10 +167,14 @@
         _macosx.GraphicsContext.__init__(self)
 
     def set_foreground(self, fg, isRGB=False):
-        if not isRGB:
-            fg = colorConverter.to_rgb(fg)
-        _macosx.GraphicsContext.set_foreground(self, fg)
+        GraphicsContextBase.set_foreground(self, fg, isRGB)
+        rgb = self.get_rgb()
+        _macosx.GraphicsContext.set_foreground(self, rgb[:3])
 
+    def set_graylevel(self, fg):
+        GraphicsContextBase.set_graylevel(self, fg)
+        _macosx.GraphicsContext.set_graylevel(self, fg)
+
     def set_clip_rectangle(self, box):
         GraphicsContextBase.set_clip_rectangle(self, box)
         if not box: return

Modified: trunk/matplotlib/src/_macosx.m
===================================================================
--- trunk/matplotlib/src/_macosx.m      2009-01-08 22:11:09 UTC (rev 6770)
+++ trunk/matplotlib/src/_macosx.m      2009-01-10 20:03:59 UTC (rev 6771)
@@ -31,6 +31,10 @@
 #define CURVE3    3
 #define CURVE4    4
 #define CLOSEPOLY 5
+
+/* Hatching */
+#define HATCH_SIZE 72
+
 /* -------------------------- Helper function ---------------------------- */
 
 static void stdin_ready(CFReadStreamRef readStream, CFStreamEventType 
eventType, void* context)
@@ -203,6 +207,269 @@
         PyErr_WarnEx(PyExc_RuntimeWarning, "ATSUDisposeTextLayout failed", 1);
 }
 
+static int
+_draw_path(CGContextRef cr, PyObject* path, CGAffineTransform affine)
+{
+    CGPoint point;
+
+    PyObject* vertices = PyObject_GetAttrString(path, "vertices");
+    if (vertices==NULL)
+    {
+        PyErr_SetString(PyExc_AttributeError, "path has no vertices");
+        return -1;
+    }
+    Py_DECREF(vertices); /* Don't keep a reference here */
+
+    PyObject* codes = PyObject_GetAttrString(path, "codes");
+    if (codes==NULL)
+    {
+        PyErr_SetString(PyExc_AttributeError, "path has no codes");
+        return -1;
+    }
+    Py_DECREF(codes); /* Don't keep a reference here */
+
+    PyArrayObject* coordinates;
+    coordinates = (PyArrayObject*)PyArray_FromObject(vertices,
+                                                     NPY_DOUBLE, 2, 2);
+    if (!coordinates)
+    {
+        PyErr_SetString(PyExc_ValueError, "failed to convert vertices array");
+        return -1;
+    }
+
+    if (PyArray_NDIM(coordinates) != 2 || PyArray_DIM(coordinates, 1) != 2)
+    {
+        Py_DECREF(coordinates);
+        PyErr_SetString(PyExc_ValueError, "invalid vertices array");
+        return -1;
+    }
+
+    npy_intp n = PyArray_DIM(coordinates, 0);
+
+    if (n==0) /* Nothing to do here */
+    {
+        Py_DECREF(coordinates);
+        return 0;
+    }
+
+    PyArrayObject* codelist = NULL;
+    if (codes != Py_None)
+    {
+        codelist = (PyArrayObject*)PyArray_FromObject(codes,
+                                                      NPY_UINT8, 1, 1);
+        if (!codelist)
+        {
+            Py_DECREF(coordinates);
+            PyErr_SetString(PyExc_ValueError, "invalid codes array");
+            return -1;
+        }
+    }
+
+    if (codelist==NULL)
+    {
+        npy_intp i;
+        npy_uint8 code = MOVETO;
+        for (i = 0; i < n; i++)
+        {
+            point.x = (CGFloat)(*(double*)PyArray_GETPTR2(coordinates, i, 0));
+            point.y = (CGFloat)(*(double*)PyArray_GETPTR2(coordinates, i, 1));
+            if (isnan(point.x) || isnan(point.y))
+            {
+                code = MOVETO;
+            }
+            else
+            {
+                point = CGPointApplyAffineTransform(point, affine);
+                switch (code)
+                {
+                    case MOVETO:
+                        CGContextMoveToPoint(cr, point.x, point.y);
+                        break;
+                    case LINETO:
+                        CGContextAddLineToPoint(cr, point.x, point.y);
+                        break;
+                }
+                code = LINETO;
+            }
+        }
+    }
+    else
+    {
+        npy_intp i = 0;
+        BOOL was_nan = false;
+        npy_uint8 code;
+        CGFloat x1, y1, x2, y2, x3, y3;
+        while (i < n)
+        {
+            code = *(npy_uint8*)PyArray_GETPTR1(codelist, i);
+            if (code == CLOSEPOLY)
+            {
+                CGContextClosePath(cr);
+                i++;
+            }
+            else if (code == STOP)
+            {
+                break;
+            }
+            else if (was_nan)
+            {
+                if (code==CURVE3) i++;
+                else if (code==CURVE4) i+=2;
+                x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
+                y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+                i++;
+                if (isnan(x1) || isnan(y1))
+                {
+                    was_nan = true;
+                }
+                else
+                {
+                    point.x = x1;
+                    point.y = y1;
+                    point = CGPointApplyAffineTransform(point, affine);
+                    CGContextMoveToPoint(cr, point.x, point.y);
+                    was_nan = false;
+                }
+            }
+            else if (code==MOVETO)
+            {
+                x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
+                y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+                i++;
+                if (isnan(x1) || isnan(y1))
+                {
+                    was_nan = true;
+                }
+                else
+                {
+                    point.x = x1;
+                    point.y = y1;
+                    point = CGPointApplyAffineTransform(point, affine);
+                    CGContextMoveToPoint(cr, point.x, point.y);
+                    was_nan = false;
+                }
+            }
+            else if (code==LINETO)
+            {
+                x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
+                y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+                i++;
+                if (isnan(x1) || isnan(y1))
+                {
+                    was_nan = true;
+                }
+                else
+                {
+                    point.x = x1;
+                    point.y = y1;
+                    point = CGPointApplyAffineTransform(point, affine);
+                    CGContextAddLineToPoint(cr, point.x, point.y);
+                    was_nan = false;
+                }
+            }
+            else if (code==CURVE3)
+            {
+                x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
+                y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+                i++;
+                x2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
+                y2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+                i++;
+                if (isnan(x1) || isnan(y1) || isnan(x2) || isnan(y2))
+                {
+                    was_nan = true;
+                }
+                else
+                {
+                    point.x = x1;
+                    point.y = y1;
+                    point = CGPointApplyAffineTransform(point, affine);
+                    x1 = point.x;
+                    y1 = point.y;
+                    point.x = x2;
+                    point.y = y2;
+                    point = CGPointApplyAffineTransform(point, affine);
+                    x2 = point.x;
+                    y2 = point.y;
+                    CGContextAddQuadCurveToPoint(cr, x1, y1, x2, y2);
+                    was_nan = false;
+                }
+            }
+            else if (code==CURVE4)
+            {
+                x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
+                y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+                i++;
+                x2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
+                y2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+                i++;
+                x3 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
+                y3 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+                i++;
+                if (isnan(x1) || isnan(y1) || isnan(x2) || isnan(y2) || 
isnan(x3) || isnan(y3))
+                {
+                    was_nan = true;
+                }
+                else
+                {
+                    point.x = x1;
+                    point.y = y1;
+                    point = CGPointApplyAffineTransform(point, affine);
+                    x1 = point.x;
+                    y1 = point.y;
+                    point.x = x2;
+                    point.y = y2;
+                    point = CGPointApplyAffineTransform(point, affine);
+                    x2 = point.x;
+                    y2 = point.y;
+                    point.x = x3;
+                    point.y = y3;
+                    point = CGPointApplyAffineTransform(point, affine);
+                    x3 = point.x;
+                    y3 = point.y;
+                    CGContextAddCurveToPoint(cr, x1, y1, x2, y2, x3, y3);
+                    was_nan = false;
+                }
+            }
+        }
+    }
+
+    Py_DECREF(coordinates);
+    Py_XDECREF(codelist);
+    return n;
+}
+
+static void _draw_hatch (void *info, CGContextRef cr)
+{
+    PyObject* hatchpath = (PyObject*)info;
+    CGAffineTransform affine = CGAffineTransformMakeScale(HATCH_SIZE, 
HATCH_SIZE);
+
+    int n = _draw_path(cr, hatchpath, affine);
+    if (n < 0)
+    {
+        PyGILState_STATE gstate = PyGILState_Ensure();
+        PyErr_Print();
+        PyGILState_Release(gstate);
+        return;
+    }
+    else if (n==0)
+    {
+        return;
+    }
+    else
+    {
+        CGContextSetLineWidth(cr, 1.0); 
+        CGContextSetLineCap(cr, kCGLineCapSquare); 
+        CGContextDrawPath(cr, kCGPathFillStroke);
+    }
+}
+
+static void _release_hatch(void* info)
+{
+    PyObject* hatchpath = (PyObject*)info;
+    Py_DECREF(hatchpath);
+}
+
 /* ---------------------------- Cocoa classes ---------------------------- */
 
 
@@ -274,7 +541,6 @@
 typedef struct {
     PyObject_HEAD
     CGContextRef cr;
-    CGPatternRef pattern;  /* For drawing hatches */
 } GraphicsContext;
 
 static PyObject*
@@ -283,7 +549,6 @@
     GraphicsContext* self = (GraphicsContext*)type->tp_alloc(type, 0);
     if (!self) return NULL;
     self->cr = NULL;
-    self->pattern = NULL;
 
     if (ngc==0)
     {
@@ -301,8 +566,6 @@
 static void
 GraphicsContext_dealloc(GraphicsContext *self)
 {
-    CGPatternRelease(self->pattern);
-
     ngc--;
     if (ngc==0) _dealloc_atsui();
 
@@ -325,12 +588,6 @@
         return NULL;
     }
 
-    if (self->pattern)
-    {
-        CGPatternRelease(self->pattern);
-        self->pattern = NULL;
-    }
-
     CGContextRestoreGState(cr);
     CGContextSaveGState(cr);
     Py_INCREF(Py_None);
@@ -431,10 +688,6 @@
         PyErr_SetString(PyExc_RuntimeError, "CGContextRef is NULL");
         return NULL;
     }
-#ifdef BUH
-    CGContextRestoreGState(cr); /* FIXME */
-    CGContextSaveGState(cr); /* FIXME */
-#endif
 
     PyObject* path;
 
@@ -759,116 +1012,7 @@
     return Py_None;
 }
 
-static void _draw_hatch (void *info, CGContextRef cr)
-{
-    int i;
-
-    PyObject* string = (PyObject*)info;
-    char* hatches = PyString_AS_STRING(string);
-
-    int frequency[4] = {0, 0, 0, 0};
-    float position, distance;
-
-    const float size = 12.0;
-    const int n = strlen(hatches);
-
-    for (i = 0; i < n; i++)
-    {
-        switch(hatches[i])
-        {
-            case '/':  frequency[3]++; break;
-            case '\\': frequency[2]++; break;
-            case '|':  frequency[1]++; break;
-            case '-':  frequency[0]++; break;
-            case '+':  frequency[0]++; frequency[1]++; break;
-            case 'x':  frequency[2]++; frequency[3]++; break;
-        }
-    }
-
-    distance = size / frequency[0];
-    position = distance / 2.0;
-    for (i = 0; i < frequency[0]; i++, position += distance)
-    {
-        CGContextMoveToPoint(cr, 0.0, position);
-        CGContextAddLineToPoint(cr, size, position);
-    }
-    distance = size / frequency[1];
-    position = distance / 2.0;
-    for (i = 0; i < frequency[1]; i++, position += distance)
-    {
-        CGContextMoveToPoint(cr, position, 0.0);
-        CGContextAddLineToPoint(cr, position, size);
-    }
-    distance = size / frequency[2];
-    position = distance / 2.0;
-    for (i = 0; i < frequency[2]; i++, position += distance)
-    {
-        CGContextMoveToPoint(cr, position, 0.0);
-        CGContextAddLineToPoint(cr, 0.0, position);
-        CGContextMoveToPoint(cr, position, size);
-        CGContextAddLineToPoint(cr, size, position);
-    }
-    distance = size / frequency[3];
-    position = distance / 2.0;
-    for (i = 0; i < frequency[3]; i++, position += distance)
-    {
-        CGContextMoveToPoint(cr, position, 0.0);
-        CGContextAddLineToPoint(cr, size, size-position);
-        CGContextMoveToPoint(cr, position, size);
-        CGContextAddLineToPoint(cr, 0.0, size-position);
-    }
-    CGContextSetLineWidth(cr, 2.0); 
-    CGContextSetLineCap(cr, kCGLineCapSquare); 
-    CGContextStrokePath(cr);
-
-    Py_DECREF(string);
-}
-
-static void _release_hatch(void* info)
-{
-    PyObject* hatches = info;
-    Py_DECREF(hatches);
-}
-
 static PyObject*
-GraphicsContext_set_hatch(GraphicsContext* self, PyObject* args)
-{   PyObject* hatches;
-
-    const float size = 12.0;
-    static const CGPatternCallbacks callbacks = {0,
-                                                 &_draw_hatch,
-                                                 &_release_hatch};
-
-    CGContextRef cr = self->cr;
-    if (!cr)
-    {
-        PyErr_SetString(PyExc_RuntimeError, "CGContextRef is NULL");
-        return NULL;
-    }
-
-    if(!PyArg_ParseTuple(args, "O", &hatches)) return NULL;
-    if(!PyString_Check(hatches)) return NULL;
-
-    Py_INCREF(hatches);
-
-    CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();
-    CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(baseSpace);
-    CGColorSpaceRelease(baseSpace);
-    CGContextSetFillColorSpace(cr, patternSpace);
-    CGColorSpaceRelease(patternSpace);
-
-    self->pattern = CGPatternCreate((void*)hatches,
-                                    CGRectMake(0, 0, size, size),
-                                    CGAffineTransformIdentity, size, size,
-                                    kCGPatternTilingNoDistortion,
-                                    false,
-                                    &callbacks);   
-
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-static PyObject*
 GraphicsContext_set_linewidth (GraphicsContext* self, PyObject* args)
 {   
     float width;
@@ -965,238 +1109,6 @@
     return 1;
 }
 
-static int
-_draw_path(CGContextRef cr, PyObject* path, CGAffineTransform affine)
-{
-    CGPoint point;
-
-    PyObject* vertices = PyObject_GetAttrString(path, "vertices");
-    if (vertices==NULL)
-    {
-        PyErr_SetString(PyExc_AttributeError, "path has no vertices");
-        return -1;
-    }
-    Py_DECREF(vertices); /* Don't keep a reference here */
-
-    PyObject* codes = PyObject_GetAttrString(path, "codes");
-    if (codes==NULL)
-    {
-        PyErr_SetString(PyExc_AttributeError, "path has no codes");
-        return -1;
-    }
-    Py_DECREF(codes); /* Don't keep a reference here */
-
-    PyArrayObject* coordinates;
-    coordinates = (PyArrayObject*)PyArray_FromObject(vertices,
-                                                     NPY_DOUBLE, 2, 2);
-    if (!coordinates)
-    {
-        PyErr_SetString(PyExc_ValueError, "failed to convert vertices array");
-        return -1;
-    }
-
-    if (PyArray_NDIM(coordinates) != 2 || PyArray_DIM(coordinates, 1) != 2)
-    {
-        Py_DECREF(coordinates);
-        PyErr_SetString(PyExc_ValueError, "invalid vertices array");
-        return -1;
-    }
-
-    npy_intp n = PyArray_DIM(coordinates, 0);
-
-    if (n==0) /* Nothing to do here */
-    {
-        Py_DECREF(coordinates);
-        return 0;
-    }
-
-    PyArrayObject* codelist = NULL;
-    if (codes != Py_None)
-    {
-        codelist = (PyArrayObject*)PyArray_FromObject(codes,
-                                                      NPY_UINT8, 1, 1);
-        if (!codelist)
-        {
-            Py_DECREF(coordinates);
-            PyErr_SetString(PyExc_ValueError, "invalid codes array");
-            return -1;
-        }
-    }
-
-    if (codelist==NULL)
-    {
-        npy_intp i;
-        npy_uint8 code = MOVETO;
-        for (i = 0; i < n; i++)
-        {
-            point.x = (CGFloat)(*(double*)PyArray_GETPTR2(coordinates, i, 0));
-            point.y = (CGFloat)(*(double*)PyArray_GETPTR2(coordinates, i, 1));
-            if (isnan(point.x) || isnan(point.y))
-            {
-                code = MOVETO;
-            }
-            else
-            {
-                point = CGPointApplyAffineTransform(point, affine);
-                switch (code)
-                {
-                    case MOVETO:
-                        CGContextMoveToPoint(cr, point.x, point.y);
-                        break;
-                    case LINETO:
-                        CGContextAddLineToPoint(cr, point.x, point.y);
-                        break;
-                }
-                code = LINETO;
-            }
-        }
-    }
-    else
-    {
-        npy_intp i = 0;
-        BOOL was_nan = false;
-        npy_uint8 code;
-        CGFloat x1, y1, x2, y2, x3, y3;
-        while (i < n)
-        {
-            code = *(npy_uint8*)PyArray_GETPTR1(codelist, i);
-            if (code == CLOSEPOLY)
-            {
-                CGContextClosePath(cr);
-                i++;
-            }
-            else if (code == STOP)
-            {
-                break;
-            }
-            else if (was_nan)
-            {
-                if (code==CURVE3) i++;
-                else if (code==CURVE4) i+=2;
-                x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
-                y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
-                i++;
-                if (isnan(x1) || isnan(y1))
-                {
-                    was_nan = true;
-                }
-                else
-                {
-                    point.x = x1;
-                    point.y = y1;
-                    point = CGPointApplyAffineTransform(point, affine);
-                    CGContextMoveToPoint(cr, point.x, point.y);
-                    was_nan = false;
-                }
-            }
-            else if (code==MOVETO)
-            {
-                x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
-                y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
-                i++;
-                if (isnan(x1) || isnan(y1))
-                {
-                    was_nan = true;
-                }
-                else
-                {
-                    point.x = x1;
-                    point.y = y1;
-                    point = CGPointApplyAffineTransform(point, affine);
-                    CGContextMoveToPoint(cr, point.x, point.y);
-                    was_nan = false;
-                }
-            }
-            else if (code==LINETO)
-            {
-                x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
-                y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
-                i++;
-                if (isnan(x1) || isnan(y1))
-                {
-                    was_nan = true;
-                }
-                else
-                {
-                    point.x = x1;
-                    point.y = y1;
-                    point = CGPointApplyAffineTransform(point, affine);
-                    CGContextAddLineToPoint(cr, point.x, point.y);
-                    was_nan = false;
-                }
-            }
-            else if (code==CURVE3)
-            {
-                x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
-                y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
-                i++;
-                x2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
-                y2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
-                i++;
-                if (isnan(x1) || isnan(y1) || isnan(x2) || isnan(y2))
-                {
-                    was_nan = true;
-                }
-                else
-                {
-                    point.x = x1;
-                    point.y = y1;
-                    point = CGPointApplyAffineTransform(point, affine);
-                    x1 = point.x;
-                    y1 = point.y;
-                    point.x = x2;
-                    point.y = y2;
-                    point = CGPointApplyAffineTransform(point, affine);
-                    x2 = point.x;
-                    y2 = point.y;
-                    CGContextAddQuadCurveToPoint(cr, x1, y1, x2, y2);
-                    was_nan = false;
-                }
-            }
-            else if (code==CURVE4)
-            {
-                x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
-                y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
-                i++;
-                x2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
-                y2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
-                i++;
-                x3 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
-                y3 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
-                i++;
-                if (isnan(x1) || isnan(y1) || isnan(x2) || isnan(y2) || 
isnan(x3) || isnan(y3))
-                {
-                    was_nan = true;
-                }
-                else
-                {
-                    point.x = x1;
-                    point.y = y1;
-                    point = CGPointApplyAffineTransform(point, affine);
-                    x1 = point.x;
-                    y1 = point.y;
-                    point.x = x2;
-                    point.y = y2;
-                    point = CGPointApplyAffineTransform(point, affine);
-                    x2 = point.x;
-                    y2 = point.y;
-                    point.x = x3;
-                    point.y = y3;
-                    point = CGPointApplyAffineTransform(point, affine);
-                    x3 = point.x;
-                    y3 = point.y;
-                    CGContextAddCurveToPoint(cr, x1, y1, x2, y2, x3, y3);
-                    was_nan = false;
-                }
-            }
-        }
-    }
-
-    Py_DECREF(coordinates);
-    Py_XDECREF(codelist);
-    return n;
-}
-
 static PyObject*
 GraphicsContext_draw_path (GraphicsContext* self, PyObject* args)
 {
@@ -1230,6 +1142,7 @@
     
     if (n > 0)
     {
+        PyObject* hatchpath;
         if(rgbFace)
         {
             float r, g, b;
@@ -1239,22 +1152,60 @@
                 return NULL;
             }
             CGContextSaveGState(cr);
-            if(self->pattern)
-            {
-                float components[4];
-                components[0] = r;
-                components[1] = g;
-                components[2] = b;
-                components[3] = 1.0;
-                CGContextSetFillPattern(cr, self->pattern, components);
-                CGPatternRelease(self->pattern);
-                self->pattern = nil;
-            }
-            else CGContextSetRGBFillColor(cr, r, g, b, 1.0);
+            CGContextSetRGBFillColor(cr, r, g, b, 1.0);
             CGContextDrawPath(cr, kCGPathFillStroke);
             CGContextRestoreGState(cr);
         }
         else CGContextStrokePath(cr);
+
+        hatchpath = PyObject_CallMethod((PyObject*)self, "get_hatch_path", "");
+        if (!hatchpath)
+        {
+            return NULL;
+        }
+        else if (hatchpath==Py_None)
+        {
+            Py_DECREF(hatchpath);
+        }
+        else
+        {
+            float color[4] = {0, 0, 0, 1};
+            CGPatternRef pattern;
+            static const CGPatternCallbacks callbacks = {0,
+                                                         &_draw_hatch,
+                                                         &_release_hatch};
+            PyObject* rgb = PyObject_CallMethod((PyObject*)self, "get_rgb", 
"");
+            if (!rgb)
+            {
+                Py_DECREF(hatchpath);
+                return NULL;
+            }
+            ok = PyArg_ParseTuple(rgb, "ffff", &color[0], &color[1], 
&color[2], &color[3]);
+            Py_DECREF(rgb);
+            if (!ok)
+            {
+                Py_DECREF(hatchpath);
+                return NULL;
+            }
+
+            CGColorSpaceRef baseSpace = 
CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+            CGColorSpaceRef patternSpace = 
CGColorSpaceCreatePattern(baseSpace);
+            CGColorSpaceRelease(baseSpace);
+            CGContextSetFillColorSpace(cr, patternSpace);
+            CGColorSpaceRelease(patternSpace);
+
+            pattern = CGPatternCreate((void*)hatchpath,
+                                      CGRectMake(0, 0, HATCH_SIZE, HATCH_SIZE),
+                                      CGAffineTransformIdentity,
+                                      HATCH_SIZE, HATCH_SIZE,
+                                      kCGPatternTilingNoDistortion,
+                                      false,
+                                      &callbacks);
+            CGContextSetFillPattern(cr, pattern, color);
+            CGPatternRelease(pattern);
+            _draw_path(cr, path, affine);
+            CGContextFillPath(cr);
+        }
     }
 
     Py_INCREF(Py_None);
@@ -1297,18 +1248,7 @@
         {
             return NULL;
         }
-        if(self->pattern)
-        {
-            float components[4];
-            components[0] = r;
-            components[1] = g;
-            components[2] = b;
-            components[3] = 1.0;
-            CGContextSetFillPattern(cr, self->pattern, components);
-            CGPatternRelease(self->pattern);
-            self->pattern = nil;
-        }
-        else CGContextSetRGBFillColor(cr, r, g, b, 1.0);
+        CGContextSetRGBFillColor(cr, r, g, b, 1.0);
     }
 
     CGAffineTransform affine;
@@ -2516,7 +2456,7 @@
     const size_t nComponents = 4; /* red, green, blue, alpha */
     const size_t bitsPerPixel = bitsPerComponent * nComponents;
     const size_t bytesPerRow = nComponents * bytesPerComponent * ncols;
-    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
+    CGColorSpaceRef colorspace = 
CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
 
     Py_INCREF(image);
     n = PyString_GET_SIZE(image);
@@ -2627,22 +2567,6 @@
      METH_VARARGS,
      "Sets the current stroke and fill color to a value in the DeviceGray 
color space."
     },
-    {"set_hatch",
-     (PyCFunction)GraphicsContext_set_hatch,
-     METH_VARARGS,
-     "\n"
-     "  hatch can be one of:\n"
-     "  /   - diagonal hatching\n"
-     "  \\   - back diagonal\n"
-     "  |   - vertical\n"
-     "  -   - horizontal\n"
-     "  #   - crossed\n"
-     "  X   - crossed diagonal\n"
-     "  letters can be combined, in which case all the specified\n"
-     "  hatchings are done\n"
-     "  if same letter repeats, it increases the density of hatching\n"
-     "  in that direction\n"
-    },
     {"set_linewidth",
      (PyCFunction)GraphicsContext_set_linewidth,
      METH_VARARGS,


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It is the best place to buy or sell services for
just about anything Open Source.
http://p.sf.net/sfu/Xq1LFB
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to