4

I know I can fill a rect using NSRectFill(bounds). However I wanted to preserve transparency for PDF output and I discovered that I can do that only with NSBezierPath(rect: bounds).fill() What is the difference (behind the scenes) of those two?

func drawBackground() {
    CGContextSaveGState(currentContext)
    if (NSGraphicsContext.currentContextDrawingToScreen()) {
        NSColor(patternImage: checkerboardImage).set()
        NSRectFillUsingOperation(bounds, NSCompositingOperation.CompositeSourceOver)
    }
    NSColor.clearColor().setFill()
    //NSRectFill(bounds) //option 1
    NSBezierPath(rect: bounds).fill() // option 2
    CGContextRestoreGState(currentContext)
}

extension NSImage {

    static func checkerboardImageWithSize(size : CGFloat) -> NSImage {
        let fullRect = NSRect(x: 0, y: 0, width: size, height: size)
        let halfSize : CGFloat = size * 0.5;
        let upperSquareRect = NSRect(x: 0, y: 0, width: halfSize, height: halfSize);
        let bottomSquareRect = NSRect(x: halfSize, y: halfSize, width:halfSize, height: halfSize);
        let image = NSImage(size: NSSize(width: size, height: size))
        image.lockFocus()
        NSColor.whiteColor()
        NSRectFill(fullRect)
        NSColor(deviceWhite: 0.0, alpha:0.1).set()
        NSRectFill(upperSquareRect)
        NSRectFill(bottomSquareRect)
        image.unlockFocus()
        return image
    }
}
Marek H
  • 5,173
  • 3
  • 31
  • 42
  • Is it because the compositing mode is NSCompositeCopy? Would NSRectFillUsingOperation have worked better? – matt Aug 22 '16 at 16:20
  • Yes, you are completely right. NSRectFillUsingOperation+CompositeCopy does the same as NSRectFill while the NSRectFillUsingOperation+CompositeSourceOver behaves like NSBezierPath + fill. Try to write it as answer and I give you credit. Thanks. – Marek H Aug 22 '16 at 18:39
  • Thanks, did so. Glad this worked out! – matt Aug 22 '16 at 19:03

1 Answers1

3

I'm mostly an iOS programmer and not very fluent these days over on the AppKit side of things, but my guess is that you're getting the wrong NSCompositingOperation. I see from the docs that NSRectFill uses NSCompositeCopy. Perhaps it would work better if you used NSRectFillUsingOperation, where you get to specify the compositing operation.

matt
  • 515,959
  • 87
  • 875
  • 1,141