Harlequin RIP SDK
Configuring the Harlequin RIP

The configuration stage of processing a job is performed before job data is interpreted. It sets up the initial state of the RIP for each individual job.

PS configuration

As noted in the preface, the Harlequin RIP uses the PostScript® language, with extensions by Global Graphics, as a scripting and configuration language. Most of the configuration options are controlled through operators that set parameters presented as declarative structured data in PostScript dictionaries. The operators include setsystemparams, setuserparams, setpagedevice, setpdfparams, setinterceptcolorspace, and setreproduction. The details of how to use these operators and the parameters they support are described in more detail in the Harlequin RIP extensions manual.

The inputs API call inputq_print_job() associates a setup name with each job added to the input queue. The job processing loop in the Harlequin SDK converts this setup name parameter to a PostScript device-relative filename and prepares the RIP to read the configuration PostScript from that device file. If the setup name is a relative name, then it is converted to PostScript form and appended onto the %configps% device name to form the full device-relative filename. If the setup name is an absolute filename, it is converted to a PostScript filename relative to the file system device for the root drive. If the setup name is already a PostScript device-relative filename, it is passed through without change.

The default location to find configurations (the %configps% device) is normally mounted on the SW/TestConfig/ sub-directory during RIP startup. The mount is conditionally done within the SW/Sys/ExtraDevices startup file using a prefix device. The location to find configurations may be changed to a different directory, or even to a location on a different device altogether by setting the /Prefix parameter on the default %configps% device, or the %configps% device may be mounted on a different device type altogether. The preboot device provides a convenient method to mount the %configps% device and any other devices that may need mounting before RIP startup.

Normally, a base configuration will be established, either by submitting a base configuration startup job, adding configuration operators to SW/Sys/HqnOEM, or adding a new SW/Sys/ExtraStart/ file to set configuration. Global Graphics recommends setting configuration that is common for all workflows in the base configuration, including the ColorantFamilies and other output capability configuration.

JSON configuration

Writing PostScript configuration is a skill that few developers have experience with, and debugging problems in PostScript configurations can be a difficult and time-consuming experience. If your configuration does not require the full programmability that PostScript brings, then you may find it easier to configure the RIP using structured data presented in JSON (JavaScript Object Notation). The Harlequin RIP supports JSON configuration for many of its configuration options, and Global Graphics is committed to supporting as many of the configuration options as possible using JSON. Another advantage of using JSON configuration is that the RIP's JSON configuration support understands order dependencies between the configuration operations, and optimizes the order of operations to avoid problems.

If the setup name parameter presented to inputq_print_job() ends with .json or .JSON, then the configuration will be parsed as JSON. Note that the JSON can be presented from any device, not just a file system device. JSON support is implemented by a translation device that converts the JSON data to PostScript configuration commands.

Many code editors support JSON validation and auto-completion. Global Graphics supplies schema files for the JSON configuration options supported by the RIP, which may be useful in setting up your editor to validate JSON configurations, or in validating JSON configuration that you create programmatically. Global Graphics have more documentation about configuring the Harlequin RIP using JSON on our website.

Page features and overrides

The override parameter to inputq_print_job() is an optional buffer of PostScript configuration data that is interpreted after the setup has been run, and may be used to modify the RIP configuration on a per-job basis. If you have many options which can apply to different RIP configurations, using the override parameter to set the options may simplify management of your RIP configurations.

The application layer is responsible for constructing the override configuration data. The "clrip" application layer uses the override parameter to implement Page Feature mix-ins to the configuration. The "clrip" application does this by using the SDK's SkinDynamicBufferReset(), SkinDynamicBufferAdd(), and SkinDynamicBufferFree() utility functions to append to a data buffer. Each Page Feature name is converted to a PostScript device-relative filename, and wrapped in a PostScript string followed by a run operator, then added to the override buffer. The SkinDynamicBufferAdd() function uses the core library's swncopyf() function to perform a formatted string write into the buffer. A useful technique when using these functions is to use the Harlequin string format modifier ! when writing PostScript string data. This modifier ensures that an arbitrary zero-terminated C string will be quoted appropriately for interpretation as PostScript. The "clrip" Page Feature code applies it in this manner:

// ...find page feature names, convert to PostScript form...
if ( !SkinDynamicBufferAdd(&overridePS, "(%!s) run\n", feature_name) ||
inputq_print_job(filename, setupname,
overridePS.used > 0 ? overridePS.data : NULL,
NULL, NULL, -1, &job_id) != SW_INPUTQ_SUCCESS ) {
// ...error cleanup and return...
SkinDynamicBufferFree(&overridePS) ;
#define inputq_print_job
Insert a job into the input queue for printing by the RIP.
Definition: inputsapi.h:401
Definition: inputsapi.h:91
Auto and static scope initialiser for configuration data buffers.
Definition: skinkit.h:1032
HqBool SkinDynamicBufferAdd(SkinDynamicBuffer *buffer, const char *format,...)
Helper function to write formatted string (using swncopyf()) to the end of a dynamic buffer,...
Definition: skinkit.c:1086
void SkinDynamicBufferFree(SkinDynamicBuffer *buffer)
Free any memory allocated for dynamic buffer data.
Definition: skinkit.c:1077
#define NULL
Definition of NULL pointer.
Definition: hqtypes.h:37
Dynamically-allocated buffer structure used to collect configuration PostScript for a job.
Definition: skinkit.h:1026

The override data should be used for short phrases of configuration data. There is a maximum length to the override data of 8192 bytes. This is derived from the string allocated in the consumeOverridePS procedure in the HqnConfigProvider ProcSet.

Configuration only jobs

Configuration jobs are PostScript jobs that modify the state of the RIP. Configuration jobs are run in a manner where any changes they make to state persists until the RIP is rebooted or stopped. Configuration jobs are normally run immediately after starting the RIP to install hooks or default state, but can be run at any time. Configuration jobs are distinguished by having a NULL filename parameter and a non-NULL override parameter in the inputq_print_job(). It is customary to also use a NULL setup name parameter in a configuration job's inputq_print_job(), because applying a setup may consume memory that may not be recoverably during the RIP's lifetime.

Configuration jobs may also be run by calling the low-level functions SwLeJobStart() and then SwLeJobEnd(). The buffer of configuration PostScript supplied to SwLeJobStart() should leave false on the PostScript stack after applying the configuration state changes. This method is not advised when the job processing loop is active, but may be used during startup. Larger amounts of configuration PostScript can be supplied using this method than inputq_print_job() supports.

Configurations and server loop save levels

After startup, the Harlequin RIP core will run its server loop, repeatedly requesting jobs to process. The server loop uses PostScript memory save levels to manage how memory is recovered during and between jobs. The server loop runs at the lowest save level (level 0), which allows any changes to data to persist for the lifetime of the RIP. The server loop takes great care not to allocate PostScript memory which may become unrecoverable. When a job is processed, the save level is increased to save level 1 before interpreting the configuration data, and then again to save level 2 before running the job. PostScript jobs that use the restoreall or grestoreall operations will restore the relevant parts of their state to the initial job state, just after configuration was run. Configuration-only jobs, and PostScript jobs that use exitserver or startjob to change default state will run at save level 0, allowing state changes to be made that persist for the lifetime of the RIP.