Search code examples
cocoansimagenscursor

Hotspot in Windows cursor .cur loaded by NSImage?


According to the Cocoa Drawing Guide documentation for Images, NSImage can load a Windows cursor .cur file.

But how do I obtain the hotspot needed for NSCursor - initWithImage:(NSImage *)newImage hotSpot:(NSPoint)point; ?


Solution

  • As the documentation also says,

    In OS X v10.4 and later, NSImage supports many additional file formats using the Image I/O framework.

    So let's grab a sample cursor file and experiment in a Swift playground:

    import Foundation
    import ImageIO
    
    let url = Bundle.main.url(forResource: "BUSY_L", withExtension: "CUR")! as CFURL
    let source = CGImageSourceCreateWithURL(url, nil)!
    print(CGImageSourceCopyPropertiesAtIndex(source, 0, nil)!)
    

    Output:

    {
        ColorModel = RGB;
        Depth = 8;
        HasAlpha = 1;
        IsIndexed = 1;
        PixelHeight = 32;
        PixelWidth = 32;
        ProfileName = "sRGB IEC61966-2.1";
        hotspotX = 16;
        hotspotY = 16;
    }
    

    So, to get the hotspot safely:

    import Foundation
    import ImageIO
    
    if let url = Bundle.main.url(forResource: "BUSY_L", withExtension: "CUR") as CFURL?,
        let source = CGImageSourceCreateWithURL(url, nil),
        let properties = CGImageSourceCopyPropertiesAtIndex(source, 0, nil) as? [String: Any],
        let x = properties["hotspotX"] as? CGFloat,
        let y = properties["hotspotY"] as? CGFloat
    {
        let hotspot = CGPoint(x: x, y: y)
        print(hotspot)
    }
    

    Output:

    (16.0, 16.0)