13

With CGContextSetLineWidth(context, 1) the width is almost alwayas at least 2 pixels instead 1

QQCandleStickLayer.m

-(id)init
{
    self = [super init];
    if(self != nil)
    {       
        self.delegate = self;       
        self.opaque = NO;       
    }
    return self;
}

- (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context{

    CGContextSetLineWidth(context, 1.0f);
    CGContextSetAllowsAntialiasing(context, false);
    CGContextSetShouldAntialias(context, false);
    CGContextSetInterpolationQuality(context,kCGInterpolationNone);
    CGContextSetShadowWithColor(context, CGSizeMake( 0.0, 0.0 ), 0, NULL);


    CGContextMoveToPoint(context, self.bounds.origin.x+30.5f, self.bounds.origin.y+self.bounds.size.height-indent);
    CGContextAddLineToPoint(context, self.bounds.origin.x+30.5f, self.bounds.origin.y+self.bounds.size.height-(self.bounds.size.height-lastY)); 
    CGContextClosePath(context);
    CGContextSetRGBStrokeColor(context, 119.0f/255, 119.0f/255, 119.0f/255, 1.0);
    CGContextStrokePath(context);
}

QQDefluviumLayer.m

- (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context{  
    UIImage *myDefluvium = [UIImage imageNamed:@"delfluviumNewRotatedSmall.png"];
    CGLayerRef layerCircle = CGLayerCreateWithContext(context, myDefluvium.size,NULL);
    if (layerCircle)
    {
        CGContextRef layerContext = CGLayerGetContext(layerCircle);
        CGContextDrawImage(layerContext, (CGRect){ CGPointZero, myDefluvium.size }, myDefluvium.CGImage);       
        CGContextDrawLayerInRect(context, CGRectMake(layer.bounds.origin.x,layer.bounds.origin.y, layer.bounds.size.width,layer.bounds.size.height), layerCircle);
        CFRelease(layerCircle);
    }
}

QuickQuoteViewController.m

defluviumLayer=[[QQDefluviumLayer alloc] init];
    [defluviumLayer setBounds:CGRectMake(0, 0, 61, 343)];
    [defluviumLayer setPosition:CGPointMake(277,246)];
    [self.view.layer addSublayer:defluviumLayer];
    [defluviumLayer update];


    candleStickLayer=[[QQCandleStickLayer alloc] init];
    [candleStickLayer setBounds:CGRectMake(0,0, defluviumLayer.frame.size.width, defluviumLayer.frame.size.height)];
    [candleStickLayer setPosition:CGPointMake(defluviumLayer.position.x,defluviumLayer.position.y)];
    [self.view.layer addSublayer:candleStickLayer];
    [candleStickLayer update];

I'm drawing in a CALayer, and have Image with image below layer, as I have tested - if i draw on clear white view - the line can be drawn with width 1, but not on the image

freennnn
  • 355
  • 2
  • 10

3 Answers3

28

The line width is indeed 1 pixel wide, but 0.5 pixel wide on one side and 0.5 pixel wide on the other side. Sticking it to the pixel grids makes appears to be 1 pixel wide at 50% opacity on both sides, making it a 2 pixel wide line at 50% opacity.

To avoid this, draw the line on half-pixel coordinates.

For example, instead of

CGContextMoveToPoint(ctx, 20.0f, 30.0f);
CGContextAddLineToPoint(ctx, 20.0f, 100.0f);

do

CGContextMoveToPoint(ctx, 20.5f, 30.0f);
CGContextAddLineToPoint(ctx, 20.5f, 100.0f);
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
  • 1
    A related explanation: https://developer.mozilla.org/En/Canvas_tutorial/Applying_styles_and_colors#A_lineWidth_example – kennytm Jan 09 '10 at 12:50
  • CGContextSetLineWidth(context, 1.0f); CGContextSetAllowsAntialiasing(context, false); CGContextSetShouldAntialias(context, false); CGContextSetShadowWithColor(context, CGSizeMake( 0.0, 0.0 ), 0, NULL); CGContextSetRGBStrokeColor(context, 119.0f/255, 119.0f/255, 119.0f/255, 1.0); CGContextMoveToPoint(context, self.bounds.origin.x+30.5f, self.bounds.origin.y+self.bounds.size.height-indent); CGContextAddLineToPoint(context, self.bounds.origin.x+30.5f, self.bounds.origin.y+self.bounds.size.height-(self.bounds.size.height-lastY)); CGContextClosePath(context); – freennnn Jan 09 '10 at 12:56
  • Can you post the code (by editing your question) to include the CALayer and the image part? From your description the crucial thing seems to be "but not on the image". – kennytm Jan 09 '10 at 13:37
23

the point of pixel is located between 2 pixels like KennyTM said, and the line by default is Antialiased before go display, so it appears as width = 2.0, turn off Antialias can fix the problem either.

CGContextSetShouldAntialias(context, NO);

from: sfkaos on iphonedevsdk

I tried, works fine for me.

flutewang
  • 529
  • 2
  • 6
  • 16
0

I agree with KennyTM, however I had to add the 0.5 to the Y axis, not the X axis to get my line to show half. I guess it depends which way your line goes, i.e. horizontal or vertical!