Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit baaf1f4

Browse filesBrowse files
committed
Merge pull request #1816 from mdehoon/master
Avoid macosx backend slowdown; issue 1563
2 parents 5a7cb7f + 8ec89ce commit baaf1f4
Copy full SHA for baaf1f4

File tree

Expand file treeCollapse file tree

1 file changed

+107
-76
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+107
-76
lines changed

‎src/_macosx.m

Copy file name to clipboardExpand all lines: src/_macosx.m
+107-76Lines changed: 107 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -240,11 +240,15 @@ static void _dealloc_atsui(void)
240240
}
241241
#endif
242242

243-
static int _draw_path(CGContextRef cr, void* iterator)
243+
static int _draw_path(CGContextRef cr, void* iterator, int nmax)
244244
{
245245
double x1, y1, x2, y2, x3, y3;
246+
static unsigned code = STOP;
247+
static double xs, ys;
248+
CGPoint current;
246249
int n = 0;
247-
unsigned code;
250+
251+
if (code == MOVETO) CGContextMoveToPoint(cr, xs, ys);
248252

249253
while (true)
250254
{
@@ -261,7 +265,6 @@ static int _draw_path(CGContextRef cr, void* iterator)
261265
else if (code == MOVETO)
262266
{
263267
CGContextMoveToPoint(cr, x1, y1);
264-
n++;
265268
}
266269
else if (code==LINETO)
267270
{
@@ -270,31 +273,50 @@ static int _draw_path(CGContextRef cr, void* iterator)
270273
}
271274
else if (code==CURVE3)
272275
{
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);
275278
n+=2;
276279
}
277280
else if (code==CURVE4)
278281
{
279282
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);
282285
n+=3;
283286
}
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+
}
284306
}
285307
return n;
286308
}
287309

288310
static void _draw_hatch(void *info, CGContextRef cr)
289311
{
312+
int n;
290313
PyObject* hatchpath = (PyObject*)info;
291314
PyObject* transform;
292315
int nd = 2;
293316
npy_intp dims[2] = {3, 3};
294317
int typenum = NPY_DOUBLE;
295318
double data[9] = {HATCH_SIZE, 0, 0, 0, HATCH_SIZE, 0, 0, 0, 1};
296319
double rect[4] = { 0.0, 0.0, HATCH_SIZE, HATCH_SIZE};
297-
int n;
298320
transform = PyArray_SimpleNewFromData(nd, dims, typenum, data);
299321
if (!transform)
300322
{
@@ -320,7 +342,7 @@ static void _draw_hatch(void *info, CGContextRef cr)
320342
PyGILState_Release(gstate);
321343
return;
322344
}
323-
n = _draw_path(cr, iterator);
345+
n = _draw_path(cr, iterator, INT_MAX);
324346
free_path_iterator(iterator);
325347
if (n==0) return;
326348
CGContextSetLineWidth(cr, 1.0);
@@ -702,7 +724,7 @@ static int _get_snap(GraphicsContext* self, enum e_snap_mode* mode)
702724
"set_clip_path: failed to obtain path iterator for clipping");
703725
return NULL;
704726
}
705-
n = _draw_path(cr, iterator);
727+
n = _draw_path(cr, iterator, INT_MAX);
706728
free_path_iterator(iterator);
707729

708730
if (n > 0) CGContextClip(cr);
@@ -952,89 +974,98 @@ static int _get_snap(GraphicsContext* self, enum e_snap_mode* mode)
952974
"draw_path: failed to obtain path iterator");
953975
return NULL;
954976
}
955-
n = _draw_path(cr, iterator);
956-
free_path_iterator(iterator);
957977

958-
if (n > 0)
978+
if(rgbFace)
959979
{
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)
962985
{
963-
float r, g, b;
964-
if (!PyArg_ParseTuple(rgbFace, "fff", &r, &g, &b))
965-
return NULL;
966986
CGContextSaveGState(cr);
967987
CGContextSetRGBFillColor(cr, r, g, b, 1.0);
968988
CGContextDrawPath(cr, kCGPathFillStroke);
969989
CGContextRestoreGState(cr);
970990
}
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);
9721003

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)
9751024
{
1025+
Py_DECREF(hatchpath);
1026+
PyErr_SetString(PyExc_RuntimeError,
1027+
"draw_path: CGColorSpaceCreateWithName failed");
9761028
return NULL;
9771029
}
978-
else if (hatchpath==Py_None)
1030+
patternSpace = CGColorSpaceCreatePattern(baseSpace);
1031+
CGColorSpaceRelease(baseSpace);
1032+
if (!patternSpace)
9791033
{
9801034
Py_DECREF(hatchpath);
1035+
PyErr_SetString(PyExc_RuntimeError,
1036+
"draw_path: CGColorSpaceCreatePattern failed");
1037+
return NULL;
9811038
}
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)
9831060
{
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;
10371065
}
1066+
n = _draw_path(cr, iterator, INT_MAX);
1067+
free_path_iterator(iterator);
1068+
if (n > 0) CGContextFillPath(cr);
10381069
}
10391070

10401071
Py_INCREF(Py_None);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.