(v13) Named color lookup
This page applies to Harlequin v13.1r0 and later; both Harlequin Core and Harlequin MultiRIP.
This section describes various ways of writing lookup procedures to obtain the replacement solid color for named colors.
Simple example
This simple example defines an NCD, called SimpleNCD, which uses the /DeviceCMYK ColorSpace
:
currentglobal false setglobal
<<
/ColorSpace [/DeviceCMYK]
/Lookup {
% on stack: NCD colorant exch /Colors get exch
% on stack: Colors colorant
2 copy known {
get
true
% on stack: solid-color true
} {
pop pop false
% on stack: false
} ifelse
} bind
/TintTransform { {1 index mul exch} forall pop } bind
/Colors <<
/Orange [ 0 0.45 1 0 ]
/Violet [ 0.8 0.8 0 0 ]
>>
>>
/SimpleNCD exch /NamedColor defineresource pop setglobal
The Lookup procedure looks for colorants that are held within the NCD in a dictionary, here called Colors, which also holds the solid color equivalent CMYK values.
One advantage of this method is that the NCD can be created from a PostScript language fragment as a memory-based resource (that is, the NCD does not need to be obtained from disk like other ways of defining NamedColor
resources).
Lookup from a table
This example defines an NCD, called InternalLookup
, which uses the /DeviceCMYK ColorSpace
:
{
currentglobal false setglobal
<<
/linebuff 100 string def
/ColorSpace /DeviceCMYK
/Lookup {
% on stack: NCD colorant
Colors exch 2 copy known {
get
true
% on stack: solid-color true
} {
pop pop false
% on stack: false
} ifelse
} bind
/TintTransform { {1 index mul exch} forall pop } bind
/Colors <<
% This loop converts each pair of lines from the end of
% this resource to a dictionary entry of:
% colorant [ CMYK values ]
{
currentfile //linebuff readline not { pop exit } if cvn
[ % And read in the 4 CMYK values
currentfile token pop
currentfile token pop
currentfile token pop
currentfile token pop
]
} loop
>>
>>
/InternalLookup exch /NamedColor defineresource pop
setglobal
} exec
Orange
0 0.45 1 0 % Stored as: /Orange [ 0 0.45 1 0 ]
Violet
0.8 0.8 0 0 % Stored as: /Violet [ 0.8 0.8 0 0 ]
It also uses the Colors dictionary to store all colorants and their CMYK equivalent solid colors known to this NCD. This method uses the convenient technique of storing the colorants and their CMYK values in a tabular format at the end of database, and reading it in a loop to populate the Colors dictionary. It is convenient because this tabular format of the color values can often be easily imported from the spreadsheet format used for many spot color libraries.
This method requires that the NCD is contained in its own file, which is normally in the SW/NamedColor directory as normal for a disk-based resource.
Use of Variant 2 Lookup procedures
This example is similar to the SimpleNCD
in Simple example but uses the Variant 2 Lookup procedure to return a different ColorSpace
and/or TintTransform
from one that is defined by the NCD.
% Define local interpolation operator to make the use of interpop simpler.
% It interpolates an in-value in range 0-1, over an equally spaced array containing
% out-values. The out-values may be any numbers.
% in-value interp-array interpop out-value
userdict /interpop 1183615869 internaldict /interpop get put
currentglobal false setglobal
<<
/ColorSpace [/DeviceCMYK]
/Lookup {
% on stack: NCD colorant
exch /Colors get exch
% on stack: Colors colorant
2 copy known {
get
true
% on stack: solid-color true
} {
pop pop false
% on stack: false
} ifelse
} bind
/TintTransform { {1 index mul exch} forall pop } bind
/Colors <<
% Variant 2 (dictionary form) returned by Lookup. ColorSpace is taken from
% the NCD.
% This TintTransform is equivalent to the simpler Variant 1 form for Purple
% in the SimpleNCD example.
(Violet) <<
/TintTransform {[0.8 0.8 0 0] {1 index mul exch} forall pop} bind
>>
% Variant 2 (dictionary form) returned by Lookup. ColorSpace is taken from
% the NCD.
% This tint transforms use an interpop array of 5 entries equi-spaced for
% values at 25% intervals. It applies a 10% dot gain to the input value.
(Orange) <<
/TintTransform {{0 0.35 0.60 0.85 1} //interpop
[0 0.45 1.0 0] {1 index mul exch} forall pop} bind
>>
% Variant 2 (dictionary form) returned by Lookup.
% ColorSpace is defined as DeviceN for this color.
% This tint transforms use an interpop array of 5 entries equi-spaced for
% values at 25% intervals. It applies a dot gain to the input value, whilst
% also scaling the tint value to a maximum of 70%. (Gold) <<
/ColorSpace [/DeviceN [/Cyan /Magenta /Yellow /Black /Orange] /DeviceCMYK
{null}]
/TintTransform {{0 0.20 0.45 0.60 0.7} //interpop
[0.05 0 0.2 0 0.7] {1 index mul exch} forall pop} bind
>>
% Variant 1 (array form) returned by Lookup that uses the ColorSpace and
% TintTransform defined in this NCD. (Grass) [0.6 0 0.7 0]
>>
>>
/SimpleNCD_Variant2 exch /NamedColor defineresource pop setglobal
{ noformat }
{panel}
External Lookup
It is sometimes desirable to lookup colorants in a more dynamic style than is allowed with the previous methods. It is possible to call out to C code to derive the results for the Lookup procedure using a PostScript language device (v13) What is a device?.
The HHR SDK supports a named color device with five example device instances, one each for CMYK, CMYKOGV, XYZ, Lab, and None color spaces. For more information see the documentation for named-color-lookup. c in the HHR SDK Developer’s Guide. As well as the C code that implements the PostScript Language device, a named color resource is required to call the device. This is a simplified version of the TEST_CMYK resource that ships with the SDK, to avoid confusion this resource is called ExternalCMYK:
currentglobal false setglobal
20 dict begin
/globalness exch def
/ColorSpace /DeviceCMYK
/NCdevname (%namedcolorCMYK%) def
/NCfullname 256 string def % full name of device+colorant filename
//NCdevname //NCfullname copy pop % initialise device prefix once
/Lookup { % NCD colorant |solid-color true OR false
exch pop
//NCfullname //NCdevname length % c fn dnl
2 copy 5 2 roll % fn dnl c fn dnl
1 index length 1 index sub getinterval % fn dnl c fs
cvs length % fn dnl csl
add 0 exch getinterval % (%namedcolorCMYK%colorant)
% Execute the (%namedcolorCMYK%colorant) string which has the effect
% of opening a ’file’ on the %namedcolorCMYK% device, which then
% returns the solid-color and success status.
currentobjectformat 0 eq {
% Binary scanning is required for this, so change the object
% format temporarily to enable binary scanning.
3 setobjectformat run 0 setobjectformat
} {
run
} ifelse
} bind def
% N.B. It is important that a tint of 0 should map to NO ink, and
% that a tint of 1 should not perturb the solid color. The RIP
% uses the tint value to compute the contributions when blending
% spots together during the overprint and compositing phase.
/TintTransform { % tint [C M Y K] |Ct Mt Yt Kt
{ % tint solid
1 index mul exch
} forall
pop
} bind def
currentdict
end
/ExternalCMYK exch /NamedColor defineresource
/globalness get setglobal
This resource is written to work with the %namedcolorCMYK%
device instance. It accepts a colorant name and writes back either a false, or a colorant array and true. This data is in binary format, which has the advantage for the PostScript language device that the emitted string is a fixed length.