@@ -240,11 +240,15 @@ static void _dealloc_atsui(void)
240
240
}
241
241
#endif
242
242
243
- static int _draw_path (CGContextRef cr, void * iterator)
243
+ static int _draw_path (CGContextRef cr, void * iterator, int nmax )
244
244
{
245
245
double x1, y1 , x2, y2, x3, y3;
246
+ static unsigned code = STOP;
247
+ static double xs, ys;
248
+ CGPoint current;
246
249
int n = 0 ;
247
- unsigned code;
250
+
251
+ if (code == MOVETO) CGContextMoveToPoint (cr, xs, ys);
248
252
249
253
while (true )
250
254
{
@@ -261,7 +265,6 @@ static int _draw_path(CGContextRef cr, void* iterator)
261
265
else if (code == MOVETO)
262
266
{
263
267
CGContextMoveToPoint (cr, x1, y1 );
264
- n++;
265
268
}
266
269
else if (code==LINETO)
267
270
{
@@ -270,31 +273,50 @@ static int _draw_path(CGContextRef cr, void* iterator)
270
273
}
271
274
else if (code==CURVE3)
272
275
{
273
- get_vertex (iterator, &x2 , &y2 );
274
- CGContextAddQuadCurveToPoint (cr, x1, y1 , x2, y2 );
276
+ get_vertex (iterator, &xs , &ys );
277
+ CGContextAddQuadCurveToPoint (cr, x1, y1 , xs, ys );
275
278
n+=2 ;
276
279
}
277
280
else if (code==CURVE4)
278
281
{
279
282
get_vertex (iterator, &x2, &y2);
280
- get_vertex (iterator, &x3 , &y3 );
281
- CGContextAddCurveToPoint (cr, x1, y1 , x2, y2, x3, y3 );
283
+ get_vertex (iterator, &xs , &ys );
284
+ CGContextAddCurveToPoint (cr, x1, y1 , x2, y2, xs, ys );
282
285
n+=3 ;
283
286
}
287
+ if (n >= nmax)
288
+ {
289
+ switch (code)
290
+ {
291
+ case MOVETO:
292
+ case LINETO:
293
+ xs = x1;
294
+ ys = y1 ;
295
+ break ;
296
+ case CLOSEPOLY:
297
+ current = CGContextGetPathCurrentPoint (cr);
298
+ xs = current.x ;
299
+ ys = current.y ;
300
+ break ;
301
+ /* nothing needed for CURVE3, CURVE4 */
302
+ }
303
+ code = MOVETO;
304
+ return -n;
305
+ }
284
306
}
285
307
return n;
286
308
}
287
309
288
310
static void _draw_hatch (void *info, CGContextRef cr)
289
311
{
312
+ int n;
290
313
PyObject* hatchpath = (PyObject*)info;
291
314
PyObject* transform;
292
315
int nd = 2 ;
293
316
npy_intp dims[2 ] = {3 , 3 };
294
317
int typenum = NPY_DOUBLE;
295
318
double data[9 ] = {HATCH_SIZE, 0 , 0 , 0 , HATCH_SIZE, 0 , 0 , 0 , 1 };
296
319
double rect[4 ] = { 0.0 , 0.0 , HATCH_SIZE, HATCH_SIZE};
297
- int n;
298
320
transform = PyArray_SimpleNewFromData (nd, dims, typenum, data);
299
321
if (!transform)
300
322
{
@@ -320,7 +342,7 @@ static void _draw_hatch(void *info, CGContextRef cr)
320
342
PyGILState_Release (gstate);
321
343
return ;
322
344
}
323
- n = _draw_path (cr, iterator);
345
+ n = _draw_path (cr, iterator, INT_MAX );
324
346
free_path_iterator (iterator);
325
347
if (n==0 ) return ;
326
348
CGContextSetLineWidth (cr, 1.0 );
@@ -702,7 +724,7 @@ static int _get_snap(GraphicsContext* self, enum e_snap_mode* mode)
702
724
" set_clip_path: failed to obtain path iterator for clipping" );
703
725
return NULL ;
704
726
}
705
- n = _draw_path (cr, iterator);
727
+ n = _draw_path (cr, iterator, INT_MAX );
706
728
free_path_iterator (iterator);
707
729
708
730
if (n > 0 ) CGContextClip (cr);
@@ -952,89 +974,98 @@ static int _get_snap(GraphicsContext* self, enum e_snap_mode* mode)
952
974
" draw_path: failed to obtain path iterator" );
953
975
return NULL ;
954
976
}
955
- n = _draw_path (cr, iterator);
956
- free_path_iterator (iterator);
957
977
958
- if (n > 0 )
978
+ if (rgbFace )
959
979
{
960
- PyObject* hatchpath;
961
- if (rgbFace)
980
+ float r, g, b;
981
+ if (!PyArg_ParseTuple (rgbFace, " fff" , &r, &g, &b))
982
+ return NULL ;
983
+ n = _draw_path (cr, iterator, INT_MAX);
984
+ if (n > 0 )
962
985
{
963
- float r, g, b;
964
- if (!PyArg_ParseTuple (rgbFace, " fff" , &r, &g, &b))
965
- return NULL ;
966
986
CGContextSaveGState (cr);
967
987
CGContextSetRGBFillColor (cr, r, g, b, 1.0 );
968
988
CGContextDrawPath (cr, kCGPathFillStroke );
969
989
CGContextRestoreGState (cr);
970
990
}
971
- else CGContextStrokePath (cr);
991
+ }
992
+ else
993
+ {
994
+ const int nmax = 100 ;
995
+ while (true )
996
+ {
997
+ n = _draw_path (cr, iterator, nmax);
998
+ if (n != 0 ) CGContextStrokePath (cr);
999
+ if (n >= 0 ) break ;
1000
+ }
1001
+ }
1002
+ free_path_iterator (iterator);
972
1003
973
- hatchpath = PyObject_CallMethod ((PyObject*)self, " get_hatch_path" , " " );
974
- if (!hatchpath)
1004
+ PyObject* hatchpath;
1005
+ hatchpath = PyObject_CallMethod ((PyObject*)self, " get_hatch_path" , " " );
1006
+ if (!hatchpath)
1007
+ {
1008
+ return NULL ;
1009
+ }
1010
+ else if (hatchpath==Py_None)
1011
+ {
1012
+ Py_DECREF (hatchpath);
1013
+ }
1014
+ else
1015
+ {
1016
+ CGPatternRef pattern;
1017
+ CGColorSpaceRef baseSpace;
1018
+ CGColorSpaceRef patternSpace;
1019
+ static const CGPatternCallbacks callbacks = {0 ,
1020
+ &_draw_hatch,
1021
+ &_release_hatch};
1022
+ baseSpace = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB );
1023
+ if (!baseSpace)
975
1024
{
1025
+ Py_DECREF (hatchpath);
1026
+ PyErr_SetString (PyExc_RuntimeError,
1027
+ " draw_path: CGColorSpaceCreateWithName failed" );
976
1028
return NULL ;
977
1029
}
978
- else if (hatchpath==Py_None)
1030
+ patternSpace = CGColorSpaceCreatePattern (baseSpace);
1031
+ CGColorSpaceRelease (baseSpace);
1032
+ if (!patternSpace)
979
1033
{
980
1034
Py_DECREF (hatchpath);
1035
+ PyErr_SetString (PyExc_RuntimeError,
1036
+ " draw_path: CGColorSpaceCreatePattern failed" );
1037
+ return NULL ;
981
1038
}
982
- else
1039
+ CGContextSetFillColorSpace (cr, patternSpace);
1040
+ CGColorSpaceRelease (patternSpace);
1041
+
1042
+ pattern = CGPatternCreate ((void *)hatchpath,
1043
+ CGRectMake (0 , 0 , HATCH_SIZE, HATCH_SIZE),
1044
+ CGAffineTransformIdentity ,
1045
+ HATCH_SIZE, HATCH_SIZE,
1046
+ kCGPatternTilingNoDistortion ,
1047
+ false ,
1048
+ &callbacks);
1049
+ CGContextSetFillPattern (cr, pattern, self->color );
1050
+ CGPatternRelease (pattern);
1051
+ iterator = get_path_iterator (path,
1052
+ transform,
1053
+ 1 ,
1054
+ 0 ,
1055
+ rect,
1056
+ SNAP_AUTO,
1057
+ linewidth,
1058
+ 0 );
1059
+ if (!iterator)
983
1060
{
984
- CGPatternRef pattern;
985
- CGColorSpaceRef baseSpace;
986
- CGColorSpaceRef patternSpace;
987
- static const CGPatternCallbacks callbacks = {0 ,
988
- &_draw_hatch,
989
- &_release_hatch};
990
- baseSpace = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB );
991
- if (!baseSpace)
992
- {
993
- Py_DECREF (hatchpath);
994
- PyErr_SetString (PyExc_RuntimeError,
995
- " draw_path: CGColorSpaceCreateWithName failed" );
996
- return NULL ;
997
- }
998
- patternSpace = CGColorSpaceCreatePattern (baseSpace);
999
- CGColorSpaceRelease (baseSpace);
1000
- if (!patternSpace)
1001
- {
1002
- Py_DECREF (hatchpath);
1003
- PyErr_SetString (PyExc_RuntimeError,
1004
- " draw_path: CGColorSpaceCreatePattern failed" );
1005
- return NULL ;
1006
- }
1007
- CGContextSetFillColorSpace (cr, patternSpace);
1008
- CGColorSpaceRelease (patternSpace);
1009
-
1010
- pattern = CGPatternCreate ((void *)hatchpath,
1011
- CGRectMake (0 , 0 , HATCH_SIZE, HATCH_SIZE),
1012
- CGAffineTransformIdentity ,
1013
- HATCH_SIZE, HATCH_SIZE,
1014
- kCGPatternTilingNoDistortion ,
1015
- false ,
1016
- &callbacks);
1017
- CGContextSetFillPattern (cr, pattern, self->color );
1018
- CGPatternRelease (pattern);
1019
- iterator = get_path_iterator (path,
1020
- transform,
1021
- 1 ,
1022
- 0 ,
1023
- rect,
1024
- SNAP_AUTO,
1025
- linewidth,
1026
- 0 );
1027
- if (!iterator)
1028
- {
1029
- Py_DECREF (hatchpath);
1030
- PyErr_SetString (PyExc_RuntimeError,
1031
- " draw_path: failed to obtain path iterator for hatching" );
1032
- return NULL ;
1033
- }
1034
- n = _draw_path (cr, iterator);
1035
- free_path_iterator (iterator);
1036
- CGContextFillPath (cr);
1061
+ Py_DECREF (hatchpath);
1062
+ PyErr_SetString (PyExc_RuntimeError,
1063
+ " draw_path: failed to obtain path iterator for hatching" );
1064
+ return NULL ;
1037
1065
}
1066
+ n = _draw_path (cr, iterator, INT_MAX);
1067
+ free_path_iterator (iterator);
1068
+ if (n > 0 ) CGContextFillPath (cr);
1038
1069
}
1039
1070
1040
1071
Py_INCREF (Py_None);
0 commit comments