From: <jd...@us...> - 2009-01-10 20:04:03
|
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. |