iphone - Clipping a CGGradient to a CGPath -


i've been banging head against wall long while trying figure out why not working.

basically, trying plot graph (chart) cgpath , use clip gradient. end effect should stocks app comes iphone.

the gradient , path draw fine separately 2 layered (unclipped) elements. if comment out cgcontextdrawpath, neither line nor gradient draw screen.

here's drawrect code:

cgcontextref context = uigraphicsgetcurrentcontext();  [[uicolor whitecolor] set]; cgcontextsetlinewidth(context, 2.0f); cgpoint lastdrawnpt = [[points objectatindex:0] cgpointvalue]; cgpoint firstdrawnpt = lastdrawnpt; //create path gradient cgmutablepathref thepath = cgpathcreatemutable(); cgpathmovetopoint(thepath, null, lastdrawnpt.x, self.bounds.size.height); // bottom left cgpathaddlinetopoint(thepath, null, lastdrawnpt.x, lastdrawnpt.y);   (int i=0; i<(points.count-1); i++) {     //cgpoint pt1 = [[points objectatindex:i] cgpointvalue];     cgpoint pt2 = [[points objectatindex:i+1] cgpointvalue];     if (pt2.x > lastdrawnpt.x+2) {         // draw if we've moved sunstantially right          //for gradient         cgpathmovetopoint(thepath, null, lastdrawnpt.x, lastdrawnpt.y);         cgpathaddlinetopoint(thepath, null, pt2.x, pt2.y);           lastdrawnpt = pt2;     } }  //finish gradient clipping path cgpathmovetopoint(thepath, null, lastdrawnpt.x, lastdrawnpt.y); cgpathaddlinetopoint(thepath, null, lastdrawnpt.x, self.bounds.size.height); // bottom right cgpathmovetopoint(thepath, null, lastdrawnpt.x, self.bounds.size.height); cgpathaddlinetopoint(thepath, null, firstdrawnpt.x, self.bounds.size.height); // bottom right  cgpathclosesubpath(thepath);  //add gradient clipping path context cgcontextsavegstate(context); cgcontextaddpath(context, thepath);  //draw path float components[4] = {1.0, 1.0, 1.0, 1.0}; cgcontextsetstrokecolor(context, components); cgcontextdrawpath(context,kcgpathstroke);  //clip path cgcontextclip(context);   //draw gradient uicolor *topcolor = [uicolor colorwithred: 1.0 green:1.0 blue:1.0 alpha:1.0]; uicolor *bottomcolor = [uicolor colorwithred:1.0 green:1.0 blue:1.0 alpha:0.0]; cgcolorref colorref[] = { [topcolor cgcolor], [bottomcolor cgcolor] }; cfarrayref colors = cfarraycreate(null, (const void**)colorref, sizeof(colorref) / sizeof(cgcolorref), &kcftypearraycallbacks);  cgcolorspaceref colorspace = cgcolorspacecreatedevicergb(); cggradientref gradient = cggradientcreatewithcolors(colorspace, colors, null); cfrelease(colorspace); cfrelease(colors);  //  draw linear gradient top bottom cgpoint gradstartpoint = cgpointmake(50.0, self.bounds.size.height); cgpoint gradendpoint = cgpointmake(50.0, 0.0); cgcontextdrawlineargradient(context, gradient, gradstartpoint, gradendpoint, 0);  cfrelease(gradient);  // cleanup cgcolorspacerelease(colorspace);  cgcontextrestoregstate(context); 

cgpathmovetopoint(thepath, null, lastdrawnpt.x, self.bounds.size.height); // bottom left cgpathaddlinetopoint(thepath, null, lastdrawnpt.x, lastdrawnpt.y);   (int i=0; i<(points.count-1); i++) {     //cgpoint pt1 = [[points objectatindex:i] cgpointvalue];     cgpoint pt2 = [[points objectatindex:i+1] cgpointvalue];     if (pt2.x > lastdrawnpt.x+2) {         // draw if we've moved sunstantially right          //for gradient         cgpathmovetopoint(thepath, null, lastdrawnpt.x, lastdrawnpt.y);         cgpathaddlinetopoint(thepath, null, pt2.x, pt2.y);           lastdrawnpt = pt2;     } }  //finish gradient clipping path cgpathmovetopoint(thepath, null, lastdrawnpt.x, lastdrawnpt.y); cgpathaddlinetopoint(thepath, null, lastdrawnpt.x, self.bounds.size.height); // bottom right cgpathmovetopoint(thepath, null, lastdrawnpt.x, self.bounds.size.height); cgpathaddlinetopoint(thepath, null, firstdrawnpt.x, self.bounds.size.height); // bottom right 

this plots series of line segments. point values, might this:

| |||| | 

it not plot single continuous shape. such, path useless clipping, empty; you've seen, clipping result in no further drawing being inside clipping path.

every lineto, curveto, arc, etc. works current point. set initially moveto, each lineto, curveto, arc, etc. not clear current point, updates it. thus, create single shape, 1 moveto followed succession of lineto (or curveto or arc), followed closepath.

speaking of closepath

cgpathclosesubpath(thepath); 

this creates closed shape in path, since shape has 0 area (being only line segment doubles on itself), still not helpful clipping purposes.

i suspect need cut out @ least 1 of moveto segments (the 1 in loop, if not 1 after it). then, can simplify loop—use fast enumeration on array, instead of using indexes, , cut out keeping track of “last drawn point”.

also, correct type indexes nsarray nsuinteger, not int. keep types matched—it avoids pain later down road.


Comments

Popular posts from this blog

java - SNMP4J General Variable Binding Error -

windows - Python Service Installation - "Could not find PythonClass entry" -

Determine if a XmlNode is empty or null in C#? -