DIRECTORY BasicTime USING [GMT], IO USING [STREAM], Imager USING [Context], Rope USING [ROPE]; DecomposerRegistry: CEDAR DEFINITIONS = BEGIN OPEN IO, Rope; Register: PROC [data: DecomposerData]; UnRegister: PROC [data: DecomposerData]; Lookup: PROC [key: ATOM] RETURNS [DecomposerData]; Enumerate: PROC RETURNS [LIST OF DecomposerData]; Attribute: TYPE = ATOM; Value: TYPE = REF ValueRep; ValueRep: TYPE = RECORD [ SELECT tag: ValueTag FROM cardinal => [cardinal: CARD32], integer => [integer: INT32], boolean => [boolean: BOOLEAN], real => [real: REAL], text => [text: Rope.ROPE], time => [time: BasicTime.GMT], sequence => [sequence: ValueSeq] ENDCASE ]; ValueTag: TYPE = {cardinal, integer, boolean, real, text, time, sequence}; ValueSeq: TYPE = REF ValueSeqRep; ValueSeqRep: TYPE = RECORD [SEQUENCE len: NAT OF Value]; MakeBoolVal: PROC [b: BOOL] RETURNS [Value]; MakeCardVal: PROC [c: CARD32] RETURNS [Value]; MakeIntVal: PROC [i: INT32] RETURNS [Value]; MakeTimeVal: PROC [gmt: BasicTime.GMT] RETURNS [Value]; MakeTextVal: PROC [rope: Rope.ROPE] RETURNS [Value]; MakeSeqVal1: PROC [val: Value] RETURNS [Value]; MakeSeqVal2: PROC [val1, val2: Value] RETURNS [Value]; MakeSeqValList: PROC [list: LIST OF Value] RETURNS [Value]; DecomposerData: TYPE = REF DecomposerDataRep; DecomposerDataRep: TYPE = RECORD [ key: ATOM _ NIL, -- the key for the decomposer doc: ROPE _ NIL, -- a brief description of the decomposer procs: REF DecomposerProcs _ NIL, -- procs supplied by the decomposer private: REF _ NIL -- private data for the decomposer ]; DecomposerProcs: TYPE = RECORD [ guess: GuessProc, -- proc to guess PDL suitability open: OpenProc, -- proc to open a document instance clean: CleanProc -- proc to clean up caches ]; GuessProc: TYPE = PROC [data: DecomposerData, seq: SequencerData] RETURNS [REAL]; OpenProc: TYPE = PROC [data: DecomposerData, seq: SequencerData] RETURNS [InstanceData]; CleanProc: TYPE = PROC [data: DecomposerData]; SequencerData: TYPE = REF SequencerDataRep; SequencerDataRep: TYPE = RECORD [ in: STREAM _ NIL, -- input stream out: STREAM _ NIL, -- normal output stream for message err: STREAM _ NIL, -- error output stream for message title: ROPE _ NIL, -- job title (optional) user: ROPE _ NIL, -- user name (optional) file: ROPE _ NIL, -- file name (optional) userTime: CARD _ 0, -- milliseconds of user+system cpu time flags: SequencerFlags _ [], -- sequencer flags procs: REF SequencerProcs _ NIL, -- sequencer operations private: REF _ NIL -- sequencer private data ]; SequencerFlags: TYPE = MACHINE DEPENDENT RECORD [ reverse: BOOL _ FALSE, -- reverse page imaging (N to 1) requested debug: BOOL _ FALSE, -- debugging info requested imaging: BOOL _ FALSE -- hint: imaging expected ]; SequencerProcs: TYPE = RECORD [ feedback: FeedbackProc, -- proc to report an event getAttr: GetAttrProc, -- proc to get an attribute setAttr: SetAttrProc -- proc to set an attribute ]; FeedbackProc: TYPE = PROC [instance: InstanceData, key: ATOM, severity: Severity, info: REF]; Severity: TYPE = {comment, warning, error, fatal}; FeedbackResult: TYPE = {continue, abort}; UncaughtInfo: TYPE = REF UncaughtInfoRep; UncaughtInfoRep: TYPE = RECORD [ signal: SIGNAL ANY RETURNS ANY, parameters: WORD]; GetAttrProc: TYPE = PROC [sd: SequencerData, key: Attribute] RETURNS [ValueSeq]; SetAttrProc: TYPE = PROC [sd: SequencerData, key: Attribute, values: ValueSeq]; InstanceData: TYPE = REF InstanceDataRep; InstanceDataRep: TYPE = RECORD [ decomposer: DecomposerData _ NIL, -- decomposer object sequencer: SequencerData _ NIL, -- sequencer object context: Imager.Context _ NIL, -- current imager context flags: InstanceFlags _ [], -- instance flags copies: INT _ 0, -- requested copies (< 0 => not known) copy: INT _ 0, -- current copy # pages: INT _ 0, -- # of pages (< 0 => not known) page: INT _ 0, -- current page # procs: REF InstanceProcs _ NIL, -- operations on document instances private: REF _ NIL -- document instance private data ]; InstanceFlags: TYPE = MACHINE DEPENDENT RECORD [ reverse: BOOL _ FALSE, -- => reverse page order granted randomAccess: BOOL _ FALSE, -- => random access to pages supported pageContext: BOOL _ FALSE -- => new context needed for each page ]; InstanceProcs: TYPE = RECORD [ attributes: AttributesProc, -- proc to visit the attributes page: PageProc, -- proc to image a page close: CloseProc, -- proc to close an instance clone: CloneProc _ NIL, -- proc to clone an instance (optional) special: SpecialProc _ NIL -- special operations (optional) ]; AttributesProc: TYPE = PROC [instance: InstanceData]; PageProc: TYPE = PROC [instance: InstanceData, page: CARDINAL, copy: CARDINAL] RETURNS [PageFlags]; PageFlags: TYPE = MACHINE DEPENDENT RECORD [ pageFailed: BOOL _ FALSE, -- page could not be decomposed docFailed: BOOL _ FALSE, -- document can no longer be decomposed imaged: BOOL _ FALSE, -- page had contents to image copyPage: BOOL _ FALSE, -- initialize next page to this one willErase: BOOL _ FALSE, -- next page will be erased allCopies: BOOL _ FALSE, -- results are good for all copies last: BOOL _ FALSE -- page was last page in document ]; CloseProc: TYPE = PROC [instance: InstanceData]; CloneProc: TYPE = PROC [instance: InstanceData] RETURNS [InstanceData]; SpecialProc: TYPE = PROC [instance: InstanceData, op: ATOM, args: LIST OF REF] RETURNS [REF]; END. Ü DecomposerRegistry.mesa Copyright Ó 1991 by Xerox Corporation. All rights reserved. Russ Atkinson (RRA) April 16, 1992 8:28 pm PDT Michael Plass, March 3, 1992 1:08 pm PST Registration of decomposers A sequencer can handle any reasonable number of decomposers (or PDLs - Page Description Languages). Each decomposer is associated with a decomposer object in the central decomposer registry. Registers a decomposer under data.key. Any previous registration for the given key is lost. Some anticipated keys are: $IP Interpress $PS PostScript $PCL HP PCL Removes the registration (if any) for the given data. Looks up a registered decomposer under a given key. NIL is returned when there is no registration. Returns a list of the current registered decomposers. The order is not important. No element in the list is NIL. Attributes and Values Attributes and values, as defined here, are used to get and set job attributes. In some cases the data base underneath the job attributes will use some other form, so the sequencer will have to translate. Types & Procedures specific to the decomposer A decomposer object provides the means to guess at the validity of a document and a means for opening the document for decomposition. Opening a document can be for prescan or for decomposition, or for prescan and imaging. Given data from the decomposer and the sequencer, returns a guess of the probability that the input stream (seq.in) is in a format that can be handled by the decomposer. The probability P should satisfy 0.0 <= P <= 1.0. For PDLs that have a unique (or presumed unique) prefix to their files (like Interpress), the probability can be 1.0 if "Interpress" starts the stream, and 0.0 otherwise. For more dubious PDLs, like PostScript, the probability might be 1.0 if the stream starts with a "%!", 0.9 if the stream starts with "%", and lesser values otherwise (e.g., 0.0 if a syntax error occurs early). The more general a handler is, the less likely that it is the "right" decomposer. For example, a "text" (or ASCII) decomposer can handle simple PostScript files, but presumably should not return a value more than (perhaps) 0.5 at most, given the tendency for PDLs to be encoded as ASCII sequences. Given data from the decomposer and the sequencer, returns an object that describes a decomposition instance for the input in the sequencer. The open operation is used in two ways: for pre-parsing and for printing. The clean operation is used to clean up caches, as might be done periodically to conserve storage or to note the installation of new decomposer data files. Types & Procedures specific to the sequencer A sequencer object provides the means to communicate with the sequencer. A new sequencer object is provided for every document instance. The sequencer flags are used to cache some booleans that are not job attributes. They should only be set by the sequencer. Called when an "interesting" event occurs in the decomposer. In the case where an error is raised but cannot be handled by the decomposer, the info is of type UncaughtInfo, otherwise the info is NIL, or a ROPE that further describes the error. The key is also used to describe the class of error. When info is of type UncaughtInfo, the feedback proc is called on the stack that raised the error. This can be helpful for debugging. If the sequencer wants to abort the decomposition, ABORTED can be raised from the feedback procedure. Called to get a specific attribute; NIL is returned if no value exists Called to set a specific attribute; values = NIL is used to indicate no values Types & Procedures specific to the document instance reverse is TRUE if the sequencer flags requested reverse page order and the decomposer will grant such order. The page index still increases from 1 to N, but the corresponding page imaged should be N to 1. randomAccess is TRUE if the decomposer supports random page ordering with little or no penalty pageContext is TRUE if the decomposer expects a new Imager context for each page (currently, Interpress expects pageContext = TRUE, PostScript expects pageContext = FALSE) The attributes operation extracts the attributes from the document and calls instance.sequencer.setAttr on each attribute found. instance.sequencer.getAttr may be used to examne previously set attributes, including those set by the sequencer. The page operation requests the decomposition of the given page. The first page is number 1. Usually, the page index will start at 1 for the first page in the document and increase by 1 for each page. For multiple copies, the page index will start at 1 for each copy. Page caching and the like may cause the page index to increase by more than one. The PDL must handle skipping pages forwards, potentially by imaging the page into a null context. The copy number indicates the logical, not the physical copy. As a special case, copy = 0 means image in a way that is insensitive to the copy number. The page flags indicate what happened during the page call. pageFailed indicates that the imaging for the page failed, so the results are not reliable. docFailed indicates that the imaging for the page failed, and that further calls for decomposition are fruitless. imaged indicates that some output was produced. copyPage indicates that the next page contents should initially be a copy of the current contents. This is to support the PostScript copypage operator. willErase indicates that the next page will be erased by the decomposer prior to imaging. If copyPage = FALSE and willErase = FALSE then the decomposer assumes that the sequencer will provide an initially blank page. allCopies = TRUE indicates that the results will not change from copy to copy, and may therefore be cached and reused on future copies. allCopies = FALSE indicates that the results may changed from copy to copy, and the decomposer should be invoved on each copy. last indicates that the page produced (if any) was the last one. It is legal to have imaged = FALSE and last = TRUE, which indicates that no page was produced, and that the previous page produced was the last in the copy. The close operation closes down the instance, which may release data specific to the document. After this call, no other calls using the instance will be supported. The clone operation clones an instance, which allows concurrent imaging of a document. Clone is NOT supported by all PDLs, and will be NIL if not supported at all. This procedure may also return NIL if the decomposer can sometimes support concurrent imaging, but not for the requested instance. If a clone is produced, it is the decomposer's duty to serialize calls to the in, out, and err streams. Failure to do so may lead to extremely undesirable results. The special operation performs decomposer-specific operations. ÊO•NewlineDelimiter ™headšœ™Icode™—L˜—Kšœ˜L˜—…—ì>