views:

32

answers:

1

Hello folks,
I'm writing some lines of code to get acquainted with the basics of Quartz 2d. I am trying to draw and image an then clear it through the kCGBlendModeClear blend mode. Here's the code of my UIView subclass code, whose background color is set to orange through IB:

- (void)drawRect:(CGRect)rect {

    UIImage *brush = [UIImage imageNamed:@"brush.png"] ;
    CGContextRef ctx = UIGraphicsGetCurrentContext();

    CGContextSetBlendMode(ctx,kCGBlendModeNormal ); 
    CGContextDrawImage(ctx, CGRectMake(100, 100, 26, 25), [brush CGImage]);

    CGContextSetBlendMode(ctx, kCGBlendModeClear);

    CGContextSetFillColorWithColor(ctx, [UIColor clearColor].CGColor);

    CGContextFillEllipseInRect(ctx, CGRectMake(110, 110, 5, 5)); // HERE!
}

Reading the docs and this question I thought that line marked HERE would produce a hole in the image I had previously drawn. Instead it creates a black circle on it (should be orange).

To debug, I tried adding my custom view over an orange uiview. This time my custom view has a black background. The hole of line HERE is correct, but I wonder why the black color of the view. Even more strangely, if I do myView.backgroundColor I can set a background color (shouldn't this be overridden by my drawRect implementation?).

I am clearly missing some basics of Quartz, can anyone help?

Davide

+1  A: 

Couple of things.

First, the Porter-Duff blend modes are only guaranteed to work in bitmap-based contexts. (i.e., contexts created by CGBitmapContextCreate)

Second, kCGBlendModeClear is defined as R = 0 — it doesn't even check src or dst pixels. So even though it's not guaranteed to work here, it appears that it is working correctly.

(see CGContext.h for better explanation than the docs give.)

Art Gillespie
two subquestion: 1) do you see kCGBlendModeClea as a viable way to implement a rubber tool? 2) Could you tell me something more about R?
nutsmuggler
1) No. `R=0` is pretty useless, you can't even set the clear color. 2) Blend modes can be expressed in terms of R, S, and D, where S is the source pixel, D is the destination pixel and R is the resulting pixel. This gives you a handy shorthand for describing blend modes, e.g, `R = S + D*(1 - Sa)` for source-over (`kCGBlendModeNormal`) It's pretty well explained in the comments beginning at CGContext.h:84
Art Gillespie
Thanks! I had guessed ModeCLear wasn't the answer, but it's nice to have confirmation.
nutsmuggler