2012-06-18 2 views
3

내부 그림자를 그리기 위해 생성 된 코드를 보았습니다. 그림자가 만들어지는 부분을 제외하고는 모두 매우 명확하고 이해됩니다 copysign.코어 그래픽이있는 내부 그림자

나는이 무엇 copysign 이해하지만, 왜, 어떻게 그것을 실제로 아래 코드에서 사용하고 있습니다.

0.1 값은 xOffset 값에 대해 중요하지 않은 것처럼 보인다.

CGContextRef context = UIGraphicsGetCurrentContext(); 

    UIColor* shadow = [UIColor redColor]; 
    CGSize shadowOffset = CGSizeMake(-2, -0); 
    CGFloat shadowBlurRadius = 2; 

    UIBezierPath* rectanglePath = [UIBezierPath bezierPathWithRect: CGRectMake(50, 50, 50, 50)]; 
    [[UIColor grayColor] setFill]; 
    [rectanglePath fill]; 

    CGRect rectangleBorderRect = CGRectInset([rectanglePath bounds], -shadowBlurRadius, -shadowBlurRadius); 
    rectangleBorderRect = CGRectOffset(rectangleBorderRect, -shadowOffset.width, -shadowOffset.height); 
    rectangleBorderRect = CGRectInset(CGRectUnion(rectangleBorderRect, [rectanglePath bounds]), -1, -1); 

    UIBezierPath* rectangleNegativePath = [UIBezierPath bezierPathWithRect: rectangleBorderRect]; 
    [rectangleNegativePath appendPath: rectanglePath]; 
    rectangleNegativePath.usesEvenOddFillRule = YES; 

    CGContextSaveGState(context); 
    { 
    CGFloat xOffset = shadowOffset.width + round(rectangleBorderRect.size.width); 
    CGFloat yOffset = shadowOffset.height; 
    CGContextSetShadowWithColor(context, 
           CGSizeMake(xOffset + copysign(0.1, xOffset), yOffset + copysign(0.1, yOffset)), 
           shadowBlurRadius, 
           shadow.CGColor); 


    [rectanglePath addClip]; 
    CGAffineTransform transform = CGAffineTransformMakeTranslation(-round(rectangleBorderRect.size.width), 0); 
    [rectangleNegativePath applyTransform: transform]; 
    [[UIColor grayColor] setFill]; 
    [rectangleNegativePath fill]; 
    } 
    CGContextRestoreGState(context); 

답변

5

개발자는 PaintCode입니다.

그림자 오프셋은 항상 정수 픽셀로 "반올림"됩니다. 불행히도 Core Graphics에는 정밀도/반올림 문제가 있습니다. 특정 값의 섀도우 오프셋의 경우 반올림이 해제되고 잘못된 오프셋이 사용됩니다 (예 : 3 대신 2).

그림자 오프셋에서 전략적으로 0.1을 더하거나 뺄 때 항상 강제로 올바르게 적용됩니다.

관련 문제