      <                                                            0          *                  PROGRAM REFERENCE FOR KIC      (                     Giles C. Billingsley    -               Electronics Research Laboratoryi  9    Electrical Engineering and Computer Science Departmentx  *                   University of California  +                  Berkeley, California 94720         2                           _A_B_S_T_R_A_C_T    7           The internal structure of  the  KIC  interac-u7      tive,  color  graphics editor is explained in thiso7      report.  The database, user interface, and  systemk7      dependencies  are  examined,  and  information  iso7      presented to assist the programmer who would  wishh      to extend the KIC program.        September 4, 1983t                                                          <                                                            1          2                          _C_h_a_p_t_e_r _1      <                         _I_n_t_r_o_d_u_c_t_i_o_n        <      KIC [1,2] is  an  interactive,  two-dimensional,  color  < graphics editor intended primarily for the mask level design  < of integrated circuits.  It is written in the C  programming  J language and runs in either a _U_N_I_X[1] or _V_M_S[2] environment.    <      KIC has  been  designed  as  a  powerful,  inexpensive,  < user-friendly  graphics  editor that will run on most low to  < medium performance graphics terminals.  Data  that  is  gen-  < erated  by KIC can be represented by an intermediate graphic  < description language,  such  as  CIF  (Caltech  Intermediate  H Form) or Calma _S_T_R_E_A_M,[3]  which  permits  the  data  to  be  < easily  transported  to  other  layout  systems.   Also, the  < geometric database used by KIC can be used to  interface  to  9 other tools, such as a layout rules checking program [8].,    <      The internal structure of the KIC program is  described  < in  detail in this report.  The reader must be familiar with  < the C programming language as defined in [3] or [9].   Other  < KIC  documentation  includes  a database manual and a user's   _________________________n1 9  [1] UNIX is a trademark of Bell Laboratories.B5 9  [2] VMS is a trademark of Digital Equipment Corp.t, 9  [3] STREAM is a trademark of Calma, Inc. 9                <                                                            2    < tutorial, both included as appendices  to  this  report.   A  < programmer  should  be  thoroughly familiar with this report  < and these two appended manuals before attempting an addition  " or enhancement to the KIC program.    <      KIC can be viewed as four major subsystems,  as  illus-   trated in Figure 1.    98                _f 98      pointing | | 98       device  |_|& 98                \     ------------& 98                 \    |          |& 98                  \   | Graphics |& 98                   \__| Terminal |& 98                      |          |& 98                      ------------! 98                            |P, 98                 ...........|..........., 98                 . KIC      |          ., 98   ----------    .    -------------    ., 98   | MFBCAP |-------->|Model Frame|    ., 98   |Database|    .    |   Buffer  |    ., 98   ----------    .    -------------    ., 98                 .          |          ., 98                 .  -----------------  ., 98                 .  |Window/Viewport|  ., 98                 .  |    Manager    |  ., 98                 .  -----------------  ., 98                 .          |          ., 98                 .   ---------------   ., 98                 .   | CD Database |   ., 98                 .   |             |   ., 98                 .   | ----------- |   ., 98                 .   | |Fast  CIF| |   .J 98                 .   | |  Parser | |   .                    ----------K 98                 .   ---------------   .      KICToCIF     /  Other   \fK 98                 .          |          .  ---------------->|   CIF    | K 98                 ...........|...........  |   CIFToKIC     \ Variants /PJ 98                            |             |                 ----------/ 98                            |             | H 98                        ---------         |                 --------I 98                       /   KIC   \<--------   KICToSTRM    / Calma  \4I 98                       |  or CD  |<----------------------->| STREAM | I 98                       \  Files  /            STRMToKIC    \ Format /gH 98                        ---------                           -------- 990                          _F_i_g_u_r_e _1.                  <                                                            3    @      KIC uses the _C_D (CIF Database) relation database system  < that manages a set of files.  Each file contains the defini-  < tion of a layout-cell that is stored as an ASCII CIF  symbol  < description [5].  A cell definition can contain instances of  < other cells, and thus  the  database  supports  hierarchical  < layout  descriptions.   Other  layout formats, such as Calma  < STREAM format, can be obtained from CD translation  routines  < [11].   The  CD database package reads these layout descrip-  < tions from disc files  and  transforms  them  into  virtual-  < memory data structures.  This package is described in detail  < in Chapter 2.  A major part of  this  process  concerns  the  < parsing  of  CIF  data from the resident disk files.  A fast  < CIF parser has  been  developed  for  this  purpose  and  is   described in Chapter 3..    <      KIC is designed to run on a wide range of raster graph-  < ics terminals or frame buffers and indeed has been used with  < several devices including the AED 512 and 767, the Tektronix  < 4113  and  4105, the HP2648A, the Metheus Omega-400, and the  < Masscomp MC500 series computer.  KIC uses the notion  of  an  F _i_d_e_a_l color graphics frame buffer, and a separate package of  F routines maps commands for this _i_d_e_a_l frame  buffer  to  the  < real  device.   This package can be a set of hard-coded rou-  \ tines for the particular terminal, or the _M_o_d_e_l _F_r_a_m_e _B_u_f_f_e_r  < (MFB)  package  can  be used.  MFB is a terminal independent  < graphics package that uses an ASCII database  file  (MFBCAP)  < to represent the frame buffer characteristics in an extended  Z UNIX termcap format; see _t_e_r_m_c_a_p(_5) and _c_u_r_s_e_s(_3) in the BSD                  <                                                            4    < UNIX  programmer's  manual.   MFBCAP  and the associated MFB  < routines are documented in Appendix D and E.  A  description  < of  how  to interface KIC to a new graphics terminal is con-   tained in Section 4.6.                                                                                                                <                                                            5      2                          _C_h_a_p_t_e_r _2      ?                       _T_h_e _C_D _D_a_t_a_b_a_s_e         - _2._1. _I_n_t_r_o_d_u_c_t_i_o_n     <      CD (CIF Database) is a  package  of  C  procedures  for  < managing CIF databases at an object level; geometric objects  < are modeled as CIF geometries and grouped  as  CIF  symbols.  < For  a description of the CIF language, see [4] or [5].  The  < KIC program is only one application of the CD database pack-  < age,  other  applications including language conversion pro-  3 grams between KIC/CD format, CIF, and Calma STREAM.C    <      Because the data model of CD is CIF,  the  CD  database  < inherits  both  the  advantages  and  limitations of the CIF  < language.  As an example, one important feature  of  CIF  is  < that it is hierarchical.  However, called and placed symbols  < can not be magnified or arrayed without adopting nonstandard  < extensions  of the language.  Such limitations are described  ( in the various sections of this chapter.    <      The reader should be aware of the following  CD  termi-  H nology:  a  _m_a_s_t_e_r refers to the definition of a symbol, and  L an _i_n_s_t_a_n_c_e refers to a  call  and  placement  of  a  symbol  j within a _m_a_s_t_e_r.  To explain the phrase _t_r_a_v_e_r_s_i_n_g _a _s_y_m_b_o_l,  < think of the symbol as a tree structure where  each  element  < is  an  instance  that is linked to its master.  A procedure                  <                                                            6    < that traverses a symbol  would  visit  each  branch  of  the  H symbol-instance  tree  structure.  Finally, a _l_a_m_b_d_a coordi-  < nate is one that is within the coarse resolution of CD;  for  < example,  if  the CD database unit is one one-hundredth of a  < micron and the coarse resolution of CD is one hundred  data-  < base  units,  then  the  minimum lambda value is one micron.  < This coarse resolution allows coordinates to be  represented  < as  integers  while providing a finer resolution when smooth   contours are required.    H      When a symbol is opened via the _C_D_O_p_e_n() routine, it is  < mapped  into  main  memory from local or library files, each  < storing one CIF symbol definition.  Also, all  symbols  that  < are  called by the symbol are read into main memory.  A sym-  X bol that has been opened is referenced by a _s_y_m_b_o_l  _d_e_s_c_r_i_p_-  B _t_o_r  defined  in the next section.  To reflect at its secon-  < dary storage site the changes to  a  symbol  that  has  been  L opened, a program invokes the _C_D_U_p_d_a_t_e() routine.  To remove  < open symbol unknown from CD (i.e., to remove  it  from  main  ? memory), a program invokes the _C_D_C_l_o_s_e() routine.;    <      Geometries or objects are collectively organized  in  a  < symbol  or cell.  The types of valid objects within a symbol  < are boxes, polygons, wires, round flashes, and symbol  calls  < or  instance  arrays.   For each object there is a procedure  < that creates the object in a particular symbol on a particu-  N lar  layer.   These  data  insertion  routines are _C_D_M_a_k_e_P_o_-   _l_y_g_o_n(), _C_D_M_a_k_e_W_i_r_e(), _C_D_M_a_k_e_B_o_x(), and  _C_D_M_a_k_e_R_o_u_n_d_F_l_a_s_h().                    <                                                            7    D The  CIF  _c_a_l_l  has been extended to handle instance arrays.  L To create an instance array, a program invokes the  _C_D_B_e_g_i_n_-  l _M_a_k_e_C_a_l_l(),  _C_D_T(),  and  _C_D_E_n_d_M_a_k_e_C_a_l_l()  procedures.   All  H object creation procedures return a  pointer  to  an  _o_b_j_e_c_t  P _d_e_s_c_r_i_p_t_o_r that has the purpose of referencing the object in  L the database.  The _C_D_D_e_l_e_t_e() procedure  removes  an  object   from a master cell.     <      There are several routines  for  acquiring  or  storing  < information  that is specific to a particular object or sym-  R bol.  The _b_o_u_n_d_i_n_g _b_o_x of an object  can be accessed via the  D _C_D_B_B()  routine.   Associated with each object is an integer  N information field that can be accessed  by  the  _C_D_S_e_t_I_n_f_o()  H and  _C_D_I_n_f_o()  routines for extending that object's descrip-  < tion.  In addition to the integer  information  field,  each  < object  can  have a linked-list of property strings that are  j accessed  via  the  _C_D_A_d_d_P_r_o_p_e_r_t_y()  and  _C_D_P_r_o_p_e_r_t_y()  pro-   cedures.    <      CD uses a two dimensional, rectilinear  or  "Manhattan"  < transformation  package  that can be used by any CD applica-  < tion program.  The transformation package  is  described  in  < Section  2.5.   With  the  transform  package, a program can  < define a current transformation  composed  of  translations,  < reflections,  and  rotations,  obtain the transformation and  < inverse transformation of coordinates,  and  manage  several  , transformations with a transformation stack.    <      Traversing the contents of a master is performed with a                  <                                                            8    b _o_b_j_e_c_t _g_e_n_e_r_a_t_o_r _l_o_o_p.  In the context of CD, an object gen-  < erator is a set of procedures  that  allow  the  program  to  < sequentially  access  objects  on  a  particular  layer that  < intersect a particular area.  To begin a generator,  a  pro-  N gram  would  invoke  the _C_D_I_n_i_t_G_e_n() routine with an area of  < interest and a specific layer as parameters.  The  procedure  b will  return a pointer to a _g_e_n_e_r_a_t_o_r _d_e_s_c_r_i_p_t_o_r, defined in  F the next section.  Every invocation of the _C_D_G_e_n() procedure  < will  then  return  a  pointer to an object descriptor whose  < bounding box, transformed  by  the  current  transformation,  < intersects  the area and lies on the particular layer.  When  F _C_D_G_e_n() has returned all objects that qualify, the procedure  0 returns a null pointer to the object descriptor.    H      The _C_D_T_y_p_e() procedure returns the type  of  an  object  < descriptor,  (e.g.,  box,  polygon, etc.) and can be used to  < dispatch to a type-specific procedure for  manipulating  the   object.     <      CD provides several routines for translating to or from  D CIF.   The  _C_D_T_o()  routine  translates CIF directly into CD  H format.  _C_D_F_r_o_m() translates a CD symbol  hierarchy  into  a  P CIF  file.   Also, the _C_D_P_a_r_s_e_C_I_F() procedure will build the  < CD database from a CIF file rather than from a directory  of  < symbol files.  This latter procedure is useful for translat-  < ing CIF into other layout languages such  as  Calma  STREAM.  , These routines are explained in Section 2.7.                        <                                                            9    > _2._2. _C_D _D_e_s_c_r_i_p_t_o_r _T_y_p_e_s    <      There are several descriptor types  defined  as  struc-   tures in the cd.h file.o  3 98            descriptor type      structure namea, 98            symbol                     s- 98            symbol table               bug, 98            master-list                m, 98            object                     o- 98            label                      las- 98            polygon                    poi, 98            round flash                r, 98            wire                       w, 98            call                       c, 98            transform                  t, 98            generator                  g0 98            property                   prpty, 98            layer                      l, 98            path                       p 99<      The following sections describe the various descriptors   in greater detail.  H _2._2._1. _T_h_e _S_y_m_b_o_l _D_e_s_c_r_i_p_t_o_r    B      The symbol descriptor is defined in the  _c_d._h  file  as   follows:   98        /* 98         * Symbol desc.e 98         */  98        struct s {1 98            int sLeft, sBottom, sRight, sTop; 98            int sBBValid;c 98            int sA, sB;n 98            char *sName; 98            short sInfo;0 98            struct o ***sBin[CDNUMLAYERS+1];& 98            struct m *sMasterList;) 98            struct prpty *sPrptyList;o 98            }; 99<      A symbol descriptor is associated with each symbol that  < resides  in  the database and is necessary for accessing the                    <                                                           10    < objects contained in the respective symbol.  This descriptor  H is  allocated  and  initialized by the _C_D_O_p_e_n() routine only  J and released by the _C_D_C_l_o_s_e() routine.  All  current  symbol  < descriptors  are referenced in the CD symbol table; the sym-  6 bol table descriptor is described in the next section.    F      The _s_N_a_m_e member is  a  pointer  to  a  null-terminated  < character  string containing the name of the respective sym-  < bol.  The bounding box of the symbol in coordinates is given  h by  _s_L_e_f_t,  _s_B_o_t_t_o_m, _s_R_i_g_h_t, and _s_T_o_p.  Because the bounding  < box of the symbol depends on the objects  contained  in  the  < symbol,  there is a time (for example, when the CIF is being  < parsed or the symbol is being opened) when the bounding  box  L is  not  valid.   This  condition is flagged by the _s_B_B_V_a_l_i_d  ( boolean member of the symbol descriptor.    D      The _s_A and _s_B members define the  magnification  factor  < of the symbol.  KIC and the CD database do not permit symbol  < magnification, and therefore these members are always set to  < unity.  If such a feature is added to KIC, it should be done  < at the symbol level rather than at the object  level  to  be  < consistent  with  the CIF data model.  For example, the mag-  < nification factor of any geometry or instance  in  a  symbol  < would always be unity.  However, the magnification factor of  < a symbol definition that is  called  by  another  would  not  < necessarily  have  to  be  unity.  This symbol magnification  @ factor would be defined by a ratio of two integers in the _D_S  < command in the respective symbol file and these two integers                    <                                                           11    D would become the _s_A and _s_B members in the symbol  descriptor    when the symbol is opened by CD.    <      The objects contained in a symbol are  organized  in  a  < storage bin structure that is explained in greater detail in  < Section 2.3.  In brief, the storage bins are a three  dimen-  < sion  array  of  doubly linked object descriptor lists; each  < object list is indexed in the array of bins according to its  < layer  and  the  lower, left coordinate of its bounding box.  D _s_B_i_n is a pointer to the  symbols  storage  bins.   The  bin  < structure    is    declared    as    a    triple    star   (  \ ***_s_B_i_n[_C_D_N_U_M_L_A_Y_E_R_S+_1] ) because the bins are  allocated  on  < demand  for  each  layer  with layer zero being the instance   layer.    F      _s_I_n_f_o is the integer information field  of  the  symbol  P and  is  initialized to zero, and _s_P_r_p_t_y_L_i_s_t is a pointer to  P the symbol property list.   If  the  _s_P_r_p_t_y_L_i_s_t  pointer  is  R NULL,  the property list is empty.  _s_M_a_s_t_e_r_L_i_s_t is a pointer  < to the symbol's master-list that  is  explained  in  greater  
 detail below.o  U _2._2._2. _T_h_e _M_a_s_t_e_r-_L_i_s_t _D_e_s_c_r_i_p_t_o_rB    B      The master-list descriptor is defined in the _c_d._h  file   as follows:t   98        /*  98         * Master-list desc. 98         */e 98        struct m {$ 98            int mReferenceCount;1 98            int mLeft, mBottom, mRight, mTop;  98            char *mName;       9   9    > 8                                                          12    ( 98            struct m *mPred, *mSucc; 98            }; 99<      Every symbol in CD has one  master-list.   The  master-  < list  is  a  doubly linked-list of structures containing one  < link for each symbol that is called by the  respective  sym-  F bol.   The  _m_N_a_m_e  member  is a pointer to a null-terminated  < character string containing the name of the  called  symbol.  < The  number  of times that the symbol is referenced is given  Z by _m_R_e_f_e_r_e_n_c_e_C_o_u_n_t.  The untransformed bounding box  of  the  h symbol  is  given by _m_L_e_f_t, _m_B_o_t_t_o_m, _m_R_i_g_h_t, and _m_T_o_p.  Note  N that if symbol _m_N_a_m_e was opened by an invocation of the _C_D_O_-  B _p_e_n()  routine,  the  bounding  box  of  the returned symbol  ` descriptor would be identical to _m_L_e_f_t, _m_B_o_t_t_o_m, _m_R_i_g_h_t, and  
 _m_T_o_p.e    <      The purpose of the master-list is to simplify the  pro-  < cedure  of  reflecting  any change to the bounding box of an  < instance in the bounding box of  all  its  masters.   For  a  @ brief  example,  consider  symbols  _X  and _Y that contain an  @ instance of symbol _Z.  If the bounding box of  symbol  _Z  is  N changed, a call to the _C_D_R_e_f_l_e_c_t() procedure with the symbol  > descriptor of _Z as an argument would cause  the  master-list  < of  every  resident symbol in the CD database, except symbol  @ _Z, to be searched for an occurrence of _Z.  When an  instance  > of  _Z  is found, the bounding box of the instance, as speci-  < fied in the respective master-list structure member, is com-  > pared  with  the computed bounding box of symbol _Z; if there  < is a difference, the master-list is modified and the  bound-       9          <                                                           13    < ing  box of the master symbol is recomputed.  At the comple-  > tion of this procedure, the bounding boxes of symbols _X  and  > _Y  will  have  been  recomputed to reflect the change in the  P bounding box of _Z.  In other words, the _C_D_R_e_f_l_e_c_t()  routine  h has the purpose of performing _b_o_u_n_d_i_n_g _b_o_x _p_r_o_p_a_g_a_t_i_o_n which  6 is further explained in Section 2.4.9 on CD integrity.    <      The symbol call descriptor also contains a pointer to a  < master-list  descriptor.   This is further explained in Sec-  : tion 2.4.4 that describes the CD object creation routines.  X _2._2._3. _T_h_e _S_y_m_b_o_l _T_a_b_l_e _D_e_s_c_r_i_p_t_o_r    <      The CD symbol table and  symbol  table  descriptor  are  * defined in the _c_d._h file as follows:   98        /*A 98         * Hash table of symbol descs keyed on symbol's name.9 98         */u 98        struct bu { ' 98            struct s *buSymbolDesc;8" 98            struct bu *buPred;" 98            struct bu *buSucc; 98            };6 998        struct bu *CDSymbolTable[CDNUMLAYERS+1]; 99<      The procedure by which CD remembers a  resident  symbol  < is  a  hash table of symbol descriptors that is keyed on the  < name of the respective symbol.  Each entry in the hash table  V named _C_D_S_y_m_b_o_l_T_a_b_l_e is a null-terminated, doubly linked-list  @ of _b_u structures that contain a pointer to  an  open  symbol  < descriptor.   A procedure for computing the entry point into   the hash table is shown below:   9         9   9    > 8                                                          14     98        #include "cd.h"  9 98        /*# 98         * Function GetSymbol() F 98         * Find and return the symbol descriptor of symbol 'Name'. 98         */b% 98        struct s *GetSymbol(Name) D 98            char *Name;     /* name of the symbol to be found */ 98            {l 98            int Key; 98            char *cp" 98            struct bu *Bucket; 99 8            cp = Name;" 98            while(*cp != NULL)* 98                Key += (int)( *cp++ );< 98            Bucket = CDSymbolTable[ Key % CDNUMLAYERS ];& 98            while(Bucket != NULL){F 98                if(strcmp(Bucket->buSymbolDesc->sName, Name) == 0)5 98                    return(Bucket->buSymbolDesc);t, 98                Bucket = Bucket->buSucc; 98                }  98            }  99H _2._2._4. _T_h_e _O_b_j_e_c_t _D_e_s_c_r_i_p_t_o_r    B      The object descriptor is defined in the  _c_d._h  file  as   follows:   98        /* 98         * Object desc.  98         */g 98        struct o {1 98            int oLeft, oBottom, oRight, oTop;  98            char oType;  98            char oLayer; 98            short oInfo;( 98            struct o *oPred, *oSucc; 98            struct o *oRep; ) 98            struct prpty *oPrptyList;a 98            }; 99<      One object descriptor is associated with each object in  < a  symbol.   This descriptor is allocated and initialized by  b an object-specific routine (e.g., _C_D_M_a_k_e_B_o_x(), _C_D_M_a_k_e_W_i_r_e(),  V _C_D_M_a_k_e_P_o_l_y_g_o_n(),  etc.  ).  An object descriptor is released       9          <                                                           15    [ only by invocation of the _C_D_D_e_l_e_t_e_O_b_j_e_c_t_D_e_s_c() routine.9    F      The _o_T_y_p_e member is a  character  that  identifies  the  < type  of  the  object  and  can  assume any of the following  & values defined in the _c_d._h file:  
 98    /* 98     * Types of geometries 98     */o% 98    #define CDSYMBOLCALL      'c'a% 98    #define CDPOLYGON         'p'y% 98    #define CDROUNDFLASH      'r'y% 98    #define CDLABEL           'l'e% 98    #define CDWIRE            'w'% 98    #define CDBOX             'b'  99P      The bounding box of the object is given by _o_L_e_f_t, _o_B_o_t_-  V _t_o_m, _o_R_i_g_h_t, and _o_T_o_p.  The layer on which the object exists  H is specified by _o_L_a_y_e_r.  When the object descriptor is allo-  D cated,  the  _o_R_e_p pointer is cast as a pointer to an object-  < specific descriptor  that  extends  the  definition  of  the  < respective  object;   these  object specific descriptors are  < defined in Section 2.4.4 concerns the object  creation  rou-   tines.    F      _o_I_n_f_o is the integer information field  of  the  symbol  P and  is  initialized to zero, and _o_P_r_p_t_y_L_i_s_t is a pointer to  < the null-terminated  object  property  list.   The  pointers  P _o_P_r_e_d  and _o_S_u_c_c are used to access the previous and succes-  < sive objects in the doubly linked-list of objects that  con-   stitute a storage bin.                              <                                                           16    Q _2._2._5. _T_h_e _G_e_n_e_r_a_t_o_r _D_e_s_c_r_i_p_t_o_r.    B      The generator descriptor is defined in the _c_d._h file as   follows:   98        /* 98         * Generator desc. 98         */o 98        struct g {1 98            int gLeft, gBottom, gRight, gTop;; 98            int gBeginX, gX, gEndX, gBeginY, gY, gEndY; 98            char gLayer;# 98            struct o *gPointer;e 98            }; 99N      An object _g_e_n_e_r_a_t_o_r in the context of CD is  a  set  of  < procedures  for acquiring object descriptors for all objects  < on a specific layer and in  a  specific  area  of  interest.  N Invocation  of  the  _C_D_I_n_i_t_G_e_n() will return a pointer to an  < allocated and initialized generator descriptor that contains  < all  the status information for the operation of the genera-  < tor.  More specifically,  the  generator  descriptor  stores  < information  that includes the area of interest, the storage  < bins that are to be searched, and the  present  position  in  ) the storage bin currently being searched.9    h      _g_L_e_f_t, _g_B_o_t_t_o_m, _g_R_i_g_h_t, and _g_T_o_p defines the area where  H the generated objects should reside, and _g_L_a_y_e_r is the layer  < on which the generated objects should exist with layer  zero  b being  the  instance layer.  The _g_B_e_g_i_n_X, _g_E_n_d_X and _g_B_e_g_i_n_Y,  F _g_E_n_d_Y members define the range of the  storage  bins  to  be  D searched,  and  _g_X  and  _g_Y  define  the storage bin that is  L currently being searched.  The _g_P_o_i_n_t_e_r member is a  pointer  < to  an  object  descriptor in the storage bins and points to                  <                                                           17    9 the descriptor where the next search sequence will begin.d  Q _2._2._6. _T_h_e _T_r_a_n_s_f_o_r_m _D_e_s_c_r_i_p_t_o_r     <      The CD package uses  only  rectilinear  or  "Manhattan"  < transformations.   In  CD, a transformation is characterized  < by a null-terminated linked-list of transformation  descrip-  B tors.   The transform descriptor is defined in the _c_d._h file   as follows:    98        /* 98         * Transform desc.E 98         * If MX, tType == CDMIRRORX.  If MY, tType == CDMIRRORX. K 98         * If R, tType == CDROTATE, tX == XDirection, tY == YDirection. = 98         * If T, tType == CDTRANSLATE, tX == TX, tY = TY;  98         */  98        struct t { 98            char tType;r 98            int tX, tY;  98            struct t *tSucc; 98            }; 99T      The transformation that is called _M_i_r_r_o_r_i_n_g _i_n _X is  an  < operation  that  effectively multiplies all x-coordinates by  < -1, or, in other words, mirrors in the direction of x.  This  < transformation can be confusing because it is also identical  < to a reflection in the y-axis.  Likewise, the transformation  T that  is  called  _M_i_r_r_o_r_i_n_g _i_n _Y is an operation that effec-  < tively multiplies all y-coordinates  by  -1,  or,  in  other  < words,  mirrors  in the direction of y.  This transformation  0 is also identical to a reflection in the x-axis.    <      A rotation is always in the counter-clockwise direction  < and about the origin of the coordinate system.  The angle of  P rotation is defined with two integers, namely _X_D_i_r_e_c_t_i_o_n and  P _Y_D_i_r_e_c_t_i_o_n,   and   is   the   arctangent   of   the   ratio                  <                                                           18    d _Y_D_i_r_e_c_t_i_o_n/_X_D_i_r_e_c_t_i_o_n.  If the angles of rotation is  always  P an  integer  multiple  of  90  degrees, either _X_D_i_r_e_c_t_i_o_n or  < _Y_D_i_r_e_c_t_i_o_n will be zero, but never both.    <      The sequence  of  transformations  is  significant.   A  < brief  example  of  this  fact  follows:  consider the point  < (0,0) translated in the positive x-direction  by  100  units  < and then rotated 90 degrees.  The resulting coordinate would  < be (0,100).  Now consider the  point  (0,0)  rotated  by  90  < degrees  and  then translated in the positive x-direction by  < 100 units, the exact opposite of the previous transformation  < order.   The  resulting  point  would  be  (100,0)  and  not   (0,100).    <      The sequence of the transforms is identical to the suc-  < cession  of the transformation descriptors in the list.  The  F character member _t_T_y_p_e specifies the type of  transformation  < that is defined by the descriptor and can be assigned to the  0 following values defined in the _c_d._h file:  
 98    /*# 98     * Types of transformationso 98     */_E 98    #define CDMIRRORX         'x'  /* mirror in direction of x */,E 98    #define CDMIRRORY         'y'  /* mirror in direction of y */ B 98    #define CDROTATE          'r'  /* rotate by vector X, Y */> 98    #define CDTRANSLATE       't'  /* translate to X, Y */ 99<      If the transformation is a rotation or  a  translation,  D _t_X  and  _t_Y  define the angle or displacement, respectively.  F The _t_S_u_c_c member points to the next transformation  descrip-  < tor  in  the  linked-list  and is null in the last transform   definition in the list.c                  <                                                           19    [ _2._2._7. _T_h_e _P_r_o_p_e_r_t_y _L_i_s_t _D_e_s_c_r_i_p_t_o_re    <      CD provides the capability of attaching property  lists  < to  symbols  and  objects;  a  CD  property  list is a null-  < terminated linked-list of property  descriptors.   The  pro-  B perty  list  descriptor  is defined in the _c_d._h file as fol-   lows:t   98        /*" 98         * Property List desc. 98         */n 98        struct prpty {  98            int prpty_Value;# 98            char *prpty_String;_) 98            struct prpty *prpty_Succ;_ 98            }; 99<      In CD, a property consists of  an  identifying  integer  < and a null-terminated character string extension.  The iden-  P tifying integer _p_r_p_t_y__V_a_l_u_e defines the  type  of  property,  R and  the string extension _p_r_p_t_y__S_t_r_i_n_g is a modifier.  There  < is no standard set of  properties  and  associated  property  < values for CD or KIC; a user is free to set his own standard  0 set of property values for his own specific use.    N      The _p_r_p_t_y__S_u_c_c  member  points  to  the  next  property  < descriptor  in  the linked-list and is null in the last pro-   perty in the list.  L _2._2._8. _T_h_e _C_D _L_a_y_e_r _D_e_s_c_r_i_p_t_o_r    B      The layer descriptor is defined in  the  _c_d._h  file  as   follows:   9   9     9   9    > 8                                                          20    & 98        #define CDNUMLAYERS     35 998        /* 98         * CD Layer Tablen 98         */h 98        struct l {! 98            char lTechnology;t 98            char lMask[3];8 98            /* True if CDFrom should output layer */ 98            char lCDFrom;  98            }:# 98        CDLayer[CDNUMLAYERS+1];r 99<      The CD layer descriptor is the building block  of  CD's  < layer table that is used to equate a layer's name to a posi-  < tive integer. This integer is always used internally  in  CD  " to represent the respective layer.    <      A CIF layer name can be up  to  four  characters  long.  < The  first  character  of  the  CIF  layer name is stored in  R _l_T_e_c_h_n_o_l_o_g_y and the remaining characters are stored  in  the  P _l_M_a_s_k  character  buffer;  the remaining characters in _l_M_a_s_k  < will be blanks.  A layer is recognized as undefined  if  the  R _l_T_e_c_h_n_o_l_o_g_y  character  member of the layer table is a blank  J or space character.  The _l_C_D_F_r_o_m boolean has the purpose  of  < identifying  the layer as visible or invisible when convert-  < ing from KIC/CD format to another layout language,  such  as   CIF or Calma STREAM.    <      The maximum layers known to CD, and therefore the  size  B of  the  layer  table, is defined by CDNUMLAYERS in the _c_d._h  @ file.  _C_D can be recompiled to  provide  more  mask  layers.  < Because object layer numbers are stored in character fields,  < the absolute maximum number of layers is 126.  The  size  of  < the  layer  table  is  larger than CDNUMLAYERS because layer                  <                                                           21    ' zero is reserved as the instance layer.r  B _2._2._9. _T_h_e _P_a_t_h _D_e_s_c_r_i_p_t_o_r    <      A contour or trajectory of coordinates  is  represented  < in  CD as a null-terminated linked-list of path descriptors.  A The path descriptor is defined in the _c_d._h file as follows:E   98        /*% 98         * Linked path structure.  98         */N 98        struct p { 98            int pX, pY;   98            struct p *pSucc; 98            }; 99D      The _p_X and _p_Y integer members define one coordinate  in  < the  path.   The  sequence of the coordinates in the path is  < identical to the succession of the path descriptors  in  the  F linked-list.   The  _p_S_u_c_c  member  points  to  the next path  < descriptor in the linked-list and is null at the last  coor-   dinate in the list.a                                                                <                                                           22    + _2._3. _S_t_o_r_a_g_e _B_i_n_sr    <      All objects contained within a CD symbol are sorted  by  < position  and  layer,  and  the sorted objects are stored in  D _b_i_n_s.  A pointer to these storage bins is contained  in  the  < symbol  descriptor,  and each symbol has one complete set of  < storage bins.  This section presents a detailed  description   of the storage algorithm.u    <      The world coordinate system of CD ranges from CDBINMINX  < to  CDBINMAXX  in  the  x-direction,  and  from CDBINMINY to  < CDBINMAXY, and the world coordinate system is covered  by  a  < square  array  of  CDNUMBINS by CDNUMBINS storage bins where  B these values are defined in the _c_d._h file  as  shown  below.  R There  is a special storage bin called the _r_e_s_i_d_u_a_l _b_i_n that  < only for convenience is contained in the storage  bin  array  4 thereby adding another row and column to this array.  
 98    /*N 98     * These are the numbers that CD uses to determine which bin an objectN 98     * resides in.  They should reflect the average size of a layout beingJ 98     * edited by KIC.  KIC will not fail if the numbers are too small.I 98     * Anything outside of this window is placed in the residual bin.rM 98     * If these numbers become too large, CDIntersect() must use floatingt 98     * point calculations. 98     */l( 98    #define CDBINMAXX         500000( 98    #define CDBINMAXY         500000. 98    #define CDBINMINX         (-CDBINMAXX). 98    #define CDBINMINY         (-CDBINMAXY)& 998    #define CDNUMBINS         10 99<      Each storage bin contains the beginning  pointer  to  a  < linked-list  of  object  descriptors, those objects that are  < contained in the particular bin.  When an object is inserted  < into  a  bin  as  a  result  of a call to an object creation     9          <                                                           23    b routines (e.g.,  _C_D_M_a_k_e_B_o_x(),  _C_D_M_a_k_e_W_i_r_e(),  etc.),  it  is  < inserted  at the top of the linked-list.  The bin into which  < an object is inserted depends on the  bounding  box  of  the  < object.   If  the bounding box intersects an area covered by  < more than one bin, the object is inserted into the  residual  < bin.   Otherwise,  the  object is inserted into the bin that  ( contains the bounding box of the object.    <      If CD is compiled with a large number of bins, it  will  < be  able  to  rapidly traverse a symbol hierarchy or quickly  < access any geometry in the symbol.   However,  many  storage  < bins  also means that a significant amount of memory must be  < dedicated to the  bin  pointers,  and  that  the  number  of  < objects  in  the residual bin to be disproportionately large  < when compared to the number  of  objects  in  the  remaining  < bins;  because  the  bins are smaller, the number of objects  < that intersect more than one bin increases and these objects  # are inserted into the residual bin.o    <      The size of the residual bin can effect  the  speed  at  < which  the  bins are searched for objects.  When the storage  < bins are searched for an object in a specific area, it is of  < course necessary to examine the contents of each storage bin  < that intersects the particular area.  However, the  bounding  < box  of  an  object  that also intersects this area may also  < intersect several bins, in which case the object  descriptor  < is  stored in the residual bin.  Therefore, the residual bin  < must always be searched, and consequently it  is  preferable                    <                                                           24    1 to have the residual bin be as small as possible.e    <      CD allocates the memory for the storage bin pointers on  < demand.   This  means  that  the memory requirements for the  < storage bins is a function of the  number  of  layers  being  < used  in  the  symbol as well as the number of storage bins.  < When CD must allocate memory for the storage  bin  pointers,  < CDNUMBINS+1  by CDNUMBINS+1 bins are allocated, where CDNUM-  B BINS is defined in the _c_d._h file.  The bin that  is  pointed  R to  by  _s_B_i_n[_L_a_y_e_r][_0][_0]  is  the  residual  bin.  The bins  l _s_B_i_n[_L_a_y_e_r][_X][_0] and _s_B_i_n[_L_a_y_e_r][_0][_Y], where _X and  _Y  are  < positive  integers  not  greater than CDNUMBINS, are unused.  < The remaining bins represent the symbols storage bin  struc-   ture.     <      The CD procedure that computes  the  range  of  storage  L bins  that  intersect  a  particular area is called _C_D_I_n_t_e_r_-  D _s_e_c_t().  The CD procedure that inserts an object  descriptor  < into  the  storage  bin of a symbol descriptor and allocates  < memory if the particular  bin  has  not  been  allocated  is  ` called  _C_D_I_n_s_e_r_t_O_b_j_e_c_t_D_e_s_c().   These  two  CD  routines are  < intended to be transparent to the  CD  user,  and  therefore  / will not be described further in this document.i    <      To possibly increase the  efficiency  of  this  binning  < algorithm,  the  values  of CDBINMAXX, CDBINMINX, CDBINMAXY,  < and CDBINMINY should be as small  as  possible  while  still  < reflecting  a realistic working area for the CD application.  < CD will not fail if the real working area exceeds CD's range                  <                                                           25    < for the world coordinate system.  Objects that exist outside  < the working world coordinate system of CD will  be  inserted  < into  the outer-most bins, and an object generator will find   such objects in those bins.s    <      To minimize the number of objects in a given  bin,  the  < value  of CDNUMBINS should be as large as is affordable with  < the resulting memory requirements.  If the size of a pointer  < is  four  bytes, then the amount of memory required for only  < the pointers of a binning  structure  in  an  entire  symbol  - hierarchy is given by the following equation:l    D 4*(number of symbols)*(number of layers)*(CDNUMBINS+1)*(CDNUMBINS+1)    < For an IC layout with 80 symbols,  eight  mask  layers,  and  < using  only  10  bins,  the  memory requirements for the bin  < structure can exceed 300 kbytes.  Also, as  the  numbers  of  < bins increases, the size of the residual bin can be expected  < to increase.  But by far the greatest  disadvantage  to  the  < binning algorithm is that most bins remain empty and unused;  < a layout can typically exist entirely in the first Cartesian  < quadrant  of the world coordinate system, in which case only  & one quarter of the bins would be used.                                          <                                                           26    . _2._4. _C_D _P_r_o_c_e_d_u_r_e_s  > _2._4._1. _C_D _I_n_i_t_i_a_l_i_z_a_t_i_o_n    <      There are three procedures for initialization of the CD  	 database.    98        void CDInit()s 99 8        int CDPath(Path) 98        char *Path;d 992 8        void CDSetLayer(Layer, Technology, Mask) 98        int Layer; 98        char Technology; 98        char Mask[3];) 99H      _C_D_I_n_i_t() must be  invoked  before  any  other  CD  pro-  < cedures.   This  routine will clear the layer table, set the  < directory search path to be the present  working  directory,  < initialize  the  transformation  stack, and allocate storage  H for diagnostics.  _C_D_I_n_i_t() should be called only once by  an   application.    H      _C_D_P_a_t_h() sets the search rules for symbol-name  resolu-  D tion.   The  argument _P_a_t_h is a pointer to a null-terminated  < string containing a list of directory names to  be  searched  H separated by blanks.  When a cell is opened via _C_D_O_p_e_n() the  < list of directories is searched for  the  existence  of  the  < symbol  file.   The  old search path is removed by a call to  H _C_D_P_a_t_h() and the default search path is the  current  direc-  D tory.   In  the  UNIX  environment,  _c_s_h(_1)  style names, as  < described in the  BSD  UNIX  programmer's  manual,  will  be   understood.                     <                                                           27    Z      _C_D_S_e_t_L_a_y_e_r() Inserts the layer argument _L_a_y_e_r into  the  l CD  layer table with the name _T_e_c_h_n_o_l_o_g_y_M_a_s_k.  If _T_e_c_h_n_o_l_o_g_y  D and _M_a_s_k contain only space or blank characters,  the  layer  < definition is removed from CD, but any object that exists on  < the particular layer is not deleted.   The  layer  table  is  + defined above with the CD layer descriptor.   C _2._4._2. _E_r_r_o_r _H_a_n_d_l_i_n_g _i_n _C_Da    <      CD has a simple mechanism for handling errors.  In  the  B _c_d._h  file,  there are two external error variables that are  " allocated by _C_D_I_n_i_t():  F 98        extern int   CDStatusInt;    /* CD's diagnostic integer */I 98        extern char  *CDStatusString;        /* CD's status string */e 99<      If a CD routine  encounters  any  difficulty,  it  will  R place an identifying diagnostic integer in _C_D_S_t_a_t_u_s_I_n_t and a  X pointer to diagnostic character  string  in  _C_D_S_t_a_t_u_s_S_t_r_i_n_g,  F and then return the with value of _F_a_l_s_e.  The possible fatal  X values for _C_D_S_t_a_t_u_s_I_n_t are defined in the _c_d._h file as  fol-   lows:e  A 98    #define CDPARSEFAILED     1    /* (FATAL) parse failed */sF 98    #define CDNEWSYMBOL       3    /* symbol not in search path */B 98    #define CDMALLOCFAILED    11   /* (FATAL) out of memory */E 98    #define CDBADBOX          12   /* zero width or length box */uE 98    #define CDXFORMSTACKFULL  13   /* transform stack overflow */eF 98    #define CDBADPATH         14   /* bad directory search path */ 99<      Error handling in CD may be confusing at first  because  < only  those routines in which an error might occur will have  < a returned  value.   The  routines  in  which  no  error  is  7 expected are assigned the type definition _v_o_i_d.o                      <                                                           28    E _2._4._3. _C_D _S_y_m_b_o_l _M_a_n_a_g_e_m_e_n_tn    <      There are four CD procedures  for  creating,  deleting,   and maintaining CD symbols.d  6 98        int CDOpen(SymbolName, SymbolDesc, Access)% 98        char *SymbolName, Access;c" 98        struct s **SymbolDesc; 99/ 8        void CDSymbol(SymbolName, SymbolDesc)e 98        char *SymbolName;r" 98        struct s **SymbolDesc; 99! 8        int CDClose(SymbolDesc) ! 98        struct s *SymbolDesc;  99. 8        int CDUpdate(SymbolDesc, SymbolName)! 98        struct s *SymbolDesc;y 98        char *SymbolName;a 99\      The procedure _C_D_O_p_e_n() opens a symbol named _S_y_m_b_o_l_N_a_m_e,  P allocates memory for and returns the pointer _S_y_m_b_o_l_D_e_s_c to a  < symbol descriptor that represents the new symbol in  the  CD  	 database.o    T      The _A_c_c_e_s_s argument to _C_D_O_p_e_n()  is  a  character  that  < determines the result after the current search path has been  P examined for the existence of a symbol named _S_y_m_b_o_l_N_a_m_e.  If  T the character _A_c_c_e_s_s equals the character 'w', then _C_D_O_p_e_n()  < will create the cell in the database if it does not exist in  < the current search path.  In other words, the symbol will be  H opened for writing.  If _A_c_c_e_s_s  equals  the  character  'r',  H then  _C_D_O_p_e_n()  will  create the cell in the database if and  < only if it exists in the  current  search  path.   In  other  < words,  the  symbol  is  only read into memory.  If the cell  < does not  exist  in  the  current  search  path,  no  symbol     9          <                                                           29    P descriptor  is inserted into the database, and _S_y_m_b_o_l_D_e_s_c is  H assigned the value of NULL.  Finally, if _A_c_c_e_s_s  equals  the  < character  'n',  the  symbol is opened regardless of whether  P any symbol named _S_y_m_b_o_l_N_a_m_e exists  in  the  current  search  < path.   If  such a file exists in the search path, it is not  ; read into memory.  In other words, CD creates a new symbol.     P      _C_D_O_p_e_n() will call the routine _P_C_I_F() to read the  sym-  < bol  into  the database.  The parsing procedure is described  D in greater detail in Chapter 3.  A brief synopsis of  _P_C_I_F()   is as follows:  5 98        PCIF(SymbolName, StatusString, StatusInt)s 98        char *SymbolName;r 98        char **StatusInt;t 98        int *StatusInt;. 99<      There are three requirements for the parser; first, the  P parser  must  locate  and  read  the  symbol _S_y_m_b_o_l_N_a_m_e, and  < insert the symbol definition into the CD database  by  using  < the  object  creation  routines  described  below in Section  b 2.4.4 (e.g., _C_D_M_a_k_e_B_o_x(), _C_D_M_a_k_e_W_i_r_e(), etc.).  Second,  the  J parser  must  provide  a file called _p_a_r_s_e_r._h which contains  < the diagnostics described below.  Finally, when the parse is  D completed, _P_C_I_F() must return a pointer to a null-terminated  f diagnostic string via _S_t_a_t_u_s_S_t_r_i_n_g, and  _S_t_a_t_u_s_I_n_t  must  be  E set to a value defined in the _p_a_r_s_e_r._h file as follows:*  > 98    #define PSUCCEEDED        1    /* successful return */: 98    #define PFAILED           2    /* parser failed */F 98    #define PNOTAPPLICABLE    3    /* parser failed, bad syntax */ 99R      _P_C_I_F() may return with the  diagnostic  string  _S_t_a_t_u_s_-                    <                                                           30    H _S_t_r_i_n_g  equal  to  NULL  if  and only if the parse succeeds.  R _C_D_O_p_e_n() returns with the value _F_a_l_s_e if the parse failed or  H if it was unable to allocate memory.  When _C_D_O_p_e_n() returns,  R _C_D_S_t_a_t_u_s_I_n_t, as defined above, is set to a diagnostic  value  2 that is defined in the _c_d._h file as follows:  A 98    #define CDPARSEFAILED     1    /* (FATAL) parse failed */nE 98    #define CDOLDSYMBOL       2    /* symbol already in opened */ F 98    #define CDNEWSYMBOL       3    /* symbol not in search path */E 98    #define CDSUCCEEDED       4    /* new symbol found in path */ 99<      Only CDPARSEFAILED is returned as a fatal error  (i.e.,  h _C_D_O_p_e_n()  returns  with the value _F_a_l_s_e, and _C_D_S_t_a_t_u_s_I_n_t has  < been set to the value of CDPARSEFAILED); this simplifies the  H diagnostic  test.  However, if the _A_c_c_e_s_s argument is set to  H 'r' and the symbol is not found in the search path, _C_D_O_p_e_n()  R returns  with  _C_D_S_t_a_t_u_s_I_n_t  set to the value of CDNEWSYMBOL.  < The application programmer should be aware of this  behavior  < because  it could be considered as an error if, for any rea-  < son, the symbol is expected to exist, such as when  travers-  H ing a symbol hierarchy.  When the returned value of _C_D_O_p_e_n()  X identifies an error, _C_D_S_t_a_t_u_s_S_t_r_i_n_g will contain a  diagnos-   tic message.    L      _C_D_S_y_m_b_o_l() returns a pointer to  symbol  descriptor  if  P the  symbol _S_y_m_b_o_l_N_a_m_e has been previously opened and exists  J in memory.  If the symbol does not exist in memory,  _S_y_m_b_o_l_-  + _D_e_s_c is returned as a null pointer.t    J      The _C_D_C_l_o_s_e() procedure will remove the symbol  identi-  P fied  by _S_y_m_b_o_l_D_e_s_c from memory and any associated instances                    <                                                           31    < and geometries.  Also, all property  lists  associated  with  7 the symbol or any object in the symbol will be removed.l    L      _C_D_U_p_d_a_t_e() will save any changes that have been made to  P the symbol referenced by _S_y_m_b_o_l_D_e_s_c.  The output will appear  < as CIF in a file in the current working directory identified  d by  the null-terminated string _S_y_m_b_o_l_N_a_m_e.  If _S_y_m_b_o_l_N_a_m_e is  < a null pointer, the name of the CIF file will  be  identical  ( to the name of the symbol being updated.  X _2._4._4. _C_D _O_b_j_e_c_t _C_r_e_a_t_i_o_n _R_o_u_t_i_n_e_s    <      There are eight procedure for inserting an object  into   a CD symbol.  K 98         int CDMakeBox(SymbolDesc, Layer, Length, Width, X, Y, Pointer) " 98         struct s *SymbolDesc;  98         struct o **Pointer; 98         int Layer; 98         int Length, Width;  98         int X, Y; 99C 8         int CDMakeLabel(SymbolDesc, Layer, Label, X, Y, Pointer)S" 98         struct s *SymbolDesc;  98         struct o **Pointer; 98         int Layer;S 98         char *Label;  98         int X, Y; 99> 8         int CDMakePolygon(SymbolDesc, Layer, Path, Pointer)" 98         struct s *SymbolDesc;  98         struct o **Pointer; 98         struct p *Path; 98         int Layer;o 99B 8         int CDMakeWire(SymbolDesc, Layer, Width, Path, Pointer)" 98         struct s *SymbolDesc;  98         struct o **Pointer; 98         struct p *Path; 98         int Layer, Width; 99   9     9   9    > 8                                                          32    J 98         int CDMakeRoundFlash(SymbolDesc, Layer, Width, X, Y, Pointer)" 98         struct s *SymbolDesc;  98         struct o **Pointer; 98         int Layer;u 98         int Width, X, Y;x 99S 8         int CDBeginMakeCall(SymbolDesc, SymbolName, NumX, DX, NumY, DY, Pointer)c" 98         struct s *SymbolDesc;  98         struct o **Pointer; 98         char *SymbolName;$ 98         int NumX, DX, NumY, DY; 99' 8         int CDT(Pointer, Type, X, Y)  98         struct o *Pointer;i 98         char Type;s 98         int X, Y; 991 8         int CDEndMakeCall(SymbolDesc, Pointer)l" 98         struct s *SymbolDesc; 98         struct o *Pointer; 99Z      _C_D_M_a_k_e_B_o_x() will create a box of length _L_e_n_g_t_h in the x  F direction  and  width  _W_i_d_t_h in the y direction, centered at  H _X,Y on the layer _L_a_y_e_r  in  the  symbol  identified  by  the  P descriptor  _S_y_m_b_o_l_D_e_s_c.   Zero width or length boxes are not  J allowed.  _P_o_i_n_t_e_r contains a returned pointer to the  object  < descriptor  of  the  newly  created box.  Because the object  < descriptor contains sufficient information to characterize a  D rectangle,  the  _o_R_e_p  member  of  the object descriptor, as  < described previously in Section 2.2.4, is a null pointer  if  < the  object  descriptor  represents  a box.  There is no box   descriptor in CD._    X      _C_D_M_a_k_e_B_o_x() will return with the value _F_a_l_s_e if  it  is  D unable  to  allocate  storage.  Otherwise, the value _T_r_u_e is  	 returned.m    \      _C_D_M_a_k_e_L_a_b_e_l() will create a label on the layer _L_a_y_e_r in                  <                                                           33    P the  symbol  identified  by  the descriptor _S_y_m_b_o_l_D_e_s_c.  The  < lower, left corner of the label will be  referenced  to  the  H coordinate  _X,Y, and _L_a_b_e_l is a pointer to a null-terminated  J string containing the label.  _P_o_i_n_t_e_r  contains  a  returned  < pointer to the object descriptor of the newly created label.  D For all labels, the _o_R_e_p member of the object descriptor, as  < described  in Section 2.2.4, is cast as a pointer to a label  = descriptor that is defined in the _c_d._h file as follows:r   98        /* 98         * Label desc. 98         */t 98        struct la {92 98            char *laLabel;     /* text body */; 98            int laX, laY;      /* lower, left corner */u 98            }; 99\      _C_D_M_a_k_e_L_a_b_e_l() will return with the value _F_a_l_s_e if it is  D unable  to  allocate  storage.  Otherwise, the value _T_r_u_e is  	 returned.n    V      _C_D_M_a_k_e_P_o_l_y_g_o_n() will create a polygon  with  a  linked-  N list  coordinate  path _P_a_t_h on the layer _L_a_y_e_r in the symbol  X identified by the descriptor _S_y_m_b_o_l_D_e_s_c.  _P_a_t_h is a  pointer  < to  a  linked-list of coordinates as described previously in  J the section that defines the path descriptor.  _P_o_i_n_t_e_r  con-  < tains  a  returned  pointer  to the object descriptor of the  D newly created polygon.  For all polygons, the _o_R_e_p member of  < the  object  descriptor,  as  described in Section 2.2.4, is  < cast as a pointer to a polygon descriptor that is defined in   the _c_d._h file as follows:t   9 9     9   9    > 8                                                          34     98        /* 98         * Polygon desc. 98         */b 98        struct po {h< 98            struct p *poPath;  /* the polygon contour */ 98            }; 99`      _C_D_M_a_k_e_P_o_l_y_g_o_n() will return with the value _F_a_l_s_e if  it  D is unable to allocate storage.  Otherwise, the value _T_r_u_e is  	 returned.     Z      _C_D_M_a_k_e_W_i_r_e() will create a wire of width _W_i_d_t_h  with  a  N coordinate path _P_a_t_h on the layer _L_a_y_e_r in the symbol refer-  X enced by the descriptor _S_y_m_b_o_l_D_e_s_c.  _P_a_t_h is a pointer to  a  < linked-list  of  coordinates  as  described above in Section  J 2.2.9 that concerns the CD path  descriptor.   _P_o_i_n_t_e_r  con-  < tains  a  returned  pointer  to the object descriptor of the  D newly created wire.  For all wires, the _o_R_e_p member  of  the  < object descriptor, as described in Section 2.2.4, is cast as  B a pointer to a wire descriptor that is defined in  the  _c_d._h   file as follows:   98        /* 98         * Wire desc.r 98         */_ 98        struct w {7 98            int wWidth;        /* the wire width */9 98            struct p *wPath;   /* the wire contour */s 98            }; 99Z      _C_D_M_a_k_e_W_i_r_e() will return with the value _F_a_l_s_e if it  is  D unable  to  allocate  storage.  Otherwise, the value _T_r_u_e is  	 returned.e    \      _C_D_M_a_k_e_R_o_u_n_d_F_l_a_s_h() will create a round flash of  diame-  R ter  _W_i_d_t_h  centered at _X,Y on the layer _L_a_y_e_r in the symbol       9          <                                                           35    P identified by  the  descriptor  _S_y_m_b_o_l_D_e_s_c.   Zero  diameter  J round  flashes are not allowed.  _P_o_i_n_t_e_r contains a returned  < pointer to the object descriptor of the newly created  round  D flash.  For all round flashes, the _o_R_e_p member of the object  < descriptor, as described in Section  2.2.4,  is  cast  as  a  < pointer  to  a round flash descriptor that is defined in the   _c_d._h file as follows:    98        /*  98         * Round flash desc. 98         */o 98        struct r {; 98            int rWidth;        /* the flash diameter */2@ 98            int rX, rY;        /* the center of the flash */ 98            }; 99<      The KIC program does not  use  round  flashes  and  the  < round  flash routines are only presented in this section for  < completeness.  All round geometries are represented  in  KIC   as polygons.    f      _C_D_M_a_k_e_R_o_u_n_d_F_l_a_s_h() will return with the value _F_a_l_s_e  if  D it is unable to allocate storage.  Otherwise, the value _T_r_u_e   is returned.    Z      _C_D_B_e_g_i_n_M_a_k_e_C_a_l_l() allocates memory and initializes  the  < object  descriptor  that  will  represent  the newly created  X instance of the symbol _S_y_m_b_o_l_N_a_m_e.  _N_u_m_X is  the  number  of  D instances  in  the untransformed x direction and _N_u_m_Y is the  @ number of instances in the untransformed  y  direction.   _D_X  @ and  _D_Y  are  the distances between the left and right edges  < and the top and bottom edges respectively  of  two  adjacent  J cells  in  the instance array.  _P_o_i_n_t_e_r returns a pointer to                  <                                                           36    D the new object descriptor.  For all symbol calls,  the  _o_R_e_p  < member  of  the  object  descriptor, as described in Section  < 2.2.4, is cast as a pointer to a  call  descriptor  that  is  * defined in the _c_d._h file as follows:   98        /* 98         * Call desc.r 98         */  98        struct c { 98            /* not used */ 98            int cNum;; 98            /* Pointer to transformation descriptor. */w 98            struct t *cT; 8 98            /* Pointer to master-list descriptor. */" 98            struct m *cMaster;' 98            /* Array parameters. */ + 98            int cNumX, cNumY, cDX, cDY;r 98            }; 99@      The _c_T member of the call descriptor is  a  pointer  to  < the  transformation  list that will be defined by subsequent  P calls to the _C_D_T() routine.  The _c_M_a_s_t_e_r member is a pointer  < to the master-list descriptor in the master-list of the sym-  < bol that instances the cell represented by the call descrip-  < tor.    Because  the  master-list  descriptor  contains  the  < instance name, it is not necessary to contain a name  buffer  < in  the  call  descriptor.   The master-list is described in   Section 2.2.2.    P      If _S_y_m_b_o_l_N_a_m_e is not in the  current  search  path,  or  x _C_D_B_e_g_i_n_M_a_k_e_C_a_l_l  cannot  allocate  storage,  _C_D_B_e_g_i_n_M_a_k_e_C_a_l_l  \ returns with the value _F_a_l_s_e and _C_D_S_t_a_t_u_s_I_n_t will be set  to  ? a diagnostic integer defined in the _c_d._h file as follows:c  A 98    #define CDPARSEFAILED     1    /* (FATAL) parse failed */ F 98    #define CDNEWSYMBOL       3    /* symbol not in search path */B 98    #define CDMALLOCFAILED    11   /* (FATAL) out of memory */ 99     9   9    > 8                                                          37     9\      After invoking _B_e_g_i_n_M_a_k_e_C_a_l_l(), the procedure _C_D_T()  is  < invoked  for  each transformation in the call.  The argument  J _P_o_i_n_t_e_r is a pointer  to  the  object  descriptor  that  was  Z returned  by the _C_D_B_e_g_i_n_M_a_k_e_C_a_l_l() procedure.  The character  D _T_y_p_e identifies the transformation to be added to the  call,  J and  the  valid  arguments  for _T_y_p_e are defined in the _c_d._h   file as follows:  E 98    #define CDMIRRORX         'x'  /* mirror in direction of x */iE 98    #define CDMIRRORY         'y'  /* mirror in direction of y */ B 98    #define CDROTATE          'r'  /* rotate by vector X, Y */> 98    #define CDTRANSLATE       't'  /* translate to X, Y */ 99F      The arguments _X and _Y of _C_D_T() are used  to  qualify  a  < rotation  or  translation.   Only  rectilinear rotations are  > valid.  For a rotation of 90 degrees, _X has the value of  1,  @ and  _Y has the value of 0.  For a rotation of 180 degrees, _X  > has the value of -1, and _Y has the value of 0.  For a  rota-  @ tion  of  270  degrees,  _X has the value of 0, and _Y has the  @ value of -1.  For a translation, the integers _X  and  _Y  are  8 used to specify the x and y displacements, respectively.    |      Remember  that  _t_r_a_n_s_f_o_r_m_a_t_i_o_n  _o_r_d_e_r  _i_s  _s_i_g_n_i_f_i_c_a_n_t.  B Each   invocation   of  _C_D_T()  adds  another  transformation  < descriptor to the transformation list that is referenced  by  @ _c_T  in  the respective call descriptor, and thus the invoca-  B tions of _C_D_T()  must  be  in  the  identical  order  of  the   instance transformation.    V      Finally, _C_D_E_n_d_M_a_k_e_C_a_l_l() is invoked to insert the  call  P into  the  master  symbol  identified  by  _S_y_m_b_o_l_D_e_s_c.   The                  <                                                           38    J argument _P_o_i_n_t_e_r was of course returned by a  previous  call  t to  the  _C_D_B_e_g_i_n_M_a_k_e_C_a_l_l()  procedure.  _C_D_E_n_d_M_a_k_e_C_a_l_l() will  F return with the value _F_a_l_s_e if  it  is  unable  to  allocate  8 storage.  Otherwise, the value _T_r_u_e is returned.  B _2._4._5. _C_D _O_b_j_e_c_t _G_e_n_e_r_a_t_o_r    N      An object _g_e_n_e_r_a_t_o_r in the context of CD is  a  set  of  < procedures  for acquiring object descriptors for all objects  < on a specific layer and in a specific area of  interest.   A  9 generator will contain the following three CD procedures:a  O 98        int CDInitGen(SymbolDesc, Layer, Left, Bottom, Right, Top, GenDesc)h! 98        struct s *SymbolDesc;  98        struct g **GenDesc; 98        int Layer; 98        int Left, Bottom;r 98        int Right, Top;h 992 8        void CDGen(SymbolDesc, GenDesc, Pointer)! 98        struct s *SymbolDesc;e 98        struct g *GenDesc; 98        struct o **Pointer;  99$ 8        void CDType(Pointer, Type) 98        struct o *Pointer; 98        char *Type;r 99N      _C_D_I_n_i_t_G_e_n() returns a pointer to  a  generator  storage  J descriptor  _G_e_n_D_e_s_c  that  is  allocated  automatically  and  F described in Section 2.2.5.  Further invocations of  _C_D_G_e_n()  J will  return each object in the symbol identified by _S_y_m_b_o_l_-  N _D_e_s_c on the layer _L_a_y_e_r whose bounding  box  intersects  the  j area given by _L_e_f_t, _B_o_t_t_o_m, _R_i_g_h_t, and _T_o_p.  If _L_a_y_e_r equals  F zero, the invocations of _C_D_G_e_n() will return instances  only  N (i.e.,  layer zero is the instance layer).  _C_D_I_n_i_t_G_e_n() will  F return with the value of _F_a_l_s_e if it is unable  to  allocate                  <                                                           39    < the  generator  storage descriptor.  Otherwise, the value of   _T_r_u_e is returned.    F      _C_D_G_e_n() returns a pointer to an object descriptor  that  < identifies  an object within the area of interest as defined  N by the previous  call  to  _C_D_I_n_i_t_G_e_n()  which  returned  the  T pointer  to  the  generator  descriptor _G_e_n_D_e_s_c.  If _C_D_G_e_n()  J returns with _P_o_i_n_t_e_r set to NULL, then the last  object  has  B been returned and _G_e_n_D_e_s_c storage has been released.    H      _C_D_T_y_p_e() returns the type of an object  pointed  to  by  R _P_o_i_n_t_e_r.  The argument _T_y_p_e is a pointer to a character that  N is set by _C_D_O_p_e_n() to a value defined as follows in the _c_d._h   file:r  
 98    /* 98     * Types of geometries 98     */.% 98    #define CDSYMBOLCALL      'c'e% 98    #define CDPOLYGON         'p'c% 98    #define CDROUNDFLASH      'r' % 98    #define CDLABEL           'l' % 98    #define CDWIRE            'w' % 98    #define CDBOX             'b'  99<      This information routine is typically used in a genera-  < tor loop to dispatch a type-specific procedure for accessing  < the object.  An example of a generator loop for traversing a  , symbol hierarchy is provided in Section 2.6.  L _2._4._6. _A_c_c_e_s_s_i_n_g _O_b_j_e_c_t_s _i_n _C_D    <      All information that is necessary  to  characterize  an  < object is stored in that object's respective object descrip-  < tor and another representative descriptor that is referenced                    <                                                           40    < in the object descriptor.  Information for a specific object  < is therefore easily  obtained  from  the  respective  object  < descriptor.   The following eight CD procedures are used for  & accessing object-specific information:  ; 98        void CDBox(Pointer, Layer, Length, Width, X, Y)i 98        struct o *Pointer;/ 98        int *Layer, *Length, *Width, *X, *Y_ 993 8        void CDLabel(Pointer, Layer, Label, X, Y)v 98        struct o *Pointer; 98        char **Label;d 98        int *Layer;_ 98        int *X, *Y;  99. 8        void CDPolygon(Pointer, Layer, Path) 98        struct o *Pointer; 98        int *Layer;_ 98        struct p **Path; 992 8        void CDWire(Pointer, Layer, Width, Path) 98        struct o *Pointer; 98        struct p **Path; 98        int *Layer, *Width;9 998 8        void CDRoundFlash(Pointer, Layer, Width, X, Y) 98        struct o *Pointer; 98        int *Layer;n 98        int *Width, *X, *Y;  99> 8        void CDCall(Pointer, SymbolName, NumX, DX, NumY, DY) 98        struct o *Pointer; 98        char **SymbolName;' 98        int *NumX, *DX, *NumY, *DY;t 99( 8        void CDInitTGen(Pointer, TGen) 98        struct o *Pointer; 98        struct t **TGen; 99' 8        void CDTGen(TGen, Type, X, Y)e 98        struct t **TGen; 98        char *Type;r 98        int *X, *Y;_ 99R      _C_D_B_o_x() will return the length _L_e_n_g_t_h in the  x  direc-  F tion  and  the  width  _W_i_d_t_h  in  the  y  direction of a box     9          <                                                           41    J identified by the pointer _P_o_i_n_t_e_r to an  object  descriptor.  @ The  box is centered at the coordinate _X, _Y and on the layer   _L_a_y_e_r.    J      _C_D_L_a_b_e_l() returns  the  pointer  to  a  null-terminated  F label  _L_a_b_e_l that has lower, left justification to the coor-  @ dinate _X, _Y and whose object descriptor  is  pointed  to  by  B _P_o_i_n_t_e_r.  The label is on the layer _L_a_y_e_r.    N      _C_D_P_o_l_y_g_o_n() will return a pointer  to  the  linked-list  D coordinate  path _P_a_t_h of a polygon identified by the pointer  J _P_o_i_n_t_e_r to an object descriptor.   The  polygon  is  on  the  F layer  _L_a_y_e_r.  The linked-list coordinate path is defined in  1 Section 2.2.9 that describes the path descriptor.     H      _C_D_W_i_r_e() will return a pointer to the linked-list coor-  N dinate  path _P_a_t_h of a wire with width _W_i_d_t_h that is identi-  J fied by the pointer _P_o_i_n_t_e_r to an  object  descriptor.   The  % wire is on the layer _L_a_y_e_r.     ^      _C_D_R_o_u_n_d_F_l_a_s_h() will return  the  diameter  _W_i_d_t_h  of  a  J round  flash  identified by the pointer _P_o_i_n_t_e_r to an object  < descriptor.  The round flash is centered at  the  coordinate  J _X, _Y and on the layer _L_a_y_e_r.  As explained earlier, KIC does    not use CD round flash routines.    H      _C_D_C_a_l_l() returns the a character pointer  to  the  name  P _S_y_m_b_o_l_N_a_m_e  of an instance referenced by the object descrip-  R tor _P_o_i_n_t_e_r.  Also returned is _N_u_m_X which is the  number  of  D instance  in the untransformed x direction and _N_u_m_Y which is                  <                                                           42    < the number of instances in the  untransformed  y  direction.  D _D_X and _D_Y are the distances between the left and right edges  < and the top and bottom edges respectively  of  two  adjacent   cells in the instance array.    P      The _C_D_I_n_i_t_T_G_e_n() routine initializes the transformation  < generator loop to access the transformations of the instance  R referenced by _P_o_i_n_t_e_r.  _T_G_e_n is  a  returned  pointer  to  a  < transform  generator  descriptor.  Subsequent invocations of  H _C_D_T_G_e_n()  will  return  the  individual  components  of  the   instance transformations.    H      _C_D_T_G_e_n() returns a character that identifies  one  com-  D ponent  of the transformation of the instance for which _T_G_e_n  P was returned by the _C_D_I_n_i_t_T_G_e_n() routine  as  the  transform  D generator  descriptor.   The argument _T_y_p_e is a pointer to a  H character that is set by _C_D_T_G_e_n() to one of the values  that  . are defined as follows in the _c_d._h file:  E 98    #define CDMIRRORX         'x'  /* mirror in direction of x */oE 98    #define CDMIRRORY         'y'  /* mirror in direction of y */8B 98    #define CDROTATE          'r'  /* rotate by vector X, Y */> 98    #define CDTRANSLATE       't'  /* translate to X, Y */ 99<      The order in which the  transformation  components  are  H returned by _C_D_T_g_e_n() is identical to the order in which they  F were defined by calls to _C_D_T().  The integer pointers  _X,  _Y  < are  used to specify a rotation or translation.  For a rota-  @ tion of 90 degrees, _X has the returned value of 0, and _Y has  > the  returned  value of 1.  For a rotation of 180 degrees, _X  > has the returned value of -1, and _Y has the  returned  value                    <                                                           43    > of  0.   For  a  rotation of 270 degrees, _X has the returned  > value of 0, and _Y has the  returned  value  of  -1.   For  a  @ translation,  the  returned  values of _X and _Y specify the x  H and y displacements, respectively.   When  _C_D_T_G_e_n()  returns  D with _T_G_e_n set to NULL, then the last transformation has been  1 returned and _T_G_e_n storage has been freed.c  F _2._4._7. _O_b_j_e_c_t _D_e_l_e_t_i_o_n _i_n _C_D    <      There is one procedure for removing objects from  their   respective symbol:  . 98        void CDDelete(SymbolDesc, Pointer)! 98        struct s *SymbolDesc;  98        struct o *Pointer; 99Z      _C_D_D_e_l_e_t_e() will remove the object pointed to by _P_o_i_n_t_e_r  P from  the  symbol  referenced  by  _S_y_m_b_o_l_D_e_s_c.   Because the  < object descriptor is doubly linked-list (i.e., it contains a  < pointer  to  the successor and predecessor in the list), the  < task of deleting the object from the list can  be  completed  < without searching the storage bins for the particular object  < that is to be removed.  Also, the  memory  of  any  property  < list that is associated with the deleted object is released.  N _2._4._8. _C_D _I_n_f_o_r_m_a_t_i_o_n _R_o_u_t_i_n_e_s    <      There are six procedure  for  accessing  or  setting  a  < variety  of  information fields in object or symbol descrip-   tors:n  D 98         int CDBB(SymbolDesc, Pointer, Left, Bottom, Right, Top)" 98         struct s *SymbolDesc; 98         struct o *Pointer; . 98         int *Left, *Bottom, *Right, *Top; 99     9   9    > 8                                                          44    3 98         void CDInfo(SymbolDesc, Pointer, Info)n" 98         struct s *SymbolDesc; 98         struct o *Pointer;f 98         int *Info;  994 8         void CDSetInfo(SymbolDesc, Pointer, Info)" 98         struct s *SymbolDesc; 98         struct o *Pointer;; 98         int Info; 999 8         void CDProperty(SymbolDesc, Pointer, Property)t" 98         struct s *SymbolDesc; 98         struct o *Pointer;9% 98         struct prpty **Property;8 99@ 8         int CDAddProperty(SymbolDesc, Pointer, Value, String)" 98         struct s *SymbolDesc; 98         struct o *Pointer;  98         char *String; 98         int Value;T 99; 8         int CDRemoveProperty(SymbolDesc, Pointer, Value)u" 98         struct s *SymbolDesc; 98         struct o *Pointer;  98         int Value;8 99D      _C_D_B_B() returns the bounding box of an object pointed to  ^ by  _P_o_i_n_t_e_r  in  the  symbol  identified  by _S_y_m_b_o_l_D_e_s_c.  If  R _P_o_i_n_t_e_r is a null pointer, then _C_D_B_B() returns the  bounding  D box  of the entire symbol.  The _C_D_B_B() procedure may have to  < use temporary storage during the computation  of  a  symbols  < bounding  box.   If it can not allocate the required memory,  N _C_D_B_B() returns with the  value  of  _F_a_l_s_e.   Otherwise,  the  " value of _T_r_u_e is returned.    P      _C_D_I_n_f_o() returns the value _I_n_f_o of the integer informa-  X tion  field  of an object referenced by _P_o_i_n_t_e_r.  If _P_o_i_n_t_e_r  < is a null pointer, then the value of the  information  field  G of the symbol referenced by _S_y_m_b_o_l_D_e_s_c is returned.N   9                <                                                           45    N      _C_D_S_e_t_I_n_f_o() sets  the  integer  information  field  the  X object pointed to by _P_o_i_n_t_e_r.  If _P_o_i_n_t_e_r is a null pointer,  D then the information field of the symbol referenced by  _S_y_m_-  J _b_o_l_D_e_s_c  is  set.  The information field is used extensively  < by KIC to mark the object or temporarily storing information  # while the object is being modified.r    `      _C_D_P_r_o_p_e_r_t_y() returns the pointer _P_r_o_p_e_r_t_y  that  refer-  < ences  the  linked-list  of  properties  associated with the  X object referenced by _P_o_i_n_t_e_r.  If _P_o_i_n_t_e_r is a null pointer,  J then  the  property list of the symbol referenced by _S_y_m_b_o_l_-  T _D_e_s_c is returned.  The pointer _P_r_o_p_e_r_t_y  is  returned  as  a  < null  pointer  if  there is no property list associated with   the particular object.    <      The property  list  structure  is  defined  in  Section  < 2.2.7.   A property consists of an identifying integer and a  < null terminated character string  extension.   There  is  no  < standard  set of properties or property values, and CD never  < tries to interpret the entries in a property list.  Property  4 lists are available for the user's own specific use.    V      _C_D_A_d_d_P_r_o_p_e_r_t_y() inserts property information  into  the  J property  list  of  the  object  referenced  by _P_o_i_n_t_e_r.  If  J _P_o_i_n_t_e_r is a null pointer, then the property is added to the  P property  list  of the symbol referenced by _S_y_m_b_o_l_D_e_s_c.  The  < property information  consists  of  an  identifying  integer  F _V_a_l_u_e  and a null-terminated character string extension that  b is pointed to by _S_t_r_i_n_g.  If _C_D_A_d_d_P_r_o_p_e_r_t_y()  is  unable  to                  <                                                           46    F allocate  memory,  the  value _F_a_l_s_e is returned.  Otherwise,  & the value of _T_r_u_e is returned.    \      _C_D_R_e_m_o_v_e_P_r_o_p_e_r_t_y() deletes  property  information  from  J the  property  list of the object referenced by _P_o_i_n_t_e_r.  If  J _P_o_i_n_t_e_r is a null pointer, then the property is removed from  P the  property  list  of the symbol referenced by _S_y_m_b_o_l_D_e_s_c.  F Every property with the  value  of  _V_a_l_u_e  is  removed.   If  \ _C_D_R_e_m_o_v_e_P_r_o_p_e_r_t_y()   has  trouble  allocating  or  releasing  F memory, the value _F_a_l_s_e is returned.  Otherwise,  the  value   of _T_r_u_e is returned.  / _2._4._9. _C_D _I_n_t_e_g_r_i_t_yi    <      After a symbol has been  created  or  modified,  it  is  < eventually  necessary  to reflect the changes throughout the  < CD database.  The following procedure is provided  for  this   purpose:  & 98         int CDReflect(SymbolDesc)" 98         struct s *SymbolDesc; 99N      _C_D_R_e_f_l_e_c_t() must be invoked at certain times by the  CD  P application  if  the symbol that is referenced by _S_y_m_b_o_l_D_e_s_c  < is modified.  If the changes to the symbol has  changed  its  N bounding box, a call to _C_D_R_e_f_l_e_c_t() will update the bounding  < box information in every other symbol  in  the  CD  database  < that references it either directly or indirectly.  This pro-  h cedure is called _b_o_u_n_d_i_n_g _b_o_x _p_r_o_p_a_g_a_t_i_o_n.  Only the changes  P to  the  symbol  referenced  by  _S_y_m_b_o_l_D_e_s_c  are  propagated   through the database.                     <                                                           47    N      The correct use of _C_D_R_e_f_l_e_c_t() is  important  and  well  @ worth  an example.  Consider two symbols _X and _Y, where sym-  B bol _Y is called in _X.  The bounding box of _Y is  changed  by  N some  means.   If  _C_D_R_e_f_l_e_c_t()  is  invoked  with the symbol  @ descriptor of _X as an argument, the changes to symbol _Y will  > not  be  reflected in the bounding box of symbol _X.  If how-  P ever _C_D_R_e_f_l_e_c_t() is invoked with the symbol descriptor of  _Y  > as  an  argument,  all  changes to the symbol _Y will then be  > reflected in the bounding box of _X  and  all  other  symbols   that call _Y.    X      The value of _F_a_l_s_e is returned if _C_D_R_e_f_l_e_c_t() is unable  D to  allocate  new  memory.   Otherwise, the value of _T_r_u_e is  	 returned.                                                                           <                                                           48    u _2._5. _T_w_o _D_i_m_e_n_s_i_o_n_a_l _T_r_a_n_s_f_o_r_m_a_t_i_o_n _P_a_c_k_a_g_ep    <      The following routines provide two dimensional, rectil-  < inear transformations using integer arithmetic.  The package  < of routines includes such capabilities as translation,  mir-  < roring,   rotation,  a  transformation  stack,  and  inverse  < transformations.  Transformations are modeled  by  three  by  < three integer matrices.  A further explanation of these pro-  < cedures and how  a  transformation  may  be  modeled  by  an  ) integer array is provided in [6] and [7].u  7 _2._5._1. _I_n_i_t_i_a_l_i_z_a_t_i_o_nD    <      The following procedure initializes the transform pack-   age:   98         void TInit()m 99F      _T_I_n_i_t() initializes the transform package  and  returns  < with  the current transform equal to the identity transform.  R Unlike the _C_D_I_n_i_t() procedure, _T_I_n_i_t() may be  invoked  more  < than  once  in  an application program where the only effect  < will be that all contexts in the  transformation  stack  are  H lost.   This  initialization routine is invoked by _C_D_I_n_i_t(),  < by KIC routines that capable of detecting a recursive symbol  . hierarchy, and by interrupt handling routines.  W _2._5._2. _T_h_e _C_u_r_r_e_n_t _T_r_a_n_s_f_o_r_m_a_t_i_o_n    <      The following eight procedures are used  to  access  or  " modify the current transformation:   98         void TIdentity()  99     9   9    > 8                                                          49    " 98         void TTranslate(X, Y) 98         int X, Y; 99 8         void TMY()l 99 8         void TMX()  99/ 8         void TRotate(XDirection, YDirection)( 98         int XDirection, YDirection; 99 8         void TPoint(X, Y) 98         int *X, *Y; 99N      _T_I_d_e_n_t_i_t_y() sets  the  current  transformation  to  the  < identity  matrix.   The  previous  current transformation is  
 destroyed.    P      _T_T_r_a_n_s_l_a_t_e() postmultiplies the current  transformation  < matrix by a transformation that translates by a displacement   of _X, _Y.    B      _T_M_Y() postmultiplies the current transformation  matrix  < by  a  transformation  that mirrors the y-coordinates (i.e.,  ( mirrors in the direction of the y axis).    B      _T_M_X() postmultiplies the current transformation  matrix  < by  a  transformation  that mirrors the x-coordinates (i.e.,  ( mirrors in the direction of the x axis).    J      _T_R_o_t_a_t_e()  postmultiplies  the  current  transformation  < matrix by a transformation that rotates counter-clockwise by  < an angle that is expressed as a CIF-style direction  vector.  2 Only 0, 90, 180, 270 degree rotations are allowed.    L      The _T_P_o_i_n_t() procedure transforms the  point  _X,  _Y  by       9          <                                                           50    4 multiplying it by the current transformation matrix.  Q _2._5._3. _T_h_e _T_r_a_n_s_f_o_r_m_a_t_i_o_n _S_t_a_c_ks    <      The transformation stack structure is  defined  in  the  ' _x_f_o_r_m_s._h file as follows:r  + 98        #define XFORMSTACKSIZE      100 99 8        /*. 98         * Transformation stack structure. 98         */y 98        struct tt {r2 98            int ttStack[XFORMSTACKSIZE][3][3]; 98            int ttSP;r$ 98            int ttCurrent[3][3];+ 98            int ttInverseCurrent[3][3];a 98            }; 99<      Transformations are saved in their respective three  by  J three  array  representations in the _t_t_S_t_a_c_k stack structure  D member.  The _t_t_S_P  integer  member  points  to  the  current  < transformation  on the stack, and the current transformation  N is also contained in the _t_t_C_u_r_r_e_n_t array member.   When  the  L user invokes the _T_I_n_v_e_r_s_e() procedure to compute the inverse  < of  the  current  transform,  the  resulting  transformation  Y matrix is saved in the _t_t_I_n_v_e_r_s_e_C_u_r_r_e_n_t structure member.l    <      The following procedures are used for  maintaining  the   transformation stack:T   98         int TEmpty()l 99 8         int TFull() 99 8         void TPush()a 99 8         void TPop() 99       9   9    > 8                                                          51     98         void TCurrent(TF) 98         int *TF;e 99P      _T_E_m_p_t_y() returns the value of _T_r_u_e if  the  transforma-  < tion  stack  is  empty.  If the transformation stack is com-  9 pletely filled, the value of _F_a_l_s_e is returned.e    N      _T_F_u_l_l() returns the value of _T_r_u_e if the transformation  D stack is full.  Otherwise, the value of _F_a_l_s_e is returned.    F      _T_P_u_s_h() pushes the current transform onto the transfor-  < mation  stack.   The  value  of the current transform is not  < changed, and the transformation stack is not checked for  an   overflow condition.    D      _T_P_o_p() pops the current transform from the  transforma-  < tion  stack.  The value of the current transform becomes the  < transform that was most recently pushed onto the stack,  and  < the  transformation  stack  is  not checked for an underflow  
 condition.    L      _T_C_u_r_r_e_n_t() places the current  transform  matrix  in  a  < nine  integer array that is passed from the calling program.  < The first row of the transformation matrix  appears  as  the  < first  three integers in the argument, the second row of the  < transformation matrix appears as the  next  three  integers,  < etc.   After  several  transformations  have been defined by  j _T_T_r_a_n_s_l_a_t_e(), _T_R_o_t_a_t_e(), _T_M_X(), and _T_M_Y(), it is possible to  < determine the minimum resultant or equivalent transformation  < through the examination  of  the  elements  of  the  current  : transformation matrix as described in the following table:     9          <                                                           52    ) 8 TF[0] TF[3] TF[1] TF[4] Transformation, 98   1      0     0     1  Translate only.7 98   0     -1     1     0  Rotate 90 deg., translate.t8 98   0      1    -1     0  Rotate 180 deg., translate.8 98   -1     0     0    -1  Rotate 270 deg., translate.4 98   -1     0     0     1  Mirror in X, translate.4 98   1      0     0    -1  Mirror in Y, translate.D 98   0     -1    -1     0  Mirror in X, rotate 90 deg., translate.E 98   0      1     1     0  Mirror in X, rotate 270 deg., translate.  99<      For all cases, the X, Y translation vector is given  by  
 TF[6], TF[7].   Z _2._5._4. _T_h_e _I_n_s_t_a_n_c_e _T_r_a_n_s_f_o_r_m_a_t_i_o_n    <      The following procedure is  provided  specifically  for  % maintaining instance transformations:     98         void TPremultiply() 99<      As an application program traverses a symbol hierarchy,  < it will maintain the current instance transformation by com-  < puting the product of the symbols current transform and  the  T transformation  of  its  master.   _T_P_r_e_m_u_l_t_i_p_l_y()  forms the  < instance transform by premultiplying the  current  transform  < with the transform that was last pushed onto the transforma-  < tion stack and placing the product in the current  transfor-  < mation  matrix.   Thus,  the  procedure for transforming the  1 coordinates of an instance is demonstrated below:r  7 98        /* push master cell transform onto stack */e 98        TPush();5 998        /* set current transform to identity */e 98        TIdentity();L 998        /* Invoke TMX, TTranslate, etc. to build instance transform */ 98        TMX(); 98        TMY(); 98        TTranslate(Dx, Dy);/ 998        /* Form the instance transform */o 98        TPremultiply();e       9   9    > 8                                                          53    < 98        /* Invoke TPoint to transform instance points */ 98        TPoint(&X, &Y); . 998        /* return to master transform */ 98        TPop();  99t _2._5._5. _I_n_v_e_r_s_e _o_f _t_h_e _C_u_r_r_e_n_t _T_r_a_n_s_f_o_r_m_a_t_i_o_n    <      The following procedures are used to obtain an  inverse   transformation:    98         void TInverse() 99# 8         void TInversePoint(X, Y)e 98         int *X, *Y; 99L      _T_I_n_v_e_r_s_e()  computes  the  inverse   of   the   current  < transformation.   Computation  of the inverse transformation  J does not affect the  current  transformation.   The  _T_I_n_v_e_r_-  N _s_e_P_o_i_n_t()  routine  transforms the point _X, _Y by multiplying  V it by the inverse  transform  matrix.   The  _T_I_n_v_e_r_s_e_P_o_i_n_t()  L routine  should  not  be  invoked before the _T_I_n_v_e_r_s_e() pro-  < cedure has computed the inverse of the  current  transforma-   tion.t                                       9                <                                                           54    n _2._6. _T_r_a_v_e_r_s_i_n_g _a _S_y_m_b_o_l _H_i_e_r_a_r_c_h_y _w_i_t_h _C_D    <      The following routine is intended to display  a  symbol  < on a graphics terminal.  The reader will note the use of the  < two dimensional transformation package  described  above  as  P well   as   routines   such  as  _D_i_s_p_l_a_y_B_o_x()  that  display  < geometries on a  CRT.   It  is  assumed  that  the  geometry  < display  routines  will  accomplish whatever window-viewport  < clipping is necessary.  This example is similar to  the  KIC   display routine.   98        #include "cd.h"s 99 8        main(){e 98                 . 98                 . 98                 .5 98            /* initialize transformation stack */h 98            TInit(); 98                 . 98                 . 98                 .N 98            /* display SymbolName in the area Left, Bottom - Right, Top */= 98            Display(SymbolName, Left, Bottom, Right, Top)t 98                 . 98                 . 98                 . 98            }T 997 8        Display(SymbolName, Left, Bottom, Right, Top)(! 98            char *SymbolName; - 98            int Left, Bottom, Right, Top;  98            {*% 98            struct s *SymbolDesc; " 98            struct g *GenDesc;" 98            struct o *Pointer; 98            struct t *TGen;P# 98            char *InstanceName; ' 98            int NumX, NumY, DX, DY;   98            int X, Y, Layer; 98            char Type;O 998            /* open symbol named SymbolName (here we assume it exists) */r5 98            CDOpen(SymbolName, &SymbolDesc, 'r');o 999     9   9    > 8                                                          55    L 98            /* initialize generator to return instances in SymbolName */M 98            CDInitGen(SymbolDesc, 0, Left, Bottom, Right, Top, &GenDesc);t 998            loop {O 98                /* Invoke CDGen to access a pointer to an instance array */a9 98                CDGen(SymbolDesc, GenDesc, &Pointer);(> 998                /* Have all instances been traversed? */' 98                if(Pointer == NULL)_ 98                    break;G 998                /* push current transform of master onto stack */ 98                TPush();= 998                /* set current transform to identity */   98                TIdentity();7 998                /* Access instance information */ K 98                CDCall(Pointer, &InstanceName, &NumX, &DX, &NumY, &DY);yT 998                /* Initialize generator to return transform of InstanceName *// 98                CDInitTGen(Pointer, &TGen);oS 998                /* place instance transformation in current transformation */_ 98                loop {5 98                    CDTGen(&TGen, &Type, &X, &Y); ( 98                    if(TGen == NULL)" 98                        break;4 98                    else if(Type == CDTRANSLATE)- 98                        TTranslate(X, Y);m2 98                    else if(Type == CDMIRRORX)" 98                        TMX();2 98                    else if(Type == CDMIRRORY)" 98                        TMY();1 98                    else if(Type == CDROTATE)m* 98                        TRotate(X, Y); 98                    }xN 998                /* Combine transform of InstanceName with it's master */# 98                TPremultiply(); U 998                /* recursively call display to traverse and display instance */[D 98                Display(InstanceName, Left, Bottom, Right, Top);; 998                /* pop master transform from stack */e 98                TPop();  98                }n3 998            /* now traverse the geometries */ ? 98            for(Layer = 1; Layer <= CDNUMLAYERS; ++Layer) { V 998                /* Set the current color to be a color associated with Layer. */$ 98                SetColor(Layer);@ 998                /* initialize generator for layer Layer */U 98                CDInitGen(SymbolDesc, Layer, Left, Bottom, Right, Top, &GenDesc);  998                loop {I 98                    /* Invoke CDGen to access pointer to an object */m= 98                    CDGen(SymbolDesc, GenDesc, &Pointer);r, 998                    /* Last object? */       9   9    > 8                                                          56    + 98                    if(Pointer == NULL)e" 98                        break;G 998                    /* Access the type of the geometry as Type */a/ 98                    CDType(Pointer, &Type); P 998                    /* Dispatch according to Type to specific procedure */+ 98                    if(Type == CDBox) { 0 98                        /* Access the box */< 98                        CDBox(SymbolDesc, Pointer, ...);= 98                        /* Transform the box's center. */ + 98                        TPoint(&X, &Y); 2 98                        /* Display the box. */< 98                        DisplayBox(X, Y, Length, Width); 98                        } 0 98                    else if(Type == CDWire){1 98                        /* Access the wire */r= 98                        CDWire(SymbolDesc, Pointer, ...);i" 98                             ." 98                             ." 98                             . 98                        }  98                         . 98                         .  98                        etc. 98                         . 98                         . 98                    }( 98                }8 98            }  99                                               9                <                                                           57    C _2._7. _T_r_a_n_s_l_a_t_i_o_n _R_o_u_t_i_n_e_s     <      The layout description language of CD is CIF.  The fol-  < lowing routines are used by CD to generate or interpret CIF:  . 98        int CDTo(CIFFile,Root,A,B,Program)  98        char *CIFFile,*Root; 98        int A,B; 98        char Program;  99? 8        int CDFrom(Root,CIFFile,A,B,Layers,NumLayers,Program)r( 98        char *Root,*CIFFile,Program;! 98        int *Layer,NumLayers;8 98        int A,B; 99. 8        int CDParseCIF(Root,CIFFile,Program)( 98        char *Root,*CIFFile,Program; 99A 8        int CDGenCIF(FileDesc,SymbolDesc,SymbolNum,A,B,Program)L 98        FILE *FileDesc; ! 98        struct s *SymbolDesc;  98        int *SymbolNum,A,B;a 98        char Program;  99R      _C_D_T_o() translates from a CIF file  named  _C_I_F_F_i_l_e  into  < symbol  files, each having a file name identical to the sym-  < bol that it contains.  CIF commands that are not  between  a  D _D_S  and  a  matching  _D_F are stored in the file specified by  H _R_o_o_t.  All objects are scaled by the ratio _A/_B  microns  per   lambda.     L      _C_D_T_o() will call the routine _P_C_I_F() to read  the  input  < CIF  file.  The requirements for this parser can be found in  H Section 2.4.3 describing the _C_D_O_p_e_n()  routine  and  in  the  + section that describes the fast CIF parser.     <      Because there are different styles of  CIF  that  embed  J symbol  names  differently,  the character _P_r_o_g_r_a_m will tell       9          <                                                           58    L _C_D_T_o() and the parser _P_C_I_F() which style of CIF  to  expect.  T Before  calling the parser, _C_D_T_o() sets the _d_P_r_o_g_r_a_m charac-  < ter in the CD parameters structure described in Section  2.8  J to  the  character  _P_r_o_g_r_a_m.   By  accessing  this structure  < member, the parser determines the origin of  the  CIF.   The  J following  values  for  _P_r_o_g_r_a_m  are  valid for the fast CIF   parser used by CD:  ' 98        Program          CIF format * 98           'a'           Stanford CIF,% 98           'b'           NCA CIF,XE 98           'e'           Berkeley's KIC with property extensions,r& 98           'h'           HP's IGS,, 98           'i'           Xerox's Icarus,, 98           'k'           Berkeley's KIC,. 98           'm'           mextra-style CIF,) 98           's'           Xerox's Sif, / 98           'n'           none of the above.e 99D      If the _C_D_T_o() routine encounters any difficulty in  the  \ CIF  conversion,  the value of _F_a_l_s_e is retuned, _C_D_S_t_a_t_u_s_I_n_t  V is set to value of _C_D_P_A_R_S_E_F_A_I_L_E_D, and a  diagnostic  message  8 is placed in _C_D_S_t_a_t_u_s_S_t_r_i_n_g.    H      The _C_D_F_r_o_m()  routine  translates  a  symbol  hierarchy  L rooted  at  the symbol named _R_o_o_t into a CIF file named _C_I_F_-  D _F_i_l_e.  The style of CIF output is identified by the  charac-  X ter  _P_r_o_g_r_a_m.   The valid arguments for _P_r_o_g_r_a_m are the same  D as for the _C_D_T_o() procedure.  All objects are scaled by  the  @ ratio  _A/_B  microns per lambda during the conversion.  It is  < assumed that all instances in the symbol hierarchy exist  in   the current search path.    P      The _L_a_y_e_r_s argument is a pointer to an  array  of  _N_u_m_-                    <                                                           59    H _L_a_y_e_r_s  integers  that are used to mask certain layers in CD  L layer table.  If _L_a_y_e_r_s[_N]  is  zero,  where  _N  is  a  non-  N negative  integer  less than _N_u_m_L_a_y_e_r_s, then any object that  > is on layer number _N in the CD layer table will  not  appear   in the CIF output file.a    H      If _C_D_F_r_o_m() encounters any difficulty  in  the  conver-  \ sion,  the  value of _F_a_l_s_e is retuned and _C_D_S_t_a_t_u_s_I_n_t is set  > to one of the following values defined in the _c_d._h file:  A 98    #define CDPARSEFAILED     1    /* (FATAL) parse failed */pF 98    #define CDNEWSYMBOL       3    /* symbol not in search path */B 98    #define CDMALLOCFAILED    11   /* (FATAL) out of memory */ 99H      If no difficulty is encountered, _C_D_F_r_o_m() returns  with   the value of _T_r_u_e.    P      The _C_D_P_a_r_s_e_C_I_F() procedure will create  a  CD  database  R rooted at a symbol named _R_o_o_t from a CIF file _C_I_F_F_i_l_e rather  < than building the database from a hierarchy of symbol files.  D The  style  of CIF input is identified by the character _P_r_o_-  R _g_r_a_m.  The valid arguments for _P_r_o_g_r_a_m are the same  as  for   the _C_D_T_o() routine.s    P      When _C_D_P_a_r_s_e_C_I_F() encounters a  reference  to  a  layer  < that  was  not previously defined in the CD layer table by a  P call to _C_D_S_e_t_L_a_y_e_r(), the new layer is added  to  the  layer  T table.  This differs from the _C_D_F_r_o_m() and _C_D_O_p_e_n() routines  < that return CDPARSEFAILED whenever they encounter  an  unde-  H fined  layer.  A layer is considered undefined if the _l_T_e_c_h_-  H _n_o_l_o_g_y field in the CD layer table  is  a  blank  character.                    <                                                           60    9 See Section 2.2.8 that describes the CD layer descriptor._    P      If  _C_D_P_a_r_s_e_C_I_F()  encounters  any  difficulty  in   the  \ conversion, the value of _F_a_l_s_e is retuned and _C_D_S_t_a_t_u_s_I_n_t is  B set to one of the following values defined in the _c_d._h file:  A 98    #define CDPARSEFAILED     1    /* (FATAL) parse failed */aF 98    #define CDNEWSYMBOL       3    /* symbol not in search path */B 98    #define CDMALLOCFAILED    11   /* (FATAL) out of memory */ 99P      If no difficulty  is  encountered,  _C_D_P_a_r_s_e_C_I_F  returns   with the value of _T_r_u_e.     T      _C_D_G_e_n_C_I_F() is used by the _C_D_T_o() routine to generate  a  L CIF  file identified by the stream _F_i_l_e_D_e_s_c of the CD symbol  b referenced by _S_y_m_b_o_l_D_e_s_c.  The  integer  _S_y_m_b_o_l_N_u_m  contains  < the  number of the first symbol created in the CIF file; the  < value will be  incremented  by  one  for  succeeding  symbol  < definitions.   The  style of CIF output is identified by the  X character _P_r_o_g_r_a_m, and the valid arguments for  _P_r_o_g_r_a_m  are  D the  same  as  for  the  _C_D_T_o()  procedure.  All objects are  @ scaled by the  ratio  _A/_B  microns  per  lambda  during  the  H conversion.    If  _C_D_F_r_o_m()  encounters  any  difficulty  in  F acquiring or  allocating  memory,  the  value  of  _F_a_l_s_e  is  R retuned  and  _C_D_S_t_a_t_u_s_I_n_t  is  set  to  the  value of CDMAL-  B LOCFAILED as defined in the _c_d._h file.  If no difficulty  is  O encountered, _C_D_G_e_n_C_I_F() returns with the value of _T_r_u_e.I                                  <                                                           61    W _2._8. _T_h_e _C_D _P_a_r_a_m_e_t_e_r_s _D_e_s_c_r_i_p_t_o_ri    <      Several  parameters  are  required  by  CD  to  control  B actions.   The  CD  parameters struct is defined in the _c_d._h   file as follows:   98        struct d { 98            /*9 98             * DCONTROLCDOPEN denotes CD is in CDOpeneJ 98             * DCONTROLPCIF denotes CD is in parsing CIF in CDParseCIF5 98             * DCONTROLCDTO denotes CD is in CDToeE 98             * DCONTROLVANILLA denotes CD is in none of the above  98             */u 98            char dControl; 99I 8            /* Current parameters for symbol being parsed in CDOpen. */ ) 98            int  dNumX,dDX,dNumY,dDY;e 996 8            /* Scale factors for CDTo and CDFrom. */ 98            int dA,dB; 99) 8            /* Symbol scale factors. */  98            int dDSA,dDSB; 99! 8            struct o *dPointer;_& 98            struct s *dSymbolDesc;( 98            struct s *dRootCellDesc; 99@ 8            /* UNIX file names are limited to 14 characters *// 98            char dSymbolName[FILENAMESIZE]; & 98            FILE *dSymbolFileDesc; 99 8            /*. 98             * Fields used in CDTo follow. 98             */c 990 8            /* True if parsing root symbol. */ 98            int dRoot; 99% 8            /* Root's file desc. */e$ 98            FILE *dRootFileDesc; 99A 8            /* Current property list for symbol being parsed */f) 98            struct prpty *dPrptyList;b 99 9     9   9    > 8                                                          62     98            /*8 98             *   dProgram   ==  'a' if Stanford CIF.3 98             *   dProgram   ==  'b' if NCA CIF.lQ 98             *   dProgram   ==  'e' if Berkeley CIF with property extensions.l4 98             *   dProgram   ==  'h' if HP's IGS.> 98             *   dProgram   ==  'i' if Xerox's Icarus CIF.8 98             *   dProgram   ==  'k' if Berkeley CIF.< 98             *   dProgram   ==  'm' if mextra-style CIF.8 98             *   dProgram   ==  's' if Sif gened it.= 98             *   dProgram   ==  'n' if none of the above. 98             */n 98            char dProgram; 99 8            /*? 98             * Symbol name table for CIF file being parsed.eL 98             * UNIX file names are 14 characters, VMS names are smaller. 98             */ ? 98            char dSymTabNames[CDNUMREMEMBER][FILENAMESIZE];12 98            int dSymTabNumbers[CDNUMREMEMBER];$ 98            int dNumSymbolTable; 99 8            /*K 98             * Because CIF files may have FORWARD references, CDTo musteM 98             * pass over the CIF file TWICE.  On the first pass,  it justt2 98             * fills up the symbol name table. 98             */  98            int dFirstPass;O 99% 8            /* True if debugging */a 98            int dDebug;O) 98            int dNumSymbolsAllocated;  98            }N 98        CDDesc;  99H      The contents of the CD parameters descriptor _C_D_D_e_s_c are  B available  to  all source files that include the _c_d._h header  < file.  Most of the members in the  CD  parameters  structure  < are  used  for  the  parsing or generating of CIF.  They are  < used most frequently by the parser and  action  routines  as  < working storage space for symbol information.  See Chapter 3  < that describes the CIF parser and action routines for a com-  < plete explanation of the use of each member in the CD param-   eters descriptor.f                    <                                                           63      2                          _C_h_a_p_t_e_r _3      G                     _T_h_e _F_a_s_t _C_I_F _P_a_r_s_e_r         <      The CIF parser is the set of  routines  that  interface  < KIC  and CD to a standard intermediate layout language (CIF)  < and the secondary storage site for symbol definitions.  This  < section  describes  the  requirements of the layout language  3 parser and the parameters that control its actions.r    D      The term _f_a_s_t is used here to  indicate  that  whenever  < there  was  a choice to be made between the size of the rou-  < tines and their respective speed, the  decision  has  always  < been to optimize for speed.  Consequently, the parser is the  < largest module in KIC.  With  the  optimizations  that  have  H been  made  to the parser, the _C_D_O_p_e_n() routine is neverthe-  < less limited by the speed of the parser that is  impeded  by  , the excessive overhead of memory allocation.    <      Three source files constitute the CIF parser; they  are  v _p_a_r_s_e_r._c, _a_c_t_i_o_n_s._c, and _g_e_n_c_i_f._c.  The routines in _p_a_r_s_e_r._c  < scan the input file for the primitive commands of the layout  < language.   The  action  routines  are invoked by the parser  < when a primitive command is found.  The gencif routines pro-  < duce the primitives of the CIF layout language in the syntax   that the parser understands.    <      Because the data model for the CD database is  CIF,  it                  <                                                           64    < would  be difficult to replace the fast CIF parser with that  < of another layout language if the user should decide  to  do  F so.  It is nevertheless possible to make CD _s_p_e_a_k in another  < language, given that the layout language is hierarchical and  < has  similar  geometry  types.  To accomplish this, the pro-  J grammer would have to replace  the  source  files  _p_a_r_s_e_r._c,  Z _a_c_t_i_o_n_s._c,  and  _g_e_n_c_i_f._c as well as rewrite the CD routines   _C_D_U_p_d_a_t_e(), _C_D_G_e_n_C_I_F(), _C_D_T_o(), _C_D_F_r_o_m(), and _C_D_P_a_r_s_e_C_I_F().s                                                                                                <                                                           65    4 _3._1. _A_c_t_i_o_n _R_o_u_t_i_n_e_s    <      The function of the parser is to interpret  the  layout  < language,  and the action routines are used by the parser to  < complete tasks that are specific to  primitive  commands  of  < the  layout  language in one of three contexts.  The context  L of actions is defined by  the  _d_C_o_n_t_r_o_l  member  of  the  CD  H parameter  descriptor _C_D_D_e_s_c that can have one of four value  3 that are defined in the _c_d._h file as follows:h  
 98    /* 98     * CD Control flagsa 98     */p% 98    #define DCONTROLCDOPEN    'o' % 98    #define DCONTROLPCIF      'p'r% 98    #define DCONTROLCDTO      't' % 98    #define DCONTROLVANILLA   'v'i 99<      This section will describe the purpose of each  of  the   above flags.    <      The action routines are invoked  only  by  the  parser.  < The DCONTROLVANILLA control character flag indicates that CD  < is not in the process of parsing  CIF.   An  action  routine  < should  therefore  never be invoked when the control flag is   set to this value.    <      The DCONTROLCDTO control flag is used to  signify  that  < CD  is  currently translating a CIF file into individual KIC  < or CD symbol files.  The action to  be  performed  for  this  < case  is  to  output the primitive command that was found by  < the parser directly into the respective symbol file.  If the  R _C_D_D_e_s_c._d_R_o_o_t  flag  is  non-zero, output will be directed to                    <                                                           66    b the file referenced by _C_D_D_e_s_c._d_R_o_o_t_F_i_l_e_D_e_s_c, and output will  < otherwise   be   directed   to   the   file   referenced  by  A _C_D_D_e_s_c._d_S_y_m_b_o_l_F_i_l_e_D_e_s_c.*    b      The root file descriptor _C_D_D_e_s_c._d_R_o_o_t_F_i_l_e_D_e_s_c  is  ini-  D tialized  by  _C_D_T_o() or whatever procedure that would invoke  X the parser with the _C_D_D_e_s_c._d_C_o_n_t_r_o_l flag set to the value of  < DCONTROLCDTO.       The      symbol      file     descriptor  f _C_D_D_e_s_c._d_S_y_m_b_o_l_F_i_l_e_D_e_s_c however must be  initialized  by  the  T action  routine  _A_B_e_g_i_n_S_y_m_b_o_l()  which  is invoked for a new  < symbol definition, and therefore this action routine must be  < capable of determining the symbol name depending on the par-  < ticular style of CIF that is  identified  by  the  value  of  n _C_D_D_e_s_c._d_P_r_o_g_r_a_m.  Also this routine must set _C_D_D_e_s_c._d_R_o_o_t to  < zero to direct subsequent output to  the  respective  symbol  R file.   The symbol file is closed and _C_D_D_e_s_c._d_R_o_o_t is set to  P unity by the action routine _A_E_n_d_S_y_m_b_o_l() which is invoked at  ' the termination of a symbol definition.n    <      Because CIF may contain forward references to  symbols,  < it  is  necessary for the action routines to build and main-  < tain a symbol table.  As a result, the parsing is a two-pass  < operation,  where  the  first  pass is dedicated to the con-  T struction of the symbol table by the  _A_B_e_g_i_n_S_y_m_b_o_l()  action  < routine.   The symbol table is represented in the CD parame-  Z ters descriptor as follows: the integer _d_N_u_m_S_y_m_b_o_l_T_a_b_l_e is a  < count  of  the  current symbols in the table.  The character   array _d_S_y_m_T_a_b_N_a_m_e_s[_C_D_N_U_M_R_E_M_E_M_B_E_R][_F_I_L_E_N_A_M_E_S_I_Z_E] contains the                    <                                                           67    r symbol  names,  and  the array _d_S_y_m_T_a_b_N_u_m_b_e_r_s[_C_D_N_U_M_R_E_M_E_M_B_E_R]  * contains the corresponding symbol numbers.    ;      All measurements are be scaled by the following value:t    8    (CDDesc.dB * CDDesc.dDSA) / (CDDesc.dA * CDDesc.dDSB)    d The integer values _C_D_D_e_s_c._d_D_S_A and _C_D_D_e_s_c._d_D_S_B are the  sym-  < bol  scale  factors, dimensionless, and are currently always  \ set to unity.  The integer values  _C_D_D_e_s_c._d_A  and  _C_D_D_e_s_c._d_B  < define  respectively  the  micron  per lambda scaling ratio.  < Because the conversion is from CIF, for which  the  database  < unit  is one one-hundredth of a micron, to KIC or CD format,  < for which the database unit is one-hundredth  of  a  lambda,  L the  value of _C_D_D_e_s_c._d_B is in the numerator.  The scale fac-  < tor is computed for every metric value to avoid the  use  of  < floating  point  arithmetic;  because  integer arithmetic is  < significantly more fast than floating point, this is  not  a   severe penalty.i    <      The DCONTROLCDOPEN control flag  is  used  when  CD  is  < currently parsing a symbol file.  This action differs signi-  < ficantly from the previously described actions in  that  the  < CD  database  is  constructed in local memory.  When objects  < are discovered by the parser, the  action  routine  for  the  < object  will insert it into the the symbol descriptor refer-  f enced by _C_D_D_e_s_c._d_S_y_m_b_o_l_D_e_s_c which is initialized by the _C_D_O_-  B _p_e_n()  procedure.  Consequently, there is one action routine  < for each of the CD object creation procedures  described  in                    <                                                           68    < Section 2.4.4.  There is no scaling performed on the objects  < when they are inserted into the symbol storage bins;  metric  < data is represented in one one-hundredth lambda units in the   KIC or CD symbol files.u    <      Because the creation of an instance requires the  invo-  < cation  of  several  CD  procedures  using  the  same object  X pointer, the parameter _C_D_D_e_s_c._d_P_o_i_n_t_e_r is used as the object  < descriptor  pointer  for  all CD object creation procedures.  \ The  property  list  referenced  by   _C_D_D_e_s_c._d_P_r_p_t_y_L_i_s_t   as  < attached  to each object or symbol after its creation.  This  < allows property information to be saved in the CIF  as  user   extensions.     <      The KIC or CD symbol files contain  extensive  informa-  < tion  that  allows  the handling of forward references to be  < postponed until all geometric objects have been parsed,  and  < thereby  avoid  two  passes through the symbol file.  When a  < symbol call is encountered, the action routine  will  insert  < the object descriptor for the instance into the storage bins  < and a reference is made in the master-list  of  the  calling  Z symbol.  The _C_D_B_e_g_i_n_M_a_k_e_C_a_l_l() procedure will not attempt to  X open the instance in CD if the _C_D_D_e_s_c._d_C_o_n_t_r_o_l flag  is  set  < to  DCONTROLCDOPEN.  When the parsing of a particular symbol  H has completed, _C_D_O_p_e_n() will begin traversing  the  symbol's  < master-list,  read  all referenced symbols into the database  F if they have not already been opened, and invoke  the  _C_D_R_e_-  F _f_l_e_c_t()  procedure  to reflect the bounding box of the every                    <                                                           69    < instance throughout the CD database.  This algorithm  allows  H _C_D_O_p_e_n()  to  be  called  recursively to build a multi-level   symbol hierarchy.y    d      The _C_D_O_p_e_n() routine will set the _C_D_D_e_s_c._d_C_o_n_t_r_o_l  con-  < trol  flag  to the value of DCONTROLVANILLA before terminat-   ing.    <      The DCONTROLPCIF control flag is used when CD  is  con-  < structing  the  database from a CIF file instead of a direc-  < tory of KIC or CD symbol files.  The actions to be performed  < are  often  identical  to those for DCONTROLCDOPEN where the  < major differences are in the handling of symbol definitions.  ^ The  symbol  descriptor _C_D_D_e_s_c._d_S_y_m_b_o_l_D_e_s_c is initialized by  P _C_D_P_a_r_s_e_C_I_F() or whatever procedure  that  would  invoke  the  X parser  with  the  _C_D_D_e_s_c._d_C_o_n_t_r_o_l  flag set to the value of  b DCONTROLPCIF.  The symbol  descriptor  _C_D_D_e_s_c._d_R_o_o_t_F_i_l_e_D_e_s_c,  ^ is  used  as  temporarily  storage of the _C_D_D_e_s_c._d_S_y_m_b_o_l_D_e_s_c  T symbol descriptor by the action routine _A_B_e_g_i_n_S_y_m_b_o_l() which  < is invoked when a new symbol definition is discovered by the  < parser.  This action routine will then open a new symbol  in  < the  database  for  the  new symbol definition and therefore  < this routine must be capable of determining  the  respective  < symbol name depending on the particular style of CIF that is  X identified by the value of _C_D_D_e_s_c._d_P_r_o_g_r_a_m.  The  descriptor  ^ pointer  _C_D_D_e_s_c._d_S_y_m_b_o_l_D_e_s_c  is  again  set  to  the pointer  v _C_D_D_e_s_c._d_R_o_o_t_F_i_l_e_D_e_s_c, by  the  action  routine  _A_E_n_d_S_y_m_b_o_l()  ; which is invoked at the termination of a symbol definition.t                    <                                                           70    <      When objects are discovered  by  the  CIF  parser,  the  < action  routine  for  the object will insert it into the the  ^ symbol descriptor referenced by  _C_D_D_e_s_c._d_S_y_m_b_o_l_D_e_s_c.   There  < is  no  scaling  performed  on  the  objects  when  they are  < inserted into the symbol storage bins.  An application  pro-  P gram  that  uses the _C_D_P_a_r_s_e_C_I_F() routine must be aware that   _t_h_e _s_i_z_e _o_f _t_h_e _C_D _d_a_t_a_b_a_s_e _u_n_i_t _i_s _o_n_e _o_n_e-_h_u_n_d_r_e_d_t_h  _o_f  _a   _m_i_c_r_o_n.o    <      Because CIF may contain forward references to  symbols,  < it  is  again necessary for the action routines to build and  < maintain a symbol table.  As a  result,  the  parsing  is  a  < two-pass operation, where the first pass is dedicated to the  T construction of  the  symbol  table  by  the  _A_B_e_g_i_n_S_y_m_b_o_l()  < action  routine.   The symbol table is represented in the CD  T parameters descriptor as follows: the  integer  _d_N_u_m_S_y_m_b_o_l_T_-  D _a_b_l_e  is  a  count of the current symbols in the table.  The   character  array   _d_S_y_m_T_a_b_N_a_m_e_s[_C_D_N_U_M_R_E_M_E_M_B_E_R][_F_I_L_E_N_A_M_E_S_I_Z_E]  < contains     the     symbol    names,    and    the    array  r _d_S_y_m_T_a_b_N_u_m_b_e_r_s[_C_D_N_U_M_R_E_M_E_M_B_E_R]  contains  the   corresponding   symbol numbers.D    <      When the parsing of the CIF file  has  been  completed,  P _C_D_P_a_r_s_e_C_I_F()  will  traverse the master-lists of all symbols  < for the purpose of assuring that all referenced symbols  are  < defined  in  the  database and for bounding box propagation.  Z The _C_D_B_e_g_i_n_M_a_k_e_C_a_l_l() procedure will not  try  to  open  the  X referenced symbol if the control flag _C_D_D_e_s_c._d_C_o_n_t_r_o_l is set                    <                                                           71    < to DCONTROLPCIF, and the  bounding  box  in  the  respective  < master-list  descriptor  is  set  to  a null box having zero  < width and heigth.  This is necessary  because  a  referenced  < symbol  may  not have been inserted into the database at the  7 time that the call command is recognized by the parser.i                                                                                                            <                                                           72      2                          _C_h_a_p_t_e_r _4      O                    _T_h_e _K_I_C _U_s_e_r _I_n_t_e_r_f_a_c_eD        ] _4._1. _W_i_n_d_o_w _a_n_d _V_i_e_w_p_o_r_t _M_a_n_a_g_e_m_e_n_t     <      A window is an area in a world coordinate  system  that  < contains objects to be displayed.  A viewport is the area on  < the graphics display in which the user views the contents of  < a window.  In other words, the window defines the objects in  < the database to be displayed, and a viewport  defines  where  < to  display the objects.  The world coordinate system in KIC  < contains the CD symbol that is currently being edited.   The  < unit  of  measurement  in the world coordinate system is one  4 one-hundredth of a lambda, the same unit used by CD.    <      A window may intersect an object in the current  symbol  < such  that  the object is not contained entirely in the win-  J dow, in which case the object would have to  be  _c_l_i_p_p_e_d  to  < the window before it is displayed in the viewport.  For KIC,  < all windows and viewports are rectangular  which  simplifies  ! the geometry clipping procedures.r    <      The coordinate system in a window is identical  to  the  < world coordinate system.  The coordinates in a viewport usu-  < ally correspond to the resolution of the  graphics  display;  < this  provides  one  viewport  coordinate per display pixel.  < The origin of the coordinate system for the layout viewports                  <                                                           73    < in  KIC  is  assumed  to  be  the  lower, left corner of the  < display.  KIC uses a different  coordinate  system  for  the  < viewports  that  contain  only textual information.  In this  < textual coordinate system, a coordinate refers to a  charac-  < ter  block,  and the origin is the upper right corner of the  < graphics display.  For example, the  text  coordinate  (1,1)  < refers to the graphical text character in the upper-most row  < and left-most column of the display;   the  text  coordinate  < (5,10)  refers  to the graphical text character in the fifth  - row and tenth column of the graphics display.     <      KIC divides the graphics display  into  six  viewports:  < the  command  menu  viewport,  the  layer menu viewport, the  < information viewport, the prompt viewport,  and  the  course  < and fine layout viewports.  The following figure illustrates  ( the relative positions of each viewport.                                                                  <                                                           74      :   --------------------------------------------------------:   |     |                                                |:   |  C  |                                                |:   |  O  |                                                |:   |  M  |                                                |:   |  M  |                                                |:   |  A  |                                                |:   |  N  |                                                |:   |  D  |                                                |:   |     |               LAYOUT VIEWPORTS                 |:   |  V  |                                                |:   |  I  |                                                |:   |  E  |                                                |:   |  W  |                                                |:   |  P  |                                                |:   |  O  |                                                |:   |  R  |                                                |:   |  T  |                                                |:   |     |                                                |:   --------------------------------------------------------:   |                  PROMPT VIEWPORT                     |:   --------------------------------------------------------:   |               INFORMATION  VIEWPORT                  |:   --------------------------------------------------------:   |               LAYER  MENU  VIEWPORT                  |:   --------------------------------------------------------    2 778                Figure 2.  The KIC viewports    <      KIC represents windows  and  viewports  with  the  area  @ descriptor that is defined in the _k_i_c._h file as follows:   98        /* 98         * Area structureh 98         */ 98        struct ka {(5 98            int kaLeft, kaBottom, kaRight, kaTop;_ 98            int kaX, kaY;t( 98            float kaWidth, kaHeight; 98            }; 99<      See Section 4.2  that  describes  the  basic  KIC  data  < structures for an explanation of the area structure members.  5 _4._1._1. _T_e_x_t _V_i_e_w_p_o_r_t_s     <      There are four viewports used  by  KIC  for  displaying                  <                                                           75    < textual  information;  the layer menu viewport, the informa-  < tion viewport, the command menu  viewport,  and  the  prompt  < viewport.   Because  the position of the prompt viewport can  < be computed from the parameter  viewport,  the  first  three  B viewports are defined in the _k_i_c._h header file as follows:   98        /*! 98         * KIC text viewportsi 98         */ # 98        struct ka MenuViewport;y) 98        struct ka LayerTableViewport;i( 98        struct ka ParameterViewport; 99<      As described above, KIC uses a special coordinate  sys-  < tem  for viewports that display only textual information.  A  < coordinate in this system refers to the space of one charac-  < ter  block on the display given that no two characters over-  < lap.  The size and position of textual viewports in KIC  are  < always  represented by these character-block units, and only  p the _k_a_L_e_f_t, _k_a_B_o_t_t_o_m, _k_a_R_i_g_h_t,  and  _k_a_T_o_p  members  of  the  < respective   area  structure  are  used  to  define  a  text  < viewport.  By using this character block  representation  of  < graphic text, KIC simulates a typical ASCII character termi-   nal.  F _4._1._1._1. _L_a_y_e_r _M_e_n_u _V_i_e_w_p_o_r_t    <      The layer menu viewport is used by KIC to  display  the  < names  and  colors  of  all  layers  in  the KIC or CD layer  < tables.  The layer menu viewport always occupies the  bottom  < text rows of the display, and is described first because the  < size and position of all  other  viewports  depend  on  it's  < size.  KIC  will  display  in  the layer viewport only those                  <                                                           76    < layers that are defined in the layer  table,  and  therefore  < the  size of the layer menu viewport is not fixed.  KIC com-  < putes the number of layer names that can be displayed  in  a  ` single  row  and  saves this value in the _k_p_L_a_y_e_r_s_P_e_r_M_e_n_u_R_o_w  < member of the KIC parameters structure that is described  in  < Section  4.3;  a  layer  name  is assumed to be less than or  < equal to four characters.  From the number of layers defined  < in  the  layer  table,  KIC then computes the number of text  < rows required for the layer menu viewport.   These  computa-  V tions are performed by the _I_n_i_t_V_i_e_w_p_o_r_t_s() procedure.  After  X the viewports are  initialized,  the  _S_h_o_w_L_a_y_e_r_T_a_b_l_e()  pro-  < cedure  is  invoked  to display the layer table in the layer   menu viewport.    D      The layer menu viewport is indeed a _m_e_n_u in that it  is  T used  to indicate and select the _c_u_r_r_e_n_t _l_a_y_e_r.  The current  J layer is represented by the _k_p_L_a_y_e_r member of the KIC param-  < eters  structure  and  defines the layer to be used by layer  < dependent commands such as the geometry creation procedures.  < The  current  layer is indicated by a box around the name of  R the layer that is  drawn  by  the  _O_u_t_l_i_n_e_T_e_x_t()  procedure.  < When  the  KIC user points at a layer name in the layer menu  N viewport with the graphical pointing device,  the  _P_o_i_n_t_L_a_y_-  J _e_r_T_a_b_l_e() procedure is invoked to determine the next current  
 layer in KIC.   E _4._1._1._2. _P_a_r_a_m_e_t_e_r _V_i_e_w_p_o_r_ts    <      The parameter viewport occupies the graphical text  row                    <                                                           77    < that  is  immediately  above  the  layer  menu viewport.  It  < displays current information such as the name of the current  < symbol  and  the width of the large, coarse window in lambda  < units.   This  information  is  displayed  by  invoking  the  X _S_h_o_w_P_a_r_a_m_e_t_e_r_s() procedure.  Also displayed in the parameter  < viewport is the lambda coordinate of the last point  entered  < through  the  graphical pointing device and the displacement  < of this coordinate from the location of the previous  point-  < ing  event.   This  information is displayed by invoking the   _S_h_o_w_X_Y() routine.   < _4._1._1._3. _P_r_o_m_p_t _V_i_e_w_p_o_r_t    <      The prompt viewport occupies  the  graphical  text  row  < that   is  immediately  above  the  parameter  viewport  and  < displays information that is relevant to  the  command  pro-  < cedure  that the KIC user currently is executing.  A charac-  < ter string is displayed in the prompt viewport  by  invoking  r the  _S_h_o_w_P_r_o_m_p_t()  or  _S_h_o_w_P_r_o_m_p_t_A_n_d_W_a_i_t()  procedures.  The  < latter procedure will a bell character (control-G) to  alarm  < the user of the prompt, and then wait for two seconds before   continuing.t    <      As it's name suggests, the prompt viewport is also used  < to  prompt  the  KIC user for keyboard input.  When the user  < responds to the prompt by typing  at  the  keyboard  of  the  < graphics  device,  the  characters  that  he  types  will be  < displayed (or echoed) in the prompt viewport.  To inform the  < keyboard input routine of the character position at which to                    <                                                           78    < begin displaying input characters,  the  character  size  of  P every prompt string is saved by the _S_h_o_w_P_r_o_m_p_t() routines in  ^ the _f_L_a_s_t_C_u_r_s_o_r_C_o_l_u_m_n member of  the  current  frame  buffer  - structure that is described in Section 4.6.1.  L _4._1._1._4. _C_o_m_m_a_n_d _M_e_n_u _V_i_e_w_p_o_r_t    <      The command menu viewport is a textual viewport used by  < KIC  to  display the current command set or command menu.  A  < command menu in KIC is represented by an array of  character  < strings,  each  string  containing  the name of a particular  < command.  When the KIC  user  points  in  the  command  menu  < viewport with the graphical pointing device, the string that  < is displayed on the row to which the user pointed is  placed  N in  the  _k_p_C_o_m_m_a_n_d buffer in the KIC parameters structure by  F the _P_o_i_n_t() procedure to identify the selection  of  a  com-  F mand.  The _P_o_i_n_t() procedure is described further in Section   4.5.    <      The width of the command menu viewport is exactly  five  < columns  or  five character block units, which requires com-  < mand names to be no longer than five characters.   The  left  < edge of the command menu viewport is the is the left edge of  < the graphics display, and the top of the  viewport  is  also  < the  top of the display.  The bottom row of the command menu  < viewport is the row that is  immediately  above  the  prompt  	 viewport.     <      A  command  menu  is  displayed  in  the  command  menu  L viewport  by  the _S_h_o_w_M_e_n_u() procedure.  When a menu command                  <                                                           79    < is selected by the  KIC  user,  it  is  highlighted  by  the  + _M_e_n_u_S_e_l_e_c_t() procedure.(  ; _4._1._2. _L_a_y_o_u_t _V_i_e_w_p_o_r_t_sr    <      There are two windows in KIC that will map  to  one  of  < three  viewports  for  displaying  layout  information;  the  < coarse viewport, the large coarse  viewport,  and  the  fine  < viewport.   No  more than two layout viewports are ever used  < at any given time.  The layout  windows  and  viewports  are  - defined in the _k_i_c._h file as follows:e   98        /*5 98         * Windows and the viewports they map to.B 98         */a% 98        int FineViewportOnBottom;i1 98        int FineWindowWidth,FineWindowHeight;m2 98        struct ka CoarseViewport,CoarseWindow;> 98        struct ka LargeCoarseViewport,SmallCoarseViewport;. 98        struct ka FineViewport,FineWindow; 99T      The coarse window _C_o_a_r_s_e_W_i_n_d_o_w  is  typically  used  to  < define  the  general  area in which the KIC user is working,  P and the fine window _F_i_n_e_W_i_n_d_o_w  defines  a  smaller  working  < area  with greater resolution.  The fine window is generally  < contained in the area of the coarse window, but is not  con-   strained to be such.    <      The four defined viewports are  allocated  as  follows:  b the large coarse viewport _L_a_r_g_e_C_o_a_r_s_e_V_i_e_w_p_o_r_t represents the  < entire area of the screen that is dedicated  for  displaying  < layout information.  The fine viewport represents either the  < bottom third or the left half of the layout  area  depending  d on  the  logical  value  of _F_i_n_e_V_i_e_w_p_o_r_t_O_n_B_o_t_t_o_m.  After the                    <                                                           80    < display area of the fine viewport has  been  allocated,  the  < remaining  layout  area  is  represented by the small coarse  b viewport _S_m_a_l_l_C_o_a_r_s_e_V_i_e_w_p_o_r_t.  The current coarse  viewport,  < the one that will be displayed depending on the width of the  F coarse  window,  is  represented  by  the  descriptor  _C_o_a_r_-  P _s_e_V_i_e_w_p_o_r_t.  Unlike text viewports, the layout viewports are  < measured by numbers of display  pixels.   The  size  of  the  < large and small coarse viewports, the fine viewport, and all  S text viewports is computed by the _I_n_i_t_V_i_e_w_p_o_r_t() procedure.    <      The coarse window is  displayed  in  either  the  large  < coarse  viewport or the small coarse window depending on the  < width of the window.  When the number of pixels  per  lambda  < in  the  large  coarse viewport exceeds roughly the value of  b _k_p_P_o_i_n_t_i_n_g_T_h_r_e_s_h_o_l_d in the KIC  parameters  structure,  only  < the  large  coarse  viewport  is  displayed,  and  the  fine  < viewport is not displayed.  For larger windows, the contents  < of  the coarse window are displayed in the small coarse win-  < dow, and the fine window is displayed  in  the  fine  coarse  < viewport.   The  decision  of  whether  the coarse window is  < displayed in the large or small coarse viewport is  made  in  V the _S_w_i_t_c_h_T_o_F_i_n_e_P_o_s_i_t_i_o_n_i_n_g() procedure.    <      To generalize, there are two modes in KIC for  display-  < ing  layout  information;  one  mode  is to display only the  < coarse window in the large coarse viewport, and  the  second  < mode  is  to  display  the coarse window in the small coarse  < viewport  and  to  display  the  fine  window  in  the  fine                    <                                                           81    < viewport.   The  current  mode  of display can be determined  ` from the contents of _k_p_R_e_d_i_s_p_l_a_y_C_o_n_t_r_o_l in the  KIC  parame-  < ters  structure  that  can  assume  one  of following values   defined in _k_i_c._h file:  
 98    /*! 98     * Viewport control flagse 98     */ ) 98    #define SPLITSCREEN           'b' ) 98    #define FINEVIEWPORTONLY      'f'i) 98    #define COARSEVIEWPORTONLY    'c'p 99<      If  both  the  fine  and  small  coarse  viewports  are  ` displayed, the _k_p_R_e_d_i_s_p_l_a_y_C_o_n_t_r_o_l parameter will be assigned  P the value of SPLITSCREEN  by  default,  and  the  _k_p_D_i_s_p_l_a_y_-  \ _F_i_n_e_V_i_e_w_p_o_r_t parameter will be set to the value of _T_r_u_e.  If  < only  the  large  coarse   viewport   is   displayed,   then  ` _k_p_R_e_d_i_s_p_l_a_y_C_o_n_t_r_o_l  will  assume the value of COARSEVIEWPOR-  f TONLY by default, and  the  _k_p_D_i_s_p_l_a_y_F_i_n_e_V_i_e_w_p_o_r_t  parameter  F will  be  set to the value of _F_a_l_s_e.  By setting the display  < control parameter to the value of FINEVIEWPORTONLY, only the  < fine  viewport will be updated by a display routine, and the  < COARSEVIEWPORTONLY switch will result in only the  small  or  < large  coarse  viewport to be effected by a display routine.  < Any procedure that uses the  display  control  parameter  to  < control  the  KIC  geometry  display routines must reset the  3 parameter to it's default value before terminating.t  % _4._1._3. _C_l_i_p_p_i_n_gc    <      Because KIC was written to run on most  "dumb"  or  low  < performance  graphics  terminals,  it is necessary to accom-  < plish  window-to-viewport  geometry  clipping  on  the  host                  <                                                           82    < machine  instead  of down-loading the task onto the graphics  < device.  Clipping is the procedure  by  which  sections  are  < removed  from  a  particular  geometry such that the contour  < will  be  contained  entirely  in  the  targeted   viewport.  < Because KIC uses only rectangular viewports, the clipping of  < rectangles is trivial and will  not  be  explained  here  in  D detail.  The _L_T_o_P() macro, which converts lambda coordinates  < to display coordinates, performs a rectangular  clipping  to   the destination viewport.e    <      If the graphics device provides  such  capabilities  as  < geometry clipping and definable viewports and windows, these  < tasks can be down-loaded to the  device,  but  probably  not  < without considerable rewriting of code.  The graphics device  < would be required to support a world coordinate system  that  < is  as  extensive  as the system used by CD.  Many terminals  < that claim to have this ability limit the  world  coordinate  < values  to short integers that are inadequate for an IC lay-  < out with sub-lambda resolution.  The KIC  window  management  < system  may have to be modified to be efficiently adapted to  < graphics device with definable viewports.  At  present,  the  < KIC  geometry  display routines operate under the assumption  < that objects can be displayed in any layout viewport at  any  < time;  in  other  words,  there  is  no  notion of a current  < viewport.  Considerable overhead may  result  from  viewport  < context  switching on a graphics device that handles the KIC  # viewport management in this manner.r                      <                                                           83    X      The procedure _M_F_B_P_o_l_y_g_o_n_C_l_i_p() for clipping polygons to  < a window is provided by the MFB library of graphics routines  < and is described in detail in [6].  It is an  easy  task  to  < clip  a  line  segment  to a half-plane when the edge of the  < half-plane is parallel to a coordinate axis.  If we consider  < the  interior of a window or viewport to be the intersection  < of four such half-planes, the clipping of a polygon  can  be  < performed  by  traversing  the edge list of the polygon once  < for each half-plane, clipping the edges  to  the  respective   half-plane.     <      Polygon clipping is performed in the  world  coordinate  < system  in  KIC; a polygon is clipped to a particular window  < and then mapped to the targeted viewport.  KIC  invokes  the  V frame  buffer  interface  routine _F_B_P_o_l_y_g_o_n_C_l_i_p() which then  X invokes the _M_F_B_P_o_l_y_g_o_n_C_l_i_p() procedure.  This  provides  the  < programmer with the ability to easily insert his own polygon  < clipping routine, if he wishes to, and still use routines in   the MFB graphics library.i  f _4._1._4. _W_i_n_d_o_w/_V_i_e_w_p_o_r_t _T_r_a_n_s_f_o_r_m_a_t_i_o_n_s    D      KIC uses the _L_T_o_P() macro for  converting  from  lambda  < database  coordinates  to pixel display coordinates, and the  D _P_T_o_L() procedure converts from display coordinates to lambda  < coordinates  in a given window;  the macro is used for speed  < and performance considerations.  For a more complete  expla-  3 nation of window/viewport transformations, see [6].a    D      The _L_T_o_P() macro performs  window-to-viewport  clipping                  <                                                           84    J of  rectangles  and  is  defined  as follows in the _c_o_o_r_d_s._h   header file:  J 98    #define LToP(Viewport,Window,X,Y){                               \J 98            X = (int)(((float)(X-Window.kaLeft)*Viewport.kaWidth)    \J 98                         /Window.kaWidth)+Viewport.kaLeft;           \J 98            Y = (int)(((float)(Y-Window.kaBottom)*Viewport.kaHeight) \J 98                         /Window.kaHeight)+Viewport.kaBottom;        \J 98            if(X < Viewport.kaLeft) X = Viewport.kaLeft;             \J 98            else if(X > Viewport.kaRight) X = Viewport.kaRight;      \J 98            if(Y < Viewport.kaBottom) Y = Viewport.kaBottom;         \J 98            else if(Y > Viewport.kaTop) Y = Viewport.kaTop; }        \ 99<      The efficiency of the procedure is essential because it  < must  be  executed at least twice before any geometry can be  < displayed on the graphics device.  Floating point arithmetic  < is however used for both safety and accuracy.  If the compu-  < tation did not use floating point  arithmetic  and  assuming  < one  hundred  database  units  per  lambda,  the approximate  < allowable window width before an overflow occurred would  be  < fourty  thousand  lambda  (for a 1k by 1k display resolution  < and a four byte integer representation).  If forty  thousand  < lambda  is an acceptable size for a world coordinate system,  < it is recommended that the transformation use  only  integer  < arithmetic  for efficiency; experience has frequently shown,  < however, that a larger world coordinate system is desirable.    D      The _P_T_o_L() macro performs viewport to window coordinate  < conversion  and also performs cursor snapping.  Cursor snap-  < ping is the procedure by which coordinates that are returned  < from the graphical pointing device are constrained to lie on  < a grid.  The lambda spacing between adjacent points  on  the  f grid is specified by the _k_p_P_i_x_T_o_L_a_m_b_d_a_S_n_a_p_p_i_n_g member in the                    <                                                           85    D KIC parameters structure defined in Section 4.3.  _P_T_o_L()  is  6 defined in the _c_o_o_r_d_s._h file as follows:  F 98        #define HALFSNAPPING  Parameters.kpHalfPixToLambdaSnappingB 98        #define SNAPPING      Parameters.kpPixToLambdaSnapping 99# 8        PToL(Viewport,Window,X,Y)s+ 98            struct ka Viewport, Window;  98            int *X, *Y;g 98            {n! 98            float tmp1, tmp2;e7 98            tmp1 = ((float)(*X - Viewport.kaLeft)); 9 98            tmp2 = Window.kaWidth / Viewport.kaWidth; : 98            *X = ((int)(tmp1 * tmp2)) + Window.kaLeft;G 98            if(*X >= 0) *X = ((*X+HALFSNAPPING)/SNAPPING)*SNAPPING; @ 98            else *X = ((*X-HALFSNAPPING)/SNAPPING)*SNAPPING;9 98            tmp1 = ((float)(*Y - Viewport.kaBottom)); ; 98            tmp2 = Window.kaHeight / Viewport.kaHeight;t< 98            *Y = ((int)(tmp1 * tmp2)) + Window.kaBottom;G 98            if(*Y >= 0) *Y = ((*Y+HALFSNAPPING)/SNAPPING)*SNAPPING; @ 98            else *Y = ((*Y-HALFSNAPPING)/SNAPPING)*SNAPPING; 98            }k 99D      The _P_T_o_L() procedure is invoked whenever the  KIC  user  < points  in  a viewport with the graphical pointing device or  < when KIC is required to compute the size  in  lambda  of  an  < area on the graphics display; efficiency is certainly not an  D issue.  Because it is essential, however,  that  the  _P_T_o_L()  D procedure  be  the  inverse of _L_T_o_P(), accuracy is an issue,  < and, therefore, floating point arithmetic is used.   If  one  < procedures  was  not the inverse of the other, the integrity  < of the layout display and graphical pointing device would be  < questionable,  and  that  for  a  graphics  editor  would be   intolerable.               9                <                                                           86    > _4._2. _K_I_C _D_a_t_a _S_t_r_u_c_t_u_r_e_s    <      The basic data structures of KIC are described in  this  < section.    The   KIC   parameters  structure  is  described   separately in Section 4.3.  B _4._2._1. _T_h_e _A_r_e_a _D_e_s_c_r_i_p_t_o_r    D      The KIC area descriptor is defined in the _k_i_c._h  header   file as follows:   98        /* 98         * Area structure. 98         */a 98        struct ka {r5 98            int kaLeft, kaBottom, kaRight, kaTop;b 98            int kaX, kaY;m( 98            float kaWidth, kaHeight; 98            }; 99<      The  KIC  area  structure  is  used  for  storing   the  < representations  of  both  rectangles and rectangular areas.  < Every possible representation of the rectangle is  contained  X in  this  structure  for  convenience.  The _k_a_L_e_f_t, _k_a_B_o_t_t_o_m  < members define the untransformed lower, left  coordinate  of  T the  rectangle,  and  the  _k_a_R_i_g_h_t, _k_a_T_o_p members define the  < untransformed upper, right coordinate of the rectangle.  The  H _k_a_X,  _k_a_Y  members represent the untransformed center of the  J rectangle, and the _k_a_W_i_d_t_h member defines the width  of  the  L rectangle  in the horizontal direction, and _k_a_H_e_i_g_h_t defines  6 the height of the rectangle in the vertical direction.    <      The area structure is also used by KIC for representing  < the several windows and viewports that are described in Sec-  Z tion 4.1.  In practice, the _k_a_W_i_d_t_h and _k_a_H_e_i_g_h_t members are                  <                                                           87    < used  exclusively  for  this  purpose  if  and  only  if the  < viewport or window is used for the display of layout  infor-  < mation.   They  are defined as floating point values so that  < the window-to-viewport transformation  routines,  which  use  < floating  point arithmetic for accuracy, are not required to  < compute the floating point width and height  and  for  every  - window-to-viewport coordinate transformation.r    Z      The _k_a_W_i_d_t_h and _k_a_H_e_i_g_h_t structure  members  are  never  @ used  when  the  _k_a area structure represents a rectangle or  < one of the four viewports that display only textual informa-  < tion; they are used exclusively for layout viewports or win-   dows.a  X _4._2._2. _T_h_e _W_i_n_d_o_w _S_t_a_c_k _D_e_s_c_r_i_p_t_o_r    <      The KIC window structure is defined as follows  in  the   _k_i_c._h header file:   98        /*= 98         * Structure used to save windows in window stack  98         */d 98        struct kw { " 98            int kwLastWindowX;" 98            int kwLastWindowY;& 98            int kwLastWindowWidth;& 98            int kwLastFineWindowX;& 98            int kwLastFineWindowY; 98            char kwName[8];e 98            }; 99<      KIC provides the user with the ability to assign  names  < to  specific  windows and to save the respective window on a  < stack such that the user can randomly return to any  desired  @ view  of the layout.  An array of _k_w structures is just such  H a list of layout windows.  The _k_w_N_a_m_e  character  string  is                  <                                                           88    < the  user-specified  name  for  the  window.   The structure  p members _k_w_L_a_s_t_W_i_n_d_o_w_X and _k_w_L_a_s_t_W_i_n_d_o_w_Y  define  the  center  ^ coordinate  of the window, and _k_w_L_a_s_t_W_i_n_d_o_w_W_i_d_t_h defines the  < width of the  coarse  window  in  one  one-hundredth  lambda  p units.   The coordinate _k_w_L_a_s_t_W_i_n_d_o_w_X, _k_w_L_a_s_t_W_i_n_d_o_w_Y defines  2 the center of the fine window or magnifying glass.    <      The width of the fine window  is  assumed  to  be  that  X default  value that is computed by the _I_n_i_t_F_i_n_e_W_i_n_d_o_w() ini-  < tialization routine.  If the width of the coarse  window  is  < such  that  it  is not necessary to display the fine window,  N this condition would be recognized by invoking the _S_w_i_t_c_h_T_o_-  Z _F_i_n_e_P_o_s_i_t_i_o_n_i_n_g() procedure after retrieving a window defin-   ition from the window stack.  _ _4._2._3. _T_h_e _K_I_C _L_a_y_e_r _T_a_b_l_e _D_e_s_c_r_i_p_t_o_ra    <      The KIC layer descriptor and layer table are defined in  ) the _k_i_c._h header file as follows:o   98        /*D 98         * The following information is read from the .KIC file. 98         */_ 98        struct kl {r8 98            int klR, klG, klB;       /* RGB color */H 98            int klMinDimensions;     /* Minimum lambda dimensions */B 98            int klFilled;            /* filled or outlined? */I 98            int klStyle[8];          /* bit array for fill pattern */7 98            int klStyleID;           /* style ID */eI 98            int klCoarseStyleID;     /* style ID for Coarse window */rG 98            int klFineStyleID;       /* style ID for Fine window */n9 98            int klVisible;           /* visibility */ > 98            int klBlink;             /* blinking layer? */8 98            int klSymbolic;          /* symbolic? */J 98            int klWireWidth;         /* wire width >= mindimensions */9 98            char klTechnology;       /* layer name */K 98            char klMask[3];l 98            }s& 98        LayerTable[CDNUMLAYERS+1]; 99     9   9    > 8                                                          89     98        int NumLayerTable; 99<      An array of KIC layer descriptors  represents  the  KIC  < layer  table that differs from the CD layer table in that it  < contains display information as well as  layout  guidelines.  < The  size of the KIC layer table is identical to that of the  < CD layer table, and the entries correspond to  directly  the  < CD   layer   numbers.    The  name  of  a  particular  layer  < represented by a KIC layer descriptor is given by the  char-  ` acter string _k_l_T_e_c_h_n_o_l_o_g_y_k_l_M_a_s_k and also is identical to the  < name of the corresponding layer in the CD layer  table.   As  < in  the  CD  database,  layer  zero  represents the instance  < layer, and because KIC has special procedures for displaying  < instances,  the  KIC  layer  descriptor  for  layer  zero is   unused.     Z      The  _k_l_M_i_n_D_i_m_e_n_s_i_o_n_s  structure  member  specifies  the  < minimum lambda dimension for the specific layer in the given  < process technology.  If the user creates a wire in the  lay-  R out,  the  width  of the new wire will be _k_l_W_i_r_e_W_i_d_t_h lambda  R units, where _k_l_W_i_r_e_W_i_d_t_h is greater than  or  equal  to  the  n value  of _k_l_M_i_n_D_i_m_e_n_s_i_o_n_s.  The _k_l_S_y_m_b_o_l_i_c member identifies  < the particular layer as either a symbolic representation  of   data or a mask level.     N      The _k_l_R, _k_l_G, and _k_l_B structure members define the  RGB  < color combination with which the layer is to be displayed in  < the layout viewports. All color intensities  are  normalized   by KIC to 255.       9          <                                                           90    <      KIC displays layers in the layout viewports  as  either  < filled  or  outlined.  If a particular layer is to be filled  < when displayed, it can have a fill pattern  associated  with  < it;  the  outlining  of  a layer is not considered as a fill  L pattern in the KIC display philosophy.  The _k_l_F_i_l_l_e_d  member  < in  the  KIC  layer  descriptor  is a boolean that specifies  < whether the respective layer should be  filled  or  outlined  N when  displayed.   The  _k_l_S_t_y_l_e_I_D  member  is the index that  < identifies the fill pattern for the  respective  layer;  the  < value  zero is always assumed to represent a solid-fill pat-  J tern.  The _k_l_S_t_y_l_e array contains and eight by eight  inten-  < sity  array  that defines of the fill pattern that is attri-  < buted to the respective layer.  The eight least  significant  J bits  of  each  integer  in  the  _k_l_S_t_y_l_e  array are used to   represent a row of the pattern.     <      Because a graphics  terminal  can  in  general  display  < solid  filled  objects more rapidly than stippled or pattern  < filled  objects,  KIC  uses  a  thresholding  procedure  for  < displaying  filled  geometries  in  the  layout viewports to  < decrease the time required  to  display  a  window.   To  do  < accomplish  this, there are separate indices to identify the  < fill pattern for a particular layer in the fine  and  coarse  < layout  viewports.  The number that identifies the fill pat-  Z tern for a layer in the coarse viewport is  _k_l_C_o_a_r_s_e_S_t_y_l_e_I_D,  V and  _k_l_F_i_n_e_S_t_y_l_e_I_D  is  the  fill pattern index for the fine  < layout viewport; for both indices, the value of zero identi-  < fies a solid-fill pattern, and layers are always outlined if                  <                                                           91    L the _k_l_F_i_l_l_e_d layer descriptor member is zero, regardless  of  < the  value  of  the fill pattern index.  If in either layout  < viewport the number of pixels that are required  to  display  < the  length  of  one  lambda unit is less than two, the fill  < pattern index for the viewport is set to  zero  to  force  a  J solid-fill  pattern.  This decision is made in the _I_n_i_t_V_L_T()  < routine that must therefore be invoked whenever the size  of   a viewport or window changes.p    <      The remaining descriptor members are used  specifically  J as  display  controls.   If  the _k_l_B_l_i_n_k member is set for a  < particular layer, the layer will be displayed in a  blinking  < mode on the graphics terminal, given that the device has the  N capability of blinking colors.  If the _k_l_V_i_s_i_b_l_e  member  is  < zero, the respective layer will not be displayed in the lay-  - out viewports; that is, it will be invisible.l  H _4._2._4. _T_h_e _C_u_r_s_o_r _D_e_s_c_r_i_p_t_o_r    D      The KIC cursor descriptor is defined in the _k_i_c._h  file   as follows:m   98        /* 98         * Cursor desc.e 98         */m 98        struct kc {l+ 98                /* In lambda units.  */_/ 98            int kcPredX, kcPredY, kcX, kcY;o 98            int kcDX, kcDY;o$ 98            int kcRow, kcColumn; 98            }i 98        Cursor;, 99F      The cursor descriptor is used by the _P_o_i_n_t() routine in  < KIC  to  report  a  user  pointing event.  When the KIC user                    <                                                           92    < points in a layout viewport  using  the  graphical  pointing  < device,  the lambda coordinate of the user-selected point is  H placed in the _k_c_X, _k_c_Y structure members of the  KIC  cursor  F descriptor  by  the  _P_o_i_n_t()  procedure.  The previous user-  H selected point is moved from the _k_c_X, _k_c_Y structure  members  X to   _k_c_P_r_e_d_X,  _k_c_P_r_e_d_Y,  and  the  orthogonal  displacements  < between the two lambda coordinates are computed  and  placed  L in  _k_c_D_X,  _k_c_D_Y.   Whenever  the KIC user points in a layout  V viewport, the _k_c_R_o_w and _k_c_C_o_l_u_m_n descriptor members are  set   to zero.    <      When the KIC user points in a text viewport  using  the  < graphical  pointing  device,  the respective row-column text  V coordinate  is  placed  in  the  _k_c_R_o_w,  _k_c_C_o_l_u_m_n  structure  F members  of  the  KIC  cursor descriptor by the _P_o_i_n_t() pro-  < cedure.  As described in Section 4.1.1, the row-column  text  < coordinate  system divides the graphical display into a grid  < of graphical character blocks with the origin being  in  the  # upper, right corner of the display.S    F      After the _P_o_i_n_t() routine is invoked in KIC, KIC deter-  < mines  the viewport to which the user pointed by testing the  < values of certain integer flags in the KIC parameters struc-  < ture  that  is  described in Section 4.3.  The parameters of   interest here are _k_p_P_o_i_n_t_C_o_a_r_s_e_W_i_n_d_o_w and _k_p_P_o_i_n_t_L_a_y_e_r_T_a_b_l_e.  L _4._2._5. _T_h_e _K_I_C _S_e_l_e_c_t_i_o_n _Q_u_e_u_e    J      The KIC selection queue  is  defined  in  the  _s_e_l_e_c_t._h   header file as follows:h                  <                                                           93     8        struct ks {e" 98            struct ks *ksSucc;$ 98            struct o *ksPointer; 98            }; 99! 8        struct ks *SelectQHead;9 99 8        struct ka SelectQBB; 99@      The selection queue is a linked-list of  _k_s  structures  < that  is  used by KIC to identify specific objects in a par-  < ticular symbol.  The list of objects is  typically  used  to  < identify  a set of objects that will be subject to an opera-  R tion such as move or copy.  The _S_e_l_e_c_t_Q_H_e_a_d  pointer  refer-  @ ences  the  first  _k_s  structure in the linked-list and is a  < null pointer if the list is empty.   When  a  an  object  is  < inserted  into  the  selection  queue, the respective object  N descriptor pointer is saved in the _k_s_P_o_i_n_t_e_r member, and the  H _k_s_S_u_c_c  pointer  member  is  assigned  to  the  value of the  h _S_e_l_e_c_t_Q_H_e_a_d pointer.  The _S_e_l_e_c_t_Q_H_e_a_d pointer is then set to  < point  to  the  new member in the selection queue.  In other  < words, new items in the selection list are  always  inserted   at the head of the list.    \      When the _S_e_l_e_c_t_Q_C_o_m_p_u_t_e_B_B() procedure is  invoked,  the  < bounding  box  of all objects in the selection queue is com-  C puted and stored in the _S_e_l_e_c_t_Q_B_B area structure.t  K _4._2._6. _T_h_e _C_o_n_t_e_x_t _D_e_s_c_r_i_p_t_o_rl    N      The KIC context descriptor is defined in the _c_o_n_t_e_x_t_s._c   source file as follows:o   9       9   9    > 8                                                          94     98        #include "cd.h"t 9 98        /*L 98         * Context stack shouldn't get deeper than transformation stack. 98         */e 98        struct cc {g/ 98            int ccX,ccY,ccWidth,ccModified;P! 98            int ccNumWindows;n8 98            struct kw ccSaveWindow[VIEW_STACK_SIZE];! 98            struct o *ccInst; " 98            char ccMaster[81]; 98            } $ 98        Context[XFORMSTACKSIZE]; 99 8        int ContextSP = 0; 99<      The context stack is used by KIC to save the context of  < an  editing session while the KIC user edits another symbol.  < A typical scenario is as follows: the user is editing a sym-  < bol  with an instance of another symbol.  The user discovers  < that the called symbols is, perhaps, lacking a contact.   He  < then  places  the contexts of the current editing session in  < the context stack and begins editing the  defective  symbol.  < When  the problems in the called symbol have been corrected,  < the user retrieves the previous  editing  session  from  the  < context  stack  and  begins  editing  where he was before he  % discovered the error in the instance.a    <      The size of the context stack can not  be  larger  than  < that of the transformation stack because the transformations  < that are associated with the symbols being edited are  saved  < on the transformation stack.  The name of the symbol that is  < being edited in the respective context is contained  in  the  X _c_c_M_a_s_t_e_r  character  string,  and _c_c_I_n_s_t is a pointer to the  < object descriptor of the instance that the  KIC  user  began       9          <                                                           95    < editing  after  the context was placed on the context stack.  V The _c_c_X, _c_c_Y, and _c_c_W_i_d_t_h define the size  and  position  of  < the  coarse window; the size and position of the fine window  F is assumed to be the default value  computed  by  the  _I_n_i_t_-  P _F_i_n_e_W_i_n_d_o_w() procedure.  The window stack that is associated  < with the  respective  editing  context  is  defined  by  the  ` _c_c_N_u_m_W_i_n_d_o_w_s and _c_c_S_a_v_e_W_i_n_d_o_w structure members.    <      The procedures for context switching are  appropriately  J called  _P_u_s_h() and _P_o_p().  Both routines are responsible for  V maintaining the context stack pointer _C_o_n_t_e_x_t_S_P.  The _P_u_s_h()  < routine  assumes  that  the object that is referenced by the  < first item in the selection queue is the  called  symbol  to    become the next editing context.                                                                          <                                                           96    W _4._3. _T_h_e _K_I_C _P_a_r_a_m_e_t_e_r_s _S_t_r_u_c_t_u_r_eu    <      The KIC parameters structure contains  the  controlling  < parameters of the KIC program that may be shared by all pro-  < gram modules.  Because this data structure is so  large  and  < the  members  mostly unrelated, this section may be the most  < confusing of any section of this document.  Nevertheless,  a  < thorough  knowledge  of  the internal structure of KIC would  < require the programmer to recognize all parameter  structure   members.    D      The KIC parameters structure is defined  in  the  _k_i_c._h   file as follows:   98        struct kp {t2 98            /* Symbol desc for current cell */% 98            struct s *kpCellDesc;t 998            /*F 98             * Object desc for a geometry currently being created.E 98             * KIC special cases the input of polygons and wires.T 98             */t$ 98            struct o *kpPointer;< 998            /* True if instances should be expanded */& 98            int kpExpandInstances;J 998            /* True if instance is expanded in fine viewport only */- 98            int kpExpandFineViewportOnly;eD 998            /* If False then the SelectQ is not redisplayed */- 98            int kpEnableSelectQRedisplay; 3 998            /* Color ID's for command menu */e$ 98            int kpMenuTextColor;, 98            int kpMenuHighlightingColor;& 98            int kpMenuSelectColor;R 998            /* If True, user pointed to layer table and Command[0] == EOS */& 98            int kpPointLayerTable;V 998            /* If True, user pointed to coarse viewport and Command[0] == EOS */( 98            int kpPointCoarseWindow;1 998            /* Control of the Layer Menu */e' 98            int kpNumLayerMenuRows; ' 98            int kpLayersPerMenuRow;s 99     9   9    > 8                                                          97    7 98            /* Number of sides for round flashes */o) 98            int kpNumRoundFlashSides;d% 998            /* Current layer */  98            int kpLayer;D 998            /* True if selection commands are LayerSpecific */- 98            int kpLayerSpecificSelection;9E 998            /* If True, then outline all stippled geometries */B 98            int kpOutline;S 998            /* If True, polygon vertices are clipped to nearest grid point */f) 98            int kpClipVerticesToGrid;eA 998            /* If True, put grid below layout geometries */c  98            int kpGridOnTop;E 998            /* If True, grid will be shown in large viewport */ . 98            int kpShowGridInLargeViewport;+ 998            /* Color ID's for grid */p& 98            int kpCoarseGridColor;$ 98            int kpFineGridColor;H 998            /* Number of RESOLUTION*lambda between grid points. */ 98            int kpGrid;_> 998            /* True if current cell has been modified */ 98            int kpModified; ; 998            /* Parameters for modifying geometries */! 98            int kpModifyLeft;   98            int kpModifyTop;3 998            /* Bounds of coordinate system */e3 98            int kpMaxX, kpMaxY, kpMinX, kpMinY;t( 998            /* Debug parameters */$ 98            int kpNumGeometries;> 998            /* If True, then show redisplay bandwidth */$ 98            int kpShowBandwidth;K 998            /* If True, user has just pressed the interrupt key    */# 98            int kpSIGINTERRUPT; 998            /*T 98             * == COARSEVIEWPORTONLY if only coarse viewport should be displayedP 98             * == FINEVIEWPORTONLY if only fine viewport should be displayed= 98             * == SPLITSCREEN if both should be displayed  98             */e' 98            int kpRedisplayControl; N 998            /* If True, Fine Viewport (Magnifying Glass) is displayed */* 98            int kpDisplayFineViewport;6 998            /* If True, all text is displayed */' 98            int kpDisplayAllLabels;_N 998            /* If True, all instances will be labeled in the viewport */( 98            int kpLabelAllInstances; 999     9   9    > 8                                                          98    E 98            /* If True, instances will be marked when selected */ * 98            int kpShowInstanceMarkers; 998            /*V 98             * PointingThreshold is the minimum value of ViewportWidth/WindowWidthT 98             * such that it is still comfortable to point with lambda precision. 98             */*( 98            int kpPointingThreshold;O 998            /* True if wires and polygons should be constrained to 45s */  98            int kp45s; 998            /*O 98             * PixToLambdaSnapping is RESOLUTION times the number of lambda K 98             * between points to which a cursor input point is snapped.i 98             */ * 98            int kpPixToLambdaSnapping;. 98            int kpHalfPixToLambdaSnapping;C 998            /* Current transform defined in Selection menu */ ; 98            int kpRotationAngle;/*0, 90, 180, or 270 */  98            int kpMX;  98            int kpMY;IM 998            /* At what level in the hierarchy are we?  See Redisplay */p% 98            int kpHierarchyLevel;m 998            /*K 98             * Window stack.  kpWindowStack[0] is always the last view.*H 98             * If kpNumWindows is zero, only the last view is saved. 98             */ 9 98            struct kw kpWindowStack[VIEW_STACK_SIZE]; ! 98            int kpNumWindows; A 998            /* Background and Highlighting color control */*( 98            int kpHighlightingPixel;& 98            int kpHighlightingRed;( 98            int kpHighlightingGreen;' 98            int kpHighlightingBlue;e$ 98            int kpBackgroundRed;& 98            int kpBackgroundGreen;% 98            int kpBackgroundBlue; , 998            /* used in Attributes.c */) 98            int kpSetBackgroundColor; + 98            int kpSetHighlightingColor;i4 998            /* Symbol name for current cell */$ 98            char kpCellName[80];A 998            /* Command selected if any from command menu */ # 98            char kpCommand[80];  998            /*' 98             * Current command menu > 98             *       == INSTANCEMENU denotes instance menuA 98             *       == ATTRIBUTESMENU denotes attribute menu > 98             *       == PROPERTYMENU denotes property menu8 98             *       == BASICMENU denotes basic menu@ 98             *       == SELECTIONMENU denotes selection menu       9   9    > 8                                                          99    8 98             *       == DEBUGMENU denotes debug menu@ 98             *       == AMBIGUITYMENU denotes ambiguity menu 98             */n 98            char kpMenu; 998            }e 98        Parameters;C 99<      The KIC parameters structure contains most of the  con-  < trolling  variables of the KIC program as well as the infor-  < mation that is shared between the separate  KIC  procedures.  < There  is at least one mechanism in KIC to allow the user to  % modify each of the structure members.9    <      The name of the symbol that is currently  being  edited  P by  KIC is saved in the _k_p_C_e_l_l_N_a_m_e character buffer, and the  < respective  CD  symbol  descriptor  is  referenced  by   the  P _k_p_C_e_l_l_D_e_s_c  member.  The current symbol descriptor is set in  " the _E_d_i_t() procedure only.    <      Another CD descriptor in the KIC  parameters  structure  N is  the  _k_p_P_o_i_n_t_e_r object descriptor pointer that is used to  < reference an object that is being inserted into the  current  < CD  symbol.   The  display  of  a  polygon  or  wire that is  < currently being created in the layout is given special  con-  < sideration;  the  object  will  be displayed above all other  < objects so as not to obscure the detail.  If the user  rede-  < fines  the  position of the fine window while in the process  < of specifying the  contour  of  the  wire  or  polygon,  the  X _S_h_o_w_F_i_n_e_W_i_n_d_o_w()  routine will recognize that the pointer is  < not a null pointer and display the referenced  object  above  < all  other  objects  in  the window if the respective object                    <                                                          100     intersects the fine window.     N      The _k_p_C_o_m_m_a_n_d character buffer indicates  when  a  user  < has selected a menu command and identifies what the specific  < command is.  When a user points at a  command  in  the  menu  < viewport with the graphical pointing device, the name of the  F command is placed in this character buffer  by  the  _P_o_i_n_t()  H routine,  or  more specificly by the _C_t_r_l_A_t() procedure.  If  < the user types at the keyboard of the of the graphics termi-  < nal while the graphical pointing device is active, the char-  < acter that the user types is placed at the end of  the  con-  F tents  of this buffer by the _P_o_i_n_t() procedure.  If the user  < does not point in the command menu viewport or does not type  F at  the  terminal keyboard, the _P_o_i_n_t() routine returns with  N the first character of the _k_p_C_o_m_m_a_n_d buffer set to the value  L of  _E_O_S.   Any  procedure  that calls the _P_o_i_n_t() routine is  < required to test the contents of this buffer  to  allow  the  < KIC  user the opportunity to make use of the command menu at  
 all times.    <      There are two other parameter  structure  members  that  h are  set by the _P_o_i_n_t() routine only.  The _k_p_P_o_i_n_t_L_a_y_e_r_T_a_b_l_e  D integer is set to the logical value of _T_r_u_e if the KIC  user  < points  in the layer menu viewport with the graphical point-  b ing device, and the _k_p_P_o_i_n_t_C_o_a_r_s_e_W_i_n_d_o_w is set to the  value  D of  _T_r_u_e if the user points in the layout viewports, regard-  < less of whether the fine window intersects the  coarse  win-  < dow.   Both  of  the structure members are by default set to                    <                                                          101    P the value of _F_a_l_s_e by the  _P_o_i_n_t()  routine.   If  the  user  Z points  in  the  layer  menu viewport, the _P_o_i_n_t_L_a_y_e_r_T_a_b_l_e()  J procedure sets the _k_p_L_a_y_e_r structure member to the value  of  : the index of the new current layer in the KIC layer table.    N      Several parameters that control the _R_e_d_i_s_p_l_a_y() routine   are   _k_p_E_x_p_a_n_d_I_n_s_t_a_n_c_e_s,   _k_p_E_x_p_a_n_d_F_i_n_e_V_i_e_w_p_o_r_t_O_n_l_y,  _k_p_E_n_a_-   _b_l_e_S_e_l_e_c_t_Q_R_e_d_i_s_p_l_a_y, and _k_p_S_h_o_w_B_a_n_d_W_i_d_t_h.  If  the  _k_p_E_x_p_a_n_-  X _d_I_n_s_t_a_n_c_e_s integer flag is set to the logical value of _T_r_u_e,  < all instances will be displayed in full detail in both  lay-  < out  viewports; otherwise, the instances will be represented  < in the layout viewports by only a line around the  perimeter  N of   the  bounding  box  of  the  cell.   If  the  _k_p_E_x_p_a_n_d_-  \ _F_i_n_e_V_i_e_w_p_o_r_t integer is set to the logical  value  of  _T_r_u_e,  < all  instances  will  be expanded in full detail in the fine  < viewport only; an instance in the coarse viewport will again  < be  represented  by the contour of its bounding box.  If the  l _k_p_E_n_a_b_l_e_S_e_l_e_c_t_Q_R_e_d_i_s_p_l_a_y integer is set to the logical value  V of  _T_r_u_e,  the _R_e_d_i_s_p_l_a_y() routine will invoke the procedure  R _S_e_l_e_c_t_Q_S_h_o_w() before terminating; this latter procedure will  < highlight  in both layout viewports all objects contained in  Z the selection queue.  The _k_p_N_u_m_G_e_o_m_e_t_r_i_e_s integer is set  to  N zero  when  the  _R_e_d_i_s_p_l_a_y()  procedure  is invoked and then  < incremented whenever a geometric object is displayed thereby  < providing  a  count  of  the  number  of geometries.  If the  l _k_p_S_h_o_w_B_a_n_d_W_i_d_t_h integer flag is set, the _R_e_d_i_s_p_l_a_y() routine  < will  compute  the  real,  user, and system time required to  < display the particular area  in  the  layout  viewports  and                  <                                                          102    3 report these values to the user before terminating.s    ^      The _R_e_d_i_s_p_l_a_y() routine will invoke the _S_h_o_w_G_r_i_d() pro-  < cedure that displays a grid in the layouts viewports accord-  H ing to the user-specified options.  If  the  _k_p_G_r_i_d  integer  < member  of the parameters structure is less than unity, then  < a grid will never be displayed in the layout viewports; oth-  H erwise,  the value of _k_p_G_r_i_d specifies the lambda spacing of  < the grid lines starting at the origin of the  world  coordi-  < nate  system.  If the number of display pixels per lambda in  \ the fine viewport exceeds the value of the  _k_p_P_o_i_n_t_i_n_g_T_h_r_e_s_-  D _h_o_l_d parameter, then a grid will be displayed in that layout  n viewport, and if the _k_p_S_h_o_w_G_r_i_d_I_n_L_a_r_g_e_V_i_e_w_p_o_r_t parameter  is  D set  to  the logical value of _T_r_u_e, then a grid will also be  < displayed in the large coarse layout viewport if the display  < pixel  per  lambda  ratio  is large enough to permit a grid.  ^ The _R_e_d_i_s_p_l_a_y() procedure will invoke  the  _S_h_o_w_G_r_i_d()  pro-  < cedure  after  all  layout geometries have been displayed if  Z the _k_p_S_h_o_w_G_r_i_d_O_n_T_o_p parameter is set to the logical value of  D _T_r_u_e  that  will  result  in  the  lines  of  the grid being  Z displayed over layout geometries.   If  the  _k_p_S_h_o_w_G_r_i_d_O_n_T_o_p  < parameter is not set, the grid will be displayed before lay-  < out geometries that will cause the view of grid lines to  be    obstructed by layout geometries.    <      The  lines  of  the  grid  that  is  displayed  by  the  L _S_h_o_w_G_r_i_d()  procedure  will be displayed in two colors.  The  Z _k_p_F_i_n_e_G_r_i_d_C_o_l_o_r parameter is the index of the layer  in  the                    <                                                          103    < KIC  layer table that will be used to display the intermedi-  < ate grid lines.  Every fifth line of the grid appear in  the  < color of the layer that is indexed in the KIC layer table by  4 _k_p_C_o_a_r_s_e_G_r_i_d_C_o_l_o_r.    <      The parameters structure contains other viewport  color  Z information.   The _k_p_M_e_n_u_T_e_x_t_C_o_l_o_r is the index of the layer  < in the KIC layer table whose color will be used as the color  < of   all   graphic   text  in  the  textual  viewport.   The   _k_p_M_e_n_u_S_e_l_e_c_t_C_o_l_o_r and _k_p_M_e_n_u_H_i_g_h_l_i_g_h_t_i_n_g_C_o_l_o_r members of the  < parameters structure define the color indices with which all  < graphic text will be displayed and highlighted in  the  com-  < mand  menu viewport if the respective command is selected; a  < highlighted command means that the name of  the  command  is  < written  over  a  box  that is displayed in the color of the  < layer  that  is  indexed  in  the   KIC   layer   table   by  F _k_p_M_e_n_u_H_i_g_h_l_i_g_h_t_i_n_g_C_o_l_o_r.          The  _k_p_B_a_c_k_g_r_o_u_n_d_R_e_d,  _k_p_B_a_c_k_g_r_o_u_n_d_G_r_e_e_n,  and  _k_p_B_a_c_k_-  P _g_r_o_u_n_d_B_l_u_e  parameter  structure  members  define  the  red-  < green-blue combination  of  the  background  color  for  all  < viewports.  The background color for KIC is always the first  < color in the video color table  of  the  graphics  terminal.   The      _k_p_H_i_g_h_l_i_g_h_t_i_n_g_R_e_d,     _k_p_H_i_g_h_l_i_g_h_t_i_n_g_G_r_e_e_n,     and  ` _k_p_H_i_g_h_l_i_g_h_t_i_n_g_B_l_u_e parameters define the red-green-blue com-  < bination   of   the   highlighting   color.   An  object  is  < highlighted in the layout viewports by displaying a line  in  < the  highlighting  color around the perimeter of the object.                    <                                                          104    < The highlighting color for KIC is always the last  color  in  < the video color table of the graphics terminal and is always  b indexed  by  the  _k_p_H_i_g_h_l_i_g_h_t_i_n_g_P_i_x_e_l  parameter   structure   member.f    <      Other members of the parameters structure that  control  < the  display  of  information in the layout viewports are as  N follows:  the _k_p_O_u_t_l_i_n_e parameter is set  to  the  value  of  < true if stippled geometries are to by outlined; depending on  < the fill patterns being used, it is occasionally more pleas-  < ing  to  the  eye  to  have  the perimeter of stipple filled  N geometries clearly visible.  If the _k_p_O_u_t_l_i_n_e flag  is  set,  < however, the time that is required for the graphics terminal  < to redraw the layout  viewports  will  of  course  increase.  < Because  KIC assumes that the graphics terminal is not capa-  N ble of scaling graphic text, the _S_h_o_w_L_a_b_e_l() routine,  which  N is  invoked by the _R_e_d_i_s_p_l_a_y() routine to display a label in  < the layout viewports, will not display a label in  a  layout  < viewport  if the number of display pixels per lambda is less  < than two; the number two  was  simply  chosen  after  trying  < several  other  values and finding that two was most reason-  ` able for typical  IC  layouts.   If  the  _k_p_D_i_s_p_l_a_y_A_l_l_L_a_b_e_l_s  R parameter  is  set to the logical value of _T_r_u_e, the _S_h_o_w_L_a_-  B _b_e_l() routine will  always  display  labels  in  the  layout  < viewports regardless of the window-to-viewport scale factor.  f If the _k_p_S_h_o_w_I_n_s_t_a_n_c_e_M_a_r_k_e_r_s member of  the  KIC  parameters  R structure  is  set,  the  _S_e_l_e_c_t_Q_S_h_o_w()  procedure, which is  N invoked  by  the  _R_e_d_i_s_p_l_a_y()  procedure  to  highlight  the                  <                                                          105    < content  of  the selection queue, will display a small, dia-  < mond shaped marker at the reference point of  each  instance  < in  the  selection queue; the reference point of an instance  < is also the origin of the world coordinate  system  for  the  < respective  symbol  and the point about which the cell would   be rotated or mirrored.     <      The procedure that places objects  into  the  selection  l queue  is  controlled by the _k_p_L_a_y_e_r_S_p_e_c_i_f_i_c_S_e_l_e_c_t_i_o_n member  < of the KIC parameters structure.  If this parameter  is  set  < when KIC asks the user to point in the layout viewports with  < the graphical pointing device to identify the object  to  be  < placed  in  the selection queue, only those objects that lie  J on the current layer, as defined by the  _k_p_L_a_y_e_r  parameter,  < will be placed in the selection queue.  If under this condi-  < tion of layer specific selection,  the  KIC  user  does  not  < point  to  any object in the layout viewports that is on the  < current layer but does point to an instance, the  respective  < instance  will  be  placed  in  the selection queue.  If the  l _k_p_L_a_y_e_r_S_p_e_c_i_f_i_c_S_e_l_e_c_t_i_o_n parameter is  set  to  the  logical  F value  of _F_a_l_s_e, all objects that the KIC user identifies by  < pointing in the layout  viewports  will  be  placed  in  the   selection queue.    <      There are several  parameters  in  the  KIC  parameters  < structure  that  control the creation and editing of objects  < by KIC.  When the KIC user creates a  wire  or  polygon  and  < begins to define the contour of the object, the angle formed                    <                                                          106    < by any two adjacent segments  along  contour  will  be  con-  F strained  to  integer  multiples  of 45 degrees if the _k_p_4_5_s  < member of the parameters structure is  set  to  the  logical  r value  of _T_r_u_e.  The _k_p_R_o_t_a_t_i_o_n_A_n_g_l_e, _k_p_M_X, and _k_p_M_Y parame-  < ters define the current transformation; if a new instance is  < placed  in  the  symbol or an object is moved or copied, the  < operation is  performed  with  the  transformation  that  is  D defined  by these parameters.  If the _k_p_M_X parameter is set,  < the transformation will mirror in the  direction  of  the  x  D axis,  and  if  the  _k_p_M_Y is set, the current transformation  < will mirror in the direction of  the  y  axis.  The  current  Z rotation angle _k_p_R_o_t_a_t_i_o_n_A_n_g_l_e may only be set to either the  T value of 0, 90, 180, or 270 degrees.  The  _k_p_M_o_d_i_f_y_L_e_f_t  and  R _k_p_M_o_d_i_f_y_T_o_p  parameters  are used exclusively to specify the  < direction in which the KIC user  will  stretch  a  rectangle  T using  the  KIC  stretch-box  command.   If the _k_p_M_o_d_i_f_y_L_e_f_t  D parameter is set to the logical value of _T_r_u_e, then the left  < edge  of  the  rectangle  will  be stretched; otherwise, the  < right edge will  be  stretched.   As  explained  in  Section  < 2.4.4,  KIC  does  not  use  the  CD round flash descriptor,  < preferring instead to represent round objects  as  polygons,  < including  arcs  and  doughnuts.   If the KIC user creates a  d round flash or doughnut,  the  _k_p_N_u_m_R_o_u_n_d_F_l_a_s_h_S_i_d_e_s  integer  < will  specify  the number of sides on the outer perimeter of  < the polygon that will represent the round object.  KIC  will  d not  allow the value of _k_p_N_u_m_R_o_u_n_d_F_l_a_s_h_S_i_d_e_s to be less than  d eight and not greater than 360.  If the _k_p_C_l_i_p_V_e_r_t_i_c_e_s_T_o_G_r_i_d                    <                                                          107    < parameter is set, the vertices of all polygonal objects will  < be clipped to the lambda grid; this could  result  in  pecu-  < liarly  shaped  round flashes or doughnuts if the respective  < diameter is small.  Finally,  if  the  user  creates  a  new  < object  in  the current symbol, or modifies an existing one,  X the _k_p_M_o_d_i_f_i_e_d flag is set to the value of _T_r_u_e, which  will  < cause  KIC  to remind the user if the user attempts to abort  6 or edit a new symbol without updating the current one.    <      The KIC parameters structure contains information  that  H is used to control many viewport actions.  The _k_p_M_e_n_u member  < of the parameters structure defines the command menu that is  < currently  displayed in the command menu viewport.  The pos-  H sible values for the _k_p_M_e_n_u parameter  are  defined  in  the   _k_i_c._h file as follows:  
 98    /* 98     * Menu namess 98     */b% 98    #define BASICMENU         'b'X% 98    #define DEBUGMENU         'd'n% 98    #define SELECTIONMENU     's' % 98    #define INSTANCEMENU      'i' % 98    #define ATTRIBUTESMENU    'a'i% 98    #define PROPERTYMENU      'p'a% 98    #define AMBIGUITYMENU     'A'k 99<      The number of layers that can be displayed in a  single  < row  of  the  layer menu viewport is defined by the value of  ` the _k_p_L_a_y_e_r_s_P_e_r_M_e_n_u_R_o_w parameter.   The  number  of  graphic  < text  rows  that are dedicated to the layer menu viewport is  ` defined by the value of  the  _k_p_N_u_m_L_a_y_e_r_M_e_n_u_R_o_w_s  parameter.  < If  the size of the coarse window is sufficiently large such  < that the  fine  window  is  to  be  displayed  in  the  fine                  <                                                          108    f viewport,  the _k_p_D_i_s_p_l_a_y_F_i_n_e_V_i_e_w_p_o_r_t parameter is set to the  D logical value of _T_r_u_e; otherwise, if only the coarse  window  < is  displayed  in  the  large coarse viewport, the parameter  p _k_p_D_i_s_p_l_a_y_F_i_n_e_V_i_e_w_p_o_r_t is set to the  value  of  _F_a_l_s_e.   The  ` _k_p_R_e_d_i_s_p_l_a_y_C_o_n_t_r_o_l  member  of the parameters structure con-  < trols  the  effect  of  a  display  routine  in  the  layout  ` viewport.   The  value  of  _k_p_R_e_d_i_s_p_l_a_y_C_o_n_t_r_o_l specifies the  < current mode of display and can be one of three options that  1 are defined as follows in the _k_i_c._h file:   
 98    /*! 98     * Viewport control flagse 98     */h) 98    #define SPLITSCREEN           'b' ) 98    #define FINEVIEWPORTONLY      'f' ) 98    #define COARSEVIEWPORTONLY    'c'd 99<      If  both  the  fine  and  small  coarse  viewports  are  ` displayed, the _k_p_R_e_d_i_s_p_l_a_y_C_o_n_t_r_o_l parameter will be assigned  P the value of SPLITSCREEN  by  default,  and  the  _k_p_D_i_s_p_l_a_y_-  \ _F_i_n_e_V_i_e_w_p_o_r_t parameter will be set to the value of _T_r_u_e.  If  < only  the  large  coarse   viewport   is   displayed,   then  ` _k_p_R_e_d_i_s_p_l_a_y_C_o_n_t_r_o_l  will  assume the value of COARSEVIEWPOR-  f TONLY by default, and  the  _k_p_D_i_s_p_l_a_y_F_i_n_e_V_i_e_w_p_o_r_t  parameter  F will  be  set to the value of _F_a_l_s_e.  By setting the display  < control parameter to the value of FINEVIEWPORTONLY, only the  < fine  viewport will be updated by a display routine, and the  < COARSEVIEWPORTONLY switch will result in only the  small  or  < large  coarse  viewport to be effected by a display routine.  < Any procedure that uses the  display  control  parameter  to  < control  the  KIC  geometry  display routines must reset the                    <                                                          109    3 parameter to it's default value before terminating._    <      The window stack of the current symbol  is  represented  n by the _k_p_W_i_n_d_o_w_S_t_a_c_k and _k_p_N_u_m_W_i_n_d_o_w_s members of the parame-  < ters structure.  See Section 4.2.2 that describes the window   stack descriptor.s    F      A user interrupt condition is identified by  the  _k_p_S_I_-  P _G_I_N_T_E_R_R_U_P_T member of the parameters structure.  Whenever the  < KIC user presses the interrupt key (break  or  delete  under  X UNIX and control C for VMS), the _k_p_S_I_G_I_N_T_E_R_R_U_P_T parameter is  Z set to the value of _T_r_u_e by the _C_a_t_c_h_S_I_G_I_N_T() interrupt han-  < dling procedure.  The top of the display loop (i.e., the top  F of the CD generator loop before  the  _C_D_G_e_n()  procedure  is  < invoked to return a pointer to an object in the window to be  X displayed) the value of the _k_p_S_I_G_I_N_T_E_R_R_U_P_T is tested for  an  < interrupt  condition.   If  an  interrupt  had occurred, the  X display routine is terminated and the _k_p_S_I_G_I_N_T_E_R_R_U_P_T parame-  8 ter is returned to its default value of _F_a_l_s_e.                                                        <                                                          110    8 _4._4. _K_I_C _C_o_m_m_a_n_d _M_e_n_u_s    <      Because of the functionality of KIC, it  is  impossible  < to  display all KIC commands simultaneously in a menu struc-  < ture.  KIC therefore is designed with  a  hierarchical  menu  < system  that provides specially tailored command sets allow-  < ing the user to easily complete specific tasks.  These  com-  < mand  sets  are not so specific or restrictive to frequently  < burdened the user with the necessity to traverse the command  # hierarchy for the desired commands.-    <      The present implementation of the KIC command menu sys-  < tem  is  slightly awkward.  This method has continued in use  < simply because it works and has not yet become inconvenient.  < This  section  explains the command menu operation, and pro-  < vides a description of the task of adding a  new  menu  com-  < mand.   Also, suggestions for improving the KIC command menu   system are provided.    <      There are seven possible hierarchical command menus for  < KIC: the basic menu at the top of the command hierarchy, the  < selection menu for object modification,  the  instance  menu  < for  instance placement, the attribute menu for defining the  < viewport display attributes, the property menu  for  editing  < the  property  lists of selected objects, the ambiguity menu  < for resolving ambiguities in  instance  selection,  and  the  < debug  menu  that the normal KIC user should never use.  The  < command menu that is currently displayed in the command menu  H viewport  is  identified  by  the  _k_p_M_e_n_u  member of the KIC                  <                                                          111    < parameters structure that  can  assume  one  of  the  values  - defined in the _k_i_c._h file as follows:m  
 98    /* 98     * Menu namesw 98     */n% 98    #define BASICMENU         'b'r% 98    #define DEBUGMENU         'd' % 98    #define SELECTIONMENU     's't% 98    #define INSTANCEMENU      'i'r% 98    #define ATTRIBUTESMENU    'a' % 98    #define PROPERTYMENU      'p'd% 98    #define AMBIGUITYMENU     'A'  99<      A command menu in KIC is an array of  character  string  < pointers,  each  pointer  referencing  a  particular command  D name.  For example, the basic menu is defined in  the  _k_i_c._h   file as follows:   98        /* 98         * KIC menus.E 98         */s 98        #ifdef AllocateE) 98                char *BasicMenu[] = {U  98                    "     ", 98                    "EDit",M 98                    "DIR", 98                    "SAve",   98                    "WRite",  98                    "     ",  98                    "ATtri",  98                    "Insta",  98                    "SElec",  98                    "PRpty",  98                    "     ",  98                    "RDraw",  98                    "EXpnd", 98                    "PEek",  98                    "PAn", 98                    "Zoom",a  98                    "WINdo", 98                    "VIEw",  98                    "LASt",   98                    "     ", 98                    "45s", 98                    "Grid",r 98                    "SNap",r  98                    "BOXes",  98                    "WIRes",       9   9    > 8                                                         112      98                    "WIDth",  98                    "POLyg",  98                    "DOnut",  98                    "FLASh", 98                    "ARC",  98                    "LABel", 98                    "Undo",r  98                    "     ", 98                    "LYra",n 98                    "TECh",g  98                    "ABort", 98                    "DEBug"g 98                    };H 98                int NumBasicMenu = sizeof(BasicMenu)/sizeof(char *); 98        #elsen& 98                char *BasicMenu[];% 98                int NumBasicMenu;n 98        #endif 99<      There must be such an array of character  pointers  for   each command menu in KIC.e    <      Notice that  the  contents  of  the  command  menu  are  L defined  by  using  of  a compile flag named _A_l_l_o_c_a_t_e.  This  < compile flag is set to a non-zero logical value by  one  and  D only  one  source  file that includes the _k_i_c._h header file;  < typically it is defined in the source file that contains the   _m_a_i_n() procedure.     <      Also notice that the command names are  of  mixed  case  < with the capitalized letters always forming a unique prefix.  < The convention has become that the first, capital letters in  < the  command  name  specify the minimum number of characters  < required to identify the particular command  name  from  any  p other  KIC  command;  _t_h_i_s _c_o_n_v_e_n_t_i_o_n _m_u_s_t _b_e _o_b_e_y_e_d because  F the _P_o_i_n_t() routine, which compares the user keyboard  input  < to the current command set and thereby allows commands to be  < selected  through  the  keyboard,  will  compare  the   user     9          <                                                          113    < keyboard input to only those characters in the command names   that are capitalized.     <      The major problem with the KIC command  menu  structure  D is  that  the menus are defined entirely in the _k_i_c._h header  < file.  As a result, it is necessary to completely  recompile  < KIC  whenever  a new command is added to a menu or the when-  < ever the structure is modified.  The preferred  solution  to  < the  menu  problem  might be to have a specific source file,  < say, menu.c, containing the routines for managing  the  com-   mand menu viewport.     L      The _S_h_o_w_M_e_n_u() procedure will display a particular com-  P mand  menu  in  the command menu viewport.  The _M_e_n_u_S_e_l_e_c_t()  < procedure command is invoked to highlight a specific command  < menu  item  whenever  the  command is user-selected, and the  T _M_e_n_u_D_e_s_e_l_e_c_t() procedure is invoked  to  return  a  specific  < command  menu item to its default, unhighlighted appearance.  < There is typically a  menu-specific  display  procedure  for  V each  command  menu,  such as the _S_h_o_w_B_a_s_i_c_M_e_n_u() procedure,  L that in turn invokes the _S_h_o_w_M_e_n_u() routine.  The reason for  < this one level of indirection is that typically several com-  < mand items in a command menu will reflect a mode  of  opera-  < tion that is identified by a particular member of the param-  < eters structure; for example, the expand command  that  will  < cause  all  called symbols to be displayed in full detail in  < all  layout  viewports.   The  menu-specific  command   menu  < display  procedure will be responsible for testing the vari-                    <                                                          114    < ous modes of KIC and highlighting  the  identifying  command  . menu item if the respective mode is in effect.    D      The _k_i_c._h  header  file  also  has  specific  character  < pointers  defined  for  each  possible command menu name for  < reasons of comparison.  Several such pointers for  the  com-  D mands  in the basic menu are defined as follows in the _k_i_c._h   file:e   98        #ifdef Allocate - 98                char *MenuEDIT  = "EDit";u, 98                char *MenuDIR   = "DIR";- 98                char *MenuSAVE  = "SAve";.. 98                char *MenuWRITE = "WRite"; 98                    .t 98                   etc.h 98                    .  98        #else # 98                char *MenuEDIT;8" 98                char *MenuDIR;# 98                char *MenuSAVE; $ 98                char *MenuWRITE; 98                    .  98                   etc.  98                    .= 98        #endif 99<      These character pointers are typically used  to  deter-  < mine whether a command menu item has been user-selected.  As  < is described in Section 4.3 on the KIC parameters structure,  < when  a  command  in  the  current  command set is selected,  < whether by use of the graphical pointing device or  keyboard  < input,  the name of the command as it appears in the command  N menu viewport is placed into the _k_p_C_o_m_m_a_n_d character  buffer  F in the KIC parameters structure by the _P_o_i_n_t() routine.  The  < procedure that monitors the  command  menu  would  therefore  N test the returned value of _k_p_C_o_m_m_a_n_d for the appearance of a                    <                                                          115    < new command name.  For example, the following sections of  C  ; code could be extracted from the _B_a_s_i_c() routine:    98        #include "kic.h" 99 8        Basic(){( 98            int LookedAhead = False; 98               . 98               . 98               . 98            loop {# 98                if(LookedAhead) , 98                    LookedAhead = False; 98                else  98                    Point();E 998                if(strcmp(Parameters.kpCommand,MenuEDIT) == 0){a 98                    .  98                    etc. 98                    .  98                    }nI 98                else if(strcmp(Parameters.kpCommand,MenuABORT) == 0){  98                    .  98                    etc. 98                    .u 98                    }tI 98                else if(strcmp(Parameters.kpCommand,MenuEXPND) == 0){f 98                    .c 98                    etc. 98                    .n 98                    }o 98                   . 98                   etc.  98                   . 98                }  98            }d 99F      In the _B_a_s_i_c() routine, the program will loop  continu-  < ously  until  the  user  invokes a command to break the loop  < such as the abort command.  This is typical of  all  command   menu routines in KIC.     <      Because the KIC command  menus  are  hierarchical,  the  X _B_a_s_i_c()  routine will invoke procedures such as _I_n_s_t_a_n_c_e_s(),  j _S_e_l(), _A_t_t_r_i(), _D_e_b_u_g(), and _P_r_o_p_e_r_t_i_e_s()  that  will  erase                    <                                                          116    < the  current  command  viewport,  display a specific command  < menu, and begin looping with the pointing device as is  done  F in the _B_a_s_i_c() routine.  The only argument that is passed to  R these menu routines is a pointer to the integer  _L_o_o_k_e_d_A_h_e_a_d  < that  is used by the subroutine to notify the parent routine  < that the user has already selected a menu command.  When the  R logical  value  of  the  _L_o_o_k_e_d_A_h_e_a_d integer is nonzero, the  F _P_o_i_n_t() routine is not invoked during that  particular  pass   through the loop.s                                                                                            <                                                          117    > _4._5. _T_h_e _P_o_i_n_t_i_n_g _D_e_v_i_c_e    <      The graphical pointing device is extremely important to  < KIC  because  it  is  used  as  the major communication link  < between the editor and the KIC user.  Consequently,  consid-  < erable  thought has been given to its application for layout  < entry and viewport control.  This section  will  survey  the  + important _P_o_i_n_t() routine in KIC.m    <      KIC demands that the graphical pointing device  be  the  < locator type; a user pointing event would return to the host  < the display coordinate that was user-specified  and  a  mask  < that would identify the button that was pushed on the point-  F ing device or keyboard.  The _P_o_i_n_t() routine  will  map  the  < display  coordinate  to the appropriate viewport and, on the  < basis of the position and the button mask, will  attempt  to  % determine the intent of the KIC user.n    <      If the graphical pointing device does not have  special  < buttons,  such  as  the commonly used four button mouse has,  < KIC will assume that the user is pointing to a lambda  coor-  < dinate  in the layout viewport if the returned display coor-  < dinate is within the layout viewport and  the  if  the  user  < pressed the space bar on the keyboard.  This being the case,  < the KIC user would use the space bar of the  terminal  when-  < ever  he  pointed  to  a  lambda  coordinate  in  the layout  
 viewports.    F      The _P_o_i_n_t() is responsible for acting on the occurrence                    <                                                          118    < of  several keyboard-specific commands.  The following table  < lists the special keyboard commands of KIC and describes the  1 actions that are performed when the event occurs:         > 8control-A       Control A will cause KIC to  abort  uncondi-@ 98                tionally.   This  keyboard  command could be@ 98                dangerous, and therefore it is  possible  toJ 98                remove it from the _P_o_i_n_t() routine by recom-@ 98                piling without the ABORT  compiler  flag  in% 98                the point.c file.t 9  > 8control-C       This keyboard command is  available  if  and@ 98                only  if  KIC is compiled to run under UNIX.@ 98                After the user  types  control-C,  KIC  will@ 98                prompt the user for a lambda coordinate that@ 98                will be accepted as if the user had  pointed@ 98                to  that  lambda  coordinate  in  the layoutJ 98                viewport.  The _P_o_i_n_t() routine  will  returnj 98                with the _k_p_P_o_i_n_t_C_o_a_r_s_e_V_i_e_w_p_o_r_t member of the@ 98                KIC parameters structure set to the  logical* 98                value of _T_r_u_e. 9  > 8control-E       This keyboard command is  identical  to  the@ 98                above control-C command.  It is intended for@ 98                VMS systems for which the control-C  command@ 98                produces  the terminal interrupt signal SIG- 98                INT. 9  > 8control-F       After typing control-F, KIC will prompt  the@ 98                user  to  identify  a new center of the fine@ 98                window in the  current  symbol.   After  the@ 98                user  has specified the new center, the fine@ 98                window will be redrawn in its new  position.@ 98                The  relative  size  of the fine window will@ 98                not be affected by  this  operation.   Also,J 98                the _P_o_i_n_t() routine will not terminate after@ 98                this  user  command;  as   a   result,   the@ 98                control-F keyboard command is transparent toA 98                whatever procedure invokes _P_o_i_n_t().r 9  > 8control-G       When the  user  types  control-G,  KIC  will@ 98                prompt  the  user to identify a new size and@ 98                position for the fine window in the  current@ 98                symbol.   After  the user has specified this@ 98                information by pointing to the endpoints  of 9     9   9    > 8                                                         119    @ 98                the  diagonal  of  the  new fine window, the@ 98                fine window will be redrawn in its new posi-@ 98                tion.  Because the fine viewport has a fixed@ 98                aspect ratio, the horizontal  width  of  the@ 98                new fine window that the user specifies will@ 98                take precedence.  This keyboard  command  is@ 98                similar to the control-F command in that theJ 98                _P_o_i_n_t() routine will not return  after  this@ 98                user  command;  as  a  result, the control-G@ 98                keyboard command is transparent to  whatever8 98                procedure invokes _P_o_i_n_t(). 9  > 8control-L       When the  user  types  control-L,  KIC  will@ 98                prompt  the user for a positive integer that@ 98                will identify the new  current  layer.   The@ 98                number  one  identifies the first mask layerJ 98                in the KIC layer table,  etc.   The  _P_o_i_n_t()\ 98                routine  will return with the _k_p_P_o_i_n_t_L_a_y_e_r_T_-H 98                _a_b_l_e member of the KIC parameters set to theH 98                value  of  _T_r_u_e  whenever the control-L key-* 98                board command is used. 9  > 8control-N       This keyboard command adds another  item  to@ 98                the  window  stack  of  the  current symbol.@ 98                After typing control-N, KIC will prompt  the@ 98                user  to  name  the  current coarse and fine@ 98                windows.  When the KIC user has  assigned  a@ 98                name to the current layout windows, the win-Z 98                dows are pushed onto the _k_p_W_i_n_d_o_w_S_t_a_c_k  win-@ 98                dow  stack  member  of  the  KIC  parametersX 98                structure, and the value of _k_p_N_u_m_W_i_n_d_o_w_s  is@ 98                incremented  by  one.  This keyboard command@ 98                is similar to the control-F command in  thatJ 98                the _P_o_i_n_t() routine will not terminate after& 98                this user command. 9  > 8control-T       This keyboard command changes the  size  and@ 98                aspect   ratio   of   the  fine  window  and@ 98                viewport.  If the fine viewport occupies the@ 98                bottom  third  of  the  layout  area  of the@ 98                graphics display  and  the  KIC  user  types@ 98                control-T,  the  layout  viewports be recom-@ 98                puted and redrawn such that the fine  window@ 98                will occupy the left half of the layout area@ 98                of the display.  The new  fine  window  will@ 98                have  the same width in lambda as the previ-@ 98                ous fine  window  and  will  have  the  same@ 98                center  position.   This keyboard command is@ 98                similar to the control-F command in that theJ 98                _P_o_i_n_t() routine will not terminate after the 98                command. 9     9   9    > 8                                                         120     9> 8control-V       This keyboard command is  identical  to  the@ 98                above control-T command.  It is intended for@ 98                VMS systems for which the control-T  command< 98                has has a special meaning to the system. 9  > 8control-W       This keyboard command provides the option ofP 98                a  '_w_h_e_r_e  _a_m  _I?'  command.   When the user@ 98                types control-W, KIC will  then  expect  the@ 98                user  to  point in the layout viewports, and@ 98                will notify the KIC user of the lambda coor-L 98                dinate  value  by invoking the _S_h_o_w_X_Y() pro-@ 98                cedure.  This keyboard command is similar toJ 98                the  control-F  command  in that the _P_o_i_n_t()@ 98                routine will not terminate  after  the  com- 98                mand.a 9  > 8character       Whenever the  KIC  user  types  a  printable@ 98                character  on the keyboard while the graphi-@ 98                cal pointing device is active, the characterJ 98                is  received  by  the  _P_o_i_n_t() routine, con-@ 98                verted to lower case, and placed at the  endR 98                of  the  contents of the _k_p_C_o_m_m_a_n_d buffer inJ 98                the KIC parameters structure.   The  _P_o_i_n_t()@ 98                procedure  maintains  a running count of the@ 98                number of buffered keyboard  characters  and@ 98                will  not  immediately  terminate  after the@ 98                user types a  character.   After  the  typed@ 98                character has been buffered, the contents ofR 98                the _k_p_C_o_m_m_a_n_d buffer are compared  with  the@ 98                current command set that is displayed in theJ 98                command menu viewport.  If the _P_o_i_n_t()  pro-@ 98                cedure  determines that the user has typed a@ 98                command name, the procedure returns with theR 98                complete   command  name  in  the  _k_p_C_o_m_m_a_n_d 98                buffer.  9  > 8escape          When the KIC user presses the escape  button@ 98                on the keyboard, all buffered keyboard char-J 98                acters are cleared.  The  _P_o_i_n_t()  procedure@ 98                does  not  return after the user presses the 98                escape key.t 9  > 8exclamation (!) The exclamation point is the only  printable@ 98                character  that  has  special meaning to theJ 98                _P_o_i_n_t() procedure.  The exclamation point is@ 98                used  as  the KIC system interface; when the@ 98                KIC user types  an  exclamation  point,  KIC@ 98                will  expect  the user to type a system com-@ 98                mand terminated by a carriage  return.   The 9     9   9    > 8                                                         121    @ 98                command  string  will  then be passed to theV 98                _S_h_o_w_P_r_o_c_e_s_s() routine that will execute  the@ 98                command  and  display any output in the area@ 98                of the fine viewport.  When the user presses@ 98                a key on the keyboard to signify that he has@ 98                read the displayed output, the  fine  windowJ 98                is  redrawn.  The _P_o_i_n_t() procedure does not@ 98                return after the user executes a process  in& 98                the fine viewport. 9  <      If the KIC user points in the layer menu viewport  with  Z the graphical pointing device, the _P_o_i_n_t_L_a_y_e_r_T_a_b_l_e() routine  < is invoked to determine if the user actually  pointed  at  a  < valid  layer.   If  the  user  user did select a new current  J layer, the _k_p_L_a_y_e_r member of the KIC parameters structure is  < set  to  the index of the new current layer in the KIC layer  F table,  and  the  _P_o_i_n_t()   procedure   returns   with   the  ^ _k_p_P_o_i_n_t_L_a_y_e_r_T_a_b_l_e member of the KIC parameters structure set  f to the logical value of _T_r_u_e.  The _k_p_P_o_i_n_t_L_a_y_e_r_T_a_b_l_e is typ-  P ically  used  by  procedures  such  as  _F_i_l_l_e(), _B_l_i_n_k(), or  F _V_i_s_i_b() that require the user to point  in  the  layer  menu  < viewport  to  identify layers to be assigned specific attri-  < butes.  As described above, the KIC user can also  select  a  6 new current layer with the control-L keyboard command.    <      When the user points in any layout  viewport  with  the  < graphical  pointing  device, the viewport coordinate is con-  H verted to the respective window coordinate by  the  _C_t_r_l_A_t()  F procedure  that is invoked by the _P_o_i_n_t() procedure, and the  H values are placed in the _k_c_X, _k_c_Y members of the KIC  cursor  < descriptor  described in Section 4.2.4.  The previous values  d of _k_c_X, _k_c_Y are moved to _k_c_P_r_e_d_X, _k_c_P_r_e_d_Y, and the displace-                    <                                                          122    L ment is computed and placed in the _k_c_D_X, _k_c_D_Y members of the  H KIC cursor descriptor.  The _C_t_r_l_A_t() procedure also sets the  f _k_p_P_o_i_n_t_C_o_a_r_s_e_V_i_e_w_p_o_r_t member of the KIC parameters structure  P to the value of _T_r_u_e and invokes  the  _S_h_o_w_X_Y()  routine  to  < display  the  current  cursor information in the information  F viewport.  The geometry input procedures, such  as  _B_o_x_e_s(),  n _W_i_r_e_s(),  and  _P_o_l_y_g_o_n_s()  will  wait  for  the _k_p_P_o_i_n_t_C_o_a_r_-  P _s_e_V_i_e_w_p_o_r_t flag to indicate that there is new information in  F the cursor descriptor.  The _P_o_i_n_t() procedure will clear the  N _k_p_C_o_m_m_a_n_d buffer in the KIC parameters structure and  return  > immediately after invoking the _C_t_r_l_A_t() procedure.    <      To repeat from the above table  of  keyboard  commands,  < when  the  KIC  user types a printable character on the key-  < board while the graphical pointing  device  is  active,  the  F character  is  received by the _P_o_i_n_t() routine, converted to  < lower case, and placed at the end of  the  contents  of  the  N _k_p_C_o_m_m_a_n_d  buffer  in  the  KIC  parameters  structure.  The  F _P_o_i_n_t() procedure maintains a running count of the number of  < buffered  keyboard  characters and will not immediately ter-  < minate after the user types a character.   After  the  typed  N character  has  been buffered, the contents of the _k_p_C_o_m_m_a_n_d  < buffer are  compared  with  the  current  command  set;  the  H current  command  set  is identified by the _k_p_M_e_n_u member of  F the KIC parameters  structure.   If  the  _P_o_i_n_t()  procedure  < determines  that the user has typed a command name, the pro-  H cedure returns with the complete command name in the  _k_p_C_o_m_-   _m_a_n_d buffer.                  <                                                          123    <      KIC will be easiest to use if  the  graphical  pointing  < device has at least four buttons.  If the graphical pointing  L device has buttons, the _f_B_u_t_t_o_n_s member of the frame  buffer  D descriptor  is  set  to the value of _T_r_u_e, and the number of  < buttons on the graphical pointing device is specified by the  R _f_N_u_m_B_u_t_t_o_n_s  member  of  the frame buffer descriptor that is  < described in Section 4.6.1.  When the  user  pushes  one  of  < these  buttons  on  the  pointing  device, the terminal will  < report a button mask to the host, and this button mask  will  < be compared with the array of button masks referenced by the  R _f_B_u_t_t_o_n_M_a_s_k member of the frame buffer descriptor  to  iden-  < tify  the  respective  button  that  was  pushed.  The first  R integer in the _f_B_u_t_t_o_n_M_a_s_k array is the value  of  the  mask  1 for the first button on the pointing device, etc.e    <      In KIC, the first button on the graphical pointing dev-  < ice is used specifically for identifying entries in the com-  < mand or layer menus and for specifying a  window  coordinate  < whenever  KIC  is  prompting  the  user for one.  The second  < pointing device button is used for repositioning the  center  < of  the  fine window, and the fourth button is used to rede-  < fine the size of the fine  window  from  two  user-specified  < window coordinates of the new fine window diagonal.  Because  < the size of the fine viewport is fixed, the size of the  new  < user-specified  fine  window will be clipped to fit into the  < fixed aspect ratio.   The  third  button  on  the  graphical  < pointing  device performs the same function as the control-W  < keyboard command; when the points in the layout viewports by                  <                                                          124    < pressing  the  third  pointing device button, the respective  < window coordinate is displayed in the  information  viewport  H by the _S_h_o_w_X_Y() procedure.  The third pointing device button  < is typically used for measuring the size of objects  in  the  F database.   The  _P_o_i_n_t()  procedure will terminate after the  < KIC user presses the second, third, or fourth pointing  dev-  < ice  button.   Only  the  first  pointing device button will  F cause the _P_o_i_n_t() procedure to  return  with  a  new  window  ( coordinate in the KIC cursor descriptor.                                                                                            <                                                          125    Q _4._6. _T_h_e _F_r_a_m_e _B_u_f_f_e_r _I_n_t_e_r_f_a_c_eB    <      As presented in Chapter 1, KIC is designed to run on  a  < wide range of raster graphics terminals or frame buffers and  < indeed runs on several devices including  the  AED  512  and  < 767,  the  Tektronix 4113 and 4105, the HP2648A, the Metheus  < Omega-400, and the Masscomp  MC500.   The  frame  buffer  is  < modeled  by  the contents of the KIC frame buffer descriptor  < that contains the boolean and numeric capabilities  describ-  < ing  the  respective  frame  buffer  characteristics.   This  < report assumes that the reader is familiar  with  the  basic  < structure of a raster color graphics terminal, including the  < use of video memory and the color look-up table.   For  more  - information on this subject, see [6] and [7].r  X _4._6._1. _T_h_e _F_r_a_m_e _B_u_f_f_e_r _D_e_s_c_r_i_p_t_o_r    <      The frame buffer descriptor is defined  as  follows  in   the _f_b._h header file.c   98        /*! 98         * Frame Buffer desc.) 98         */_ 98        struct f { 98            char *fDisplay;e" 98            char *fDeviceName;R 98            int *fButtonMask;           /* pointer to array of button masks */O 98            int fMaxX,fMaxY;            /* raster dimensions of viewport */eD 98            int fFontHeight;            /* standard font size */ 98            int fFontWidth;iS 98            int fMaxIntensity;          /* set to 255 (normalized intensity) */tE 98            int fMaxP;                  /* max pixel intensity */dA 98            int fNumColors;             /* max color index */eO 98            int fNumRows;               /* max number of horizontal rows */nP 98            int fNumColumns;            /* max number of vertical columns */@ 98            int fNumFillPatterns;       /* max fill index */J 98            int fInitialized;           /* FB struct is initialized */N 98            int fNonDestructiveText;    /* text doesn't wipe background */R 98            int fLastCursorColumn;      /* last column used by ShowPrompt() */R 98            int fFilledPolygons;        /* frame buffer has filled polygons */       9   9    > 8                                                         126    K 98            int fDefinableFillPatterns; /* fill styles are definable */ M 98            int fButtons;               /* pointing device has buttons */ S 98            int fNumButtons;            /* number of pointing device buttons */_ 98            }_ 98            FB;_ 99L      The _f_D_i_s_p_l_a_y member of the frame buffer structure is  a  < pointer  to  a  character  string that specifies the name or  < type of the respective graphics terminal; for  example,  the  R Tektronix  4113  might  be named "t5".  The _f_D_e_v_i_c_e_N_a_m_e is a  < pointer to the name of the  system  device  driver  for  the  < graphics  device.  An example of a UNIX device name might be   "/_d_e_v/_t_t_y_0_1".i    <      The resolution of the graphics display  is  defined  by  P the  _f_M_a_x_X and _f_M_a_x_Y frame buffer structure members.  If the  < display size of the graphics device is characterized by  640  < horizontal  pixels  and  480  vertical pixels, the values of  F _f_M_a_x_X and _f_M_a_x_Y would be 639 and 479 respectively.    <      The maximum color index for the frame buffer is defined  P by  the  _f_N_u_m_C_o_l_o_r_s  member  of the frame buffer descriptor.  < For a monochromatic display, this structure member would  be  < assigned  the  value  of unity.  Zero is a valid color index  < and is always used by KIC as the background  color.   For  a  < color  display, the maximum gun intensity for red, green, or  F blue is defined by the value of the _f_M_a_x_P structure  member.  V The _f_M_a_x_I_n_t_e_n_s_i_t_y structure member is the value to which KIC  < normalizes the gun intensities and should always be  set  to  < the  value of 255.  In other words, KIC assumes that the gun  < intensity for the color display is an eight bit value.   The       9          <                                                          127    F _F_B_V_L_T()  routine,  which  redefines  an  entry  in the frame  < buffer's color look-up table, will convert a color intensity  < of 255 to the value of the _f_M_a_x_P structure member.    <      The maximum index of fill patterns for the frame buffer  \ is  given  by the value of the _f_N_u_m_F_i_l_l_P_a_t_t_e_r_n_s frame buffer  < structure member.  Zero is assumed to be  the  index  for  a  < solid-fill  pattern.   If  the  fill patterns are definable,  h then the _f_D_e_f_i_n_a_b_l_e_F_i_l_l_P_a_t_t_e_r_n_s structure member is  set  to  D the  value  of  _T_r_u_e,  and if the frame buffer is capable of  P filled polygons, including solid fill, then  the  _f_F_i_l_l_e_d_P_o_-  P _l_y_g_o_n_s  structure  member  is also set to the value of _T_r_u_e.  < The polygon display mechanism for graphics devices that  are  < not  capable of filled polygons is to draw a line around the   perimeter of the object.    <      The pixel size of the font array for  graphic  text  is  f defined  by  the  _f_F_o_n_t_W_i_d_t_h  and _f_F_o_n_t_H_e_i_g_h_t members of the  < frame buffer structure.  From these  two  structure  members  P and  the  _f_M_a_x_X  and  _f_M_a_x_Y structure members, the values of  r _f_N_u_m_R_o_w_s and _f_N_u_m_C_o_l_u_m_n_s are  computed;  _f_N_u_m_R_o_w_s  specifies  < the  number  of  graphic test rows from the top to bottom of  R the graphics display, and _f_N_u_m_C_o_l_u_m_n_s contains the number of  < graphic  text columns from the left to right of the display.  < The size of the graphic text  font  should  be  sufficiently  L small to allow the value of the _f_N_u_m_R_o_w_s structure member to  < be greater than 30.  See Section 4.1.1  that  describes  the  < graphic  text  coordinate  system  in  menu  and information                    <                                                          128    
 viewports.    P      When KIC invokes the _S_h_o_w_P_r_o_m_p_t()  routine  to  display  < text  in  the  prompt  viewport,  the last textual column in  ^ which text is displayed is saved  in  the  _f_L_a_s_t_C_u_r_s_o_r_C_o_l_u_m_n  P frame  buffer  structure  member.  The _F_B_K_e_y_b_o_a_r_d() routine,  < which obtains a user-typed character string  from  the  key-  < board of the graphics terminal, will use this information to  < decide where to begin to echo user-typed text in the  prompt  	 viewport.r    <      If the graphic text is not destructive, i.e., the back-  < ground  in  the  character  font array is not changed when a  b graphic  character  is  displayed,  the  _f_N_o_n_D_e_s_t_r_u_c_t_i_v_e_T_e_x_t  D frame  buffer  structure member is set to the value of _T_r_u_e.  < It is preferable for graphic text to be non-destructive.  If  < the  text  is destructive, the display of layout information  < may be corrupted by a  textual  label,  and  KIC  will  also  P highlight command menu items differently in the _M_e_n_u_S_e_l_e_c_t()  
 procedure.    <      It is assumed that the frame buffer has  some  form  of  < graphical pointing device.  If the graphical pointing device  < has buttons that send locator reports to the host such  that  < the  host  can determine which button was pressed by the KIC  L user, the _f_B_u_t_t_o_n_s structure member is set to the  value  of  D _T_r_u_e.  The number of buttons on the pointing device is given  j by  the  _f_N_u_m_B_u_t_t_o_n_s  structure  member.   The  _f_B_u_t_t_o_n_M_a_s_k_s  < pointer  references  an  array  of integers that are used to                  <                                                          129    < identify the buttons of the graphical pointing  device.   If  < the  KIC  user presses the first button on the pointing dev-  J ice, the _F_B_P_o_i_n_t() routine will return with  the  respective  < button  mask  that  was  received by the host from the frame  F buffer.  The _P_o_i_n_t() procedure will recognize that the first  < button  was  pushed  because  the  button mask value will be  < identical to the first integer in the  array  referenced  by  T the  _f_B_u_t_t_o_n_M_a_s_k_s  pointer, etc.  KIC uses no more than four  ) buttons on the graphical pointing device.r    T      The _f_I_n_i_t_i_a_l_i_z_e_d structure member is set when the frame  < buffer descriptor is completely initialized and the graphics  D device driver is in CBREAK mode; see _t_t_y(_4) in the BSD  UNIX  < programmer's  manual.   CBREAK  mode implies that characters  < that are typed at the terminal are not buffered, but becomes  < available  to KIC when they are typed.  Also, character echo  < must be disabled; KIC will echo the  keyboard  input.   Flow  : control and interrupt processing should always be enabled.  R _4._6._2. _T_h_e _F_r_a_m_e _B_u_f_f_e_r _R_o_u_t_i_n_e_s    <      The frame buffer routines that are required for KIC  to  < control  a  graphics device or frame buffer are described in  < this section.  There should be sufficient  information  pro-  < vided  here for any programmer to write a display driver for  < KIC.  However, the best procedure for interfacing KIC  to  a  < new  graphics  terminal  is to take an existing set of frame  < buffer routines for another graphics terminal and modify the  % routines for the new graphics device.                    <                                                          130    <      All graphics device dependencies are managed  by  these  < frame  buffer  routines,  and,  as  a result, a set of frame  < buffer routines that were written  for  a  particular  frame  < buffer  will probably differ greatly from routines that were  < written  for  another  graphics  device.   Separate  display  < drivers have been written for several graphics terminals and  \ graphics work stations as well as  the  _M_o_d_e_l  _F_r_a_m_e  _B_u_f_f_e_r  & terminal independent graphics package.    <      The following is a synopsis of all  frame  buffer  rou-  7 tines that are required by KIC for any graphics device:u   98        FBBegin(Display) 98        char *Display; 99 8        FBInitialize() 99 8        FBHalt() 99 8        FBEnd()s 99 8        FBMoveTo(X1,Y1)v 98        int X1,Y1; 99 8        FBDrawLineTo(X2,Y2)e 98        int X2,Y2; 99 8        FBLine(X1,Y1,X2,Y2)  98        int X1,Y1,X2,Y2; 99. 8        FBForeground(DisplayOrErase,ColorId)  98        char DisplayOrErase; 98        int ColorId; 99J 8        FBBox(ColorId,DisplayOrErase,Type,StyleId,Left,Bottom,Right,Top)% 98        char Type,DisplayOrErase;6 98        int StyleId,ColorId,Left,Bottom,Right,Top; 99/ 8        FBDefineFillPattern(StyleId,BitArray). 98        int StyleId; 9     9   9    > 8                                                         131     98        int *BitArray; 99# 8        FBSetFillPattern(StyleId)  98        int StyleId; 99' 8        FBVLT(ColorId,Red,Green,Blue)e' 98        int ColorId,Red,Green,Blue;a 99, 8        FBText(Mode,RowOrX,ColumnOrY,Text)! 98        int RowOrX,ColumnOrY;l 98        char *Text;y 98        char Mode; 994 8        FBPolygon(ColorId,Type,StyleId,xy,ncoords) 98        int *xy;( 98        int ColorId,StyleId,ncoords; 98        char Type; 99. 8        FBBlink(ColorId,Red,Green,Blue,Flag) 98        int ColorId, Flag; 98        int Red,Green,Blue;d 99 8        FBFlood()  99# 8        FBSetCursorColor(ColorId)e 98        int ColorId; 99* 8        FBPolygonClip(xy,ncoords,window) 98        int *xy,*ncoords;r 98        struct ka window;. 99 8        FBTransfer() 99 8        FBKeyboard(TypeIn) 98        char **TypeIn; 99" 8        FBPoint(X,Y,Key,Buttons) 98        int *X,*Y,*Buttons;  98        char *Key; 990 8        FBMore(Left,Bottom,Right,Top,Textfile)& 98        int Left,Bottom,Right,Top; 98        FILE *Textfile;A 99<      KIC assumes that all frame buffer routines  work  prop-  < erly  and  therefore are not required to return a diagnostic       9          <                                                          132     value.    J      The _F_B_B_e_g_i_n() routine is the first frame buffer routine  < invoked  by  KIC and initializes the frame buffer descriptor  < described above for the  respective  graphics  device.   The  J only argument _D_i_s_p_l_a_y specifies the display name or type and  L becomes the _f_D_i_s_p_l_a_y member of the frame buffer  descriptor.  T The  _f_I_n_i_t_i_a_l_i_z_e_d  member  of the frame buffer descriptor is  < used to define the state of the graphics device  driver  and  > is typically not set by the _F_B_B_e_g_i_n() procedure.    b      The _F_B_B_e_g_i_n() routine will  invoke  the  _F_B_I_n_i_t_i_a_l_i_z_e()  < procedure  to  initialize  the graphics device driver to the  T required state.  If the _f_I_n_i_t_i_a_l_i_z_e_d  member  of  the  frame  T buffer descriptor is set to zero, the _F_B_I_n_i_t_i_a_l_i_z_e() routine  < will save the current state of the  graphics  device  driver  < and  then  set the state of the driver to a CBREAK mode with  D no  character  echoing;  see  _t_t_y(_4)   in   the   BSD   UNIX  < programmer's  manual.   CBREAK  mode  allows  a character to  < become available to the user program as soon as  it  appears  < from  the  terminal  and  also permits flow control.  If the  T _f_I_n_i_t_i_a_l_i_z_e_d structure member is  not  set,  then  typically  T there is no action when _F_B_I_n_i_t_i_a_l_i_z_e() is invoked.  When the  < communication link with the  graphics  device  is  not  over  F _s_t_d_i_o,  such  as  for a Metheus Omega 400 display controller  < which does not have a keyboard,  it  is  also  desirable  to  < place  the  standard input in CBREAK mode; when KIC requests  < the user to input through the keyboard, the user input  will                    <                                                          133    < be  taken from the standard input device and echoed normally  T on the graphics display.  The  _f_I_n_i_t_i_a_l_i_z_e_d  member  of  the  D frame  buffer  descriptor is set to the value of _T_r_u_e before  @ the _F_B_I_n_i_t_i_a_l_i_z_e() procedure terminates.    <      There are two procedures for releasing control  of  the  R graphics display or frame buffer: _F_B_H_a_l_t() and _F_B_E_n_d().  The  H _F_B_H_a_l_t() routine is invoked when KIC receives a SIGTSTP stop  < signal  (UNIX  only) which is generated by the KIC user from  < the keyboard when he wants to suspend,  but  not  terminate,  F the  KIC  program.   The _F_B_E_n_d() routine is however the last  < frame buffer procedure invoked by KIC.  Both procedures will  < clear  the graphics display, return the device driver to its  T original state, and set the _f_I_n_i_t_i_a_l_i_z_e_d member of the frame  F buffer descriptor to the value of _F_a_l_s_e.  If the KIC program  T was suspended by the user, invocation of the  _F_B_I_n_i_t_i_a_l_i_z_e()  < procedure  will  again  save the current state of the device  6 driver and set the driver to the required CBREAK mode.    <      A common configuration for running KIC  is  to  have  a  < graphics  terminal connected to the host over a serial, full  < duplex, RS-232 line with a 9600 or 19200  Baud  rate.   When  < this  is  the  case,  it is always necessary to use buffered  < output to reduce the number of system I/O  requests  to  the  < host  computer.  An example C procedure for buffering output   characters is shown below:   9     9     9   9    > 8                                                         134      98        #define BUFSIZE 4096 99+ 8        static  int     NumTTYBuffer = 0;o/ 98        static  char    TTYBuffer[BUFSIZE];r 99 8        FBWrite(cp,n)sG 98            char *cp;   /* pointer to string to be put in buffer */ID 98            int n;      /* size of string to be put in buffer */ 98            {s. 98            /* test for buffer overflow */2 98            if((NumTTYBuffer + n) >= BUFSIZE){4 98                write(1,TTYBuffer,NumTTYBuffer);% 98                NumTTYBuffer = 0;0 98                }  98            while(n--)6 98                TTYBuffer[NumTTYBuffer++] = *cp++; 98            }d 99<      If the output graphics code is  buffered,  it  is  fre-  < quently necessary to flush the output buffer or transfer all  < buffered characters to insure that a specific display action  P will  occur  immediately.   The _F_B_T_r_a_n_s_f_e_r() procedure would  < accomplish this, as in the above C procedure, by writing all  < buffered  characters  to the graphics device and setting the  < buffered character count to zero.  If  output  is  not  buf-  N fered, the _F_B_T_r_a_n_s_f_e_r() routine will perform no operation.    \      The _F_B_S_e_t_F_i_l_l_P_a_t_t_e_r_n() routine is invoked  to  set  the  < current  fill pattern of the frame buffer to that identified  J by the integer _S_t_y_l_e_I_d that is greater than or equal to zero  \ and  less  than or equal to the value of _f_N_u_m_F_i_l_l_P_a_t_t_e_r_n_s in  < the frame buffer descriptor.  Solid fill is  always  defined  J by  _S_t_y_l_e_I_d  equal to zero.  If the graphics device does not  H provide filled geometries or has only solid fill, the _F_B_S_e_t_-  H _F_i_l_l_P_a_t_t_e_r_n() procedure will perform no operation.     9                <                                                          135    b      The _F_B_D_e_f_i_n_e_F_i_l_l_P_a_t_t_e_r_n() procedure  defines  the  fill  X pattern  identified  by  _S_t_y_l_e_I_d and returns with _S_t_y_l_e_I_d as  \ the current fill style.  As for the _F_B_S_e_t_F_i_l_l_P_a_t_t_e_r_n()  pro-  J cedure,  the  value  of  _S_t_y_l_e_I_d is greater than or equal to  \ zero and less than or equal to the value of _f_N_u_m_F_i_l_l_P_a_t_t_e_r_n_s  L in  the frame buffer descriptor.  The _B_i_t_A_r_r_a_y argument is a  < pointer to an array of eight integers whose  least  signifi-  < cant  eight  bits  represent  individual rows in an eight by  < eight intensity array.  For example, a fill pattern with  an  < ascending  diagonal  line  may  be  defined by the following   eight (decimal) integers:9    *                   1 2 4 8 16 32 64 128 256    < A diagonal-grid fill pattern can be defined with the follow-   ing integer array:    +                 257 130 68 40 40 68 130 257       J      The value of the _C_o_l_o_r_I_d argument for all frame  buffer  < routines must be greater than or equal to zero and less than  P or equal to the value of  _f_N_u_m_C_o_l_o_r_s  in  the  frame  buffer  J descriptor.   The _C_o_l_o_r_I_d argument is in fact the index of a  < particular display color in the video  color  table  of  the  P respective graphics device, and the _f_N_u_m_C_o_l_o_r_s member of the  < frame buffer descriptor specifies  the  size  of  the  color   table.    <      The color map that is used by KIC is simple; the  first                    <                                                          136    < color  in  the  video  color  table,  which corresponds to a  J _C_o_l_o_r_I_d value of zero, is always the background color of the  < display.   The  last  color  in the video color table, which  ^ corresponds to a  _C_o_l_o_r_I_d  value  equal  to  the  _f_N_u_m_C_o_l_o_r_s  < member  of  the  frame buffer descriptor, is always used for  < highlighting objects in the selection queue, displaying  the  < coordinate  axes,  and also defines the color of the cursor.  < The remaining colors are dedicated to the  display  of  mask  < geometries.   Two  mask  layers can not share the same color  < index of the video color table unless there are insufficient  < display  colors  in  which case the several mask layers will  < share the last entry in the color  table,  the  highlighting   color.    F      The _F_B_V_L_T() procedure defines  the  video  color  table  J entry  for  the  color identified by _S_t_y_l_e_I_d to be the color  T represented by the _R_e_d, _G_r_e_e_n, _B_l_u_e combination. The  values  T of  _R_e_d,  _G_r_e_e_n, and _B_l_u_e are normalized to the value of the  V _f_M_a_x_I_n_t_e_n_s_i_t_y member of the frame buffer  descriptor,  which  < is usually equal to 255, and their absolute maximum value is  F specified by the _f_M_a_x_P frame buffer structure member.   Once  J the   color  corresponding  to  _C_o_l_o_r_I_d  is  redefined,  all  < geometries that were written into the display memory of  the  < respective frame buffer will immediately be displayed in the  J new color.  The  value  of  the  _C_o_l_o_r_I_d  argument  must  be  < greater  than or equal to zero and less than or equal to the  G value of _f_N_u_m_C_o_l_o_r_s in the frame buffer descriptor.-                      <                                                          137    T      The  _F_B_F_o_r_e_g_r_o_u_n_d()  routine  is  invoked  to  set  the  J current drawing color to that specified by the _C_o_l_o_r_I_d argu-  X ment.  The _D_i_s_p_l_a_y_O_r_E_r_a_s_e  argument  specifies  whether  the  < color  is  to  be displayed or erased, and it must be one of  < the values defined as follows in the _f_b._h header file:  B 98    #define ERASE         'e'  /* Erase to background color */A 98    #define DISPLAY       'd'  /* Show object as specified */  99<      If the color is to be erased, it  is  assumed  that  it  X will  be erased to the background color.  The _D_i_s_p_l_a_y_O_r_E_r_a_s_e  < argument is redundant if the  foreground  color  is  set  to  < color  zero,  the  background color.  It is provided for the  < programmer who wishes to write a frame  buffer  driver  that  F uses a special _A_L_U _m_o_d_e which requires this information.    <      To explain the meaning of the ALU mode, it is necessary  < to  understand  the procedure by which a geometry is written  < into the video memory of the graphics display.  If we assume  < that  the  display is a typical raster device, each pixel of  < the display is  represented  by  a  location  in  the  video  < memory,  and  that memory location contains the index in the  < video color table for the  color  by  which  the  respective  < pixel  is  to  be  displayed on the CRT.  Most frame buffers  < provide the  capability  of  specifying  how  video  display  < memory  is changed by a write operation.  One common mode of  < writing into the video memory is an arithmetic  'OR'  opera-  < tion  between the source color index and the contents of the  < destination memory location, where the source color index is  < the  current, foreground color index.  In this case, the ALU                  <                                                          138    < mode is  the  'OR'  mode.   KIC  will  in  general  use  the  < 'replace'  mode  in  which the contents of the video display  < memory are replaced by the source color index, regardless of  , the previous contents of the display memory.    J      The _F_B_F_l_o_o_d() procedure is invoked to clear the  entire  ) display to the current, foreground color.a    \      The _F_B_S_e_t_C_u_r_s_o_r_C_o_l_o_r() routine is invoked  to  set  the  < color  of  the  graphical  cursor to the color identified by  J _C_o_l_o_r_I_d.  As described above, the last entry  in  the  video  < color  table of the frame buffer is always used for the cur-  
 sor color.    <      KIC allows mask colors  to  blink,  if  the  respective  J frame  buffer has this capability.  If the _F_B_B_l_i_n_k() routine  D is invoked with the _F_l_a_g argument  equal  to  the  value  of  D _T_r_u_e,  the color that is identified in the video color table  J of the graphics display by the _C_o_l_o_r_I_d index is set to blink  < between  its normal color and the color defined by the color  T combination of the arguments _R_e_d, _G_r_e_e_n, and _B_l_u_e.  The nor-  J mal  color  for any given value of _C_o_l_o_r_I_d is the color that  < is defined in the video color table.  The rate  of  blinking  < is not definable; colors should blink at a rate that is com-  J fortable to view.  If the _F_B_B_l_i_n_k() routine is invoked  with  N the  value of the _F_l_a_g argument set to _F_a_l_s_e, then the color  J identified by the value of _C_o_l_o_r_I_d is set to a  non-blinking  < state.   If the respective frame buffer does not provide the  < capability  of  blinking  colors,   or   alternating   color                  <                                                          139    J definitions  in  the  video  color table, the _F_B_B_l_i_n_k() pro-   cedure performs no operation.     <      There  are  six  routines  for  displaying  figures  or  \ geometries  on  the  graphics  display: _F_B_M_o_v_e_T_o(), _F_B_D_r_a_w_L_-  z _i_n_e_T_o(),  _F_B_L_i_n_e(),  _F_B_B_o_x(),  _F_B_P_o_l_y_g_o_n(),  and   _F_B_T_e_x_t().  < These frame buffer routines will display an object or figure  < in the current, foreground color and with the  current  fill  < pattern,  if applicable.  All coordinates that are passed as  < arguments to these frame buffer procedures are display coor-  @ dinates  with  there (_0,_0) origin in the bottom, left corner  < of the graphics display.  The effect of these routines might  P be  delayed  until  the _F_B_T_r_a_n_s_f_e_r() procedure is invoked to   flush the output.     L      The _F_B_M_o_v_e_T_o()  procedure  sets  the  current  graphics  D position  to  the display coordinate identified by the _X_1,_Y_1  T arguments.  A subsequent invocation  of  the  _F_B_D_r_a_w_L_i_n_e_T_o()  < procedure  will produce a solid line from the current graph-  < ics position to the display  coordinate  identified  by  the  D _X_2,_Y_2  arguments,  and  the  current  graphics position then  H moves to the latter display coordinate.  The  _F_B_L_i_n_e()  rou-  D tine  is  invoked  to  display  a  solid line from the _X_1,_Y_1  D display coordinate to the _X_2,_Y_2  display  coordinate,  after  D which  the  current  graphics  position  is set to the _X_2,_Y_2   display coordinate.     F      The _F_B_B_o_x() routine is invoked to display  or  erase  a  J box  in  the color identified by the _C_o_l_o_r_I_d argument and in                  <                                                          140    R the pattern identified by the _T_y_p_e  and  _S_t_y_l_e_I_d  arguments.  < The  resulting  box  is  defined  by the display coordinates  ` _L_e_f_t, _B_o_t_t_o_m, _R_i_g_h_t, _T_o_p and  is  either  displayed  in  the  J color  identified  by  _C_o_l_o_r_I_d, which becomes the foreground  < color, or is erased to the background color depending on the  t value  of  the  _D_i_s_p_l_a_y_O_r_E_r_a_s_e argument.  The _D_i_s_p_l_a_y_O_r_E_r_a_s_e  < argument must be set to one of the values defined as follows   in the _f_b._h header file:  B 98    #define ERASE         'e'  /* Erase to background color */A 98    #define DISPLAY       'd'  /* Shoe object as specified */  99D      The _T_y_p_e argument specifies whether the box  is  to  be  < filled  or  outlined,  and  this argument must be one of the  8 values defined as follows in the _f_b._h header file:  B 98    #define FILL          'f'  /* Fill with current pattern */B 98    #define OUTLINE       'o'  /* Outline contour of object */ 99J      If the box is filled, the _S_t_y_l_e_I_d argument defines  the  < fill pattern to be used; this fill style becomes the current  < fill pattern.  The box must always be  filled  whenever  the  Q _D_i_s_p_l_a_y_O_r_E_r_a_s_e argument specifies an erase operation.d    N      _F_B_P_o_l_y_g_o_n() is invoked to  display  a  polygon  in  the  J color  identified by the _C_o_l_o_r_I_d argument and in the pattern  R identified by the _T_y_p_e and _S_t_y_l_e_I_d arguments.  The  vertices  < of  the  polygon are defined in the integer array referenced  @ by the _x_y pointer; the number of vertices  is  specified  by  J the  _n_c_o_o_r_d_s  argument,  and the first display coordinate is  N (_x_y[_0], _x_y[_1]), the second  display  coordinate  is  (_x_y[_2],  J _x_y[_3]),  etc.   The  _T_y_p_e  argument  specifies  whether  the                  <                                                          141    < polygon is to be filled or outlined, and this argument  must  B be  one  of the values defined as follows in the _f_b._h header   file:i  B 98    #define FILL          'f'  /* Fill with current pattern */B 98    #define OUTLINE       'o'  /* Outline contour of object */ 99J      If the polygon is filled, the _S_t_y_l_e_I_d argument  defines  < the  fill  pattern  to  be used; this fill style becomes the  < current fill pattern.  If the frame buffer is not capable of  < displaying  filled  polygons,  the  polygons are always out-   lined.    H      _F_B_T_e_x_t() is  invoked  to  display  a  character  string  D referenced  by  the _T_e_x_t argument at the position defined by  Z the _R_o_w_O_r_X and _C_o_l_u_m_n_O_r_Y arguments.  As described in Section  < 4.1.1,  KIC  uses two coordinate systems for the positioning  H of graphic text, and the _F_B_T_e_x_t() procedure must accommodate  D both  systems.  The _M_o_d_e argument specifies which coordinate  < system is to be used and must be set to one  of  the  values  1 defined as follows in the _f_b._h header file:b  D 98    #define ROW_COLUMN        'r'  /* use ASCII terminal mode */F 98    #define PIXEL_COORDINATE  'p'  /* use graphics display mode */ 99D      If the _M_o_d_e argument is set to the value of ROW_COLUMN,  Z the  _R_o_w_O_r_X and _C_o_l_u_m_n_O_r_Y arguments specify the position for  < the first character of the string in the row-column or char-  < acter  block  coordinate  system; otherwise, these arguments  < specify the lower, left display  coordinate  for  the  first  < character  of  the  string.  Displayed text is never rotated  < and normally uses a  single  character  font.   Because  the                  <                                                          142    < row-column   coordinate   system  is  used  exclusively  for  < displaying text in the command, information, and layer  menu  D viewports,  the  _M_o_d_e  argument  could  be used, however, to  & specify one of two graphic text fonts.    J      _F_B_P_o_i_n_t() is the only frame buffer  routine  that  con-  < trols  the  graphical  pointing  device.   When invoked, the  J _F_B_P_o_i_n_t() routine displays the  graphical  cursor  and  then  < waits  for a user pointing event.  If the graphical pointing  < device is equipped with buttons,  a  pointing  event  occurs  < when  the KIC user presses one of these buttons or presses a  < character key on the keyboard; otherwise, if  there  are  no  < buttons  on  the graphical pointing device, a pointing event  < occurs only when the user presses a  character  key  on  the  < keyboard.   After  one user pointing event, the routine ter-  < minates, and the returned values also depend on whether  the  < graphical  pointing device is equipped with buttons.  If the  < graphical pointing device has buttons and the  user  pressed  J one  of  these  buttons, _F_B_P_o_i_n_t() returns with the value of  B zero in the character referenced by  the  _K_e_y  pointer,  the  < display  coordinate coordinate of the graphics cursor (i.e.,  < the position of the cursor) in the  integers  referenced  by  @ the  _X,  _Y  pointers, and the identifying button mask in the  J integer referenced by the _B_u_t_t_o_n_s pointer; this button  mask  R can  be compared with the contents of the _f_B_u_t_t_o_n_M_a_s_k member  < of the frame buffer descriptor to determine the button  that  < was  pressed.   If the graphical pointing device has buttons  < and the KIC user types  at  the  keyboard  of  the  graphics                  <                                                          143    < terminal, then the character that was user-typed is returned  B in the character referenced by  the  _K_e_y  pointer,  and  the  < other  returned  values  are  meaningless.  If the graphical  < pointing device does not have buttons and the user presses a  J character key on the keyboard, the _F_B_P_o_i_n_t() routine returns  < with the value of typed character in  the  character  refer-  B enced by the _K_e_y pointer, the display coordinate of the cur-  @ sor  position  in  the  integers  referenced  by  the  _X,  _Y  J pointers,  and the returned value of the _B_u_t_t_o_n_s argument is  < meaningless.  The graphics cursor is always disabled  before  # _F_B_P_o_i_n_t() terminates.h    P      The _F_B_K_e_y_b_o_a_r_d() procedure is invoked  to  obtain  user  < input  from the device keyboard or the standard input.  This  < input routine will perform  character  buffering  and  input  H line  management, and return the pointer _T_y_p_e_I_n to the input  < character buffer.  The input line  management  includes  the  < handling  of  the  erase  character  (typically control-H or  < delete), the line kill character (control-X  or  control-U),  < special hacking of control characters (especially the escape  < character), and character echoing.  All characters that  are  < typed by the KIC user are echoed in the information viewport  T beginning at the text column specified by  the  _f_L_a_s_t_C_u_r_s_o_r_-  H _C_o_l_u_m_n  member  of  the  frame  buffer  descriptor,  and are  Z displayed with the color identified by  the  _k_p_M_e_n_u_T_e_x_t_C_o_l_o_r  < member  of  the  KIC parameters structure, which becomes the  P foreground color.  _F_B_K_e_y_b_o_a_r_d()  terminates  when  the  user  < presses  either  the  new-line  or  return key (control-J or                  <                                                          144     control-M).h    <      To display the contents of a file in a viewport of  the  H graphics  display,  KIC  invokes  the _F_B_M_o_r_e() routine.  The  L _T_e_x_t_f_i_l_e argument is the file descriptor for the  text  file  < that  is  to  be  displayed in the viewport specified by the  l _L_e_f_t, _B_o_t_t_o_m and _R_i_g_h_t, _T_o_p display  coordinates.   _F_B_M_o_r_e()  < will  display  characters  from the file until it has filled  < the space of the viewport, and then will prompt the KIC user  < in  the  same  viewport  before continuing; the procedure is  R similar to the UNIX _m_o_r_e(_1) command.  As for the the  _F_B_K_e_y_-  F _b_o_a_r_d()  routine,  special  hacking  of  control  characters  < should be performed because a frame buffer  with  a  serial,  < full  duplex,  RS-232 interface could enter an unknown state  < when it receives information that  is  similar  to  graphics  < command  code.   When  the  end  of  the  file detected, the  H _F_B_M_o_r_e() routine will erase the viewport to  the  background  < color,  color  index  equal  to  zero, and return.  The file  L referenced by the _T_e_x_t_f_i_l_e argument  is  not  closed  before   termination.    V      _F_B_P_o_l_y_g_o_n_C_l_i_p() will  clip  a  polygon  to  the  window  H defined by the _w_i_n_d_o_w argument.  The vertices of the polygon  < to be clipped are defined in the integer array referenced by  @ the  _x_y  pointer; the number of vertices is specified by the  J integer referenced by the _n_c_o_o_r_d_s argument,  and  the  first  H window coordinate is (_x_y[_0], _x_y[_1]), the second window coor-  H dinate is (_x_y[_2], _x_y[_3]),  etc.   It  is  assumed  that  the                    <                                                          145    @ integer  buffer referenced by the _x_y pointer is sufficiently  < large to  contain  the  returned  vertices  of  the  clipped  < polygon.   The  number of vertices of the clipped polygon is  J returned in the integer referenced by the _n_c_o_o_r_d_s  argument.  < See Section 4.1.3 that describes window-to-viewport clipping   in KIC.s                                                                                                        <                                                          146    P _4._7. _G_e_o_m_e_t_r_y _D_i_s_p_l_a_y _R_o_u_t_i_n_e_s    <      There are seven routines that are built on top  of  the  < frame buffer routines specifically for displaying objects in  p the layout viewports: _S_h_o_w_B_o_x(), _S_h_o_w_P_o_l_y_g_o_n(),  _S_h_o_w_W_i_r_e(),   _S_h_o_w_L_a_b_e_l(),     _S_h_o_w_L_i_n_e(),     _S_h_o_w_M_a_n_h_a_t_t_a_n_L_i_n_e(),    and  L _S_h_o_w_P_a_t_h().  These routines perform  the  window-to-viewport  < transformations,  window  to  viewport  clipping,  and  then  < display the respective object in  the  appropriate  viewport  ` depending  on the value of the _k_p_R_e_d_i_s_p_l_a_y_C_o_n_t_r_o_l parameter.  - A synopsis of these display routines follows:   & 98        ShowBox(Layer, BB, Window) 98        int Layer;! 98        struct ka BB, Window;i 99- 8        ShowLabel(Layer, Label, X, Y, Flag)a 98        char *Label;" 98        int Layer, X, Y, Flag; 991 8        ShowLine(Layer, X1, Y1, X2, Y2, Window)y& 98        int Layer, X1, Y1, X2, Y2; 98        struct ka Window;  99: 8        ShowManhattanLine(Layer, X1, Y1, X2, Y2, Window)& 98        int Layer, X1, Y1, X2, Y2; 98        struct ka Window;t 992 8        ShowPath(Layer, Path, Window, Terminate) 98        struct p *Path;x 98        struct ka Window;f! 98        int Layer, Terminate; 99* 8        ShowPolygon(Layer, Path, Window) 98        struct p *Path;w 98        struct ka Window;v 98        int Layer; 99. 8        ShowWire(Layer, Width, Path, Window) 98        struct p *Path;t 98        struct ka Window;p 98        int Layer, Width;e       9   9    > 8                                                         147     9<      All coordinate values that are passed as  arguments  to  < these  display  routines  must  be world coordinates and not  F display coordinates.  The _L_a_y_e_r argument defines  the  color  H with  which  the  object  is to be displayed, and the _W_i_n_d_o_w  < argument defines the window to which the  object  should  be   clipped.    <      The display routines must also consider the  fill  pat-  < tern  for  the  respective  layer.   Because there are frame  < buffers that do not provide the capability of stippled  fill  < patterns, the KIC geometry display routines provide at least  < two modes of presentation for  the  objects  on  any  layer.  < These  two  modes are filled and outlined, and the presenta-  < tion mode for a given layer is  determined  by  the  logical  L value  of the _k_l_F_i_l_l_e_d member of the KIC layer table for the  < respective layer.  See Section 4.2.3 that describes the  KIC   layer table descriptor.w    <      Except for a few peculiarities, these procedures should  < be  easily  understood by any programmer ho is familiar with  < the frame buffer  routines  and  CD  path  descriptor.   The  < remainder  of  section will discuss the peculiarities of the   individual routines.    <      Because the CD database has no notion of text  size,  a  Z _W_i_n_d_o_w  argument is not passed to the _S_h_o_w_L_a_b_e_l() procedure.  < This display procedure will attempt to evaluate the size and  < position  of  the  text  label  in  display  pixels from the                    <                                                          148    f _f_F_o_n_t_W_i_d_t_h and  _f_F_o_n_t_H_e_i_g_h_t  members  of  the  frame  buffer  < descriptor,  and from this information it will determine the  < number of characters in the label that will fit into each of  N the  layout  viewports.   Normally,  the _S_h_o_w_L_a_b_e_l() routine  < will not attempt to display a label in  a  viewport  if  the  < number  of display pixels to window lambda is less than two;  < the label will however always be  displayed  in  all  layout  L viewports  if  the  _F_l_a_g  argument  is set to a _T_r_u_e logical   value.    ^      The _S_h_o_w_M_a_n_h_a_t_t_a_n_L_i_n_e() routine  is  identical  to  the  L _S_h_o_w_L_i_n_e()  routine, except that it uses a more simple clip-  < ping algorithm.  If this procedure is used to display a line  < that  is  neither vertical or horizontal with respect to the  < graphics display and is not contained  entirely  within  the  H window  defined  by  the  _W_i_n_d_o_w  argument,  it  will not be   displayed accurately.n    X      The _S_h_o_w_P_a_t_h() routine will use the _F_B_L_i_n_e()  procedure  D to  display  the  path list referenced by the _P_a_t_h argument.  N If the _T_e_r_m_i_n_a_t_e argument is set, the path is terminated  to  ! produce the contour of a polygon.m  ( _4._7._1. _R_e_d_i_s_p_l_a_y    <      Before an area of the layout viewports can be drawn, it  J must first be erased to the background color.  The _S_h_o_w_B_o_x()  < routine could be  used  to  erase  an  area  of  the  layout  < viewports  by drawing a box on layer zero, but typically the  - _E_r_a_s_e_B_o_x() procedure is used.i                  <                                                          149      8        EraseBox(Area, Window)# 98        struct ka Area, Window;t 99L      The _E_r_a_s_e_B_o_x() procedure will erase the area identified  P by  the _A_r_e_a argument in the window identified by the _W_i_n_d_o_w  	 argument.     <      After an area of the layout viewports has been  erased,  N the  _R_e_d_i_s_p_l_a_y()  routine  is  invoked to display the layout   information in the viewport.  & 98        Redisplay(SymbolDesc, AOI)! 98        struct s *SymbolDesc;  98        struct ka AOI; 99N      The  _R_e_d_i_s_p_l_a_y()  procedure  will  display  all  layout  P information  of  the  CD symbol referenced by the _S_y_m_b_o_l_D_e_s_c  < symbol descriptor contained within the window defined by the  f _A_O_I  argument.   The  _k_p_R_e_d_i_s_p_l_a_y_C_o_n_t_r_o_l  member  of the KIC  < parameters structure determines the viewports that  will  be  < affected  by  this routine.  This routine is also controlled   by the _E_x_p_a_n_d_I_n_s_t_a_n_c_e_s and _k_p_E_x_p_a_n_d_F_i_n_e_V_i_e_w_p_o_r_t_O_n_l_y  members  7 of the KIC parameters structure defined in Section 4.3.     <      Given  the  above  geometry   display   routines,   the  N _R_e_d_i_s_p_l_a_y()  procedure  is  a  simple  application of the CD  < database.  The example C procedure that is provided in  Sec-  < tion  2.6  as an example of traversing a symbol hierarchy is  K similar, but not identical, to the _R_e_d_i_s_p_l_a_y() procedure.u    <      Because of the display philosophy of KIC, in particular  < the fact that a red box displayed on top of a green box will  < hide the green box, this routine is  inherently  inefficient     9          <                                                          150    < since  it must traverse the entire symbol hierarchy once for  < each layer so that the layer interactions will be consistent  < (e.g.,   red   objects  are  always  displayed  above  green  < objects).  There are at  least  two  possible  modifications  < that   would  increase  the  efficiency  and  speed  of  the  N _R_e_d_i_s_p_l_a_y() procedure:  the first is to modify the CD  data-  < base  to  recognize the layers in the symbol's bin structure  < that are in use.  This would eliminate the overhead of  ini-  < tializing  CD  to search an empty bin structure.  The second  < modification would be to change the  display  philosophy  of  < KIC  and  use  the 'OR' ALU mode described in Section 4.6.2.  < In this case, each layer  would  correspond  to  one  memory  < plane in the frame buffer, and a red object displayed on top  < of a green object would produce a, perhaps, brown object  in  < the area of intersection.  This approach was used in earlier  < versions of KIC  but  was  rejected  in  favor  of  priority  < redisplay  and  color  stipple  patterns.  The major problem  < with the plane-per-layer, color mixing solution is  that  it  < severely  limits  the number of uniquely colored layers that  < can be displayed  simultaneously  on  the  graphics  display  < because most frame buffers have fewer than 10 memory planes,  < and most IC designers claim to be more comfortable with  the  < notion of layer depth than with puzzling layer interactions.                                    <                                                          151    J _4._8. _G_e_o_m_e_t_r_y _I_n_p_u_t _R_o_u_t_i_n_e_s    <      There are seven routines in KIC that allow the user  to  < create objects in the CD database.  A synopsis of these pro-   cedures follows:   98        Arcs(LookedAhead)a 98        int *LookedAhead;  99 8        Boxes(LookedAhead) 98        int *LookedAhead;t 99 8        Doughnut(LookedAhead)  98        int *LookedAhead;t 99 8        Flash(LookedAhead) 98        int *LookedAhead;t 99 8        Label(LookedAhead) 98        int *LookedAhead;n 99 8        Polygons(LookedAhead) 98        int *LookedAhead;f 99 8        Wires(LookedAhead) 98        int *LookedAhead;3 99<      From the argument  list  of  each  routine,  one  could  < correctly  conclude  that  these routines are similar.  This  < section will describe the requirements and  resulting  simi-  # larities of these input procedures.p    <      Each of the above procedures for creating geometries is  < invoked  after  the KIC user selects a corresponding command  < menu item.  Each routine will terminate when the user either  < selects  a  new  menu command or after an error condition is  < detected, such as if the CD database is unable to create  an  H object  because of a failure of the _m_a_l_l_o_c() routine.  While                  <                                                          152    < in one of  the  geometry  creation  routines,  if  the  user  < selects another menu command, the integer that is referenced  Z by the _L_o_o_k_e_d_A_h_e_a_d argument is set to  the  value  of  _T_r_u_e.  R Another way of interpreting the use of the _L_o_o_k_e_d_A_h_e_a_d argu-  < ment is that it is used by a child procedure to  notify  the  < parent  procedure  that the KIC user has performed an action  < that the child procedure is unable to handle.   See  Section  ) 4.4 that describes the KIC command menus.t    <      Because these procedures interface to the KIC user  and  < thereby  directly affect how efficiently he can use KIC, the  < procedures  must  be  user-friendly.   There  is  a  set  of  < requirements  for any such routine.  Firstly, geometry crea-  < tion must be a mode of operation, rather than a single  com-  < mand;   this  allows  the KIC user to create several objects  < without having to specify that  he  is  doing  so  for  each  < object.   Secondly,  the KIC user must be able to change the  < current layer while KIC is in the geometry creation mode  of  < operation.   The  user must also be capable of 'undoing' his   last action.    <      A pseudo C procedure is provided below as an example of  < a  basic KIC user interface routine.  All the above geometry  5 creation routines are similar to the following model:e   9             9     9   9    > 8                                                         153    % 98        MakeObject( LookedAhead )9! 98            int *LookedAhead;  98            {k/ 98            _i_n_i_t_i_a_l_i_z_e;8 98            _u_s_e _S_h_o_w_P_r_o_m_p_t _t_o _t_e_l_l _t_h_e _u_s_e_r _w_h_a_t _h_e'_s _d_o_i_n_g; 99 8            while( True ){ 99 8                Point(); 99= 8                /* Has the user selected a menu command? */c: 98                if ( Parameters.kpCommand[0] != EOS ){ 997 8                    /* Did the user point to UNDO? */sJ 98                    if ( strcmp(Parameters.kpCommand,MenuUNDO) == 0 ){M 98                        if ( _n_o_t_h_i_n_g _t_o _u_n_d_o ){a4 98                            *LookedAhead = True;' 98                            return;m! 98                            }  98                        else if ( _c_u_r_r_e_n_t _o_b_j_e_c_t _h_a_s _b_e_e_n _t_e_r_m_i_n_a_t_e_d ){ec 98                            _d_e_l_e_t_e _t_h_e _e_n_t_i_r_e _o_b_j_e_c_t;  98                            _s_e_t _f_l_a_g _t_o _e_x_p_e_c_t _f_i_r_s_t _p_o_i_n_t _o_f _n_e_w _o_b_j_e_c_t;d! 98                            } ! 98                        else{tT 98                            _u_n_d_o _t_h_e _l_a_s_t _p_o_i_n_t;! 98                            }f 98                        }aE 98                    /* The user selected another menu command. */n 98                    else{ k 98                        _t_e_r_m_i_n_a_t_e _t_h_e _c_u_r_r_e_n_t _o_b_j_e_c_t;T0 98                        *LookedAhead = True;# 98                        return;i 98                        }i 98                    }t 99F 8                /* Did the user not point in the layout viewport? */? 98                else if ( !Parameters.kpPointCoarseWindow )a! 98                    continue;i 99E 8                /* Do we expect the first point of a new object? */ S 98                else if ( _e_x_p_e_c_t _f_i_r_s_t _p_o_i_n_t ){eE 98                    _b_e_g_i_n _n_e_w _o_b_j_e_c_t;r 98                    }s 999 8                /* Is this the same point as before? */eD 98                else if ( Cursor.kcX == X And Cursor.kcY == Y ){ 98                    _t_e_r_m_i_n_a_t_e _c_u_r_r_e_n_t _o_b_j_e_c_t _t_o _b_e_g_i_n _a_n_o_t_h_e_r; 98                    _s_e_t _f_l_a_g _t_o _e_x_p_e_c_t _f_i_r_s_t _p_o_i_n_t _o_f _n_e_w _o_b_j_e_c_t;  98                    }  99       9   9    > 8                                                         154    P 98                /* If none of the above, add point to object description. */ 98                else{ob 98                    _a_d_d _p_o_i_n_t _t_o _c_u_r_r_e_n_t _o_b_j_e_c_t; 98                    }  99 8                }n 98            }p 99P      The above _M_a_k_e_O_b_j_e_c_t() procedure  allows  the  user  to  < describe an object by interactions with the graphical point-  < ing device, and thereby enter the object into the  CD  data-  < base.   The  user  also has the ability to 'undo' either the  < previously entered point or the previously  created  object.  < The  procedure also recognizes when the user has not pointed  < in the layout viewports which permits  the  user  to  easily  < change  the  current  layer  by  pointing  in the layer menu  	 viewport.                                                                           <                                                          155    e _4._9. _G_e_o_m_e_t_r_y _M_o_d_i_f_i_c_a_t_i_o_n _P_r_o_c_e_d_u_r_e_s     <      The KIC user must have the capability of easily editing  < or modifying geometric objects.  There is an entire KIC com-  < mand menu, the selection menu, dedicated to this user  need.  < This chapter will describe KIC's philosophy of object modif-  ( ication and the user interface routines.    <      The first assumption of object editing in KIC  is  that  < the  user  will  desire to modify several objects simultane-  < ously rather than one object at a time.  For example, he may  < wish to stretch a signal bus containing several wires, or he  < may want to copy a bipolar transistor and add  a  90  degree  : rotation without destroying the inter-spacing of geometry.    <      The  question  then  arises  of  how  to  remember  and  < represent  the  several  objects  that the user will want to  < modify in a way that the user can easily control  and  in  a  < way  that  will not be cumbersome for any editing operation.  < In other words, how would the KIC user define a working  set  < of  objects?   One  solution might be to require the user to  < define a rectangular area that contains every object  to  be  < modified.   A problem with this simple solution, however, is  < that it does not allow the user to  be  as  specific  as  he  < might  wish  to  be;  suppose,  for  example,  that the user  < intends to move all objects in a rectangular area except one   box.    <      The KIC solution to this problem is the selection queue                    <                                                          156    < that  contains pointers to the user-specified objects in the  < symbol that is currently being edited.  The selection  queue  9 is defined in the _s_e_l_e_c_t._h file as follows:    98        struct ks { " 98            struct ks *ksSucc;$ 98            struct o *ksPointer; 98            }; 99! 8        struct ks *SelectQHead;r 99 8        struct ka SelectQBB; 99<      The following procedures are used by KIC to control the   selection queue.   98        SelectQInit()y 99  8        SelectQInsert(Pointer) 98        struct o *Pointer; 99  8        SelectQDelete(Pointer) 98        struct o *Pointer; 99 8        SelectQFirst(Pointer)h 98        struct o **Pointer;i 99 8        SelectQClear() 99 8        SelectQComputBB()e 99 8        SelectQShow(AOI) 98        struct ka AOI; 99R      The _S_e_l_e_c_t_Q_I_n_i_t() procedure is invoked  to  initialiaze  < the  selection mechanism.  This procedure is invoked once by  X the _I_n_i_t_P_a_r_a_m_e_t_e_r_s()  procedure  that  assigns  the  default  2 values to members of the KIC parameters structure.    V      _S_e_l_e_c_t_Q_I_n_s_e_r_t() is invoked to add  an  object  that  is                    <                                                          157    J referenced by _P_o_i_n_t_e_r to the selection queue.  The object is  < always inserted at the top of the list.  Any procedure  that  V invokes _S_e_l_e_c_t_Q_I_n_s_e_r_t() is required by convention to set the  < information field of the particular object to the  value  of  ; one via the _C_D_S_e_t_I_n_f_o() database routine.n    V      _S_e_l_e_c_t_Q_D_e_l_e_t_e() removes from the selection  queue  that  J object  referenced  by the _P_o_i_n_t_e_r argument and releases the  @ memory that was used by the  respective  _k_s  structure.   No  < action  occurs  if the object descriptor is not contained in  < the   selection   queue.    Any   procedure   that   invokes  V _S_e_l_e_c_t_Q_D_e_l_e_t_e()  is required by convention to set the infor-  < mation field of the removed object to the value of zero  via  3 the _C_D_S_e_t_I_n_f_o() database routine.t    T      The _S_e_l_e_c_t_Q_F_i_r_s_t() returns in the pointer referenced by  J _P_o_i_n_t_e_r  the first object in the selection queue (the object  < that is at the head of the list).  If the selection queue is  " empty, a null pointer is returned.    T      The _S_e_l_e_c_t_Q_C_l_e_a_r() procedure is invoked to  remove  all  < objects  from  the  selection  queue and release all related  T memory.  Before _S_e_l_e_c_t_Q_C_l_e_a_r() terminates,  the  pointer  to  R the  top  of  the selection queue _S_e_l_e_c_t_Q_H_e_a_d is assigned to   the value of NULL.    Z      When the _S_e_l_e_c_t_Q_C_o_m_p_u_t_B_B() is invoked, the bounding box  < of  all objects that are in the selection queue is evaluated  N and stored in the _S_e_l_e_c_t_Q_B_B area descriptor.  If the  selec-                    <                                                          158    < tion  queue  is  empty, the resulting bounding box will have  < impossible values; the top of the box will be below the bot-  6 tom, and the right side will be left of the left side.    R      The _S_e_l_e_c_t_Q_S_h_o_w() routine is invoked  to  highlight  in  < the  layout viewports all objects contained in the selection  B queue that intersect the area defined by the  _A_O_I  argument.  < The  emphasis  is  provided  by outlining the contour of all  < objects that qualify with the color that  is  identified  by  b the  _k_p_H_i_g_h_l_i_g_h_t_i_n_g_P_i_x_e_l member of the KIC parameters struc-  N ture.  This routine is always  invoked  by  the  _R_e_d_i_s_p_l_a_y()   procedure before it terminates.s    <      The information field of an object is used  by  KIC  to  < identify  the  status  of the particular object.  A table of  < the current uses of the object information  field  is  shown   below:  @ 98        Info = 0       Object is unselected (default value).E 98       *Info = 1       Object is selected and in selection queue.fR 98        Info = 2       Object is conditionally deleted and in selection queue.Q 98        Info = 3       Object is conditionally copied and in selection queue.uS 98        Info = 4       Object is conditionally selected and in selection queue.eC 98        Info = 5       Object is polygon or wire being created._S 98        Info = 10      Object is box that could not be stretched (see modify.c)dG 98       *Info = 11-255  Object has conditionally new layer and is inIN 98                       selection queue.  The old layer number = Info - 10.E 998       * means that SelectQShow() will highlight these objects.f 99<      Given the above routines  for  managing  the  selection  < queue, an example is in order.  The following procedure will  < examine the contents of the selection queue and  delete  all   objects that are boxes:t   9       9   9    > 8                                                         159     98        #include "kic.h" 98        #include "select.h"i 99 8        DeleteBoxes() { ' 98            struct ks *SelectQDesc;  98            char Type;, 998            SelectQDesc = SelectQHead;+ 98            while(SelectQDesc != NULL){i9 98                CDType(SelectQDesc->ksPointer,&Type);a& 98                if(Type == CDBOX){O 98                    CDDelete(Parameters.kpCellDesc,SelectQDesc->ksPointer); > 98                    SelectQDelete(SelectQDesc->ksPointer); 98                    }T6 98                SelectQDesc = SelectQDesc->ksSucc; 98                }a 98            }e 99<      There are six routines for the user-editing of  objects  < in KIC; each procedure uses the selection queue.  A synopsis   of each is provided below:  $ 98        ChangeLayer(LookedAhead) 98        int *LookedAhead;  99 8        Copy(LookedAhead)e 98        int *LookedAhead;e 99 8        Del(LookedAhead) 98        int *LookedAhead;h 99 8        Move(LookedAhead)  98        int *LookedAhead;e 99! 8        StretchBox(LookedAhead)w 98        int *LookedAhead;a 99" 8        StretchPath(LookedAhead) 98        int *LookedAhead;  99<      The requirements of these user-interface procedures for  < geometry  modification  are  similar  to  those for geometry  < creation.  The KIC user must be  capable  of  'undoing'  any  < command, but he most also be capable of canceling the effect                    <                                                          160    < of an 'undo'.   These  procedures  are  also  mode-oriented,  < thereby  allowing  the user to, for example, move objects in  < the layout viewports without being required  to  select  the  < particular  command  before  each action.  Also, the user is  < capable of redefining the current transformation of  objects  < at  any time in the editing process; the current transforma-  < tion is described in Section 4.3 covering the KIC parameters  
 structure.                                                                                                <                                                          161      2                          _C_h_a_p_t_e_r _5      K                     _S_y_s_t_e_m _D_e_p_e_n_d_e_n_c_i_e_s         <      At present, KIC runs under Berkeley  VM/UNIX,  Masscomp  < Real-Time  UNIX,  and  VAX/VMS; clearly the program is port-  < able.  The major problems that are involved with  transport-  < ing  KIC  to  another operating system are described in this  < chapter.  It is, of course, impossible to predict every pos-  < sible  problem  that  may arise by attempting to move KIC to  < another system;  only  those  difficulties  that  have  been  < experienced  in past are described.  It is also assumed here  < that all C compilers are  friendly  and  free  of  bugs  and   quirks!X    <      The standard definition of the C  programming  language  < is  [3].   It  is  assumed in KIC to be legal to pass entire  < structures in argument lists.   All  data  structure  member  < names  in  KIC  are  unique, and therefore no problem should  < ever arise from conflicting structure member  names.   Also,    data unions are not used in KIC.  N _5._1. _T_e_r_m_i_n_a_l _I/_O _D_e_p_e_n_d_e_n_c_i_e_s    <      Because the C programming language does not at  present  < have  a  standard set of procedures for special I/O control,  < the first problem with transporting KIC to another system is  < usually  the  frame buffer interface.  KIC must operate in a                    <                                                          162    F CBREAK mode; standard I/O,  or  _s_t_d_i_o,  is  not  sufficient.  < CBREAK  mode  implies  that characters typed at the terminal  < are not buffered, but becomes available to the program  when  < they  are  typed.   Character echoing must also be disabled.  D This mode is easily obtained with the Berkeley  UNIX  _t_t_y(_4)  < general  tty  interface;  under VMS it is available from the  0 _s_y_s$_q_i_o_w() system service routine.  N _5._2. _T_h_e _D_i_r_e_c_t_o_r_y _S_e_a_r_c_h _P_a_t_h    <      To have the capability of easily  using  standard  cell  < libraries, KIC must have a directory search path capability.  < When KIC requires that a file be opened, a  list  of  direc-  < tories  will be searched for that file in the order that the  < directory names appear on the respective  list.   The  first  < file  found in the directory list is opened, and if the file  < name is not found, a new  file  is  opened  in  the  current  < directory.   This  directory search algorithm is provided in   the _P_O_p_e_n() routine.    L      The list of directories is defined  by  the  _P_S_e_t_P_a_t_h()  V routine  that  will  invoke the _P_C_o_n_v_e_r_t_T_i_l_d_e() procedure to  < perform special character conversion.  Under Berkeley  UNIX,  < the  tilde  (~)  character is converted to the complete path  < name of the user's home  directory;  under  VMS,  the  tilde  0 character is converted to the user's login name.    <      To transport KIC to a system that does  not  have  UNIX  < style  directory  path names or does not have the equivalent  N of the UNIX _g_e_t_p_w_n_a_m(_3) routine, it is necessary  to  modify                  <                                                          163    V the  _P_C_o_n_v_e_r_t_T_i_l_d_e()  procedure  such  that  it will perform  < tilde  expansion  correctly.   And  most  importantly,   the  F _P_O_p_e_n()  procedure  must  be  modified  such that it will be  < capable of correctly appending a file name to any  directory  < name  in  the  directory search list.  As an example of this  F under the VMS file system, the file name _C_E_L_L._K  would  have  ^ to  be appended to the directory name _D_M_A_0:[_U_S_E_R._J_O_E._L_A_Y_O_U_T]  h to produce the character string _D_M_A_0:[_U_S_E_R._J_O_E._L_A_Y_O_U_T]_C_E_L_L._K  1 as the complete path name of the respective file.i  : _5._3. _M_e_m_o_r_y _M_a_n_a_g_e_m_e_n_t    <      On virtual memory systems, KIC and the CD database will  < allocate memory on demand.  For speed considerations, a spe-  J cial memory  management  package  called  _n_m_a_l_l_o_c  has  been  D developed.  In general, the memory allocation procedure _m_a_l_-  B _l_o_c(), which is  provided  in  most  C  run-time  libraries,  < attempts  to be efficient and miserly with the existing free  6 memory; consequently, it tends to be undesirably slow.    J      The _n_m_a_l_l_o_c() routine maintains a  separate  free  list  < for  objects of a particular size.  A free list in this case  < is a linked-list of free memory blocks; the first few  bytes  < of  the  memory block are used as a pointer to the next free  < block of memory with the same size.  Because large blocks of  < memory  (greater than 100 bytes) are infrequently requested,  < free lists are maintained only  for  memory  blocks  smaller  < than  80  bytes.   If a larger piece of memory is requested,  V the _n_m_a_l_l_o_c() routine defaults to the usual _m_a_l_l_o_c()  memory                    <                                                          164     allocation library routine.i    J      All memory blocks are aligned by _n_m_a_l_l_o_c() to the  size  < of an integer, which is typically four bytes.  Therefore, if  J _n_m_a_l_l_o_c() is invoked to return a pointer to 10 bytes of free  < memory,  the  actual size of the allocated memory block will  J be 12 bytes.  Furthermore, if _n_m_a_l_l_o_c() maintains free lists  < for  free memory blocks that are smaller than 80 bytes, only   20 free lists are required.e    <      The free storage that is contained in a free list for a  F particular  size  of  memory block is allocated by the _n_m_a_l_-  B _l_o_c() routine only when a block of memory having  that  par-  < ticular  size is requested.  When the free list must be con-  J structed, or additional memory added to the list,  _n_m_a_l_l_o_c()  < will  request a large block of memory from the system (typi-  < cally 4096 bytes),  and  this  memory  block  will  then  be  < divided to build the desired free list.  Under Berkeley UNIX  F the _s_b_r_k(_2) library routine is used to  acquire  this  large  < block  of  memory  from  the system, and VMS uses the normal  % _m_a_l_l_o_c() library routine._    <      To   transport   KIC    to    another    system,    the  T _n_m__b_l_o_c_k__a_l_l_o_c() procedure must be modified such that previ-  < ously described free lists will be properly constructed.  It  H is possible to compile KIC to use the usual _m_a_l_l_o_c() library  J procedure, and not  the  _n_m_a_l_l_o_c  package,  by  setting  the  J USE_OLD_MALLOC compiler flag in the _n_m_a_l_l_o_c._h header file.                      <                                                          165    A _5._4. _T_h_e _S_y_s_t_e_m _I_n_t_e_r_f_a_c_et    R      The _S_h_o_w_P_r_o_c_e_s_s() procedure is used by KIC to execute a  < system  command  or  a  child process.  This routine must be  < capable of running a process, displaying any output  in  the  < area  of  the  fine viewport, and detecting when the process  H has completed.  Under Berkeley  UNIX  the  _p_o_p_e_n(_3)  library  L routine  is  used, and under VMS the _L_I_B$_S_P_A_W_N() system ser-   vice routine is used.e    <      To transport KIC to another  operating  system,  it  is  R necessary to modify the _S_h_o_w_P_r_o_c_e_s_s() routine, and the argu-  < ment lists must also be corrected.  For example, to  display  < a  directory  listing  in the area of the fine viewport, the  ( command string under UNIX is as follows:    *                  ShowProcess( " ls -C " );    9 The corresponding command string under VMS is as follows:t    6      ShowProcess( " DIRECTORY/COLUMN=3/OUTPUT=KIC " );    P The  _S_h_o_w_P_r_o_m_p_t()  procedure  for  VMS  will  recognize  the  < "OUTPUT=KIC"  string  and replace the three characters "KIC"  < with the name of a temporary file.  When the spawned process  < has  completed,  the  contents  of  the  temporary  file are  + displayed in the area of the fine viewport.e                                <                                                          A.1          5                          _A_p_p_e_n_d_i_x _At      l             _A _C_a_t_a_l_o_g _o_f _A_l_l _R_o_u_t_i_n_e_s _a_n_d _M_a_c_r_o_s        <      The following pages contain a catalog of  all  routines  < and  macros  used  in KIC and the source files in which they  < are found.  This list has two uses: it provides a index that  < will  allow  the  programmer to quickly determine the source  < file that contains a particular routine, and it also  allows  < the  programmer  to  easily  check  the argument list of any   function call.                                                                            <                                                          A.2       SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________     G 8ABeginCall(SymbolNum)                                       actions.c  98int SymbolNum; 99G 8ABeginSymbol(SymbolNum, A, B)                               actions.c 98int SymbolNum;
 98int A, B;e 99G 8ABox(Length, Width, X, Y, XDirection, YDirection)           actions.c  98int Length, Width;
 98int X, Y;m 98int XDirection, YDirection;r 99G 8AComment(Text)                                              actions.c  98char *Text;f 99G 8ADeleteSymbol(SymbolNum)                                    actions.c  98int SymbolNum; 99G 8AEnd()                                                      actions.cA 99G 8AEndCall()                                                  actions.co 99G 8AEndSymbol()                                                actions.c 99G 8ALayer(Technology, Mask)                                    actions.co 98char Technology; 98char *Mask;  99G 8AMallocFailed()                                             actions.ca 99G 8APolygon(Path)                                              actions.cn 98struct p *Path;r 99G 8ARoundFlash(Width, X, Y)                                    actions.c; 98int Width;
 98int X, Y;o 99G 8AT(Type, X, Y)                                              actions.c  98char Type;
 98int X, Y;s 99G 8AUserExtension(Digit, Text)                                 actions.cc 98char Digit;o 98char *Text;t       9   9    > 8                                                         A.3   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________e    G 8AWire(Width, Path)                                          actions.cc 98struct p *Path;n 98int Width; 99E 8AddLayer()                                                  attri.ca 99E 8AddProperty()                                               prpty.cl 99D 8AddResultingTransform(Pointer, TF)                          move.c 98struct o *Pointer; 98int *TF; 99E 8AppendPointToPath(X, Y, Path)                               wires.c  98struct p **Path;
 98int X, Y;  99G 8Arcs(LookedAhead)                                           polygns.c  98int *LookedAhead;o 99F 8Area(LookedAhead)                                           select.c 98int *LookedAhead;  99E 8Attri()                                                     attri.c  99F 8BBLabel(Label, X, Y, BBCoarse, BBFine)                      labels.c 98struct ka *BBCoarse; 98struct ka *BBFine; 98char *Label;
 98int X, Y;( 99E 8Basic()                                                     basic.cs 99E 8Blink(LookedAhead)                                          attri.cm 98int *LookedAhead;a 99E 8Box(DisplayOrErase, Layer, L, B, R, T)                      boxes.cy 98char DisplayOrErase; 98int Layer, L, B, R, T; 99E 8Boxes(LookedAhead)                                          boxes.cb 98int *LookedAhead;e 99   9     9   9    > 8                                                         A.4   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________     B 8CDBB(SymbolDesc, Pointer, Left, Bottom, Right, Top)         cd.c 98struct s *SymbolDesc;X 98struct o *Pointer; 98int *Left, *Bottom;  98int *Right, *Top;e 99D 8CDBeginMakeCall(SymbolDesc, Name, NumX, DX, NumY, DY, Pointer)cd.c 98struct s *SymbolDesc;e 98struct o *Pointer; 98char *Name;  98int NumX, DX, NumY, DY;  99B 8CDAddProperty(SymbolDesc, Pointer, Value, String)           cd.c 98struct s *SymbolDesc;  98struct o *Pointer; 98char *String;  98int Value; 99B 8CDBox(Pointer, Layer, Length, Width, X, Y)                  cd.c 98struct o *Pointer; 98int *Length, *Width; 98int *Layer;_ 98int *X, *Y;a 99B 8CDCall(Pointer, SymbolName, NumX, DX, NumY, DY)             cd.c 98struct o *Pointer; 98char *SymbolName;  98int NumX, DX;  98int NumY, DY; 99B 8CDCheckPath(Path)                                           cd.c 98struct p *Path;  99B 8CDClose(SymbolDesc)                                         cd.c 98struct s *SymbolDesc;  99B 8CDDebug(Debug)                                              cd.c 98int Debug; 99B 8CDDelete(SymbolDesc, ObjectDesc)                            cd.h 98struct s *SymbolDesc;e 98struct o *ObjectDesc;  99B 8CDDeleteObjectDesc(SymbolDesc, ObjectDesc)                  cd.c 98struct s *SymbolDesc;t 98struct o *ObjectDesc;        9   9    > 8                                                         A.5   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________     B 8CDEndMakeCall(SymbolDesc, Pointer)                          cd.c 98struct s *SymbolDesc;; 98struct o *Pointer; 99B 8CDError(ID)                                                 cd.c 98int ID;s 99B 8CDFrom(Root, CIFFile, A, B, Layers, NumLayers, Program)     cd.c" 98char *Root, *CIFFile, Program; 98int *Layers, NumLayers;L
 98int A, B;  99B 8CDGen(SymbolDesc, GenDesc, Pointer)                         cd.c 98struct s *SymbolDesc;h 98struct g *GenDesc; 98struct o **Pointer;e 99B 8CDGenCIF(FileDesc, SymbolDesc, SymbolNum, A, B, Program)    cd.c 98struct s *SymbolDesc;  98FILE *FileDesc;  98int *SymbolNum;  98char Program; 
 98int A, B;  99B 8CDInfo(SymbolDesc, Pointer, Info)                           cd.c 98struct s *SymbolDesc;_ 98struct o *Pointer; 98int *Info; 99B 8CDInit()                                                    cd.c 99E 8CDInitGen(SymbolDesc, Layer, Left, Bottom, Right, Top, GenDesc)cd.c9 98struct s *SymbolDesc;8 98struct g **GenDesc; ( 98int Layer, Left, Bottom, Right, Top; 99B 8CDInitTGen(Pointer, TGen)                                   cd.c 98struct o *Pointer; 98struct t **TGen; 99B 8CDInsertObjectDesc(SymbolDesc, ObjectDesc)                  cd.c 98struct s *SymbolDesc;l 98struct o *ObjectDesc;e 99         9   9    > 8                                                         A.6   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________e    G 8CDIntersect(Left, Bottom, Right, Top, BeginX, EndX, BeginY, EndY)cd.c ! 98int Left, Bottom, Right, Top;d' 98int *BeginX, *EndX, *BeginY, *EndY;( 99B 8CDLabel(Pointer, Layer, Label, X, Y)                        cd.c 98struct o *Pointer; 98char *Label; 98int *Layer;  98int *X, *Y;n 99B 8CDMakeBox(SymbolDesc, Layer, Length, Width, X, Y, Pointer)  cd.c 98struct s *SymbolDesc;  98struct o **Pointer;9# 98int Layer, Length, Width, X, Y;  99B 8CDMakeLabel(SymbolDesc, Layer, Label, X, Y, Pointer)        cd.c 98struct s *SymbolDesc;  98struct o **Pointer;E 98char *Label; 98int Layer;
 98int X, Y;  99B 8CDMakePolygon(SymbolDesc, Layer, Path, Pointer)             cd.c 98struct s *SymbolDesc;9 98struct p *Path;9 98struct o **Pointer;M 98int Layer; 99B 8CDMakeRoundFlash(SymbolDesc, Layer, Width, X, Y, Pointer)   cd.c 98struct s *SymbolDesc;  98struct o **Pointer;n 98int Layer, Width, X, Y;9 99B 8CDMakeWire(SymbolDesc, Layer, Width, Path, Pointer)         cd.c 98struct s *SymbolDesc;  98struct p *Path;p 98struct o **Pointer;  98int Layer, Width;  99B 8CDOpen(SymbolName, SymbolDesc, Access)                      cd.c 98struct s **SymbolDesc; 98char *SymbolName;c 98char Access; 99B 8CDParseCIF(Root, CIFFile, Program)                          cd.c 98char *Root, *CIFFile;3 9     9   9    > 8                                                         A.7   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________      8char Program;  99B 8CDPatchInstances(SymbolDesc, MasterName)                    cd.c 98struct s *SymbolDesc;  98char *MasterName;8 99B 8CDPath(Path)                                                cd.c 98char *Path;t 99B 8CDPolygon(Pointer, Layer, Path)                             cd.c 98struct o *Pointer; 98struct p *Path;d 98int *Layer;* 99B 8CDProperty(SymbolDesc, Pointer, Property)                   cd.c 98struct s *SymbolDesc;  98struct o *Pointer; 98struct prpty **Property; 99B 8CDReflect(SymbolDesc)                                       cd.c 98struct s *SymbolDesc;  99B 8CDRemoveProperty(SymbolDesc, Pointer, Value)                cd.c 98struct s *SymbolDesc; 98struct o *Pointer; 98int Value; 99B 8CDRoundFlash(Pointer, Layer, Width, X, Y)                   cd.c 98struct o *Pointer; 98int *Layer, *Width, *X, *Y;X 99B 8CDSetInfo(SymbolDesc, Pointer, Info)                        cd.c 98struct s *SymbolDesc;9 98struct o *Pointer;
 98int Info;  99B 8CDSetLayer(Layer, Technology, Mask)                         cd.c 98int  Layer;  98char Technology, *Mask;a 99B 8CDSymbol(SymbolName, SymbolDesc)                            cd.c 98struct s *SymbolDesc;o 98char *SymbolName;a 99 9     9   9    > 8                                                         A.8   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________t    B 8CDT(Pointer, Type, X, Y)                                    cd.c 98struct o *Pointer; 98char Type;
 98int X, Y;  99B 8CDTGen(TGen, Type, X, Y)                                    cd.c 98struct t **TGen; 98char *Type;, 98int *X, *Y;t 99B 8CDTo(CIFFile, Root, A, B, Program)                          cd.c 98char *CIFFile, *Root;  98char Program;h
 98int A, B;p 99B 8CDType(Pointer, Type)                                       cd.c 98struct o *Pointer; 98char *Type;9 99B 8CDUnmark(SymbolDesc)                                        cd.c 98struct s *SymbolDesc;o 99B 8CDUpdate(SymbolDesc, SymbolFile)                            cd.c 98struct s *SymbolDesc;  98char *SymbolFile;  99B 8CDWire(Pointer, Layer, Width, Path)                         cd.c 98struct o *Pointer; 98struct p *Path; 98int *Layer, *Width;_ 99C 8Catch(sig)                                                  kic.c  98int sig; 99D 8CatchLyra(sig)                                              lyra.c 98int sig; 99C 8CatchSIGINT(sig)                                            kic.c  98int sig; 99E 8CenterFullView()                                            basic.c  99F 8ChangeLayer(LookedAhead)                                    change.c 98int *LookedAhead;r 99     9   9    > 8                                                         A.9   9   SYNOPSIS                                                    SOURCE FILE9________________________________________________________________________    F 8ClipToGridPoint(X, Y)                                       coords.c 98int *X, *Y;9 99D 8Copy(LookedAhead)                                           copy.c 98int *LookedAhead;  99D 8CopyPathWithXForm(Path)                                     copy.c 98struct p **Path; 99E 8CtrlAt(Menu, X, Y)                                          point.cL 98char **Menu;
 98int X, Y;y 99E 8Debug()                                                     debug.cl 99D 8DefaultWindows()                                            init.c 99F 8Del(LookedAhead)                                            delete.c 98int *LookedAhead;c 99F 8Desel()                                                     select.c 99E 8Dimen(LookedAhead)                                          attri.cl 98int *LookedAhead;o 99F 8DotKIC()                                                    dotkic.c 99G 8Doughnut(LookedAhead)                                       polygns.co 98int *LookedAhead;t 99E 8Edit(Ready, Center, Modified)                               basic.cR  98int Ready, Center, Modified; 99G 8ElapsedRealTime()                                           measure.c8 99G 8ElapsedSystemTime()                                         measure.c  99G 8ElapsedUserTime()                                           measure.ce 99E 8EraseBox(BB, Window)                                        boxes.cy 98struct ka BB, Window;e 99       9   9    > 8                                                        A.10   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________     F 8EraseLabel(Layer, Label, X, Y)                              labels.c 98char *Label; 98int Layer, X, Y; 99I 8EraseMagnifyingGlass()                                      viewports.cG 99I 8ErasePrompt()                                               viewports.c8 99E 8Expand()                                                    basic.c8 99B 8FBBegin(Display)                                            fb.c 98char *Display; 99B 8FBBlink(ColorId,Red,Green,Blue,Flag)                        fb.c 98int ColorId, Flag; 98int Red,Green,Blue;  99M 8FBBox(ColorId, DisplayOrErase, Type, StyleId, Left, Bottom, Right, Top)fb.c 98char Type, DisplayOrErase;3 98int StyleId, ColorId, Left, Bottom, Right, Top;_ 99B 8FBDefineFillPattern(StyleId,BitArray)                       fb.c 98int StyleId; 98int *BitArray; 99B 8FBDrawLineTo(X2,Y2)                                         fb.c 98int X2,Y2; 99B 8FBEnd()                                                     fb.c 99B 8FBFlood()                                                   fb.c 99B 8FBForeground(DisplayOrErase, ColorId)                       fb.c 98char DisplayOrErase; 98int ColorId; 99B 8FBHalt()                                                    fb.c 99 8FBInitialize() 99B 8FBKeyboard(TypeIn)                                          fb.c 98char **TypeIn; 999     9   9    > 8                                                        A.11   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________     B 8FBLine(X1,Y1,X2,Y2)                                         fb.c 98int X1,Y1,X2,Y2; 99B 8FBMore(Left,Bottom,Right,Top,Textfile)                      fb.c 98int Left,Bottom,Right,Top; 98FILE *Textfile;  99B 8FBMoveTo(X1,Y1)                                             fb.c 98int X1,Y1; 99B 8FBPoint(X,Y,Key,Buttons)                                    fb.c 98int *X,*Y,*Buttons;. 98char *Key; 99B 8FBPolygon(ColorId, Type, StyleId, xy, ncoords)              fb.c 98int *xy;" 98int ColorId, StyleId, ncoords; 98char Type; 99B 8FBPolygonClip(xy, ncoords, window)                          fb.c 98int *xy; 98int *ncoords;  98struct ka window; 99B 8FBSetCursorColor(colorId)                                   fb.c 98int colorId; 99B 8FBSetFillPattern(StyleId)                                   fb.c 98int StyleId; 99B 8FBText(Mode, RowOrX, ColumnOrY, Text)                       fb.c 98char *Text;  98char Mode; 98int RowOrX, ColumnOrY; 99B 8FBTransfer()                                                fb.c 99B 8FBVLT(ColorId, R, G, B)                                     fb.c 98int ColorId, R, G, B;  99E 8Fille(LookedAhead)                                          attri.cS 98int *LookedAhead;  99         9   9    > 8                                                        A.12   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________9    E 8FinePosition(X, Y, Key)                                     point.c8
 98int X, Y;;
 98char Key;e 99G 8Flash(LookedAhead)                                          polygns.c  98int *LookedAhead;r 99G 8Flatten()                                                   flatten.c  99G 8FlattenCell(CellDesc)                                       flatten.ch 98struct s *CellDesc;a 99E 8FullRedisplay()                                             point.cb 99F 8GenBeginCall(FileDesc, Number)                              gencif.c 98FILE *FileDesc;y 98int Number;h 99F 8GenBeginSymbol(FileDesc, SymbolNum, A, B)                   gencif.c 98FILE *FileDesc;u 98int SymbolNum, A, B; 99F 8GenBox(FileDesc, Length, Width, X, Y, XDir, YDir)           gencif.c 98FILE *FileDesc;  98int Length, Width; 98int X, Y, XDir, YDir;; 99F 8GenComment(FileDesc, Text)                                  gencif.c 98FILE *FileDesc;o 98char *Text;  99F 8GenEnd(FileDesc)                                            gencif.c 98FILE *FileDesc;  99F 8GenEndCall(FileDesc)                                        gencif.c 98FILE *FileDesc;  99F 8GenEndSymbol(FileDesc)                                      gencif.c 98FILE *FileDesc;n 99F 8GenLayer(FileDesc, Technology, Mask)                        gencif.c 98FILE *FileDesc;o 98char *Mask;S 98char Technology; 9     9   9    > 8                                                        A.13   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________9    F 8GenMirrorX(FileDesc)                                        gencif.c 98FILE *FileDesc;B 99F 8GenMirrorY(FileDesc)                                        gencif.c 98FILE *FileDesc;9 99F 8GenPolygon(FileDesc, Path)                                  gencif.c 98FILE *FileDesc;  98struct p *Path;, 99F 8GenRotation(FileDesc, X, Y)                                 gencif.c 98FILE *FileDesc;d
 98int X, Y;  99F 8GenTranslation(FileDesc, X, Y)                              gencif.c 98FILE *FileDesc; 
 98int X, Y;  99F 8GenUserExtension(FileDesc, Digit, Text)                     gencif.c 98FILE *FileDesc;  98char *Text;F 98char Digit; 99F 8GenWire(FileDesc, Width, Path)                              gencif.c 98FILE *FileDesc;_ 98struct p *Path;_ 98int Width; 99D 8GetCurrentTransform()                                       copy.c 99F 8GetKeyWord(file, inbuf)                                     dotkic.c 98FILE *file;o 98char *inbuf; 99D 8GetMoveTransform()                                          move.c 99E 8InBox(X, Y, AOI)                                            boxes.c  98struct ka AOI;
 98int X, Y;* 99G 8InPath(Delta, Path, X, Y)                                   polygns.c  98struct p *Path;B 98int X, Y, Delta; 99       9   9    > 8                                                        A.14   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________n    D 8Init()                                                      init.c 99D 8InitCoarseWindow(X, Y, Width)                               init.c 98int X, Y, Width; 99D 8InitFineWindow(X, Y)                                        init.c
 98int X, Y;  99D 8InitParameters()                                            init.c 99C 8InitSignals()                                               kic.c  99D 8InitVLT()                                                   init.c 99D 8InitViewport()                                              init.c 99H 8Instances(LookedAhead)                                      instance.c 98int *LookedAhead;T 99C 8IsManhattan(X1, Y1, X2, Y2)                                 45s.cb 98int X1, Y1, X2, Y2;8 99I 8KIC()                                                       viewports.c  99D 8LRCLayer(CellDesc,AOI,Layer)                                lyra.c 98struct s *CellDesc;9 98struct ka AOI; 98int Layer; 99F 8LToP(Viewport, Window, X, Y)                                coords.h 98struct ka Viewport;b 98struct ka Window;r 98int *X, *Y;o 99F 8Label(LookedAhead)                                          labels.c 98int *LookedAhead;) 99D 8LastView()                                                  zoom.c 99D 8Lyra(LookedAhead)                                           lyra.c 98int *LookedAhead;  99 9     9   9    > 8                                                        A.15   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________1    E 8MakeLayerInvisible(Layer)                                   attri.c  98int Layer; 99E 8MakeLayerVisible(Layer)                                     attri.c  98int Layer; 99C 8MallocFailed()                                              kic.c) 99I 8MenuDeselect(Selection)                                     viewports.c9 98char *Selection; 99I 8MenuSelect(Selection)                                       viewports.c  98char *Selection; 99D 8Move(LookedAhead)                                           move.c 98int *LookedAhead; 99D 8MovePath(TX, TY, Path)                                      move.c 98struct p **Path; 98int TX, TY;_ 99C 8NextCellName()                                              kic.c  99E 8NotPointingAtLayout()                                       point.c  99Q 8OutlineText(Left, Bottom, Right, Top, Type, DisplayOrErase, ColorId)viewports.c,* 98int Left, Bottom, Right, Top, ColorId; 98char Type, DisplayOrErase; 99E 8OversizeBox(BB, Delta)                                      boxes.c, 98struct ka *BB; 98int Delta; 99F 8PBox()                                                      parser.c 99F 8PCIF(CIFFileName, StatusString, StatusInt)                  parser.c 98char *CIFFileName; 98char **StatusString; 98int *StatusInt;  99F 8PCall()                                                     parser.c 99         9   9    > 8                                                        A.16   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________     F 8PCharacter(Returned, WhiteSpaceControl, EOFControl)         parser.h0 98int Returned, WhiteSpaceControl, EOFControl; 99F 8PComment()                                                  parser.c 99E 8PConvertTilde(psource, pdest, size)                         paths.c  98char **psource;8 98char **pdest;  98int *size; 99F 8PDeleteSymbol()                                             parser.c 99F 8PEnd()                                                      parser.c 99F 8PError(PErrorMessage)                                       parser.c 98char *PErrorMessage; 99F 8PErrorCD()                                                  parser.c 99F 8PErrorEOF()                                                 parser.c 99F 8PErrorNoSemicolon()                                         parser.c 99F 8PErrorUndefinedLayer(Tech, Mask)                            parser.c 98char *Mask;s 98char Tech; 99E 8PGetPath()                                                  paths.cd 99F 8PInteger(Returned, EOFControl)                              parser.h 98int Returned, EOFControl;  99F 8PLayer()                                                    parser.c 99F 8PLookAhead(Returned, WhiteSpaceControl, For)                parser.h) 98int Returned, WhiteSpaceControl, For;  99F 8PLookForSemi(Returned)                                      parser.h 98int Returned;  99     9     9   9    > 8                                                        A.17   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________D    E 8POpen(file, mode, ext, prealname)                           paths.c  98char *file;h 98char *mode;t 98char *ext; 98char **prealname;  99F 8PPath(Path)                                                 parser.c 98struct p *Path;) 99F 8PPoint(X, Y)                                                parser.c
 98int X, Y;E 99F 8PPolygon()                                                  parser.c 99F 8PPrimitiveCommand()                                         parser.c 99F 8PRoundFlash()                                               parser.c 99E 8PSetPath(string)                                            paths.c  98char *string;c 99F 8PSymbol()                                                   parser.c 99F 8PToL(Viewport, Window, X, Y)                                coords.c 98struct ka Viewport;  98struct ka Window;( 98int *X, *Y;  99F 8PUserExtension()                                            parser.c 99F 8PWhiteSpace(Returned, WhiteSpaceControl, EOFControl)        parser.h0 98int Returned, WhiteSpaceControl, EOFControl; 99F 8PWhiteSpace1(Returned, EOFControl)                          parser.h 98int Returned, EOFControl;  99F 8PWhiteSpace2(Returned, EOFControl)                          parser.h 98int Returned, EOFControl; 99F 8PWhiteSpace3(Returned, EOFControl)                          parser.h 98int Returned, EOFControl;  99         9   9    > 8                                                        A.18   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________     F 8PWire()                                                     parser.c 99D 8Pan(LookedAhead)                                            zoom.c 98int *LookedAhead;C 99E 8Peek()                                                      basic.c  99I 8PeekLayer(CellDesc, AOI, Layer, BottomVisibleLayer)         redisplay.cs 98struct s *CellDesc;h 98struct ka AOI; 98int Layer; 98int BottomVisibleLayer;  99E 8Point()                                                     point.c  99I 8PointLayerTable()                                           viewports.c  99F 8Point_At_LAYER()                                            select.c 99G 8Polygons(LookedAhead)                                       polygns.c_ 98int *LookedAhead;_ 99H 8Pop()                                                       contexts.c 99D 8PrintLRC(file)                                              lyra.c 98FILE *file;* 99E 8Properties(LookedAhead)                                     prpty.c  98int *LookedAhead;t 99H 8Push()                                                      contexts.c 99I 8Redisplay(CellDesc, AOI)                                    redisplay.c  98struct s *CellDesc;9 98struct ka AOI; 99I 8RedisplayAfterInterrupt()                                   redisplay.c  99I 8RedisplayLayer(CellDesc, AOI, Layer, BottomVisibleLayer)    redisplay.c  98struct s *CellDesc;  98struct ka AOI; 98int Layer; 98int BottomVisibleLayer;  9     9   9    > 8                                                        A.19   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________S    E 8RemoveLastPointInPath(Path)                                 wires.co 98struct p **Path; 99E 8RemoveLayer(LookedAhead)                                    attri.cn 98int *LookedAhead;  99 8RemoveProperty() 99E 8RemovePropertyList(Pointer, PrptyDesc)                      prpty.cn 98struct o *Pointer; 98struct prpty **PrptyDesc;  99E 8RestorePropertyList(Pointer, PrptyDesc)                     prpty.c9 98struct o *Pointer; 98struct prpty *PrptyDesc; 99E 8Save()                                                      basic.c  99C 8SaveDotKIC()                                                kic.c 99D 8SaveLastView()                                              zoom.c 99D 8SaveViewOnStack()                                           zoom.c 99F 8Sel(LookedAhead)                                            select.c 98int *LookedAhead;S 99F 8SelectQClear()                                              select.c 99F 8SelectQComputeBB()                                          select.c 99F 8SelectQDelete(Pointer)                                      select.c 98struct o *Pointer; 99F 8SelectQFirst(Pointer)                                       select.c 98struct o *Pointer; 99F 8SelectQInit()                                               select.c 99F 8SelectQInsert(Pointer)                                      select.c 98struct o *Pointer; 99       9   9    > 8                                                        A.20   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________d    F 8SelectQShow(AOI)                                            select.c 98struct ka AOI; 99F 8Selection(AOI)                                              select.c 98struct ka AOI; 99F 8SelectionInstances(AOI)                                     select.c 98struct ka AOI; 99F 8SelectionLayer(AOI, Layer)                                  select.c 98struct ka AOI; 98int Layer; 99F 8Selections(LookedAhead)                                     select.c 98int *LookedAhead;r 99E 8SetDebounceTime()                                           point.ca 99E 8SetGridParameters(LookedAhead)                              attri.ca 98int *LookedAhead;A 99E 8SetMenuParameters(LookedAhead)                              attri.ca 98int *LookedAhead;e 99E 8ShowAttributeMenu()                                         attri.cs 99D 8ShowAxes(Viewport, Window)                                  grid.c 98struct ka Viewport, Window;  99E 8ShowBasicMenu()                                             basic.c  99E 8ShowBox(Layer, BB, Window)                                  boxes.c  98int Layer; 98struct ka BB, Window;e 99I 8ShowCommandMenu()                                           viewports.co 99E 8ShowDebugMenu()                                             debug.c  99I 8ShowFineViewport()                                          viewports.c  99D 8ShowGrid(Viewport, Window, AOI)                             grid.c$ 98struct ka Viewport, Window, AOI;       9   9    > 8                                                        A.21   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________     H 8ShowInstanceMenu()                                          instance.c 99F 8ShowLabel(Layer, Label, X, Y, Flag)                         labels.c 98char *Label; 98int Layer;
 98int X, Y;u
 98int Flag;  99I 8ShowLayerTable()                                            viewports.c9 99I 8ShowLayout()                                                viewports.cu 99E 8ShowLine(Layer, X1, Y1, X2, Y2, Window)                     lines.c  98int Layer; 98int X1, Y1, X2, Y2;S 98struct ka Window;  99E 8ShowManhattanLine(Layer, X1, Y1, X2, Y2, Window)            lines.c 98int Layer; 98int X1, Y1, X2, Y2;_ 98struct ka Window;_ 99I 8ShowMenu(Menu, NumMenu)                                     viewports.c  98char **Menu; 98int NumMenu; 99I 8ShowParameters()                                            viewports.c  99G 8ShowPath(Layer, Path, Window, Terminate)                    polygns.c  98struct p *Path;  98struct ka Window;t 98int Layer; 98int Terminate; 99G 8ShowPolygon(Layer, Path, Window)                            polygns.c  98struct p *Path;t 98struct ka Window;  98int Layer; 99I 8ShowPrompt(Prompt)                                          viewports.c  98char *Prompt;  99I 8ShowPromptAndWait(Prompt)                                   viewports.c  98char *Prompt;  99     9   9    > 8                                                        A.22   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________     E 8ShowProperties()                                            prpty.c  99E 8ShowPropertyMenu()                                          prpty.c  99G 8ShowRatio(Name, Value, PerUnitName, PerUnitValue)           measure.cd 98char *Name;  98char *PerUnitName; 98int Value; 98int PerUnitValue;  99E 8ShowRGB()                                                   attri.c9 99F 8ShowSelectionMenu()                                         select.c 99E 8ShowWire(Layer, Width, Path, Window)                        wires.c  98struct p *Path;L 98struct ka Window;u 98int Layer, Width;  99I 8ShowXY()                                                    viewports.c  99G 8StartTiming()                                               measure.cu 99G 8StopTiming()                                                measure.c  99F 8StretchBox(LookedAhead)                                     modify.c 98int *LookedAhead;t 99F 8StretchPath(LookedAhead)                                    modify.c 98int *LookedAhead;9 99F 8SwapInts(Dragon, Eagle)                                     macros.h 98int Dragon, Eagle; 99D 8SwitchToFinePositioning()                                   init.c 99F 8TCurrent(TFP)                                               xforms.c
 98int *TFP;_ 99F 8TEmpty()                                                    xforms.c 99F 8TFull()                                                     xforms.c 99     9   9    > 8                                                        A.23   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________w    F 8TIdentity()                                                 xforms.c 99F 8TInit()                                                     xforms.c 99F 8TInverse()                                                  xforms.c 99F 8TInversePoint(X, Y)                                         xforms.c 98int *X, *Y;  99F 8TMX()                                                       xforms.c 99F 8TMY()                                                       xforms.c 99F 8TPoint(X, Y)                                                xforms.c 98int *X, *Y;  99F 8TPop()                                                      xforms.c 99F 8TPremultiply()                                              xforms.c 99F 8TPush()                                                     xforms.c 99F 8TRotate(XDirection, YDirection)                             xforms.c 98int XDirection, YDirection;( 99F 8TTranslate(X, Y)                                            xforms.c
 98int X, Y;U 99C 8To45(x1, y1, x2, y2)                                        45s.c  98int x1, y1, *x2, *y2;  99C 8Trap(n)                                                     kic.c 
 98int n; 99E 8TypeCoordinate()                                            point.c  99D 8UseLRC(cp)                                                  lyra.c
 98char *cp;8 99D 8UseRules(rules)                                             lyra.c 98char *rules; 999     9   9    > 8                                                        A.24   9   SYNOPSIS                                                    SOURCE FILE9_______________________________________________________________________y    E 8Visib(LookedAhead)                                          attri.c  98int *LookedAhead;r 99E 8WhereAmI(X, Y, Key)                                         point.c 
 98int X, Y; 
 98char Key;9 99E 8Width(LookedAhead)                                          wires.c8 98int *LookedAhead;p 99D 8Windo(LookedAhead)                                          zoom.c 98int *LookedAhead;  99E 8Wires(LookedAhead)                                          wires.c  98int *LookedAhead;  99H 8WriteCell()                                                 contexts.c 99D 8Zoom(LookedAhead)                                           zoom.c 98int *LookedAhead; 99F 8abs(Dragon)                                                 macros.h 98int Dragon;  99G 8free(ptr)                                                   nmalloc.h  98char *ptr; 99E 8index(s, c)                                                 paths.c  98char *s, c;  99C 8main(argc, argv)                                            kic.c 
 98int argc;r 98char *argv[];Y 99F 8max(Dragon, Eagle)                                          macros.h 98int Dragon, Eagle; 99F 8min(Dragon, Eagle)                                          macros.h 98int Dragon, Eagle; 99       9                <                                                          B.1          5                          _A_p_p_e_n_d_i_x _B(      Y                 _T_h_e _C_D _P_r_o_g_r_a_m_m_e_r_s'_s _M_a_n_u_a_l8        <      The Section 3 UNIX manual pages  for  the  CD  database  ' package are contained in this appendix.9                                                                                                <                                                          C.1          5                          _A_p_p_e_n_d_i_x _C9      \                _T_h_e _K_I_C _T_u_t_o_r_i_a_l _U_s_e_r'_s _G_u_i_d_e        <      The KIC tutorial user's  guide  is  contained  in  this  < appendix.   This user's guide is appropriate for KIC running   under both UNIX and VMS.                                                                                            <                                                          D.1          5                          _A_p_p_e_n_d_i_x _D;      \                 _T_h_e _M_F_B _P_r_o_g_r_a_m_m_e_r_s'_s _M_a_n_u_a_l        <      The Section 3 UNIX manual pages  for  the  Model  Frame  7 Buffer graphics package are contained in this appendix.                                                                                                 <                                                          E.1          5                          _A_p_p_e_n_d_i_x _E       a                _T_h_e _M_F_B_C_A_P _P_r_o_g_r_a_m_m_e_r'_s _M_a_n_u_a_l         <      The Section 5 UNIX manual pages for the MFBCAP graphics  6 terminal database file are contained in this appendix.                                                                                                <                                                          F.1          5                          _A_p_p_e_n_d_i_x _F       \                 _K_I_C _a_n_d _R_e_l_a_t_e_d _M_a_n_u_a_l _P_a_g_e_s        <      The Section 1 UNIX manual pages for KIC and all related  ( programs are contained in this appendix.                                                                                                <                                                          R.1          7                          _R_e_f_e_r_e_n_c_e_sr          d [1]  K. H. Keller and A. R Newton, _K_I_C_2: _A _L_o_w-_C_o_s_t _I_n_t_e_r_a_c_-        _t_i_v_e  _E_d_i_t_o_r  _f_o_r  _I_n_t_e_g_r_a_t_e_d _C_i_r_c_u_i_t _D_e_s_i_g_n, Digest of  <      Papers, IEEE Compcon 82 Conf., San Fransisco,  Califor-  ,      nia, February 22-25, 1982, pp. 302-304.        z [2]  K. H. Keller, _K_I_C, _A  _G_r_a_p_h_i_c_s  _E_d_i_t_o_r  _f_o_r  _I_n_t_e_g_r_a_t_e_d  L      _C_i_r_c_u_i_t_s,  Masters  Report,  Department  of  Electrical  <      Engineering and Computer Science, University  of  Cali-  &      fornia, Berkeley, Ca., June 1981.        Z [3]  B. W. Kernighan and D. M. Ritchie,  _T_h_e  _C  _P_r_o_g_r_a_m_m_i_n_g  L      _L_a_n_g_u_a_g_e,  Prentice-Hall, Englewood Cliffs, New Jersey,  
      1978.        n [4]  C. A. Mead and L. Conway, _I_n_t_r_o_d_u_c_t_i_o_n _t_o _V_L_S_I _S_y_s_t_e_m_s,  *      Addison-Wesley, Reading, Mass., 1980.        n [5]  R. Hon ad C. Sequin, _A  _G_u_i_d_e  _t_o  _L_S_I  _I_m_p_l_e_m_e_n_t_a_t_i_o_n,  0      Xerox PARC Technical Report SSL-79-7, 1980.                          <                                                          R.2    d [6]  W. M. Newman and R. F. Sproull, _P_r_i_n_c_i_p_l_e_s _o_f  _I_n_t_e_r_a_c_-  a      _t_i_v_e _C_o_m_p_u_t_e_r _G_r_a_p_h_i_c_s, McGraw-Hill, New York, 1977.         n [7]  J. D. Foley and A. Van Dam, _F_u_n_d_a_m_e_n_t_a_l_s _o_f _I_n_t_e_r_a_c_t_i_v_e  \      _C_o_m_p_u_t_e_r   _G_r_a_p_h_i_c_s,  Addison-Wesley,  Reading,  Mass.,  
      1982.        \ [8]  M. H. Arnold and J. K. Ousterhout, _L_Y_R_A: _A _N_e_w _A_p_p_r_o_a_c_h  v      _t_o  _G_e_o_m_e_t_r_i_c  _L_a_y_o_u_t _R_u_l_e _C_h_e_c_k_i_n_g, Proc. 19th ACM IEE  <      Design Automation Conf.  Las Vegas, Nevada, June 14-16,        1982, pp.530-536.        b [9]  _P_r_o_g_r_a_m_m_i_n_g _i_n _V_A_X-_1_1_C, Digital Equipment  Corporation,  3      P.O. Box CS2008, Nashua, New Hampshire.  03061         < [10] KIC2 under VAX/VMS is also distributed by the Engineer-  <      ing  Systems  Group  of Digital Equipment Corp., 2 Iron         Way, Marlboro, Mass.  01752        < [11] STREAM is a proprietary description format for  graphic  <      data  that  is  licensed by Calma, Inc.  The conversion  <      programs between KIC and Calma STREAM were developed at  <      Tektronix,  Inc.,  and the Electronics Research Labora-  <      tory with the permission of Calma and may  be  released  <      by the Electronics Research Laboratory only to licensed                  <                                                          R.3          customers of Calma.                                                                                                                            <                                                            i          H                         _A_c_k_n_o_w_l_e_d_g_e_m_e_n_t_s          <      I would like to thank all those who have contributed to  < the  development  of the KIC editor.  The history of KIC and  < all related programs spans several years, and  appropriately  < there  are  many  persons  to be acknowledged for their kind   help and support.d    <      The invaluable advice and  encouragement  of  Professor  < Richard Newton is greatly appreciated.  Professor Newton has  < guided the development of the KIC editor from the time  that  < the  project  was  begun by Kenneth H. Keller in the Fall of  < 1980, and he has provided excellent opportunities  for  both  < the  KIC  program  and  myself.   The  opportunities  for me  < include a Research Assistantship funded in part by Tektronix  < Inc.,  National  Semiconductor  Corp., and Digital Equipment  < Corp., the opportunity to develop the  KIC  editor  with  an  < excellent  user  community  including Berkeley graduate stu-  < dents in the Integrated Circuits Group  and  designers  from  < National  Semiconductor,  Evans  and Sutherland Corp., CSIRO  < Australia, and Tektronix, and the opportunity to be part  of  < perhaps  the  world's most prestigious university CAD effort   in integrated circuits.    <      The support and professional  experiences  provided  by  < Professor  D.  O.  Pederson  are  also  greatly appreciated.                  <                                                           ii    < Professor Pederson, along with Dr. Stewart  Taylor  of  Tek-  < tronix,  convinced me to enter the graduate study program at  < Berkeley and has continually helped to make  my  studies  at  # Berkeley productive and beneficial.s    <      I am very grateful to those persons who  have  provided  < assistance  and  software  during the development of the KIC  < program.  These persons include Kenneth H. Keller  who  ini-  < tially  designed  and wrote KIC and the CD database package,  < Peter P. Moore who developed the nmalloc  memory  management  < package, Chris Wilson of CSIRO who wrote the initial version  < of geometry stretching procedures, Peter Harris  of  Jupiter  < Systems  Inc. for firmware support on the AED 512, Professor  < J. K. Ousterhout who provided the UNIX directory search path  < procedures,   and  Professor  Carlo  Sequin  for  his  early  < interest in the KIC program and his helpful suggestions  for  < the  user interface.  Also, Mark Bales implemented the first  $ version of the MFB graphics package.    <      I also gratefully acknowledge the helpful support  from  < the  early  industrial users of KIC.  Dr. J. Craig Mudge and  < Chris Wilson of the VLSI design group  at  the  Division  of  < Computing  Research,  CSIRO,  Australia, provided both ideas  < and software for the geometry stretching  commands  in  KIC.  < J. Halverson and R. Haslan of Evans and Sutherland have pro-  < vided help for the development and improvement of KIC  under  < VMS.   S.  Sriram, F. Taku, and S. Carcia of the Engineering  < Systems Group of Digital Equipment Corp. and A.  Hanover  of                    <                                                          iii    < the  Methodology  and  Advanced Development Group of Digital  < Equipment Corp. have also given considerable support to  the  < development  of  KIC  on VMS.  Jim Solomon and Joe Santos of  < the Speech Design Group of National Semiconductor,  where  I  < worked  on  KIC  as  a  summer employee during the Summer of  < 1982, were the first major industrial users of  KIC  in  the  < Santa Clara area, and I am very grateful for their kind sup-  < port.  The work of Ed Gould, who helped to improve the  user  < interface of the CIF conversion programs and who wrote a new  < .KIC parser, is appreciated.  Tektronix has been  generously  < supportive  of  my  work by providing graphics and computing  < equipment, financial support, and the opportunity  to  share  < ideas  with  their  excellent  CAD  effort; in particular, I  < would like to acknowledge the assistance and advice  of  Dr.  < E.  Cohen,  J.  Crawford, and S. Potter of the Tektronix MCE  
 CAD group.    <      I would also like to thank Dr. I. Getreu  of  Tektronix  < for  his  support and encouragement throughout the course of  
 this work.    <      The most important acknowledgements, the personal ones,  < are  saved  for  last.   To my parents in Oregon, Virgil and  < Rosemary, I am deeply thankful  for  their  their  constant,  < loving  support  and  infinite  patience  during my graduate  < years.  And to my Uncle Jess and Aunt Betty Billingsley I am  < especially  grateful  for their understanding and for making  < certain that  this  over-worked  Berkeley  graduate  student                    <                                                           iv    8 enjoyed at least one good, home-cooked meal every month!    <      Finally, to the friends that I have found  at  Berkeley  < who   have   given   me  helpful  criticism  and  assistance  < throughout the course of my research project.  I  thankfully  < acknowledge  the generous assistance of Clem Cole, Mark Hof-  < mann, Ken Keller, Jim Kleckner, Grace Mah, Peter Moore,  Tom   Quarles, and Rick Spickelmier.                                                                                                  <                                                            v          &                      Table of Contents        < Chapter 1:  Introduction ..............................    1    < Chapter 2:  The CD Database ...........................    5    <     2.1. Introduction .................................    5    <     2.2. CD Descriptor Types ..........................    9    <         2.2.1. The Symbol Descriptor ..................    9    <         2.2.2. The Master-List Descriptor .............   11    <         2.2.3. The Symbol Table Descriptor ............   13    <         2.2.4. The Object Descriptor ..................   14    <         2.2.5. The Generator Descriptor ...............   15    <         2.2.6. The Transform Descriptor ...............   17    <         2.2.7. The Property List Descriptor ...........   18    <         2.2.8. The CD Layer Descriptor ................   19    <         2.2.9. The Path Descriptor ....................   21    <     2.3. Storage Bins .................................   22    <     2.4. CD Procedures ................................   26    <         2.4.1. CD Initialization ......................   26                  <                                                           vi    <         2.4.2. Error Handling in CD ...................   27    <         2.4.3. CD Symbol Management ...................   27    <         2.4.4. CD Object Creation Routines ............   31    <         2.4.5. CD Object Generator ....................   38    <         2.4.6. Accessing Objects in CD ................   39    <         2.4.7. Object Deletion in CD ..................   43    <         2.4.8. CD Information Routines ................   43    <         2.4.9. CD Integrity ...........................   46    <     2.5. Two Dimensional Transformation Package .......   48    <         2.5.1. Initialization .........................   48    <         2.5.2. The Current Transformation .............   48    <         2.5.3. The Transformation Stack ...............   50    <         2.5.4. The Instance Transformation ............   52    4         2.5.5. Inverse of the Current Transformation    <     2.6. Traversing a Symbol Hierarchy with CD ........   54    <     2.7. Translation Routines .........................   57    <     2.8. The CD Parameters Descriptor .................   61    < Chapter 3:  The Fast CIF Parser .......................   63                      <                                                          vii    <     3.1. Action Routines ..............................   65    < Chapter 4:  The KIC User Interface ....................   72    <     4.1. Window and Viewport Management ...............   72    <         4.1.1. Text Viewports .........................   74    <             4.1.1.1. Layer Menu Viewport ..............   75    <             4.1.1.2. Parameter Viewport ...............   76    <             4.1.1.3. Prompt Viewport ..................   77    <             4.1.1.4. Command Menu Viewport ............   78    <         4.1.2. Layout Viewports .......................   79    <         4.1.3. Clipping ...............................   81    <         4.1.4. Window/Viewport Transformations ........   83    <     4.2. KIC Data Structures ..........................   86    <         4.2.1. The Area Descriptor ....................   86    <         4.2.2. The Window Stack Descriptor ............   87    <         4.2.3. The KIC Layer Table Descriptor .........   88    <         4.2.4. The Cursor Descriptor ..................   91    <         4.2.5. The KIC Selection Queue ................   92    <         4.2.6. The Context Descriptor .................   93                      <                                                         viii    <     4.3. The KIC Parameters Structure .................   96    <     4.4. KIC Command Menus ............................  110    <     4.5. The Pointing Device ..........................  117    <     4.6. The Frame Buffer Interface ...................  125    <         4.6.1.  The Frame Buffer Descriptor ...........  125    <         4.6.2.  The Frame Buffer Routines .............  129    <     4.7. Geometry Display Routines ....................  146    <         4.7.1. Redisplay ..............................  148    <     4.8. Geometry Input Routines ......................  151    4     4.9. Geometry and Symbol Modification Procedures    < Chapter 5:  System Dependencies .......................  161    <     5.1. Terminal I/O Dependencies ....................  161    <     5.2. The Directory Search Path ....................  162    <     5.3. Memory Management ............................  163    <     5.4. The System Interface .........................  164    1 Appendix A:  A Catalog of All Routines and Macros.    < Appendix B:  The CD Programmers's Manual ..............  B.1    < Appendix C:  The KIC Tutorial User's Guide ............  C.1                      <                                                           ix    < Appendix D:  The MFB Programmers's Manual .............  D.1    < Appendix E:  The MFBCAP Programmer's Manual ...........  E.1    < Appendix F:  KIC and Related Manual Pages .............  F.1    P _R_e_f_e_r_e_n_c_e_s ............................................  R.1                                                                                                    