How do I create a custom CGColorSpace?

51 views Asked by At

I am trying to create a custom CGColorSpace in Swift on macOS but am not sure I really understand the concepts.

I want to use a custom color space called Spot1 and if I extract the spot color from a PDF I get the following:

"ColorSpace<Dictionary>" = {
    "Cs2<Array>" = (
        Separation,
        Spot1,
        DeviceCMYK,
        {
            "BitsPerSample<Integer>" = 8;
            "Domain<Array>" = (
                0,
                1
            );
            "Filter<Name>" = FlateDecode;
            "FunctionType<Integer>" = 0;
            "Length<Integer>" = 526;
            "Range<Array>" = (
                0,
                1,
                0,
                1,
                0,
                1,
                0,
                1
            );
            "Size<Array>" = (
                1024
            );
        }
    );
};

How can I create this same color space using the CGColorSpace(propertyListPlist: CFPropertyList) API

func createSpot1() -> CGColorSpace? {
    let dict0 : NSDictionary = [
        "BitsPerSample": 8,
        "Domain" : [0,1],
        "Filter" : "FlateDecode",
        "FunctionType" : 0,
        "Length" : 526,
        "Range" : [0,1,0,1,0,1,0,1],
        "Size" : [1024]]
    
    let dict : NSDictionary = [
        "Cs2" : ["Separation","Spot1", "DeviceCMYK", dict0]
            ]
    
    let space = CGColorSpace(propertyListPlist: dict as CFPropertyList)
    
    if space == nil {
        DebugLog("Spot1 color space is nil!")
    }
    
    return space
}

I found the following pseudo code for creating such a color space

> The following C# pseudocode can be used to create a separation color
> space based on a PostScript function:
>
> static ColorSpace CreateSpotColorSpace(PDFDoc doc)
> {
>   Obj sep_cs = doc.CreateIndirectArray();
>
>   sep_cs.PushBackName("Separation");
>   sep_cs.PushBackName("LogoGreen");  // The name of the colorant
>   sep_cs.PushBackName("DeviceCMYK"); // Alternate color space
>
> // Create tint function (using PostScript calculator function).
> // Tint function is used to transform a tint value into color
> // component values in the alternate color space.
> string ps_funct = "{ dup 0.84 mul exch 0.00 exch dup 0.44 mul exch
> 0.21 mul }";
>   Obj tint_funct = doc.CreateIndirectStream(new
> System.Text.UTF8Encoding().GetBytes(ps_funct));
>   tint_funct.PutNumber("FunctionType", 4);
>
>   Obj tint_domain = tint_funct.PutArray("Domain");
>   tint_domain.PushBackNumber(0);  // Gray
>   tint_domain.PushBackNumber(1);
>
>   Obj tint_range = tint_funct.PutArray("Range");
>   tint_range.PushBackNumber(0); // C
>   tint_range.PushBackNumber(1);
>   tint_range.PushBackNumber(0); // M
>   tint_range.PushBackNumber(1);
>   tint_range.PushBackNumber(0); // Y
>   tint_range.PushBackNumber(1);
>   tint_range.PushBackNumber(0); // K
>   tint_range.PushBackNumber(1);
>
>   sep_cs.PushBack(tint_funct);
>   return new ColorSpace(sep_cs);
>
> }

This appears to be similar to the Apple CGPDFDocument object type definitions here https://developer.apple.com/documentation/coregraphics/cgpdfobjecttype

So I wonder whether one would need to use these CG pdf object types to construct the ColorSpace PropertyList.

0

There are 0 answers