Skip to main content
Skip table of contents

(v13) Structured data parameters for raster handlers

This page applies to Harlequin v13.1r0 and later; and to Harlequin Core but not Harlequin MultiRIP.

The functionality described in this section is new from Harlequin Core v12.1r0.

The RasterDescription structure (see (v13) RasterDescription contains a pointer to a structured data object. This object allows you to pass through parameters to raster handlers without having to modify SDK code.

The structured data pass-through method uses the Structured Data Callback API defined in lib/interface/swdataapi.h in the SDK. The structured data API provides an abstract type, sw_datum, to represent data represented as dictionaries (that is, lookup tables), arrays, or the primitive types integers, real numbers, Booleans, strings, or the null value. See the Doxygen documentation for full details of the operations supported by this API.

The RasterDescription contains a pointer to a sw_datum object called rasterParams. If parameters are presented to the setpagedevice PostScript operator in the correct form, then they are passed through to the raster backend, where they can be unpacked, copied, and iterated. Version 20181206 of the structured data API also contains methods to retain and release the structured data object, permitting its lifetime to be preserved past the scope of a raster page. The skintest raster backend file lib/skintest/src/libtiffrast.c contains an example of how to:

  • discover the structured data API using RDR
  • extract a parameter
  • use that parameter to change a setting in the output generated

Passing parameters with the structured data API

To pass parameters through to the backend as structured data, you should declare a RasterParams dictionary member in setpagedevice's ExtraPageDeviceKeys dictionary:

                        /PageBufferType /OEMRaster
                        /ExtraPageDeviceKeys <<
                          /RasterParams <<
                          /OEMRaster <<
                            /OEMParam1 100
                            /OEMParam2 true
                            /MyArray [ (string) false 100.1 ]

The name of the entry immediately below /RasterParams must match the PageBufferType used to select your raster output backend. This allows raster parameters for different raster output backends to be present simultaneously, without interfering with each other. The object associated with the raster backend name (that is the dictionary following OEMRaster in the example above) is the object that is passed through as the structured data sw_datum to the raster handler. This does not need to be a dictionary; it can be any object type supported by the structured data interface.

However, Global Graphics strongly recommends using a dictionary because of the flexibility it enables.

The raster parameters method only works with PageBufferType set using setpagedevice , and not with any override used on the Harlequin Core example clrip's command line (using the -o command-line parameter). If you are using clrip without replacing skintest, do not use output overrides in production; they are an aid to testing and debugging only.

For an example of using RasterParams to specify the compression to be used for the LIBTIFF PageBufferType, see (v13) GDI printer support (Windows only) For an example of reading parameters in a raster backend, see also lib/skintest/src/libtiffrast.c in (v13) Structured data parameters for raster handlers.

Discovering the structured data API and extracting parameters

To use the structured data API, the raster handler needs to include the required header files for the data API, and for RDR to discover the API:

	#include "apis.h"
	#include "swdataapi.h"

In a suitable routine where the parameters are to be used, the raster handler should discover the API, and then attempt to extract parameters. Discovery only needs to be attempted once; in the Harlequin Core version, the API is either present or not present:

	if ( rd->rasterParams != NULL ) {
		static sw_data_api *dataapi = NULL ;
		if ( dataapi != NULL ||
			 SwFindRDR(RDR_CLASS_API, RDR_API_DATA, 20181206, (void **)&dataapi, NULL) == SW_RDR_SUCCESS ) {
			sw_data_match match[] = {
				SW_DATUM_OPTIONALKEY(STRING, "CompressionType"),
			} ;
			if ( dataapi->match(rd->rasterParams, match, NUM_ARRAY_ITEMS(match)) == SW_DATA_OK ) {
				if ( match[0].value.type == SW_DATUM_TYPE_INVALID ) {
					/* Optional */
				} else if ( HqMemCmp(STRING_AND_LENGTH("LZW"),
									 match[0].value.value.string, (int32)match[0].value.length) == 0 ) {
					compression = COMPRESSION_LZW ;
				} else if ( ... ) { /* More option values */
				} else {
					/* unknown value error */
			} else {
				/* failed match error */
		} /* else old version error (no API discovered) */
	} /* else no raster parameters, nothing to do? */

Parameter extraction may use the match() method from the structured data API, or may be coded using the get_indexed() or get_keyed() methods, or even directly coded by checking datum types and values for simple datum.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.