Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

John Baughman

macrumors regular
Original poster
Oct 27, 2003
100
0
I asked this question differently in the iPhone programming forum without any answer.

I have a path that I am stroking with a dashed line set to a width of 2. If I fill the path with either a solid fill or with a linear gradient I lose the dashed line of the path.

How can I fill the path and still see the stroked line?

Code:
CGContextBeginPath(context);
.
.
    //create the path
.
.
CGContextClosePath(context);

[[UIColor colorWithRed:0.808 green:0.58 blue:0.255 alpha:1.0] setFill];
CGContextFillPath(context);

[[UIColor blackColor] setStroke];
CGContextSetLineWidth(context, 2.0);
CGFloat dash1[] = {5.0, 2.0};
CGContextSetLineDash(context, 0.0, dash1, 2);	

CGContextStrokePath(context);
 

mdeh

macrumors 6502
Jan 3, 2009
345
2
I have a path that I am stroking with a dashed line ...... If I fill the path with either a solid fill or with a linear gradient I lose the dashed line of the path.

How can I fill the path and still see the stroked line?


Have you tried doing the fill first, then the dashed line?
 

Catfish_Man

macrumors 68030
Sep 13, 2001
2,579
2
Portland, OR
Offhand that looks fine to me. Not sure what's going wrong. Try making your lengths and widths really big so it's extremely obvious when you get it drawing? :)
 

John Baughman

macrumors regular
Original poster
Oct 27, 2003
100
0
Offhand that looks fine to me. Not sure what's going wrong. Try making your lengths and widths really big so it's extremely obvious when you get it drawing? :)

Yes I had done that, set it to 10. Shifting back and forth between filled and not filled you can see that the fill is overlapping where the line should be. In other words the fill fills out to the outer edge of the path line.

Same thing with the linear gradient where the clip clips out to the outer edge of the path line.
 

John Baughman

macrumors regular
Original poster
Oct 27, 2003
100
0
Ok I figured out a solution to the problem with regard to the fill. The path line will be display if I use

CGContextDrawPath(context, kCGPathFillStroke);

instead of...

CGContextStrokePath(context);

Still cannot figure out the gradient fill. CGContextDrawLinearGradient does not have an option similar to kCGPathFillStroke. Here is what my code looks like for a gradient fill...

Code:
CGGradientRef gradientFill;
CGColorSpaceRef colorSpace;
size_t num_locations = 2;
CGFloat locations[2] = { 0.0, 1.0 };
CGFloat components[8] = { 0.95, 0.30, 0.30, 1.0,  // Start color
		0.93, 0.94, 0.30, 1.0 }; // End color
		
colorSpace = CGColorSpaceCreateDeviceRGB();
gradientFill = CGGradientCreateWithColorComponents (colorSpace, components,											 locations, num_locations);

CGPoint myStartPoint, myEndPoint;
myStartPoint.x = 0.0; //gradientXStart-20;
myStartPoint.y = rect.size.height / 2.0;
myEndPoint.x = rect.size.width; //gradientXEnd+20;
myEndPoint.y = rect.size.height / 2.0;
		
[[UIColor blackColor] setStroke];
CGContextSetLineWidth(context, 2.0);
if(border.selectedSegmentIndex	== 1){
	CGContextSetLineDash(context, 0.0, dash1, 2);
			
}

CGContextClip(context);		
CGContextDrawLinearGradient (context, gradientFill, myStartPoint, myEndPoint, 0);
CGColorSpaceRelease(colorSpace);

//CGContextStrokePath(context);
//CGContextDrawPath(context, kCGPathFillStroke);

I tried using both CGContextStrokePath and CGContextDrawPath and neither gives me the line path.

I did just learn that I can leave out a path draw or stroke command and still get the polygon, which I assume is just the gradient in the clipped polygon. I would have thought that then calling the draw or stroke path command would draw the path over the gradient giving it the border I am looking for.
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
I would use CGPaths instead of manipulating the path directly on the context.

Here's how I did it (you'll obviously want to modify the path, and replace the NS* classes with the UI* ones.):

Code:
// create the path
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 10.0, 10.0);
CGPathAddLineToPoint(path, NULL, 100.0, 10.0);
CGPathAddLineToPoint(path, NULL, 100.0, 100.0);
CGPathAddLineToPoint(path, NULL, 10.0, 100.0);
CGPathAddLineToPoint(path, NULL, 10.0, 10.0);

// setup the gradient
CGFloat locations[2] = { 0.0, 1.0 };
CGFloat components[8] = {
	0.95, 0.30, 0.30, 1.0,  // Start color
	0.93, 0.94, 0.30, 1.0	// End color
};
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradientFill = CGGradientCreateWithColorComponents (colorSpace, components, locations, 2);

// setup gradient points
CGRect pathRect = CGPathGetBoundingBox(path);
CGPoint myStartPoint, myEndPoint;
myStartPoint.x = CGRectGetMinX(pathRect);
myStartPoint.y = CGRectGetMinY(pathRect);
myEndPoint.x = CGRectGetMaxX(pathRect);
myEndPoint.y = CGRectGetMinY(pathRect);

// draw the gradient
CGContextAddPath(context, path);
CGContextSaveGState(context);
CGContextClip(context);
CGContextDrawLinearGradient (context, gradientFill, myStartPoint, myEndPoint, 0);
CGContextRestoreGState(context);

// draw the dash
CGContextAddPath(context, path);
[[NSColor blackColor] setStroke];
CGContextSetLineWidth(context, 2.0);
CGFloat dash1[] = {5.0, 2.0};
CGContextSetLineDash(context, 0.0, dash1, 2);
CGContextStrokePath(context);

// cleanup
CGColorSpaceRelease(colorSpace);
CGGradientRelease(gradientFill);
CGPathRelease(path);

The key is to use CGContextAddPath() which adds the path back onto the context. I guess CG removes it after a fill/stroke.

Here's how it looks (draw inside an OS X window):

path.png
 

John Baughman

macrumors regular
Original poster
Oct 27, 2003
100
0
I would use CGPaths instead of manipulating the path directly on the context.
... snip
The key is to use CGContextAddPath() which adds the path back onto the context. I guess CG removes it after a fill/stroke.

View attachment 197106

Fantastic. That looks great. I looked at CGContextAddPath but did not recognize that with it I could add paths to a context created as CGPaths outside of a context. Good stuff.

A quick question. Why do you save the state before you clip and draw the gradient. What is actually being done when you save and restore a context's state? That is really fuzzy to me.

Thanks,

John
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
A quick question. Why do you save the state before you clip and draw the gradient. What is actually being done when you save and restore a context's state? That is really fuzzy to me.

Usually saving/restoring the graphics state is done when you're clipping, adding a shadow or affine transformation, or other things that affect subsequent draws. More info at Graphics Contexts (see the Graphics State Information section).

So in this case, I save/restore it before drawing the dashed line, because the dashed line would be clipped also. Stroked paths are drawn centered on the path, not inside or outside it. If you remove those save/restore calls, you'll see what I mean when the path is stroked.
 

vtata

macrumors newbie
Apr 26, 2013
1
0
I asked this question differently in the iPhone programming forum without any answer.

I have a path that I am stroking with a dashed line set to a width of 2. If I fill the path with either a solid fill or with a linear gradient I lose the dashed line of the path.

How can I fill the path and still see the stroked line?

Code:
CGContextBeginPath(context);
.
.
    //create the path
.
.
CGContextClosePath(context);

[[UIColor colorWithRed:0.808 green:0.58 blue:0.255 alpha:1.0] setFill];
CGContextFillPath(context);

[[UIColor blackColor] setStroke];
CGContextSetLineWidth(context, 2.0);
CGFloat dash1[] = {5.0, 2.0};
CGContextSetLineDash(context, 0.0, dash1, 2);	

CGContextStrokePath(context);




How can I draw a gradient line on iPad.
Can any one please help me .
Thanks in advance.
 

gnasher729

Suspended
Nov 25, 2005
17,980
5,565
How can I draw a gradient line on iPad.
Can any one please help me .
Thanks in advance.

Apple can help you.

Start Xcode. Press Command-Shift-2. Click on "Documentation". Enter "gradient" in the search box.
 

xStep

macrumors 68020
Jan 28, 2003
2,031
143
Less lost in L.A.
How can I draw a gradient line on iPad.
Can any one please help me .
Thanks in advance.

You start by doing some research on gradients.

Next, when posting a more descriptive question to MR, you begin a new thread. Hijacking an old one for what is an unrelated question is not good etiquette.

When you come back to post your question, state what you have tried and your intended end goal.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.