ps code presentation

Upload: sourabh-jakhar

Post on 12-Oct-2015

20 views

Category:

Documents


0 download

TRANSCRIPT

  • b

    Adobe Confidential 1

    a PostScript RIP The PS interpreter consists of 2 main parts. the product code and the packages. The 2 products are Camelot and cpsi, each having their own functionalities, but both share the same packages which forms the core of the interpreter.

    A short summary on what each of the packages do, should ease the understanding of the flow of the interpretation process.

    Package Overview

    The main packages and their respective functions in the RIP are as follows

    1. language

    This package consists of the basic PostScript language interpreter.

    The functions performed by the files in this package are

    i. Scanning stream ( scanner.c )ii. Tokenizing stream ( scanner.c )iii. Making the PostScript Objects from the tokens ( StmToken in scanner.c )iv. The main execution loop of the RIP is psExecute in exec.c from which

    the respective postscript functions are called

    v. Implementation of the control operators, the major files in this being exec.c, stack.c, dict.c, math.c for their respective areas

  • b

    Adobe Confidential 2

    a Package Overview 2. graphics

    This package is responsible for graphics, under can be divided into

    i. Maintaining graphics state ( color, linewidth, other parameters )This functionality is mainly implemented in gstates.c, psgraphics.c

    ii. Managing path opertators like newpath,closepath,stroke, fillthis is implemented in pathops.c, rect.c, userpath.c.

    iii. Managing patterns All the pattern related implementation is found in fandp.c

    iv. Interpretation of images, this is implemented in image.c, imageint.c etc

    v. Shading interpretation, the files here are shade*.c

    vi. Marking device primitives onto framebuffer is performed if frame device is used, else rendering into displaylist in case of Band device.The implementation is in shademark.c & graphmark.c.

    3. devpath

    The devpath package is the main path interpreter.Its main roles include

    i. It takes care of stroke, fill

    ii. Related functions, like stroke adjustments, miter points, line joins etc

  • b

    Adobe Confidential 3

    a Package Overview 4. font/truetype/buildch

    All the above are font related packages. Their are useddepending on the font type and function.

    i. The font package contains the implementation of the show operator,in fontshow.c, which is the main file. It determines the furtherpath the program takes depending on the type of font chosen.

    ii. The buildch is the font rendering package that does theglyph interpretation.

    iii. The truetype package is used specially for truetype fonts. The truetype glyph building is done in ttbuild.c, but the rendering is done by the common buildch package.

    5. vm

    The vm package is used for PostScript vm maintenance, its main functions are garbagecollection and managing storage of composite objects

    6. device

    This package is implements the primitives storage into the display listand also the retrieving of data from display lists

    i. this implements the different device types like band, frame etc

    ii. the primitives are stored into the display list in the banddevdlwalk.c, where functions like WalkTraps call thestore functions like StoreTrap to store data into the display list

  • b

    Adobe Confidential 4

    a Package Overview iii. The showpage is achieved through the HybridShowPage

    iv. the ProcessBand function is called for the actual rendering, and thisis implemented in banddevprocessband.c

    7. devpattern

    this package is a rendering package used mainly for color conversion.not much is known about this package as of nowthis package is a mystery, it has lots of files.

    8. displaylist

    the displaylist is used to store primitives in buffers. The buffers are managedby this package. some of its major functions are i. managing of display list in RAM and on disk as buffers grow bigger

    ii. its used during rendering for in the renderer

    9. framemarker

    this is a rendering package. this package contains rendering code for all primitives except images.

    10. others

    The other packages play small roles in different part of the executionsome of their functions are

    i. framestorage manages frame buffer and generates checksums

  • b

    Adobe Confidential 5

    a Package Overview ii. fp implements fixed point arithmetic functions

    iii. io implements a wrapper layer to the OS io

    iv. opsys implements a wrapper layer for system calls

    v. pslib implements a memory manager, cache etc

    vi. rest of packages are not that important

  • b

    Adobe Confidential 6

    a Rip basicsAt startup the PS RIP loads PS.VM. The PS.VM contains operator names, resource dictionaries

    etc. The interpreter takes even the operator names from PS.VM file, and it looks up arrays to map operator names to C functions. Also some core objects need to build to startup. Building the VM, each time the RIP starts, would slow it down, and hence PS.VM is used. Thus PS.VM is a snapshot of the VM pre-created for RIP efficiency.

    At startup the command line param supplied are processed by the product running ( cpsi or Camelot ). The product code updates the parameters supplied in its data structures, for later use by the RIP. The below chart shows the RIPS overall flow for CPSI.

    The PS interpreter does its job by executing entities called PostScript Objects. These objects may be numbers, boolean, strings etc. Other objects are executable like operators, procedures etc. The interpreter works by executing these objects in a sequence. In PostScript 2 types of objects are defined, Literal objects and Executable Objects. The Object structure used in RIP is below.

    typedef struct _t_Object {BitField tag:1; /* decides if literal or exec for 0 or 1Access access:3; /* Access is actually a BitField too */BitField type:4;BitField shared:1;BitField seen:1;BitField mayRecycle:1; /* 1: may be recyclable; 0: definitely not */BitField level:5; BitField length:16;

  • b

    Adobe Confidential 7

    a Rip basicsunion {

    /* null */ Int32 nullval;/* int */ Int32 ival;/* real */ real rval;/* name */ PNameEntry nmval;/* bool */ boolean bval;/* str */ charptr strval;/* stm */ PStmBody stmval;/* cmd */ PNameEntry cmdval;/* dict */ PDictBody dictval;/* array */ PObject arrayval;/* pkdary */ PCard8 pkdaryval;/* mark */ Int32 markval;/* save */ Int32 saveval;/* font */ Int32 fontval;/* generic */ PGenericBody genericval;/* gstate */ PGState gstateval;/* cond */ PCondition condval;/* lock */ PLock lockval;/* namearray*/PNameArrayBody namearrayval;/* magic */ PMagicBody magicval;

    } val;} Object;

  • b

    Adobe Confidential 8

    a Rip program flowStart CPSI

    Process command args

    Fill in CPSIEngine,CPSIRasterBuffer

    with relevant parameters

    psExecute( ) starts Parsing PS data

    A function for each operator Is called, like PSMoveTo,

    PSLineTo etc

    showpage operator gives final

    output

  • b

    Adobe Confidential 9

    a PS parsingThe first functionality the RIP has to accomplish is parsing the input PS file. The parsing and

    object creation is done by the StmToken rouctine in scanner.c. The StmToken routine reads the input string character wise creates objects from them. If the object created is a operator the StmToken returns a executable Object to its caller, which is psExecute. When StmToken meets operand objects it pushes them onto the operand stack.

    For.e.g consider the input PS string 100 100 moveto

    Its execution through StmToken is traced below.

    Step 1. Read in 1, recognizes numbers, starts begnum sectionStep 2. Read in 0, recognizes as number, a new number has been begun earlier and so

    appends 0 to current number, to get 10. Step 3. Read in 0, a number appends to current number to get 100.Step 4. Read a space. End current number and object created. As object is not executable

    IPushSimple pushes it onto stack.Step 5. Read in 1. Steps 1-4 are repeated again.Step 6. Read in m, recognized as character, starts begname section to create nameStep 7. Read in o, append to current name.Step 8. The above continues till EOL is met, then a executable object is returned to

    psExecuteStep 9. psExecute calls function PSMoveTo which was registered as the function for

    moveto operator Step 10. If we give a invalid operator say mmoveto the psExecute fails to find the name

    as defined and a error is flagged and interpretation stops

    This shows the basic parsing process of the RIP.

  • b

    Adobe Confidential 10

    a How is the opcode determined?

    When the StmToken encounters a name object it 1. Tries to look for the name in a matching name in the dictionary.2. FastPName() is called which first hashes the name. 3. Then it searches for name in the hash chain.4. If the name matches then it returns a matching name object5. Otherwise a new name object is created and returned.

    Once StmToken gets the object the control is transferred to psExecute()1. The currentCmd is stored in ob.length2. psExecute() transfers control to the relevant function by (*cmds.cmds[ob.length])();

    *cmds.cms[] is like a lookup table where the opcodes are mapped to the relevant function. Some of these mapping are defined in languagenames.h

    Examplecmd = movetoob.length = 263psExecute calls PSMoveTo() on this opcode.

  • b

    Adobe Confidential 11

    a Stack The PS Stack is the main structure the interpreter maintains. The operand stack holds data that

    will be consumed by the operators. To illustrate how the stack works, consider the earlier example where the integer type object ( 100 ) was pushed onto the stack using IPushSimple function.

    This function just takes in the stack pointer, checks for overflow and pushes the object and updates the stack top pointer. If the input string was 100 moveto then a stackunderflow error occurs since 2 objects are not available to be popped out for moveto.

    The PS manages 2 other stacks, the dictionary stack and the execution stack. The dictionary stack contains the holds only dictionary objects. The execution stack holds executable objects. If for some reason the interpreter pauses it pushes the executable object on this stack to be able to resume later

  • b

    Adobe Confidential 12

    a Graphics in PS

    PostScript provided a great deal of functionality for graphical manipulations. There are seven kinds of operators in PS

    1. Graphic State Operator which modify the graphic state, the global framework within which the other graphical operators execute

    2. Coordinate system and matrix operators are responsible for transformation from the user to device coordinates. They are also used for transformations like skew, rotation, scaling, translation

    3. Path Construction Operators current path which define shapes and line trajectories. 1. 0 0 moveto moves the current point to 0, 0 in in the user coordinate and sets it as

    the initial position of any path4. Painting Operators these operators are used for painting graphical elements into the raster

    memory of the output device. 5. Glyph and Font operators - select and paint character glyphs from fonts. Most of these are

    grouped with path and paint operators. 6. Device Setup Operators establish an association between the raster memory and a

    physical output device like a printer.7. Output operators Once a page has been completely described, executing an output

    operator transfers the page to the output device.

  • b

    Adobe Confidential 13

    a Graphic StateAll the graphical manipulation in PS takes place through the graphical state

    typedef struct _t_GState {GenericBody header;Mtx matrix, /* CTM */

    defaultMatrix; /* used by defaultmatrix, initgraphics */PMakeFontEntry pMfe;PReadyFontEntry pRfe;DictObj fontDict, pfontDict;Path path;Path clip;integer clipID; /* used in distillery */PCState clipStack;Integer clipCount; /* number of entries on the clipStack */Cd cp;real lineWidth;real miterlimit;real devhlw;AryObj dashArray;real dashOffset;Color color; Screen screen;TfrFcn baseTfrFcn, tfrFcn;

  • b

    Adobe Confidential 14

    a Graphic StateRendering rendering;real flatEps; /* epsilon for curve flatness test */real smoothness; /* error percentage for smooth shading */DevPoint screenphase;PDevice device;boolean isCharPath:1boolean noColorAllowed:1; /* following fields should total to 16 bits */boolean saveState:1;boolean strokeAdjust:1;boolean circleAdjust:1;boolean overprint:1;boolean overprintmode:1;BitField lineCap:2;BitField lineJoin:2;boolean colorRemapped:1;boolean useCIEColor:1;BitField unused2:3;

    /* end of 16 bits */real strokeWidth;PGState previous;Object origColorSpaceObject;char *extension; /* for experimental additions */

    } GState;

  • b

    Adobe Confidential 15

    a Graphics StateThe PS needs to maintain a graphics state to keep track of the current execution state. This is done

    though a global graphics state variable gs. gs is always the current graphics state. The gs holds the current transformation matrix which is the key to conversion from user co-ordinate system to the device co-ordinate system. The CTM is on the form [a b c d tx ty] where tx & ty are translation factors in x and y direction, a,b,c & d are the scaling/rotation factors. Consider the operators that modify the CTM.

    Case 1. 100 100 translate, the PSTlat function pops the 100 100 from stack and passesthem to the Tlat routine. This routine adds the translation values after convertingthem to device space to the CTM->tx and CTM->ty ( gs->matrix is CTM ).

    Case 2. 10 10 scale, the PSScal function pops the 10 10 from stack and passes them tothe Scal routine, which initializes the CTM->a and CTM->d to scaleX and scaleYrespectively.

    Case 3. 20 rotate, the PSRtat function pops the 20 from stack and passes them to theRtat routine, which initializes CTM->a=CTM->d = cos(angle) and CTM->c= -CTM->b=sin(angle);

    Other than the above routines there are many functions that modify the graphics state. Some of the important routines and the variables they modify are

    NewPath this routine initiates a new path, by clearing the gs->path structure that holds the current path.

    PSLineWidth this routine sets a new line width chosen in gs->linewidthPSSetStrokeAdjust this routine sets the strokeadjust flagGSave saves the current graphics state by pushing it onto a graphics state stack for

    restoring it later stage if necessaryGRestore restores the graphics state from the graphics state stackPSMoveTo sets the current point variable in gs ( gs->cp )

  • b

    Adobe Confidential 16

    a Paths

    The paths define shapes, trajectories and regions of all kinds. It comprises straight and curved line segments which might be connected or disconnected. Current path of graphics state contains all the information about a path being constructed. Clipping path outlines the clipping region.

    How are paths constructed ? There are essentially 3 steps required:

    1. Modify the CTM if required2. Call the procedures to construct the path3. Invoke the painting operator to mark the path

    Example:0 0 moveto100 100 lineto 100 0 linetoclosepathstroke

    2

    33

  • b

    Adobe Confidential 17

    a Paths (MoveTo)

    100 100 moveto

    when the parser reaches this position the operands for moveto have already been placed on the stack. After the command is parsed control returns to psExecute() which then in turn calls PSMoveTo().

    PSMoveTo()1. PopPCd() gets the coordinate to which the moveto is performed, (100 100) in this case.

    They are stored on the top of the opStk2. Then TfmPCd() converts this point to device coordinates3. PSMoveTo then calls DPR_MoveTo() which then in turn calls InnerDPR_MoveTo()4. InnerDPR_MoveTo() finds out whether a moveto was performed in the pervious step, if it

    was then the previous point is removed from the path.5. The BBox is increased to accommodate the current point6. It adds this point on which the moveto was performed to dpOpnds in the path and the length

    of the path is incremented7. gs->cd = cd, the current point in the graphic state is updated

    lineto operates in a similar manner.

  • b

    Adobe Confidential 18

    a Stroke

    The moveto, lineto, arcto operators just define the path. It is added to the display list only when a stroke operator is called.

    PSStroke()1. It determines whether the color space is patterned or not. If it is then the pattern is cached.2. A call to Stroke( gs->path ) is made3. If the path is a char path then a stroke path is created using StrkPath()4. All kinds of paths which are not list paths are converted to list path5. Then the stroke parameters are filled up by a call to PS2CurrentStrokeParams()6. GetDevClipBBox() in viewclip.c returns the BBox for the current clip and and the view

    clip7. After all the path parameters have been set StrokeDevPath() is called which in turn calls

    InnerStrokeDevPath()8. The control passes from DPFinStroke() in devstroke.c to StdTrapsFilled() in graphmark.c

    to HybridMark() in banddevmain.c where a Display List is created and marked.9. The control then returns to PSStroke() where the memory for the path is freed. 10. The current point gs->cp is reinitialized to fpZero.

  • b

    Adobe Confidential 19

    a Graphic PrimitivesThe graphic primitives are added to the Display List in form data in the NDLBuffer when we perform a

    stroke.

    PSStroke() StdInitMark()

    StrokeDevPath()

    creates a DevMaskMaker

    InnerStrokeDevPath() PreStroke() devstroke.c

    Sets stroke param, s->doing vectors, s->dashed, s->strokeAdjustCase and then sets the half width using setHalfWidth()

    DPFinStroke()graphmark.c

    MarkDevPrim() graphmark.c

    If the path is not empty

    HybridMark() banddevmain.c

    Sets up the colorspace, gs->colorspace->patterned then get the pattern object else setup using gs->color

    BdMark() banddevmain.c

    NewDLResources() banddevmain.c

    DLCreate() displaylist.c

    Creates a new DisplayList and

    initializes the PDLBandHeaders

    BandBdMark() banddevdlwalk.c

    Walk proc banddevdlwalk.c

    This is the final step where the data is added to the NDLBuffer for each band using macros defined in display.h. The data is piced upfrom here during the showpage

    If no DL

    Store proc displaylist.h

  • b

    Adobe Confidential 20

    a Display List

    A display list is an internal representation of the marks that have been painted on the current page or previous pages but have not yet been scan-converted into raster memory. Display List for a page are processed when it is time to print the page. Graphic elements are retrieved from the list and rendered into the framebuffer storage for subsequent delivery to the printers imaging machinery.

    Band

    Page

    Display List

    PDLBandHeader

    NDLBuffer NDLBuffer NDLBuffer

    P

    a

    g

    e

    S

    i

    n

    k

    M

    o

    d

    e

    l

  • b

    Adobe Confidential 21

    a ClippingClipping is limiting the drawing area by defining a definite boundary for the drawing to be done

    in. In PS we can define a clipping path by building a path and using the clip operator. The new clipping area will be the intersection of the constructed path and the existing clipping path. For. E.g.. Consider defining a square area as the clipping path. On executing the clip operator the following actions are performed.

    Step 1. The PSClip function is called for the clip operator. This acts only as a wrapper and calls CurrentGStateDoClip routine.

    Step 2. The ReducePathClipInt calculates the bounding box of the current path Step 3. The 2 bounding boxes are considered and the intersection is calculated as the new

    clipping area.Step 4. The clip path is calculated and updated into gs->clip which holds current clipping

    information.Step 5. When we stroke a path next, the point to be marked is tested for insideness w.r.t

    the clipping boundary to decide whether to mark or not to mark.

  • b

    Adobe Confidential 22

    a Fill HandlingThe fill operator is handled in the following method.

    Step 1. fill encountered, a call to PSFill in pathops.c is madeStep 2. If pattern filling is needed PatternFill is called, else Fill is calledStep 3. Fill calls FillDevPath in devpath.c and sends it current path and current marking

    stateStep 4. This routine calls EnumerateDevPath to mark the path outline and then calls the

    StdTrapsFilled routines in graphmark.c code to do the actual filling. Step 5. After a fill, a newpath in performed.Step 6. To evaluate whether a given point is inside or outside a path PS uses the winding

    number rule or the even odd rule. The fill routine uses one of the algorithm tocheck for insideness of a point

    Step 7. In case of a pattern being used for filling, the pattern itself is first executed using PatternFill, the filled pattern is cached and the Fill routine continues. The MarkPattern routine does the actual pattern marking

    Step 8. The presence or absence of a pattern is tested through a flag in the graphics stategs.

  • b

    Adobe Confidential 23

    a FontsPS supports various types of fonts like Type 0, Type 1, Type 2, Type 3, CID fonts,

    TTF fonts ( Type 42 ) etc. The type of a font should be known for the code to be able to call the correct glyph building procedures. The type is always encoded in the font dictionary under the FontType key.

    The font always contains all glyph specific data like width, height, kerning data, side bearing etc. Also encoded is the character outline as a sequence of co-ordinates w.r.t the font co-ordinate system. These points define the outline of the font using lines and curves. The exact method depends on the font types. For e.g TTF uses quadratic splines to store curve info while Type 1 font uses cubic splines. The below image shows an example of a character outline and its contour point details

  • b

    Adobe Confidential 24

    a Font Handling Consider a generic example below. The required font has already been chosen at this point, we

    will see how the show operator works in this case> (hello world) show

    Step 1. The string hello world is pushed onto the stack as a object of type stringStep 2. The show operator is implemented in PSShow in fontshow.c, it pops the string on

    the stack and calls ShowInternal, the parameters for show are passed to it in a ShowState structure

    Step 3. The ShowInternal sets some necessary variables like currentpoint, type of show etc.

    Step 4. The next major function is FastBuildGlyph which calls the BuildGlyph function based on the font type. i.e. If a type 1 font is being used it calls BuildGlyph1, for a TTF font it calls BuildGlyph42. These font specific functions are defined in the current font manager structure.

    Step 5. The corresponding BuildGlyph function calls CallBC which is the main character building routine.

    Step 6. The CallBC routine makes use of the CallBCCharOutline or CallBCCharBitmap depending on size of glyph to be rendered. These routines perform the actual rendering.

    Step 7. Once the character has been rendered, the current point is updated to the next position using the character width information and the next character is taken forprocessing.

    The above steps form the basic font handling routines. All shows go through the CallBC routine, and the ShowInternal in fontshow.c.

  • b

    Adobe Confidential 25

    a Interpretation of ImagesPS supports image rendering. In PS, images are specified using some basic properties like height,

    width, color depth and the color values themselves are specified as a matrix of values of height x width. To understand interepreteation of images let us assume that the PS interpreter meets a image operator and all the necessary information are supplied to it. The following steps can summarize the interpretation of the image.

    Step 1. The top level function called on encountering the image operator is PSImage.Step 2. The PSImage saves current graphics state using GSave and calls DoImage for

    further processingStep 3. DoImage pops the necessary information from stack, like height, width, matrix etc

    and fills up the ImageObj structure, which is sent to ImageInternal routine.Step 4. The ImageInternal routine runs a loop son imagerows until it becomes 0, each

    time reading a slice of data through ReadSlices, and the data is stored in theImageObj structure.

    Step 5. This image information is sent to the Mark routine for the final rendering. Thisprocess continues for all imagerows.

  • b

    Adobe Confidential 26

    a ShowpageThe content of all the PS operators does not generate any printed output until a showpage is

    performed. The PS interpreter holds are rendered data in display lists and only on occurrence of showpage are these written to the output media. If a PS file has no showpage then, no output is generated. The different steps that finally print the data are as follows

    Step 1. When RIP meets a showpage operator, a the routine PSShowPage is called, this routine is only a wrapper which calls PSShowPageInternal

    Step 2. The PSShowPageInternal finds number of copies of output to be generated and then calls CurrentGStateDoShowPage

    Step 3. This routine retrieves the page feed information and checks if manual feed is on, before calling the HybridShowPage

    Step 4. HybridShowPage decides if color separation is needed, and it fills up the necessary information for printing in the relevant structures and passes them to PSPCHandoffPage

    Step 5. The PSPCHandoffPage fills up the PrintPage structure and sends it to the HandoffPage procedure in the PageSink object.

    Step 6. The HandoffPage receives PageSink and repeatedly uses the RenderBandcallback routine in the PrintPage to render a band each time.

    Step 7. The above steps are generic and varies for the product. In case of Camelot the HandoffPage in campagecontrolST.c is called, and it is sent the PrintPage and current PageSink instance.

    Step 8. The HandoffPage uses the display list constructed to render data band by band. For each band the WriteBand routine is called, which writes out data on standard output. Here RenderBand is WriteBand

  • b

    Adobe Confidential 27

    a Man Pages

    Considering that most of our work is around PS, there is usually a need to find out about a operator at some point. Its almost impossible to remember all the operators and their argumanets and functions. What I suggest we make a set of man pages for instant reference. This can be of great use to everybody working on PostScript.

    How is the opcode determined?Graphics in PSGraphic StateGraphic StatePathsPaths (MoveTo)StrokeGraphic PrimitivesDisplay List