iPDFdev Tips & Tricks for PDF development

IFXPDFFactory – part 4 – Colors and colorspaces

December 20th, 2012

I finished implementing support for PDF colors and colorspaces. The following colors are supported: RGB, CMYK, Gray, CalRGB, CalGray, Indexed, Icc, Lab and Separation.

All color classes inherit from IFXPDFColor class, all colorspace classes inherit from IFXPDFColorSpace class.

RGB

RGB colors are based on DeviceRGB colorspace. Because this is a simple colorspace without parameters, there is no need to create a colorspace object before creating a color, the colorspace being created automatically.
An RGB color is defined by 3 double values, red, green, blue, each one in 0 - 1 range. The IFXPDFRgbColor class represents the RGB color and IFXPDFRgbColor objects can be created like this:

// By default a black color is created.
IFXPDFRgbColor* rgbColor = [[IFXPDFRgbColor alloc] init];
// Change the color properties to red.
rgbColor.red = 1;
rgbColor.green = 0;
rgbColor.blue = 0;
// ...
[rgbColor release];
//
// or
//
IFXPDFRgbColor* redColor = [[IFXPDFRgbColor alloc] initWithRed: 1 green: 0 blue: 0];
// ...
[redColor release];
// 
// or get an autoreleased color
// 
IFXPDFRgbColor* blueColor = [IFXPDFRgbColor rgbColorWithRed: 0 green: 0 blue: 1];
//
// or use one of the predefined colors
//
IFXPDFRgbColor* greenColor = [IFXPDFRgbColor greenColor];

CMYK

CMYK colors are based on DeviceCMYK colorspace. Because this is a simple colorspace without parameters, there is no need to create a colorspace object before creating a color, the colorspace being created automatically.
A CMYK color is defined by 4 double values, cyan, magenta, yellow, black, each one in 0 - 1 range. The IFXPDFCmykColor class represents the CMYK color and IFXPDFCmykColor objects can be created like this:

// By default a black color is created.
IFXPDFCmykColor* cmykColor = [[IFXPDFCmykColor alloc] init];
// Change the color properties to cyan.
cmykColor.c = 1;
cmykColor.m = 0;
cmykColor.y = 0;
cmykColor.k = 0; 
// ...
[cmykColor release];
//
// or
//
IFXPDFCmykColor* cyanColor = [[IFXPDFCmykColor alloc] initWithC: 1 m: 0 y: 0 k: 0];
// ...
[cyanColor release];
// 
// or get an autoreleased color
// 
IFXPDFCmykColor* magentaColor = [IFXPDFCmykColor cmykColorWithC: 0 m: 1 y: 0 k: 0];

Gray

Gray colors are based on DeviceGray colorspace. Because this is a simple colorspace without parameters, there is no need to create a colorspace object before creating a color, the colorspace being created automatically.
A Gray color is defined by a one double value in 0 - 1 range, 0 means black 1 means white. The IFXPDFGrayColor class represents the Gray color and IFXPDFGrayColor objects can be created like this:

// By default a black color is created.
IFXPDFGrayColor* grayColor = [[IFXPDFGrayColor alloc] init];
// Change the color properties to medium gray.
grayColor.g = 0.5;
// ...
[grayColor release];
//
// or
//
IFXPDFGrayColor* mediumGrayColor = [[IFXPDFGrayColor alloc] initWithG: 0.5];
// ...
mediumGrayColor release];
// 
// or get an autoreleased color
// 
IFXPDFGrayColor* lightGrayColor = [IFXPDFGrayColor grayColorWithG: 0.75];

CalGray

CalGray colors are based on CalGray colorspace (Calibrated Gray). Because a CalGray colorspace can be customized, a colorspace object must be created before creating the colors. The IFXPDFCalGrayColorSpace class defines a CalGray colorspace. The whitePoint, blackPoint and gamma properties let you customize the colorspace.
The IFXPDFCalGrayColor class defines a CalGray color. When a IFXPDFCalGrayColor object is created a IFXPDFCalGrayColorSpace object must be always provided as parameter. The gray property is used to set the color value.

// class method calGrayColorSpace creates a default CalGray colorspace
IFXPDFCalGrayColorSpace* calGrayColorSpace = [IFXPDFCalGrayColorSpace calGrayColorSpace];
 
// CalGray colors can be created using a convenient class method that returns an autoreleased object
IFXPDFCalGrayColor* calGrayLightGrayColor = [IFXPDFCalGrayColor calGrayColorWithColorSpace: calGrayColorSpace andGray: 0.9];
// or using the designated class initializer
IFXPDFCalGrayColor* calGrayDarkGrayColor = [[IFXPDFCalGrayColor alloc] initWithCalGrayColorSpace: calGrayColorSpace];
calGrayDarkGrayColor.gray = 0.3;
// ...
[calGrayDarkGrayColor release];

CalRGB

CalRGB colors are based on CalRGB colorspace (Calibrated RGB). Because a CalRGB colorspace can be customized, a colorspace object must be created before creating the colors. The IFXPDFCalRGBColorSpace class defines a CalRGB colorspace. The whitePoint, blackPoint, matrix and gamma properties let you customize the colorspace.
The IFXPDFCalRGBColor class defines a CalRGB color. When a IFXPDFCalRGBColor object is created a IFXPDFCalRGBColorSpace object must be always provided as parameter. The red, green and blue properties are used to set the color value. The values for these properties must fit the 0 - 1 range.

// class method calRGBColorSpace creates a default CalRGB colorspace
IFXPDFCalRGBColorSpace* calRgbColorSpace = [IFXPDFCalRGBColorSpace calRGBColorSpace];
 
// CalRGB colors can be created using a convenient class method that returns an autoreleased object
IFXPDFCalRGBColor* calRgbRedColor =
    [IFXPDFCalRGBColor calRGBColorWithColorSpace: calRgbColorSpace andRed: 1 green: 0 blue:0];
// or using the designated class initializer
IFXPDFCalRGBColor* calRgbGreenColor = [[IFXPDFCalGrayColor alloc] initWithCalRGBColorSpace: calRgbColorSpace];
calRgbGreenColor.red = 0;
calRgbGreenColor.green = 0.9;
calRgbGreenColor.blue = 0;
// ...
[calRgbGreenColor release];

Indexed

Indexed colors are based on Indexed colorspace. The indexed colorspace defines a fixed number of colors based on color samples. Because an indexed colorspace can be customized, a colorspace object must be created before creating the colors. The IFXPDFIndexedColorSpace class defines an indexed colorspace. The maxIndex, baseColorSpace and colorTable properties let you customize the colorspace.
The IFXPDFIndexedColor class defines an indexed color. When a IFXPDFIndexedColor object is created a IFXPDFIndexedColorSpace object must be always provided as parameter. The colorIndex property is used to select a color from the color table defined on the colorspace. The value for this property must by in 0 - maxIndex range.

// class method indexedColorSpace creates a default indexed colorspace
IFXPDFIndexedColorSpace* indexedColorSpace = [IFXPDFIndexedColorSpace indexedColorSpace];
// the colorspace defines only 2 colors based on RGB colorspace (3 bytes per color)
Byte colorTable[] = { 255, 0, 0, 192, 0, 192 };
indexedColorSpace.colorTable = [NSData dataWithBytes: colorTable length: sizeof(colorTable)];
// maxIndex for colors defined on this colorspace is number of colors - 1.
indexedColorSpace.maxIndex = 1;
// the color samples in the colorTable are defined in the RGB colorspace.
indexedColorSpace.baseColorSpace = [IFXPDFRgbColorSpace rgbColorSpace];
// a color can be created like this
IFXPDFIndexedColor* redColor = [IFXPDFIndexedColor indexedColorWithColorSpace: indexedColorSpace andColorIndex: 0];
// or like this
IFXPDFIndexedColor* violetColor = [[IFXPDFIndexedColor alloc] initWithIndexedColorSpace: indexedColorSpace];
violetColor.colorIndex = 1;
// use the color
// ...
[violetColor release];

ICC

ICC colors are based on an ICC profile embedded in the PDF file as an ICC colorspace. The ICC profile must be loaded in an ICC colorspace before the colors are created. The IFXPDFIccColorSpace class defines an ICC colorspace. The profileData, alternateColorSpace and colorComponentsCount properties let you customize the colorspace.
The IFXPDFIccColor class defines an ICC color. When a IFXPDFIccColor object is created a IFXPDFIccColorSpace object must be always provided as parameter. Because the number of color components in an ICC color depends on the ICC colorspace, the colorComponents property is a double array that accepts up to 8 values. For a RGB based ICC colorspace the first 3 elements in the array must be set with values between 0 and 1. For a CMYK based ICC colorspace the first 4 elements in the array must be set with values between 0 and 1.

// Load theICC profile from the rgb.icc file
NSString *iccFile = [[NSBundle mainBundle] pathForResource:@"rgb" ofType:@"icc"];
NSData *iccData = [NSData dataWithContentsOfFile: iccFile];
 
// Get a default ICC colorspace
IFXPDFIccColorSpace* iccColorSpace = [IFXPDFIccColorSpace iccColorSpace];
// Set the profile data. The color components are interpreted in the context of the ICC profile.
iccColorSpace.profileData = iccData;
// Set the alternate colorspace, it acts as a fallback colorspace for applications that do not support the ICC profile.
// Must be compatible with the profile (if ICC profile is RGB based do not set CMYK as alternate colorspace)
iccColorSpace.alternateColorSpace = [IFXPDFRgbColorSpace rgbColorSpace];
// Set that number of components that represent a color in the ICC colorspace
iccColorSpace.colorComponentsCount = 3;
 
// Create an ICC color and set its components.
// For an RGB based ICC colorspace the first 3 elements in the colorComponents array are set.
IFXPDFIccColor* redColor = [IFXPDFIccColor iccColorWithColorSpace: iccColorSpace];
// The values must be in 0 - 1 range or the output will be undefined.
redColor.colorComponents[0] = 1;
redColor.colorComponents[1] = 0;
redColor.colorComponents[2] = 0;
IFXPDFIccColor* blueColor = [IFXPDFIccColor iccColorWithColorSpace: iccColorSpace];
blueColor.colorComponents[0] = 0;
blueColor.colorComponents[1] = 0;
blueColor.colorComponents[2] = 0.75;

Lab

A Lab colorspace is a CIE 1976 L*a*b* space.
The IFXPDFLabColorSpace class defines a Lab colorspace. The whitePoint, blackPoint and range properties can be used to customize the colorspace, but default values are provided for them.
The IFXPDFLabColor class defines a Lab color. When a IFXPDFLabColor object is created a IFXPDFLabColorSpace object must be always provided as parameter. The L, a and b properties define a Lab color. The range of the first (L) component shall be 0 to 100; the ranges of the second and third (a and b) components shall be defined by the range property of the colorspace (by default -100 - 100).

// Create a default Lab colorspace
IFXPDFLabColorSpace* labColorSpace = [IFXPDFLabColorSpace labColorSpace];
// Create some autoreleased colors
IFXPDFLabColor* color1 = [IFXPDFLabColor labColorWithColorSpace: labColorSpace andL: 90 a: 20 b:-10];
IFXPDFLabColor* color2 = [IFXPDFLabColor labColorWithColorSpace: labColorSpace andL: 10 a: 70 b: -50];
// or
IFXPDFLabColor* color3 = [[IFXPDFLabColor alloc] initWithLabColorSpace: labColorSpace];
color3.L = 90;
color3.a = 20;
color3.b = -10;
// ...
[color3 release];

Separation

A Separation colorspace provides a means for specifying the use of additional colorants for a subtractive device. A separation colour is defined b a single component called tint that defines the intensity of the colorant applied on the output device.
The IFXPDFSeparationColorSpace class defines a Separation colorspace. The alternateColorSpace, colorant and tintTransform properties are used to define the colorspace. If the output device does not support Separation colorspaces then the alternate colorspace is used. The tintTransform specifies a function that transforms the tint value in color components for the alternate colorspace.
The IFXPDFSeparationColor class defines a Separation color. When a IFXPDFSeparationColor object is created a IFXPDFSeperationColorSpace object must be always provided as parameter. The tint property defines the intensity of the color. Its range is 0 - 1.

// Setup the tint transform function, it maps a tint value to 4 CMYK colour components.
IFXPDFExponentialFunction* orangeTintTransform = [[IFXPDFExponentialFunction alloc] init];
double domain[] = { 0, 1 };
orangeTintTransform.domain = [IFXPDFNumberArray arrayWithDoubles: domain length: 2];
double range[] = { 0, 1, 0, 1, 0, 1, 0, 1 };
orangeTintTransform.range = [IFXPDFNumberArray arrayWithDoubles: range length: 8];
orangeTintTransform.exponent = 1;
double c0[] = { 0, 0, 0, 0 };
orangeTintTransform.c0 = [IFXPDFNumberArray arrayWithDoubles: c0 length: 4];
double orangeC1[] = { 0, 0.53, 1, 0 };
orangeTintTransform.c1 = [IFXPDFNumberArray arrayWithDoubles: orangeC1 length: 4];
// Create an empty separation colour space. By default the alternateColorSpace is set to CMYK
IFXPDFSeparationColorSpace* orangeColorSpace = [IFXPDFSeparationColorSpace separationColorSpace];
// Set the name of the colorant represented by the colorspace
orangeColorSpace.colorant = @"PANTONE Orange 021 C";
// Set the tint transform
orangeColorSpace.tintTransform = orangeTintTransform;
[orangeTintTransform release];
// Create the separation color.
IFXPDFSeparationColor* darkOrangeColor = [IFXPDFSeparationColor separationColorWithColorSpace: orangeColorSpace andTint: 0.9];
// or
IFXPDFSeparationColor* lightOrangeColor = [[IFXPDFSeparationColor alloc] initWithSeparationColorSpace: orangeColorSpace];
lightOrangeColor.tint = 0.2;
// ...
[lightOrangeColor release];
Comments (2) Trackbacks (0)
  1. Thanks for this article and all the hardwork you are doing for this library.
    I am still impatient to test the beta 😉


Leave a comment

No trackbacks yet.